From 0e8fd3398771da2f016d72830179507f3edda51b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 4 May 1996 07:50:46 +0000 Subject: Initial version imported to CVS (This used to be commit 291551d80711daab7b7581720bcd9a08d6096517) --- source3/libsmb/nmblib.c | 936 ++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smbencrypt.c | 202 ++++++++++ 2 files changed, 1138 insertions(+) create mode 100644 source3/libsmb/nmblib.c create mode 100644 source3/libsmb/smbencrypt.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c new file mode 100644 index 0000000000..6743227173 --- /dev/null +++ b/source3/libsmb/nmblib.c @@ -0,0 +1,936 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NBT netbios library routines + Copyright (C) Andrew Tridgell 1994-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "includes.h" +#include "nameserv.h" + +extern int DEBUGLEVEL; + +int num_good_sends=0; +int num_good_receives=0; +static uint16 name_trn_id = 0; +BOOL CanRecurse = True; +extern pstring scope; + +/******************************************************************* + handle "compressed" name pointers + ******************************************************************/ +static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, + BOOL *got_pointer,int *ret) +{ + int loop_count=0; + + while ((ubuf[*offset] & 0xC0) == 0xC0) { + if (!*got_pointer) (*ret) += 2; + (*got_pointer)=True; + (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; + if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { + return(False); + } + } + return(True); +} + +/******************************************************************* + parse a nmb name from "compressed" format to something readable + return the space taken by the name, or 0 if the name is invalid + ******************************************************************/ +static int parse_nmb_name(char *inbuf,int offset,int length, + struct nmb_name *name) +{ + int m,n=0; + unsigned char *ubuf = (unsigned char *)inbuf; + int ret = 0; + BOOL got_pointer=False; + + if (length - offset < 2) return(0); + + /* handle initial name pointers */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + + m = ubuf[offset]; + + if (!m) return(0); + if ((m & 0xC0) || offset+m+2 > length) return(0); + + bzero((char *)name,sizeof(*name)); + + /* the "compressed" part */ + if (!got_pointer) ret += m + 2; + offset++; + while (m) { + unsigned char c1,c2; + c1 = ubuf[offset++]-'A'; + c2 = ubuf[offset++]-'A'; + if ((c1 & 0xF0) || (c2 & 0xF0)) return(0); + name->name[n++] = (c1<<4) | c2; + m -= 2; + } + name->name[n] = 0; + + if (n==16) { + /* parse out the name type, + its always in the 16th byte of the name */ + name->name_type = name->name[15]; + + /* remove trailing spaces */ + name->name[15] = 0; + n = 14; + while (n && name->name[n]==' ') name->name[n--] = 0; + } + + /* now the domain parts (if any) */ + n = 0; + while ((m=ubuf[offset])) { + /* we can have pointers within the domain part as well */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + + if (!got_pointer) ret += m+1; + if (n) name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0); + offset++; + while (m--) name->scope[n++] = (char)ubuf[offset++]; + } + name->scope[n++] = 0; + + return(ret); +} + + +/******************************************************************* + put a compressed nmb name into a buffer. return the length of the + compressed name + + compressed names are really weird. The "compression" doubles the + size. The idea is that it also means that compressed names conform + to the doman name system. See RFC1002. + ******************************************************************/ +static int put_nmb_name(char *buf,int offset,struct nmb_name *name) +{ + int ret,m; + fstring buf1; + char *p; + + if (name->name[0] == '*') { + /* special case for wildcard name */ + bzero(buf1,20); + buf1[0] = '*'; + } else { + sprintf(buf1,"%-15.15s%c",name->name,name->name_type); + } + + buf[offset] = 0x20; + + ret = 34; + + for (m=0;m<16;m++) { + buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + } + offset += 33; + + buf[offset] = 0; + + if (name->scope[0]) { + /* XXXX this scope handling needs testing */ + ret += strlen(name->scope) + 1; + strcpy(&buf[offset+1],name->scope); + + p = &buf[offset+1]; + while ((p = strchr(p,'.'))) { + buf[offset] = PTR_DIFF(p,&buf[offset]); + offset += buf[offset]; + p = &buf[offset+1]; + } + buf[offset] = strlen(&buf[offset+1]); + } + + return(ret); +} + +/******************************************************************* + useful for debugging messages + ******************************************************************/ +char *namestr(struct nmb_name *n) +{ + static int i=0; + static fstring ret[4]; + char *p = ret[i]; + + if (!n->scope[0]) + sprintf(p,"%s(%x)",n->name,n->name_type); + else + sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope); + + i = (i+1)%4; + return(p); +} + +/******************************************************************* + allocate are parse some resource records + ******************************************************************/ +static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, + struct res_rec **recs, + int count) +{ + int i; + *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + if (!*recs) return(False); + + bzero(*recs,sizeof(**recs)*count); + + for (i=0;i length) { + free(*recs); + return(False); + } + (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); + (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); + (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); + (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); + (*offset) += 10; + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || + (*offset)+(*recs)[i].rdlength > length) { + free(*recs); + return(False); + } + memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); + (*offset) += (*recs)[i].rdlength; + } + return(True); +} + +/******************************************************************* + put a resource record into a packet + ******************************************************************/ +static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) +{ + int ret=0; + int i; + + for (i=0;iheader.msg_type = CVAL(inbuf,0); + flags = CVAL(inbuf,1); + dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); + if (flags & 1) dgram->header.flags.more = True; + if (flags & 2) dgram->header.flags.first = True; + dgram->header.dgm_id = RSVAL(inbuf,2); + putip((char *)&dgram->header.source_ip,inbuf+4); + dgram->header.source_port = RSVAL(inbuf,8); + dgram->header.dgm_length = RSVAL(inbuf,10); + dgram->header.packet_offset = RSVAL(inbuf,12); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); + offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); + } + + if (offset >= length || (length-offset > sizeof(dgram->data))) + return(False); + + dgram->datasize = length-offset; + memcpy(dgram->data,inbuf+offset,dgram->datasize); + + return(True); +} + + +/******************************************************************* + parse a nmb packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise + ******************************************************************/ +static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) +{ + int nm_flags,offset; + + bzero((char *)nmb,sizeof(*nmb)); + + if (length < 12) return(False); + + /* parse the header */ + nmb->header.name_trn_id = RSVAL(inbuf,0); + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; + nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; + nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); + nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; + nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; + nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; + nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.rcode = CVAL(inbuf,3) & 0xF; + nmb->header.qdcount = RSVAL(inbuf,4); + nmb->header.ancount = RSVAL(inbuf,6); + nmb->header.nscount = RSVAL(inbuf,8); + nmb->header.arcount = RSVAL(inbuf,10); + + if (nmb->header.qdcount) { + offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); + if (!offset) return(False); + + if (length - (12+offset) < 4) return(False); + nmb->question.question_type = RSVAL(inbuf,12+offset); + nmb->question.question_class = RSVAL(inbuf,12+offset+2); + + offset += 12+4; + } else { + offset = 12; + } + + /* and any resource records */ + if (nmb->header.ancount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, + nmb->header.ancount)) + return(False); + + if (nmb->header.nscount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, + nmb->header.nscount)) + return(False); + + if (nmb->header.arcount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, + nmb->header.arcount)) + return(False); + + return(True); +} + +/******************************************************************* + free up any resources associated with an nmb packet + ******************************************************************/ +void free_nmb_packet(struct nmb_packet *nmb) +{ + if (nmb->answers) free(nmb->answers); + if (nmb->nsrecs) free(nmb->nsrecs); + if (nmb->additional) free(nmb->additional); +} + +/******************************************************************* + free up any resources associated with a packet + ******************************************************************/ +void free_packet(struct packet_struct *packet) +{ + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + free(packet); +} + +/******************************************************************* + read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket + ******************************************************************/ +struct packet_struct *read_packet(int fd,enum packet_type packet_type) +{ + extern struct in_addr lastip; + extern int lastport; + struct packet_struct *packet; + char buf[MAX_DGRAM_SIZE]; + int length; + BOOL ok=False; + + length = read_udp_socket(fd,buf,sizeof(buf)); + if (length < MIN_DGRAM_SIZE) return(NULL); + + packet = (struct packet_struct *)malloc(sizeof(*packet)); + if (!packet) return(NULL); + + packet->next = NULL; + packet->prev = NULL; + packet->ip = lastip; + packet->port = lastport; + packet->fd = fd; + packet->timestamp = time(NULL); + packet->packet_type = packet_type; + switch (packet_type) + { + case NMB_PACKET: + ok = parse_nmb(buf,length,&packet->packet.nmb); + break; + + case DGRAM_PACKET: + ok = parse_dgram(buf,length,&packet->packet.dgram); + break; + } + if (!ok) { + free(packet); + return(NULL); + } + + num_good_receives++; + + DEBUG(4,("%s received a packet of len %d from (%s) port %d\n", + timestring(),length,inet_ntoa(packet->ip),packet->port)); + + return(packet); +} + + +/******************************************************************* + send a udp packet on a already open socket + ******************************************************************/ +static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) +{ + BOOL ret; + struct sockaddr_in sock_out; + + /* set the address and port */ + bzero((char *)&sock_out,sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)&ip); + sock_out.sin_port = htons( port ); + sock_out.sin_family = AF_INET; + + DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n", + timestring(),len,inet_ntoa(ip),port)); + + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, + sizeof(sock_out)) >= 0); + + if (!ret) + DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", + inet_ntoa(ip),port,strerror(errno))); + + if (ret) + num_good_sends++; + + return(ret); +} + +/******************************************************************* + build a dgram packet ready for sending + + XXXX This currently doesn't handle packets too big for one + datagram. It should split them and use the packet_offset, more and + first flags to handle the fragmentation. Yuck. + ******************************************************************/ +static int build_dgram(char *buf,struct packet_struct *p) +{ + struct dgram_packet *dgram = &p->packet.dgram; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + if (dgram->header.flags.more) ubuf[1] |= 1; + if (dgram->header.flags.first) ubuf[1] |= 2; + RSSVAL(ubuf,2,dgram->header.dgm_id); + putip(ubuf+4,(char *)&dgram->header.source_ip); + RSSVAL(ubuf,8,dgram->header.source_port); + RSSVAL(ubuf,12,dgram->header.packet_offset); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); + offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); + } + + memcpy(ubuf+offset,dgram->data,dgram->datasize); + offset += dgram->datasize; + + /* automatically set the dgm_length */ + dgram->header.dgm_length = offset; + RSSVAL(ubuf,10,dgram->header.dgm_length); + + return(offset); +} + +/******************************************************************* + build a nmb name + ******************************************************************/ +void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) +{ + strcpy(n->name,name); + strupper(n->name); + n->name_type = type; + strcpy(n->scope,this_scope); +} + + +/******************************************************************* + build a nmb packet ready for sending + + XXXX this currently relies on not being passed something that expands + to a packet too big for the buffer. Eventually this should be + changed to set the trunc bit so the receiver can request the rest + via tcp (when that becomes supported) + ******************************************************************/ +static int build_nmb(char *buf,struct packet_struct *p) +{ + struct nmb_packet *nmb = &p->packet.nmb; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + RSSVAL(ubuf,offset,nmb->header.name_trn_id); + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) ubuf[offset+2] |= (1<<7); + if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; + if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; + ubuf[offset+3] |= (nmb->header.rcode & 0xF); + RSSVAL(ubuf,offset+4,nmb->header.qdcount); + RSSVAL(ubuf,offset+6,nmb->header.ancount); + RSSVAL(ubuf,offset+8,nmb->header.nscount); + RSSVAL(ubuf,offset+10,nmb->header.arcount); + + offset += 12; + if (nmb->header.qdcount) { + /* XXXX this doesn't handle a qdcount of > 1 */ + offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); + RSSVAL(ubuf,offset,nmb->question.question_type); + RSSVAL(ubuf,offset+2,nmb->question.question_class); + offset += 4; + } + + if (nmb->header.ancount) + offset += put_res_rec((char *)ubuf,offset,nmb->answers, + nmb->header.ancount); + + if (nmb->header.nscount) + offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, + nmb->header.nscount); + + if (nmb->header.arcount) + offset += put_res_rec((char *)ubuf,offset,nmb->additional, + nmb->header.arcount); + + return(offset); +} + + +/******************************************************************* + send a packet_struct + ******************************************************************/ +BOOL send_packet(struct packet_struct *p) +{ + char buf[1024]; + int len=0; + + bzero(buf,sizeof(buf)); + + switch (p->packet_type) + { + case NMB_PACKET: + len = build_nmb(buf,p); + break; + + case DGRAM_PACKET: + len = build_dgram(buf,p); + break; + } + + if (!len) return(False); + + return(send_udp(p->fd,buf,len,p->ip,p->port)); +} + +/**************************************************************************** + receive a packet with timeout on a open UDP filedescriptor + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_packet(int fd,enum packet_type type,int t) +{ + fd_set fds; + struct timeval timeout; + + FD_ZERO(&fds); + FD_SET(fd,&fds); + timeout.tv_sec = t/1000; + timeout.tv_usec = 1000*(t%1000); + + sys_select(&fds,&timeout); + + if (FD_ISSET(fd,&fds)) + return(read_packet(fd,type)); + + return(NULL); +} + + +/**************************************************************************** +interpret a node status response +****************************************************************************/ +static void interpret_node_status(char *p, char *master,char *rname) +{ + int level = (master||rname)?4:0; + int numnames = CVAL(p,0); + DEBUG(level,("received %d names\n",numnames)); + + if (rname) *rname = 0; + if (master) *master = 0; + + p += 1; + while (numnames--) + { + char qname[17]; + int type; + fstring flags; + *flags = 0; + StrnCpy(qname,p,15); + type = CVAL(p,15); + p += 16; + + if (p[0] & 0x80) strcat(flags," "); + if ((p[0] & 0x60) == 0) strcat(flags,"B "); + if ((p[0] & 0x60) == 1) strcat(flags,"P "); + if ((p[0] & 0x60) == 2) strcat(flags,"M "); + if ((p[0] & 0x60) == 3) strcat(flags,"_ "); + if (p[0] & 0x10) strcat(flags," "); + if (p[0] & 0x08) strcat(flags," "); + if (p[0] & 0x04) strcat(flags," "); + if (p[0] & 0x02) strcat(flags," "); + + if (master && !*master && type == 0x1d) { + StrnCpy(master,qname,15); + trim_string(master,NULL," "); + } + + if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { + StrnCpy(rname,qname,15); + trim_string(rname,NULL," "); + } + + DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags)); + p+=2; + } + DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", + IVAL(p,20),IVAL(p,24))); +} + + +/**************************************************************************** + do a netbios name status query on a host + + the "master" parameter is a hack used for finding workgroups. + **************************************************************************/ +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname, + void (*fn)()) +{ + BOOL found=False; + int retries = 2; + int retry_time = 5000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + + bzero((char *)&p,sizeof(p)); + + if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + + (getpid()%(unsigned)100); + name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; + + nmb->header.name_trn_id = name_trn_id; + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = False; + nmb->header.nm_flags.recursion_available = CanRecurse; + nmb->header.nm_flags.recursion_desired = recurse; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type,scope); + + nmb->question.question_type = 0x21; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return(False); + + retries--; + + while (1) + { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) break; + if (!found && !send_packet(&p)) + return False; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_packet(fd,NMB_PACKET,90))) + { + struct nmb_packet *nmb2 = &p2->packet.nmb; + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || + !nmb2->header.response) { + /* its not for us - maybe deal with it later */ + if (fn) + fn(p2); + else + free_packet(p2); + continue; + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount || + nmb2->answers->rr_type != 0x21) { + /* XXXX what do we do with this? could be a redirect, but + we'll discard it for the moment */ + free_packet(p2); + continue; + } + + interpret_node_status(&nmb2->answers->rdata[0], master,rname); + free_packet(p2); + return(True); + } + } + + + DEBUG(0,("No status response (this is not unusual)\n")); + + return(False); +} + + +/**************************************************************************** + do a netbios name query to find someones IP + ****************************************************************************/ +BOOL name_query(int fd,char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, struct in_addr *ip,void (*fn)()) +{ + BOOL found=False; + int retries = 3; + int retry_time = bcast?250:2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + + bzero((char *)&p,sizeof(p)); + + if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + + (getpid()%(unsigned)100); + name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; + + nmb->header.name_trn_id = name_trn_id; + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = bcast; + nmb->header.nm_flags.recursion_available = CanRecurse; + nmb->header.nm_flags.recursion_desired = recurse; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type,scope); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return(False); + + retries--; + + while (1) + { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) break; + if (!found && !send_packet(&p)) + return False; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_packet(fd,NMB_PACKET,90))) + { + struct nmb_packet *nmb2 = &p2->packet.nmb; + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || + !nmb2->header.response) { + /* its not for us - maybe deal with it later + (put it on the queue?) */ + if (fn) + fn(p2); + else + free_packet(p2); + continue; + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount) { + /* XXXX what do we do with this? could be a redirect, but + we'll discard it for the moment */ + free_packet(p2); + continue; + } + + if (ip) { + putip((char *)ip,&nmb2->answers->rdata[2]); + DEBUG(fn?3:2,("Got a positive name query response from %s", + inet_ntoa(p2->ip))); + DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip))); + } + found=True; retries=0; + free_packet(p2); + if (fn) break; + } + } + + return(found); +} + + +/**************************************************************************** + construct and send a netbios DGRAM + + Note that this currently sends all answers to port 138. thats the + wrong things to do! I should send to the requestors port. XXX + **************************************************************************/ +BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len, + char *srcname,char *dstname, + int src_type,int dest_type, + struct in_addr dest_ip, + struct in_addr src_ip) +{ + struct packet_struct p; + struct dgram_packet *dgram = &p.packet.dgram; + char *ptr,*p2; + char tmp[4]; + + bzero((char *)&p,sizeof(p)); + + dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */ + dgram->header.flags.node_type = M_NODE; + dgram->header.flags.first = True; + dgram->header.flags.more = False; + dgram->header.dgm_id = name_trn_id++; + dgram->header.source_ip = src_ip; + dgram->header.source_port = DGRAM_PORT; + dgram->header.dgm_length = 0; /* let build_dgram() handle this */ + dgram->header.packet_offset = 0; + + make_nmb_name(&dgram->source_name,srcname,src_type,scope); + make_nmb_name(&dgram->dest_name,dstname,dest_type,scope); + + ptr = &dgram->data[0]; + + /* now setup the smb part */ + ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */ + memcpy(tmp,ptr,4); + set_message(ptr,17,17 + len,True); + memcpy(ptr,tmp,4); + + CVAL(ptr,smb_com) = SMBtrans; + SSVAL(ptr,smb_vwv1,len); + SSVAL(ptr,smb_vwv11,len); + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); + SSVAL(ptr,smb_vwv13,3); + SSVAL(ptr,smb_vwv14,1); + SSVAL(ptr,smb_vwv15,1); + SSVAL(ptr,smb_vwv16,2); + p2 = smb_buf(ptr); + strcpy(p2,mailslot); + p2 = skip_string(p2,1); + + memcpy(p2,buf,len); + p2 += len; + + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */ + + p.ip = dest_ip; + p.port = DGRAM_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = DGRAM_PACKET; + + return(send_packet(&p)); +} + + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c new file mode 100644 index 0000000000..a0683b5d28 --- /dev/null +++ b/source3/libsmb/smbencrypt.c @@ -0,0 +1,202 @@ +#ifdef SMB_PASSWD +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB parameters and setup + Copyright (C) Andrew Tridgell 1992-1995 + Modified by Jeremy Allison 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "loadparm.h" +#include "des.h" +#include "md4.h" + +extern int DEBUGLEVEL; + +#ifndef uchar +#define uchar unsigned char +#endif +#ifndef int16 +#define int16 unsigned short +#endif +#ifndef uint16 +#define uint16 unsigned short +#endif +#ifndef uint32 +#define uint32 unsigned int +#endif + +#include "byteorder.h" + +void str_to_key(uchar *str,uchar *key) +{ + void des_set_odd_parity(des_cblock *); + int i; + + key[0] = str[0]>>1; + key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); + key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); + key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); + key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); + key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); + key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); + key[7] = str[6]&0x7F; + for (i=0;i<8;i++) { + key[i] = (key[i]<<1); + } + des_set_odd_parity((des_cblock *)key); +} + +void D1(uchar *k, uchar *d, uchar *out) +{ + des_key_schedule ks; + des_cblock deskey; + + str_to_key(k,(uchar *)deskey); + des_set_key(deskey,ks); + des_ecb_encrypt(d, out, ks, DES_DECRYPT); +} + +void E1(uchar *k, uchar *d, uchar *out) +{ + des_key_schedule ks; + des_cblock deskey; + + str_to_key(k,(uchar *)deskey); + des_set_key(deskey,ks); + des_ecb_encrypt(d, out, ks, DES_ENCRYPT); +} + +void E_P16(uchar *p14,uchar *p16) +{ + uchar sp7[7]; + /* the following constant makes us compatible with other + implementations. Note that publishing this constant does not reduce the + security of the encryption mechanism */ + uchar sp8[] = {0xAA,0xD3,0xB4,0x35,0xB5,0x14,0x4,0xEE}; + uchar x[8]; + + memset(sp7,'\0',7); + + D1(sp7, sp8, x); + E1(p14, x, p16); + E1(p14+7, x, p16+8); +} + +void E_P24(uchar *p21, uchar *c8, uchar *p24) +{ + E1(p21, c8, p24); + E1(p21+7, c8, p24+8); + E1(p21+14, c8, p24+16); +} + + +/* + This implements the X/Open SMB password encryption + It takes a password, a 8 byte "crypt key" and puts 24 bytes of + encrypted password into p24 */ +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) +{ + uchar p14[15], p21[21]; + + memset(p21,'\0',21); + memset(p14,'\0',14); + StrnCpy((char *)p14,(char *)passwd,14); + + strupper((char *)p14); + E_P16(p14, p21); + E_P24(p21, c8, p24); +} + +/* Routines for Windows NT MD4 Hash functions. */ +static int _my_wcslen(int16 *str) +{ + int len = 0; + while(*str++ != 0) + len++; + return len; +} + +/* + * Convert a string into an NT UNICODE string. + * Note that regardless of processor type + * this must be in intel (little-endian) + * format. + */ + +static int _my_mbstowcs(int16 *dst, uchar *src, int len) +{ + int i; + int16 val; + + for(i = 0; i < len; i++) { + val = *src; + SSVAL(dst,0,val); + dst++; + src++; + if(val == 0) + break; + } + return i; +} + +/* + * Creates the MD4 Hash of the users password in NT UNICODE. + */ + +void E_md4hash(uchar *passwd, uchar *p16) +{ + int i, len; + int16 wpwd[129]; + MDstruct MD; + + /* Password cannot be longer than 128 characters */ + len = strlen(passwd); + if(len > 128) + len = 128; + /* Password must be converted to NT unicode */ + _my_mbstowcs( wpwd, passwd, len); + wpwd[len] = 0; /* Ensure string is null terminated */ + /* Calculate length in bytes */ + len = _my_wcslen(wpwd) * sizeof(int16); + + MDbegin(&MD); + for(i = 0; i + 64 <= len; i += 64) + MDupdate(&MD,wpwd + (i/2), 512); + MDupdate(&MD,wpwd + (i/2),(len-i)*8); + SIVAL(p16,0,MD.buffer[0]); + SIVAL(p16,4,MD.buffer[1]); + SIVAL(p16,8,MD.buffer[2]); + SIVAL(p16,12,MD.buffer[3]); +} + +/* Does the NT MD4 hash then des encryption. */ + +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) +{ + uchar p21[21]; + + memset(p21,'\0',21); + + E_md4hash(passwd, p21); + E_P24(p21, c8, p24); +} + +#else +void smbencrypt_dummy(void){} +#endif -- cgit From 1956d1349441d8d5694df6dda67528bec4b1c10e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 May 1996 07:47:47 +0000 Subject: cleanups to make thinsg compile cleanly (This used to be commit 39fbeb04ae938594c380d97ebe67c012fa0dd51a) --- source3/libsmb/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index a0683b5d28..0221520ce6 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -166,7 +166,7 @@ void E_md4hash(uchar *passwd, uchar *p16) MDstruct MD; /* Password cannot be longer than 128 characters */ - len = strlen(passwd); + len = strlen((char *)passwd); if(len > 128) len = 128; /* Password must be converted to NT unicode */ -- cgit From 58734631b4233ec08b7a262587e400792f31f185 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 May 1996 15:13:29 +0000 Subject: Lots of changes! - add faq info on NT printer handling - add "delete readonly" option to help rcs users - add stuff to man pages on new printer options - add "proxy name resolution" option - add "command string" -c option to smbclient (thanks Ken) - split time functions into time.c - rearrange the quotas stuff a bit and fix some bugs - complete rehash of the time handling code thanks to Paul Eggert - fix nmblookup output a bit - add plp print queue parsing from Bertrand Wallrich (This used to be commit 635b56f19c817527c52e9bbde31faa6a8a47777b) --- source3/libsmb/nmblib.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6743227173..1f78996156 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -625,16 +625,17 @@ static void interpret_node_status(char *p, char *master,char *rname) char qname[17]; int type; fstring flags; + int i; *flags = 0; StrnCpy(qname,p,15); type = CVAL(p,15); p += 16; - if (p[0] & 0x80) strcat(flags," "); - if ((p[0] & 0x60) == 0) strcat(flags,"B "); - if ((p[0] & 0x60) == 1) strcat(flags,"P "); - if ((p[0] & 0x60) == 2) strcat(flags,"M "); - if ((p[0] & 0x60) == 3) strcat(flags,"_ "); + strcat(flags, (p[0] & 0x80) ? " " : " "); + if ((p[0] & 0x60) == 0x00) strcat(flags,"B "); + if ((p[0] & 0x60) == 0x20) strcat(flags,"P "); + if ((p[0] & 0x60) == 0x40) strcat(flags,"M "); + if ((p[0] & 0x60) == 0x60) strcat(flags,"_ "); if (p[0] & 0x10) strcat(flags," "); if (p[0] & 0x08) strcat(flags," "); if (p[0] & 0x04) strcat(flags," "); @@ -650,7 +651,10 @@ static void interpret_node_status(char *p, char *master,char *rname) trim_string(rname,NULL," "); } - DEBUG(level,("\t%s (type=0x%x)\t%s\n",qname,type,flags)); + for (i = strlen( qname) ; --i >= 0 ; ) { + if (!isprint(qname[i])) qname[i] = '.'; + } + DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags)); p+=2; } DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", -- cgit From a2c1623827406667a4f2f058c24f1d971f6627f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Jun 1996 06:42:03 +0000 Subject: a huge pile of changes :-) The biggest thing is the integration of Lukes new nmbd. Its still largely untested, so we will really need some feedback I've also added auto prototype generation and cleaned up a lot of minor things as a result (This used to be commit 0d8dcfa13c527ec2c8aca39ba49c09e4e694b26c) --- source3/libsmb/namequery.c | 292 +++++++++++++++++++++++++++++ source3/libsmb/nmblib.c | 445 ++++++++++---------------------------------- source3/libsmb/smbencrypt.c | 15 +- 3 files changed, 394 insertions(+), 358 deletions(-) create mode 100644 source3/libsmb/namequery.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c new file mode 100644 index 0000000000..d1b1ae7d3e --- /dev/null +++ b/source3/libsmb/namequery.c @@ -0,0 +1,292 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + name query routines + Copyright (C) Andrew Tridgell 1994-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "includes.h" + +extern pstring scope; +extern int DEBUGLEVEL; + + +/**************************************************************************** +interpret a node status response +****************************************************************************/ +static void _interpret_node_status(char *p, char *master,char *rname) +{ + int level = (master||rname)?4:0; + int numnames = CVAL(p,0); + DEBUG(level,("received %d names\n",numnames)); + + if (rname) *rname = 0; + if (master) *master = 0; + + p += 1; + while (numnames--) + { + char qname[17]; + int type; + fstring flags; + int i; + *flags = 0; + StrnCpy(qname,p,15); + type = CVAL(p,15); + p += 16; + + strcat(flags, (p[0] & 0x80) ? " " : " "); + if ((p[0] & 0x60) == 0x00) strcat(flags,"B "); + if ((p[0] & 0x60) == 0x20) strcat(flags,"P "); + if ((p[0] & 0x60) == 0x40) strcat(flags,"M "); + if ((p[0] & 0x60) == 0x60) strcat(flags,"_ "); + if (p[0] & 0x10) strcat(flags," "); + if (p[0] & 0x08) strcat(flags," "); + if (p[0] & 0x04) strcat(flags," "); + if (p[0] & 0x02) strcat(flags," "); + + if (master && !*master && type == 0x1d) { + StrnCpy(master,qname,15); + trim_string(master,NULL," "); + } + + if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { + StrnCpy(rname,qname,15); + trim_string(rname,NULL," "); + } + + for (i = strlen( qname) ; --i >= 0 ; ) { + if (!isprint(qname[i])) qname[i] = '.'; + } + DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags)); + p+=2; + } + DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", + IVAL(p,20),IVAL(p,24))); +} + + +/**************************************************************************** + do a netbios name status query on a host + + the "master" parameter is a hack used for finding workgroups. + **************************************************************************/ +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname, + void (*fn)()) +{ + BOOL found=False; + int retries = 2; + int retry_time = 5000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + static int name_trn_id = 0; + + bzero((char *)&p,sizeof(p)); + + if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + + (getpid()%(unsigned)100); + name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; + + nmb->header.name_trn_id = name_trn_id; + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = False; + nmb->header.nm_flags.recursion_available = 0; + nmb->header.nm_flags.recursion_desired = 1; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type,scope); + + nmb->question.question_type = 0x21; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return(False); + + retries--; + + while (1) + { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) break; + if (!found && !send_packet(&p)) + return False; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_packet(fd,NMB_PACKET,90))) + { + struct nmb_packet *nmb2 = &p2->packet.nmb; + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || + !nmb2->header.response) { + /* its not for us - maybe deal with it later */ + if (fn) + fn(p2); + else + free_packet(p2); + continue; + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount || + nmb2->answers->rr_type != 0x21) { + /* XXXX what do we do with this? could be a redirect, but + we'll discard it for the moment */ + free_packet(p2); + continue; + } + + _interpret_node_status(&nmb2->answers->rdata[0], master,rname); + free_packet(p2); + return(True); + } + } + + + DEBUG(0,("No status response (this is not unusual)\n")); + + return(False); +} + + +/**************************************************************************** + do a netbios name query to find someones IP + ****************************************************************************/ +BOOL name_query(int fd,char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, struct in_addr *ip,void (*fn)()) +{ + BOOL found=False; + int retries = 3; + int retry_time = bcast?250:2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + static int name_trn_id = 0; + + bzero((char *)&p,sizeof(p)); + + if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + + (getpid()%(unsigned)100); + name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; + + nmb->header.name_trn_id = name_trn_id; + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = bcast; + nmb->header.nm_flags.recursion_available = 0; + nmb->header.nm_flags.recursion_desired = 1; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type,scope); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return(False); + + retries--; + + while (1) + { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) break; + if (!found && !send_packet(&p)) + return False; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_packet(fd,NMB_PACKET,90))) + { + struct nmb_packet *nmb2 = &p2->packet.nmb; + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || + !nmb2->header.response) { + /* its not for us - maybe deal with it later + (put it on the queue?) */ + if (fn) + fn(p2); + else + free_packet(p2); + continue; + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount) { + /* XXXX what do we do with this? could be a redirect, but + we'll discard it for the moment */ + free_packet(p2); + continue; + } + + if (ip) { + putip((char *)ip,&nmb2->answers->rdata[2]); + DEBUG(fn?3:2,("Got a positive name query response from %s", + inet_ntoa(p2->ip))); + DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip))); + } + found=True; retries=0; + free_packet(p2); + if (fn) break; + } + } + + return(found); +} diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 1f78996156..d8d6eb0ee4 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,15 +21,104 @@ */ #include "includes.h" -#include "nameserv.h" +#include "localnet.h" +#include "loadparm.h" +extern struct in_addr myip; extern int DEBUGLEVEL; -int num_good_sends=0; -int num_good_receives=0; -static uint16 name_trn_id = 0; -BOOL CanRecurse = True; +int num_good_sends = 0; +int num_good_receives = 0; extern pstring scope; +extern pstring myname; +extern struct in_addr ipzero; + + +/**************************************************************************** + print out a res_rec structure + ****************************************************************************/ +static void debug_nmb_res_rec(struct res_rec *res, char *hdr) +{ + int i, j; + + DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, + namestr(&res->rr_name), + res->rr_type, + res->rr_class, + res->ttl)); + + if (res->rdlength == 0 || res->rdata == NULL) return; + + for (i = 0; i < res->rdlength; i+= 16) + { + DEBUG(4, (" %s %3x char ", hdr, i)); + + for (j = 0; j < 16; j++) + { + unsigned char x = res->rdata[i+j]; + if (x < 32 || x > 127) x = '.'; + + if (i+j >= res->rdlength) break; + DEBUG(4, ("%c", x)); + } + + DEBUG(4, (" hex ", i)); + + for (j = 0; j < 16; j++) + { + if (i+j >= res->rdlength) break; + DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j])); + } + + DEBUG(4, ("\n")); + } +} + +/**************************************************************************** + process a nmb packet + ****************************************************************************/ +void debug_nmb_packet(struct packet_struct *p) +{ + struct nmb_packet *nmb = &p->packet.nmb; + + DEBUG(4,("nmb packet from %s header: id=%d opcode=%d response=%s\n", + inet_ntoa(p->ip), + nmb->header.name_trn_id,nmb->header.opcode,BOOLSTR(nmb->header.response))); + DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR(nmb->header.nm_flags.bcast), + BOOLSTR(nmb->header.nm_flags.recursion_available), + BOOLSTR(nmb->header.nm_flags.recursion_desired), + BOOLSTR(nmb->header.nm_flags.trunc), + BOOLSTR(nmb->header.nm_flags.authoritative))); + DEBUG(4,(" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, + nmb->header.nscount, + nmb->header.arcount)); + + if (nmb->header.qdcount) + { + DEBUG(4,(" question: q_name=%s q_type=%d q_class=%d\n", + namestr(&nmb->question.question_name), + nmb->question.question_type, + nmb->question.question_class)); + } + + if (nmb->answers && nmb->header.ancount) + { + debug_nmb_res_rec(nmb->answers,"answers"); + } + if (nmb->nsrecs && nmb->header.nscount) + { + debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); + } + if (nmb->additional && nmb->header.arcount) + { + debug_nmb_res_rec(nmb->additional,"additional"); + } +} /******************************************************************* handle "compressed" name pointers @@ -38,7 +127,7 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { int loop_count=0; - + while ((ubuf[*offset] & 0xC0) == 0xC0) { if (!*got_pointer) (*ret) += 2; (*got_pointer)=True; @@ -54,8 +143,7 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, parse a nmb name from "compressed" format to something readable return the space taken by the name, or 0 if the name is invalid ******************************************************************/ -static int parse_nmb_name(char *inbuf,int offset,int length, - struct nmb_name *name) +static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name) { int m,n=0; unsigned char *ubuf = (unsigned char *)inbuf; @@ -186,11 +274,10 @@ char *namestr(struct nmb_name *n) } /******************************************************************* - allocate are parse some resource records + allocate and parse some resource records ******************************************************************/ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, - struct res_rec **recs, - int count) + struct res_rec **recs, int count) { int i; *recs = (struct res_rec *)malloc(sizeof(**recs)*count); @@ -382,10 +469,10 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) char buf[MAX_DGRAM_SIZE]; int length; BOOL ok=False; - + length = read_udp_socket(fd,buf,sizeof(buf)); if (length < MIN_DGRAM_SIZE) return(NULL); - + packet = (struct packet_struct *)malloc(sizeof(*packet)); if (!packet) return(NULL); @@ -528,6 +615,7 @@ static int build_nmb(char *buf,struct packet_struct *p) if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80; if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; ubuf[offset+3] |= (nmb->header.rcode & 0xF); + RSSVAL(ubuf,offset+4,nmb->header.qdcount); RSSVAL(ubuf,offset+6,nmb->header.ancount); RSSVAL(ubuf,offset+8,nmb->header.nscount); @@ -607,334 +695,3 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) } -/**************************************************************************** -interpret a node status response -****************************************************************************/ -static void interpret_node_status(char *p, char *master,char *rname) -{ - int level = (master||rname)?4:0; - int numnames = CVAL(p,0); - DEBUG(level,("received %d names\n",numnames)); - - if (rname) *rname = 0; - if (master) *master = 0; - - p += 1; - while (numnames--) - { - char qname[17]; - int type; - fstring flags; - int i; - *flags = 0; - StrnCpy(qname,p,15); - type = CVAL(p,15); - p += 16; - - strcat(flags, (p[0] & 0x80) ? " " : " "); - if ((p[0] & 0x60) == 0x00) strcat(flags,"B "); - if ((p[0] & 0x60) == 0x20) strcat(flags,"P "); - if ((p[0] & 0x60) == 0x40) strcat(flags,"M "); - if ((p[0] & 0x60) == 0x60) strcat(flags,"_ "); - if (p[0] & 0x10) strcat(flags," "); - if (p[0] & 0x08) strcat(flags," "); - if (p[0] & 0x04) strcat(flags," "); - if (p[0] & 0x02) strcat(flags," "); - - if (master && !*master && type == 0x1d) { - StrnCpy(master,qname,15); - trim_string(master,NULL," "); - } - - if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { - StrnCpy(rname,qname,15); - trim_string(rname,NULL," "); - } - - for (i = strlen( qname) ; --i >= 0 ; ) { - if (!isprint(qname[i])) qname[i] = '.'; - } - DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags)); - p+=2; - } - DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", - IVAL(p,20),IVAL(p,24))); -} - - -/**************************************************************************** - do a netbios name status query on a host - - the "master" parameter is a hack used for finding workgroups. - **************************************************************************/ -BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname, - void (*fn)()) -{ - BOOL found=False; - int retries = 2; - int retry_time = 5000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - - bzero((char *)&p,sizeof(p)); - - if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + - (getpid()%(unsigned)100); - name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; - - nmb->header.name_trn_id = name_trn_id; - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = CanRecurse; - nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type,scope); - - nmb->question.question_type = 0x21; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return(False); - - retries--; - - while (1) - { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) break; - if (!found && !send_packet(&p)) - return False; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_packet(fd,NMB_PACKET,90))) - { - struct nmb_packet *nmb2 = &p2->packet.nmb; - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) { - /* its not for us - maybe deal with it later */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount || - nmb2->answers->rr_type != 0x21) { - /* XXXX what do we do with this? could be a redirect, but - we'll discard it for the moment */ - free_packet(p2); - continue; - } - - interpret_node_status(&nmb2->answers->rdata[0], master,rname); - free_packet(p2); - return(True); - } - } - - - DEBUG(0,("No status response (this is not unusual)\n")); - - return(False); -} - - -/**************************************************************************** - do a netbios name query to find someones IP - ****************************************************************************/ -BOOL name_query(int fd,char *name,int name_type, - BOOL bcast,BOOL recurse, - struct in_addr to_ip, struct in_addr *ip,void (*fn)()) -{ - BOOL found=False; - int retries = 3; - int retry_time = bcast?250:2000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - - bzero((char *)&p,sizeof(p)); - - if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + - (getpid()%(unsigned)100); - name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; - - nmb->header.name_trn_id = name_trn_id; - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = CanRecurse; - nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type,scope); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return(False); - - retries--; - - while (1) - { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) break; - if (!found && !send_packet(&p)) - return False; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_packet(fd,NMB_PACKET,90))) - { - struct nmb_packet *nmb2 = &p2->packet.nmb; - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) { - /* its not for us - maybe deal with it later - (put it on the queue?) */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount) { - /* XXXX what do we do with this? could be a redirect, but - we'll discard it for the moment */ - free_packet(p2); - continue; - } - - if (ip) { - putip((char *)ip,&nmb2->answers->rdata[2]); - DEBUG(fn?3:2,("Got a positive name query response from %s", - inet_ntoa(p2->ip))); - DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip))); - } - found=True; retries=0; - free_packet(p2); - if (fn) break; - } - } - - return(found); -} - - -/**************************************************************************** - construct and send a netbios DGRAM - - Note that this currently sends all answers to port 138. thats the - wrong things to do! I should send to the requestors port. XXX - **************************************************************************/ -BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len, - char *srcname,char *dstname, - int src_type,int dest_type, - struct in_addr dest_ip, - struct in_addr src_ip) -{ - struct packet_struct p; - struct dgram_packet *dgram = &p.packet.dgram; - char *ptr,*p2; - char tmp[4]; - - bzero((char *)&p,sizeof(p)); - - dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */ - dgram->header.flags.node_type = M_NODE; - dgram->header.flags.first = True; - dgram->header.flags.more = False; - dgram->header.dgm_id = name_trn_id++; - dgram->header.source_ip = src_ip; - dgram->header.source_port = DGRAM_PORT; - dgram->header.dgm_length = 0; /* let build_dgram() handle this */ - dgram->header.packet_offset = 0; - - make_nmb_name(&dgram->source_name,srcname,src_type,scope); - make_nmb_name(&dgram->dest_name,dstname,dest_type,scope); - - ptr = &dgram->data[0]; - - /* now setup the smb part */ - ptr -= 4; /* XXX ugliness because of handling of tcp SMB length */ - memcpy(tmp,ptr,4); - set_message(ptr,17,17 + len,True); - memcpy(ptr,tmp,4); - - CVAL(ptr,smb_com) = SMBtrans; - SSVAL(ptr,smb_vwv1,len); - SSVAL(ptr,smb_vwv11,len); - SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); - SSVAL(ptr,smb_vwv13,3); - SSVAL(ptr,smb_vwv14,1); - SSVAL(ptr,smb_vwv15,1); - SSVAL(ptr,smb_vwv16,2); - p2 = smb_buf(ptr); - strcpy(p2,mailslot); - p2 = skip_string(p2,1); - - memcpy(p2,buf,len); - p2 += len; - - dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length */ - - p.ip = dest_ip; - p.port = DGRAM_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = DGRAM_PACKET; - - return(send_packet(&p)); -} - - diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 0221520ce6..be22fc50fc 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -28,19 +28,6 @@ extern int DEBUGLEVEL; -#ifndef uchar -#define uchar unsigned char -#endif -#ifndef int16 -#define int16 unsigned short -#endif -#ifndef uint16 -#define uint16 unsigned short -#endif -#ifndef uint32 -#define uint32 unsigned int -#endif - #include "byteorder.h" void str_to_key(uchar *str,uchar *key) @@ -198,5 +185,5 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) } #else -void smbencrypt_dummy(void){} + void smbencrypt_dummy(void){} #endif -- cgit From a2641cfe00b7857056fd8fd1e020aae7ea817690 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Jun 1996 15:14:47 +0000 Subject: Did more integration of Lukes code ready for the first release. I've now got WINS registration working, and refresh working. Its looking pretty good so far, but needs lots of testing. (This used to be commit 045014aa57721b9701ca379bcab055b908773184) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d8d6eb0ee4..87fe5fee78 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -472,7 +472,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) length = read_udp_socket(fd,buf,sizeof(buf)); if (length < MIN_DGRAM_SIZE) return(NULL); - + packet = (struct packet_struct *)malloc(sizeof(*packet)); if (!packet) return(NULL); -- cgit From e38afbf38210b8cf30c5b13dc5ea96a6dda433f7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Jun 1996 15:16:09 +0000 Subject: - changed some debug levels in clientutil.c - added dir_check_ftype() to clean up the file type checking a bit - added check for libc version >= 5 for setfsuid() for Linux - moved the AM_MASTER() and related macros to nameserv.h - added proper defines for the various netbios announce types - don't call the announce_backup() code, as I'm pretty sure its wrong it sent ANN_GetBackupListReq packets as broadcasts, they are supposed to be used only by clients to the master browser to find a list of available backup servers to remote a netserverenum to, I don't think nmbd should ever send one. - fixed a bug in the browse list writing - minor debug cleanups - put in the code to discard our own broadcasts (it won't work for multi-homed hosts though) - changed ELECTION_VERSION to 1 so we can be beaten by a NT 3.51 server by lowering the os level. - only do sync_browse_lists() if we are the master browser, otherwise we'll cause network overload - don't call tell_become_backup() as it appears to be badly broken, it should only be used when the machine being told has its MAINTAIN_LIST to to auto. Not calling it does no great harm anyway - fix a nasty bug where becomebackup was confused with reset browser! - make setbuffer() not get caught by the auto protototypes (This used to be commit cfbad9b08242962f41595273de08a7293fe432b1) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 87fe5fee78..d82d89f653 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -500,7 +500,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) num_good_receives++; - DEBUG(4,("%s received a packet of len %d from (%s) port %d\n", + DEBUG(5,("%s received a packet of len %d from (%s) port %d\n", timestring(),length,inet_ntoa(packet->ip),packet->port)); return(packet); @@ -521,7 +521,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; - DEBUG(4,("%s sending a packet of len %d to (%s) on port %d\n", + DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n", timestring(),len,inet_ntoa(ip),port)); ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, -- cgit From b9ae225b28f4707609e6436dad4be7ebdd7e181f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jun 1996 11:43:09 +0000 Subject: - added interface.c and removed all the references to myip, bcast_ip and Netmask, instead replacing them with calls to routines in interface.c - got rid of old MAXINT define - added code to ensure we only return one entry for each name in the ipc enum routines - added new_only option to add_netbios_entry() to prevent overwriting of important names - minor time handling fixup (This used to be commit 7ed71b73ae745da099072eee36fc2700d1d91407) --- source3/libsmb/nmblib.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d82d89f653..e1737cd41c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,10 +21,8 @@ */ #include "includes.h" -#include "localnet.h" #include "loadparm.h" -extern struct in_addr myip; extern int DEBUGLEVEL; int num_good_sends = 0; -- cgit From 7e3b4a1c0df1434eb3d02f93c736ce065f9898d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 04:38:24 +0000 Subject: got rid of a lot of redundent header files as we now globally generate prototypes automatically using "make proto". This is much less prone to error than the old method of manually adding prototypes (This used to be commit b551dc98f7cc194a5fc2e67a4ebae7fd67a01bbc) --- source3/libsmb/nmblib.c | 1 - source3/libsmb/smbencrypt.c | 1 - 2 files changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index e1737cd41c..3434f31a33 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "loadparm.h" extern int DEBUGLEVEL; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index be22fc50fc..c666e79547 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -22,7 +22,6 @@ */ #include "includes.h" -#include "loadparm.h" #include "des.h" #include "md4.h" -- cgit From 25b30c08dce8c04b7b98c02ac1de61d7aa76798f Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 17 Jul 1996 18:33:36 +0000 Subject: lots of changes to nmbd lkcl (This used to be commit 45d3b2644733333c657c48a69719fec72881f7df) --- source3/libsmb/namequery.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index d1b1ae7d3e..5480913001 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -173,6 +173,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, continue; } + debug_nmb_packet(p2); + _interpret_node_status(&nmb2->answers->rdata[0], master,rname); free_packet(p2); return(True); @@ -266,6 +268,8 @@ BOOL name_query(int fd,char *name,int name_type, continue; } + debug_nmb_packet(p2); + if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || nmb2->header.rcode || -- cgit From 3ffb30e8be5bcddca9d0489e1993085a4995c3af Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 1 Aug 1996 17:49:40 +0000 Subject: local_only NetServerEnum syncs can now be issued. bug spotted in nameservresp.c - arguments to test subnet the response is received on (same_net()) were the wrong way round (ccm@shentel.net) samba was adding WORKGROUP(1e) as a unique not a group name: fixed this bug in reply_name_status() and reply_name_query(): WINS entries weren't being looked up. name status reply adds local SELF entries to WINS SELF entries: some SELF entries are only added locally, while others are only added via WINS. name status needs to have both, combined. a sync will only occur when an ANN_LocalMasterAnnouncement is received, NOT an ANN_HostAnnouncement or an ANN_DomainAnnouncement. when samba is a member of a workgroup, it looks for (using a wins server) and announces to its domain master. NAME_QUERY_ANNOUNCE_HOST - yet another 'state' - has been created to do this: do the name query on the wins server and send the announce host to the answer to this query. jeremy @ vantive wrote the original code to do this, which used the name_query() function. i'm trying to avoid name_query: it times out and generally messes things up, but using queue_netbios_packet() and queue_netbios_pkt_wins() is... not intuitive? lkcl with help from jra (This used to be commit 6e932e4bae8b46e7ff4a55a75484bad78308336a) --- source3/libsmb/namequery.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 5480913001..21d3bd1e50 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -54,7 +54,7 @@ static void _interpret_node_status(char *p, char *master,char *rname) if ((p[0] & 0x60) == 0x00) strcat(flags,"B "); if ((p[0] & 0x60) == 0x20) strcat(flags,"P "); if ((p[0] & 0x60) == 0x40) strcat(flags,"M "); - if ((p[0] & 0x60) == 0x60) strcat(flags,"_ "); + if ((p[0] & 0x60) == 0x60) strcat(flags,"H "); if (p[0] & 0x10) strcat(flags," "); if (p[0] & 0x08) strcat(flags," "); if (p[0] & 0x04) strcat(flags," "); @@ -109,8 +109,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, nmb->header.opcode = 0; nmb->header.response = False; nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = 0; - nmb->header.nm_flags.recursion_desired = 1; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = False; nmb->header.nm_flags.trunc = False; nmb->header.nm_flags.authoritative = False; nmb->header.rcode = 0; @@ -152,6 +152,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, if ((p2=receive_packet(fd,NMB_PACKET,90))) { struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response) { /* its not for us - maybe deal with it later */ @@ -173,8 +175,6 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, continue; } - debug_nmb_packet(p2); - _interpret_node_status(&nmb2->answers->rdata[0], master,rname); free_packet(p2); return(True); @@ -257,6 +257,8 @@ BOOL name_query(int fd,char *name,int name_type, if ((p2=receive_packet(fd,NMB_PACKET,90))) { struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response) { /* its not for us - maybe deal with it later @@ -268,8 +270,6 @@ BOOL name_query(int fd,char *name,int name_type, continue; } - debug_nmb_packet(p2); - if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || nmb2->header.rcode || -- cgit From 396311075cc808278e6dd8469e3ac7eb7e7498c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Aug 1996 08:57:55 +0000 Subject: - sequent-ptx support from bressler@iftccu.ca.boeing.com (Rick Bressler) - machten support from Trevor Strohman (trev@figment.tenon.com) - added qinfo command to client as part of drag-and-drop printer support for win95 from David Chappell He also added the "printer driver" option - use sigblock() on more systems and use sigsetmask(0) instead of sigunblock() as its more portable. This beats a problem with zombies on heavilily loaded systems. - added internals.doc written by David Chappell into the source tree - get rid of PRINT_COMMAND options from local.h as they are no longer relevent - new kanji code from Fujita - don't set the recursion_available flag on queries in nmbd - fix a potential bug with pointer subtraction in printing.c - got rid of error_count code as the real fix (the EOF problem) is now in (This used to be commit aa6f8b04d125b5bc00f267abf72b800228aabf7d) --- source3/libsmb/namequery.c | 4 ++-- source3/libsmb/nmblib.c | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 21d3bd1e50..f1847e38ba 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -214,8 +214,8 @@ BOOL name_query(int fd,char *name,int name_type, nmb->header.opcode = 0; nmb->header.response = False; nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = 0; - nmb->header.nm_flags.recursion_desired = 1; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = True; nmb->header.nm_flags.trunc = False; nmb->header.nm_flags.authoritative = False; nmb->header.rcode = 0; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 3434f31a33..4113b34cab 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -609,7 +609,8 @@ static int build_nmb(char *buf,struct packet_struct *p) if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4; if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available) ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) ubuf[offset+3] |= 0x80; if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; ubuf[offset+3] |= (nmb->header.rcode & 0xF); -- cgit From 5a2f52b79e28530c454cb488a44588147640f061 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Oct 1996 14:09:22 +0000 Subject: - a huge pile of changes from Luke which implement the browse.conf stuff and also fix a pile of nmbd bugs. Unfortunately I found it very hard to disentangle the new features from the bug fixes so I am putting in the new code. I hope this is the last big pile of changes to the 1.9.16 series! (This used to be commit 20b6203dac4bbb43e4e7bea0b214496d76d679d9) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4113b34cab..ef5c9da434 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -65,7 +65,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j])); + DEBUG(4, ("%02x", (unsigned char)res->rdata[i+j])); } DEBUG(4, ("\n")); -- cgit From afd08462ad5ff6b3c4bf621e39c55853a608175e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Oct 1996 15:41:30 +0000 Subject: backout all the changes to nmbd. The 1.9.16 tree is now back to 1.9.16p2 as far as nmbd is concerned apart from a small change that fixes the announce type in two places. (This used to be commit 45e66a69d320024877c8b13f12b21bf895e04410) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ef5c9da434..4113b34cab 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -65,7 +65,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUG(4, ("%02x", (unsigned char)res->rdata[i+j])); + DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j])); } DEBUG(4, ("\n")); -- cgit From 38087ccb4071bfff29801026e2bf5c47565305b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Oct 1996 02:54:37 +0000 Subject: - use workgroup from smb.conf in smbclient - change debug level on clitar stuff - define MAP_FILE if not defined - ensure we never set authoritative on queries in nmbd - fake a positive response to SMBioctl, apparently this is needed for some WfWg printer drivers - deny file access for non-fcbopen queries when (access_allowed == AREAD && flags == O_RDWR) - add sys_waitpid() (This used to be commit 61e3116e573637d6b5a878eeb8db72831e3c5bd1) --- source3/libsmb/nmblib.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4113b34cab..c70311f997 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -395,7 +395,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; nmb->header.rcode = CVAL(inbuf,3) & 0xF; nmb->header.qdcount = RSVAL(inbuf,4); nmb->header.ancount = RSVAL(inbuf,6); @@ -606,7 +606,8 @@ static int build_nmb(char *buf,struct packet_struct *p) RSSVAL(ubuf,offset,nmb->header.name_trn_id); ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; if (nmb->header.response) ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative) ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.authoritative && + nmb->header.response) ubuf[offset+2] |= 0x4; if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; if (nmb->header.nm_flags.recursion_available && -- cgit From c71c1ff55f60f317039e3399f786e961dfac9e0b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Oct 1996 05:49:42 +0000 Subject: - set default printer driver string to "NULL" - fixed debug levels for name status parsing (This used to be commit f2c5f1eab1f3de7a9ae2b7ec4770a5c455dc04e4) --- source3/libsmb/namequery.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f1847e38ba..fc02add5b5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -31,9 +31,8 @@ interpret a node status response ****************************************************************************/ static void _interpret_node_status(char *p, char *master,char *rname) { - int level = (master||rname)?4:0; int numnames = CVAL(p,0); - DEBUG(level,("received %d names\n",numnames)); + DEBUG(1,("received %d names\n",numnames)); if (rname) *rname = 0; if (master) *master = 0; @@ -73,10 +72,10 @@ static void _interpret_node_status(char *p, char *master,char *rname) for (i = strlen( qname) ; --i >= 0 ; ) { if (!isprint(qname[i])) qname[i] = '.'; } - DEBUG(level,("\t%-15s <%02x> - %s\n",qname,type,flags)); + DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags)); p+=2; } - DEBUG(level,("num_good_sends=%d num_good_receives=%d\n", + DEBUG(1,("num_good_sends=%d num_good_receives=%d\n", IVAL(p,20),IVAL(p,24))); } -- cgit From 08d00eb68ee93eaead0f3bbaabc3d89540e0818e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 24 Oct 1996 00:09:08 +0000 Subject: - added support for TMPDIR env variable - fixed fault.c for linux 2.1 - put back in the FIND_SELF failing code - cleaned up casts in encryption (This used to be commit 3af04f1580b2569c0a4f2549bf6352c7a25afa0d) --- source3/libsmb/smbencrypt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index c666e79547..7ebb99ca1a 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -54,8 +54,8 @@ void D1(uchar *k, uchar *d, uchar *out) des_cblock deskey; str_to_key(k,(uchar *)deskey); - des_set_key(deskey,ks); - des_ecb_encrypt(d, out, ks, DES_DECRYPT); + des_set_key((des_cblock *)deskey,ks); + des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_DECRYPT); } void E1(uchar *k, uchar *d, uchar *out) @@ -64,8 +64,8 @@ void E1(uchar *k, uchar *d, uchar *out) des_cblock deskey; str_to_key(k,(uchar *)deskey); - des_set_key(deskey,ks); - des_ecb_encrypt(d, out, ks, DES_ENCRYPT); + des_set_key((des_cblock *)deskey,ks); + des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_ENCRYPT); } void E_P16(uchar *p14,uchar *p16) -- cgit From 9db489ea558598d1d0cd9b9d9f131ec02e3f7fc6 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 10 Dec 1996 18:02:08 +0000 Subject: Fixed for FreeBsd. jra@cygnus.com (This used to be commit 979acbc1096dda3f36f95eaed88de94931cfb164) --- source3/libsmb/smbencrypt.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 7ebb99ca1a..ee2b17ae5d 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -54,7 +54,11 @@ void D1(uchar *k, uchar *d, uchar *out) des_cblock deskey; str_to_key(k,(uchar *)deskey); +#ifdef __FreeBSD__ + des_set_key(&deskey,ks); +#else /* __FreeBSD__ */ des_set_key((des_cblock *)deskey,ks); +#endif /* __FreeBsd */ des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_DECRYPT); } @@ -64,7 +68,11 @@ void E1(uchar *k, uchar *d, uchar *out) des_cblock deskey; str_to_key(k,(uchar *)deskey); +#ifdef __FreeBSD__ + des_set_key(&deskey,ks); +#else /* __FreeBsd__ */ des_set_key((des_cblock *)deskey,ks); +#endif /* __FreeBsd__ */ des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_ENCRYPT); } -- cgit From ab0bdc6682815fe9878afdda6cc8119798fa2770 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 7 Mar 1997 17:28:41 +0000 Subject: Added better debug for what kind of netbios packet we got. jra@cygnus.com (This used to be commit 4563d978feaed37aab78e62461026a79dbc50249) --- source3/libsmb/nmblib.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index c70311f997..a0f93331d9 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -30,6 +30,34 @@ extern pstring scope; extern pstring myname; extern struct in_addr ipzero; +static struct opcode_names { + const char *nmb_opcode_name; + int opcode; +} nmb_header_opcode_names[] = { + { "Query", 0 }, + {"Registration", 5 }, + {"Release", 6 }, + {"WACK", 7 }, + {"refresh", 8 }, + {0, -1 } +}; + +/**************************************************************************** + * Lookup a nmb opcode name. + ****************************************************************************/ + +const char *lookup_opcode_name( int opcode ) +{ + struct opcode_names *op_namep; + int i; + + for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { + op_namep = &nmb_header_opcode_names[i]; + if(opcode == op_namep->opcode) + return op_namep->nmb_opcode_name; + } + return ""; +} /**************************************************************************** print out a res_rec structure @@ -79,9 +107,11 @@ void debug_nmb_packet(struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - DEBUG(4,("nmb packet from %s header: id=%d opcode=%d response=%s\n", + DEBUG(4,("nmb packet from %s header: id=%d opcode=%s(%d) response=%s\n", inet_ntoa(p->ip), - nmb->header.name_trn_id,nmb->header.opcode,BOOLSTR(nmb->header.response))); + nmb->header.name_trn_id, + lookup_opcode_name(nmb->header.opcode), + nmb->header.opcode,BOOLSTR(nmb->header.response))); DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", BOOLSTR(nmb->header.nm_flags.bcast), BOOLSTR(nmb->header.nm_flags.recursion_available), -- cgit From 0f1f0ceb9519368188f695e18e2341ccfd1b2d15 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 8 May 1997 01:14:17 +0000 Subject: 'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6) --- source3/libsmb/namequery.c | 2 +- source3/libsmb/nmblib.c | 2 +- source3/libsmb/smbencrypt.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index fc02add5b5..55f70be122 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. name query routines - Copyright (C) Andrew Tridgell 1994-1995 + Copyright (C) Andrew Tridgell 1994-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index a0f93331d9..89a5cf9534 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. NBT netbios library routines - Copyright (C) Andrew Tridgell 1994-1995 + Copyright (C) Andrew Tridgell 1994-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ee2b17ae5d..8bb21cfed2 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -3,7 +3,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1995 + Copyright (C) Andrew Tridgell 1992-1997 Modified by Jeremy Allison 1995. This program is free software; you can redistribute it and/or modify -- cgit From 3ab97ebe6db1a5a4a0573c7c8482c94876bbce9a Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 30 May 1997 20:40:48 +0000 Subject: charcnv.c: Fixed silly bugs detected on IRIX. client.c: Fixed silly bugs detected on IRIX. namedbname.c: Stopped 1d names from being registered in WINS db. namedbsubnet.c: Only register 1e names on broadcast subnet. nameelect.c: Changed add_my_name entries. Forced host announces if we have less than 10 servers listed. Fixed registering 1b domain name issues. namepacket.c: Added error message when dgram discarded. nameserv.c: Added notion of 'direct' names that are not registered on the network. Needed to get around bugs in earlier nmbd handling of DOMAIN(1b) names. nameservreply.c:Tidied up debug message. nameservresp.c: Added response_name_query_domain() code. Deals with re-registering DOMAIN(1b) name. nmbd.c: Fixed silly bugs detected on IRIX. nmblib.c: Added paranoia debugs. proto.h: Updated remove_name_entry(), add_my_name_entry(). server.c: Fixed silly bugs detected on IRIX. trans2.c: Fixed silly bugs detected on IRIX. uid.c: Fixed silly bugs detected on IRIX. version.h: Updated to alpha3. Jeremy (jallison@whistle.com). (This used to be commit f08222bd8b86a061c52d22015f946a4737eb47fd) --- source3/libsmb/nmblib.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 89a5cf9534..bc967bdacb 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -418,6 +418,9 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) /* parse the header */ nmb->header.name_trn_id = RSVAL(inbuf,0); + + DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); @@ -521,6 +524,8 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) break; } if (!ok) { + DEBUG(10,("parse_nmb: discarding packet id = %d\n", + packet->packet.nmb.header.name_trn_id)); free(packet); return(NULL); } -- cgit From 58ec10049b8029de82e70ba10559e143a1b16707 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Sep 1997 16:19:49 +0000 Subject: This is a written from scratch DES implementation. I couldn't find a GPLd implementation so I decided to write one. This version only does DES ecb encryption and isn't very general, so it may in fact be exempt from ITAR regulations. ITAR regulations do not prohibit the distribution of code that can be used for authentication purposes only. This code has no decrypt function so it would be useless for a normal encryption application and thus may be ITAR exempt. It is also very slow, but we don't need it to be fast. It is a literal implementation from the standard and treats each bit as one byte to make the code easy to write. (This used to be commit c2bc073a878179dd56db97c66dc957d42fe0b81b) --- source3/libsmb/smbdes.c | 290 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 source3/libsmb/smbdes.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c new file mode 100644 index 0000000000..e207e58c24 --- /dev/null +++ b/source3/libsmb/smbdes.c @@ -0,0 +1,290 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + a implementation of DES designed for use in the SMB authentication protocol + Copyright (C) Andrew Tridgell 1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +/* NOTE: This code makes no attempt to be fast! In fact, it is a very + slow DES implementation */ + +static int perm1[56] = {57, 49, 41, 33, 25, 17, 9, + 1, 58, 50, 42, 34, 26, 18, + 10, 2, 59, 51, 43, 35, 27, + 19, 11, 3, 60, 52, 44, 36, + 63, 55, 47, 39, 31, 23, 15, + 7, 62, 54, 46, 38, 30, 22, + 14, 6, 61, 53, 45, 37, 29, + 21, 13, 5, 28, 20, 12, 4}; + +static int perm2[48] = {14, 17, 11, 24, 1, 5, + 3, 28, 15, 6, 21, 10, + 23, 19, 12, 4, 26, 8, + 16, 7, 27, 20, 13, 2, + 41, 52, 31, 37, 47, 55, + 30, 40, 51, 45, 33, 48, + 44, 49, 39, 56, 34, 53, + 46, 42, 50, 36, 29, 32}; + +static int perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, + 60, 52, 44, 36, 28, 20, 12, 4, + 62, 54, 46, 38, 30, 22, 14, 6, + 64, 56, 48, 40, 32, 24, 16, 8, + 57, 49, 41, 33, 25, 17, 9, 1, + 59, 51, 43, 35, 27, 19, 11, 3, + 61, 53, 45, 37, 29, 21, 13, 5, + 63, 55, 47, 39, 31, 23, 15, 7}; + +static int perm4[48] = { 32, 1, 2, 3, 4, 5, + 4, 5, 6, 7, 8, 9, + 8, 9, 10, 11, 12, 13, + 12, 13, 14, 15, 16, 17, + 16, 17, 18, 19, 20, 21, + 20, 21, 22, 23, 24, 25, + 24, 25, 26, 27, 28, 29, + 28, 29, 30, 31, 32, 1}; + +static int perm5[32] = { 16, 7, 20, 21, + 29, 12, 28, 17, + 1, 15, 23, 26, + 5, 18, 31, 10, + 2, 8, 24, 14, + 32, 27, 3, 9, + 19, 13, 30, 6, + 22, 11, 4, 25}; + + +static int perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, + 39, 7, 47, 15, 55, 23, 63, 31, + 38, 6, 46, 14, 54, 22, 62, 30, + 37, 5, 45, 13, 53, 21, 61, 29, + 36, 4, 44, 12, 52, 20, 60, 28, + 35, 3, 43, 11, 51, 19, 59, 27, + 34, 2, 42, 10, 50, 18, 58, 26, + 33, 1, 41, 9, 49, 17, 57, 25}; + + +static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; + +static int sbox[8][4][16] = { + {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, + {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, + {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 1}}, + + {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, + {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, + {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, + {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, + + {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, + {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, + {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, + {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, + + {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, + {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, + {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, + {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, + + {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, + {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, + {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, + {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, + + {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, + {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, + {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, + {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, + + {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, + {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, + {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, + {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, + + {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, + {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, + {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, + {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; + + +static void permute(char *out, char *in, int *p, int n) +{ + int i; + for (i=0;i>1; + key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); + key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); + key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); + key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); + key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); + key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); + key[7] = str[6]&0x7F; + for (i=0;i<8;i++) { + key[i] = (key[i]<<1); + } +} + + +/* this is the entry point to the DES routine. The key is 56 bits (no parity) */ +void smbdes(unsigned char *out, unsigned char *in, unsigned char *key) +{ + int i, j; + char outb[64]; + char inb[64]; + char keyb[64]; + unsigned char key2[8]; + + str_to_key(key, key2); + + for (i=0;i<64;i++) { + inb[i] = (in[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + keyb[i] = (key2[i/8] & (1<<(7-(i%8)))) ? 1 : 0; + outb[i] = 0; + } + + for (i=0;i<8;i++) { + int count = 0; + for (j=0;j<7;j++) + count += keyb[i*8 + j]; + if ((count&1) == 0) + keyb[i*8 + 7] = 1; + else + keyb[i*8 + 7] = 0; + } + + dodes(outb, inb, keyb); + + for (i=0;i<64;i++) { + if (outb[i]) + out[i/8] |= (1<<(7-(i%8))); + else + out[i/8] &= ~(1<<(7-(i%8))); + } +} + -- cgit From 33a003de4056532be0c9a199d4857b9da1b18034 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Sep 1997 16:37:18 +0000 Subject: This commit does 3 main things: 1) put the encryption code in by default, with no #ifdef. It is still disabled by default so you need to add "encrypt passwords = yes" in smb.conf but at least all binaries will have it. 2) cleanup the kanji code so it compiles with no warnings 3) get rid of lots of uses of ugly non-portable C code. The main offender being things like "register" but also remove uses of the "const" keyword as there are compilers out there that don't support it and even those that do often complain about its usage. Users don't like warnings :-( There is still some work to do. We need to replace the md4 code with our own implementation. The current code (from rfc1186) is PD but is not very portable. The new RFC (rfc1320) is more portable but adds copyright restrictions. I'll do a from-scratch MD4 soon. We also need to test that what I've implemented is portable. It should be, but I'm too tired right now to test it on anything other than intel linux. (This used to be commit db917c62c14315afe6f0745a8097c1bca25cbf07) --- source3/libsmb/nmblib.c | 6 ++-- source3/libsmb/smbencrypt.c | 73 +++++++-------------------------------------- 2 files changed, 13 insertions(+), 66 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index bc967bdacb..456a8218d8 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -31,8 +31,8 @@ extern pstring myname; extern struct in_addr ipzero; static struct opcode_names { - const char *nmb_opcode_name; - int opcode; + char *nmb_opcode_name; + int opcode; } nmb_header_opcode_names[] = { { "Query", 0 }, {"Registration", 5 }, @@ -46,7 +46,7 @@ static struct opcode_names { * Lookup a nmb opcode name. ****************************************************************************/ -const char *lookup_opcode_name( int opcode ) +char *lookup_opcode_name( int opcode ) { struct opcode_names *op_namep; int i; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 8bb21cfed2..b2ae363952 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -1,4 +1,3 @@ -#ifdef SMB_PASSWD /* Unix SMB/Netbios implementation. Version 1.9. @@ -22,81 +21,32 @@ */ #include "includes.h" -#include "des.h" #include "md4.h" extern int DEBUGLEVEL; #include "byteorder.h" -void str_to_key(uchar *str,uchar *key) -{ - void des_set_odd_parity(des_cblock *); - int i; - - key[0] = str[0]>>1; - key[1] = ((str[0]&0x01)<<6) | (str[1]>>2); - key[2] = ((str[1]&0x03)<<5) | (str[2]>>3); - key[3] = ((str[2]&0x07)<<4) | (str[3]>>4); - key[4] = ((str[3]&0x0F)<<3) | (str[4]>>5); - key[5] = ((str[4]&0x1F)<<2) | (str[5]>>6); - key[6] = ((str[5]&0x3F)<<1) | (str[6]>>7); - key[7] = str[6]&0x7F; - for (i=0;i<8;i++) { - key[i] = (key[i]<<1); - } - des_set_odd_parity((des_cblock *)key); -} - -void D1(uchar *k, uchar *d, uchar *out) -{ - des_key_schedule ks; - des_cblock deskey; - - str_to_key(k,(uchar *)deskey); -#ifdef __FreeBSD__ - des_set_key(&deskey,ks); -#else /* __FreeBSD__ */ - des_set_key((des_cblock *)deskey,ks); -#endif /* __FreeBsd */ - des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_DECRYPT); -} - void E1(uchar *k, uchar *d, uchar *out) { - des_key_schedule ks; - des_cblock deskey; - - str_to_key(k,(uchar *)deskey); -#ifdef __FreeBSD__ - des_set_key(&deskey,ks); -#else /* __FreeBsd__ */ - des_set_key((des_cblock *)deskey,ks); -#endif /* __FreeBsd__ */ - des_ecb_encrypt((des_cblock *)d,(des_cblock *)out, ks, DES_ENCRYPT); + smbdes(out, d, k); } void E_P16(uchar *p14,uchar *p16) { - uchar sp7[7]; - /* the following constant makes us compatible with other - implementations. Note that publishing this constant does not reduce the - security of the encryption mechanism */ - uchar sp8[] = {0xAA,0xD3,0xB4,0x35,0xB5,0x14,0x4,0xEE}; - uchar x[8]; - - memset(sp7,'\0',7); - - D1(sp7, sp8, x); - E1(p14, x, p16); - E1(p14+7, x, p16+8); + /* the following constant makes us compatible with other + implementations. Note that publishing this constant does not reduce the + security of the encryption mechanism */ + uchar sp8[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + E1(p14, sp8, p16); + E1(p14+7, sp8, p16+8); } void E_P24(uchar *p21, uchar *c8, uchar *p24) { - E1(p21, c8, p24); - E1(p21+7, c8, p24+8); - E1(p21+14, c8, p24+16); + E1(p21, c8, p24); + E1(p21+7, c8, p24+8); + E1(p21+14, c8, p24+16); } @@ -191,6 +141,3 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) E_P24(p21, c8, p24); } -#else - void smbencrypt_dummy(void){} -#endif -- cgit From ddb2ce9d8100bd2c0475032b99869624db36304c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Sep 1997 02:49:38 +0000 Subject: rewrote md4.c from scratch. This implementation should be portable and doesn't have any worries about RSA copyright. (This used to be commit a1569971663f01c245c145b18290d9dba965dc36) --- source3/libsmb/smbencrypt.c | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b2ae363952..2738103692 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -21,7 +21,6 @@ */ #include "includes.h" -#include "md4.h" extern int DEBUGLEVEL; @@ -105,28 +104,20 @@ static int _my_mbstowcs(int16 *dst, uchar *src, int len) void E_md4hash(uchar *passwd, uchar *p16) { - int i, len; + int len; int16 wpwd[129]; - MDstruct MD; - + /* Password cannot be longer than 128 characters */ len = strlen((char *)passwd); if(len > 128) len = 128; /* Password must be converted to NT unicode */ - _my_mbstowcs( wpwd, passwd, len); + _my_mbstowcs(wpwd, passwd, len); wpwd[len] = 0; /* Ensure string is null terminated */ /* Calculate length in bytes */ len = _my_wcslen(wpwd) * sizeof(int16); - - MDbegin(&MD); - for(i = 0; i + 64 <= len; i += 64) - MDupdate(&MD,wpwd + (i/2), 512); - MDupdate(&MD,wpwd + (i/2),(len-i)*8); - SIVAL(p16,0,MD.buffer[0]); - SIVAL(p16,4,MD.buffer[1]); - SIVAL(p16,8,MD.buffer[2]); - SIVAL(p16,12,MD.buffer[3]); + + mdfour(p16, (unsigned char *)wpwd, len); } /* Does the NT MD4 hash then des encryption. */ -- cgit From 72b02acd7e2c24efcff2faffb2555d70378b01b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Sep 1997 03:53:54 +0000 Subject: bug fix in the new des code. I had one of the sbox[] constants wrong, which interestingly gave a 20% chance of the whole algorithm failing. (This used to be commit 9a42f88a0963d006e8bf091775a3f55f6c6b4f77) --- source3/libsmb/smbdes.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index e207e58c24..135df7fbb4 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -85,44 +85,43 @@ static int sbox[8][4][16] = { {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, - {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 1}}, - + {15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13}}, + {{15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10}, {3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5}, {0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15}, {13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9}}, - + {{10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8}, {13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1}, {13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7}, {1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12}}, - + {{7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15}, {13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9}, {10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4}, {3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14}}, - + {{2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9}, {14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6}, {4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14}, {11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3}}, - + {{12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11}, {10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8}, {9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6}, {4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13}}, - + {{4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1}, {13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6}, {1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2}, {6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12}}, - + {{13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7}, {1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2}, {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; - static void permute(char *out, char *in, int *p, int n) { int i; @@ -230,6 +229,7 @@ static void dodes(char *out, char *in, char *key) } concat(rl, r, l, 32, 32); + permute(out, rl, perm6, 64); } @@ -254,7 +254,7 @@ static void str_to_key(unsigned char *str,unsigned char *key) /* this is the entry point to the DES routine. The key is 56 bits (no parity) */ void smbdes(unsigned char *out, unsigned char *in, unsigned char *key) { - int i, j; + int i; char outb[64]; char inb[64]; char keyb[64]; @@ -268,23 +268,15 @@ void smbdes(unsigned char *out, unsigned char *in, unsigned char *key) outb[i] = 0; } + dodes(outb, inb, keyb); + for (i=0;i<8;i++) { - int count = 0; - for (j=0;j<7;j++) - count += keyb[i*8 + j]; - if ((count&1) == 0) - keyb[i*8 + 7] = 1; - else - keyb[i*8 + 7] = 0; + out[i] = 0; } - dodes(outb, inb, keyb); - for (i=0;i<64;i++) { if (outb[i]) out[i/8] |= (1<<(7-(i%8))); - else - out[i/8] &= ~(1<<(7-(i%8))); } } -- cgit From 57c2578cb2b7e02acc6c04d07adc11a77c40aa9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Sep 1997 04:41:16 +0000 Subject: - change generate_challenge() to use md4 instead of des - move routines about a bit between smbencrypt.c and smbdes.c. Ensure that there is no entry point for normal DES operation - add the following comment: This code is NOT a complete DES implementation. It implements only the minimum necessary for SMB authentication, as used by all SMB products (including every copy of Microsoft Windows95 ever sold) In particular, it can only do a unchained forward DES pass. This means it is not possible to use this code for encryption/decryption of data, instead it is only useful as a "hash" algorithm. There is no entry point into this code that allows normal DES operation. I believe this means that this code does not come under ITAR regulations but this is NOT a legal opinion. If you are concerned about the applicability of ITAR regulations to this code then you should confirm it for yourself (and maybe let me know if you come up with a different answer to the one above) (This used to be commit 35b92e725f351c9a9f2846a6b55f71c234f187c7) --- source3/libsmb/smbdes.c | 52 +++++++++++++++++++++++++++++++++++++++------ source3/libsmb/smbencrypt.c | 23 -------------------- 2 files changed, 45 insertions(+), 30 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 135df7fbb4..1c38612b73 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -1,7 +1,10 @@ /* Unix SMB/Netbios implementation. Version 1.9. - a implementation of DES designed for use in the SMB authentication protocol + + a partial implementation of DES designed for use in the + SMB authentication protocol + Copyright (C) Andrew Tridgell 1997 This program is free software; you can redistribute it and/or modify @@ -20,8 +23,29 @@ */ -/* NOTE: This code makes no attempt to be fast! In fact, it is a very - slow DES implementation */ +/* NOTES: + + This code makes no attempt to be fast! In fact, it is a very + slow implementation + + This code is NOT a complete DES implementation. It implements only + the minimum necessary for SMB authentication, as used by all SMB + products (including every copy of Microsoft Windows95 ever sold) + + In particular, it can only do a unchained forward DES pass. This + means it is not possible to use this code for encryption/decryption + of data, instead it is only useful as a "hash" algorithm. + + There is no entry point into this code that allows normal DES operation. + + I believe this means that this code does not come under ITAR + regulations but this is NOT a legal opinion. If you are concerned + about the applicability of ITAR regulations to this code then you + should confirm it for yourself (and maybe let me know if you come + up with a different answer to the one above) +*/ + + static int perm1[56] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, @@ -154,7 +178,7 @@ static void xor(char *out, char *in1, char *in2, int n) out[i] = in1[i] ^ in2[i]; } -static void dodes(char *out, char *in, char *key) +static void dohash(char *out, char *in, char *key) { int i, j, k; char pk1[56]; @@ -251,8 +275,7 @@ static void str_to_key(unsigned char *str,unsigned char *key) } -/* this is the entry point to the DES routine. The key is 56 bits (no parity) */ -void smbdes(unsigned char *out, unsigned char *in, unsigned char *key) +static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) { int i; char outb[64]; @@ -268,7 +291,7 @@ void smbdes(unsigned char *out, unsigned char *in, unsigned char *key) outb[i] = 0; } - dodes(outb, inb, keyb); + dohash(outb, inb, keyb); for (i=0;i<8;i++) { out[i] = 0; @@ -280,3 +303,18 @@ void smbdes(unsigned char *out, unsigned char *in, unsigned char *key) } } +void E_P16(unsigned char *p14,unsigned char *p16) +{ + unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; + smbhash(p16, sp8, p14); + smbhash(p16+8, sp8, p14+7); +} + +void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) +{ + smbhash(p24, c8, p21); + smbhash(p24+8, c8, p21+7); + smbhash(p24+16, c8, p21+14); +} + + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 2738103692..27172fd413 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -26,29 +26,6 @@ extern int DEBUGLEVEL; #include "byteorder.h" -void E1(uchar *k, uchar *d, uchar *out) -{ - smbdes(out, d, k); -} - -void E_P16(uchar *p14,uchar *p16) -{ - /* the following constant makes us compatible with other - implementations. Note that publishing this constant does not reduce the - security of the encryption mechanism */ - uchar sp8[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - E1(p14, sp8, p16); - E1(p14+7, sp8, p16+8); -} - -void E_P24(uchar *p21, uchar *c8, uchar *p24) -{ - E1(p21, c8, p24); - E1(p21+7, c8, p24+8); - E1(p21+14, c8, p24+16); -} - - /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of -- cgit From cef59090bb2fd3f8a9efd1a453cb90264b891d58 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 18:55:29 +0000 Subject: Adding Andrews buffer overflow fixes into the main branch. Jeremy (jallison@whistle.com) (This used to be commit e7eb1f044d3101679dc7a118820ea5efe0cd837c) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 456a8218d8..48f988de2a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -616,10 +616,10 @@ static int build_dgram(char *buf,struct packet_struct *p) ******************************************************************/ void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) { - strcpy(n->name,name); + fstrcpy(n->name,name); strupper(n->name); n->name_type = type; - strcpy(n->scope,this_scope); + fstrcpy(n->scope,this_scope); } -- cgit From f726e5517d5348537e31cf3747344d0abd7028c5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 9 Oct 1997 10:01:12 +0000 Subject: an implementation of the NT domain credentials protocol (This used to be commit dd6ac9b1eea3b0ace27fbd014b5ad4625c1fdf94) --- source3/libsmb/credentials.c | 101 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 source3/libsmb/credentials.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c new file mode 100644 index 0000000000..efa0d83ec2 --- /dev/null +++ b/source3/libsmb/credentials.c @@ -0,0 +1,101 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + code to manipulate domain credentials + Copyright (C) Andrew Tridgell 1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +/**************************************************************************** + setup the session key. +Input: 8 byte challenge block + 8 byte server challenge block + 16 byte md4 encrypted password +Output: + 8 byte session key +****************************************************************************/ +void cred_session_key(char *challenge, char *srv_challenge, char *pass, + char *session_key) +{ + uint32 sum[2]; + char sum2[8]; + char buf[8]; + + sum[0] = IVAL(challenge, 0) + IVAL(srv_challenge, 0); + sum[1] = IVAL(challenge, 4) + IVAL(srv_challenge, 4); + + SIVAL(sum2,0,sum[0]); + SIVAL(sum2,4,sum[1]); + + E1(pass,sum2,buf); + E1(pass+9,buf,session_key); +} + + +/**************************************************************************** +create a credential + +Input: + 8 byte sesssion key + 8 byte stored credential + 4 byte timestamp + +Output: + 8 byte credential +****************************************************************************/ +void cred_create(char *session_key, char *stored_cred, uint32 time, + char *cred) +{ + char key2[7]; + char buf[8]; + char timecred[8]; + + memcpy(timecred, stored_cred, 8); + SIVAL(timecred, 0, IVAL(stored_cred, 0) + time); + + E1(session_key, timecred, buf); + memset(key2, 0, 7); + key2[0] = session_key[7]; + E1(key2, buf, cred); +} + + +/**************************************************************************** + check a supplied credential + +Input: + 8 byte received credential + 8 byte sesssion key + 8 byte stored credential + 4 byte timestamp + +Output: + returns 1 if computed credential matches received credential + returns 0 otherwise +****************************************************************************/ +int cred_assert(char *cred, char *session_key, char *stored_cred, + uint32 time) +{ + char cred2[8]; + + cred_create(session_key, stored_cred, time, cred2); + + return memcmp(cred, cred2, 8) == 0; +} + -- cgit From ad54a5671405374b6308929154c6922bc6a7d0d7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 9 Oct 1997 14:40:46 +0000 Subject: credentials.c: use UTIME structure (defined and commented in smb.h to be time, secs, since 01jan1970) pipes.c: another sub-function. util.c: added char *unistr2(uint16 *buff) function. same as unistr except it takes uint16* instead of char*. smbparse.c smb.h: more structure sorting. proto.h: the usual. (This used to be commit 72a86f514f0c92b69499718e63f5dd73ebece56e) --- source3/libsmb/credentials.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index efa0d83ec2..4c81177fb2 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -59,7 +59,7 @@ Input: Output: 8 byte credential ****************************************************************************/ -void cred_create(char *session_key, char *stored_cred, uint32 time, +void cred_create(char *session_key, char *stored_cred, UTIME timestamp, char *cred) { char key2[7]; @@ -67,7 +67,7 @@ void cred_create(char *session_key, char *stored_cred, uint32 time, char timecred[8]; memcpy(timecred, stored_cred, 8); - SIVAL(timecred, 0, IVAL(stored_cred, 0) + time); + SIVAL(timecred, 0, IVAL(stored_cred, 0) + timestamp.time); E1(session_key, timecred, buf); memset(key2, 0, 7); @@ -90,11 +90,11 @@ Output: returns 0 otherwise ****************************************************************************/ int cred_assert(char *cred, char *session_key, char *stored_cred, - uint32 time) + NTTIME timestamp) { char cred2[8]; - cred_create(session_key, stored_cred, time, cred2); + cred_create(session_key, stored_cred, timestamp, cred2); return memcmp(cred, cred2, 8) == 0; } -- cgit From c5e739febe5ab3bcc5d147fe791c788ec72531a3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 10 Oct 1997 14:48:05 +0000 Subject: Makefile: added credentials.c to smbd credentials.c: using credential structures instead of char* password.c uid.c server.c: added sid and attr to user_struct. smbdes.c: smbhash and str_to_key make public instead of private. pipes.c smb.h: lsa structures, sub-functions. proto.h: usual. (This used to be commit 87a0a944855a673d693d934e446bdc231b1c7f02) --- source3/libsmb/credentials.c | 30 +++++++++++++++--------------- source3/libsmb/smbdes.c | 4 ++-- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 4c81177fb2..eb1039ddb0 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -30,21 +30,21 @@ Input: 8 byte challenge block Output: 8 byte session key ****************************************************************************/ -void cred_session_key(char *challenge, char *srv_challenge, char *pass, +void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, char *session_key) { uint32 sum[2]; char sum2[8]; char buf[8]; - sum[0] = IVAL(challenge, 0) + IVAL(srv_challenge, 0); - sum[1] = IVAL(challenge, 4) + IVAL(srv_challenge, 4); + sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); + sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - E1(pass,sum2,buf); - E1(pass+9,buf,session_key); + smbhash(pass, sum2, buf); + smbhash(pass+9,buf,session_key); } @@ -59,20 +59,20 @@ Input: Output: 8 byte credential ****************************************************************************/ -void cred_create(char *session_key, char *stored_cred, UTIME timestamp, - char *cred) +void cred_create(char *session_key, DOM_CHAL *stored_cred, UTIME timestamp, + DOM_CHAL *cred) { char key2[7]; char buf[8]; char timecred[8]; - memcpy(timecred, stored_cred, 8); + memcpy(timecred, stored_cred->data, 8); SIVAL(timecred, 0, IVAL(stored_cred, 0) + timestamp.time); - E1(session_key, timecred, buf); + smbhash(session_key, timecred, buf); memset(key2, 0, 7); key2[0] = session_key[7]; - E1(key2, buf, cred); + smbhash(key2, buf, cred->data); } @@ -89,13 +89,13 @@ Output: returns 1 if computed credential matches received credential returns 0 otherwise ****************************************************************************/ -int cred_assert(char *cred, char *session_key, char *stored_cred, - NTTIME timestamp) +int cred_assert(DOM_CHAL *cred, char *session_key, DOM_CHAL *stored_cred, + UTIME timestamp) { - char cred2[8]; + DOM_CHAL cred2; - cred_create(session_key, stored_cred, timestamp, cred2); + cred_create(session_key, stored_cred, timestamp, &cred2); - return memcmp(cred, cred2, 8) == 0; + return memcmp(cred->data, cred2.data, 8) == 0; } diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 1c38612b73..b62a160418 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -257,7 +257,7 @@ static void dohash(char *out, char *in, char *key) permute(out, rl, perm6, 64); } -static void str_to_key(unsigned char *str,unsigned char *key) +void str_to_key(unsigned char *str,unsigned char *key) { int i; @@ -275,7 +275,7 @@ static void str_to_key(unsigned char *str,unsigned char *key) } -static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) +void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) { int i; char outb[64]; -- cgit From 2259e56a947104b19a1196154af4e43ab15e4b7c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 13 Oct 1997 12:21:56 +0000 Subject: byteorder.h : debugging output wasn't (still isn't) perfect. credentials.c lsaparse.c smbparse.c : added DEBUG strings. pipes.c : lost some changes, to do with setup of RPC headers. arg. (This used to be commit 9fdd697d17b68293bb95fd68f44c24f0f5b97f5f) --- source3/libsmb/credentials.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index eb1039ddb0..ce7159f7ff 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -21,7 +21,7 @@ #include "includes.h" - +extern int DEBUGLEVEL; /**************************************************************************** setup the session key. Input: 8 byte challenge block @@ -37,14 +37,24 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, char sum2[8]; char buf[8]; + DEBUG(4,("cred_session_key\n")); + + DEBUG(5,(" clnt_chal: %lx %lx srv_chal: %lx %lx\n", + + IVAL(clnt_chal->data, 0), IVAL(clnt_chal->data, 4), + IVAL(srv_chal->data, 0), IVAL(srv_chal->data, 4))); + sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - smbhash(pass, sum2, buf); - smbhash(pass+9,buf,session_key); + smbhash(pass , sum2, buf); + smbhash(pass+9, buf , session_key); + + DEBUG(5,(" session_key: ")); + dump_data(5, session_key, 16); } -- cgit From 2225fe13766ae07a44e27cc4a1fb665cf5afc804 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 13 Oct 1997 13:35:37 +0000 Subject: debug info added (This used to be commit a3f96555b47265b8cd4d1f735af58375e2591d56) --- source3/libsmb/credentials.c | 43 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index ce7159f7ff..3af182c5db 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -37,13 +37,6 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, char sum2[8]; char buf[8]; - DEBUG(4,("cred_session_key\n")); - - DEBUG(5,(" clnt_chal: %lx %lx srv_chal: %lx %lx\n", - - IVAL(clnt_chal->data, 0), IVAL(clnt_chal->data, 4), - IVAL(srv_chal->data, 0), IVAL(srv_chal->data, 4))); - sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); @@ -53,6 +46,18 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, smbhash(pass , sum2, buf); smbhash(pass+9, buf , session_key); + /* debug output*/ + DEBUG(4,("cred_session_key\n")); + + DEBUG(5,(" clnt_chal: ")); + dump_data(5, clnt_chal->data, 8); + + DEBUG(5,(" srv_chal: ")); + dump_data(5, srv_chal->data, 8); + + DEBUG(5,(" clnt_chal+srv_chal: ")); + dump_data(5, sum2, 8); + DEBUG(5,(" session_key: ")); dump_data(5, session_key, 16); } @@ -83,6 +88,21 @@ void cred_create(char *session_key, DOM_CHAL *stored_cred, UTIME timestamp, memset(key2, 0, 7); key2[0] = session_key[7]; smbhash(key2, buf, cred->data); + + /* debug output*/ + DEBUG(4,("cred_create\n")); + + DEBUG(5,(" session_key: ")); + dump_data(5, session_key, 16); + + DEBUG(5,(" stored_cred: ")); + dump_data(5, stored_cred->data, 8); + + DEBUG(5,(" timecred: ")); + dump_data(5, timecred, 8); + + DEBUG(5,(" cred: ")); + dump_data(5, cred->data, 8); } @@ -106,6 +126,15 @@ int cred_assert(DOM_CHAL *cred, char *session_key, DOM_CHAL *stored_cred, cred_create(session_key, stored_cred, timestamp, &cred2); + /* debug output*/ + DEBUG(4,("cred_assert\n")); + + DEBUG(5,(" challenge: ")); + dump_data(5, cred->data, 16); + + DEBUG(5,(" calculated: ")); + dump_data(5, cred2.data, 8); + return memcmp(cred->data, cred2.data, 8) == 0; } -- cgit From fcc885e0169ac6418cca9e6030863a225dee6adf Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 13 Oct 1997 14:19:17 +0000 Subject: debugging... no idea what i'm doing. (This used to be commit d7a9a02e0a9e1e791810c24bcfcbd39a6bd7dac5) --- source3/libsmb/credentials.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 3af182c5db..3355ab1704 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -130,7 +130,7 @@ int cred_assert(DOM_CHAL *cred, char *session_key, DOM_CHAL *stored_cred, DEBUG(4,("cred_assert\n")); DEBUG(5,(" challenge: ")); - dump_data(5, cred->data, 16); + dump_data(5, cred->data, 8); DEBUG(5,(" calculated: ")); dump_data(5, cred2.data, 8); -- cgit From 6084046eede3652d7cabafb33227e940f00f92a8 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 14 Oct 1997 17:01:43 +0000 Subject: credentials, query info reply. (This used to be commit 9b095887df204393090d7da9a47508685ddd5163) --- source3/libsmb/credentials.c | 68 +++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 3355ab1704..07816bc0cf 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -31,11 +31,12 @@ Output: 8 byte session key ****************************************************************************/ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, - char *session_key) + uint32 session_key[2]) { uint32 sum[2]; char sum2[8]; char buf[8]; + char netsesskey[8]; sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); @@ -44,22 +45,18 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, SIVAL(sum2,4,sum[1]); smbhash(pass , sum2, buf); - smbhash(pass+9, buf , session_key); + smbhash(pass+9, buf , netsesskey); - /* debug output*/ - DEBUG(4,("cred_session_key\n")); - - DEBUG(5,(" clnt_chal: ")); - dump_data(5, clnt_chal->data, 8); + session_key[0] = IVAL(netsesskey, 0); + session_key[1] = IVAL(netsesskey, 4); - DEBUG(5,(" srv_chal: ")); - dump_data(5, srv_chal->data, 8); - - DEBUG(5,(" clnt_chal+srv_chal: ")); - dump_data(5, sum2, 8); + /* debug output */ + DEBUG(4,("cred_session_key\n")); - DEBUG(5,(" session_key: ")); - dump_data(5, session_key, 16); + DEBUG(5,(" clnt_chal: %lx %lx\n", clnt_chal->data[0], clnt_chal->data[1])); + DEBUG(5,(" srv_chal : %lx %lx\n", srv_chal ->data[0], srv_chal ->data[1])); + DEBUG(5,(" clnt+srv : %lx %lx\n", sum [0], sum [1])); + DEBUG(5,(" sess_key : %lx %lx\n", session_key [0], session_key [1])); } @@ -74,35 +71,36 @@ Input: Output: 8 byte credential ****************************************************************************/ -void cred_create(char *session_key, DOM_CHAL *stored_cred, UTIME timestamp, +void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, DOM_CHAL *cred) { char key2[7]; char buf[8]; + char calc_cred[8]; char timecred[8]; + char netsesskey[8]; + + SIVAL(netsesskey, 0, session_key[0]); + SIVAL(netsesskey, 4, session_key[1]); - memcpy(timecred, stored_cred->data, 8); - SIVAL(timecred, 0, IVAL(stored_cred, 0) + timestamp.time); + SIVAL(timecred, 0, IVAL(stor_cred, 0) + timestamp.time); + SIVAL(timecred, 4, IVAL(stor_cred, 4)); - smbhash(session_key, timecred, buf); + smbhash(netsesskey, timecred, buf); memset(key2, 0, 7); - key2[0] = session_key[7]; - smbhash(key2, buf, cred->data); + key2[0] = netsesskey[7]; + smbhash(key2, buf, calc_cred); + + cred->data[0] = IVAL(calc_cred, 0); + cred->data[1] = IVAL(calc_cred, 4); /* debug output*/ DEBUG(4,("cred_create\n")); - DEBUG(5,(" session_key: ")); - dump_data(5, session_key, 16); - - DEBUG(5,(" stored_cred: ")); - dump_data(5, stored_cred->data, 8); - - DEBUG(5,(" timecred: ")); - dump_data(5, timecred, 8); - - DEBUG(5,(" cred: ")); - dump_data(5, cred->data, 8); + DEBUG(5,(" sess_key : %lx %lx\n", session_key [0], session_key [1])); + DEBUG(5,(" stor_cred: %lx %lx\n", stor_cred->data[0], stor_cred->data[1])); + DEBUG(5,(" timecred : %lx %lx\n", IVAL(timecred, 0), IVAL(timecred, 4))); + DEBUG(5,(" calc_cred: %lx %lx\n", cred ->data[0], cred ->data[1])); } @@ -119,7 +117,7 @@ Output: returns 1 if computed credential matches received credential returns 0 otherwise ****************************************************************************/ -int cred_assert(DOM_CHAL *cred, char *session_key, DOM_CHAL *stored_cred, +int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, UTIME timestamp) { DOM_CHAL cred2; @@ -129,11 +127,9 @@ int cred_assert(DOM_CHAL *cred, char *session_key, DOM_CHAL *stored_cred, /* debug output*/ DEBUG(4,("cred_assert\n")); + DEBUG(5,(" challenge : %lx %lx\n", cred->data[0], cred->data[1])); + DEBUG(5,(" calculated: %lx %lx\n", cred2.data[0], cred2.data[1])); DEBUG(5,(" challenge: ")); - dump_data(5, cred->data, 8); - - DEBUG(5,(" calculated: ")); - dump_data(5, cred2.data, 8); return memcmp(cred->data, cred2.data, 8) == 0; } -- cgit From be73ce8321d5714fcd74f71ed9f6532ca4e1090b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Oct 1997 04:51:23 +0000 Subject: fixed a stack overflow bug in api_lsa_req_chal() changed the order of arguments to smbhash() in credentials.c. Luke, when you changed from E1() to smbhash() you didn't notice that the arguments are in a different order. This is why your new code was failing. NT logon still fails, but now gets to SAMLOGON. It shouldn't take much to get it working now. (This used to be commit 708edc348f0fb81d9c918e4bf857f339a13a3781) --- source3/libsmb/credentials.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 07816bc0cf..babc8180f2 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -44,8 +44,8 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - smbhash(pass , sum2, buf); - smbhash(pass+9, buf , netsesskey); + smbhash(buf, sum2, pass); + smbhash(netsesskey, buf, pass+9); session_key[0] = IVAL(netsesskey, 0); session_key[1] = IVAL(netsesskey, 4); @@ -86,10 +86,10 @@ void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, SIVAL(timecred, 0, IVAL(stor_cred, 0) + timestamp.time); SIVAL(timecred, 4, IVAL(stor_cred, 4)); - smbhash(netsesskey, timecred, buf); + smbhash(buf, timecred, netsesskey); memset(key2, 0, 7); key2[0] = netsesskey[7]; - smbhash(key2, buf, calc_cred); + smbhash(calc_cred, buf, key2); cred->data[0] = IVAL(calc_cred, 0); cred->data[1] = IVAL(calc_cred, 4); -- cgit From 54c3f7bbb02bc12fec53aeb042f5356f100e3472 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Oct 1997 09:17:21 +0000 Subject: add the port number to a debug statement (This used to be commit 97d06dd05e952a134be26ec5998ec4b8d38991dd) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 48f988de2a..e8f281bc25 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -107,8 +107,8 @@ void debug_nmb_packet(struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - DEBUG(4,("nmb packet from %s header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), + DEBUG(4,("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa(p->ip), p->port, nmb->header.name_trn_id, lookup_opcode_name(nmb->header.opcode), nmb->header.opcode,BOOLSTR(nmb->header.response))); -- cgit From d83845241381fb6ff86890d1d43c3d3bf6522a2b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 15 Oct 1997 19:16:38 +0000 Subject: smb.h smbparse.c pipenetlog.c : whoops, the SAM Logon structure was wrong. updated this, and cifsntdomain.txt. more debug info in pipenetlog.c. the crash is somewhere around deal_with_credentials(). byteorder.h : put in uint8, uint16 and uint32 typecasts around debug info, because sign extending was resulting in ffffffe8 being displayed instead of e8. credentials.c : some debugging info, because i'm tracking a coredump. without gdb. nothing like making things difficult. reply.c : whoops, missed this (important) bit from paul's code, which tells the NT workstation that the MACHINE$ entry doesn't already exist, and we're going to create a default entry with a password "machine" right now. proto.h: the usual. (This used to be commit ed606bc7d4e6fb1091e527ea70a3e950d50a1db4) --- source3/libsmb/credentials.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index babc8180f2..d56598e98a 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -99,7 +99,7 @@ void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, DEBUG(5,(" sess_key : %lx %lx\n", session_key [0], session_key [1])); DEBUG(5,(" stor_cred: %lx %lx\n", stor_cred->data[0], stor_cred->data[1])); - DEBUG(5,(" timecred : %lx %lx\n", IVAL(timecred, 0), IVAL(timecred, 4))); + DEBUG(5,(" timecred : %lx %lx\n", IVAL(timecred, 0) , IVAL(timecred, 4) )); DEBUG(5,(" calc_cred: %lx %lx\n", cred ->data[0], cred ->data[1])); } @@ -129,7 +129,6 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, DEBUG(5,(" challenge : %lx %lx\n", cred->data[0], cred->data[1])); DEBUG(5,(" calculated: %lx %lx\n", cred2.data[0], cred2.data[1])); - DEBUG(5,(" challenge: ")); return memcmp(cred->data, cred2.data, 8) == 0; } -- cgit From 9e4626593f59ba4f5a678fc6d8d6e239cdff9c39 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 17 Oct 1997 16:46:56 +0000 Subject: pipenetlog.c lsaparse.c smb.h : SAM logon sorting. too many buffer pointers. added in the missing switch value (value of 3). dealing with the buffer pointers to the user info structure in a slightly different way. (This used to be commit 7993e17c9a1edddae6407d3f12790c461def705a) --- source3/libsmb/credentials.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index d56598e98a..8881704a7a 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -130,6 +130,15 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, DEBUG(5,(" challenge : %lx %lx\n", cred->data[0], cred->data[1])); DEBUG(5,(" calculated: %lx %lx\n", cred2.data[0], cred2.data[1])); - return memcmp(cred->data, cred2.data, 8) == 0; + if (memcmp(cred->data, cred2.data, 8) == 0) + { + DEBUG(5, ("credentials check ok\n")); + return True; + } + else + { + DEBUG(5, ("credentials check wrong\n")); + return False; + } } -- cgit From 62b73f0913894ce7cf6e327cb9928a283f305403 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Oct 1997 01:00:08 +0000 Subject: move calls to smbhash() inside smbdes.c (for legal reasons) (This used to be commit 9dfab27da3634539e99eb48c85dd5a64212e7005) --- source3/libsmb/credentials.c | 11 ++--------- source3/libsmb/smbdes.c | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 8881704a7a..f1a41b0b3b 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -35,7 +35,6 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, { uint32 sum[2]; char sum2[8]; - char buf[8]; char netsesskey[8]; sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); @@ -44,8 +43,7 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - smbhash(buf, sum2, pass); - smbhash(netsesskey, buf, pass+9); + cred_hash1(netsesskey, sum2, pass); session_key[0] = IVAL(netsesskey, 0); session_key[1] = IVAL(netsesskey, 4); @@ -74,8 +72,6 @@ Output: void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, DOM_CHAL *cred) { - char key2[7]; - char buf[8]; char calc_cred[8]; char timecred[8]; char netsesskey[8]; @@ -86,10 +82,7 @@ void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, SIVAL(timecred, 0, IVAL(stor_cred, 0) + timestamp.time); SIVAL(timecred, 4, IVAL(stor_cred, 4)); - smbhash(buf, timecred, netsesskey); - memset(key2, 0, 7); - key2[0] = netsesskey[7]; - smbhash(calc_cred, buf, key2); + cred_hash2(calc_cred, timecred, netsesskey); cred->data[0] = IVAL(calc_cred, 0); cred->data[1] = IVAL(calc_cred, 4); diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index b62a160418..90bad778c5 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -275,7 +275,7 @@ void str_to_key(unsigned char *str,unsigned char *key) } -void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) +static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) { int i; char outb[64]; @@ -317,4 +317,21 @@ void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) smbhash(p24+16, c8, p21+14); } +void cred_hash1(char *out, char *in, char *key) +{ + char buf[8]; + + smbhash(buf, in, key); + smbhash(out, buf, key+9); +} + +void cred_hash2(char *out, char *in, char *key) +{ + char buf[8]; + static char key2[8]; + + smbhash(buf, in, key); + key2[0] = key[7]; + smbhash(out, buf, key2); +} -- cgit From f4b4b3e6e35916dc5e280542f5f914e40b25dd21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Oct 1997 02:50:12 +0000 Subject: casting cleanups (This used to be commit ab849a97821c9e1f199eea8ea2ec477687bed947) --- source3/libsmb/credentials.c | 12 ++++++------ source3/libsmb/smbdes.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index f1a41b0b3b..ee7b1493e1 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -34,8 +34,8 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, uint32 session_key[2]) { uint32 sum[2]; - char sum2[8]; - char netsesskey[8]; + unsigned char sum2[8]; + unsigned char netsesskey[8]; sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); @@ -43,7 +43,7 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(netsesskey, sum2, pass); + cred_hash1(netsesskey, sum2,(unsigned char *)pass); session_key[0] = IVAL(netsesskey, 0); session_key[1] = IVAL(netsesskey, 4); @@ -72,9 +72,9 @@ Output: void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, DOM_CHAL *cred) { - char calc_cred[8]; - char timecred[8]; - char netsesskey[8]; + unsigned char calc_cred[8]; + unsigned char timecred[8]; + unsigned char netsesskey[8]; SIVAL(netsesskey, 0, session_key[0]); SIVAL(netsesskey, 4, session_key[1]); diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 90bad778c5..67e27016c3 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -257,7 +257,7 @@ static void dohash(char *out, char *in, char *key) permute(out, rl, perm6, 64); } -void str_to_key(unsigned char *str,unsigned char *key) +static void str_to_key(unsigned char *str,unsigned char *key) { int i; @@ -317,18 +317,18 @@ void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) smbhash(p24+16, c8, p21+14); } -void cred_hash1(char *out, char *in, char *key) +void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) { - char buf[8]; + unsigned char buf[8]; smbhash(buf, in, key); smbhash(out, buf, key+9); } -void cred_hash2(char *out, char *in, char *key) +void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) { - char buf[8]; - static char key2[8]; + unsigned char buf[8]; + static unsigned char key2[8]; smbhash(buf, in, key); key2[0] = key[7]; -- cgit From 8adc95a55ab51597cce665705c2a866294b743ac Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Oct 1997 09:12:41 +0000 Subject: This is a set of generic SMB client routines. I needed this in a hurry to fix the password server code, so I didn't use SMBlib. This code is fairly generic and uses a "struct cli_state" to hold the client state. (This used to be commit 3a0b5f06f42efdb522f1c5d3d9a4b4afabe03b40) --- source3/libsmb/clientgen.c | 673 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 673 insertions(+) create mode 100644 source3/libsmb/clientgen.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c new file mode 100644 index 0000000000..d47c5a2755 --- /dev/null +++ b/source3/libsmb/clientgen.c @@ -0,0 +1,673 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client generic functions + Copyright (C) Andrew Tridgell 1994-1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + + +extern int DEBUGLEVEL; + +/**************************************************************************** +setup basics in a outgoing packet +****************************************************************************/ +static void cli_setup_pkt(struct cli_state *cli) +{ + SSVAL(cli->outbuf,smb_pid,cli->pid); + SSVAL(cli->outbuf,smb_uid,cli->uid); + SSVAL(cli->outbuf,smb_mid,cli->mid); + if (cli->protocol > PROTOCOL_CORE) { + SCVAL(cli->outbuf,smb_flg,0x8); + SSVAL(cli->outbuf,smb_flg2,0x1); + } +} + + +/**************************************************************************** + send a SMB trans or trans2 request + ****************************************************************************/ +static BOOL cli_send_trans(struct cli_state *cli, + int trans, char *name, int fid, int flags, + char *data,char *param,uint16 *setup, int ldata,int lparam, + int lsetup,int mdata,int mparam,int msetup) +{ + int i; + int this_ldata,this_lparam; + int tot_data=0,tot_param=0; + char *outdata,*outparam; + char *p; + + this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */ + this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*SIZEOFWORD+this_lparam)); + + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,14+lsetup,0,True); + CVAL(cli->outbuf,smb_com) = trans; + SSVAL(cli->outbuf,smb_tid, cli->cnum); + cli_setup_pkt(cli); + + outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3); + outdata = outparam+this_lparam; + + /* primary request */ + SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ + SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ + SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ + SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ + SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ + SSVAL(cli->outbuf,smb_flags,flags); /* flags */ + SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ + SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ + SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ + SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ + SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ + SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ + for (i=0;ioutbuf,smb_setup+i*SIZEOFWORD,setup[i]); + p = smb_buf(cli->outbuf); + if (trans==SMBtrans) { + strcpy(p,name); /* name[] */ + } else { + *p++ = 0; /* put in a null smb_name */ + *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ + } + if (this_lparam) /* param[] */ + memcpy(outparam,param,this_lparam); + if (this_ldata) /* data[] */ + memcpy(outdata,data,this_ldata); + set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ + PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + + show_msg(cli->outbuf); + send_smb(cli->fd,cli->outbuf); + + if (this_ldata < ldata || this_lparam < lparam) { + /* receive interim response */ + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || + CVAL(cli->inbuf,smb_rcls) != 0) { + return(False); + } + + tot_data = this_ldata; + tot_param = this_lparam; + + while (tot_data < ldata || tot_param < lparam) { + this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ + this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); + + set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); + CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2; + + outparam = smb_buf(cli->outbuf); + outdata = outparam+this_lparam; + + /* secondary request */ + SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ + SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ + SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ + SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ + SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ + SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ + SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ + SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ + if (trans==SMBtrans2) + SSVAL(cli->outbuf,smb_sfid,fid); /* fid */ + if (this_lparam) /* param[] */ + memcpy(outparam,param,this_lparam); + if (this_ldata) /* data[] */ + memcpy(outdata,data,this_ldata); + set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ + PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + + show_msg(cli->outbuf); + send_smb(cli->fd,cli->outbuf); + + tot_data += this_ldata; + tot_param += this_lparam; + } + } + + return(True); +} + + +/**************************************************************************** + receive a SMB trans or trans2 response allocating the necessary memory + ****************************************************************************/ +static BOOL cli_receive_trans(struct cli_state *cli, + int trans,int *data_len, + int *param_len, char **data,char **param) +{ + int total_data=0; + int total_param=0; + int this_data,this_param; + + *data_len = *param_len = 0; + + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + show_msg(cli->inbuf); + + /* sanity check */ + if (CVAL(cli->inbuf,smb_com) != trans) { + DEBUG(0,("Expected %s response, got command 0x%02x\n", + trans==SMBtrans?"SMBtrans":"SMBtrans2", + CVAL(cli->inbuf,smb_com))); + return(False); + } + if (CVAL(cli->inbuf,smb_rcls) != 0) + return(False); + + /* parse out the lengths */ + total_data = SVAL(cli->inbuf,smb_tdrcnt); + total_param = SVAL(cli->inbuf,smb_tprcnt); + + /* allocate it */ + *data = Realloc(*data,total_data); + *param = Realloc(*param,total_param); + + while (1) { + this_data = SVAL(cli->inbuf,smb_drcnt); + this_param = SVAL(cli->inbuf,smb_prcnt); + + if (this_data + *data_len > total_data || + this_param + *param_len > total_param) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) + memcpy(*data + SVAL(cli->inbuf,smb_drdisp), + smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), + this_data); + if (this_param) + memcpy(*param + SVAL(cli->inbuf,smb_prdisp), + smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), + this_param); + *data_len += this_data; + *param_len += this_param; + + /* parse out the total lengths again - they can shrink! */ + total_data = SVAL(cli->inbuf,smb_tdrcnt); + total_param = SVAL(cli->inbuf,smb_tprcnt); + + if (total_data <= *data_len && total_param <= *param_len) + break; + + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + show_msg(cli->inbuf); + + /* sanity check */ + if (CVAL(cli->inbuf,smb_com) != trans) { + DEBUG(0,("Expected %s response, got command 0x%02x\n", + trans==SMBtrans?"SMBtrans":"SMBtrans2", + CVAL(cli->inbuf,smb_com))); + return(False); + } + if (CVAL(cli->inbuf,smb_rcls) != 0) + return(False); + } + + return(True); +} + + +/**************************************************************************** +call a remote api +****************************************************************************/ +static BOOL cli_api(struct cli_state *cli, + int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt, + int *rdrcnt, char *param,char *data, + char **rparam, char **rdata) +{ + cli_send_trans(cli,SMBtrans,"\\PIPE\\LANMAN",0,0, + data,param,NULL, + drcnt,prcnt,0, + mdrcnt,mprcnt,0); + + return (cli_receive_trans(cli,SMBtrans, + rdrcnt,rprcnt, + rdata,rparam)); +} + + +/**************************************************************************** +perform a NetWkstaUserLogon +****************************************************************************/ +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt; + pstring param; + + memset(param, 0, sizeof(param)); + + /* send a SMBtrans command with api NetWkstaUserLogon */ + p = param; + SSVAL(p,0,132); /* api number */ + p += 2; + strcpy(p,"OOWb54WrLh"); + p = skip_string(p,1); + strcpy(p,"WB21BWDWWDDDDDDDzzzD"); + p = skip_string(p,1); + SSVAL(p,0,1); + p += 2; + strcpy(p,user); + strupper(p); + p += 21; p++; p += 15; p++; + strcpy(p, workstation); + strupper(p); + p += 16; + SSVAL(p, 0, BUFFER_SIZE); + p += 2; + SSVAL(p, 0, BUFFER_SIZE); + p += 2; + + cli->error = -1; + + if (cli_api(cli, PTR_DIFF(p,param),0, + 1024,BUFFER_SIZE, + &rprcnt,&rdrcnt, + param,NULL, + &rparam,&rdata)) { + cli->error = SVAL(rparam,0); + p = rdata; + + if (cli->error == 0) { + DEBUG(4,("NetWkstaUserLogon success\n")); + cli->privilages = SVAL(p, 24); + fstrcpy(cli->eff_name,p+2); + } else { + DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error)); + } + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + return cli->error == 0; +} + + + +static struct { + int prot; + char *name; + } +prots[] = + { + {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1,"LANMAN1.0"}, + {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LM 0.12"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {-1,NULL} + }; + + +/**************************************************************************** +send a session setup +****************************************************************************/ +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup) +{ + char *p; + fstring pword; + + if (cli->protocol < PROTOCOL_LANMAN1) + return False; + + if (passlen > sizeof(pword)-1) { + return False; + } + + if ((cli->sec_mode & 2) && *pass && passlen != 24) { + passlen = 24; + SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + } else { + memcpy(pword, pass, passlen); + } + + /* if in share level security then don't send a password now */ + if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} + + /* send a session setup command */ + bzero(cli->outbuf,smb_size); + + if (cli->protocol < PROTOCOL_NT1) { + set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_pkt(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,1); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += passlen; + strcpy(p,user); + strupper(p); + } else { + set_message(cli->outbuf,13,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_pkt(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + SSVAL(cli->outbuf,smb_vwv8,ntpasslen); + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += SVAL(cli->outbuf,smb_vwv7); + memcpy(p,ntpass,ntpasslen); + p += SVAL(cli->outbuf,smb_vwv8); + strcpy(p,user); + strupper(p); + p = skip_string(p,1); + strcpy(p,workgroup); + strupper(p); + p = skip_string(p,1); + strcpy(p,"Unix");p = skip_string(p,1); + strcpy(p,"Samba");p = skip_string(p,1); + set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + } + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + show_msg(cli->inbuf); + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + /* use the returned uid from now on */ + cli->uid = SVAL(cli->inbuf,smb_uid); + + return True; +} + + +/**************************************************************************** +send a tconX +****************************************************************************/ +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pword, int passlen) +{ + char *p; + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,4, + 2 + strlen(share) + passlen + strlen(dev),True); + CVAL(cli->outbuf,smb_com) = SMBtconX; + cli_setup_pkt(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv3,passlen); + + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += passlen; + strcpy(p,share); + p = skip_string(p,1); + strcpy(p,dev); + + SCVAL(cli->inbuf,smb_rcls, 1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + cli->cnum = SVAL(cli->inbuf,smb_tid); + return True; +} + + +/**************************************************************************** +send a tree disconnect +****************************************************************************/ +BOOL cli_tdis(struct cli_state *cli) +{ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBtdis; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_pkt(cli); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + return CVAL(cli->inbuf,smb_rcls) == 0; +} + + +/**************************************************************************** +send a negprot command +****************************************************************************/ +BOOL cli_negprot(struct cli_state *cli) +{ + char *p; + int numprots; + int plength; + + bzero(cli->outbuf,smb_size); + + /* setup the protocol strings */ + for (plength=0,numprots=0; + prots[numprots].name && prots[numprots].prot<=cli->protocol; + numprots++) + plength += strlen(prots[numprots].name)+2; + + set_message(cli->outbuf,0,plength,True); + + p = smb_buf(cli->outbuf); + for (numprots=0; + prots[numprots].name && prots[numprots].prot<=cli->protocol; + numprots++) { + *p++ = 2; + strcpy(p,prots[numprots].name); + p += strlen(p) + 1; + } + + CVAL(cli->outbuf,smb_com) = SMBnegprot; + cli_setup_pkt(cli); + + CVAL(smb_buf(cli->outbuf),0) = 2; + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + show_msg(cli->inbuf); + + if (CVAL(cli->inbuf,smb_rcls) != 0 || + ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { + return(False); + } + + cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + + + if (cli->protocol < PROTOCOL_NT1) { + cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); + cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); + cli->sesskey = IVAL(cli->inbuf,smb_vwv6); + cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; + /* this time is converted to GMT by make_unix_date */ + cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); + if (cli->protocol >= PROTOCOL_COREPLUS) { + cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); + cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); + } + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + } else { + /* NT protocol */ + cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); + cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); + cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); + cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; + /* this time arrives in real GMT */ + cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + if (IVAL(cli->inbuf,smb_vwv9+1) & 1) + cli->readbraw_supported = + cli->writebraw_supported = True; + } + + return True; +} + + +/**************************************************************************** + send a session request +****************************************************************************/ +BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, + char *myname) +{ + fstring dest; + char *p; + int len = 4; + /* send a session request (RFC 1002) */ + + fstrcpy(dest,host); + + p = strchr(dest,'.'); + if (p) *p = 0; + + fstrcpy(cli->desthost, dest); + + /* put in the destination name */ + p = cli->outbuf+len; + name_mangle(dest,p,name_type); + len += name_len(p); + + /* and my name */ + p = cli->outbuf+len; + name_mangle(myname,p,0); + len += name_len(p); + + /* setup the packet length */ + _smb_setlen(cli->outbuf,len); + CVAL(cli->outbuf,0) = 0x81; + + send_smb(cli->fd,cli->outbuf); + DEBUG(5,("Sent session request\n")); + + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + if (CVAL(cli->inbuf,0) != 0x82) { + cli->error = CVAL(cli->inbuf,0); + return False; + } + return(True); +} + + +/**************************************************************************** +open the client sockets +****************************************************************************/ +BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) +{ + struct in_addr dest_ip; + + fstrcpy(cli->desthost, host); + + if (!ip) { + struct hostent *hp; + + if ((hp = Get_Hostbyname(cli->desthost)) == 0) { + return False; + } + + putip((char *)&dest_ip,(char *)hp->h_addr); + } else { + dest_ip = *ip; + } + + + cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout); + if (cli->fd == -1) + return False; + + return True; +} + + +/**************************************************************************** +initialise a client structure +****************************************************************************/ +BOOL cli_initialise(struct cli_state *cli) +{ + if (cli->initialised) cli_shutdown(cli); + + memset(cli, 0, sizeof(*cli)); + cli->fd = -1; + cli->cnum = -1; + cli->pid = getpid(); + cli->mid = 1; + cli->uid = getuid(); + cli->protocol = PROTOCOL_NT1; + cli->timeout = 20000; + cli->bufsize = 0x10000; + cli->max_xmit = cli->bufsize - 4; + cli->outbuf = (char *)malloc(cli->bufsize); + cli->inbuf = (char *)malloc(cli->bufsize); + if (!cli->outbuf || !cli->inbuf) return False; + cli->initialised = 1; + return True; +} + +/**************************************************************************** +shutdown a client structure +****************************************************************************/ +void cli_shutdown(struct cli_state *cli) +{ + if (cli->outbuf) free(cli->outbuf); + if (cli->inbuf) free(cli->inbuf); + if (cli->fd != -1) close(cli->fd); + memset(cli, 0, sizeof(*cli)); +} -- cgit From e5c319186d079eeef55a7ee62fac2a993e932938 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Oct 1997 11:02:00 +0000 Subject: Implemented asynchronous DNS lookups in nmbd. I realised this afternoon just how easy it is to add this, so I thought I'd implement it while the idea was fresh. nmbd forks at startup and uses a pipe to talk to its child. The child does the DNS lookups and the file descriptor of the child is added to the main select loop. While I was doing this I discovered a bug in nmbd that explains why the dns proxy option has been so expensive. The DNS cache entries in the WINS list were never being checked, which means we always did a DNS lookup even if we have done it before and it is in cache. I'm sure this used to work (I tested the DNS cache when I added it) so someone broke it :-( Anyway, the async DNS gets rid of the problem completely. I'll commit just the fix to the DNS cache bug to the 1.9.17 tree. You can disable async DNS by adding -DSYNC_DNS to the compile flags. (This used to be commit 178e27de0791c1ff3268cb456ed5c5efc9ac2a01) --- source3/libsmb/nmblib.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index e8f281bc25..121008685b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -482,9 +482,11 @@ void free_nmb_packet(struct nmb_packet *nmb) ******************************************************************/ void free_packet(struct packet_struct *packet) { - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - free(packet); + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + free(packet); } /******************************************************************* @@ -511,6 +513,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) packet->ip = lastip; packet->port = lastport; packet->fd = fd; + packet->locked = False; packet->timestamp = time(NULL); packet->packet_type = packet_type; switch (packet_type) -- cgit From 5557ab3c007b79c132e9a2da16e41be7b13f1b39 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 23 Oct 1997 19:27:53 +0000 Subject: renamed static cli_setup_pkt() to static cli_setup_packet() because it clashed with the currently-used cli_setup_pkt() in clientutil.c (This used to be commit 25560cf40b997e400d16fa0c1380e5bc29c015a5) --- source3/libsmb/clientgen.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d47c5a2755..7cd2ef6903 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,7 +31,7 @@ extern int DEBUGLEVEL; /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ -static void cli_setup_pkt(struct cli_state *cli) +static void cli_setup_packet(struct cli_state *cli) { SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->uid); @@ -64,7 +64,7 @@ static BOOL cli_send_trans(struct cli_state *cli, set_message(cli->outbuf,14+lsetup,0,True); CVAL(cli->outbuf,smb_com) = trans; SSVAL(cli->outbuf,smb_tid, cli->cnum); - cli_setup_pkt(cli); + cli_setup_packet(cli); outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3); outdata = outparam+this_lparam; @@ -367,7 +367,7 @@ BOOL cli_session_setup(struct cli_state *cli, if (cli->protocol < PROTOCOL_NT1) { set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_pkt(cli); + cli_setup_packet(cli); CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); @@ -383,7 +383,7 @@ BOOL cli_session_setup(struct cli_state *cli, } else { set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_pkt(cli); + cli_setup_packet(cli); CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,BUFFER_SIZE); @@ -438,7 +438,7 @@ BOOL cli_send_tconX(struct cli_state *cli, set_message(cli->outbuf,4, 2 + strlen(share) + passlen + strlen(dev),True); CVAL(cli->outbuf,smb_com) = SMBtconX; - cli_setup_pkt(cli); + cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv3,passlen); @@ -474,7 +474,7 @@ BOOL cli_tdis(struct cli_state *cli) set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBtdis; SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_pkt(cli); + cli_setup_packet(cli); send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) @@ -513,7 +513,7 @@ BOOL cli_negprot(struct cli_state *cli) } CVAL(cli->outbuf,smb_com) = SMBnegprot; - cli_setup_pkt(cli); + cli_setup_packet(cli); CVAL(smb_buf(cli->outbuf),0) = 2; -- cgit From a12f04753348e6d52df1f9a2359794deacfc9007 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 24 Oct 1997 13:15:34 +0000 Subject: nterr.c : added a structure that wraps nt errors as strings and enums, so we can do a smb_nt_error() function. Makefile ntclient.c : added ntclient.c, broken out nt domain stuff into a separate file. getting fed up of compile-times and size of client.c. fixed the do_lsa_req_chal() function. made it read the response, and return the challenge credentials received from the server. next stop: do_lsa_auth_2(). client.c : removed nt domain logon functions into a separate file. pipenetlog.c pipentlsa.c pipesrvsvc.c smbparse.c : i'd broken the offsets of the RPC_HDR while trying to sort out the nt client code. fixed it again. added some robustness stuff. util.c : the unistrn2() function was null-terminating the string at one character too many. (This used to be commit 39cec7f698c4461aee05cfbb213879fbd486117d) --- source3/libsmb/nterr.c | 514 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 514 insertions(+) create mode 100644 source3/libsmb/nterr.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c new file mode 100644 index 0000000000..bda0f882a6 --- /dev/null +++ b/source3/libsmb/nterr.c @@ -0,0 +1,514 @@ + +#include "nterr.h" + +static struct +{ + char *nt_errstr; + uint16 nt_errcode; + +} nt_errs[] = +{ + { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, + { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, + { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, + { "NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH }, + { "NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION }, + { "NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR }, + { "NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA }, + { "NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE }, + { "NT_STATUS_BAD_INITIAL_STACK", NT_STATUS_BAD_INITIAL_STACK }, + { "NT_STATUS_BAD_INITIAL_PC", NT_STATUS_BAD_INITIAL_PC }, + { "NT_STATUS_INVALID_CID", NT_STATUS_INVALID_CID }, + { "NT_STATUS_TIMER_NOT_CANCELED", NT_STATUS_TIMER_NOT_CANCELED }, + { "NT_STATUS_INVALID_PARAMETER", NT_STATUS_INVALID_PARAMETER }, + { "NT_STATUS_NO_SUCH_DEVICE", NT_STATUS_NO_SUCH_DEVICE }, + { "NT_STATUS_NO_SUCH_FILE", NT_STATUS_NO_SUCH_FILE }, + { "NT_STATUS_INVALID_DEVICE_REQUEST", NT_STATUS_INVALID_DEVICE_REQUEST }, + { "NT_STATUS_END_OF_FILE", NT_STATUS_END_OF_FILE }, + { "NT_STATUS_WRONG_VOLUME", NT_STATUS_WRONG_VOLUME }, + { "NT_STATUS_NO_MEDIA_IN_DEVICE", NT_STATUS_NO_MEDIA_IN_DEVICE }, + { "NT_STATUS_UNRECOGNIZED_MEDIA", NT_STATUS_UNRECOGNIZED_MEDIA }, + { "NT_STATUS_NONEXISTENT_SECTOR", NT_STATUS_NONEXISTENT_SECTOR }, + { "NT_STATUS_MORE_PROCESSING_REQUIRED", NT_STATUS_MORE_PROCESSING_REQUIRED }, + { "NT_STATUS_NO_MEMORY", NT_STATUS_NO_MEMORY }, + { "NT_STATUS_CONFLICTING_ADDRESSES", NT_STATUS_CONFLICTING_ADDRESSES }, + { "NT_STATUS_NOT_MAPPED_VIEW", NT_STATUS_NOT_MAPPED_VIEW }, + { "NT_STATUS_UNABLE_TO_FREE_VM", NT_STATUS_UNABLE_TO_FREE_VM }, + { "NT_STATUS_UNABLE_TO_DELETE_SECTION", NT_STATUS_UNABLE_TO_DELETE_SECTION }, + { "NT_STATUS_INVALID_SYSTEM_SERVICE", NT_STATUS_INVALID_SYSTEM_SERVICE }, + { "NT_STATUS_ILLEGAL_INSTRUCTION", NT_STATUS_ILLEGAL_INSTRUCTION }, + { "NT_STATUS_INVALID_LOCK_SEQUENCE", NT_STATUS_INVALID_LOCK_SEQUENCE }, + { "NT_STATUS_INVALID_VIEW_SIZE", NT_STATUS_INVALID_VIEW_SIZE }, + { "NT_STATUS_INVALID_FILE_FOR_SECTION", NT_STATUS_INVALID_FILE_FOR_SECTION }, + { "NT_STATUS_ALREADY_COMMITTED", NT_STATUS_ALREADY_COMMITTED }, + { "NT_STATUS_ACCESS_DENIED", NT_STATUS_ACCESS_DENIED }, + { "NT_STATUS_BUFFER_TOO_SMALL", NT_STATUS_BUFFER_TOO_SMALL }, + { "NT_STATUS_OBJECT_TYPE_MISMATCH", NT_STATUS_OBJECT_TYPE_MISMATCH }, + { "NT_STATUS_NONCONTINUABLE_EXCEPTION", NT_STATUS_NONCONTINUABLE_EXCEPTION }, + { "NT_STATUS_INVALID_DISPOSITION", NT_STATUS_INVALID_DISPOSITION }, + { "NT_STATUS_UNWIND", NT_STATUS_UNWIND }, + { "NT_STATUS_BAD_STACK", NT_STATUS_BAD_STACK }, + { "NT_STATUS_INVALID_UNWIND_TARGET", NT_STATUS_INVALID_UNWIND_TARGET }, + { "NT_STATUS_NOT_LOCKED", NT_STATUS_NOT_LOCKED }, + { "NT_STATUS_PARITY_ERROR", NT_STATUS_PARITY_ERROR }, + { "NT_STATUS_UNABLE_TO_DECOMMIT_VM", NT_STATUS_UNABLE_TO_DECOMMIT_VM }, + { "NT_STATUS_NOT_COMMITTED", NT_STATUS_NOT_COMMITTED }, + { "NT_STATUS_INVALID_PORT_ATTRIBUTES", NT_STATUS_INVALID_PORT_ATTRIBUTES }, + { "NT_STATUS_PORT_MESSAGE_TOO_LONG", NT_STATUS_PORT_MESSAGE_TOO_LONG }, + { "NT_STATUS_INVALID_PARAMETER_MIX", NT_STATUS_INVALID_PARAMETER_MIX }, + { "NT_STATUS_INVALID_QUOTA_LOWER", NT_STATUS_INVALID_QUOTA_LOWER }, + { "NT_STATUS_DISK_CORRUPT_ERROR", NT_STATUS_DISK_CORRUPT_ERROR }, + { "NT_STATUS_OBJECT_NAME_INVALID", NT_STATUS_OBJECT_NAME_INVALID }, + { "NT_STATUS_OBJECT_NAME_NOT_FOUND", NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { "NT_STATUS_OBJECT_NAME_COLLISION", NT_STATUS_OBJECT_NAME_COLLISION }, + { "NT_STATUS_HANDLE_NOT_WAITABLE", NT_STATUS_HANDLE_NOT_WAITABLE }, + { "NT_STATUS_PORT_DISCONNECTED", NT_STATUS_PORT_DISCONNECTED }, + { "NT_STATUS_DEVICE_ALREADY_ATTACHED", NT_STATUS_DEVICE_ALREADY_ATTACHED }, + { "NT_STATUS_OBJECT_PATH_INVALID", NT_STATUS_OBJECT_PATH_INVALID }, + { "NT_STATUS_OBJECT_PATH_NOT_FOUND", NT_STATUS_OBJECT_PATH_NOT_FOUND }, + { "NT_STATUS_OBJECT_PATH_SYNTAX_BAD", NT_STATUS_OBJECT_PATH_SYNTAX_BAD }, + { "NT_STATUS_DATA_OVERRUN", NT_STATUS_DATA_OVERRUN }, + { "NT_STATUS_DATA_LATE_ERROR", NT_STATUS_DATA_LATE_ERROR }, + { "NT_STATUS_DATA_ERROR", NT_STATUS_DATA_ERROR }, + { "NT_STATUS_CRC_ERROR", NT_STATUS_CRC_ERROR }, + { "NT_STATUS_SECTION_TOO_BIG", NT_STATUS_SECTION_TOO_BIG }, + { "NT_STATUS_PORT_CONNECTION_REFUSED", NT_STATUS_PORT_CONNECTION_REFUSED }, + { "NT_STATUS_INVALID_PORT_HANDLE", NT_STATUS_INVALID_PORT_HANDLE }, + { "NT_STATUS_SHARING_VIOLATION", NT_STATUS_SHARING_VIOLATION }, + { "NT_STATUS_QUOTA_EXCEEDED", NT_STATUS_QUOTA_EXCEEDED }, + { "NT_STATUS_INVALID_PAGE_PROTECTION", NT_STATUS_INVALID_PAGE_PROTECTION }, + { "NT_STATUS_MUTANT_NOT_OWNED", NT_STATUS_MUTANT_NOT_OWNED }, + { "NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED", NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED }, + { "NT_STATUS_PORT_ALREADY_SET", NT_STATUS_PORT_ALREADY_SET }, + { "NT_STATUS_SECTION_NOT_IMAGE", NT_STATUS_SECTION_NOT_IMAGE }, + { "NT_STATUS_SUSPEND_COUNT_EXCEEDED", NT_STATUS_SUSPEND_COUNT_EXCEEDED }, + { "NT_STATUS_THREAD_IS_TERMINATING", NT_STATUS_THREAD_IS_TERMINATING }, + { "NT_STATUS_BAD_WORKING_SET_LIMIT", NT_STATUS_BAD_WORKING_SET_LIMIT }, + { "NT_STATUS_INCOMPATIBLE_FILE_MAP", NT_STATUS_INCOMPATIBLE_FILE_MAP }, + { "NT_STATUS_SECTION_PROTECTION", NT_STATUS_SECTION_PROTECTION }, + { "NT_STATUS_EAS_NOT_SUPPORTED", NT_STATUS_EAS_NOT_SUPPORTED }, + { "NT_STATUS_EA_TOO_LARGE", NT_STATUS_EA_TOO_LARGE }, + { "NT_STATUS_NONEXISTENT_EA_ENTRY", NT_STATUS_NONEXISTENT_EA_ENTRY }, + { "NT_STATUS_NO_EAS_ON_FILE", NT_STATUS_NO_EAS_ON_FILE }, + { "NT_STATUS_EA_CORRUPT_ERROR", NT_STATUS_EA_CORRUPT_ERROR }, + { "NT_STATUS_FILE_LOCK_CONFLICT", NT_STATUS_FILE_LOCK_CONFLICT }, + { "NT_STATUS_LOCK_NOT_GRANTED", NT_STATUS_LOCK_NOT_GRANTED }, + { "NT_STATUS_DELETE_PENDING", NT_STATUS_DELETE_PENDING }, + { "NT_STATUS_CTL_FILE_NOT_SUPPORTED", NT_STATUS_CTL_FILE_NOT_SUPPORTED }, + { "NT_STATUS_UNKNOWN_REVISION", NT_STATUS_UNKNOWN_REVISION }, + { "NT_STATUS_REVISION_MISMATCH", NT_STATUS_REVISION_MISMATCH }, + { "NT_STATUS_INVALID_OWNER", NT_STATUS_INVALID_OWNER }, + { "NT_STATUS_INVALID_PRIMARY_GROUP", NT_STATUS_INVALID_PRIMARY_GROUP }, + { "NT_STATUS_NO_IMPERSONATION_TOKEN", NT_STATUS_NO_IMPERSONATION_TOKEN }, + { "NT_STATUS_CANT_DISABLE_MANDATORY", NT_STATUS_CANT_DISABLE_MANDATORY }, + { "NT_STATUS_NO_LOGON_SERVERS", NT_STATUS_NO_LOGON_SERVERS }, + { "NT_STATUS_NO_SUCH_LOGON_SESSION", NT_STATUS_NO_SUCH_LOGON_SESSION }, + { "NT_STATUS_NO_SUCH_PRIVILEGE", NT_STATUS_NO_SUCH_PRIVILEGE }, + { "NT_STATUS_PRIVILEGE_NOT_HELD", NT_STATUS_PRIVILEGE_NOT_HELD }, + { "NT_STATUS_INVALID_ACCOUNT_NAME", NT_STATUS_INVALID_ACCOUNT_NAME }, + { "NT_STATUS_USER_EXISTS", NT_STATUS_USER_EXISTS }, + { "NT_STATUS_NO_SUCH_USER", NT_STATUS_NO_SUCH_USER }, + { "NT_STATUS_GROUP_EXISTS", NT_STATUS_GROUP_EXISTS }, + { "NT_STATUS_NO_SUCH_GROUP", NT_STATUS_NO_SUCH_GROUP }, + { "NT_STATUS_MEMBER_IN_GROUP", NT_STATUS_MEMBER_IN_GROUP }, + { "NT_STATUS_MEMBER_NOT_IN_GROUP", NT_STATUS_MEMBER_NOT_IN_GROUP }, + { "NT_STATUS_LAST_ADMIN", NT_STATUS_LAST_ADMIN }, + { "NT_STATUS_WRONG_PASSWORD", NT_STATUS_WRONG_PASSWORD }, + { "NT_STATUS_ILL_FORMED_PASSWORD", NT_STATUS_ILL_FORMED_PASSWORD }, + { "NT_STATUS_PASSWORD_RESTRICTION", NT_STATUS_PASSWORD_RESTRICTION }, + { "NT_STATUS_LOGON_FAILURE", NT_STATUS_LOGON_FAILURE }, + { "NT_STATUS_ACCOUNT_RESTRICTION", NT_STATUS_ACCOUNT_RESTRICTION }, + { "NT_STATUS_INVALID_LOGON_HOURS", NT_STATUS_INVALID_LOGON_HOURS }, + { "NT_STATUS_INVALID_WORKSTATION", NT_STATUS_INVALID_WORKSTATION }, + { "NT_STATUS_PASSWORD_EXPIRED", NT_STATUS_PASSWORD_EXPIRED }, + { "NT_STATUS_ACCOUNT_DISABLED", NT_STATUS_ACCOUNT_DISABLED }, + { "NT_STATUS_NONE_MAPPED", NT_STATUS_NONE_MAPPED }, + { "NT_STATUS_TOO_MANY_LUIDS_REQUESTED", NT_STATUS_TOO_MANY_LUIDS_REQUESTED }, + { "NT_STATUS_LUIDS_EXHAUSTED", NT_STATUS_LUIDS_EXHAUSTED }, + { "NT_STATUS_INVALID_SUB_AUTHORITY", NT_STATUS_INVALID_SUB_AUTHORITY }, + { "NT_STATUS_INVALID_ACL", NT_STATUS_INVALID_ACL }, + { "NT_STATUS_INVALID_SID", NT_STATUS_INVALID_SID }, + { "NT_STATUS_INVALID_SECURITY_DESCR", NT_STATUS_INVALID_SECURITY_DESCR }, + { "NT_STATUS_PROCEDURE_NOT_FOUND", NT_STATUS_PROCEDURE_NOT_FOUND }, + { "NT_STATUS_INVALID_IMAGE_FORMAT", NT_STATUS_INVALID_IMAGE_FORMAT }, + { "NT_STATUS_NO_TOKEN", NT_STATUS_NO_TOKEN }, + { "NT_STATUS_BAD_INHERITANCE_ACL", NT_STATUS_BAD_INHERITANCE_ACL }, + { "NT_STATUS_RANGE_NOT_LOCKED", NT_STATUS_RANGE_NOT_LOCKED }, + { "NT_STATUS_DISK_FULL", NT_STATUS_DISK_FULL }, + { "NT_STATUS_SERVER_DISABLED", NT_STATUS_SERVER_DISABLED }, + { "NT_STATUS_SERVER_NOT_DISABLED", NT_STATUS_SERVER_NOT_DISABLED }, + { "NT_STATUS_TOO_MANY_GUIDS_REQUESTED", NT_STATUS_TOO_MANY_GUIDS_REQUESTED }, + { "NT_STATUS_GUIDS_EXHAUSTED", NT_STATUS_GUIDS_EXHAUSTED }, + { "NT_STATUS_INVALID_ID_AUTHORITY", NT_STATUS_INVALID_ID_AUTHORITY }, + { "NT_STATUS_AGENTS_EXHAUSTED", NT_STATUS_AGENTS_EXHAUSTED }, + { "NT_STATUS_INVALID_VOLUME_LABEL", NT_STATUS_INVALID_VOLUME_LABEL }, + { "NT_STATUS_SECTION_NOT_EXTENDED", NT_STATUS_SECTION_NOT_EXTENDED }, + { "NT_STATUS_NOT_MAPPED_DATA", NT_STATUS_NOT_MAPPED_DATA }, + { "NT_STATUS_RESOURCE_DATA_NOT_FOUND", NT_STATUS_RESOURCE_DATA_NOT_FOUND }, + { "NT_STATUS_RESOURCE_TYPE_NOT_FOUND", NT_STATUS_RESOURCE_TYPE_NOT_FOUND }, + { "NT_STATUS_RESOURCE_NAME_NOT_FOUND", NT_STATUS_RESOURCE_NAME_NOT_FOUND }, + { "NT_STATUS_ARRAY_BOUNDS_EXCEEDED", NT_STATUS_ARRAY_BOUNDS_EXCEEDED }, + { "NT_STATUS_FLOAT_DENORMAL_OPERAND", NT_STATUS_FLOAT_DENORMAL_OPERAND }, + { "NT_STATUS_FLOAT_DIVIDE_BY_ZERO", NT_STATUS_FLOAT_DIVIDE_BY_ZERO }, + { "NT_STATUS_FLOAT_INEXACT_RESULT", NT_STATUS_FLOAT_INEXACT_RESULT }, + { "NT_STATUS_FLOAT_INVALID_OPERATION", NT_STATUS_FLOAT_INVALID_OPERATION }, + { "NT_STATUS_FLOAT_OVERFLOW", NT_STATUS_FLOAT_OVERFLOW }, + { "NT_STATUS_FLOAT_STACK_CHECK", NT_STATUS_FLOAT_STACK_CHECK }, + { "NT_STATUS_FLOAT_UNDERFLOW", NT_STATUS_FLOAT_UNDERFLOW }, + { "NT_STATUS_INTEGER_DIVIDE_BY_ZERO", NT_STATUS_INTEGER_DIVIDE_BY_ZERO }, + { "NT_STATUS_INTEGER_OVERFLOW", NT_STATUS_INTEGER_OVERFLOW }, + { "NT_STATUS_PRIVILEGED_INSTRUCTION", NT_STATUS_PRIVILEGED_INSTRUCTION }, + { "NT_STATUS_TOO_MANY_PAGING_FILES", NT_STATUS_TOO_MANY_PAGING_FILES }, + { "NT_STATUS_FILE_INVALID", NT_STATUS_FILE_INVALID }, + { "NT_STATUS_ALLOTTED_SPACE_EXCEEDED", NT_STATUS_ALLOTTED_SPACE_EXCEEDED }, + { "NT_STATUS_INSUFFICIENT_RESOURCES", NT_STATUS_INSUFFICIENT_RESOURCES }, + { "NT_STATUS_DFS_EXIT_PATH_FOUND", NT_STATUS_DFS_EXIT_PATH_FOUND }, + { "NT_STATUS_DEVICE_DATA_ERROR", NT_STATUS_DEVICE_DATA_ERROR }, + { "NT_STATUS_DEVICE_NOT_CONNECTED", NT_STATUS_DEVICE_NOT_CONNECTED }, + { "NT_STATUS_DEVICE_POWER_FAILURE", NT_STATUS_DEVICE_POWER_FAILURE }, + { "NT_STATUS_FREE_VM_NOT_AT_BASE", NT_STATUS_FREE_VM_NOT_AT_BASE }, + { "NT_STATUS_MEMORY_NOT_ALLOCATED", NT_STATUS_MEMORY_NOT_ALLOCATED }, + { "NT_STATUS_WORKING_SET_QUOTA", NT_STATUS_WORKING_SET_QUOTA }, + { "NT_STATUS_MEDIA_WRITE_PROTECTED", NT_STATUS_MEDIA_WRITE_PROTECTED }, + { "NT_STATUS_DEVICE_NOT_READY", NT_STATUS_DEVICE_NOT_READY }, + { "NT_STATUS_INVALID_GROUP_ATTRIBUTES", NT_STATUS_INVALID_GROUP_ATTRIBUTES }, + { "NT_STATUS_BAD_IMPERSONATION_LEVEL", NT_STATUS_BAD_IMPERSONATION_LEVEL }, + { "NT_STATUS_CANT_OPEN_ANONYMOUS", NT_STATUS_CANT_OPEN_ANONYMOUS }, + { "NT_STATUS_BAD_VALIDATION_CLASS", NT_STATUS_BAD_VALIDATION_CLASS }, + { "NT_STATUS_BAD_TOKEN_TYPE", NT_STATUS_BAD_TOKEN_TYPE }, + { "NT_STATUS_BAD_MASTER_BOOT_RECORD", NT_STATUS_BAD_MASTER_BOOT_RECORD }, + { "NT_STATUS_INSTRUCTION_MISALIGNMENT", NT_STATUS_INSTRUCTION_MISALIGNMENT }, + { "NT_STATUS_INSTANCE_NOT_AVAILABLE", NT_STATUS_INSTANCE_NOT_AVAILABLE }, + { "NT_STATUS_PIPE_NOT_AVAILABLE", NT_STATUS_PIPE_NOT_AVAILABLE }, + { "NT_STATUS_INVALID_PIPE_STATE", NT_STATUS_INVALID_PIPE_STATE }, + { "NT_STATUS_PIPE_BUSY", NT_STATUS_PIPE_BUSY }, + { "NT_STATUS_ILLEGAL_FUNCTION", NT_STATUS_ILLEGAL_FUNCTION }, + { "NT_STATUS_PIPE_DISCONNECTED", NT_STATUS_PIPE_DISCONNECTED }, + { "NT_STATUS_PIPE_CLOSING", NT_STATUS_PIPE_CLOSING }, + { "NT_STATUS_PIPE_CONNECTED", NT_STATUS_PIPE_CONNECTED }, + { "NT_STATUS_PIPE_LISTENING", NT_STATUS_PIPE_LISTENING }, + { "NT_STATUS_INVALID_READ_MODE", NT_STATUS_INVALID_READ_MODE }, + { "NT_STATUS_IO_TIMEOUT", NT_STATUS_IO_TIMEOUT }, + { "NT_STATUS_FILE_FORCED_CLOSED", NT_STATUS_FILE_FORCED_CLOSED }, + { "NT_STATUS_PROFILING_NOT_STARTED", NT_STATUS_PROFILING_NOT_STARTED }, + { "NT_STATUS_PROFILING_NOT_STOPPED", NT_STATUS_PROFILING_NOT_STOPPED }, + { "NT_STATUS_COULD_NOT_INTERPRET", NT_STATUS_COULD_NOT_INTERPRET }, + { "NT_STATUS_FILE_IS_A_DIRECTORY", NT_STATUS_FILE_IS_A_DIRECTORY }, + { "NT_STATUS_NOT_SUPPORTED", NT_STATUS_NOT_SUPPORTED }, + { "NT_STATUS_REMOTE_NOT_LISTENING", NT_STATUS_REMOTE_NOT_LISTENING }, + { "NT_STATUS_DUPLICATE_NAME", NT_STATUS_DUPLICATE_NAME }, + { "NT_STATUS_BAD_NETWORK_PATH", NT_STATUS_BAD_NETWORK_PATH }, + { "NT_STATUS_NETWORK_BUSY", NT_STATUS_NETWORK_BUSY }, + { "NT_STATUS_DEVICE_DOES_NOT_EXIST", NT_STATUS_DEVICE_DOES_NOT_EXIST }, + { "NT_STATUS_TOO_MANY_COMMANDS", NT_STATUS_TOO_MANY_COMMANDS }, + { "NT_STATUS_ADAPTER_HARDWARE_ERROR", NT_STATUS_ADAPTER_HARDWARE_ERROR }, + { "NT_STATUS_INVALID_NETWORK_RESPONSE", NT_STATUS_INVALID_NETWORK_RESPONSE }, + { "NT_STATUS_UNEXPECTED_NETWORK_ERROR", NT_STATUS_UNEXPECTED_NETWORK_ERROR }, + { "NT_STATUS_BAD_REMOTE_ADAPTER", NT_STATUS_BAD_REMOTE_ADAPTER }, + { "NT_STATUS_PRINT_QUEUE_FULL", NT_STATUS_PRINT_QUEUE_FULL }, + { "NT_STATUS_NO_SPOOL_SPACE", NT_STATUS_NO_SPOOL_SPACE }, + { "NT_STATUS_PRINT_CANCELLED", NT_STATUS_PRINT_CANCELLED }, + { "NT_STATUS_NETWORK_NAME_DELETED", NT_STATUS_NETWORK_NAME_DELETED }, + { "NT_STATUS_NETWORK_ACCESS_DENIED", NT_STATUS_NETWORK_ACCESS_DENIED }, + { "NT_STATUS_BAD_DEVICE_TYPE", NT_STATUS_BAD_DEVICE_TYPE }, + { "NT_STATUS_BAD_NETWORK_NAME", NT_STATUS_BAD_NETWORK_NAME }, + { "NT_STATUS_TOO_MANY_NAMES", NT_STATUS_TOO_MANY_NAMES }, + { "NT_STATUS_TOO_MANY_SESSIONS", NT_STATUS_TOO_MANY_SESSIONS }, + { "NT_STATUS_SHARING_PAUSED", NT_STATUS_SHARING_PAUSED }, + { "NT_STATUS_REQUEST_NOT_ACCEPTED", NT_STATUS_REQUEST_NOT_ACCEPTED }, + { "NT_STATUS_REDIRECTOR_PAUSED", NT_STATUS_REDIRECTOR_PAUSED }, + { "NT_STATUS_NET_WRITE_FAULT", NT_STATUS_NET_WRITE_FAULT }, + { "NT_STATUS_PROFILING_AT_LIMIT", NT_STATUS_PROFILING_AT_LIMIT }, + { "NT_STATUS_NOT_SAME_DEVICE", NT_STATUS_NOT_SAME_DEVICE }, + { "NT_STATUS_FILE_RENAMED", NT_STATUS_FILE_RENAMED }, + { "NT_STATUS_VIRTUAL_CIRCUIT_CLOSED", NT_STATUS_VIRTUAL_CIRCUIT_CLOSED }, + { "NT_STATUS_NO_SECURITY_ON_OBJECT", NT_STATUS_NO_SECURITY_ON_OBJECT }, + { "NT_STATUS_CANT_WAIT", NT_STATUS_CANT_WAIT }, + { "NT_STATUS_PIPE_EMPTY", NT_STATUS_PIPE_EMPTY }, + { "NT_STATUS_CANT_ACCESS_DOMAIN_INFO", NT_STATUS_CANT_ACCESS_DOMAIN_INFO }, + { "NT_STATUS_CANT_TERMINATE_SELF", NT_STATUS_CANT_TERMINATE_SELF }, + { "NT_STATUS_INVALID_SERVER_STATE", NT_STATUS_INVALID_SERVER_STATE }, + { "NT_STATUS_INVALID_DOMAIN_STATE", NT_STATUS_INVALID_DOMAIN_STATE }, + { "NT_STATUS_INVALID_DOMAIN_ROLE", NT_STATUS_INVALID_DOMAIN_ROLE }, + { "NT_STATUS_NO_SUCH_DOMAIN", NT_STATUS_NO_SUCH_DOMAIN }, + { "NT_STATUS_DOMAIN_EXISTS", NT_STATUS_DOMAIN_EXISTS }, + { "NT_STATUS_DOMAIN_LIMIT_EXCEEDED", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, + { "NT_STATUS_OPLOCK_NOT_GRANTED", NT_STATUS_OPLOCK_NOT_GRANTED }, + { "NT_STATUS_INVALID_OPLOCK_PROTOCOL", NT_STATUS_INVALID_OPLOCK_PROTOCOL }, + { "NT_STATUS_INTERNAL_DB_CORRUPTION", NT_STATUS_INTERNAL_DB_CORRUPTION }, + { "NT_STATUS_INTERNAL_ERROR", NT_STATUS_INTERNAL_ERROR }, + { "NT_STATUS_GENERIC_NOT_MAPPED", NT_STATUS_GENERIC_NOT_MAPPED }, + { "NT_STATUS_BAD_DESCRIPTOR_FORMAT", NT_STATUS_BAD_DESCRIPTOR_FORMAT }, + { "NT_STATUS_INVALID_USER_BUFFER", NT_STATUS_INVALID_USER_BUFFER }, + { "NT_STATUS_UNEXPECTED_IO_ERROR", NT_STATUS_UNEXPECTED_IO_ERROR }, + { "NT_STATUS_UNEXPECTED_MM_CREATE_ERR", NT_STATUS_UNEXPECTED_MM_CREATE_ERR }, + { "NT_STATUS_UNEXPECTED_MM_MAP_ERROR", NT_STATUS_UNEXPECTED_MM_MAP_ERROR }, + { "NT_STATUS_UNEXPECTED_MM_EXTEND_ERR", NT_STATUS_UNEXPECTED_MM_EXTEND_ERR }, + { "NT_STATUS_NOT_LOGON_PROCESS", NT_STATUS_NOT_LOGON_PROCESS }, + { "NT_STATUS_LOGON_SESSION_EXISTS", NT_STATUS_LOGON_SESSION_EXISTS }, + { "NT_STATUS_INVALID_PARAMETER_1", NT_STATUS_INVALID_PARAMETER_1 }, + { "NT_STATUS_INVALID_PARAMETER_2", NT_STATUS_INVALID_PARAMETER_2 }, + { "NT_STATUS_INVALID_PARAMETER_3", NT_STATUS_INVALID_PARAMETER_3 }, + { "NT_STATUS_INVALID_PARAMETER_4", NT_STATUS_INVALID_PARAMETER_4 }, + { "NT_STATUS_INVALID_PARAMETER_5", NT_STATUS_INVALID_PARAMETER_5 }, + { "NT_STATUS_INVALID_PARAMETER_6", NT_STATUS_INVALID_PARAMETER_6 }, + { "NT_STATUS_INVALID_PARAMETER_7", NT_STATUS_INVALID_PARAMETER_7 }, + { "NT_STATUS_INVALID_PARAMETER_8", NT_STATUS_INVALID_PARAMETER_8 }, + { "NT_STATUS_INVALID_PARAMETER_9", NT_STATUS_INVALID_PARAMETER_9 }, + { "NT_STATUS_INVALID_PARAMETER_10", NT_STATUS_INVALID_PARAMETER_10 }, + { "NT_STATUS_INVALID_PARAMETER_11", NT_STATUS_INVALID_PARAMETER_11 }, + { "NT_STATUS_INVALID_PARAMETER_12", NT_STATUS_INVALID_PARAMETER_12 }, + { "NT_STATUS_REDIRECTOR_NOT_STARTED", NT_STATUS_REDIRECTOR_NOT_STARTED }, + { "NT_STATUS_REDIRECTOR_STARTED", NT_STATUS_REDIRECTOR_STARTED }, + { "NT_STATUS_STACK_OVERFLOW", NT_STATUS_STACK_OVERFLOW }, + { "NT_STATUS_NO_SUCH_PACKAGE", NT_STATUS_NO_SUCH_PACKAGE }, + { "NT_STATUS_BAD_FUNCTION_TABLE", NT_STATUS_BAD_FUNCTION_TABLE }, + { "NT_STATUS_DIRECTORY_NOT_EMPTY", NT_STATUS_DIRECTORY_NOT_EMPTY }, + { "NT_STATUS_FILE_CORRUPT_ERROR", NT_STATUS_FILE_CORRUPT_ERROR }, + { "NT_STATUS_NOT_A_DIRECTORY", NT_STATUS_NOT_A_DIRECTORY }, + { "NT_STATUS_BAD_LOGON_SESSION_STATE", NT_STATUS_BAD_LOGON_SESSION_STATE }, + { "NT_STATUS_LOGON_SESSION_COLLISION", NT_STATUS_LOGON_SESSION_COLLISION }, + { "NT_STATUS_NAME_TOO_LONG", NT_STATUS_NAME_TOO_LONG }, + { "NT_STATUS_FILES_OPEN", NT_STATUS_FILES_OPEN }, + { "NT_STATUS_CONNECTION_IN_USE", NT_STATUS_CONNECTION_IN_USE }, + { "NT_STATUS_MESSAGE_NOT_FOUND", NT_STATUS_MESSAGE_NOT_FOUND }, + { "NT_STATUS_PROCESS_IS_TERMINATING", NT_STATUS_PROCESS_IS_TERMINATING }, + { "NT_STATUS_INVALID_LOGON_TYPE", NT_STATUS_INVALID_LOGON_TYPE }, + { "NT_STATUS_NO_GUID_TRANSLATION", NT_STATUS_NO_GUID_TRANSLATION }, + { "NT_STATUS_CANNOT_IMPERSONATE", NT_STATUS_CANNOT_IMPERSONATE }, + { "NT_STATUS_IMAGE_ALREADY_LOADED", NT_STATUS_IMAGE_ALREADY_LOADED }, + { "NT_STATUS_ABIOS_NOT_PRESENT", NT_STATUS_ABIOS_NOT_PRESENT }, + { "NT_STATUS_ABIOS_LID_NOT_EXIST", NT_STATUS_ABIOS_LID_NOT_EXIST }, + { "NT_STATUS_ABIOS_LID_ALREADY_OWNED", NT_STATUS_ABIOS_LID_ALREADY_OWNED }, + { "NT_STATUS_ABIOS_NOT_LID_OWNER", NT_STATUS_ABIOS_NOT_LID_OWNER }, + { "NT_STATUS_ABIOS_INVALID_COMMAND", NT_STATUS_ABIOS_INVALID_COMMAND }, + { "NT_STATUS_ABIOS_INVALID_LID", NT_STATUS_ABIOS_INVALID_LID }, + { "NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE", NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE }, + { "NT_STATUS_ABIOS_INVALID_SELECTOR", NT_STATUS_ABIOS_INVALID_SELECTOR }, + { "NT_STATUS_NO_LDT", NT_STATUS_NO_LDT }, + { "NT_STATUS_INVALID_LDT_SIZE", NT_STATUS_INVALID_LDT_SIZE }, + { "NT_STATUS_INVALID_LDT_OFFSET", NT_STATUS_INVALID_LDT_OFFSET }, + { "NT_STATUS_INVALID_LDT_DESCRIPTOR", NT_STATUS_INVALID_LDT_DESCRIPTOR }, + { "NT_STATUS_INVALID_IMAGE_NE_FORMAT", NT_STATUS_INVALID_IMAGE_NE_FORMAT }, + { "NT_STATUS_RXACT_INVALID_STATE", NT_STATUS_RXACT_INVALID_STATE }, + { "NT_STATUS_RXACT_COMMIT_FAILURE", NT_STATUS_RXACT_COMMIT_FAILURE }, + { "NT_STATUS_MAPPED_FILE_SIZE_ZERO", NT_STATUS_MAPPED_FILE_SIZE_ZERO }, + { "NT_STATUS_TOO_MANY_OPENED_FILES", NT_STATUS_TOO_MANY_OPENED_FILES }, + { "NT_STATUS_CANCELLED", NT_STATUS_CANCELLED }, + { "NT_STATUS_CANNOT_DELETE", NT_STATUS_CANNOT_DELETE }, + { "NT_STATUS_INVALID_COMPUTER_NAME", NT_STATUS_INVALID_COMPUTER_NAME }, + { "NT_STATUS_FILE_DELETED", NT_STATUS_FILE_DELETED }, + { "NT_STATUS_SPECIAL_ACCOUNT", NT_STATUS_SPECIAL_ACCOUNT }, + { "NT_STATUS_SPECIAL_GROUP", NT_STATUS_SPECIAL_GROUP }, + { "NT_STATUS_SPECIAL_USER", NT_STATUS_SPECIAL_USER }, + { "NT_STATUS_MEMBERS_PRIMARY_GROUP", NT_STATUS_MEMBERS_PRIMARY_GROUP }, + { "NT_STATUS_FILE_CLOSED", NT_STATUS_FILE_CLOSED }, + { "NT_STATUS_TOO_MANY_THREADS", NT_STATUS_TOO_MANY_THREADS }, + { "NT_STATUS_THREAD_NOT_IN_PROCESS", NT_STATUS_THREAD_NOT_IN_PROCESS }, + { "NT_STATUS_TOKEN_ALREADY_IN_USE", NT_STATUS_TOKEN_ALREADY_IN_USE }, + { "NT_STATUS_PAGEFILE_QUOTA_EXCEEDED", NT_STATUS_PAGEFILE_QUOTA_EXCEEDED }, + { "NT_STATUS_COMMITMENT_LIMIT", NT_STATUS_COMMITMENT_LIMIT }, + { "NT_STATUS_INVALID_IMAGE_LE_FORMAT", NT_STATUS_INVALID_IMAGE_LE_FORMAT }, + { "NT_STATUS_INVALID_IMAGE_NOT_MZ", NT_STATUS_INVALID_IMAGE_NOT_MZ }, + { "NT_STATUS_INVALID_IMAGE_PROTECT", NT_STATUS_INVALID_IMAGE_PROTECT }, + { "NT_STATUS_INVALID_IMAGE_WIN_16", NT_STATUS_INVALID_IMAGE_WIN_16 }, + { "NT_STATUS_LOGON_SERVER_CONFLICT", NT_STATUS_LOGON_SERVER_CONFLICT }, + { "NT_STATUS_TIME_DIFFERENCE_AT_DC", NT_STATUS_TIME_DIFFERENCE_AT_DC }, + { "NT_STATUS_SYNCHRONIZATION_REQUIRED", NT_STATUS_SYNCHRONIZATION_REQUIRED }, + { "NT_STATUS_DLL_NOT_FOUND", NT_STATUS_DLL_NOT_FOUND }, + { "NT_STATUS_OPEN_FAILED", NT_STATUS_OPEN_FAILED }, + { "NT_STATUS_IO_PRIVILEGE_FAILED", NT_STATUS_IO_PRIVILEGE_FAILED }, + { "NT_STATUS_ORDINAL_NOT_FOUND", NT_STATUS_ORDINAL_NOT_FOUND }, + { "NT_STATUS_ENTRYPOINT_NOT_FOUND", NT_STATUS_ENTRYPOINT_NOT_FOUND }, + { "NT_STATUS_CONTROL_C_EXIT", NT_STATUS_CONTROL_C_EXIT }, + { "NT_STATUS_LOCAL_DISCONNECT", NT_STATUS_LOCAL_DISCONNECT }, + { "NT_STATUS_REMOTE_DISCONNECT", NT_STATUS_REMOTE_DISCONNECT }, + { "NT_STATUS_REMOTE_RESOURCES", NT_STATUS_REMOTE_RESOURCES }, + { "NT_STATUS_LINK_FAILED", NT_STATUS_LINK_FAILED }, + { "NT_STATUS_LINK_TIMEOUT", NT_STATUS_LINK_TIMEOUT }, + { "NT_STATUS_INVALID_CONNECTION", NT_STATUS_INVALID_CONNECTION }, + { "NT_STATUS_INVALID_ADDRESS", NT_STATUS_INVALID_ADDRESS }, + { "NT_STATUS_DLL_INIT_FAILED", NT_STATUS_DLL_INIT_FAILED }, + { "NT_STATUS_MISSING_SYSTEMFILE", NT_STATUS_MISSING_SYSTEMFILE }, + { "NT_STATUS_UNHANDLED_EXCEPTION", NT_STATUS_UNHANDLED_EXCEPTION }, + { "NT_STATUS_APP_INIT_FAILURE", NT_STATUS_APP_INIT_FAILURE }, + { "NT_STATUS_PAGEFILE_CREATE_FAILED", NT_STATUS_PAGEFILE_CREATE_FAILED }, + { "NT_STATUS_NO_PAGEFILE", NT_STATUS_NO_PAGEFILE }, + { "NT_STATUS_INVALID_LEVEL", NT_STATUS_INVALID_LEVEL }, + { "NT_STATUS_WRONG_PASSWORD_CORE", NT_STATUS_WRONG_PASSWORD_CORE }, + { "NT_STATUS_ILLEGAL_FLOAT_CONTEXT", NT_STATUS_ILLEGAL_FLOAT_CONTEXT }, + { "NT_STATUS_PIPE_BROKEN", NT_STATUS_PIPE_BROKEN }, + { "NT_STATUS_REGISTRY_CORRUPT", NT_STATUS_REGISTRY_CORRUPT }, + { "NT_STATUS_REGISTRY_IO_FAILED", NT_STATUS_REGISTRY_IO_FAILED }, + { "NT_STATUS_NO_EVENT_PAIR", NT_STATUS_NO_EVENT_PAIR }, + { "NT_STATUS_UNRECOGNIZED_VOLUME", NT_STATUS_UNRECOGNIZED_VOLUME }, + { "NT_STATUS_SERIAL_NO_DEVICE_INITED", NT_STATUS_SERIAL_NO_DEVICE_INITED }, + { "NT_STATUS_NO_SUCH_ALIAS", NT_STATUS_NO_SUCH_ALIAS }, + { "NT_STATUS_MEMBER_NOT_IN_ALIAS", NT_STATUS_MEMBER_NOT_IN_ALIAS }, + { "NT_STATUS_MEMBER_IN_ALIAS", NT_STATUS_MEMBER_IN_ALIAS }, + { "NT_STATUS_ALIAS_EXISTS", NT_STATUS_ALIAS_EXISTS }, + { "NT_STATUS_LOGON_NOT_GRANTED", NT_STATUS_LOGON_NOT_GRANTED }, + { "NT_STATUS_TOO_MANY_SECRETS", NT_STATUS_TOO_MANY_SECRETS }, + { "NT_STATUS_SECRET_TOO_LONG", NT_STATUS_SECRET_TOO_LONG }, + { "NT_STATUS_INTERNAL_DB_ERROR", NT_STATUS_INTERNAL_DB_ERROR }, + { "NT_STATUS_FULLSCREEN_MODE", NT_STATUS_FULLSCREEN_MODE }, + { "NT_STATUS_TOO_MANY_CONTEXT_IDS", NT_STATUS_TOO_MANY_CONTEXT_IDS }, + { "NT_STATUS_LOGON_TYPE_NOT_GRANTED", NT_STATUS_LOGON_TYPE_NOT_GRANTED }, + { "NT_STATUS_NOT_REGISTRY_FILE", NT_STATUS_NOT_REGISTRY_FILE }, + { "NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED }, + { "NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR", NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR }, + { "NT_STATUS_FT_MISSING_MEMBER", NT_STATUS_FT_MISSING_MEMBER }, + { "NT_STATUS_ILL_FORMED_SERVICE_ENTRY", NT_STATUS_ILL_FORMED_SERVICE_ENTRY }, + { "NT_STATUS_ILLEGAL_CHARACTER", NT_STATUS_ILLEGAL_CHARACTER }, + { "NT_STATUS_UNMAPPABLE_CHARACTER", NT_STATUS_UNMAPPABLE_CHARACTER }, + { "NT_STATUS_UNDEFINED_CHARACTER", NT_STATUS_UNDEFINED_CHARACTER }, + { "NT_STATUS_FLOPPY_VOLUME", NT_STATUS_FLOPPY_VOLUME }, + { "NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND", NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND }, + { "NT_STATUS_FLOPPY_WRONG_CYLINDER", NT_STATUS_FLOPPY_WRONG_CYLINDER }, + { "NT_STATUS_FLOPPY_UNKNOWN_ERROR", NT_STATUS_FLOPPY_UNKNOWN_ERROR }, + { "NT_STATUS_FLOPPY_BAD_REGISTERS", NT_STATUS_FLOPPY_BAD_REGISTERS }, + { "NT_STATUS_DISK_RECALIBRATE_FAILED", NT_STATUS_DISK_RECALIBRATE_FAILED }, + { "NT_STATUS_DISK_OPERATION_FAILED", NT_STATUS_DISK_OPERATION_FAILED }, + { "NT_STATUS_DISK_RESET_FAILED", NT_STATUS_DISK_RESET_FAILED }, + { "NT_STATUS_SHARED_IRQ_BUSY", NT_STATUS_SHARED_IRQ_BUSY }, + { "NT_STATUS_FT_ORPHANING", NT_STATUS_FT_ORPHANING }, + { "NT_STATUS_PARTITION_FAILURE", NT_STATUS_PARTITION_FAILURE }, + { "NT_STATUS_INVALID_BLOCK_LENGTH", NT_STATUS_INVALID_BLOCK_LENGTH }, + { "NT_STATUS_DEVICE_NOT_PARTITIONED", NT_STATUS_DEVICE_NOT_PARTITIONED }, + { "NT_STATUS_UNABLE_TO_LOCK_MEDIA", NT_STATUS_UNABLE_TO_LOCK_MEDIA }, + { "NT_STATUS_UNABLE_TO_UNLOAD_MEDIA", NT_STATUS_UNABLE_TO_UNLOAD_MEDIA }, + { "NT_STATUS_EOM_OVERFLOW", NT_STATUS_EOM_OVERFLOW }, + { "NT_STATUS_NO_MEDIA", NT_STATUS_NO_MEDIA }, + { "NT_STATUS_NO_SUCH_MEMBER", NT_STATUS_NO_SUCH_MEMBER }, + { "NT_STATUS_INVALID_MEMBER", NT_STATUS_INVALID_MEMBER }, + { "NT_STATUS_KEY_DELETED", NT_STATUS_KEY_DELETED }, + { "NT_STATUS_NO_LOG_SPACE", NT_STATUS_NO_LOG_SPACE }, + { "NT_STATUS_TOO_MANY_SIDS", NT_STATUS_TOO_MANY_SIDS }, + { "NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, + { "NT_STATUS_KEY_HAS_CHILDREN", NT_STATUS_KEY_HAS_CHILDREN }, + { "NT_STATUS_CHILD_MUST_BE_VOLATILE", NT_STATUS_CHILD_MUST_BE_VOLATILE }, + { "NT_STATUS_DEVICE_CONFIGURATION_ERROR", NT_STATUS_DEVICE_CONFIGURATION_ERROR }, + { "NT_STATUS_DRIVER_INTERNAL_ERROR", NT_STATUS_DRIVER_INTERNAL_ERROR }, + { "NT_STATUS_INVALID_DEVICE_STATE", NT_STATUS_INVALID_DEVICE_STATE }, + { "NT_STATUS_IO_DEVICE_ERROR", NT_STATUS_IO_DEVICE_ERROR }, + { "NT_STATUS_DEVICE_PROTOCOL_ERROR", NT_STATUS_DEVICE_PROTOCOL_ERROR }, + { "NT_STATUS_BACKUP_CONTROLLER", NT_STATUS_BACKUP_CONTROLLER }, + { "NT_STATUS_LOG_FILE_FULL", NT_STATUS_LOG_FILE_FULL }, + { "NT_STATUS_TOO_LATE", NT_STATUS_TOO_LATE }, + { "NT_STATUS_NO_TRUST_LSA_SECRET", NT_STATUS_NO_TRUST_LSA_SECRET }, + { "NT_STATUS_NO_TRUST_SAM_ACCOUNT", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, + { "NT_STATUS_TRUSTED_DOMAIN_FAILURE", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, + { "NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, + { "NT_STATUS_EVENTLOG_FILE_CORRUPT", NT_STATUS_EVENTLOG_FILE_CORRUPT }, + { "NT_STATUS_EVENTLOG_CANT_START", NT_STATUS_EVENTLOG_CANT_START }, + { "NT_STATUS_TRUST_FAILURE", NT_STATUS_TRUST_FAILURE }, + { "NT_STATUS_MUTANT_LIMIT_EXCEEDED", NT_STATUS_MUTANT_LIMIT_EXCEEDED }, + { "NT_STATUS_NETLOGON_NOT_STARTED", NT_STATUS_NETLOGON_NOT_STARTED }, + { "NT_STATUS_ACCOUNT_EXPIRED", NT_STATUS_ACCOUNT_EXPIRED }, + { "NT_STATUS_POSSIBLE_DEADLOCK", NT_STATUS_POSSIBLE_DEADLOCK }, + { "NT_STATUS_NETWORK_CREDENTIAL_CONFLICT", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, + { "NT_STATUS_REMOTE_SESSION_LIMIT", NT_STATUS_REMOTE_SESSION_LIMIT }, + { "NT_STATUS_EVENTLOG_FILE_CHANGED", NT_STATUS_EVENTLOG_FILE_CHANGED }, + { "NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, + { "NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, + { "NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, + { "NT_STATUS_DOMAIN_TRUST_INCONSISTENT", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, + { "NT_STATUS_FS_DRIVER_REQUIRED", NT_STATUS_FS_DRIVER_REQUIRED }, + { "NT_STATUS_NO_USER_SESSION_KEY", NT_STATUS_NO_USER_SESSION_KEY }, + { "NT_STATUS_USER_SESSION_DELETED", NT_STATUS_USER_SESSION_DELETED }, + { "NT_STATUS_RESOURCE_LANG_NOT_FOUND", NT_STATUS_RESOURCE_LANG_NOT_FOUND }, + { "NT_STATUS_INSUFF_SERVER_RESOURCES", NT_STATUS_INSUFF_SERVER_RESOURCES }, + { "NT_STATUS_INVALID_BUFFER_SIZE", NT_STATUS_INVALID_BUFFER_SIZE }, + { "NT_STATUS_INVALID_ADDRESS_COMPONENT", NT_STATUS_INVALID_ADDRESS_COMPONENT }, + { "NT_STATUS_INVALID_ADDRESS_WILDCARD", NT_STATUS_INVALID_ADDRESS_WILDCARD }, + { "NT_STATUS_TOO_MANY_ADDRESSES", NT_STATUS_TOO_MANY_ADDRESSES }, + { "NT_STATUS_ADDRESS_ALREADY_EXISTS", NT_STATUS_ADDRESS_ALREADY_EXISTS }, + { "NT_STATUS_ADDRESS_CLOSED", NT_STATUS_ADDRESS_CLOSED }, + { "NT_STATUS_CONNECTION_DISCONNECTED", NT_STATUS_CONNECTION_DISCONNECTED }, + { "NT_STATUS_CONNECTION_RESET", NT_STATUS_CONNECTION_RESET }, + { "NT_STATUS_TOO_MANY_NODES", NT_STATUS_TOO_MANY_NODES }, + { "NT_STATUS_TRANSACTION_ABORTED", NT_STATUS_TRANSACTION_ABORTED }, + { "NT_STATUS_TRANSACTION_TIMED_OUT", NT_STATUS_TRANSACTION_TIMED_OUT }, + { "NT_STATUS_TRANSACTION_NO_RELEASE", NT_STATUS_TRANSACTION_NO_RELEASE }, + { "NT_STATUS_TRANSACTION_NO_MATCH", NT_STATUS_TRANSACTION_NO_MATCH }, + { "NT_STATUS_TRANSACTION_RESPONDED", NT_STATUS_TRANSACTION_RESPONDED }, + { "NT_STATUS_TRANSACTION_INVALID_ID", NT_STATUS_TRANSACTION_INVALID_ID }, + { "NT_STATUS_TRANSACTION_INVALID_TYPE", NT_STATUS_TRANSACTION_INVALID_TYPE }, + { "NT_STATUS_NOT_SERVER_SESSION", NT_STATUS_NOT_SERVER_SESSION }, + { "NT_STATUS_NOT_CLIENT_SESSION", NT_STATUS_NOT_CLIENT_SESSION }, + { "NT_STATUS_CANNOT_LOAD_REGISTRY_FILE", NT_STATUS_CANNOT_LOAD_REGISTRY_FILE }, + { "NT_STATUS_DEBUG_ATTACH_FAILED", NT_STATUS_DEBUG_ATTACH_FAILED }, + { "NT_STATUS_SYSTEM_PROCESS_TERMINATED", NT_STATUS_SYSTEM_PROCESS_TERMINATED }, + { "NT_STATUS_DATA_NOT_ACCEPTED", NT_STATUS_DATA_NOT_ACCEPTED }, + { "NT_STATUS_NO_BROWSER_SERVERS_FOUND", NT_STATUS_NO_BROWSER_SERVERS_FOUND }, + { "NT_STATUS_VDM_HARD_ERROR", NT_STATUS_VDM_HARD_ERROR }, + { "NT_STATUS_DRIVER_CANCEL_TIMEOUT", NT_STATUS_DRIVER_CANCEL_TIMEOUT }, + { "NT_STATUS_REPLY_MESSAGE_MISMATCH", NT_STATUS_REPLY_MESSAGE_MISMATCH }, + { "NT_STATUS_MAPPED_ALIGNMENT", NT_STATUS_MAPPED_ALIGNMENT }, + { "NT_STATUS_IMAGE_CHECKSUM_MISMATCH", NT_STATUS_IMAGE_CHECKSUM_MISMATCH }, + { "NT_STATUS_LOST_WRITEBEHIND_DATA", NT_STATUS_LOST_WRITEBEHIND_DATA }, + { "NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID", NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID }, + { "NT_STATUS_PASSWORD_MUST_CHANGE", NT_STATUS_PASSWORD_MUST_CHANGE }, + { "NT_STATUS_NOT_FOUND", NT_STATUS_NOT_FOUND }, + { "NT_STATUS_NOT_TINY_STREAM", NT_STATUS_NOT_TINY_STREAM }, + { "NT_STATUS_RECOVERY_FAILURE", NT_STATUS_RECOVERY_FAILURE }, + { "NT_STATUS_STACK_OVERFLOW_READ", NT_STATUS_STACK_OVERFLOW_READ }, + { "NT_STATUS_FAIL_CHECK", NT_STATUS_FAIL_CHECK }, + { "NT_STATUS_DUPLICATE_OBJECTID", NT_STATUS_DUPLICATE_OBJECTID }, + { "NT_STATUS_OBJECTID_EXISTS", NT_STATUS_OBJECTID_EXISTS }, + { "NT_STATUS_CONVERT_TO_LARGE", NT_STATUS_CONVERT_TO_LARGE }, + { "NT_STATUS_RETRY", NT_STATUS_RETRY }, + { "NT_STATUS_FOUND_OUT_OF_SCOPE", NT_STATUS_FOUND_OUT_OF_SCOPE }, + { "NT_STATUS_ALLOCATE_BUCKET", NT_STATUS_ALLOCATE_BUCKET }, + { "NT_STATUS_PROPSET_NOT_FOUND", NT_STATUS_PROPSET_NOT_FOUND }, + { "NT_STATUS_MARSHALL_OVERFLOW", NT_STATUS_MARSHALL_OVERFLOW }, + { "NT_STATUS_INVALID_VARIANT", NT_STATUS_INVALID_VARIANT }, + { "NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, + { "NT_STATUS_ACCOUNT_LOCKED_OUT", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "NT_STATUS_HANDLE_NOT_CLOSABLE", NT_STATUS_HANDLE_NOT_CLOSABLE }, + { "NT_STATUS_CONNECTION_REFUSED", NT_STATUS_CONNECTION_REFUSED }, + { "NT_STATUS_GRACEFUL_DISCONNECT", NT_STATUS_GRACEFUL_DISCONNECT }, + { "NT_STATUS_ADDRESS_ALREADY_ASSOCIATED", NT_STATUS_ADDRESS_ALREADY_ASSOCIATED }, + { "NT_STATUS_ADDRESS_NOT_ASSOCIATED", NT_STATUS_ADDRESS_NOT_ASSOCIATED }, + { "NT_STATUS_CONNECTION_INVALID", NT_STATUS_CONNECTION_INVALID }, + { "NT_STATUS_CONNECTION_ACTIVE", NT_STATUS_CONNECTION_ACTIVE }, + { "NT_STATUS_NETWORK_UNREACHABLE", NT_STATUS_NETWORK_UNREACHABLE }, + { "NT_STATUS_HOST_UNREACHABLE", NT_STATUS_HOST_UNREACHABLE }, + { "NT_STATUS_PROTOCOL_UNREACHABLE", NT_STATUS_PROTOCOL_UNREACHABLE }, + { "NT_STATUS_PORT_UNREACHABLE", NT_STATUS_PORT_UNREACHABLE }, + { "NT_STATUS_REQUEST_ABORTED", NT_STATUS_REQUEST_ABORTED }, + { "NT_STATUS_CONNECTION_ABORTED", NT_STATUS_CONNECTION_ABORTED }, + { "NT_STATUS_BAD_COMPRESSION_BUFFER", NT_STATUS_BAD_COMPRESSION_BUFFER }, + { "NT_STATUS_USER_MAPPED_FILE", NT_STATUS_USER_MAPPED_FILE }, + { "NT_STATUS_AUDIT_FAILED", NT_STATUS_AUDIT_FAILED }, + { "NT_STATUS_TIMER_RESOLUTION_NOT_SET", NT_STATUS_TIMER_RESOLUTION_NOT_SET }, + { "NT_STATUS_CONNECTION_COUNT_LIMIT", NT_STATUS_CONNECTION_COUNT_LIMIT }, + { "NT_STATUS_LOGIN_TIME_RESTRICTION", NT_STATUS_LOGIN_TIME_RESTRICTION }, + { "NT_STATUS_LOGIN_WKSTA_RESTRICTION", NT_STATUS_LOGIN_WKSTA_RESTRICTION }, + { "NT_STATUS_IMAGE_MP_UP_MISMATCH", NT_STATUS_IMAGE_MP_UP_MISMATCH }, + { "NT_STATUS_INSUFFICIENT_LOGON_INFO", NT_STATUS_INSUFFICIENT_LOGON_INFO }, + { "NT_STATUS_BAD_DLL_ENTRYPOINT", NT_STATUS_BAD_DLL_ENTRYPOINT }, + { "NT_STATUS_BAD_SERVICE_ENTRYPOINT", NT_STATUS_BAD_SERVICE_ENTRYPOINT }, + { "NT_STATUS_LPC_REPLY_LOST", NT_STATUS_LPC_REPLY_LOST }, + { "NT_STATUS_IP_ADDRESS_CONFLICT1", NT_STATUS_IP_ADDRESS_CONFLICT1 }, + { "NT_STATUS_IP_ADDRESS_CONFLICT2", NT_STATUS_IP_ADDRESS_CONFLICT2 }, + { "NT_STATUS_REGISTRY_QUOTA_LIMIT", NT_STATUS_REGISTRY_QUOTA_LIMIT }, + { "NT_STATUS_PATH_NOT_COVERED", NT_STATUS_PATH_NOT_COVERED }, + { "NT_STATUS_NO_CALLBACK_ACTIVE", NT_STATUS_NO_CALLBACK_ACTIVE }, + { "NT_STATUS_LICENSE_QUOTA_EXCEEDED", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, + { "NT_STATUS_PWD_TOO_SHORT", NT_STATUS_PWD_TOO_SHORT }, + { "NT_STATUS_PWD_TOO_RECENT", NT_STATUS_PWD_TOO_RECENT }, + { "NT_STATUS_PWD_HISTORY_CONFLICT", NT_STATUS_PWD_HISTORY_CONFLICT }, + { "NT_STATUS_PLUGPLAY_NO_DEVICE", NT_STATUS_PLUGPLAY_NO_DEVICE }, + { "NT_STATUS_UNSUPPORTED_COMPRESSION", NT_STATUS_UNSUPPORTED_COMPRESSION }, + { "NT_STATUS_INVALID_HW_PROFILE", NT_STATUS_INVALID_HW_PROFILE }, + { "NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH", NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH }, + { "NT_STATUS_DRIVER_ORDINAL_NOT_FOUND", NT_STATUS_DRIVER_ORDINAL_NOT_FOUND }, + { "NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND", NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND }, + { "NT_STATUS_RESOURCE_NOT_OWNED", NT_STATUS_RESOURCE_NOT_OWNED }, + { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, + { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, + { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, + { NULL, 0 } +}; + -- cgit From be0f2e14b5d32fe29b57e4c80f8da5c9cfa66e60 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 24 Oct 1997 13:51:17 +0000 Subject: nmblib.c : adding some debug info pipenetlog.c pipentlsa.c pipesrvsvc.c : using unistrn2 instead of unistr2 in the SAM logon username. wrong offset for command in request (use "reserved" field not cancel_count. AGH i'll get there) (This used to be commit 6d301d2cfd25b18ba18685d926d7a5bc08695b6d) --- source3/libsmb/nmblib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 121008685b..6a91b20ea8 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -697,6 +697,7 @@ BOOL send_packet(struct packet_struct *p) { case NMB_PACKET: len = build_nmb(buf,p); + debug_nmb_packet(p); break; case DGRAM_PACKET: -- cgit From 390c1f3c4d3136b454fa5eb8681fa9ca34eaacc2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 25 Oct 1997 10:58:18 +0000 Subject: Makefile : adding bits for new nt domain code byteorder.h : trying to get macros right, and not to crash on SUNOS5... client.c : added #ifdef NTDOMAIN, and created do_nt_login() function. don't want to have to recompile client.c unless absolutely necessary. credentials.c : moved deal_with_creds() [possibly inappropriately] into credentials.c ipc.c reply.c server.c uid.c : attempting to make (un)become_root() functions calleable from smbclient. this is a little tricky: smbclient might have to be another setuid root program, immediately setuid'ing to non-root, so that we can reset-uid to root to get at the smbpasswd file. or, have a secure pipe mechanism to smbd to grab smbpasswd entries. or the like. smbdes.c smbencrypt.c : created a function to generate lm and nt owf hashes. lsaparse.c ntclient.c smbparse.c : added nt client LSA_AUTH2 code. it works, too! pipenetlog.c pipentlsa.c pipesrvsvc.c : simplification. code-shuffling. getting that damn offset right for the opcode in RPC_HDR. smb.h : changed dcinfo xxx_creds to DOM_CRED structures instead of DOM_CHAL. we might need to store the server times as well. proto.h : the usual. (This used to be commit 82436a3d99d4bdce249ce9ff27fd2ca4b2447e07) --- source3/libsmb/credentials.c | 107 +++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smbdes.c | 5 ++ source3/libsmb/smbencrypt.c | 24 ++++++++++ 3 files changed, 136 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index ee7b1493e1..109a5a1b90 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -135,3 +135,110 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, } } + +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL srv_deal_with_creds(struct dcinfo *dc, DOM_CRED *clnt_cred, DOM_CRED *srv_cred) +{ + UTIME new_clnt_time; + uint32 new_cred; + + DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + + /* check that the client credentials are valid */ + if (!cred_assert(&(clnt_cred->challenge), dc->sess_key, + &(dc->clnt_cred.challenge), clnt_cred->timestamp)) + { + return False; + } + + /* increment client time by one second */ + new_clnt_time.time = clnt_cred->timestamp.time + 1; + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(dc->clnt_cred.challenge.data, 0); + new_cred += new_clnt_time.time; + + DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred)); + + /* doesn't matter that server time is 0 */ + srv_cred->timestamp.time = 0; + + DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time)); + + /* create return credentials for inclusion in the reply */ + cred_create(dc->sess_key, &(dc->clnt_cred.challenge), new_clnt_time, + &(srv_cred->challenge)); + + DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n", + dc->clnt_cred.challenge.data[0])); + + /* store new seed in client and server credentials */ + SIVAL(dc->clnt_cred.challenge.data, 0, new_cred); + SIVAL(dc->srv_cred .challenge.data, 0, new_cred); + + return True; +} + + +#if 0 +/**************************************************************************** + checks credentials; generates next step in the credential chain +****************************************************************************/ +BOOL clnt_deal_with_creds(struct dcinfo *dc, DOM_CRED *srv_cred, DOM_CRED *clnt_cred) +{ + UTIME new_clnt_time; + uint32 new_cred; + + DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + + /* setup new client time */ + dc->clnt_cred.timestamp.time = time(NULL); + + /* create sent credentials for inclusion in the reply */ + cred_create(dc->sess_key, srv_cred, dc->clnt_cred.timestamp.time, clnt_cred); + + /* increment client time by one second */ + (dc->clnt_cred.timestamp.time)++; + + /* create expected return credentials to be received from server */ + cred_create(dc->sess_key, srv_cred, dc->clnt_cred.timestamp.time, clnt_cred); + + + + /* check that the server credentials are valid */ + if (!cred_assert(&(srv_cred->challenge), dc->sess_key, + &(dc->clnt_cred), clnt_cred->timestamp)) + { + return False; + } + /* increment client time by one second */ + new_clnt_time = (dc->clnt_cred.timestamp.time += 1); + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(dc->clnt_cred.data, 0); + new_cred += new_clnt_time.time; + + DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred)); + + /* create new client credentials */ + cred_create(dc->sess_key, new_cred, new_clnt_time, clnt_cred); + + DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time)); + + /* create return credentials for inclusion in the reply + cred_create(dc->sess_key, srv_cred, new_clnt_time, + clnt_cred); + */ + DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n", + dc->clnt_cred.data[0])); + + /* store new seed in client and server credentials */ + SIVAL(dc->clnt_cred.data, 0, new_cred); + SIVAL(dc->srv_cred .data, 0, new_cred); + + return True; +} + +#endif diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 67e27016c3..9675401f14 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -329,7 +329,12 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) { unsigned char buf[8]; static unsigned char key2[8]; + int i; + for (i=0;i<8;i++) { + key2[i] = 0; + } + smbhash(buf, in, key); key2[0] = key[7]; smbhash(out, buf, key2); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 27172fd413..517ee0f941 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -109,3 +109,27 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) E_P24(p21, c8, p24); } +/* Does both the NT and LM owfs of a user's password */ + +void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16]) +{ + char passwd[129]; + strncpy(passwd, pwd, 129); + + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + E_md4hash((uchar *)passwd, nt_p16); + + /* Mangle the passwords into Lanman format */ + passwd[14] = '\0'; + strupper(passwd); + + /* Calculate the SMB (lanman) hash functions of the password */ + + memset(p16, '\0', 16); + E_P16((uchar *) passwd, p16); + + /* clear out local copy of user's password (just being paranoid). */ + bzero(passwd, sizeof(passwd)); +} + -- cgit From a342ff5bf407679918a1a5d0c2faaf0a3465d303 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Oct 1997 07:32:02 +0000 Subject: The browse synchronisation code in nmbsync.c now uses the clientgen.c code, which means we don't have to link with a fake getpass routine and we don't have a whole pile of global variables that really have nothing to do with nmbd and were there to keep the client code happy. The code should function identically to what it did before (hopefully it was correct) The only thing that now uses the horrible clientutil.c code is smbclient. (This used to be commit 4bf5c03b18f88b566f3ac12cc4b3a9c5c96fd35d) --- source3/libsmb/clientgen.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7cd2ef6903..b6ad1611ac 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -313,6 +313,79 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) } +/**************************************************************************** +call a NetServerEnum for the specified workgroup and servertype mask. +This function then calls the specified callback function for each name returned. + +The callback function takes 3 arguments: the machine name, the server type and +the comment. +****************************************************************************/ +BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, + void (*fn)(char *, uint32, char *)) +{ + char *rparam = NULL; + char *rdata = NULL; + int rdrcnt,rprcnt; + char *p; + pstring param; + int uLevel = 1; + int count = -1; + + /* send a SMBtrans command with api NetServerEnum */ + p = param; + SSVAL(p,0,0x68); /* api number */ + p += 2; + strcpy(p,"WrLehDz"); + p = skip_string(p,1); + + strcpy(p,"B16BBDz"); + + p = skip_string(p,1); + SSVAL(p,0,uLevel); + SSVAL(p,2,BUFFER_SIZE); + p += 4; + SIVAL(p,0,stype); + p += 4; + + pstrcpy(p, workgroup); + p = skip_string(p,1); + + if (cli_api(cli, + PTR_DIFF(p,param), /* param count */ + 8, /*data count */ + 0, /* mprcount */ + BUFFER_SIZE, /* mdrcount */ + &rprcnt,&rdrcnt, + param, NULL, + &rparam,&rdata)) { + int res = SVAL(rparam,0); + int converter=SVAL(rparam,2); + int i; + + if (res == 0) { + count=SVAL(rparam,4); + p = rdata; + + for (i = 0;i < count;i++, p += 26) { + char *sname = p; + int comment_offset = IVAL(p,22) & 0xFFFF; + char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + + stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + + fn(sname, stype, cmnt); + } + } + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + + return(count > 0); +} + + + static struct { int prot; -- cgit From f8c059517af070fe8718f7152a0a9c89668162fa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 26 Oct 1997 07:45:36 +0000 Subject: fix some casting errors in smbencrypt and some multiply-defined errors in clientutil.c (Luke, you can't just copy a global variable declaration from one file to another, you need to declare one of them extern) (This used to be commit 944ecbcbd47afcc20e2e408a06d57c7b8d0d86a8) --- source3/libsmb/smbdes.c | 5 ----- source3/libsmb/smbencrypt.c | 10 +++++----- 2 files changed, 5 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 9675401f14..e4f8280f9b 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -329,11 +329,6 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) { unsigned char buf[8]; static unsigned char key2[8]; - int i; - - for (i=0;i<8;i++) { - key2[i] = 0; - } smbhash(buf, in, key); key2[0] = key[7]; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 517ee0f941..38d414cf23 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -111,14 +111,14 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) /* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16]) +void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16) { - char passwd[129]; - strncpy(passwd, pwd, 129); + char passwd[130]; + StrnCpy(passwd, pwd, sizeof(passwd)-1); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash((uchar *)passwd, nt_p16); + E_md4hash((uchar *)passwd, (uchar *)nt_p16); /* Mangle the passwords into Lanman format */ passwd[14] = '\0'; @@ -127,7 +127,7 @@ void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16]) /* Calculate the SMB (lanman) hash functions of the password */ memset(p16, '\0', 16); - E_P16((uchar *) passwd, p16); + E_P16((uchar *) passwd, (uchar *)p16); /* clear out local copy of user's password (just being paranoid). */ bzero(passwd, sizeof(passwd)); -- cgit From 95b3b1473f84cd48ec3d0333c89e3280e1e10678 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 26 Oct 1997 18:42:47 +0000 Subject: hooray. hooray some more. hooray a lot. got the client-side working. Q/R LSA_REQ_CHAL; Q/R LSA_AUTH2; Q/R LSA_SAMLOGON; Q/R LSA_SAMLOGOFF. the last (non-essential right now) bit is the LSA_SRV_PWSET. the next stage is to do LSA_OPENPOLICY; add the pipe binds (missing right now); then we can test against an NT Server. (This used to be commit 0a549e62fbf11a3ff1f1de663176e30006553e08) --- source3/libsmb/credentials.c | 98 ++++++++++++++++++-------------------------- 1 file changed, 39 insertions(+), 59 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 109a5a1b90..6711604f6d 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -72,6 +72,7 @@ Output: void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, DOM_CHAL *cred) { + DOM_CHAL time_cred; unsigned char calc_cred[8]; unsigned char timecred[8]; unsigned char netsesskey[8]; @@ -87,12 +88,16 @@ void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, cred->data[0] = IVAL(calc_cred, 0); cred->data[1] = IVAL(calc_cred, 4); + time_cred.data[0] = IVAL(timecred, 0); + time_cred.data[1] = IVAL(timecred, 4); + /* debug output*/ DEBUG(4,("cred_create\n")); DEBUG(5,(" sess_key : %lx %lx\n", session_key [0], session_key [1])); DEBUG(5,(" stor_cred: %lx %lx\n", stor_cred->data[0], stor_cred->data[1])); - DEBUG(5,(" timecred : %lx %lx\n", IVAL(timecred, 0) , IVAL(timecred, 4) )); + DEBUG(5,(" timestamp: %lx\n" , timestamp.time)); + DEBUG(5,(" timecred : %lx %lx\n", time_cred .data[0], time_cred .data[1])); DEBUG(5,(" calc_cred: %lx %lx\n", cred ->data[0], cred ->data[1])); } @@ -139,106 +144,81 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, /**************************************************************************** checks credentials; generates next step in the credential chain ****************************************************************************/ -BOOL srv_deal_with_creds(struct dcinfo *dc, DOM_CRED *clnt_cred, DOM_CRED *srv_cred) +BOOL clnt_deal_with_creds(uint32 sess_key[2], + DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred) { UTIME new_clnt_time; uint32 new_cred; - DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__)); + + /* increment client time by one second */ + new_clnt_time.time = sto_clnt_cred->timestamp.time + 1; - /* check that the client credentials are valid */ - if (!cred_assert(&(clnt_cred->challenge), dc->sess_key, - &(dc->clnt_cred.challenge), clnt_cred->timestamp)) + /* check that the received server credentials are valid */ + if (!cred_assert(&(rcv_srv_cred->challenge), sess_key, + &(sto_clnt_cred->challenge), new_clnt_time)) { return False; } - /* increment client time by one second */ - new_clnt_time.time = clnt_cred->timestamp.time + 1; - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(dc->clnt_cred.challenge.data, 0); + new_cred = IVAL(sto_clnt_cred->challenge.data, 0); new_cred += new_clnt_time.time; - DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred)); - - /* doesn't matter that server time is 0 */ - srv_cred->timestamp.time = 0; - - DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time)); - - /* create return credentials for inclusion in the reply */ - cred_create(dc->sess_key, &(dc->clnt_cred.challenge), new_clnt_time, - &(srv_cred->challenge)); - - DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n", - dc->clnt_cred.challenge.data[0])); - - /* store new seed in client and server credentials */ - SIVAL(dc->clnt_cred.challenge.data, 0, new_cred); - SIVAL(dc->srv_cred .challenge.data, 0, new_cred); + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); + DEBUG(5,(" new clnt cred: %lx %lx\n", sto_clnt_cred->challenge.data[0], + sto_clnt_cred->challenge.data[1])); return True; } -#if 0 /**************************************************************************** checks credentials; generates next step in the credential chain ****************************************************************************/ -BOOL clnt_deal_with_creds(struct dcinfo *dc, DOM_CRED *srv_cred, DOM_CRED *clnt_cred) +BOOL deal_with_creds(uint32 sess_key[2], + DOM_CRED *sto_clnt_cred, + DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred) { UTIME new_clnt_time; uint32 new_cred; DEBUG(5,("deal_with_creds: %d\n", __LINE__)); - /* setup new client time */ - dc->clnt_cred.timestamp.time = time(NULL); - - /* create sent credentials for inclusion in the reply */ - cred_create(dc->sess_key, srv_cred, dc->clnt_cred.timestamp.time, clnt_cred); - - /* increment client time by one second */ - (dc->clnt_cred.timestamp.time)++; - - /* create expected return credentials to be received from server */ - cred_create(dc->sess_key, srv_cred, dc->clnt_cred.timestamp.time, clnt_cred); - - - - /* check that the server credentials are valid */ - if (!cred_assert(&(srv_cred->challenge), dc->sess_key, - &(dc->clnt_cred), clnt_cred->timestamp)) + /* check that the received client credentials are valid */ + if (!cred_assert(&(rcv_clnt_cred->challenge), sess_key, + &(sto_clnt_cred->challenge), rcv_clnt_cred->timestamp)) { return False; } + /* increment client time by one second */ - new_clnt_time = (dc->clnt_cred.timestamp.time += 1); + new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1; /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(dc->clnt_cred.data, 0); + new_cred = IVAL(sto_clnt_cred->challenge.data, 0); new_cred += new_clnt_time.time; DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred)); - /* create new client credentials */ - cred_create(dc->sess_key, new_cred, new_clnt_time, clnt_cred); + /* doesn't matter that server time is 0 */ + rtn_srv_cred->timestamp.time = 0; DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time)); - /* create return credentials for inclusion in the reply - cred_create(dc->sess_key, srv_cred, new_clnt_time, - clnt_cred); - */ + /* create return credentials for inclusion in the reply */ + cred_create(sess_key, &(sto_clnt_cred->challenge), new_clnt_time, + &(rtn_srv_cred->challenge)); + DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n", - dc->clnt_cred.data[0])); + sto_clnt_cred->challenge.data[0])); - /* store new seed in client and server credentials */ - SIVAL(dc->clnt_cred.data, 0, new_cred); - SIVAL(dc->srv_cred .data, 0, new_cred); + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); return True; } -#endif + -- cgit From 224c40a52335bf1afc7662183900e143307aa5be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 1 Nov 1997 13:22:16 +0000 Subject: a simple SMB torture tester. This will allow us to evaluate locking techniques more accurately. (This used to be commit 054e3b2ae3a8cfb98fde72becef9b05de34d2ba7) --- source3/libsmb/clientgen.c | 334 ++++++++++++++++++++++++++++++++++++++++++++- source3/libsmb/smberr.c | 182 ++++++++++++++++++++++++ 2 files changed, 513 insertions(+), 3 deletions(-) create mode 100644 source3/libsmb/smberr.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b6ad1611ac..b2ecb07ded 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -502,14 +502,29 @@ BOOL cli_session_setup(struct cli_state *cli, send a tconX ****************************************************************************/ BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pword, int passlen) + char *share, char *dev, char *pass, int passlen) { + fstring fullshare, pword; char *p; bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); + if (cli->sec_mode & 1) { + passlen = 1; + pass = ""; + } + + if ((cli->sec_mode & 2) && *pass && passlen != 24) { + passlen = 24; + SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + } else { + memcpy(pword, pass, passlen); + } + + sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); + set_message(cli->outbuf,4, - 2 + strlen(share) + passlen + strlen(dev),True); + 2 + strlen(fullshare) + passlen + strlen(dev),True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -519,7 +534,7 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - strcpy(p,share); + strcpy(p,fullshare); p = skip_string(p,1); strcpy(p,dev); @@ -556,6 +571,294 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } +/**************************************************************************** +delete a file +****************************************************************************/ +BOOL cli_unlink(struct cli_state *cli, char *fname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,1, 2 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBunlink; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,fname); + p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + + +/**************************************************************************** +open a file +****************************************************************************/ +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) +{ + char *p; + unsigned openfn=0; + unsigned accessmode=0; + + if (flags & O_CREAT) + openfn |= (1<<4); + if (!(flags & O_EXCL)) { + if (flags & O_TRUNC) + openfn |= (1<<1); + else + openfn |= (1<<0); + } + + accessmode = (share_mode<<4); + + if ((flags & O_RDWR) == O_RDWR) { + accessmode |= 2; + } else if ((flags & O_WRONLY) == O_WRONLY) { + accessmode |= 1; + } + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,15,1 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBopenX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + SSVAL(cli->outbuf,smb_vwv3,accessmode); + SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv5,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv8,openfn); + + p = smb_buf(cli->outbuf); + strcpy(p,fname); + p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2); +} + + + + +/**************************************************************************** + close a file +****************************************************************************/ +BOOL cli_close(struct cli_state *cli, int fnum) +{ + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,3,0,True); + + CVAL(cli->outbuf,smb_com) = SMBclose; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SSVAL(cli->outbuf,smb_vwv1,0); + SSVAL(cli->outbuf,smb_vwv2,0); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + +/**************************************************************************** + lock a file +****************************************************************************/ +BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,8,10,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = 0; + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,0); + SSVAL(cli->outbuf,smb_vwv7,1); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** + unlock a file +****************************************************************************/ +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,8,10,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = 0; + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,1); + SSVAL(cli->outbuf,smb_vwv7,0); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + +/**************************************************************************** + read from a file +****************************************************************************/ +int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + SSVAL(cli->outbuf,smb_vwv5,size); + SSVAL(cli->outbuf,smb_vwv6,size); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + size = SVAL(cli->inbuf, smb_vwv5); + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + + memcpy(buf, p, size); + + return size; +} + + +/**************************************************************************** + write to a file +****************************************************************************/ +int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,12,size,True); + + CVAL(cli->outbuf,smb_com) = SMBwriteX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + + SSVAL(cli->outbuf,smb_vwv10,size); + SSVAL(cli->outbuf,smb_vwv11,smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + memcpy(p, buf, size); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf, smb_vwv2); +} + /**************************************************************************** send a negprot command @@ -744,3 +1047,28 @@ void cli_shutdown(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); memset(cli, 0, sizeof(*cli)); } + +/**************************************************************************** + return a description of the error +****************************************************************************/ +char *cli_errstr(struct cli_state *cli) +{ + return smb_errstr(cli->inbuf); +} + +/**************************************************************************** + return error codes for the last packet +****************************************************************************/ +void cli_error(struct cli_state *cli, int *eclass, int *num) +{ + *eclass = CVAL(cli->inbuf,smb_rcls); + *num = SVAL(cli->inbuf,smb_err); +} + +/**************************************************************************** +set socket options on a open connection +****************************************************************************/ +void cli_sockopt(struct cli_state *cli, char *options) +{ + set_socket_options(cli->fd, options); +} diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c new file mode 100644 index 0000000000..5149568c04 --- /dev/null +++ b/source3/libsmb/smberr.c @@ -0,0 +1,182 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Copyright (C) Andrew Tridgell 1997 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + +extern int DEBUGLEVEL; + +/* error code stuff - put together by Merik Karman + merik@blackadder.dsh.oz.au */ + +typedef struct +{ + char *name; + int code; + char *message; +} err_code_struct; + +/* Dos Error Messages */ +err_code_struct dos_msgs[] = { + {"ERRbadfunc",1,"Invalid function."}, + {"ERRbadfile",2,"File not found."}, + {"ERRbadpath",3,"Directory invalid."}, + {"ERRnofids",4,"No file descriptors available"}, + {"ERRnoaccess",5,"Access denied."}, + {"ERRbadfid",6,"Invalid file handle."}, + {"ERRbadmcb",7,"Memory control blocks destroyed."}, + {"ERRnomem",8,"Insufficient server memory to perform the requested function."}, + {"ERRbadmem",9,"Invalid memory block address."}, + {"ERRbadenv",10,"Invalid environment."}, + {"ERRbadformat",11,"Invalid format."}, + {"ERRbadaccess",12,"Invalid open mode."}, + {"ERRbaddata",13,"Invalid data."}, + {"ERR",14,"reserved."}, + {"ERRbaddrive",15,"Invalid drive specified."}, + {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."}, + {"ERRdiffdevice",17,"Not same device."}, + {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."}, + {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, + {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRnosuchshare", 67, "You specified an invalid share name"}, + {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."}, + {"ERRbadpipe",230,"Pipe invalid."}, + {"ERRpipebusy",231,"All instances of the requested pipe are busy."}, + {"ERRpipeclosing",232,"Pipe close in progress."}, + {"ERRnotconnected",233,"No process on other end of pipe."}, + {"ERRmoredata",234,"There is more data to be returned."}, + {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"}, + {NULL,-1,NULL}}; + +/* Server Error Messages */ +err_code_struct server_msgs[] = { + {"ERRerror",1,"Non-specific error code."}, + {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."}, + {"ERRbadtype",3,"reserved."}, + {"ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."}, + {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."}, + {"ERRinvnetname",6,"Invalid network name in tree connect."}, + {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."}, + {"ERRqfull",49,"Print queue full (files) -- returned by open print file."}, + {"ERRqtoobig",50,"Print queue full -- no space."}, + {"ERRqeof",51,"EOF on print queue dump."}, + {"ERRinvpfid",52,"Invalid print file FID."}, + {"ERRsmbcmd",64,"The server did not recognize the command received."}, + {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."}, + {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."}, + {"ERRreserved",68,"reserved."}, + {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."}, + {"ERRreserved",70,"reserved."}, + {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."}, + {"ERRpaused",81,"Server is paused."}, + {"ERRmsgoff",82,"Not receiving messages."}, + {"ERRnoroom",83,"No room to buffer message."}, + {"ERRrmuns",87,"Too many remote user names."}, + {"ERRtimeout",88,"Operation timed out."}, + {"ERRnoresource",89,"No resources currently available for request."}, + {"ERRtoomanyuids",90,"Too many UIDs active on this session."}, + {"ERRbaduid",91,"The UID is not known as a valid ID on this session."}, + {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."}, + {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."}, + {"ERRcontmpx",252,"Continue in MPX mode."}, + {"ERRreserved",253,"reserved."}, + {"ERRreserved",254,"reserved."}, + {"ERRnosupport",0xFFFF,"Function not supported."}, + {NULL,-1,NULL}}; + +/* Hard Error Messages */ +err_code_struct hard_msgs[] = { + {"ERRnowrite",19,"Attempt to write on write-protected diskette."}, + {"ERRbadunit",20,"Unknown unit."}, + {"ERRnotready",21,"Drive not ready."}, + {"ERRbadcmd",22,"Unknown command."}, + {"ERRdata",23,"Data error (CRC)."}, + {"ERRbadreq",24,"Bad request structure length."}, + {"ERRseek",25 ,"Seek error."}, + {"ERRbadmedia",26,"Unknown media type."}, + {"ERRbadsector",27,"Sector not found."}, + {"ERRnopaper",28,"Printer out of paper."}, + {"ERRwrite",29,"Write fault."}, + {"ERRread",30,"Read fault."}, + {"ERRgeneral",31,"General failure."}, + {"ERRbadshare",32,"An open conflicts with an existing open."}, + {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRwrongdisk",34,"The wrong disk was found in a drive."}, + {"ERRFCBUnavail",35,"No FCBs are available to process request."}, + {"ERRsharebufexc",36,"A sharing buffer has been exceeded."}, + {NULL,-1,NULL}}; + + +struct +{ + int code; + char *class; + err_code_struct *err_msgs; +} err_classes[] = { + {0,"SUCCESS",NULL}, + {0x01,"ERRDOS",dos_msgs}, + {0x02,"ERRSRV",server_msgs}, + {0x03,"ERRHRD",hard_msgs}, + {0x04,"ERRXOS",NULL}, + {0xE1,"ERRRMX1",NULL}, + {0xE2,"ERRRMX2",NULL}, + {0xE3,"ERRRMX3",NULL}, + {0xFF,"ERRCMD",NULL}, + {-1,NULL,NULL}}; + + +/**************************************************************************** +return a SMB error string from a SMB buffer +****************************************************************************/ +char *smb_errstr(char *inbuf) +{ + static pstring ret; + int class = CVAL(inbuf,smb_rcls); + int num = SVAL(inbuf,smb_err); + int i,j; + + for (i=0;err_classes[i].class;i++) + if (err_classes[i].code == class) + { + if (err_classes[i].err_msgs) + { + err_code_struct *err = err_classes[i].err_msgs; + for (j=0;err[j].name;j++) + if (num == err[j].code) + { + if (DEBUGLEVEL > 0) + sprintf(ret,"%s - %s (%s)",err_classes[i].class, + err[j].name,err[j].message); + else + sprintf(ret,"%s - %s",err_classes[i].class,err[j].name); + return ret; + } + } + + sprintf(ret,"%s - %d",err_classes[i].class,num); + return ret; + } + + sprintf(ret,"Error: Unknown error (%d,%d)",class,num); + return(ret); +} -- cgit From 4012c1cc8f47c7b3271a76a362ed2e4be4e8405c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 2 Nov 1997 04:01:57 +0000 Subject: convert the credentials code back to uchar[8] from uint32[2] This should fix the byte order problems (maybe!) (This used to be commit 21878e7d8628d05786c3c76f2943e31df1096577) --- source3/libsmb/credentials.c | 84 +++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 43 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 6711604f6d..754aebca99 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -22,6 +22,22 @@ #include "includes.h" extern int DEBUGLEVEL; + + + +/**************************************************************************** +represent a credential as a string +****************************************************************************/ +char *credstr(uchar *cred) +{ + static fstring buf; + sprintf(buf,"%02X%02X%02X%02X%02X%02X%02X%02X", + cred[0], cred[1], cred[2], cred[3], + cred[4], cred[5], cred[6], cred[7]); + return buf; +} + + /**************************************************************************** setup the session key. Input: 8 byte challenge block @@ -31,11 +47,10 @@ Output: 8 byte session key ****************************************************************************/ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, - uint32 session_key[2]) + uchar session_key[8]) { uint32 sum[2]; unsigned char sum2[8]; - unsigned char netsesskey[8]; sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); @@ -43,18 +58,15 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(netsesskey, sum2,(unsigned char *)pass); - - session_key[0] = IVAL(netsesskey, 0); - session_key[1] = IVAL(netsesskey, 4); + cred_hash1(session_key, sum2,(unsigned char *)pass); /* debug output */ DEBUG(4,("cred_session_key\n")); - DEBUG(5,(" clnt_chal: %lx %lx\n", clnt_chal->data[0], clnt_chal->data[1])); - DEBUG(5,(" srv_chal : %lx %lx\n", srv_chal ->data[0], srv_chal ->data[1])); - DEBUG(5,(" clnt+srv : %lx %lx\n", sum [0], sum [1])); - DEBUG(5,(" sess_key : %lx %lx\n", session_key [0], session_key [1])); + DEBUG(5,(" clnt_chal: %s\n", credstr(clnt_chal->data))); + DEBUG(5,(" srv_chal : %s\n", credstr(srv_chal->data))); + DEBUG(5,(" clnt+srv : %s\n", credstr(sum2))); + DEBUG(5,(" sess_key : %s\n", credstr(session_key))); } @@ -69,36 +81,24 @@ Input: Output: 8 byte credential ****************************************************************************/ -void cred_create(uint32 session_key[2], DOM_CHAL *stor_cred, UTIME timestamp, +void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, DOM_CHAL *cred) { DOM_CHAL time_cred; - unsigned char calc_cred[8]; - unsigned char timecred[8]; - unsigned char netsesskey[8]; - - SIVAL(netsesskey, 0, session_key[0]); - SIVAL(netsesskey, 4, session_key[1]); - - SIVAL(timecred, 0, IVAL(stor_cred, 0) + timestamp.time); - SIVAL(timecred, 4, IVAL(stor_cred, 4)); - - cred_hash2(calc_cred, timecred, netsesskey); - cred->data[0] = IVAL(calc_cred, 0); - cred->data[1] = IVAL(calc_cred, 4); + SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time); + SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4)); - time_cred.data[0] = IVAL(timecred, 0); - time_cred.data[1] = IVAL(timecred, 4); + cred_hash2(cred->data, time_cred.data, session_key); /* debug output*/ DEBUG(4,("cred_create\n")); - DEBUG(5,(" sess_key : %lx %lx\n", session_key [0], session_key [1])); - DEBUG(5,(" stor_cred: %lx %lx\n", stor_cred->data[0], stor_cred->data[1])); + DEBUG(5,(" sess_key : %s\n", credstr(session_key))); + DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); DEBUG(5,(" timestamp: %lx\n" , timestamp.time)); - DEBUG(5,(" timecred : %lx %lx\n", time_cred .data[0], time_cred .data[1])); - DEBUG(5,(" calc_cred: %lx %lx\n", cred ->data[0], cred ->data[1])); + DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); + DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); } @@ -115,7 +115,7 @@ Output: returns 1 if computed credential matches received credential returns 0 otherwise ****************************************************************************/ -int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, +int cred_assert(DOM_CHAL *cred, char session_key[8], DOM_CHAL *stored_cred, UTIME timestamp) { DOM_CHAL cred2; @@ -125,8 +125,8 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, /* debug output*/ DEBUG(4,("cred_assert\n")); - DEBUG(5,(" challenge : %lx %lx\n", cred->data[0], cred->data[1])); - DEBUG(5,(" calculated: %lx %lx\n", cred2.data[0], cred2.data[1])); + DEBUG(5,(" challenge : %s\n", credstr(cred->data))); + DEBUG(5,(" calculated: %s\n", credstr(cred2.data))); if (memcmp(cred->data, cred2.data, 8) == 0) { @@ -144,8 +144,8 @@ int cred_assert(DOM_CHAL *cred, uint32 session_key[2], DOM_CHAL *stored_cred, /**************************************************************************** checks credentials; generates next step in the credential chain ****************************************************************************/ -BOOL clnt_deal_with_creds(uint32 sess_key[2], - DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred) +BOOL clnt_deal_with_creds(char sess_key[8], + DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred) { UTIME new_clnt_time; uint32 new_cred; @@ -157,7 +157,7 @@ BOOL clnt_deal_with_creds(uint32 sess_key[2], /* check that the received server credentials are valid */ if (!cred_assert(&(rcv_srv_cred->challenge), sess_key, - &(sto_clnt_cred->challenge), new_clnt_time)) + &(sto_clnt_cred->challenge), new_clnt_time)) { return False; } @@ -169,8 +169,7 @@ BOOL clnt_deal_with_creds(uint32 sess_key[2], /* store new seed in client credentials */ SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); - DEBUG(5,(" new clnt cred: %lx %lx\n", sto_clnt_cred->challenge.data[0], - sto_clnt_cred->challenge.data[1])); + DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data))); return True; } @@ -178,9 +177,9 @@ BOOL clnt_deal_with_creds(uint32 sess_key[2], /**************************************************************************** checks credentials; generates next step in the credential chain ****************************************************************************/ -BOOL deal_with_creds(uint32 sess_key[2], - DOM_CRED *sto_clnt_cred, - DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred) +BOOL deal_with_creds(uchar sess_key[8], + DOM_CRED *sto_clnt_cred, + DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred) { UTIME new_clnt_time; uint32 new_cred; @@ -212,8 +211,7 @@ BOOL deal_with_creds(uint32 sess_key[2], cred_create(sess_key, &(sto_clnt_cred->challenge), new_clnt_time, &(rtn_srv_cred->challenge)); - DEBUG(5,("deal_with_creds: clnt_cred[0]=%lx\n", - sto_clnt_cred->challenge.data[0])); + DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data))); /* store new seed in client credentials */ SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); -- cgit From e67c2e9dc64e8a9f848d2769c33eef1d09fdb3e1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 2 Nov 1997 04:11:05 +0000 Subject: fix some uchar/char conflicts (This used to be commit c164681dfe2ad9623a59f01eea914bf27d4801e5) --- source3/libsmb/credentials.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 754aebca99..b06ca6ffc6 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -115,7 +115,7 @@ Output: returns 1 if computed credential matches received credential returns 0 otherwise ****************************************************************************/ -int cred_assert(DOM_CHAL *cred, char session_key[8], DOM_CHAL *stored_cred, +int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, UTIME timestamp) { DOM_CHAL cred2; @@ -144,7 +144,7 @@ int cred_assert(DOM_CHAL *cred, char session_key[8], DOM_CHAL *stored_cred, /**************************************************************************** checks credentials; generates next step in the credential chain ****************************************************************************/ -BOOL clnt_deal_with_creds(char sess_key[8], +BOOL clnt_deal_with_creds(uchar sess_key[8], DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred) { UTIME new_clnt_time; -- cgit From a90d2061316d19c30d9f14c1e78d6f6266183ce0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Nov 1997 04:02:05 +0000 Subject: added two more sets of tests to the smbtorture test. The tests I added are ones that I know Samba fails. They are: 1) correct support for retaining locks over a close (ie. the server must not use posix semantics) 2) support for lock timeouts 3) the server supports multiple locking contexts on the one SMB connection, distinguished by PID. 4) the server correctly fails overlapping locks made by the same PID (this goes against POSIX behaviour, which is why it is tricky to implement) 5) the server denies unlock requests by an incorrect client PID I've been discussing with Jeremy ways that we can re-implement the locking code to handle these correctly. This test code will be useful to see that we have got it right. (This used to be commit 097781e2992f12c545170c82ada2f4023a9784f5) --- source3/libsmb/clientgen.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b2ecb07ded..b98f2fca69 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1072,3 +1072,13 @@ void cli_sockopt(struct cli_state *cli, char *options) { set_socket_options(cli->fd, options); } + +/**************************************************************************** +set the PID to use for smb messages. Return the old pid. +****************************************************************************/ +int cli_setpid(struct cli_state *cli, int pid) +{ + int ret = cli->pid; + cli->pid = pid; + return ret; +} -- cgit From e357d9106895b165bfa3f8331b9f186004c9a6cd Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 9 Nov 1997 17:30:10 +0000 Subject: attempting to mark up 32 bit error codes, needed for NT domains. separated out smb server-mode password validation into a separate file. added called and calling netbios names to client gen state: referenced section in rfc1002.txt. created workstation trust account checking code in ntclient.c there might be a bug in reply_session_setup_andX. i indented and added { } around single-line if statements: the lm password checking code now doesn't look right (around the GUEST_SESSSETUP bits). *no code semantics have been changed by the indentation process*. (This used to be commit f27966957fa7f16d337a4a58719239d036deab4c) --- source3/libsmb/clientgen.c | 146 +++++++++++++++++++++++++------------------- source3/libsmb/nterr.c | 30 ++++++++- source3/libsmb/smbencrypt.c | 22 +++++-- source3/libsmb/smberr.c | 26 +++++++- 4 files changed, 149 insertions(+), 75 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b98f2fca69..78bbf8115f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -104,7 +104,7 @@ static BOOL cli_send_trans(struct cli_state *cli, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || - CVAL(cli->inbuf,smb_rcls) != 0) { + cli_error(cli,NULL, NULL)) { return(False); } @@ -176,8 +176,7 @@ static BOOL cli_receive_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (CVAL(cli->inbuf,smb_rcls) != 0) - return(False); + if (cli_error(cli,NULL, NULL)) return(False); /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -227,8 +226,7 @@ static BOOL cli_receive_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (CVAL(cli->inbuf,smb_rcls) != 0) - return(False); + if (cli_error(cli,NULL, NULL)) return(False); } return(True); @@ -300,7 +298,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privilages = SVAL(p, 24); + cli->privileges = SVAL(p, 24); fstrcpy(cli->eff_name,p+2); } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error)); @@ -424,15 +422,22 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & USE_CHALLENGE_RESPONSE) && *pass && passlen != 24) + { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - } else { + } + else + { memcpy(pword, pass, passlen); } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} + if (!(cli->sec_mode & USE_USER_LEVEL_SECURITY)) + { + fstrcpy(pword, ""); + passlen=1; + } /* send a session setup command */ bzero(cli->outbuf,smb_size); @@ -487,9 +492,7 @@ BOOL cli_session_setup(struct cli_state *cli, show_msg(cli->inbuf); - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return(False); /* use the returned uid from now on */ cli->uid = SVAL(cli->inbuf,smb_uid); @@ -509,19 +512,19 @@ BOOL cli_send_tconX(struct cli_state *cli, bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); - if (cli->sec_mode & 1) { + if (cli->sec_mode & USE_USER_LEVEL_SECURITY) { passlen = 1; pass = ""; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & USE_CHALLENGE_RESPONSE) && *pass && passlen != 24) { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); } else { memcpy(pword, pass, passlen); } - sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); + sprintf(fullshare, "\\\\%s\\%s", cli->called_netbios_name, share); set_message(cli->outbuf,4, 2 + strlen(fullshare) + passlen + strlen(dev),True); @@ -544,9 +547,7 @@ BOOL cli_send_tconX(struct cli_state *cli, if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return(False); cli->cnum = SVAL(cli->inbuf,smb_tid); return True; @@ -568,7 +569,7 @@ BOOL cli_tdis(struct cli_state *cli) if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; - return CVAL(cli->inbuf,smb_rcls) == 0; + return !cli_error(cli,NULL, NULL); } /**************************************************************************** @@ -599,9 +600,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return False; return True; } @@ -659,9 +658,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } + if (cli_error(cli,NULL, NULL)) return -1; return SVAL(cli->inbuf,smb_vwv2); } @@ -692,9 +689,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return False; return True; } @@ -733,9 +728,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return False; return True; } @@ -773,9 +766,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli,NULL, NULL)) return False; return True; } @@ -808,9 +799,7 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } + if (cli_error(cli,NULL, NULL)) return -1; size = SVAL(cli->inbuf, smb_vwv5); p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); @@ -852,9 +841,7 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } + if (cli_error(cli,NULL, NULL)) return -1; return SVAL(cli->inbuf, smb_vwv2); } @@ -899,10 +886,8 @@ BOOL cli_negprot(struct cli_state *cli) show_msg(cli->inbuf); - if (CVAL(cli->inbuf,smb_rcls) != 0 || - ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { - return(False); - } + if (cli_error(cli,NULL, NULL)) return False; + if ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots) return(False); cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; @@ -936,33 +921,43 @@ BOOL cli_negprot(struct cli_state *cli) return True; } +#define TRUNCATE_NETBIOS_NAME 1 /**************************************************************************** - send a session request + send a session request. see rfc1002.txt 4.3 and 4.3.2 ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, - char *myname) +BOOL cli_session_request(struct cli_state *cli, + char *called_host_name , int called_name_type, + char calling_netbios_name[16], int calling_name_type) { - fstring dest; char *p; int len = 4; /* send a session request (RFC 1002) */ - fstrcpy(dest,host); + strncpy(cli->called_netbios_name , called_host_name , sizeof(cli->called_netbios_name )); + strncpy(cli->calling_netbios_name, calling_netbios_name, sizeof(cli->calling_netbios_name)); - p = strchr(dest,'.'); + /* sorry, don't trust strncpy to null-terminate the string... */ + cli->called_netbios_name [sizeof(cli->called_netbios_name )-1] = 0; + cli->calling_netbios_name[sizeof(cli->calling_netbios_name)-1] = 0; + +#ifdef TRUNCATE_NETBIOS_NAME + /* ok. this is because of a stupid microsoft-ism. if the called host + name contains a '.', microsoft clients expect you to truncate the + netbios name up to and including the '.' + */ + p = strchr(cli->called_netbios_name, '.'); if (p) *p = 0; - - fstrcpy(cli->desthost, dest); +#endif /* TRUNCATE_NETBIOS_NAME */ /* put in the destination name */ p = cli->outbuf+len; - name_mangle(dest,p,name_type); + name_mangle(cli->called_netbios_name, p, called_name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; - name_mangle(myname,p,0); + name_mangle(cli->calling_netbios_name, p, calling_name_type); len += name_len(p); /* setup the packet length */ @@ -990,26 +985,27 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) { struct in_addr dest_ip; - fstrcpy(cli->desthost, host); + fstrcpy(cli->full_dest_host_name, host); - if (!ip) { + if (!ip) + { + /* no ip specified - look up the name */ struct hostent *hp; - if ((hp = Get_Hostbyname(cli->desthost)) == 0) { + if ((hp = Get_Hostbyname(host)) == 0) { return False; } putip((char *)&dest_ip,(char *)hp->h_addr); } else { + /* use the given ip address */ dest_ip = *ip; } - + /* open the socket */ cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout); - if (cli->fd == -1) - return False; - return True; + return (cli->fd != -1); } @@ -1059,10 +1055,32 @@ char *cli_errstr(struct cli_state *cli) /**************************************************************************** return error codes for the last packet ****************************************************************************/ -void cli_error(struct cli_state *cli, int *eclass, int *num) +BOOL cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { - *eclass = CVAL(cli->inbuf,smb_rcls); - *num = SVAL(cli->inbuf,smb_err); + int flgs2 = SVAL(cli->inbuf,smb_flg2); + + if (eclass) *eclass = 0; + if (num ) *num = 0; + + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + { + /* 32 bit error codes detected */ + uint32 nt_err = IVAL(cli->inbuf,smb_rcls); + if (num) *num = nt_err; + return (nt_err != 0); + } + else + { + /* dos 16 bit error codes detected */ + char rcls = CVAL(cli->inbuf,smb_rcls); + if (rcls != 0) + { + if (eclass) *eclass = rcls; + if (num ) *num = SVAL(cli->inbuf,smb_err); + return True; + } + } + return False; } /**************************************************************************** diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index bda0f882a6..7dd2234e1d 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -1,12 +1,16 @@ +/* NT error codes. please read nterr.h */ +#include "includes.h" #include "nterr.h" -static struct +typedef struct { char *nt_errstr; uint16 nt_errcode; -} nt_errs[] = +} nt_err_code_struct; + +nt_err_code_struct nt_errs[] = { { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, @@ -512,3 +516,25 @@ static struct { NULL, 0 } }; +/***************************************************************************** + returns an NT error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +char *get_nt_error_msg(uint16 nt_code) +{ + static pstring msg; + int idx = 0; + + strcpy(msg, "Unknown NT error"); + + while (nt_errs[idx].nt_errstr != NULL) + { + if (nt_errs[idx].nt_errcode == nt_code) + { + strcpy(msg, nt_errs[idx].nt_errstr); + return msg; + } + idx++; + } + return NULL; +} + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 38d414cf23..1bf0bcc8e6 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -29,8 +29,9 @@ extern int DEBUGLEVEL; /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of - encrypted password into p24 */ -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) + encrypted password into p24 + */ +void SMBencrypt(uchar *passwd, uchar *c8, uchar p24[24]) { uchar p14[15], p21[21]; @@ -97,9 +98,19 @@ void E_md4hash(uchar *passwd, uchar *p16) mdfour(p16, (unsigned char *)wpwd, len); } -/* Does the NT MD4 hash then des encryption. */ +/* Does the des encryption from the NT or LM MD4 hash. */ +void SMBOWFencrypt(char passwd[16], uchar *c8, uchar p24[24]) +{ + uchar p21[21]; + + memset(p21,'\0',21); -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) + memcpy(p21, passwd, sizeof(passwd)); + E_P24(p21, c8, p24); +} + +/* Does the NT MD4 hash then des encryption. */ +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar p24[24]) { uchar p21[21]; @@ -110,8 +121,7 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) } /* Does both the NT and LM owfs of a user's password */ - -void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16) +void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16]) { char passwd[130]; StrnCpy(passwd, pwd, sizeof(passwd)-1); diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 5149568c04..35cd0bf88f 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -151,9 +151,28 @@ return a SMB error string from a SMB buffer char *smb_errstr(char *inbuf) { static pstring ret; + int i,j; + BOOL nt_errors = (SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES; + + if (nt_errors) + { + char *nt_errstr = NULL; + uint32 nt_err = IVAL(inbuf, smb_rcls); + uint16 nt_num = nt_err & 0x0000ffff; + uint16 class = (nt_err & 0xffff0000) >> 16; + + /* maybe lookup the error message in the nt error codes... */ + if ((nt_errstr = get_nt_error_msg(nt_num)) != NULL) + { + sprintf(ret,"NT Error: (%4x, %s)", class, nt_errstr); + return ret; + } + sprintf(ret,"NT Error: Unknown error (%4x %4x)", class, nt_num); + } + else + { int class = CVAL(inbuf,smb_rcls); int num = SVAL(inbuf,smb_err); - int i,j; for (i=0;err_classes[i].class;i++) if (err_classes[i].code == class) @@ -176,7 +195,8 @@ char *smb_errstr(char *inbuf) sprintf(ret,"%s - %d",err_classes[i].class,num); return ret; } - - sprintf(ret,"Error: Unknown error (%d,%d)",class,num); + sprintf(ret,"Error: Unknown error (%4x,%d)", class, num); + } + return(ret); } -- cgit From 77aec4ae6307c0ad0b843bbf23d64ccb1aaf7476 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Nov 1997 19:23:17 +0000 Subject: Rolled back tree state to 11:59pm 8th November 1997 EST to remove problems. Jeremy (This used to be commit 4a36ac236c2ad634f05efcd0179875d09988614a) --- source3/libsmb/clientgen.c | 146 +++++++++++++++++++------------------------- source3/libsmb/nterr.c | 30 +-------- source3/libsmb/smbencrypt.c | 22 ++----- source3/libsmb/smberr.c | 26 +------- 4 files changed, 75 insertions(+), 149 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 78bbf8115f..b98f2fca69 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -104,7 +104,7 @@ static BOOL cli_send_trans(struct cli_state *cli, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || - cli_error(cli,NULL, NULL)) { + CVAL(cli->inbuf,smb_rcls) != 0) { return(False); } @@ -176,7 +176,8 @@ static BOOL cli_receive_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_error(cli,NULL, NULL)) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0) + return(False); /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -226,7 +227,8 @@ static BOOL cli_receive_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_error(cli,NULL, NULL)) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0) + return(False); } return(True); @@ -298,7 +300,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privileges = SVAL(p, 24); + cli->privilages = SVAL(p, 24); fstrcpy(cli->eff_name,p+2); } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error)); @@ -422,22 +424,15 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if ((cli->sec_mode & USE_CHALLENGE_RESPONSE) && *pass && passlen != 24) - { + if ((cli->sec_mode & 2) && *pass && passlen != 24) { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - } - else - { + } else { memcpy(pword, pass, passlen); } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & USE_USER_LEVEL_SECURITY)) - { - fstrcpy(pword, ""); - passlen=1; - } + if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} /* send a session setup command */ bzero(cli->outbuf,smb_size); @@ -492,7 +487,9 @@ BOOL cli_session_setup(struct cli_state *cli, show_msg(cli->inbuf); - if (cli_error(cli,NULL, NULL)) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } /* use the returned uid from now on */ cli->uid = SVAL(cli->inbuf,smb_uid); @@ -512,19 +509,19 @@ BOOL cli_send_tconX(struct cli_state *cli, bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); - if (cli->sec_mode & USE_USER_LEVEL_SECURITY) { + if (cli->sec_mode & 1) { passlen = 1; pass = ""; } - if ((cli->sec_mode & USE_CHALLENGE_RESPONSE) && *pass && passlen != 24) { + if ((cli->sec_mode & 2) && *pass && passlen != 24) { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); } else { memcpy(pword, pass, passlen); } - sprintf(fullshare, "\\\\%s\\%s", cli->called_netbios_name, share); + sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); set_message(cli->outbuf,4, 2 + strlen(fullshare) + passlen + strlen(dev),True); @@ -547,7 +544,9 @@ BOOL cli_send_tconX(struct cli_state *cli, if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; - if (cli_error(cli,NULL, NULL)) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } cli->cnum = SVAL(cli->inbuf,smb_tid); return True; @@ -569,7 +568,7 @@ BOOL cli_tdis(struct cli_state *cli) if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; - return !cli_error(cli,NULL, NULL); + return CVAL(cli->inbuf,smb_rcls) == 0; } /**************************************************************************** @@ -600,7 +599,9 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) return False; } - if (cli_error(cli,NULL, NULL)) return False; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } return True; } @@ -658,7 +659,9 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) return -1; } - if (cli_error(cli,NULL, NULL)) return -1; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } return SVAL(cli->inbuf,smb_vwv2); } @@ -689,7 +692,9 @@ BOOL cli_close(struct cli_state *cli, int fnum) return False; } - if (cli_error(cli,NULL, NULL)) return False; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } return True; } @@ -728,7 +733,9 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti return False; } - if (cli_error(cli,NULL, NULL)) return False; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } return True; } @@ -766,7 +773,9 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int return False; } - if (cli_error(cli,NULL, NULL)) return False; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } return True; } @@ -799,7 +808,9 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s return -1; } - if (cli_error(cli,NULL, NULL)) return -1; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } size = SVAL(cli->inbuf, smb_vwv5); p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); @@ -841,7 +852,9 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 return -1; } - if (cli_error(cli,NULL, NULL)) return -1; + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } return SVAL(cli->inbuf, smb_vwv2); } @@ -886,8 +899,10 @@ BOOL cli_negprot(struct cli_state *cli) show_msg(cli->inbuf); - if (cli_error(cli,NULL, NULL)) return False; - if ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots) return(False); + if (CVAL(cli->inbuf,smb_rcls) != 0 || + ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { + return(False); + } cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; @@ -921,43 +936,33 @@ BOOL cli_negprot(struct cli_state *cli) return True; } -#define TRUNCATE_NETBIOS_NAME 1 /**************************************************************************** - send a session request. see rfc1002.txt 4.3 and 4.3.2 + send a session request ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, - char *called_host_name , int called_name_type, - char calling_netbios_name[16], int calling_name_type) +BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, + char *myname) { + fstring dest; char *p; int len = 4; /* send a session request (RFC 1002) */ - strncpy(cli->called_netbios_name , called_host_name , sizeof(cli->called_netbios_name )); - strncpy(cli->calling_netbios_name, calling_netbios_name, sizeof(cli->calling_netbios_name)); + fstrcpy(dest,host); - /* sorry, don't trust strncpy to null-terminate the string... */ - cli->called_netbios_name [sizeof(cli->called_netbios_name )-1] = 0; - cli->calling_netbios_name[sizeof(cli->calling_netbios_name)-1] = 0; - -#ifdef TRUNCATE_NETBIOS_NAME - /* ok. this is because of a stupid microsoft-ism. if the called host - name contains a '.', microsoft clients expect you to truncate the - netbios name up to and including the '.' - */ - p = strchr(cli->called_netbios_name, '.'); + p = strchr(dest,'.'); if (p) *p = 0; -#endif /* TRUNCATE_NETBIOS_NAME */ + + fstrcpy(cli->desthost, dest); /* put in the destination name */ p = cli->outbuf+len; - name_mangle(cli->called_netbios_name, p, called_name_type); + name_mangle(dest,p,name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; - name_mangle(cli->calling_netbios_name, p, calling_name_type); + name_mangle(myname,p,0); len += name_len(p); /* setup the packet length */ @@ -985,27 +990,26 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) { struct in_addr dest_ip; - fstrcpy(cli->full_dest_host_name, host); + fstrcpy(cli->desthost, host); - if (!ip) - { - /* no ip specified - look up the name */ + if (!ip) { struct hostent *hp; - if ((hp = Get_Hostbyname(host)) == 0) { + if ((hp = Get_Hostbyname(cli->desthost)) == 0) { return False; } putip((char *)&dest_ip,(char *)hp->h_addr); } else { - /* use the given ip address */ dest_ip = *ip; } - /* open the socket */ + cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout); + if (cli->fd == -1) + return False; - return (cli->fd != -1); + return True; } @@ -1055,32 +1059,10 @@ char *cli_errstr(struct cli_state *cli) /**************************************************************************** return error codes for the last packet ****************************************************************************/ -BOOL cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) +void cli_error(struct cli_state *cli, int *eclass, int *num) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); - - if (eclass) *eclass = 0; - if (num ) *num = 0; - - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) - { - /* 32 bit error codes detected */ - uint32 nt_err = IVAL(cli->inbuf,smb_rcls); - if (num) *num = nt_err; - return (nt_err != 0); - } - else - { - /* dos 16 bit error codes detected */ - char rcls = CVAL(cli->inbuf,smb_rcls); - if (rcls != 0) - { - if (eclass) *eclass = rcls; - if (num ) *num = SVAL(cli->inbuf,smb_err); - return True; - } - } - return False; + *eclass = CVAL(cli->inbuf,smb_rcls); + *num = SVAL(cli->inbuf,smb_err); } /**************************************************************************** diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 7dd2234e1d..bda0f882a6 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -1,16 +1,12 @@ -/* NT error codes. please read nterr.h */ -#include "includes.h" #include "nterr.h" -typedef struct +static struct { char *nt_errstr; uint16 nt_errcode; -} nt_err_code_struct; - -nt_err_code_struct nt_errs[] = +} nt_errs[] = { { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, @@ -516,25 +512,3 @@ nt_err_code_struct nt_errs[] = { NULL, 0 } }; -/***************************************************************************** - returns an NT error message. not amazingly helpful, but better than a number. - *****************************************************************************/ -char *get_nt_error_msg(uint16 nt_code) -{ - static pstring msg; - int idx = 0; - - strcpy(msg, "Unknown NT error"); - - while (nt_errs[idx].nt_errstr != NULL) - { - if (nt_errs[idx].nt_errcode == nt_code) - { - strcpy(msg, nt_errs[idx].nt_errstr); - return msg; - } - idx++; - } - return NULL; -} - diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 1bf0bcc8e6..38d414cf23 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -29,9 +29,8 @@ extern int DEBUGLEVEL; /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of - encrypted password into p24 - */ -void SMBencrypt(uchar *passwd, uchar *c8, uchar p24[24]) + encrypted password into p24 */ +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) { uchar p14[15], p21[21]; @@ -98,19 +97,9 @@ void E_md4hash(uchar *passwd, uchar *p16) mdfour(p16, (unsigned char *)wpwd, len); } -/* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(char passwd[16], uchar *c8, uchar p24[24]) -{ - uchar p21[21]; - - memset(p21,'\0',21); - - memcpy(p21, passwd, sizeof(passwd)); - E_P24(p21, c8, p24); -} - /* Does the NT MD4 hash then des encryption. */ -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar p24[24]) + +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) { uchar p21[21]; @@ -121,7 +110,8 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar p24[24]) } /* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(char *pwd, char nt_p16[16], char p16[16]) + +void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16) { char passwd[130]; StrnCpy(passwd, pwd, sizeof(passwd)-1); diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 35cd0bf88f..5149568c04 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -151,28 +151,9 @@ return a SMB error string from a SMB buffer char *smb_errstr(char *inbuf) { static pstring ret; - int i,j; - BOOL nt_errors = (SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES) == FLAGS2_32_BIT_ERROR_CODES; - - if (nt_errors) - { - char *nt_errstr = NULL; - uint32 nt_err = IVAL(inbuf, smb_rcls); - uint16 nt_num = nt_err & 0x0000ffff; - uint16 class = (nt_err & 0xffff0000) >> 16; - - /* maybe lookup the error message in the nt error codes... */ - if ((nt_errstr = get_nt_error_msg(nt_num)) != NULL) - { - sprintf(ret,"NT Error: (%4x, %s)", class, nt_errstr); - return ret; - } - sprintf(ret,"NT Error: Unknown error (%4x %4x)", class, nt_num); - } - else - { int class = CVAL(inbuf,smb_rcls); int num = SVAL(inbuf,smb_err); + int i,j; for (i=0;err_classes[i].class;i++) if (err_classes[i].code == class) @@ -195,8 +176,7 @@ char *smb_errstr(char *inbuf) sprintf(ret,"%s - %d",err_classes[i].class,num); return ret; } - sprintf(ret,"Error: Unknown error (%4x,%d)", class, num); - } - + + sprintf(ret,"Error: Unknown error (%d,%d)",class,num); return(ret); } -- cgit From 5b6d9d4376ff163a4ee4b4e7a7939c56e5394ffb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Nov 1997 02:38:54 +0000 Subject: fixed a bug which caused nmbd to core dump. The problem was incorrect parameters to cli_NetServerEnum() (This used to be commit 628d5895aa8a6add1a76bcf2561d01881b7c8c63) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b98f2fca69..66d54a9b99 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -352,8 +352,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, if (cli_api(cli, PTR_DIFF(p,param), /* param count */ - 8, /*data count */ - 0, /* mprcount */ + 0, /*data count */ + 8, /* mprcount */ BUFFER_SIZE, /* mdrcount */ &rprcnt,&rdrcnt, param, NULL, -- cgit From 6a6653f8152a0caf523639eca913f22431b2211a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Nov 1997 23:50:02 +0000 Subject: changed nmblookup to only set recursion_desired in queries if the -R option is used. (This used to be commit 4561b8242e12c63401d008e7fdb2442457bd366d) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 55f70be122..15bf58bc55 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -214,7 +214,7 @@ BOOL name_query(int fd,char *name,int name_type, nmb->header.response = False; nmb->header.nm_flags.bcast = bcast; nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = True; + nmb->header.nm_flags.recursion_desired = recurse; nmb->header.nm_flags.trunc = False; nmb->header.nm_flags.authoritative = False; nmb->header.rcode = 0; -- cgit From 8bf0f359f3ec440ace0bba6c12ca65d25ba45fd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 02:41:22 +0000 Subject: added a test for the NT SMBgetatr bug in smbtorture added support for choosing the protocol level in smbtorture (-m option) use -1 for null date in cli_close() get the attributes right in cli_open() (This used to be commit d64d40a6ec57a4a999ae1f39175bcfd86ccb196e) --- source3/libsmb/clientgen.c | 78 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 59 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 66d54a9b99..031c0c10de 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -368,8 +368,9 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, for (i = 0;i < count;i++, p += 26) { char *sname = p; - int comment_offset = IVAL(p,22) & 0xFFFF; - char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; + char *cmnt = comment_offset?(rdata+comment_offset):""; + if (comment_offset < 0 || comment_offset > rdrcnt) continue; stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; @@ -418,7 +419,7 @@ BOOL cli_session_setup(struct cli_state *cli, fstring pword; if (cli->protocol < PROTOCOL_LANMAN1) - return False; + return True; if (passlen > sizeof(pword)-1) { return False; @@ -647,7 +648,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ SSVAL(cli->outbuf,smb_vwv3,accessmode); SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); - SSVAL(cli->outbuf,smb_vwv5,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv8,openfn); p = smb_buf(cli->outbuf); @@ -684,8 +685,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,fnum); - SSVAL(cli->outbuf,smb_vwv1,0); - SSVAL(cli->outbuf,smb_vwv2,0); + SIVALS(cli->outbuf,smb_vwv1,-1); send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -860,6 +860,44 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 } +/**************************************************************************** +stat a file (actually a SMBgetattr call) +This only fills in a few of the stat fields +****************************************************************************/ +BOOL cli_stat(struct cli_state *cli, char *fname, struct stat *st) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,0,strlen(fname)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBgetatr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p = 4; + strcpy(p+1, fname); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + memset(st, 0, sizeof(*st)); + st->st_size = IVAL(cli->inbuf, smb_vwv3); + + st->st_mtime = make_unix_date3(cli->inbuf+smb_vwv1); + return True; +} + + /**************************************************************************** send a negprot command ****************************************************************************/ @@ -907,19 +945,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if (cli->protocol < PROTOCOL_NT1) { - cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); - cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); - cli->sesskey = IVAL(cli->inbuf,smb_vwv6); - cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; - /* this time is converted to GMT by make_unix_date */ - cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); - if (cli->protocol >= PROTOCOL_COREPLUS) { - cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); - cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); - } - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - } else { + if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); @@ -931,6 +957,20 @@ BOOL cli_negprot(struct cli_state *cli) if (IVAL(cli->inbuf,smb_vwv9+1) & 1) cli->readbraw_supported = cli->writebraw_supported = True; + } else if (cli->protocol >= PROTOCOL_LANMAN1) { + cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); + cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); + cli->sesskey = IVAL(cli->inbuf,smb_vwv6); + cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; + /* this time is converted to GMT by make_unix_date */ + cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); + cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); + cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + } else { + /* the old core protocol */ + cli->sec_mode = 0; + cli->serverzone = TimeDiff(time(NULL)); } return True; -- cgit From a1c5442abb3bc221157ca3620d35e1a013b26232 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 03:09:59 +0000 Subject: test SMBsetatr as well (This used to be commit 2f29c24ba721e417828efca57011ed45892191a5) --- source3/libsmb/clientgen.c | 57 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 031c0c10de..39d1226f9d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -861,10 +861,10 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 /**************************************************************************** -stat a file (actually a SMBgetattr call) -This only fills in a few of the stat fields +do a SMBgetatr call ****************************************************************************/ -BOOL cli_stat(struct cli_state *cli, char *fname, struct stat *st) +BOOL cli_getatr(struct cli_state *cli, char *fname, + int *attr, uint32 *size, time_t *t) { char *p; @@ -890,10 +890,55 @@ BOOL cli_stat(struct cli_state *cli, char *fname, struct stat *st) return False; } - memset(st, 0, sizeof(*st)); - st->st_size = IVAL(cli->inbuf, smb_vwv3); + if (size) { + *size = IVAL(cli->inbuf, smb_vwv3); + } + + if (t) { + *t = make_unix_date3(cli->inbuf+smb_vwv1); + } + + if (attr) { + *attr = SVAL(cli->inbuf,smb_vwv0); + } + + + return True; +} + + +/**************************************************************************** +do a SMBsetatr call +****************************************************************************/ +BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,8,strlen(fname)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBsetatr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0, attr); + put_dos_date3(cli->outbuf,smb_vwv1, t); + + p = smb_buf(cli->outbuf); + *p = 4; + strcpy(p+1, fname); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } - st->st_mtime = make_unix_date3(cli->inbuf+smb_vwv1); return True; } -- cgit From c16d132bf95d96e2aa572cb9ba18a68abfbbeb8d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 05:55:44 +0000 Subject: added some QPATHINFO and QFILEINFO tests into smbtorture. This tests for things like midnight access times, sticky create times and word reversed INFO_STANDARD returns (This used to be commit 89141de14edf9e46ab279d2a74a9b026716a0ba8) --- source3/libsmb/clientgen.c | 116 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 111 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 39d1226f9d..7060467aee 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -24,6 +24,7 @@ #endif #include "includes.h" +#include "trans2.h" extern int DEBUGLEVEL; @@ -57,8 +58,8 @@ static BOOL cli_send_trans(struct cli_state *cli, char *outdata,*outparam; char *p; - this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*SIZEOFWORD)); /* hack */ - this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*SIZEOFWORD+this_lparam)); + this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ + this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); bzero(cli->outbuf,smb_size); set_message(cli->outbuf,14+lsetup,0,True); @@ -83,7 +84,7 @@ static BOOL cli_send_trans(struct cli_state *cli, SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ for (i=0;ioutbuf,smb_setup+i*SIZEOFWORD,setup[i]); + SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); p = smb_buf(cli->outbuf); if (trans==SMBtrans) { strcpy(p,name); /* name[] */ @@ -131,7 +132,7 @@ static BOOL cli_send_trans(struct cli_state *cli, SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ if (trans==SMBtrans2) - SSVAL(cli->outbuf,smb_sfid,fid); /* fid */ + SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ if (this_lparam) /* param[] */ memcpy(outparam,param,this_lparam); if (this_ldata) /* data[] */ @@ -243,7 +244,7 @@ static BOOL cli_api(struct cli_state *cli, int *rdrcnt, char *param,char *data, char **rparam, char **rdata) { - cli_send_trans(cli,SMBtrans,"\\PIPE\\LANMAN",0,0, + cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0, data,param,NULL, drcnt,prcnt,0, mdrcnt,mprcnt,0); @@ -942,6 +943,111 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) return True; } +/**************************************************************************** +send a qpathinfo call +****************************************************************************/ +BOOL cli_qpathinfo(struct cli_state *cli, char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + param_len = strlen(fname) + 7; + + memset(param, 0, param_len); + SSVAL(param, 0, SMB_INFO_STANDARD); + pstrcpy(¶m[6], fname); + + if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, + NULL, param, &setup, + data_len, param_len, 1, + cli->max_xmit, 10, 0)) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, + &rdata, &rparam)) { + return False; + } + + if (!rdata || data_len < 22) { + return False; + } + + if (c_time) { + *c_time = make_unix_date2(rdata+0); + } + if (a_time) { + *a_time = make_unix_date2(rdata+4); + } + if (m_time) { + *m_time = make_unix_date2(rdata+8); + } + if (size) { + *size = IVAL(rdata, 12); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + + +/**************************************************************************** +send a qfileinfo call +****************************************************************************/ +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QFILEINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + param_len = 4; + + memset(param, 0, param_len); + SSVAL(param, 0, fnum); + SSVAL(param, 2, SMB_INFO_STANDARD); + + if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, + NULL, param, &setup, + data_len, param_len, 1, + cli->max_xmit, 2, 0)) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, + &rdata, &rparam)) { + return False; + } + + if (!rdata || data_len < 22) { + return False; + } + + if (c_time) { + *c_time = make_unix_date2(rdata+0); + } + if (a_time) { + *a_time = make_unix_date2(rdata+4); + } + if (m_time) { + *m_time = make_unix_date2(rdata+8); + } + if (size) { + *size = IVAL(rdata, 12); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + /**************************************************************************** send a negprot command -- cgit From 931d0150b0751d2e52cded550061374826214943 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 07:26:42 +0000 Subject: added a SMB_QUERY_FILE_ALL_INFO test into smbtorture W95 doesn't seem to support this call. (This used to be commit 162947c6e672580216c6223a44d25b874f0487ab) --- source3/libsmb/clientgen.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7060467aee..89557905fc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -995,6 +995,62 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, return True; } +/**************************************************************************** +send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level +****************************************************************************/ +BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, uint32 *size) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + param_len = strlen(fname) + 7; + + memset(param, 0, param_len); + SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); + pstrcpy(¶m[6], fname); + + if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, + NULL, param, &setup, + data_len, param_len, 1, + cli->max_xmit, 10, 0)) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, + &rdata, &rparam)) { + return False; + } + + if (!rdata || data_len < 22) { + return False; + } + + if (c_time) { + *c_time = interpret_long_date(rdata+0) - cli->serverzone; + } + if (a_time) { + *a_time = interpret_long_date(rdata+8) - cli->serverzone; + } + if (m_time) { + *m_time = interpret_long_date(rdata+16) - cli->serverzone; + } + if (w_time) { + *w_time = interpret_long_date(rdata+24) - cli->serverzone; + } + if (size) { + *size = IVAL(rdata, 40); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + /**************************************************************************** send a qfileinfo call -- cgit From ebe7c7a173efa32057908af43a5c3d74d8b3739a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 24 Nov 1997 13:44:52 +0000 Subject: added cli_rmdir and cli_mkdir added test in smbtorture for the server updating the directory modify time when a file is added to a directory cleanup in smbtorture so no garbage files are left on the server (This used to be commit 3a5e07f1e994396853e6340e8ef3f4d12bb0243e) --- source3/libsmb/clientgen.c | 66 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 89557905fc..1bd55cffe8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -594,7 +594,71 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; strcpy(p,fname); - p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + +/**************************************************************************** +create a directory +****************************************************************************/ +BOOL cli_mkdir(struct cli_state *cli, char *dname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,0, 2 + strlen(dname),True); + + CVAL(cli->outbuf,smb_com) = SMBmkdir; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,dname); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** +remove a directory +****************************************************************************/ +BOOL cli_rmdir(struct cli_state *cli, char *dname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,0, 2 + strlen(dname),True); + + CVAL(cli->outbuf,smb_com) = SMBrmdir; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,dname); send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { -- cgit From 15a6097263d4d5179b0eed43ede74fd65a83e090 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 30 Nov 1997 02:58:34 +0000 Subject: clientgen.c: Added cli_mv() (used in a recent torture test). reply.c: Changed reply_open_and_X to split out the oplock request bits from core and extended and if an oplock was granted only set the corresponding bit on reply. server.c: Added code to dynamically allocate i/o buffers in oplock_break (prevents recursion problems) , also made reset of sent_oplock_break explicit. Jeremy. (This used to be commit 16e55ee2b8be9a4210d8cf87691cdf42373759d2) --- source3/libsmb/clientgen.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1bd55cffe8..69e940845c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -573,6 +573,43 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } +/**************************************************************************** +rename a file +****************************************************************************/ +BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); + + CVAL(cli->outbuf,smb_com) = SMBmv; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,fname_src); + p = skip_string(p,1); + *p++ = 4; + strcpy(p,fname_dst); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + /**************************************************************************** delete a file ****************************************************************************/ -- cgit From f97a49c39e467b1efb93fc3b585af92c3e52f606 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 1997 23:30:43 +0000 Subject: add the null string to SMBsetatr calls (This used to be commit fbb2be050ded099741345a101ba13e6b12ebc823) --- source3/libsmb/clientgen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 69e940845c..d827eadfe1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1019,7 +1019,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); - set_message(cli->outbuf,8,strlen(fname)+2,True); + set_message(cli->outbuf,8,strlen(fname)+4,True); CVAL(cli->outbuf,smb_com) = SMBsetatr; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1031,6 +1031,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) p = smb_buf(cli->outbuf); *p = 4; strcpy(p+1, fname); + p = skip_string(p,1); + *p = 4; send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { -- cgit From 64f0348a3f994334abe64a4d4896109c3c8c9039 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Dec 1997 14:16:07 +0000 Subject: This is it ! The mega-merge of the JRA_NMBD_REWRITE branch back into the main tree. For the cvs logs of all the files starting nmbd_*.c, look in the JRA_NMBD_REWRITE branch. That branch has now been discontinued. Jeremy. (This used to be commit d80b0cb645f81d16734929a0b27a91c6650499bb) --- source3/libsmb/namequery.c | 36 ++++++---- source3/libsmb/nmblib.c | 161 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 170 insertions(+), 27 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 15bf58bc55..9915ee92a8 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -189,21 +189,25 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, /**************************************************************************** do a netbios name query to find someones IP + returns an array of IP addresses or NULL if none + *count will be set to the number of addresses returned ****************************************************************************/ -BOOL name_query(int fd,char *name,int name_type, - BOOL bcast,BOOL recurse, - struct in_addr to_ip, struct in_addr *ip,void (*fn)()) +struct in_addr *name_query(int fd,char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count, void (*fn)()) { BOOL found=False; - int retries = 3; + int i, retries = 3; int retry_time = bcast?250:2000; struct timeval tval; struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; static int name_trn_id = 0; + struct in_addr *ip_list = NULL; bzero((char *)&p,sizeof(p)); + (*count) = 0; if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100); @@ -237,7 +241,7 @@ BOOL name_query(int fd,char *name,int name_type, GetTimeOfDay(&tval); if (!send_packet(&p)) - return(False); + return NULL; retries--; @@ -248,7 +252,7 @@ BOOL name_query(int fd,char *name,int name_type, if (TvalDiff(&tval,&tval2) > retry_time) { if (!retries) break; if (!found && !send_packet(&p)) - return False; + return NULL; GetTimeOfDay(&tval); retries--; } @@ -256,7 +260,7 @@ BOOL name_query(int fd,char *name,int name_type, if ((p2=receive_packet(fd,NMB_PACKET,90))) { struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); + debug_nmb_packet(p2); if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response) { @@ -279,11 +283,17 @@ BOOL name_query(int fd,char *name,int name_type, continue; } - if (ip) { - putip((char *)ip,&nmb2->answers->rdata[2]); - DEBUG(fn?3:2,("Got a positive name query response from %s", - inet_ntoa(p2->ip))); - DEBUG(fn?3:2,(" (%s)\n",inet_ntoa(*ip))); + ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) * + ((*count)+nmb2->answers->rdlength/6)); + if (ip_list) { + DEBUG(fn?3:2,("Got a positive name query response from %s ( ", + inet_ntoa(p2->ip))); + for (i=0;ianswers->rdlength/6;i++) { + putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); + DEBUG(fn?3:2,("%s ",inet_ntoa(ip_list[(*count)]))); + (*count)++; + } + DEBUG(fn?3:2,(")\n")); } found=True; retries=0; free_packet(p2); @@ -291,5 +301,5 @@ BOOL name_query(int fd,char *name,int name_type, } } - return(found); + return ip_list; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6a91b20ea8..0335f01833 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -34,11 +34,13 @@ static struct opcode_names { char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { - { "Query", 0 }, + {"Query", 0 }, {"Registration", 5 }, {"Release", 6 }, {"WACK", 7 }, - {"refresh", 8 }, + {"Refresh", 8 }, + {"Refresh(altcode)", 9 }, + {"Multi-homed Registration", 15 }, {0, -1 } }; @@ -205,7 +207,7 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na if (n==16) { /* parse out the name type, its always in the 16th byte of the name */ - name->name_type = name->name[15]; + name->name_type = ((unsigned char)name->name[15]) & 0xff; /* remove trailing spaces */ name->name[15] = 0; @@ -249,6 +251,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) /* special case for wildcard name */ bzero(buf1,20); buf1[0] = '*'; + buf1[15] = name->name_type; } else { sprintf(buf1,"%-15.15s%c",name->name,name->name_type); } @@ -292,9 +295,9 @@ char *namestr(struct nmb_name *n) char *p = ret[i]; if (!n->scope[0]) - sprintf(p,"%s(%x)",n->name,n->name_type); + sprintf(p,"%s<%02x>",n->name,n->name_type); else - sprintf(p,"%s(%x).%s",n->name,n->name_type,n->scope); + sprintf(p,"%s<%02x>.%s",n->name,n->name_type,n->scope); i = (i+1)%4; return(p); @@ -467,26 +470,146 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) return(True); } +/******************************************************************* + 'Copy constructor' for an nmb packet + ******************************************************************/ +static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) +{ + struct nmb_packet *nmb; + struct nmb_packet *copy_nmb; + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) + { + DEBUG(0,("copy_nmb_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* Ensure this copy has no resource records. */ + nmb = &packet->packet.nmb; + copy_nmb = &pkt_copy->packet.nmb; + + copy_nmb->answers = NULL; + copy_nmb->nsrecs = NULL; + copy_nmb->additional = NULL; + + /* Now copy any resource records. */ + + if (nmb->answers) + { + if((copy_nmb->answers = (struct res_rec *) + malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->answers, (char *)nmb->answers, + nmb->header.ancount * sizeof(struct res_rec)); + } + if (nmb->nsrecs) + { + if((copy_nmb->nsrecs = (struct res_rec *) + malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, + nmb->header.nscount * sizeof(struct res_rec)); + } + if (nmb->additional) + { + if((copy_nmb->additional = (struct res_rec *) + malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->additional, (char *)nmb->additional, + nmb->header.arcount * sizeof(struct res_rec)); + } + + return pkt_copy; + +free_and_exit: + + if(copy_nmb->answers) + free((char *)copy_nmb->answers); + if(copy_nmb->nsrecs) + free((char *)copy_nmb->nsrecs); + if(copy_nmb->additional) + free((char *)copy_nmb->additional); + free((char *)pkt_copy); + + DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); + return NULL; +} + +/******************************************************************* + 'Copy constructor' for a dgram packet + ******************************************************************/ +static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) +{ + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) + { + DEBUG(0,("copy_dgram_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* There are no additional pointers in a dgram packet, + we are finished. */ + return pkt_copy; +} + +/******************************************************************* + 'Copy constructor' for a generic packet + ******************************************************************/ +struct packet_struct *copy_packet(struct packet_struct *packet) +{ + if(packet->packet_type == NMB_PACKET) + return copy_nmb_packet(packet); + else if (packet->packet_type == DGRAM_PACKET) + return copy_dgram_packet(packet); + return NULL; +} + /******************************************************************* free up any resources associated with an nmb packet ******************************************************************/ -void free_nmb_packet(struct nmb_packet *nmb) +static void free_nmb_packet(struct nmb_packet *nmb) { if (nmb->answers) free(nmb->answers); if (nmb->nsrecs) free(nmb->nsrecs); if (nmb->additional) free(nmb->additional); } +/******************************************************************* + free up any resources associated with a dgram packet + ******************************************************************/ +static void free_dgram_packet(struct dgram_packet *nmb) +{ + /* We have nothing to do for a dgram packet. */ +} + /******************************************************************* free up any resources associated with a packet ******************************************************************/ void free_packet(struct packet_struct *packet) { - if (packet->locked) - return; - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - free(packet); + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + else if (packet->packet_type == DGRAM_PACKET) + free_dgram_packet(&packet->packet.dgram); + free(packet); } /******************************************************************* @@ -619,12 +742,22 @@ static int build_dgram(char *buf,struct packet_struct *p) ******************************************************************/ void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) { - fstrcpy(n->name,name); + StrnCpy(n->name,name,15); strupper(n->name); - n->name_type = type; - fstrcpy(n->scope,this_scope); + n->name_type = (unsigned int)type & 0xFF; + StrnCpy(n->scope,this_scope,63); } +/******************************************************************* + Compare two nmb names + ******************************************************************/ + +BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) +{ + return ((n1->name_type == n2->name_type) && + strequal(n1->name ,n2->name ) && + strequal(n1->scope,n2->scope)); +} /******************************************************************* build a nmb packet ready for sending -- cgit From be71d43585cf4b42efff7995dbf061fddd6077f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 20 Dec 1997 14:36:11 +0000 Subject: client.c: clientgen.c: clientutil.c: clitar.c: Changed usage of receive_smb to new function client_receive_smb except for one use of receive_smb in client.c. This is the receive_smb used to discard packets received whilst in a keyboard wait state. util.c: Created new function client_receive_smb that ignores session keepalives just as the old receive_smb used to do. Created internal function read_smb_length_return_keepalive that is used internally by the changed receive_smb call. Changed read_smb_len to not use an internal buffer - it is never called with a null buffer so such code is redundant. Jeremy. (This used to be commit 1084fb46821cb96702da35439da4a8df9d255698) --- source3/libsmb/clientgen.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d827eadfe1..4185c19fea 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -104,7 +104,7 @@ static BOOL cli_send_trans(struct cli_state *cli, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout) || + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout) || CVAL(cli->inbuf,smb_rcls) != 0) { return(False); } @@ -165,7 +165,7 @@ static BOOL cli_receive_trans(struct cli_state *cli, *data_len = *param_len = 0; - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; show_msg(cli->inbuf); @@ -216,7 +216,7 @@ static BOOL cli_receive_trans(struct cli_state *cli, if (total_data <= *data_len && total_param <= *param_len) break; - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; show_msg(cli->inbuf); @@ -484,7 +484,7 @@ BOOL cli_session_setup(struct cli_state *cli, } send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; show_msg(cli->inbuf); @@ -543,7 +543,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; if (CVAL(cli->inbuf,smb_rcls) != 0) { @@ -567,7 +567,7 @@ BOOL cli_tdis(struct cli_state *cli) cli_setup_packet(cli); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; return CVAL(cli->inbuf,smb_rcls) == 0; @@ -599,7 +599,7 @@ BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) strcpy(p,fname_dst); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -633,7 +633,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) strcpy(p,fname); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -666,7 +666,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) strcpy(p,dname); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -698,7 +698,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) strcpy(p,dname); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -758,7 +758,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) p = skip_string(p,1); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -790,7 +790,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SIVALS(cli->outbuf,smb_vwv1,-1); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -831,7 +831,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SIVAL(p, 6, len); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -871,7 +871,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 6, len); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -906,7 +906,7 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s SSVAL(cli->outbuf,smb_vwv6,size); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -950,7 +950,7 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 memcpy(p, buf, size); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -984,7 +984,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, strcpy(p+1, fname); send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1035,7 +1035,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) *p = 4; send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1242,7 +1242,7 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; send_smb(cli->fd,cli->outbuf); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; show_msg(cli->inbuf); @@ -1322,7 +1322,7 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, send_smb(cli->fd,cli->outbuf); DEBUG(5,("Sent session request\n")); - if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; if (CVAL(cli->inbuf,0) != 0x82) { -- cgit From 4f9674d1c85f2e7293874477ae0da15fee1538c7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jan 1998 08:58:00 +0000 Subject: reply.c: server.c: Test fix for NT worstation SMBmv oplock bug. smbdes.c: Addition of 'forward' parameter in preparation of allowing password change. Jeremy. (This used to be commit 0b0b1fb122a52e67a8fdc77d013ad0b3bbb90d19) --- source3/libsmb/smbdes.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index e4f8280f9b..c3cc2c7133 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -178,7 +178,7 @@ static void xor(char *out, char *in1, char *in2, int n) out[i] = in1[i] ^ in2[i]; } -static void dohash(char *out, char *in, char *key) +static void dohash(char *out, char *in, char *key, int forw) { int i, j, k; char pk1[56]; @@ -222,7 +222,7 @@ static void dohash(char *out, char *in, char *key) permute(er, r, perm4, 48); - xor(erk, er, ki[i], 48); + xor(erk, er, ki[forw ? i : 15 - i], 48); for (j=0;j<8;j++) for (k=0;k<6;k++) @@ -275,7 +275,7 @@ static void str_to_key(unsigned char *str,unsigned char *key) } -static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) +static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) { int i; char outb[64]; @@ -291,7 +291,7 @@ static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) outb[i] = 0; } - dohash(outb, inb, keyb); + dohash(outb, inb, keyb, forw); for (i=0;i<8;i++) { out[i] = 0; @@ -306,23 +306,23 @@ static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key) void E_P16(unsigned char *p14,unsigned char *p16) { unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - smbhash(p16, sp8, p14); - smbhash(p16+8, sp8, p14+7); + smbhash(p16, sp8, p14, 1); + smbhash(p16+8, sp8, p14+7, 1); } void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) { - smbhash(p24, c8, p21); - smbhash(p24+8, c8, p21+7); - smbhash(p24+16, c8, p21+14); + smbhash(p24, c8, p21, 1); + smbhash(p24+8, c8, p21+7, 1); + smbhash(p24+16, c8, p21+14, 1); } void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) { unsigned char buf[8]; - smbhash(buf, in, key); - smbhash(out, buf, key+9); + smbhash(buf, in, key, 1); + smbhash(out, buf, key+9, 1); } void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) @@ -330,8 +330,8 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) unsigned char buf[8]; static unsigned char key2[8]; - smbhash(buf, in, key); + smbhash(buf, in, key, 1); key2[0] = key[7]; - smbhash(out, buf, key2); + smbhash(out, buf, key2, 1); } -- cgit From 1ea8ceac458501719a055700902d456304c4ee0a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Jan 1998 07:08:21 +0000 Subject: charcnv.c: Added codepage 866 support onto the file system. Patch from Max Khon . chgpasswd.c: Allow old RAP change password to work with encrypted passwords. Samba can now allow Windows 95/NT clients to securely change the Lanman password ! (But not the NT hash - that gets lost). ipc.c: smbdes.c: smbpass.c: Support for the above. server.c: #ifdef'ed out fix for NT redirector bug. util.c: Fix NIS bug with server name. Jeremy. (This used to be commit cd9fad92d0316e5a0007ba3c5668906dc2f011f1) --- source3/libsmb/smbdes.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index c3cc2c7133..7446f31e15 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -317,6 +317,12 @@ void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) smbhash(p24+16, c8, p21+14, 1); } +void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) +{ + smbhash(out, in, p14, 0); + smbhash(out+8, in+8, p14+7, 0); +} + void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) { unsigned char buf[8]; -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/credentials.c | 2 +- source3/libsmb/namequery.c | 2 +- source3/libsmb/nmblib.c | 2 +- source3/libsmb/smbdes.c | 2 +- source3/libsmb/smbencrypt.c | 2 +- source3/libsmb/smberr.c | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4185c19fea..319a77beb6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB client generic functions - Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Andrew Tridgell 1994-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index b06ca6ffc6..9f5c70e5e4 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. code to manipulate domain credentials - Copyright (C) Andrew Tridgell 1997 + Copyright (C) Andrew Tridgell 1997-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 9915ee92a8..207f064670 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. name query routines - Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Andrew Tridgell 1994-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 0335f01833..1400b88434 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. NBT netbios library routines - Copyright (C) Andrew Tridgell 1994-1997 + Copyright (C) Andrew Tridgell 1994-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 7446f31e15..c345d051bd 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -5,7 +5,7 @@ a partial implementation of DES designed for use in the SMB authentication protocol - Copyright (C) Andrew Tridgell 1997 + Copyright (C) Andrew Tridgell 1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 38d414cf23..052dae06f1 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB parameters and setup - Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. This program is free software; you can redistribute it and/or modify diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 5149568c04..e8c4544394 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -1,7 +1,7 @@ /* Unix SMB/Netbios implementation. Version 1.9. - Copyright (C) Andrew Tridgell 1997 + Copyright (C) Andrew Tridgell 1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From c54af0f8b20e3f93c59da6a817920e1de6c4a870 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 16 Mar 1998 20:59:47 +0000 Subject: Adding the same change as was added to 1.9.18 branch to add the "name resolve order" parameter. source/Makefile: Re-ordered link for name resolve order code. source/clientgen.c: source/clientutil.c: Added calls to resolve_name(). source/includes.h: Added HPUX zombie fix. source/loadparm.c: Added new name resolve order parameter. source/namequery.c: Re-wrote to include parsing of lmhosts file, new resolve_name() function requested by John. source/nmbd.c: Tell resolve_name not to do WINS lookups if we are the WINS server. source/nmbd_lmhosts.c: Call lmhosts parsing functions in namequery.c source/password.c: Call resolve_name() to lookup security=server name. source/reply.c: source/time.c: source/trans2.c: "fake directory create times" fix from Jim Hague - hague@research.canon.com.au. source/util.c: Removed isalnum() test in Get_Hostname() that seems to cause problems on many systems. Jeremy. (This used to be commit 7f118970da7c43eaddcf92dc056d3e849f1e7d5c) --- source3/libsmb/clientgen.c | 10 +- source3/libsmb/namequery.c | 263 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 319a77beb6..4585c8a544 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1343,13 +1343,9 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) fstrcpy(cli->desthost, host); if (!ip) { - struct hostent *hp; - - if ((hp = Get_Hostbyname(cli->desthost)) == 0) { - return False; - } - - putip((char *)&dest_ip,(char *)hp->h_addr); + if(!resolve_name( cli->desthost, &dest_ip)) { + return False; + } } else { dest_ip = *ip; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 207f064670..6bf41b9f9e 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -25,6 +25,8 @@ extern pstring scope; extern int DEBUGLEVEL; +/* nmbd.c sets this to True. */ +BOOL global_in_nmbd = False; /**************************************************************************** interpret a node status response @@ -303,3 +305,264 @@ struct in_addr *name_query(int fd,char *name,int name_type, return ip_list; } + +/******************************************************** + Start parsing the lmhosts file. +*********************************************************/ + +FILE *startlmhosts(char *fname) +{ + FILE *fp = fopen(fname,"r"); + if (!fp) { + DEBUG(2,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", + fname, strerror(errno))); + return NULL; + } + return fp; +} + +/******************************************************** + Parse the next line in the lmhosts file. +*********************************************************/ + +BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr) +{ + pstring line; + + while(!feof(fp) && !ferror(fp)) { + pstring ip,flags,extra; + char *ptr; + int count = 0; + + *name_type = -1; + + if (!fgets_slash(line,sizeof(pstring),fp)) + continue; + + if (*line == '#') + continue; + + strcpy(ip,""); + strcpy(name,""); + strcpy(flags,""); + + ptr = line; + + if (next_token(&ptr,ip ,NULL)) + ++count; + if (next_token(&ptr,name ,NULL)) + ++count; + if (next_token(&ptr,flags,NULL)) + ++count; + if (next_token(&ptr,extra,NULL)) + ++count; + + if (count <= 0) + continue; + + if (count > 0 && count < 2) + { + DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line)); + continue; + } + + if (count >= 4) + { + DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); + continue; + } + + DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); + + if (strchr(flags,'G') || strchr(flags,'S')) + { + DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); + continue; + } + + *ipaddr = *interpret_addr2(ip); + + /* Extra feature. If the name ends in '#XX', where XX is a hex number, + then only add that name type. */ + if((ptr = strchr(name, '#')) != NULL) + { + char *endptr; + + ptr++; + *name_type = (int)strtol(ptr, &endptr,0); + + if(!*ptr || (endptr == ptr)) + { + DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); + continue; + } + + *(--ptr) = '\0'; /* Truncate at the '#' */ + } + + return True; + } + + return False; +} + +/******************************************************** + Finish parsing the lmhosts file. +*********************************************************/ + +void endlmhosts(FILE *fp) +{ + fclose(fp); +} + +/******************************************************** + Resolve a name into an IP address. Use this function if + the string is either an IP address, DNS or host name + or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. +*********************************************************/ + +BOOL resolve_name(char *name, struct in_addr *return_ip) +{ + char *p; + int i; + BOOL pure_address = True; + + if (strcmp(name,"0.0.0.0") == 0) { + return_ip->s_addr = 0; + return True; + } + if (strcmp(name,"255.255.255.255") == 0) { + return_ip->s_addr = 0xFFFFFFFF; + return True; + } + + for (i=0; pure_address && name[i]; i++) + if (!(isdigit(name[i]) || name[i] == '.')) + pure_address = False; + + /* if it's in the form of an IP address then get the lib to interpret it */ + if (pure_address) { + return_ip->s_addr = inet_addr(name); + return True; + } + + for (p=strtok(lp_name_resolve_order(),LIST_SEP); p; p = strtok(NULL,LIST_SEP)) { + if(strequal(p, "host") || strequal(p, "hosts")) { + + /* + * "host" means do a localhost, or dns lookup. + */ + + struct hostent *hp; + + DEBUG(3,("resolve_name: Attempting host lookup for name %s\n")); + + if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + putip((char *)return_ip,(char *)hp->h_addr); + return True; + } + + } else if(strequal( p, "lmhosts")) { + + /* + * "lmhosts" means parse the local lmhosts file. + */ + + FILE *fp; + pstring lmhost_name; + int name_type; + + DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n")); + + fp = startlmhosts( LMHOSTSFILE ); + if(fp) { + while( getlmhostsent(fp, lmhost_name, &name_type, return_ip ) ) { + if( strequal(name, lmhost_name )) { + endlmhosts(fp); + return True; + } + } + endlmhosts(fp); + } + + } else if(strequal( p, "wins")) { + + int sock; + + /* + * "wins" means do a unicast lookup to the WINS server. + * Ignore if there is no WINS server specified or if the + * WINS server is one of our interfaces (if we're being + * called from within nmbd - we can't do this call as we + * would then block). + */ + + DEBUG(3,("resolve_name: Attempting wins lookup for name %s\n")); + + if(*lp_wins_server()) { + struct in_addr wins_ip = *interpret_addr2(lp_wins_server()); + BOOL wins_ismyip = ismyip(wins_ip); + + if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()) ); + + if (sock != -1) { + struct in_addr *iplist = NULL; + int count; + iplist = name_query(sock, name, 0x20, False, True, wins_ip, &count, NULL); + if(iplist != NULL) { + *return_ip = iplist[0]; + free((char *)iplist); + close(sock); + return True; + } + close(sock); + } + } + } else { + DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n")); + } + } else if(strequal( p, "bcast")) { + + int sock; + + /* + * "bcast" means do a broadcast lookup on all the local interfaces. + */ + + DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s\n")); + + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()) ); + + if (sock != -1) { + struct in_addr *iplist = NULL; + int count; + int num_interfaces = iface_count(); + set_socket_options(sock,"SO_BROADCAST"); + /* + * Lookup the name on all the interfaces, return on + * the first successful match. + */ + for( i = 0; i < num_interfaces; i++) { + struct in_addr sendto_ip = *iface_bcast(*iface_n_ip(i)); + iplist = name_query(sock, name, 0x20, True, False, sendto_ip, &count, NULL); + if(iplist != NULL) { + *return_ip = iplist[0]; + free((char *)iplist); + close(sock); + return True; + } + } + close(sock); + } + + } else { + DEBUG(0,("resolve_name: unknown name switch type %s\n", p)); + } + } + + return False; +} -- cgit From f912f5d872c346951347bb81116136dcc937ac96 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 17 Mar 1998 00:57:46 +0000 Subject: Fixes for the static data bugs & incorrect use of strtok that Andrew pointed out. Jeremy. (This used to be commit 734dde8d686827c387e17922fa6ac56af60780d9) --- source3/libsmb/namequery.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6bf41b9f9e..7b8a01b28f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -424,9 +424,11 @@ void endlmhosts(FILE *fp) BOOL resolve_name(char *name, struct in_addr *return_ip) { - char *p; int i; BOOL pure_address = True; + pstring name_resolve_list; + fstring tok; + char *ptr; if (strcmp(name,"0.0.0.0") == 0) { return_ip->s_addr = 0; @@ -447,8 +449,10 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) return True; } - for (p=strtok(lp_name_resolve_order(),LIST_SEP); p; p = strtok(NULL,LIST_SEP)) { - if(strequal(p, "host") || strequal(p, "hosts")) { + pstrcpy(name_resolve_list, lp_name_resolve_order()); + ptr = name_resolve_list; + while (next_token(&ptr, tok, LIST_SEP)) { + if(strequal(tok, "host") || strequal(tok, "hosts")) { /* * "host" means do a localhost, or dns lookup. @@ -463,7 +467,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) return True; } - } else if(strequal( p, "lmhosts")) { + } else if(strequal( tok, "lmhosts")) { /* * "lmhosts" means parse the local lmhosts file. @@ -486,7 +490,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) endlmhosts(fp); } - } else if(strequal( p, "wins")) { + } else if(strequal( tok, "wins")) { int sock; @@ -524,7 +528,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) } else { DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n")); } - } else if(strequal( p, "bcast")) { + } else if(strequal( tok, "bcast")) { int sock; @@ -560,7 +564,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) } } else { - DEBUG(0,("resolve_name: unknown name switch type %s\n", p)); + DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); } } -- cgit From da050244c305c1e03e2f3fb2ac02f6bc93ad47ca Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Mar 1998 19:07:53 +0000 Subject: Added SamOEMChangePassword functionality. Jeremy. (This used to be commit e02e3bcbbd4333113dde7bef47763fb229148007) --- source3/libsmb/smbdes.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index c345d051bd..8f95a5a297 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -341,3 +341,43 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) smbhash(out, buf, key2, 1); } +void SamOEMhash( unsigned char *data, unsigned char *key) +{ + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + s_box[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (s_box[ind] + key[ind%16]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + + for( ind = 0; ind < 516; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } +} -- cgit From 7abbf368f908cacdb2978e33069e49755e54faa8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Mar 1998 20:06:47 +0000 Subject: Adding the same changes to HEAD as were added to BRANCH_1_9_18. Changed smbpasswd to be client-server for a normal user, rather than accessing the private/smbpasswd file directly (it still accesses this file directly when run as root, so root can add users/change a users password without knowing the old password). A shakeout of this change is that smbpasswd can now be used to change a users password on a remote NT machine (yep - you heard that one right - we can now change a NT password from UNIX !!!!!). Jeremy. (This used to be commit 20770b6f1c25288e90d3e0d215afa7f0809ce124) --- source3/libsmb/clientgen.c | 100 ++++++++++++++++++++++++++++++++++++++++++++- source3/libsmb/smbdes.c | 10 ++++- 2 files changed, 107 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4585c8a544..dcebf70455 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -426,7 +426,7 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & 2) && passlen != 24) { passlen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); } else { @@ -1207,6 +1207,104 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return True; } +/**************************************************************************** +Send a SamOEMChangePassword command +****************************************************************************/ + +BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password, + char *old_password) +{ + char param[16+sizeof(fstring)]; + char data[532]; + char *p = param; + fstring upper_case_old_pw; + fstring upper_case_new_pw; + unsigned char old_pw_hash[16]; + unsigned char new_pw_hash[16]; + int data_len; + int param_len = 0; + int new_pw_len = strlen(new_password); + char *rparam = NULL; + char *rdata = NULL; + int rprcnt, rdrcnt; + + cli->error = -1; + + if(strlen(user) >= sizeof(fstring)-1) { + DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); + return False; + } + + if(new_pw_len > 512) { + DEBUG(0,("cli_oem_change_password: new password for user %s is too long.\n", user)); + return False; + } + + SSVAL(p,0,214); /* SamOEMChangePassword command. */ + p += 2; + strcpy(p, "zsT"); + p = skip_string(p,1); + strcpy(p, "B516B16"); + p = skip_string(p,1); + fstrcpy(p,user); + p = skip_string(p,1); + SSVAL(p,0,532); + p += 2; + + param_len = PTR_DIFF(p,param); + + /* + * Now setup the data area. + */ + memset(data, '\0', sizeof(data)); + fstrcpy( &data[512 - new_pw_len], new_password); + SIVAL(data, 512, new_pw_len); + + /* + * Get the Lanman hash of the old password, we + * use this as the key to SamOEMHash(). + */ + memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); + fstrcpy(upper_case_old_pw, old_password); + strupper(upper_case_old_pw); + E_P16((uchar *)upper_case_old_pw, old_pw_hash); + + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); + + /* + * Now place the old password hash in the data. + */ + memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); + fstrcpy(upper_case_new_pw, new_password); + strupper(upper_case_new_pw); + + E_P16((uchar *)upper_case_new_pw, new_pw_hash); + + E_old_pw_hash( new_pw_hash, old_pw_hash, &data[516]); + + data_len = 532; + + if(cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0, + data,param,NULL, + data_len , param_len,0, + 0,2,0) == False) { + DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", + user )); + return False; + } + + if(cli_receive_trans(cli,SMBtrans, &rdrcnt, &rprcnt, &rdata, &rparam)) { + if(rparam) + cli->error = SVAL(rparam,0); + } + + if (rparam) + free(rparam); + if (rdata) + free(rdata); + + return (cli->error == 0); +} /**************************************************************************** send a negprot command diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 8f95a5a297..e5d8f4a1e0 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -323,6 +323,12 @@ void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) smbhash(out+8, in+8, p14+7, 0); } +void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out) +{ + smbhash(out, in, p14, 1); + smbhash(out+8, in+8, p14+7, 1); +} + void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) { unsigned char buf[8]; @@ -341,7 +347,7 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) smbhash(out, buf, key2, 1); } -void SamOEMhash( unsigned char *data, unsigned char *key) +void SamOEMhash( unsigned char *data, unsigned char *key, int val) { unsigned char s_box[256]; unsigned char index_i = 0; @@ -365,7 +371,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key) s_box[j] = tc; } - for( ind = 0; ind < 516; ind++) + for( ind = 0; ind < (val ? 516 : 16); ind++) { unsigned char tc; unsigned char t; -- cgit From 5d7c8375e4ffb017ef0f9eed7e619e533b3e8d12 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Mar 1998 00:37:53 +0000 Subject: clientgen.c ipc.c smbpasswd.c: Fixes for warnings (from Herb). quotas.c: Linux quota fix. util.c: Ensure smb_read_error is zero in all calls that can set it. lib/rpc/include/rpc_misc.h lib/rpc/include/rpc_netlogon.h lib/rpc/parse/parse_misc.c lib/rpc/parse/parse_net.c lib/rpc/server/srv_netlog.c : Modify Luke's code to call SamOEMhash(). Jeremy. (This used to be commit 7f749708383b8b36c3f23a5fbc5cbdf39bc8e555) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index dcebf70455..4f57c08a95 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1280,7 +1280,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo E_P16((uchar *)upper_case_new_pw, new_pw_hash); - E_old_pw_hash( new_pw_hash, old_pw_hash, &data[516]); + E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); data_len = 532; -- cgit From a1db330263e15a9c5db9fe38a7278bd1408ae79d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Mar 1998 01:27:27 +0000 Subject: RFC1002 says we must put compressed name pointers in the following outgoing packets : NMB_NAME_REG_OPCODE, NMB_NAME_RELEASE_OPCODE, NMB_NAME_REFRESH_OPCODE, NMB_NAME_MULTIHOMED_REG_OPCODE. A WINS server written by Shadow Software was rejecting our packets as we weren't using name pointers in those requests (talk about picky :-). Jeremy. (This used to be commit a31aa09173db30c39f59d4ee5761075b0e00dd71) --- source3/libsmb/nmblib.c | 42 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 40 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 1400b88434..f2aee12615 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -362,6 +362,27 @@ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) return(ret); } +/******************************************************************* + put a compressed name pointer record into a packet + ******************************************************************/ +static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset) +{ + int ret=0; + buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); + buf[offset+1] = (ptr_offset & 0xFF); + offset += 2; + ret += 2; + RSSVAL(buf,offset,rec->rr_type); + RSSVAL(buf,offset+2,rec->rr_class); + RSIVAL(buf,offset+4,rec->ttl); + RSSVAL(buf,offset+8,rec->rdlength); + memcpy(buf+offset+10,rec->rdata,rec->rdlength); + offset += 10+rec->rdlength; + ret += 10+rec->rdlength; + + return(ret); +} + /******************************************************************* parse a dgram packet. Return False if the packet can't be parsed or is invalid for some reason, True otherwise @@ -808,10 +829,27 @@ static int build_nmb(char *buf,struct packet_struct *p) offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, nmb->header.nscount); - if (nmb->header.arcount) + /* + * The spec says we must put compressed name pointers + * in the following outgoing packets : + * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, + * NAME_RELEASE_REQUEST. + */ + + if((nmb->header.response == False) && + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && + (nmb->header.arcount == 1)) { + + offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); + + } else if (nmb->header.arcount) { offset += put_res_rec((char *)ubuf,offset,nmb->additional, nmb->header.arcount); - + } return(offset); } -- cgit From a4156f9b50c81fe40823cd8e32ec990690d3884c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Mar 1998 19:59:14 +0000 Subject: chgpasswd.c, ipc.c, loadparm.c: Added boolean "unix password sync" parameter which allows the new change password code to change the unix password also. Defaults to OFF. includes.h: Added termios.h to FreeBSD to allow password changing. namequery.c: Fixed missing name parameters to debug statements. Jeremy. (This used to be commit 4ac50c0f0aa5af084ddad89b1f9baf6c2c1ddcb8) --- source3/libsmb/namequery.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7b8a01b28f..faa2a09007 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -460,7 +460,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) struct hostent *hp; - DEBUG(3,("resolve_name: Attempting host lookup for name %s\n")); + DEBUG(3,("resolve_name: Attempting host lookup for name %s\n", name)); if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { putip((char *)return_ip,(char *)hp->h_addr); @@ -477,7 +477,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) pstring lmhost_name; int name_type; - DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n")); + DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n", name)); fp = startlmhosts( LMHOSTSFILE ); if(fp) { @@ -502,7 +502,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) * would then block). */ - DEBUG(3,("resolve_name: Attempting wins lookup for name %s\n")); + DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x20>\n", name)); if(*lp_wins_server()) { struct in_addr wins_ip = *interpret_addr2(lp_wins_server()); @@ -536,7 +536,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) * "bcast" means do a broadcast lookup on all the local interfaces. */ - DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s\n")); + DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x20>\n", name)); sock = open_socket_in( SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()) ); -- cgit From 5f7e1d2aa5ad4c57074c9344f7a970e8bd783dda Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Apr 1998 02:48:52 +0000 Subject: support O_SYNC in opens for smbtorture (This used to be commit 000b871839e12065fc514f857ba205590a95b040) --- source3/libsmb/clientgen.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4f57c08a95..4bca10cb3a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -737,6 +737,10 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) accessmode |= 1; } + if ((flags & O_SYNC) == O_SYNC) { + accessmode |= (1<<14); + } + bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); -- cgit From b5f599daf77a366d6dabbd41567d49ffdbb5959d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Apr 1998 02:50:43 +0000 Subject: if the resolve order is blank then assume "host" (This used to be commit d361a06fa14b899cf1bd697a9524b5a32f7bf204) --- source3/libsmb/namequery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index faa2a09007..8927522090 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -451,6 +451,8 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) pstrcpy(name_resolve_list, lp_name_resolve_order()); ptr = name_resolve_list; + if (!ptr || !*ptr) ptr = "host"; + while (next_token(&ptr, tok, LIST_SEP)) { if(strequal(tok, "host") || strequal(tok, "hosts")) { -- cgit From cac6a060af598bf94e6414b06e7365ec51ca360e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Apr 1998 19:24:06 +0000 Subject: Changes to allow Samba to be compiled with -Wstrict-prototypes with gcc. (Not a big change although it looks like it :-). Jeremy. (This used to be commit cd2613c57261456485fe4eeecfda209ada70de8e) --- source3/libsmb/namequery.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8927522090..4de10f10ce 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -89,7 +89,7 @@ static void _interpret_node_status(char *p, char *master,char *rname) **************************************************************************/ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, struct in_addr to_ip,char *master,char *rname, - void (*fn)()) + void (*fn)(struct packet_struct *)) { BOOL found=False; int retries = 2; @@ -194,9 +194,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, returns an array of IP addresses or NULL if none *count will be set to the number of addresses returned ****************************************************************************/ -struct in_addr *name_query(int fd,char *name,int name_type, - BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count, void (*fn)()) +struct in_addr *name_query(int fd,char *name,int name_type, BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *)) { BOOL found=False; int i, retries = 3; -- cgit From 373d7c62577c13e1a85043844953a8d779858432 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Apr 1998 19:29:51 +0000 Subject: Changing of machine passwords now works !!!!!! smbdes.c: Added cred_hash3. smbpasswd.c: Fixes for adding a machine account (needs more work). lib/rpc/server/srv_netlog.c: Turn on the machine password changing code by default (calls cred_hash3). Jeremy. (This used to be commit 50aa513b969c6e41911aeee8207b065f93af0beb) --- source3/libsmb/smbdes.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index e5d8f4a1e0..cf46e53ff5 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -347,6 +347,15 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) smbhash(out, buf, key2, 1); } +void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key) +{ + static unsigned char key2[8]; + + smbhash(out, in, key, 0); + key2[0] = key[7]; + smbhash(out + 8, in + 8, key2, 0); +} + void SamOEMhash( unsigned char *data, unsigned char *key, int val) { unsigned char s_box[256]; -- cgit From f9a96f060bdc8d045748b5f7e31d177e43e8810a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Apr 1998 22:44:01 +0000 Subject: clientgen.c: Changes 'cli_xxx_' calls to use the following regularized parameter syntax: setup, setup_count, max_setup_count, params, params_count, max_params_count, data, data_count, max_data_count, (and if a reply is needed) *reply_params, *reply_data_len *reply_data, *reply_data_len This allows the pointers and the lengths that relate to these pointers to be next to each other in the parameter list. This makes seeing what you are passing to these functions much easier to see. Getting ready for adding the lib/rpc/client functions needed to do security=domain. torture.c: Fixed it so it uses / rather than \\ internally for the //machine/share syntax. Jeremy. (This used to be commit 38350ea8b949d0908497490898ff04df7591ccac) --- source3/libsmb/clientgen.c | 152 +++++++++++++++++++++++++++++---------------- 1 file changed, 99 insertions(+), 53 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4bca10cb3a..bffce26294 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -47,10 +47,12 @@ static void cli_setup_packet(struct cli_state *cli) /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ -static BOOL cli_send_trans(struct cli_state *cli, - int trans, char *name, int fid, int flags, - char *data,char *param,uint16 *setup, int ldata,int lparam, - int lsetup,int mdata,int mparam,int msetup) +static BOOL cli_send_trans(struct cli_state *cli, int trans, + char *name, int pipe_name_len, + int fid, int flags, + uint16 *setup, int lsetup, int msetup, + char *param, int lparam, int mparam, + char *data, int ldata, int mdata) { int i; int this_ldata,this_lparam; @@ -67,7 +69,7 @@ static BOOL cli_send_trans(struct cli_state *cli, SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); - outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? strlen(name)+1 : 3); + outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len+1 : 3); outdata = outparam+this_lparam; /* primary request */ @@ -87,7 +89,7 @@ static BOOL cli_send_trans(struct cli_state *cli, SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); p = smb_buf(cli->outbuf); if (trans==SMBtrans) { - strcpy(p,name); /* name[] */ + memcpy(p,name, pipe_name_len + 1); /* name[] */ } else { *p++ = 0; /* put in a null smb_name */ *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ @@ -155,9 +157,9 @@ static BOOL cli_send_trans(struct cli_state *cli, /**************************************************************************** receive a SMB trans or trans2 response allocating the necessary memory ****************************************************************************/ -static BOOL cli_receive_trans(struct cli_state *cli, - int trans,int *data_len, - int *param_len, char **data,char **param) +static BOOL cli_receive_trans(struct cli_state *cli,int trans, + char **param, int *param_len, + char **data, int *data_len) { int total_data=0; int total_param=0; @@ -235,23 +237,51 @@ static BOOL cli_receive_trans(struct cli_state *cli, return(True); } +/**************************************************************************** +Call a remote api on an arbitrary pipe. takes param, data and setup buffers. +****************************************************************************/ +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 *setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 *rparam_count, + char **rdata, uint32 *rdata_count) +{ + if(pipe_name_len == 0) + pipe_name_len = strlen(pipe_name); + + cli_send_trans(cli, SMBtrans, + pipe_name, pipe_name_len, + 0,0, /* fid, flags */ + setup, setup_count, max_setup_count, + params, param_count, max_param_count, + data, data_count, max_data_count); + + return (cli_receive_trans(cli, SMBtrans, + rparam, rparam_count, + rdata, rdata_count)); +} /**************************************************************************** call a remote api ****************************************************************************/ static BOOL cli_api(struct cli_state *cli, - int prcnt,int drcnt,int mprcnt,int mdrcnt,int *rprcnt, - int *rdrcnt, char *param,char *data, - char **rparam, char **rdata) + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt) { - cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0, - data,param,NULL, - drcnt,prcnt,0, - mdrcnt,mprcnt,0); + cli_send_trans(cli,SMBtrans, + PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ + 0,0, /* fid, flags */ + NULL,0,0, /* Setup, length, max */ + param, prcnt, mprcnt, /* Params, length, max */ + data, drcnt, mdrcnt /* Data, length, max */ + ); return (cli_receive_trans(cli,SMBtrans, - rdrcnt,rprcnt, - rdata,rparam)); + rparam, rprcnt, + rdata, rdrcnt)); } @@ -291,11 +321,12 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) cli->error = -1; - if (cli_api(cli, PTR_DIFF(p,param),0, - 1024,BUFFER_SIZE, - &rprcnt,&rdrcnt, - param,NULL, - &rparam,&rdata)) { + if (cli_api(cli, + param, PTR_DIFF(p,param),1024, /* param, length, max */ + NULL, 0, BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { cli->error = SVAL(rparam,0); p = rdata; @@ -352,13 +383,11 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = skip_string(p,1); if (cli_api(cli, - PTR_DIFF(p,param), /* param count */ - 0, /*data count */ - 8, /* mprcount */ - BUFFER_SIZE, /* mdrcount */ - &rprcnt,&rdrcnt, - param, NULL, - &rparam,&rdata)) { + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { int res = SVAL(rparam,0); int converter=SVAL(rparam,2); int i; @@ -1068,15 +1097,19 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, SSVAL(param, 0, SMB_INFO_STANDARD); pstrcpy(¶m[6], fname); - if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, - NULL, param, &setup, - data_len, param_len, 1, - cli->max_xmit, 10, 0)) { + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { return False; } - if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, - &rdata, &rparam)) { + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { return False; } @@ -1121,15 +1154,19 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); pstrcpy(¶m[6], fname); - if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, - NULL, param, &setup, - data_len, param_len, 1, - cli->max_xmit, 10, 0)) { + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { return False; } - if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, - &rdata, &rparam)) { + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { return False; } @@ -1177,15 +1214,19 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, SSVAL(param, 0, fnum); SSVAL(param, 2, SMB_INFO_STANDARD); - if (!cli_send_trans(cli, SMBtrans2, NULL, -1, 0, - NULL, param, &setup, - data_len, param_len, 1, - cli->max_xmit, 2, 0)) { + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { return False; } - if (!cli_receive_trans(cli, SMBtrans2, &data_len, ¶m_len, - &rdata, &rparam)) { + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { return False; } @@ -1288,16 +1329,21 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo data_len = 532; - if(cli_send_trans(cli,SMBtrans,PIPE_LANMAN,0,0, - data,param,NULL, - data_len , param_len,0, - 0,2,0) == False) { + if(cli_send_trans(cli,SMBtrans, + PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ + 0,0, /* fid, flags */ + NULL,0,0, /* setup, length, max */ + param,param_len,2, /* param, length, max */ + data,data_len,0 /* data, length, max */ + ) == False) { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); return False; } - if(cli_receive_trans(cli,SMBtrans, &rdrcnt, &rprcnt, &rdata, &rparam)) { + if(cli_receive_trans(cli,SMBtrans, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { if(rparam) cli->error = SVAL(rparam,0); } -- cgit From efb71742ca8ff9ec3211c5b3cf5d311fdceecd1c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Apr 1998 22:43:54 +0000 Subject: Makefile: Added genrand.o clientgen.c: Changed to fill change password buffer with random stuff. password.c: Changed to get challenge from genrand.c server.c: Added #ifdef around O_SYNC. version.h: Changed to 1.9.19prealpha. genrand.c: New code to generate (hopefully) good random numbers for use in crypto challenges/session keys etc. PLEASE REVIEW THIS CODE AND SUGGEST IMPROVEMENTS !!!!!! Jeremy. (This used to be commit 608e98546392fd0aac9b33f4feac43615dbb4405) --- source3/libsmb/clientgen.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bffce26294..1f2f746576 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -766,9 +766,11 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) accessmode |= 1; } +#if defined(O_SYNC) if ((flags & O_SYNC) == O_SYNC) { accessmode |= (1<<14); } +#endif /* O_SYNC */ bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); @@ -1300,8 +1302,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo /* * Now setup the data area. + * We need to generate a random fill + * for this area to make it harder to + * decrypt. JRA. */ - memset(data, '\0', sizeof(data)); + generate_random_buffer(data, sizeof(data), False); fstrcpy( &data[512 - new_pw_len], new_password); SIVAL(data, 512, new_pw_len); -- cgit From 2dee1ed38867504d067d593c62734ecff0eca77c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Apr 1998 02:23:24 +0000 Subject: clientgen.c: Added cli_ulogoff() call. password.c: Added call to cli_ulogoff on successfull sessionsetup. Jeremy. (This used to be commit 77882f002b2a8203aad419e485fc885303d999a0) --- source3/libsmb/clientgen.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1f2f746576..ea51395a8f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -528,6 +528,25 @@ BOOL cli_session_setup(struct cli_state *cli, return True; } +/**************************************************************************** + Send a uloggoff. +*****************************************************************************/ + +BOOL cli_ulogoff(struct cli_state *cli) +{ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,2,0,True); + CVAL(cli->outbuf,smb_com) = SMBulogoffX; + cli_setup_packet(cli); + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + + send_smb(cli->fd,cli->outbuf); + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + return False; + + return CVAL(cli->inbuf,smb_rcls) == 0; +} /**************************************************************************** send a tconX -- cgit From 002a47de8e0cf03c79cedbed2db52f391001f459 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 20:12:17 +0000 Subject: clientgen.c: Added rap error codes to cli_error, moved from smbpasswd.c password.c: Changed global cli -> pw_cli, removed strtok (bad strtok, bad :-) use in security=server, started to extend security=domain code. smbpasswd.c: Removed rap error code functions. Jeremy. (This used to be commit 0f00b8fce1a5cad7f8c212568fa33f09986e5bd6) --- source3/libsmb/clientgen.c | 71 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 63 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ea51395a8f..9de6afccee 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -29,6 +29,69 @@ extern int DEBUGLEVEL; +/***************************************************** + RAP error codes - a small start but will be extended. +*******************************************************/ + +struct +{ + int err; + char *message; +} rap_errmap[] = +{ + {5, "User has insufficient privilege" }, + {86, "The specified password is invalid" }, + {2226, "Operation only permitted on a Primary Domain Controller" }, + {2242, "The password of this user has expired." }, + {2243, "The password of this user cannot change." }, + {2244, "This password cannot be used now (password history conflict)." }, + {2245, "The password is shorter than required." }, + {2246, "The password of this user is too recent to change."}, + {0, NULL} +}; + +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +char *cli_smb_errstr(struct cli_state *cli) +{ + return smb_errstr(cli->inbuf); +} + +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char *cli_errstr(struct cli_state *cli) +{ + static fstring error_message; + int errclass; + int errnum; + int i; + + /* + * Errors are of two kinds - smb errors, + * dealt with by cli_smb_errstr, and rap + * errors, whose error code is in cli.error. + */ + + cli_error(cli, &errclass, &errnum); + if(errclass != 0) + return cli_smb_errstr(cli); + + sprintf(error_message, "code %d", cli->error); + + for(i = 0; rap_errmap[i].message != NULL; i++) { + if (rap_errmap[i].err == cli->error) { + fstrcpy( error_message, rap_errmap[i].message); + break; + } + } + + return error_message; +} + /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ @@ -1566,14 +1629,6 @@ void cli_shutdown(struct cli_state *cli) memset(cli, 0, sizeof(*cli)); } -/**************************************************************************** - return a description of the error -****************************************************************************/ -char *cli_errstr(struct cli_state *cli) -{ - return smb_errstr(cli->inbuf); -} - /**************************************************************************** return error codes for the last packet ****************************************************************************/ -- cgit From 5baa991aef0088a1e0f5d0e9350f3fd3168b13fb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 22:08:39 +0000 Subject: We will need this new nterr.c for the DOMAIN_CLIENT code. Jeremy. (This used to be commit 932b22cd495b9ce1ba03e5b91a50b314167255d7) --- source3/libsmb/nterr.c | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index bda0f882a6..dca97ab923 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -1,18 +1,23 @@ +/* NT error codes. please read nterr.h */ +#include "includes.h" #include "nterr.h" -static struct +typedef struct { char *nt_errstr; - uint16 nt_errcode; + uint32 nt_errcode; -} nt_errs[] = +} nt_err_code_struct; + +nt_err_code_struct nt_errs[] = { { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, { "NT_STATUS_INFO_LENGTH_MISMATCH", NT_STATUS_INFO_LENGTH_MISMATCH }, { "NT_STATUS_ACCESS_VIOLATION", NT_STATUS_ACCESS_VIOLATION }, + { "STATUS_BUFFER_OVERFLOW", STATUS_BUFFER_OVERFLOW }, { "NT_STATUS_IN_PAGE_ERROR", NT_STATUS_IN_PAGE_ERROR }, { "NT_STATUS_PAGEFILE_QUOTA", NT_STATUS_PAGEFILE_QUOTA }, { "NT_STATUS_INVALID_HANDLE", NT_STATUS_INVALID_HANDLE }, @@ -512,3 +517,25 @@ static struct { NULL, 0 } }; +/***************************************************************************** + returns an NT error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +char *get_nt_error_msg(uint32 nt_code) +{ + static pstring msg; + int idx = 0; + + strcpy(msg, "Unknown NT error"); + + while (nt_errs[idx].nt_errstr != NULL) + { + if (nt_errs[idx].nt_errcode == nt_code) + { + strcpy(msg, nt_errs[idx].nt_errstr); + return msg; + } + idx++; + } + return NULL; +} + -- cgit From 30675f81f60bab24f47758baab8316d4467709ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 22:59:19 +0000 Subject: Makefile: Added nterr.c into the mix. clientgen.c: Added nt_error as an entry in the struct client_state. password.c: Open the netlogon pipe. smb.h: Added nt_error as an entry in the struct client_state. lib/rpc/parse/parse_net.c: Added comments on net logon. lib/rpc/server/srv_netlog.c: Added comments on net logon. Jeremy. (This used to be commit 899a9f0dce50c73e03c8da2ebe920957491c8ad7) --- source3/libsmb/clientgen.c | 53 +++++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9de6afccee..f23c846cf9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -71,19 +71,39 @@ char *cli_errstr(struct cli_state *cli) int i; /* - * Errors are of two kinds - smb errors, - * dealt with by cli_smb_errstr, and rap - * errors, whose error code is in cli.error. + * Errors are of three kinds - smb errors, + * dealt with by cli_smb_errstr, NT errors, + * whose code is in cli.nt_error, and rap + * errors, whose error code is in cli.rap_error. */ cli_error(cli, &errclass, &errnum); if(errclass != 0) return cli_smb_errstr(cli); - - sprintf(error_message, "code %d", cli->error); + + /* + * Was it an NT error ? + */ + + if(cli->nt_error) { + char *nt_msg = get_nt_error_msg(cli->nt_error); + + if(nt_msg == NULL) + sprintf(error_message, "NT code %d", cli->nt_error); + else + fstrcpy(error_message, nt_msg); + + return error_message; + } + + /* + * Must have been a rap error. + */ + + sprintf(error_message, "code %d", cli->rap_error); for(i = 0; rap_errmap[i].message != NULL; i++) { - if (rap_errmap[i].err == cli->error) { + if (rap_errmap[i].err == cli->rap_error) { fstrcpy( error_message, rap_errmap[i].message); break; } @@ -97,6 +117,8 @@ setup basics in a outgoing packet ****************************************************************************/ static void cli_setup_packet(struct cli_state *cli) { + cli->rap_error = 0; + cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->uid); SSVAL(cli->outbuf,smb_mid,cli->mid); @@ -382,29 +404,27 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) SSVAL(p, 0, BUFFER_SIZE); p += 2; - cli->error = -1; - if (cli_api(cli, param, PTR_DIFF(p,param),1024, /* param, length, max */ NULL, 0, BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { - cli->error = SVAL(rparam,0); + cli->rap_error = SVAL(rparam,0); p = rdata; - if (cli->error == 0) { + if (cli->rap_error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); cli->privilages = SVAL(p, 24); fstrcpy(cli->eff_name,p+2); } else { - DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->error)); + DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); } } if (rparam) free(rparam); if (rdata) free(rdata); - return cli->error == 0; + return (cli->rap_error == 0); } @@ -1357,8 +1377,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo char *rdata = NULL; int rprcnt, rdrcnt; - cli->error = -1; - if(strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); return False; @@ -1432,7 +1450,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo &rparam, &rprcnt, &rdata, &rdrcnt)) { if(rparam) - cli->error = SVAL(rparam,0); + cli->rap_error = SVAL(rparam,0); } if (rparam) @@ -1440,7 +1458,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo if (rdata) free(rdata); - return (cli->error == 0); + return (cli->rap_error == 0); } /**************************************************************************** @@ -1561,7 +1579,8 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, return False; if (CVAL(cli->inbuf,0) != 0x82) { - cli->error = CVAL(cli->inbuf,0); + /* This is the wrong place to put the error... JRA. */ + cli->rap_error = CVAL(cli->inbuf,0); return False; } return(True); -- cgit From e7ac86607c80912e55ac7179b100cea22749c16f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 25 Apr 1998 01:12:08 +0000 Subject: This looks like a big change but really isn't. It is changing the global variables "myname" and "myworkgroup" to "global_myname" and "global_myworkgroup" respectively. This is to make it very explicit when we are messing with a global (don't ask - it makes the domain client code much clearer :-). Jeremy. (This used to be commit 866406bfe399cf757c8275093dacd5ce4843afa0) --- source3/libsmb/nmblib.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index f2aee12615..9c7b260c59 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -27,7 +27,6 @@ extern int DEBUGLEVEL; int num_good_sends = 0; int num_good_receives = 0; extern pstring scope; -extern pstring myname; extern struct in_addr ipzero; static struct opcode_names { -- cgit From d7cecb7bd3cfcab48af07366e24b65b2bb8b09bb Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 28 Apr 1998 09:53:42 +0000 Subject: added NetShareEnum from Bartlomej Czardybon (This used to be commit 37cbc356741055d0660b80594117fa312d252b85) --- source3/libsmb/clientgen.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f23c846cf9..3f8c6e32cc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -427,6 +427,65 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) return (cli->rap_error == 0); } +/**************************************************************************** +call a NetShareEnum - try and browse available connections on a host +****************************************************************************/ +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *)) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt; + pstring param; + int count = -1; + + /* now send a SMBtrans command with api RNetShareEnum */ + p = param; + SSVAL(p,0,0); /* api number */ + p += 2; + strcpy(p,"WrLeh"); + p = skip_string(p,1); + strcpy(p,"B13BWz"); + p = skip_string(p,1); + SSVAL(p,0,1); + SSVAL(p,2,BUFFER_SIZE); + p += 4; + + if (cli_api(cli, + PTR_DIFF(p,param), + 0, /* data count */ + 1024, /* mprcount */ + BUFFER_SIZE, /* mdrcount */ + &rprcnt, &rdrcnt, + param,NULL, + &rparam,&rdata)) + { + int res = SVAL(rparam,0); + int converter=SVAL(rparam,2); + int i; + BOOL long_share_name=False; + + if (res == 0) + { + count=SVAL(rparam,4); + p = rdata; + + for (i=0;i0); +} /**************************************************************************** call a NetServerEnum for the specified workgroup and servertype mask. -- cgit From b807469d40a816e9f61b797b6ab26a40bb4363cb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Apr 1998 16:43:02 +0000 Subject: Fixed checked in code that didn't compile. Jeremy. (This used to be commit 5f258abf526243f753c3a64cde2e1f67e4d60b6b) --- source3/libsmb/clientgen.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3f8c6e32cc..7fc19a5f39 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -452,18 +452,14 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) p += 4; if (cli_api(cli, - PTR_DIFF(p,param), - 0, /* data count */ - 1024, /* mprcount */ - BUFFER_SIZE, /* mdrcount */ - &rprcnt, &rdrcnt, - param,NULL, - &rparam,&rdata)) + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, BUFFER_SIZE, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ { int res = SVAL(rparam,0); int converter=SVAL(rparam,2); int i; - BOOL long_share_name=False; if (res == 0) { @@ -1465,7 +1461,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo * for this area to make it harder to * decrypt. JRA. */ - generate_random_buffer(data, sizeof(data), False); + generate_random_buffer((unsigned char *)data, sizeof(data), False); fstrcpy( &data[512 - new_pw_len], new_password); SIVAL(data, 512, new_pw_len); -- cgit From d3832506b2583130c4f4ba4b3edeabca987b7cbb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Apr 1998 00:02:57 +0000 Subject: This is the checkin that adds the security=domain functionality. WARNING - so far this has only been tested against a Samba PDC (still waiting for IS to add me the machine accounts :-). Still missing is the code in smbpasswd that will add a machine account password and change it on the domain controller, but this is not hard, and I will check it in soon. Jeremy. (This used to be commit 17b94a7084621b3f0106dd4d3386f05cdfc56d19) --- source3/libsmb/nterr.c | 4 +++- source3/libsmb/smbdes.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index dca97ab923..0788ae1b60 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -527,6 +527,8 @@ char *get_nt_error_msg(uint32 nt_code) strcpy(msg, "Unknown NT error"); + nt_code &= 0xFFFF; + while (nt_errs[idx].nt_errstr != NULL) { if (nt_errs[idx].nt_errcode == nt_code) @@ -536,6 +538,6 @@ char *get_nt_error_msg(uint32 nt_code) } idx++; } - return NULL; + return msg; } diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index cf46e53ff5..4daf616588 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -347,13 +347,13 @@ void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) smbhash(out, buf, key2, 1); } -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key) +void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw) { static unsigned char key2[8]; - smbhash(out, in, key, 0); + smbhash(out, in, key, forw); key2[0] = key[7]; - smbhash(out + 8, in + 8, key2, 0); + smbhash(out + 8, in + 8, key2, forw); } void SamOEMhash( unsigned char *data, unsigned char *key, int val) -- cgit From e305c2c9e2e657974d34d1d58a8f9372921fdae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Apr 1998 19:22:01 +0000 Subject: clientgen.c: Fixed null session setup bug. password.c: Stopped cli_nt_logout call (we don't have it correct yet). Added Luke object-orientation fix :-). smb.h: Added clnt_name_slash to cli_state. lib/rpc/client/cli_login.c: Changed global_myname to clnt_name_slash where needed. lib/rpc/client/cli_netlogon.c: Fixed debug messages, don't check creds on error. lib/rpc/client/cli_pipe.c: Fixed debug messages, Added Luke object-orientation fix. lib/rpc/parse/parse_misc.c: Fixed STRING2 linearization bug that was adding 1. Jeremy. (This used to be commit c6c22df20196cb7f0ae84b1a1dd202a87adb8d4e) --- source3/libsmb/clientgen.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7fc19a5f39..d72040505f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -593,12 +593,17 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if ((cli->sec_mode & 2) && passlen != 24) { - passlen = 24; - SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - } else { - memcpy(pword, pass, passlen); - } + if(((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { + /* Null session connect. */ + pword[0] = '\0'; + } else { + if ((cli->sec_mode & 2) && passlen != 24) { + passlen = 24; + SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + } else { + memcpy(pword, pass, passlen); + } + } /* if in share level security then don't send a password now */ if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} -- cgit From 3dfc0c847240ac7e12c39f4ed9c31a888949ade1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 May 1998 06:38:36 +0000 Subject: changed to use slprintf() instead of sprintf() just about everywhere. I've implemented slprintf() as a bounds checked sprintf() using mprotect() and a non-writeable page. This should prevent any sprintf based security holes. (This used to be commit ee09e9dadb69aaba5a751dd20ccc6d587d841bd6) --- source3/libsmb/clientgen.c | 7 ++++--- source3/libsmb/nmblib.c | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d72040505f..8b4001827c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -343,8 +343,8 @@ BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, data, data_count, max_data_count); return (cli_receive_trans(cli, SMBtrans, - rparam, rparam_count, - rdata, rdata_count)); + rparam, (int *)rparam_count, + rdata, (int *)rdata_count)); } /**************************************************************************** @@ -714,7 +714,8 @@ BOOL cli_send_tconX(struct cli_state *cli, memcpy(pword, pass, passlen); } - sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); + slprintf(fullshare, sizeof(fullshare)-1, + "\\\\%s\\%s", cli->desthost, share); set_message(cli->outbuf,4, 2 + strlen(fullshare) + passlen + strlen(dev),True); diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9c7b260c59..5a8a037ce5 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -294,9 +294,9 @@ char *namestr(struct nmb_name *n) char *p = ret[i]; if (!n->scope[0]) - sprintf(p,"%s<%02x>",n->name,n->name_type); + slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); else - sprintf(p,"%s<%02x>.%s",n->name,n->name_type,n->scope); + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); i = (i+1)%4; return(p); -- cgit From f888868f46a5418bac9ab528497136c152895305 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 May 1998 00:55:32 +0000 Subject: This is a security audit change of the main source. It removed all ocurrences of the following functions : sprintf strcpy strcat The replacements are slprintf, safe_strcpy and safe_strcat. It should not be possible to use code in Samba that uses sprintf, strcpy or strcat, only the safe_equivalents. Once Andrew has fixed the slprintf implementation then this code will be moved back to the 1.9.18 code stream. Jeremy. (This used to be commit 2d774454005f0b54e5684cf618da7060594dfcbb) --- source3/libsmb/clientgen.c | 58 ++++++++++++++++++++++---------------------- source3/libsmb/credentials.c | 2 +- source3/libsmb/namequery.c | 24 +++++++++--------- source3/libsmb/nmblib.c | 4 +-- source3/libsmb/nterr.c | 4 +-- source3/libsmb/smberr.c | 8 +++--- 6 files changed, 50 insertions(+), 50 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8b4001827c..9dfd482da3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -89,7 +89,7 @@ char *cli_errstr(struct cli_state *cli) char *nt_msg = get_nt_error_msg(cli->nt_error); if(nt_msg == NULL) - sprintf(error_message, "NT code %d", cli->nt_error); + slprintf(error_message, sizeof(fstring) - 1, "NT code %d", cli->nt_error); else fstrcpy(error_message, nt_msg); @@ -100,7 +100,7 @@ char *cli_errstr(struct cli_state *cli) * Must have been a rap error. */ - sprintf(error_message, "code %d", cli->rap_error); + slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); for(i = 0; rap_errmap[i].message != NULL; i++) { if (rap_errmap[i].err == cli->rap_error) { @@ -387,16 +387,16 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) p = param; SSVAL(p,0,132); /* api number */ p += 2; - strcpy(p,"OOWb54WrLh"); + pstrcpy(p,"OOWb54WrLh"); p = skip_string(p,1); - strcpy(p,"WB21BWDWWDDDDDDDzzzD"); + pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); p = skip_string(p,1); SSVAL(p,0,1); p += 2; - strcpy(p,user); + pstrcpy(p,user); strupper(p); p += 21; p++; p += 15; p++; - strcpy(p, workstation); + pstrcpy(p, workstation); strupper(p); p += 16; SSVAL(p, 0, BUFFER_SIZE); @@ -443,9 +443,9 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) p = param; SSVAL(p,0,0); /* api number */ p += 2; - strcpy(p,"WrLeh"); + pstrcpy(p,"WrLeh"); p = skip_string(p,1); - strcpy(p,"B13BWz"); + pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); SSVAL(p,2,BUFFER_SIZE); @@ -505,10 +505,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - strcpy(p,"WrLehDz"); + pstrcpy(p,"WrLehDz"); p = skip_string(p,1); - strcpy(p,"B16BBDz"); + pstrcpy(p,"B16BBDz"); p = skip_string(p,1); SSVAL(p,0,uLevel); @@ -625,7 +625,7 @@ BOOL cli_session_setup(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - strcpy(p,user); + pstrcpy(p,user); strupper(p); } else { set_message(cli->outbuf,13,0,True); @@ -644,14 +644,14 @@ BOOL cli_session_setup(struct cli_state *cli, p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpass,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - strcpy(p,user); + pstrcpy(p,user); strupper(p); p = skip_string(p,1); - strcpy(p,workgroup); + pstrcpy(p,workgroup); strupper(p); p = skip_string(p,1); - strcpy(p,"Unix");p = skip_string(p,1); - strcpy(p,"Samba");p = skip_string(p,1); + pstrcpy(p,"Unix");p = skip_string(p,1); + pstrcpy(p,"Samba");p = skip_string(p,1); set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } @@ -728,9 +728,9 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - strcpy(p,fullshare); + fstrcpy(p,fullshare); p = skip_string(p,1); - strcpy(p,dev); + pstrcpy(p,dev); SCVAL(cli->inbuf,smb_rcls, 1); @@ -785,10 +785,10 @@ BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) p = smb_buf(cli->outbuf); *p++ = 4; - strcpy(p,fname_src); + pstrcpy(p,fname_src); p = skip_string(p,1); *p++ = 4; - strcpy(p,fname_dst); + pstrcpy(p,fname_dst); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -822,7 +822,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; - strcpy(p,fname); + pstrcpy(p,fname); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -855,7 +855,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - strcpy(p,dname); + pstrcpy(p,dname); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -887,7 +887,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - strcpy(p,dname); + pstrcpy(p,dname); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -952,7 +952,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) SSVAL(cli->outbuf,smb_vwv8,openfn); p = smb_buf(cli->outbuf); - strcpy(p,fname); + pstrcpy(p,fname); p = skip_string(p,1); send_smb(cli->fd,cli->outbuf); @@ -1179,7 +1179,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, p = smb_buf(cli->outbuf); *p = 4; - strcpy(p+1, fname); + pstrcpy(p+1, fname); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -1228,7 +1228,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) p = smb_buf(cli->outbuf); *p = 4; - strcpy(p+1, fname); + pstrcpy(p+1, fname); p = skip_string(p,1); *p = 4; @@ -1450,11 +1450,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; - strcpy(p, "zsT"); + pstrcpy(p, "zsT"); p = skip_string(p,1); - strcpy(p, "B516B16"); + pstrcpy(p, "B516B16"); p = skip_string(p,1); - fstrcpy(p,user); + pstrcpy(p,user); p = skip_string(p,1); SSVAL(p,0,532); p += 2; @@ -1546,7 +1546,7 @@ BOOL cli_negprot(struct cli_state *cli) prots[numprots].name && prots[numprots].prot<=cli->protocol; numprots++) { *p++ = 2; - strcpy(p,prots[numprots].name); + pstrcpy(p,prots[numprots].name); p += strlen(p) + 1; } diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 9f5c70e5e4..c9f7ee429b 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -31,7 +31,7 @@ represent a credential as a string char *credstr(uchar *cred) { static fstring buf; - sprintf(buf,"%02X%02X%02X%02X%02X%02X%02X%02X", + slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", cred[0], cred[1], cred[2], cred[3], cred[4], cred[5], cred[6], cred[7]); return buf; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 4de10f10ce..7f3d012c30 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -51,15 +51,15 @@ static void _interpret_node_status(char *p, char *master,char *rname) type = CVAL(p,15); p += 16; - strcat(flags, (p[0] & 0x80) ? " " : " "); - if ((p[0] & 0x60) == 0x00) strcat(flags,"B "); - if ((p[0] & 0x60) == 0x20) strcat(flags,"P "); - if ((p[0] & 0x60) == 0x40) strcat(flags,"M "); - if ((p[0] & 0x60) == 0x60) strcat(flags,"H "); - if (p[0] & 0x10) strcat(flags," "); - if (p[0] & 0x08) strcat(flags," "); - if (p[0] & 0x04) strcat(flags," "); - if (p[0] & 0x02) strcat(flags," "); + fstrcat(flags, (p[0] & 0x80) ? " " : " "); + if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B "); + if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P "); + if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M "); + if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H "); + if (p[0] & 0x10) fstrcat(flags," "); + if (p[0] & 0x08) fstrcat(flags," "); + if (p[0] & 0x04) fstrcat(flags," "); + if (p[0] & 0x02) fstrcat(flags," "); if (master && !*master && type == 0x1d) { StrnCpy(master,qname,15); @@ -341,9 +341,9 @@ BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr if (*line == '#') continue; - strcpy(ip,""); - strcpy(name,""); - strcpy(flags,""); + pstrcpy(ip,""); + pstrcpy(name,""); + pstrcpy(flags,""); ptr = line; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 5a8a037ce5..6c178758c6 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -252,7 +252,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) buf1[0] = '*'; buf1[15] = name->name_type; } else { - sprintf(buf1,"%-15.15s%c",name->name,name->name_type); + slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type); } buf[offset] = 0x20; @@ -270,7 +270,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) if (name->scope[0]) { /* XXXX this scope handling needs testing */ ret += strlen(name->scope) + 1; - strcpy(&buf[offset+1],name->scope); + pstrcpy(&buf[offset+1],name->scope); p = &buf[offset+1]; while ((p = strchr(p,'.'))) { diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 0788ae1b60..d2f9335000 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -525,7 +525,7 @@ char *get_nt_error_msg(uint32 nt_code) static pstring msg; int idx = 0; - strcpy(msg, "Unknown NT error"); + pstrcpy(msg, "Unknown NT error"); nt_code &= 0xFFFF; @@ -533,7 +533,7 @@ char *get_nt_error_msg(uint32 nt_code) { if (nt_errs[idx].nt_errcode == nt_code) { - strcpy(msg, nt_errs[idx].nt_errstr); + pstrcpy(msg, nt_errs[idx].nt_errstr); return msg; } idx++; diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index e8c4544394..c284d18ba6 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -165,18 +165,18 @@ char *smb_errstr(char *inbuf) if (num == err[j].code) { if (DEBUGLEVEL > 0) - sprintf(ret,"%s - %s (%s)",err_classes[i].class, + slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class, err[j].name,err[j].message); else - sprintf(ret,"%s - %s",err_classes[i].class,err[j].name); + slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name); return ret; } } - sprintf(ret,"%s - %d",err_classes[i].class,num); + slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num); return ret; } - sprintf(ret,"Error: Unknown error (%d,%d)",class,num); + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); return(ret); } -- cgit From 4b587cd3ed32b416b43865bcc0afb21d7af3eecb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 13 May 1998 05:03:17 +0000 Subject: test for overflow in nmb name parsing code (This used to be commit 204a939807d6fe66fcd721aabf7a88ee33eb23d6) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6c178758c6..f59371d559 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -197,7 +197,7 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na unsigned char c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0)) return(0); + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0); name->name[n++] = (c1<<4) | c2; m -= 2; } -- cgit From bce6d410130982af6ca58dc9a0d297b5f80e6c6c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 May 1998 03:20:42 +0000 Subject: namequery.c: Fixed SGI IRIX 5.x compiler problem. server.c: Added MACHINE.SID file generation - use lp_domain_sid() be default. smbpass.c: Exposed do_file_lock() as I now use it in server.c Jeremy. (This used to be commit 5bf17840ac7d65d08dd3fdfe8b789010488f6808) --- source3/libsmb/namequery.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7f3d012c30..a578ad8947 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -552,7 +552,9 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) * the first successful match. */ for( i = 0; i < num_interfaces; i++) { - struct in_addr sendto_ip = *iface_bcast(*iface_n_ip(i)); + struct in_addr sendto_ip; + /* Done this way to fix compiler error on IRIX 5.x */ + sendto_ip = *iface_bcast(*iface_n_ip(i)); iplist = name_query(sock, name, 0x20, True, False, sendto_ip, &count, NULL); if(iplist != NULL) { *return_ip = iplist[0]; -- cgit From cb757820f5452d192ce3b1eeb4f19a17ee93c3fe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Jun 1998 01:35:52 +0000 Subject: Added SSL support from Christian Starkjohann This patch may not yet compile with -DUSE_SSL enabled, further Makefile changes may be needed. But it was important to get this code in place before I go off to USENIX. Jeremy. (This used to be commit 31e768369fdc61e07c59630c86c62239f3d3f3f7) --- source3/libsmb/clientgen.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9dfd482da3..68bd369606 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1633,12 +1633,25 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, _smb_setlen(cli->outbuf,len); CVAL(cli->outbuf,0) = 0x81; +#ifdef USE_SSL +retry: +#endif /* USE_SSL */ + send_smb(cli->fd,cli->outbuf); DEBUG(5,("Sent session request\n")); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; +#ifdef USE_SSL + if(CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ + if(!sslutil_fd_is_ssl(cli->fd)){ + if(sslutil_connect(cli->fd) == 0) + goto retry; + } + } +#endif /* USE_SSL */ + if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ cli->rap_error = CVAL(cli->inbuf,0); -- cgit From bbd7ca65e706457f5dbc046e83b4bd8cdde5be8f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Jun 1998 18:25:36 +0000 Subject: clientgen: Added USE_SSL for client shutdown. clitar.c: Added 'Samba style' comments before string_create_s(). loadparm.c: Fixed missing comma in SSL code. util.c: Removed string_create_s(). Currently it's only called from clitar.c and having it here as well as a static in clitar causes the compile to break (Richard, please decide where you want this function). lib/rpc/parse/parse_net.c: Fix from to stop coredump on missing parameter. Jeremy. (This used to be commit d23b44322570cb9a7aa2b86407bf4f91010a237b) --- source3/libsmb/clientgen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 68bd369606..093b3aedf9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1718,6 +1718,9 @@ void cli_shutdown(struct cli_state *cli) { if (cli->outbuf) free(cli->outbuf); if (cli->inbuf) free(cli->inbuf); +#ifdef USE_SSL + if (cli->fd != -1) sslutil_disconnect(cli->fd); +#endif /* USE_SSL */ if (cli->fd != -1) close(cli->fd); memset(cli, 0, sizeof(*cli)); } -- cgit From 8afebcdd7e055cd6c6f9eb69f9ba652b4e1ab591 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 21 Jun 1998 12:44:34 +0000 Subject: Remove the copyright to Canon Information Systems Australia, as we don't want them to have the copyright. Added a new DOSERR response code that Win95 returns, unimp, unimplemented. Added code to ignore errors on setting remote time, as Win 95 does not like the time being changed on a directory. Win NT and Samba are OK at this. This is the next to last clean-ups here. Next is to properly handle restore times on directories (except for Win95--see above). Now have Jay's changes in and have fixed a bug reported by Tim Lee. (This used to be commit dc9436bae4493b71ba92970d6cc49dbb33cd55cd) --- source3/libsmb/smberr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index c284d18ba6..ee751c0f80 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -58,6 +58,7 @@ err_code_struct dos_msgs[] = { {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."}, {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRunsup", 50, "The operation is unsupported"}, {"ERRnosuchshare", 67, "You specified an invalid share name"}, {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."}, {"ERRbadpipe",230,"Pipe invalid."}, -- cgit From d8b0a8bab2334e9214975e3ac35c1556c4030fd9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 27 Jun 1998 00:27:44 +0000 Subject: nisppass.c: Fixed incorrect parameter usage. nmbd_become_lmb.c: Add 'force_new_election' parameter to some functions. This allows the start of the election to be done *after* the demotion from local master browser is done. Also changed code so release of 1d name is done immediately to allow other local master to gain it. nmbd_elections.c: Ensured no elections are run until we have registered the WORKGROUP<1e> name that we must listen on to participate in elections. nmbd_incomingdgrams.c: Use force_new_election code. nmbd_namelistdb.c: Make update_name_in_namelist static. nmbd_subnetdb.c: Fix bug in comparison function. We cannot use memcmp as structure packing may make this fail. nmbd_packets.c: Ensure that we only send one release packet when sending a broadcast packet. nmbd_workgroupdb.c: Ensure we put the correct value in the ElectionCriterion field. nmblib.c: Ensure make_nmb_name zero's the struct nmb_name. Jeremy. (This used to be commit 1fcb094ba04f01be1261ac92198c25b21b0d5ad5) --- source3/libsmb/nmblib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index f59371d559..89b0fa7a92 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -762,6 +762,7 @@ static int build_dgram(char *buf,struct packet_struct *p) ******************************************************************/ void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) { + memset((char *)n, '\0', sizeof(struct nmb_name)); StrnCpy(n->name,name,15); strupper(n->name); n->name_type = (unsigned int)type & 0xFF; -- cgit From a5ddf0881e2410b7d4d8f1a389785e4db28d989e Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Tue, 14 Jul 1998 01:52:09 +0000 Subject: Added strupper() function call to up-case the scope field in the make_nmb_name() function. Database lookups (eg. gdbm) will often use byte-by-byte comparisons, so it is important that the case and padding are correct. Chris -)----- (This used to be commit d64ca4250ff0df4ceffe49b7d462df699a6981b4) --- source3/libsmb/nmblib.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 89b0fa7a92..66f85d40fd 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -759,14 +759,15 @@ static int build_dgram(char *buf,struct packet_struct *p) /******************************************************************* build a nmb name - ******************************************************************/ -void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) + *******************************************************************/ +void make_nmb_name( struct nmb_name *n, char *name, int type, char *this_scope ) { - memset((char *)n, '\0', sizeof(struct nmb_name)); - StrnCpy(n->name,name,15); - strupper(n->name); + memset( (char *)n, '\0', sizeof(struct nmb_name) ); + StrnCpy( n->name, name, 15 ); + strupper( n->name ); n->name_type = (unsigned int)type & 0xFF; - StrnCpy(n->scope,this_scope,63); + StrnCpy( n->scope, this_scope, 63 ); + strupper( n->scope ); } /******************************************************************* -- cgit From 64578c0589a3a741f81fb55c16eeb882128da00b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Jul 1998 03:08:05 +0000 Subject: merge from the autoconf2 branch to the main branch (This used to be commit 3bda7ac417107a7b01d91805ca71c4330657ed21) --- source3/libsmb/clientgen.c | 16 +++++++--------- source3/libsmb/namequery.c | 2 +- source3/libsmb/smberr.c | 4 +--- 3 files changed, 9 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 093b3aedf9..7dc57bfb47 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -19,9 +19,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef SYSLOG -#undef SYSLOG -#endif +#define NO_SYSLOG #include "includes.h" #include "trans2.h" @@ -1633,9 +1631,9 @@ BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, _smb_setlen(cli->outbuf,len); CVAL(cli->outbuf,0) = 0x81; -#ifdef USE_SSL +#ifdef WITH_SSL retry: -#endif /* USE_SSL */ +#endif /* WITH_SSL */ send_smb(cli->fd,cli->outbuf); DEBUG(5,("Sent session request\n")); @@ -1643,14 +1641,14 @@ retry: if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; -#ifdef USE_SSL +#ifdef WITH_SSL if(CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ if(!sslutil_fd_is_ssl(cli->fd)){ if(sslutil_connect(cli->fd) == 0) goto retry; } } -#endif /* USE_SSL */ +#endif /* WITH_SSL */ if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ @@ -1718,9 +1716,9 @@ void cli_shutdown(struct cli_state *cli) { if (cli->outbuf) free(cli->outbuf); if (cli->inbuf) free(cli->inbuf); -#ifdef USE_SSL +#ifdef WITH_SSL if (cli->fd != -1) sslutil_disconnect(cli->fd); -#endif /* USE_SSL */ +#endif /* WITH_SSL */ if (cli->fd != -1) close(cli->fd); memset(cli, 0, sizeof(*cli)); } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a578ad8947..344806083a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -313,7 +313,7 @@ FILE *startlmhosts(char *fname) { FILE *fp = fopen(fname,"r"); if (!fp) { - DEBUG(2,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", + DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", fname, strerror(errno))); return NULL; } diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index ee751c0f80..c2d8884d73 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -18,9 +18,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#ifdef SYSLOG -#undef SYSLOG -#endif +#define NO_SYSLOG #include "includes.h" -- cgit From 28900ea26ff1c8d41328bba30206db7fe91e2184 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 31 Jul 1998 22:39:15 +0000 Subject: As per a Andrew's message, I went through and removed the timestring() timestamps from several DEBUG messages. The timestamps are redundant now that DEBUG() provides them automatically. There are still a few more files to do, but I've got to get home for dinner. Chris -)----- (This used to be commit 60286ccecaa6028d687e6406755016455e3b3a26) --- source3/libsmb/nmblib.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 66f85d40fd..62c3f22b1a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -678,8 +678,8 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) num_good_receives++; - DEBUG(5,("%s received a packet of len %d from (%s) port %d\n", - timestring(),length,inet_ntoa(packet->ip),packet->port)); + DEBUG(5,("Received a packet of len %d from (%s) port %d\n", + length, inet_ntoa(packet->ip), packet->port ) ); return(packet); } @@ -699,8 +699,8 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; - DEBUG(5,("%s sending a packet of len %d to (%s) on port %d\n", - timestring(),len,inet_ntoa(ip),port)); + DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", + len, inet_ntoa(ip), port ) ); ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); -- cgit From f1abfacd4d230075e5c4029271f2f3952ac2c68a Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 3 Aug 1998 18:13:13 +0000 Subject: I finished removing timestring() calls from DEBUG() messages. Also went through and changed some DEBUG() calls to DEBUGADD() to combine output under a single timestamp. There were too many timestamps. Note that Jeremy has told me that he's working on adding a config parameter to turn timestamps off. Cool. Chris -)----- (This used to be commit 247dbc9a24987035a47f1ba4fa143b1e2c050e92) --- source3/libsmb/nmblib.c | 77 ++++++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 62c3f22b1a..9c7a606a26 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -67,18 +67,19 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) { int i, j; - DEBUG(4,(" %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", - hdr, - namestr(&res->rr_name), - res->rr_type, - res->rr_class, - res->ttl)); - - if (res->rdlength == 0 || res->rdata == NULL) return; + DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, + namestr(&res->rr_name), + res->rr_type, + res->rr_class, + res->ttl ) ); + + if( res->rdlength == 0 || res->rdata == NULL ) + return; for (i = 0; i < res->rdlength; i+= 16) { - DEBUG(4, (" %s %3x char ", hdr, i)); + DEBUGADD(4, (" %s %3x char ", hdr, i)); for (j = 0; j < 16; j++) { @@ -86,18 +87,18 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) if (x < 32 || x > 127) x = '.'; if (i+j >= res->rdlength) break; - DEBUG(4, ("%c", x)); + DEBUGADD(4, ("%c", x)); } - DEBUG(4, (" hex ", i)); + DEBUGADD(4, (" hex ", i)); for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUG(4, ("%02X", (unsigned char)res->rdata[i+j])); + DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); } - DEBUG(4, ("\n")); + DEBUGADD(4, ("\n")); } } @@ -107,34 +108,38 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) void debug_nmb_packet(struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - - DEBUG(4,("nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), p->port, - nmb->header.name_trn_id, - lookup_opcode_name(nmb->header.opcode), - nmb->header.opcode,BOOLSTR(nmb->header.response))); - DEBUG(4,(" header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", - BOOLSTR(nmb->header.nm_flags.bcast), - BOOLSTR(nmb->header.nm_flags.recursion_available), - BOOLSTR(nmb->header.nm_flags.recursion_desired), - BOOLSTR(nmb->header.nm_flags.trunc), - BOOLSTR(nmb->header.nm_flags.authoritative))); - DEBUG(4,(" header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", - nmb->header.rcode, - nmb->header.qdcount, - nmb->header.ancount, - nmb->header.nscount, - nmb->header.arcount)); + + if( DEBUGLVL( 4 ) ) + { + dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa(p->ip), p->port, + nmb->header.name_trn_id, + lookup_opcode_name(nmb->header.opcode), + nmb->header.opcode, + BOOLSTR(nmb->header.response) ); + dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR(nmb->header.nm_flags.bcast), + BOOLSTR(nmb->header.nm_flags.recursion_available), + BOOLSTR(nmb->header.nm_flags.recursion_desired), + BOOLSTR(nmb->header.nm_flags.trunc), + BOOLSTR(nmb->header.nm_flags.authoritative) ); + dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, + nmb->header.nscount, + nmb->header.arcount ); + } if (nmb->header.qdcount) { - DEBUG(4,(" question: q_name=%s q_type=%d q_class=%d\n", - namestr(&nmb->question.question_name), - nmb->question.question_type, - nmb->question.question_class)); + DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", + namestr(&nmb->question.question_name), + nmb->question.question_type, + nmb->question.question_class) ); } - if (nmb->answers && nmb->header.ancount) + if (nmb->answers && nmb->header.ancount) { debug_nmb_res_rec(nmb->answers,"answers"); } -- cgit From 27ff18a184556f1e157de7c2789f39e3e70a40fc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 9 Aug 1998 11:24:15 +0000 Subject: these dummy files are needed for autoconf processing (This used to be commit be762dc3de6c1ef768790522dfe93007a61ce5d7) --- source3/libsmb/dummy.in | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 source3/libsmb/dummy.in (limited to 'source3/libsmb') diff --git a/source3/libsmb/dummy.in b/source3/libsmb/dummy.in new file mode 100644 index 0000000000..e69de29bb2 -- cgit From 87bcd5502c105921b48f9654d1c4f6d14ed9e9f6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 9 Aug 1998 11:25:49 +0000 Subject: added ignore rules for the dummy files (This used to be commit 687f76a17d6d3ebd33b4d9a848deef56f3c1f56a) --- source3/libsmb/.cvsignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 source3/libsmb/.cvsignore (limited to 'source3/libsmb') diff --git a/source3/libsmb/.cvsignore b/source3/libsmb/.cvsignore new file mode 100644 index 0000000000..421376db9e --- /dev/null +++ b/source3/libsmb/.cvsignore @@ -0,0 +1 @@ +dummy -- cgit From b9623ab59e813131b1ed3f51616a46e719d59c21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Aug 1998 17:38:29 +0000 Subject: this is the bug change to using connection_struct* instead of cnum. Connections[] is now a local array in server.c I might have broken something with this change. In particular the oplock code is suspect and some .dll files aren't being oplocked when I expected them to be. I'll look at it after I've got some sleep. (This used to be commit c7ee025ead4a85b6fa44a832047b878451845fb6) --- source3/libsmb/credentials.c | 6 +++--- source3/libsmb/nmblib.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index c9f7ee429b..26d5c13bc9 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -96,7 +96,7 @@ void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, DEBUG(5,(" sess_key : %s\n", credstr(session_key))); DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); - DEBUG(5,(" timestamp: %lx\n" , timestamp.time)); + DEBUG(5,(" timestamp: %x\n" , timestamp.time)); DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); } @@ -200,12 +200,12 @@ BOOL deal_with_creds(uchar sess_key[8], new_cred = IVAL(sto_clnt_cred->challenge.data, 0); new_cred += new_clnt_time.time; - DEBUG(5,("deal_with_creds: new_cred[0]=%lx\n", new_cred)); + DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred)); /* doesn't matter that server time is 0 */ rtn_srv_cred->timestamp.time = 0; - DEBUG(5,("deal_with_creds: new_clnt_time=%lx\n", new_clnt_time.time)); + DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time)); /* create return credentials for inclusion in the reply */ cred_create(sess_key, &(sto_clnt_cred->challenge), new_clnt_time, diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9c7a606a26..c887ff55de 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -90,7 +90,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) DEBUGADD(4, ("%c", x)); } - DEBUGADD(4, (" hex ", i)); + DEBUGADD(4, (" hex ")); for (j = 0; j < 16; j++) { -- cgit From e13aeea928dd89373cfaf3916c96f853c1227884 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Aug 1998 01:19:26 +0000 Subject: configure: Changes for extra headers. configure.in: Source for header changes. client/clitar.c: Fixed isXXX macros & debugs for gcc pedantic compile. include/config.h.in: Added MEMSET, BZERO, MEMORY, RPCSVC_YPCLNT, STRINGS headers. include/includes.h: Headers for the above. include/smb.h: Made SIGNAL_CAST POSIX by default void (*)(int). lib/access.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/charset.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/debug.c: Fixed signal functs. lib/kanji.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/smbrun.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/util.c: Fixed isXXX macros & debugs for gcc pedantic compile. libsmb/namequery.c: Fixed isXXX macros & debugs for gcc pedantic compile. locking/shmem.c: Fixed isXXX macros & debugs for gcc pedantic compile. locking/shmem_sysv.c: Fixed error messages in sysV stuff. nmbd/asyncdns.c: Fixed signal functs. nmbd/nmbd.c: Fixed isXXX macros & debugs for gcc pedantic compile. passdb/passdb.c: Fixed isXXX macros & debugs for gcc pedantic compile. passdb/smbpassfile.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/chgpasswd.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/ipc.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/nttrans.c: Fixed fsp code path. smbd/password.c: fixed HAVE_YP_GET_DEFAULT_DOMAIN problem. smbd/printing.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/reply.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/server.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/trans2.c: Fixed core dump bug. smbd/uid.c: Fixed isXXX macros & debugs for gcc pedantic compile. Jeremy. (This used to be commit 1b9cbcd02e575dc0a95fa589f720df30a4acc46b) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 344806083a..8b0d68ce6a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -72,7 +72,7 @@ static void _interpret_node_status(char *p, char *master,char *rname) } for (i = strlen( qname) ; --i >= 0 ; ) { - if (!isprint(qname[i])) qname[i] = '.'; + if (!isprint((int)qname[i])) qname[i] = '.'; } DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags)); p+=2; @@ -439,7 +439,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) } for (i=0; pure_address && name[i]; i++) - if (!(isdigit(name[i]) || name[i] == '.')) + if (!(isdigit((int)name[i]) || name[i] == '.')) pure_address = False; /* if it's in the form of an IP address then get the lib to interpret it */ -- cgit From 8978aae69699ccab76fdf95037948b1cc7e7c286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 03:52:05 +0000 Subject: much cleaner chain pointer handling for both files and pipes. the chain pointer is now stored as a static and is set whenever a handle is created or extracted. This also makes the code less error prone. (This used to be commit 068a862982bea726e8d7b1b4065d510b9840a272) --- source3/libsmb/nmblib.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index c887ff55de..9390302ab2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -26,8 +26,6 @@ extern int DEBUGLEVEL; int num_good_sends = 0; int num_good_receives = 0; -extern pstring scope; -extern struct in_addr ipzero; static struct opcode_names { char *nmb_opcode_name; -- cgit From 69c6f1624d79e4cf4296856d66216cca90863286 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Aug 1998 06:14:52 +0000 Subject: reduced the memory footprint a bit by changing some large static int arrays to uchar (This used to be commit 01b642a3793a1bea0517370a9a64945fd86ddf02) --- source3/libsmb/smbdes.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 4daf616588..eebe0dc54f 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -46,8 +46,9 @@ */ +#define uchar unsigned char -static int perm1[56] = {57, 49, 41, 33, 25, 17, 9, +static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, @@ -56,7 +57,7 @@ static int perm1[56] = {57, 49, 41, 33, 25, 17, 9, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; -static int perm2[48] = {14, 17, 11, 24, 1, 5, +static uchar perm2[48] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, @@ -65,7 +66,7 @@ static int perm2[48] = {14, 17, 11, 24, 1, 5, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; -static int perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, +static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, @@ -74,7 +75,7 @@ static int perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; -static int perm4[48] = { 32, 1, 2, 3, 4, 5, +static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, @@ -83,7 +84,7 @@ static int perm4[48] = { 32, 1, 2, 3, 4, 5, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; -static int perm5[32] = { 16, 7, 20, 21, +static uchar perm5[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, @@ -93,7 +94,7 @@ static int perm5[32] = { 16, 7, 20, 21, 22, 11, 4, 25}; -static int perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, +static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, @@ -103,9 +104,9 @@ static int perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, 33, 1, 41, 9, 49, 17, 57, 25}; -static int sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; +static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; -static int sbox[8][4][16] = { +static uchar sbox[8][4][16] = { {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, @@ -146,7 +147,7 @@ static int sbox[8][4][16] = { {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; -static void permute(char *out, char *in, int *p, int n) +static void permute(char *out, char *in, uchar *p, int n) { int i; for (i=0;i Date: Tue, 25 Aug 1998 06:42:09 +0000 Subject: some smbtorture hacks (random IPC calls) (This used to be commit b32a346a1c50ba40224b8165e08e78867be2d376) --- source3/libsmb/clientgen.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7dc57bfb47..117d065f76 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -348,11 +348,11 @@ BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, /**************************************************************************** call a remote api ****************************************************************************/ -static BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) +BOOL cli_api(struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt) { cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ -- cgit From 38142a1ebbe860778e26eaff68585726061c05e2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Aug 1998 21:46:29 +0000 Subject: This checking fixes the statcache bug that stopped NetBench from running correctly. Added new parameter "stat cache size" - set to 50 by default. I now declare the statcache code officially "open" for business :-). It gets a hit rate of 97% with a NetBench run and seems to make using a case insensitive run as efficient as a case sensitive run. Also tidied up our sys_select usage - added a maxfd parameter and also added an implementation of select in terms of poll(), for systems where poll() is much faster. This is disabled by default. Jeremy. (This used to be commit 779b924ec1f6c81ff578d22295b20fece698d1fc) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9390302ab2..81a9505d6b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -899,7 +899,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - sys_select(&fds,&timeout); + sys_select(fd+1,&fds,&timeout); if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); -- cgit From 179e8c66f121e01b5e69ad8b1c39f8a1a1e45814 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Aug 1998 08:45:23 +0000 Subject: changed the way that name query records are sorted in replies. They are now sorted by the number of common leading bits in the IP address with the address of the querying host. (This used to be commit 4460a1bc6aa7666d1c71d32ba73855d6ed32320a) --- source3/libsmb/nmblib.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 81a9505d6b..7729380615 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -908,3 +908,47 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) } +/**************************************************************************** +return the number of bits that match between two 4 character buffers + ***************************************************************************/ +static int matching_bits(uchar *p1, uchar *p2) +{ + int i, j, ret = 0; + for (i=0; i<4; i++) { + if (p1[i] != p2[i]) break; + ret += 8; + } + + if (i==4) return ret; + + for (j=0; j<8; j++) { + if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; + ret++; + } + + return ret; +} + + +static uchar sort_ip[4]; + +/**************************************************************************** +compare two query reply records + ***************************************************************************/ +static int name_query_comp(uchar *p1, uchar *p2) +{ + return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip); +} + +/**************************************************************************** +sort a set of 6 byte name query response records so that the IPs that +have the most leading bits in common with the specified address come first + ***************************************************************************/ +void sort_query_replies(char *data, int n, struct in_addr ip) +{ + if (n <= 1) return; + + putip(sort_ip, (char *)&ip); + + qsort(data, n, 6, name_query_comp); +} -- cgit From 61b5fd6f32e9ccb612df1354a3e3b3bed5f2b808 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Aug 1998 03:11:42 +0000 Subject: bounds check next_token() to prevent possible buffer overflows (This used to be commit 3eade55dc7c842bdc50205c330802d211fae54d3) --- source3/libsmb/namequery.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8b0d68ce6a..5e189020ad 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -347,13 +347,13 @@ BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr ptr = line; - if (next_token(&ptr,ip ,NULL)) + if (next_token(&ptr,ip ,NULL,sizeof(ip))) ++count; - if (next_token(&ptr,name ,NULL)) + if (next_token(&ptr,name ,NULL, sizeof(name))) ++count; - if (next_token(&ptr,flags,NULL)) + if (next_token(&ptr,flags,NULL, sizeof(flags))) ++count; - if (next_token(&ptr,extra,NULL)) + if (next_token(&ptr,extra,NULL, sizeof(extra))) ++count; if (count <= 0) @@ -452,7 +452,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) ptr = name_resolve_list; if (!ptr || !*ptr) ptr = "host"; - while (next_token(&ptr, tok, LIST_SEP)) { + while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if(strequal(tok, "host") || strequal(tok, "hosts")) { /* -- cgit From cc022132a6dd937eff330612ebaaefe23bff8a6c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Aug 1998 03:13:20 +0000 Subject: cast the qsort to prevent warnings (This used to be commit 55333edd2eed33961ced4eb4b6898f5ca9ca1820) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7729380615..ab57590b6f 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -950,5 +950,5 @@ void sort_query_replies(char *data, int n, struct in_addr ip) putip(sort_ip, (char *)&ip); - qsort(data, n, 6, name_query_comp); + qsort(data, n, 6, QSORT_CAST name_query_comp); } -- cgit From 9076947b935fbeb13babf42974ff527ef916aabb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Aug 1998 07:21:54 +0000 Subject: if an address is ipzero in cli_connect() then do a name query (This used to be commit 0a5718b0aef29706be81a50f2ac2c5eb4c6fbb32) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 117d065f76..52919d9eb4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1665,10 +1665,11 @@ open the client sockets BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) { struct in_addr dest_ip; + extern struct in_addr ipzero; fstrcpy(cli->desthost, host); - if (!ip) { + if (!ip || ip_equal(*ip, ipzero)) { if(!resolve_name( cli->desthost, &dest_ip)) { return False; } -- cgit From e9ea36e4d2270bd7d32da12ef6d6e2299641582d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Sep 1998 05:07:05 +0000 Subject: tridge the destroyer returns! prompted by the interpret_security() dead code that Jean-Francois pointed out I added a make target "finddead" that finds potentially dead (ie. unused) code. It spat out 304 function names ... I went through these are deleted many of them, making others static (finddead also reports functions that are used only in the local file). in doing this I have almost certainly deleted some useful code. I may have even prevented compilation with some compile options. I apologise. I decided it was better to get rid of this code now and add back the one or two functions that are needed than to keep all this baggage. So, if I have done a bit too much "destroying" then let me know. Keep the swearing to a minimum :) One bit I didn't do is the ubibt code. Chris, can you look at that? Heaps of unused functions there. Can they be made static? (This used to be commit 2204475c87f3024ea8fd1fbd7385b2def617a46f) --- source3/libsmb/clientgen.c | 6 +++++- source3/libsmb/nmblib.c | 3 +-- source3/libsmb/smbencrypt.c | 23 ----------------------- 3 files changed, 6 insertions(+), 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 52919d9eb4..c85de92989 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -51,7 +51,7 @@ struct /**************************************************************************** return a description of an SMB error ****************************************************************************/ -char *cli_smb_errstr(struct cli_state *cli) +static char *cli_smb_errstr(struct cli_state *cli) { return smb_errstr(cli->inbuf); } @@ -425,6 +425,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) return (cli->rap_error == 0); } +#if UNUSED_CODE /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ @@ -480,6 +481,7 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) return(count>0); } +#endif /**************************************************************************** call a NetServerEnum for the specified workgroup and servertype mask. @@ -763,6 +765,7 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } +#if UNUSED_CODE /**************************************************************************** rename a file ****************************************************************************/ @@ -799,6 +802,7 @@ BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) return True; } +#endif /**************************************************************************** delete a file diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ab57590b6f..d08003133f 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -44,8 +44,7 @@ static struct opcode_names { /**************************************************************************** * Lookup a nmb opcode name. ****************************************************************************/ - -char *lookup_opcode_name( int opcode ) +static char *lookup_opcode_name( int opcode ) { struct opcode_names *op_namep; int i; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 052dae06f1..6840f2e2c8 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -109,27 +109,4 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) E_P24(p21, c8, p24); } -/* Does both the NT and LM owfs of a user's password */ - -void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16) -{ - char passwd[130]; - StrnCpy(passwd, pwd, sizeof(passwd)-1); - - /* Calculate the MD4 hash (NT compatible) of the password */ - memset(nt_p16, '\0', 16); - E_md4hash((uchar *)passwd, (uchar *)nt_p16); - - /* Mangle the passwords into Lanman format */ - passwd[14] = '\0'; - strupper(passwd); - - /* Calculate the SMB (lanman) hash functions of the password */ - - memset(p16, '\0', 16); - E_P16((uchar *) passwd, (uchar *)p16); - - /* clear out local copy of user's password (just being paranoid). */ - bzero(passwd, sizeof(passwd)); -} -- cgit From e649750cb4d2d2577f0577b1d7a87ae4daf8fb6f Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Mon, 21 Sep 1998 09:07:08 +0000 Subject: major autoconf clean-up fix problems in builds with srcdir!=builddir (This used to be commit 1ffc3b807a3f80644c974b454ff5e6f68e89b546) --- source3/libsmb/dummy.in | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dummy.in b/source3/libsmb/dummy.in index e69de29bb2..8b13789179 100644 --- a/source3/libsmb/dummy.in +++ b/source3/libsmb/dummy.in @@ -0,0 +1 @@ + -- cgit From 66d5d73a5d75e88a77970f7b27687b8354ab2e80 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 25 Sep 1998 21:01:52 +0000 Subject: added rpcclient program (This used to be commit aa38f39d67fade4dfd7badb7a9b39c833a1dd1ca) --- source3/libsmb/clientgen.c | 173 +++++++++++++++++++++++++++++--- source3/libsmb/pwd_cache.c | 236 ++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smbencrypt.c | 35 +++++++ 3 files changed, 432 insertions(+), 12 deletions(-) create mode 100644 source3/libsmb/pwd_cache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c85de92989..89caad419f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1604,31 +1604,26 @@ BOOL cli_negprot(struct cli_state *cli) /**************************************************************************** - send a session request + send a session request. see rfc1002.txt 4.3 and 4.3.2 ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, - char *myname) +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called) { - fstring dest; char *p; int len = 4; /* send a session request (RFC 1002) */ - fstrcpy(dest,host); + memcpy(&(cli->calling), calling, sizeof(*calling)); + memcpy(&(cli->called ), called , sizeof(*called )); - p = strchr(dest,'.'); - if (p) *p = 0; - - fstrcpy(cli->desthost, dest); - /* put in the destination name */ p = cli->outbuf+len; - name_mangle(dest,p,name_type); + name_mangle(cli->called .name, p, cli->called .name_type); len += name_len(p); /* and my name */ p = cli->outbuf+len; - name_mangle(myname,p,0); + name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); /* setup the packet length */ @@ -1754,3 +1749,157 @@ int cli_setpid(struct cli_state *cli, int pid) cli->pid = pid; return ret; } + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_reestablish_connection(struct cli_state *cli) +{ + struct nmb_name calling; + struct nmb_name called; + fstring dest_host; + struct in_addr dest_ip; + fstring share; + fstring dev; + BOOL do_tcon = False; + + if (!cli->initialised || cli->fd == -1) + { + DEBUG(3,("cli_reestablish_connection: not connected\n")); + return False; + } + + /* copy the parameters necessary to re-establish the connection */ + + if (cli->cnum != 0) + { + fstrcpy(share, cli->share); + fstrcpy(dev , cli->dev); + do_tcon = True; + } + + memcpy(&called , &(cli->called ), sizeof(called )); + memcpy(&calling, &(cli->calling), sizeof(calling)); + fstrcpy(dest_host, cli->full_dest_host_name); + dest_ip = cli->dest_ip; + + DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", + namestr(&calling), namestr(&called), inet_ntoa(dest_ip), + cli->user_name, cli->domain)); + + return cli_establish_connection(cli, + dest_host, &dest_ip, + &calling, &called, + share, dev, False, do_tcon); +} + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon) +{ + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + namestr(calling), namestr(called), inet_ntoa(*dest_ip), + cli->user_name, cli->domain)); + + /* establish connection */ + + if ((!cli->initialised)) + { + return False; + } + + if (cli->fd == -1) + { + if (!cli_connect(cli, dest_host, dest_ip)) + { + DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", + namestr(calling), inet_ntoa(*dest_ip))); + return False; + } + } + + if (!cli_session_request(cli, calling, called)) + { + DEBUG(1,("failed session request\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (!cli_negprot(cli)) + { + DEBUG(1,("failed negprot\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (cli->pwd.cleartext || cli->pwd.null_pwd) + { + /* attempt clear-text session */ + + fstring passwd; + + pwd_get_cleartext(&(cli->pwd), passwd); + + /* attempt clear-text session */ + if (!cli_session_setup(cli, cli->user_name, + passwd, strlen(passwd), + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)passwd, strlen(passwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + } + } + else + { + /* attempt encrypted session */ + uchar nt_sess_pwd[24]; + uchar lm_sess_pwd[24]; + + /* creates (storing a copy of) and then obtains a 24 byte password OWF */ + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); + + /* attempt encrypted session */ + if (!cli_session_setup(cli, cli->user_name, + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + nt_sess_pwd, sizeof(nt_sess_pwd), + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) cli_shutdown(cli); + return False; + } + } + } + + if (do_shutdown) cli_shutdown(cli); + + return True; +} diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c new file mode 100644 index 0000000000..e799a5458c --- /dev/null +++ b/source3/libsmb/pwd_cache.c @@ -0,0 +1,236 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Password cacheing. obfuscation is planned + Copyright (C) Luke Kenneth Casson Leighton 1996-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; + + +/**************************************************************************** +initialises a password structure +****************************************************************************/ +void pwd_init(struct pwd_info *pwd) +{ + bzero(pwd->password , sizeof(pwd->password )); + bzero(pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); + bzero(pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); + bzero(pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); + bzero(pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + + pwd->null_pwd = True; /* safest option... */ + pwd->cleartext = False; + pwd->crypted = False; +} + +/**************************************************************************** +de-obfuscates a password +****************************************************************************/ +static void pwd_deobfuscate(struct pwd_info *pwd) +{ +} + +/**************************************************************************** +obfuscates a password +****************************************************************************/ +static void pwd_obfuscate(struct pwd_info *pwd) +{ +} + +/**************************************************************************** +sets the obfuscation key info +****************************************************************************/ +void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) +{ +} + +/**************************************************************************** +reads a password +****************************************************************************/ +void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) +{ + /* grab a password */ + char *user_pass; + + pwd_init(pwd); + + user_pass = (char*)getpass(passwd_report); + + if (user_pass == NULL || user_pass[0] == 0) + { + pwd_set_nullpwd(pwd); + } + else if (do_encrypt) + { + pwd_make_lm_nt_16(pwd, user_pass); + } + else + { + pwd_set_cleartext(pwd, user_pass); + } +} + +/**************************************************************************** + stores a cleartext password + ****************************************************************************/ +void pwd_set_nullpwd(struct pwd_info *pwd) +{ + pwd_init(pwd); + + pwd->cleartext = False; + pwd->null_pwd = True; + pwd->crypted = False; +} + +/**************************************************************************** + stores a cleartext password + ****************************************************************************/ +void pwd_set_cleartext(struct pwd_info *pwd, char *clr) +{ + pwd_init(pwd); + fstrcpy(pwd->password, clr); + pwd->cleartext = True; + pwd->null_pwd = False; + pwd->crypted = False; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + gets a cleartext password + ****************************************************************************/ +void pwd_get_cleartext(struct pwd_info *pwd, char *clr) +{ + pwd_deobfuscate(pwd); + if (pwd->cleartext) + { + fstrcpy(clr, pwd->password); + } + else + { + clr[0] = 0; + } + pwd_obfuscate(pwd); +} + +/**************************************************************************** + stores lm and nt hashed passwords + ****************************************************************************/ +void pwd_set_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]) +{ + pwd_init(pwd); + + if (lm_pwd) + { + memcpy(pwd->smb_lm_pwd, lm_pwd, 16); + } + else + { + bzero(pwd->smb_lm_pwd, 16); + } + + if (nt_pwd) + { + memcpy(pwd->smb_nt_pwd, nt_pwd, 16); + } + else + { + bzero(pwd->smb_nt_pwd, 16); + } + + pwd->null_pwd = False; + pwd->cleartext = False; + pwd->crypted = False; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + gets lm and nt hashed passwords + ****************************************************************************/ +void pwd_get_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]) +{ + pwd_deobfuscate(pwd); + memcpy(lm_pwd, pwd->smb_lm_pwd, 16); + memcpy(nt_pwd, pwd->smb_nt_pwd, 16); + pwd_obfuscate(pwd); +} + +/**************************************************************************** + makes lm and nt hashed passwords + ****************************************************************************/ +void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) +{ + pwd_init(pwd); + + nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pwd->null_pwd = False; + pwd->cleartext = False; + pwd->crypted = False; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + makes lm and nt OWF crypts + ****************************************************************************/ +void pwd_make_lm_nt_owf(struct pwd_info *pwd, char cryptkey[8]) +{ + pwd_deobfuscate(pwd); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("client cryptkey: ")); + dump_data(100, cryptkey, 8); +#endif + + SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_owf_passwd: ")); + dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + DEBUG(100,("nt_sess_pwd: ")); + dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); +#endif + + SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm_owf_passwd: ")); + dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + DEBUG(100,("lm_sess_pwd: ")); + dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); +#endif + + pwd->crypted = True; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + gets lm and nt crypts + ****************************************************************************/ +void pwd_get_lm_nt_owf(struct pwd_info *pwd, char lm_owf[24], char nt_owf[24]) +{ + pwd_deobfuscate(pwd); + memcpy(lm_owf, pwd->smb_lm_owf, 24); + memcpy(nt_owf, pwd->smb_nt_owf, 24); + pwd_obfuscate(pwd); +} + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6840f2e2c8..5a946e22c9 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -97,6 +97,41 @@ void E_md4hash(uchar *passwd, uchar *p16) mdfour(p16, (unsigned char *)wpwd, len); } +/* Does both the NT and LM owfs of a user's password */ +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) +{ + char passwd[130]; + StrnCpy(passwd, pwd, sizeof(passwd)-1); + + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + E_md4hash((uchar *)passwd, nt_p16); + + /* Mangle the passwords into Lanman format */ + passwd[14] = '\0'; + strupper(passwd); + + /* Calculate the SMB (lanman) hash functions of the password */ + + memset(p16, '\0', 16); + E_P16((uchar *) passwd, (uchar *)p16); + + /* clear out local copy of user's password (just being paranoid). */ + bzero(passwd, sizeof(passwd)); +} + +/* Does the des encryption from the NT or LM MD4 hash. */ +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) +{ + uchar p21[21]; + + memset(p21,'\0',21); + + memcpy(p21, passwd, 16); + E_P24(p21, c8, p24); +} + + /* Does the NT MD4 hash then des encryption. */ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) -- cgit From cf971f88ac188eec353a7fb021744b8076cc4eb7 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Mon, 28 Sep 1998 00:14:36 +0000 Subject: automated generation of .dummy files for each subdirectory; dummy.in files are no longer needed, and new directories will be taken care of automatically, at configure (or config.status --recheck) time (This used to be commit 237a8e5fe62d757c04b8207cbbee4df1470cfe4e) --- source3/libsmb/dummy.in | 1 - 1 file changed, 1 deletion(-) delete mode 100644 source3/libsmb/dummy.in (limited to 'source3/libsmb') diff --git a/source3/libsmb/dummy.in b/source3/libsmb/dummy.in deleted file mode 100644 index 8b13789179..0000000000 --- a/source3/libsmb/dummy.in +++ /dev/null @@ -1 +0,0 @@ - -- cgit From cf3a9741dc7427efb97eff09a3c197a906ce6767 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Sep 1998 21:43:48 +0000 Subject: Changes to test in configure if capabilities are enabled on a system. Changes to get Samba to compile cleanly with the IRIX compiler with the options : -fullwarn -woff 1209,1174 (the -woff options are to turn off warnings about unused function parameters and controlling loop expressions being constants). Split prototype generation as we hit a limit in IRIX nawk. Removed "." code in smbd/filename.c (yet again :-). Jeremy. (This used to be commit e0567433bd72aec17bf5a54cc292701095d25f09) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/namequery.c | 8 ++++---- source3/libsmb/pwd_cache.c | 9 ++++----- 3 files changed, 9 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 89caad419f..30f7dc5d99 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1879,7 +1879,7 @@ BOOL cli_establish_connection(struct cli_state *cli, /* attempt encrypted session */ if (!cli_session_setup(cli, cli->user_name, (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - nt_sess_pwd, sizeof(nt_sess_pwd), + (char*)nt_sess_pwd, sizeof(nt_sess_pwd), cli->domain)) { DEBUG(1,("failed session setup\n")); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 5e189020ad..f988504bba 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -102,8 +102,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, bzero((char *)&p,sizeof(p)); - if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + - (getpid()%(unsigned)100); + if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + + ((unsigned)getpid()%(unsigned)100); name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; nmb->header.name_trn_id = name_trn_id; @@ -210,8 +210,8 @@ struct in_addr *name_query(int fd,char *name,int name_type, BOOL bcast,BOOL recu bzero((char *)&p,sizeof(p)); (*count) = 0; - if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) + - (getpid()%(unsigned)100); + if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + + ((unsigned)getpid()%(unsigned)100); name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; nmb->header.name_trn_id = name_trn_id; diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index e799a5458c..92eee015b3 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -133,7 +133,7 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) /**************************************************************************** stores lm and nt hashed passwords ****************************************************************************/ -void pwd_set_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]) +void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_init(pwd); @@ -165,7 +165,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]) /**************************************************************************** gets lm and nt hashed passwords ****************************************************************************/ -void pwd_get_lm_nt_16(struct pwd_info *pwd, char lm_pwd[16], char nt_pwd[16]) +void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_deobfuscate(pwd); memcpy(lm_pwd, pwd->smb_lm_pwd, 16); @@ -191,7 +191,7 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) /**************************************************************************** makes lm and nt OWF crypts ****************************************************************************/ -void pwd_make_lm_nt_owf(struct pwd_info *pwd, char cryptkey[8]) +void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) { pwd_deobfuscate(pwd); @@ -226,11 +226,10 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, char cryptkey[8]) /**************************************************************************** gets lm and nt crypts ****************************************************************************/ -void pwd_get_lm_nt_owf(struct pwd_info *pwd, char lm_owf[24], char nt_owf[24]) +void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) { pwd_deobfuscate(pwd); memcpy(lm_owf, pwd->smb_lm_owf, 24); memcpy(nt_owf, pwd->smb_nt_owf, 24); pwd_obfuscate(pwd); } - -- cgit From a2d7f765e8500f23c126c7b7cb6bb346adc11641 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Tue, 29 Sep 1998 04:52:17 +0000 Subject: get away with dummy and .dummy files (This used to be commit 90a8a02484a0897b053fd6531b7fec5d23098b6f) --- source3/libsmb/.cvsignore | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/.cvsignore b/source3/libsmb/.cvsignore index 421376db9e..e69de29bb2 100644 --- a/source3/libsmb/.cvsignore +++ b/source3/libsmb/.cvsignore @@ -1 +0,0 @@ -dummy -- cgit From 6ecd472ef3a8beaa78edfb7cc431fa07674c494f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Sep 1998 17:48:44 +0000 Subject: uchar / char typecast issues (This used to be commit 1a1d8d0483fc05765e6dcc2da00405e0ec7421a2) --- source3/libsmb/clientgen.c | 4 ++-- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 30f7dc5d99..214f6c4445 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1869,8 +1869,8 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt encrypted session */ - uchar nt_sess_pwd[24]; - uchar lm_sess_pwd[24]; + char nt_sess_pwd[24]; + char lm_sess_pwd[24]; /* creates (storing a copy of) and then obtains a 24 byte password OWF */ pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 5a946e22c9..045008fac9 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -121,7 +121,7 @@ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) } /* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) +void SMBOWFencrypt(uchar passwd[16], char *c8, uchar p24[24]) { uchar p21[21]; -- cgit From 9066025a8a4afe1f7f559c455d86fc023792ed17 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Sep 1998 20:24:17 +0000 Subject: Got very strict about the differences and uses of uid_t, gid_t and vuid. Added sys_getgroups() to get around the int * return problem. Set correct datatypes for all uid, gid and vuid variables. Jeremy. (This used to be commit e570db46fc3a78e499523fd342e9a34cebb18998) --- source3/libsmb/clientgen.c | 76 +++++++++++++++++++++++++++++---------------- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 50 insertions(+), 28 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 214f6c4445..d77c58e00a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -118,7 +118,7 @@ static void cli_setup_packet(struct cli_state *cli) cli->rap_error = 0; cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); - SSVAL(cli->outbuf,smb_uid,cli->uid); + SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); if (cli->protocol > PROTOCOL_CORE) { SCVAL(cli->outbuf,smb_flg,0x8); @@ -393,7 +393,10 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) p += 2; pstrcpy(p,user); strupper(p); - p += 21; p++; p += 15; p++; + p += 21; + p++; + p += 15; + p++; pstrcpy(p, workstation); strupper(p); p += 16; @@ -420,8 +423,10 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) } } - if (rparam) free(rparam); - if (rdata) free(rdata); + if (rparam) + free(rparam); + if (rdata) + free(rdata); return (cli->rap_error == 0); } @@ -476,8 +481,10 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) } } - if (rparam) free(rparam); - if (rdata) free(rdata); + if (rparam) + free(rparam); + if (rdata) + free(rdata); return(count>0); } @@ -547,8 +554,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, } } - if (rparam) free(rparam); - if (rdata) free(rdata); + if (rparam) + free(rparam); + if (rdata) + free(rdata); return(count > 0); } @@ -665,8 +674,8 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - /* use the returned uid from now on */ - cli->uid = SVAL(cli->inbuf,smb_uid); + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); return True; } @@ -1690,21 +1699,23 @@ initialise a client structure ****************************************************************************/ BOOL cli_initialise(struct cli_state *cli) { - if (cli->initialised) cli_shutdown(cli); + if (cli->initialised) + cli_shutdown(cli); memset(cli, 0, sizeof(*cli)); cli->fd = -1; cli->cnum = -1; - cli->pid = getpid(); + cli->pid = (uint16)getpid(); cli->mid = 1; - cli->uid = getuid(); + cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; cli->timeout = 20000; cli->bufsize = 0x10000; cli->max_xmit = cli->bufsize - 4; cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); - if (!cli->outbuf || !cli->inbuf) return False; + if (!cli->outbuf || !cli->inbuf) + return False; cli->initialised = 1; return True; } @@ -1714,12 +1725,16 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { - if (cli->outbuf) free(cli->outbuf); - if (cli->inbuf) free(cli->inbuf); + if (cli->outbuf) + free(cli->outbuf); + if (cli->inbuf) + free(cli->inbuf); #ifdef WITH_SSL - if (cli->fd != -1) sslutil_disconnect(cli->fd); + if (cli->fd != -1) + sslutil_disconnect(cli->fd); #endif /* WITH_SSL */ - if (cli->fd != -1) close(cli->fd); + if (cli->fd != -1) + close(cli->fd); memset(cli, 0, sizeof(*cli)); } @@ -1743,9 +1758,9 @@ void cli_sockopt(struct cli_state *cli, char *options) /**************************************************************************** set the PID to use for smb messages. Return the old pid. ****************************************************************************/ -int cli_setpid(struct cli_state *cli, int pid) +uint16 cli_setpid(struct cli_state *cli, uint16 pid) { - int ret = cli->pid; + uint16 ret = cli->pid; cli->pid = pid; return ret; } @@ -1826,14 +1841,16 @@ BOOL cli_establish_connection(struct cli_state *cli, if (!cli_session_request(cli, calling, called)) { DEBUG(1,("failed session request\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } @@ -1852,7 +1869,8 @@ BOOL cli_establish_connection(struct cli_state *cli, cli->domain)) { DEBUG(1,("failed session setup\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } if (do_tcon) @@ -1861,7 +1879,8 @@ BOOL cli_establish_connection(struct cli_state *cli, (char*)passwd, strlen(passwd))) { DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } } @@ -1883,7 +1902,8 @@ BOOL cli_establish_connection(struct cli_state *cli, cli->domain)) { DEBUG(1,("failed session setup\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } @@ -1893,13 +1913,15 @@ BOOL cli_establish_connection(struct cli_state *cli, (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) { DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return False; } } } - if (do_shutdown) cli_shutdown(cli); + if (do_shutdown) + cli_shutdown(cli); return True; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 045008fac9..5a946e22c9 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -121,7 +121,7 @@ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) } /* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(uchar passwd[16], char *c8, uchar p24[24]) +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) { uchar p21[21]; -- cgit From 5a8458c377b6901b67a039eafbd5727ed1207cf3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Sep 1998 01:05:51 +0000 Subject: libsmb/clientgen.c: Fixed signed/unsigned compile warnings spotted by Herb. param/loadparm.c: smbd/oplock.c: Allow kernel oplocks to be turned off in the smb.conf file. smbd/server.c: Move init_structs() to after the smb.conf file is loaded - preparation for making a "max open files" parameter. Jeremy. (This used to be commit 6a261517a09b005f502a37941431308fa8bf2c5c) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d77c58e00a..0892714b39 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1888,8 +1888,8 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt encrypted session */ - char nt_sess_pwd[24]; - char lm_sess_pwd[24]; + unsigned char nt_sess_pwd[24]; + unsigned char lm_sess_pwd[24]; /* creates (storing a copy of) and then obtains a 24 byte password OWF */ pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); -- cgit From 53033c081a07ac4e2f81b8cb4891a281281c6b67 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Oct 1998 01:27:47 +0000 Subject: Fixed *nasty* bug in nt_lm_owf_gen() - this function was not ensuring a zero filled buffer before doing crypto stuff. See PR#10121. Beware of this ! Jeremy. (This used to be commit c42fb702b70f18dfe3b97ce7ea24c4ce4b3f890f) --- source3/libsmb/smbencrypt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 5a946e22c9..89c6eba810 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -101,7 +101,9 @@ void E_md4hash(uchar *passwd, uchar *p16) void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) { char passwd[130]; - StrnCpy(passwd, pwd, sizeof(passwd)-1); + + memset(passwd,'\0',130); + safe_strcpy( passwd, pwd, sizeof(passwd)-1); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); -- cgit From 019c8d2fdda74dc03d9089eacfbd2b77e1056169 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 2 Oct 1998 12:36:18 +0000 Subject: several clientgen mods to support smbwrapper. In particular added cli_list() for directory listing and expended some other functions a bit. (This used to be commit 9bae21abaf3d69a204c6e617f06094303da4da48) --- source3/libsmb/clientgen.c | 275 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 272 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0892714b39..81842d920f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -847,7 +847,6 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) return True; } - /**************************************************************************** create a directory ****************************************************************************/ @@ -1259,7 +1258,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size) + time_t *c_time, time_t *a_time, time_t *m_time, + uint32 *size, int *mode) { int data_len = 0; int param_len = 0; @@ -1305,6 +1305,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, if (size) { *size = IVAL(rdata, 12); } + if (mode) { + *mode = SVAL(rdata,l1_attrFile); + } if (rdata) free(rdata); if (rparam) free(rparam); @@ -1376,7 +1379,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - time_t *c_time, time_t *a_time, time_t *m_time, uint32 *size) + time_t *c_time, time_t *a_time, time_t *m_time, + uint32 *size, int *mode) { int data_len = 0; int param_len = 0; @@ -1422,12 +1426,277 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, if (size) { *size = IVAL(rdata, 12); } + if (mode) { + *mode = SVAL(rdata,l1_attrFile); + } if (rdata) free(rdata); if (rparam) free(rparam); return True; } + +/**************************************************************************** +interpret a long filename structure - this is mostly guesses at the moment +The length of the structure is returned +The structure of a long filename depends on the info level. 260 is used +by NT and 2 is used by OS/2 +****************************************************************************/ +static int interpret_long_filename(int level,char *p,file_info *finfo) +{ + extern file_info def_finfo; + + if (finfo) + memcpy(finfo,&def_finfo,sizeof(*finfo)); + + switch (level) + { + case 1: /* OS/2 understands this */ + if (finfo) { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + pstrcpy(finfo->name,p+27); + } + return(28 + CVAL(p,26)); + + case 2: /* this is what OS/2 uses mostly */ + if (finfo) { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + pstrcpy(finfo->name,p+31); + } + return(32 + CVAL(p,30)); + + /* levels 3 and 4 are untested */ + case 3: + if (finfo) { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2(p+8); + finfo->atime = make_unix_date2(p+12); + finfo->mtime = make_unix_date2(p+16); + finfo->size = IVAL(p,20); + finfo->mode = CVAL(p,28); + pstrcpy(finfo->name,p+33); + } + return(SVAL(p,4)+4); + + case 4: + if (finfo) { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2(p+8); + finfo->atime = make_unix_date2(p+12); + finfo->mtime = make_unix_date2(p+16); + finfo->size = IVAL(p,20); + finfo->mode = CVAL(p,28); + pstrcpy(finfo->name,p+37); + } + return(SVAL(p,4)+4); + + case 260: /* NT uses this, but also accepts 2 */ + if (finfo) { + int ret = SVAL(p,0); + int namelen; + p += 4; /* next entry offset */ + p += 4; /* fileindex */ + + /* these dates appear to arrive in a + weird way. It seems to be localtime + plus the serverzone given in the + initial connect. This is GMT when + DST is not in effect and one hour + from GMT otherwise. Can this really + be right?? + + I suppose this could be called + kludge-GMT. Is is the GMT you get + by using the current DST setting on + a different localtime. It will be + cheap to calculate, I suppose, as + no DST tables will be needed */ + + finfo->ctime = interpret_long_date(p); p += 8; + finfo->atime = interpret_long_date(p); p += 8; + finfo->mtime = interpret_long_date(p); p += 8; p += 8; + finfo->size = IVAL(p,0); p += 8; + p += 8; /* alloc size */ + finfo->mode = CVAL(p,0); p += 4; + namelen = IVAL(p,0); p += 4; + p += 4; /* EA size */ + p += 2; /* short name len? */ + p += 24; /* short name? */ + StrnCpy(finfo->name,p,namelen); + return(ret); + } + return(SVAL(p,0)); + } + + DEBUG(1,("Unknown long filename format %d\n",level)); + return(SVAL(p,0)); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found + ****************************************************************************/ +int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info *)) +{ + int max_matches = 512; + /* NT uses 260, OS/2 uses 2. Both accept 1. */ + int info_level = cli->protocol 200) { + DEBUG(0,("Error: Looping in FIND_NEXT??\n")); + break; + } + + param_len = 12+strlen(mask)+1; + + if (First) { + setup = TRANSACT2_FINDFIRST; + SSVAL(param,0,attribute); /* attribute */ + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,8+4+2); /* resume required + close on end + continue */ + SSVAL(param,6,info_level); + SIVAL(param,8,0); + pstrcpy(param+12,mask); + } else { + setup = TRANSACT2_FINDNEXT; + SSVAL(param,0,ff_dir_handle); + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,info_level); + SIVAL(param,6,ff_resume_key); /* ff_resume_key */ + SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ + pstrcpy(param+12,mask); + + DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n", + ff_dir_handle,ff_resume_key,ff_lastname,mask)); + } + + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, 0, + cli->max_xmit /* data, length, max */ + )) { + return -1; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return -1; + } + + /* parse out some important return info */ + p = rparam; + if (First) { + ff_dir_handle = SVAL(p,0); + ff_searchcount = SVAL(p,2); + ff_eos = SVAL(p,4); + ff_lastname = SVAL(p,8); + } else { + ff_searchcount = SVAL(p,0); + ff_eos = SVAL(p,2); + ff_lastname = SVAL(p,6); + } + + if (ff_searchcount == 0) + break; + + /* point to the data bytes */ + p = rdata; + + /* we might need the lastname for continuations */ + if (ff_lastname > 0) { + switch(info_level) + { + case 260: + ff_resume_key =0; + StrnCpy(mask,p+ff_lastname, + data_len-ff_lastname); + break; + case 1: + pstrcpy(mask,p + ff_lastname + 1); + ff_resume_key = 0; + break; + } + } else { + pstrcpy(mask,""); + } + + /* and add them to the dirlist pool */ + dirlist = Realloc(dirlist,dirlist_len + data_len); + + if (!dirlist) { + DEBUG(0,("Failed to expand dirlist\n")); + break; + } + + /* put in a length for the last entry, to ensure we can chain entries + into the next packet */ + for (p2=p,i=0;i<(ff_searchcount-1);i++) + p2 += interpret_long_filename(info_level,p2,NULL); + SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); + + /* grab the data for later use */ + memcpy(dirlist+dirlist_len,p,data_len); + dirlist_len += data_len; + + total_received += ff_searchcount; + + if (rdata) free(rdata); rdata = NULL; + if (rparam) free(rparam); rparam = NULL; + + DEBUG(3,("received %d entries (eos=%d resume=%d)\n", + ff_searchcount,ff_eos,ff_resume_key)); + + First = False; + } + + for (p=dirlist,i=0;i Date: Fri, 2 Oct 1998 18:45:07 +0000 Subject: - static function "create_new_hashes" was identical to "nt_lm_owf_gen". create_new_hashes didn't zero the buffer for the md4hash: nt_lm_owf_gen did, because jeremy sorted this out a couple of days ago. call nt_lm_owf_gen instead. - call SMBOWFencrypt from SMBencrypt and SMBNTencrypt. - added #ifdef DEBUG_PASSWORD debug password calls. (This used to be commit a4e7cc3e46b713aa0ae55de74a1c70921bef578d) --- source3/libsmb/smbencrypt.c | 46 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 89c6eba810..bf9736d724 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -32,15 +32,23 @@ extern int DEBUGLEVEL; encrypted password into p24 */ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) { - uchar p14[15], p21[21]; + uchar p14[15], p21[21]; - memset(p21,'\0',21); - memset(p14,'\0',14); - StrnCpy((char *)p14,(char *)passwd,14); + memset(p21,'\0',21); + memset(p14,'\0',14); + StrnCpy((char *)p14,(char *)passwd,14); + + strupper((char *)p14); + E_P16(p14, p21); + + SMBOWFencrypt(p21, c8, p24); - strupper((char *)p14); - E_P16(p14, p21); - E_P24(p21, c8, p24); +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); +#endif } /* Routines for Windows NT MD4 Hash functions. */ @@ -102,13 +110,19 @@ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) { char passwd[130]; - memset(passwd,'\0',130); - safe_strcpy( passwd, pwd, sizeof(passwd)-1); + memset(passwd,'\0',130); + safe_strcpy( passwd, pwd, sizeof(passwd)-1); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); E_md4hash((uchar *)passwd, nt_p16); +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); + dump_data(120, passwd, strlen(passwd)); + dump_data(100, nt_p16, 16); +#endif + /* Mangle the passwords into Lanman format */ passwd[14] = '\0'; strupper(passwd); @@ -118,6 +132,11 @@ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) memset(p16, '\0', 16); E_P16((uchar *) passwd, (uchar *)p16); +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); + dump_data(120, passwd, strlen(passwd)); + dump_data(100, p16, 16); +#endif /* clear out local copy of user's password (just being paranoid). */ bzero(passwd, sizeof(passwd)); } @@ -143,7 +162,14 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) memset(p21,'\0',21); E_md4hash(passwd, p21); - E_P24(p21, c8, p24); + SMBOWFencrypt(p21, c8, p24); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); +#endif } -- cgit From 732d4ff7dacce985fb209ee99569cef907e2cbf4 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 2 Oct 1998 21:09:23 +0000 Subject: Makefile.in : - added srvsvc client files clientgen.c : - replaced cli_error(cli, int *cls, int *err) with cli_error(cli, uint8 cls, uint32 *err). this version detects 32 bit status messages. the DOS error "MORE_DATA", the equivalent of the 32 bit *warning* 0x8000 0005 (STATUS_BUFFER_OVERFLOW), was being processed as an error, terminating the cli_receive_trans() call. cli_pipe.c : - replaced calls that had been incorrectly modified from 32 bit warnings (0x8000 0005 - STATUS_BUFFER_OVERFLOW) to 8 bit DOS errors (0x01 0xEA - MORE_DATA). the use of the old version of cli_error (DOS only) instead of the new one (DOS and 32 bit) caused the dce/rpc client code to fail. - replaced 2 space indentation with tab indentation in all functions. cli_srvsvc.c : cmd_srvsvc.c : - added these files back in, fixing them up to use jeremy's modified versions of the dce/rpc client functions. parse_srv.c : - added back in some "unused" functions required by dce/rpc client-side code. it would be helpful if all such "unused" functions could be added back in. rpcclient.c : - added "session", "file", "share", "connection" enumeration functions back in. these are equivalent to nt's "NetXXXXXEnum" Win32 (MSDN) functions. - added "srvinfo" function back in. this is equivalent to nt's NetServerGetInfo Win32 (MSDN) function. (This used to be commit bcf39ffdcc64e049bca2d70a394a99976291e81d) --- source3/libsmb/clientgen.c | 162 +++++++++++++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 58 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 81842d920f..4c1690f6f2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -63,51 +63,61 @@ static char *cli_smb_errstr(struct cli_state *cli) char *cli_errstr(struct cli_state *cli) { - static fstring error_message; - int errclass; - int errnum; - int i; - - /* - * Errors are of three kinds - smb errors, - * dealt with by cli_smb_errstr, NT errors, - * whose code is in cli.nt_error, and rap - * errors, whose error code is in cli.rap_error. - */ + static fstring error_message; + uint8 errclass; + uint32 errnum; + int i; - cli_error(cli, &errclass, &errnum); - if(errclass != 0) - return cli_smb_errstr(cli); + /* + * Errors are of three kinds - smb errors, + * dealt with by cli_smb_errstr, NT errors, + * whose code is in cli.nt_error, and rap + * errors, whose error code is in cli.rap_error. + */ - /* - * Was it an NT error ? - */ + cli_error(cli, &errclass, &errnum); - if(cli->nt_error) { - char *nt_msg = get_nt_error_msg(cli->nt_error); + if (errclass != 0) + { + return cli_smb_errstr(cli); + } - if(nt_msg == NULL) - slprintf(error_message, sizeof(fstring) - 1, "NT code %d", cli->nt_error); - else - fstrcpy(error_message, nt_msg); + /* + * Was it an NT error ? + */ - return error_message; - } + if (cli->nt_error) + { + char *nt_msg = get_nt_error_msg(cli->nt_error); - /* - * Must have been a rap error. - */ + if (nt_msg == NULL) + { + slprintf(error_message, sizeof(fstring) - 1, "NT code %d", cli->nt_error); + } + else + { + fstrcpy(error_message, nt_msg); + } - slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); - - for(i = 0; rap_errmap[i].message != NULL; i++) { - if (rap_errmap[i].err == cli->rap_error) { - fstrcpy( error_message, rap_errmap[i].message); - break; - } - } - - return error_message; + return error_message; + } + + /* + * Must have been a rap error. + */ + + slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); + + for (i = 0; rap_errmap[i].message != NULL; i++) + { + if (rap_errmap[i].err == cli->rap_error) + { + fstrcpy( error_message, rap_errmap[i].message); + break; + } + } + + return error_message; } /**************************************************************************** @@ -262,8 +272,11 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - if (CVAL(cli->inbuf,smb_rcls) != 0) + + if (cli_error(cli, NULL, NULL)) + { return(False); + } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -313,8 +326,10 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - if (CVAL(cli->inbuf,smb_rcls) != 0) + if (cli_error(cli, NULL, NULL)) + { return(False); + } } return(True); @@ -330,7 +345,7 @@ BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, char **rparam, uint32 *rparam_count, char **rdata, uint32 *rdata_count) { - if(pipe_name_len == 0) + if (pipe_name_len == 0) pipe_name_len = strlen(pipe_name); cli_send_trans(cli, SMBtrans, @@ -602,7 +617,7 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - if(((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { + if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { /* Null session connect. */ pword[0] = '\0'; } else { @@ -620,7 +635,8 @@ BOOL cli_session_setup(struct cli_state *cli, /* send a session setup command */ bzero(cli->outbuf,smb_size); - if (cli->protocol < PROTOCOL_NT1) { + if (cli->protocol < PROTOCOL_NT1) + { set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -636,7 +652,9 @@ BOOL cli_session_setup(struct cli_state *cli, p += passlen; pstrcpy(p,user); strupper(p); - } else { + } + else + { set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -648,11 +666,15 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); + SSVAL(cli->outbuf,smb_vwv11,CAP_STATUS32); p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpass,ntpasslen); - p += SVAL(cli->outbuf,smb_vwv8); + if (ntpasslen != 0) + { + memcpy(p,ntpass,ntpasslen); + p += SVAL(cli->outbuf,smb_vwv8); + } pstrcpy(p,user); strupper(p); p = skip_string(p,1); @@ -1718,12 +1740,12 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo char *rdata = NULL; int rprcnt, rdrcnt; - if(strlen(user) >= sizeof(fstring)-1) { + if (strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); return False; } - if(new_pw_len > 512) { + if (new_pw_len > 512) { DEBUG(0,("cli_oem_change_password: new password for user %s is too long.\n", user)); return False; } @@ -1775,7 +1797,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo data_len = 532; - if(cli_send_trans(cli,SMBtrans, + if (cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ @@ -1787,10 +1809,10 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo return False; } - if(cli_receive_trans(cli,SMBtrans, + if (cli_receive_trans(cli,SMBtrans, &rparam, &rprcnt, &rdata, &rdrcnt)) { - if(rparam) + if (rparam) cli->rap_error = SVAL(rparam,0); } @@ -1919,9 +1941,9 @@ retry: return False; #ifdef WITH_SSL - if(CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ - if(!sslutil_fd_is_ssl(cli->fd)){ - if(sslutil_connect(cli->fd) == 0) + if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ + if (!sslutil_fd_is_ssl(cli->fd)){ + if (sslutil_connect(cli->fd) == 0) goto retry; } } @@ -1947,7 +1969,7 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) fstrcpy(cli->desthost, host); if (!ip || ip_equal(*ip, ipzero)) { - if(!resolve_name( cli->desthost, &dest_ip)) { + if (!resolve_name( cli->desthost, &dest_ip)) { return False; } } else { @@ -2007,13 +2029,37 @@ void cli_shutdown(struct cli_state *cli) memset(cli, 0, sizeof(*cli)); } + /**************************************************************************** return error codes for the last packet ****************************************************************************/ -void cli_error(struct cli_state *cli, int *eclass, int *num) +BOOL cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { - *eclass = CVAL(cli->inbuf,smb_rcls); - *num = SVAL(cli->inbuf,smb_err); + int flgs2 = SVAL(cli->inbuf,smb_flg2); + + if (eclass) *eclass = 0; + if (num ) *num = 0; + + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + { + /* 32 bit error codes detected */ + uint32 nt_err = IVAL(cli->inbuf,smb_rcls); + if (num) *num = nt_err; + DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); + return (IS_BITS_SET_ALL(nt_err, 0xc0000000)); + } + else + { + /* dos 16 bit error codes detected */ + char rcls = CVAL(cli->inbuf,smb_rcls); + if (rcls != 0) + { + if (eclass) *eclass = rcls; + if (num ) *num = SVAL(cli->inbuf,smb_err); + return True; + } + } + return False; } /**************************************************************************** -- cgit From 27e5850fd3e1c8885e54bc901cb9d79ae695466c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 08:33:07 +0000 Subject: - ignore *.p files - enable cli_RNetSharEnum - fix password handling in sesssetup for NT1 protocol - handle partial reads and writes in cli_{read,write} - added cli_getattrE - modify cli_qpathinfo() to swap byte order for win95 servers - handle temporary errors from FINDFIRST/FINDNEXT from win95 servers, when we get a error we sleep for a bit and retry - return approx unix errno from cli_error(). Need to add a lot more cases to this. (This used to be commit 715a6631c714bbd6a965e45fba1e0d0b37a27df6) --- source3/libsmb/.cvsignore | 1 + source3/libsmb/clientgen.c | 308 ++++++++++++++++++++++++++++++++------------- 2 files changed, 222 insertions(+), 87 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/.cvsignore b/source3/libsmb/.cvsignore index e69de29bb2..f20330ba4d 100644 --- a/source3/libsmb/.cvsignore +++ b/source3/libsmb/.cvsignore @@ -0,0 +1 @@ +*.p diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4c1690f6f2..7be2717bed 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -445,7 +445,6 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) return (cli->rap_error == 0); } -#if UNUSED_CODE /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ @@ -501,9 +500,9 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *) if (rdata) free(rdata); - return(count>0); + return count; } -#endif + /**************************************************************************** call a NetServerEnum for the specified workgroup and servertype mask. @@ -608,29 +607,38 @@ BOOL cli_session_setup(struct cli_state *cli, char *workgroup) { char *p; - fstring pword; + fstring pword, ntpword; if (cli->protocol < PROTOCOL_LANMAN1) return True; - if (passlen > sizeof(pword)-1) { + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { return False; } if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { /* Null session connect. */ pword[0] = '\0'; + ntpword[0] = '\0'; } else { if ((cli->sec_mode & 2) && passlen != 24) { passlen = 24; + ntpasslen = 24; SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + SMBNTencrypt((uchar *)ntpass,(uchar *)cli->cryptkey,(uchar *)ntpword); } else { memcpy(pword, pass, passlen); + memcpy(ntpword, ntpass, ntpasslen); } } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} + if (!(cli->sec_mode & 1)) { + fstrcpy(pword, ""); + passlen=1; + fstrcpy(ntpword, ""); + ntpasslen=1; + } /* send a session setup command */ bzero(cli->outbuf,smb_size); @@ -670,11 +678,8 @@ BOOL cli_session_setup(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); - if (ntpasslen != 0) - { - memcpy(p,ntpass,ntpasslen); - p += SVAL(cli->outbuf,smb_vwv8); - } + memcpy(p,ntpword,ntpasslen); + p += SVAL(cli->outbuf,smb_vwv8); pstrcpy(p,user); strupper(p); p = skip_string(p,1); @@ -773,6 +778,12 @@ BOOL cli_send_tconX(struct cli_state *cli, return False; } + if (cli->protocol >= PROTOCOL_NT1 && + smb_buflen(cli->inbuf) == 3) { + /* almost certainly win95 - enable bug fixes */ + cli->win95 = True; + } + cli->cnum = SVAL(cli->inbuf,smb_tid); return True; } @@ -1119,37 +1130,51 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) { char *p; + int total=0; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + while (total < size) { + int size1 = MIN(size-total, cli->max_xmit - (smb_size+32)); + int size2; - set_message(cli->outbuf,10,0,True); + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); - CVAL(cli->outbuf,smb_com) = SMBreadX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - SSVAL(cli->outbuf,smb_vwv5,size); - SSVAL(cli->outbuf,smb_vwv6,size); + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset+total); + SSVAL(cli->outbuf,smb_vwv5,size1); + SSVAL(cli->outbuf,smb_vwv6,size1); + + send_smb(cli->fd,cli->outbuf); + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return total?total:-1; + } - send_smb(cli->fd,cli->outbuf); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { - return -1; - } + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return total?total:-1; + } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } + size2 = SVAL(cli->inbuf, smb_vwv5); + if (size2 > size1) { + DEBUG(0,("server returned more than we wanted!\n")); + exit(1); + } + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + + if (size2 <= 0) break; - size = SVAL(cli->inbuf, smb_vwv5); - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf+total, p, size2); - memcpy(buf, p, size); + total += size2; + } - return size; + return total; } @@ -1159,36 +1184,100 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) { char *p; + int total=0; + while (total < size) { + int size1 = MIN(size-total, cli->max_xmit - (smb_size+32)); + int size2; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,12,size1,True); + + CVAL(cli->outbuf,smb_com) = SMBwriteX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset+total); + + SSVAL(cli->outbuf,smb_vwv10,size1); + SSVAL(cli->outbuf,smb_vwv11, + smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + memcpy(p, buf+total, size1); + + send_smb(cli->fd,cli->outbuf); + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + size2 = SVAL(cli->inbuf, smb_vwv2); + + if (size2 <= 0) break; + + total += size2; + } + + return total; +} + + +/**************************************************************************** +do a SMBgetattrE call +****************************************************************************/ +BOOL cli_getattrE(struct cli_state *cli, int fd, + int *attr, uint32 *size, + time_t *c_time, time_t *a_time, time_t *m_time) +{ bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); - set_message(cli->outbuf,12,size,True); + set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBwriteX; + CVAL(cli->outbuf,smb_com) = SMBgetattrE; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - - SSVAL(cli->outbuf,smb_vwv10,size); - SSVAL(cli->outbuf,smb_vwv11,smb_buf(cli->outbuf) - smb_base(cli->outbuf)); - - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); - memcpy(p, buf, size); + SSVAL(cli->outbuf,smb_vwv0,fd); send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { - return -1; + return False; } - + if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; + return False; + } + + if (size) { + *size = IVAL(cli->inbuf, smb_vwv6); + } + + if (attr) { + *attr = SVAL(cli->inbuf,smb_vwv10); + } + + if (c_time) { + *c_time = make_unix_date3(cli->inbuf+smb_vwv0); } - return SVAL(cli->inbuf, smb_vwv2); + if (a_time) { + *a_time = make_unix_date3(cli->inbuf+smb_vwv2); + } + + if (m_time) { + *m_time = make_unix_date3(cli->inbuf+smb_vwv4); + } + + return True; } @@ -1196,7 +1285,7 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 do a SMBgetatr call ****************************************************************************/ BOOL cli_getatr(struct cli_state *cli, char *fname, - int *attr, uint32 *size, time_t *t) + uint32 *attr, size_t *size, time_t *t) { char *p; @@ -1281,13 +1370,16 @@ send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - uint32 *size, int *mode) + size_t *size, uint32 *mode) { int data_len = 0; int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; + int count=8; + BOOL ret; + time_t (*date_fn)(void *); param_len = strlen(fname) + 7; @@ -1295,34 +1387,46 @@ BOOL cli_qpathinfo(struct cli_state *cli, char *fname, SSVAL(param, 0, SMB_INFO_STANDARD); pstrcpy(¶m[6], fname); - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } + do { + ret = (cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + ) && + cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)); + if (!ret) { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error(cli, &eclass, &ecode); + if (eclass != ERRSRV || ecode != ERRerror) break; + msleep(100); + } + } while (count-- && ret==False); - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { + if (!ret || !rdata || data_len < 22) { return False; } - if (!rdata || data_len < 22) { - return False; + if (cli->win95) { + date_fn = make_unix_date; + } else { + date_fn = make_unix_date2; } if (c_time) { - *c_time = make_unix_date2(rdata+0); + *c_time = date_fn(rdata+0); } if (a_time) { - *a_time = make_unix_date2(rdata+4); + *a_time = date_fn(rdata+4); } if (m_time) { - *m_time = make_unix_date2(rdata+8); + *m_time = date_fn(rdata+8); } if (size) { *size = IVAL(rdata, 12); @@ -1579,7 +1683,7 @@ int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info int i; char *dirlist = NULL; int dirlist_len = 0; - int total_received = 0; + int total_received = -1; BOOL First = True; int ff_resume_key = 0; int ff_searchcount=0; @@ -1633,15 +1737,24 @@ int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info NULL, 0, cli->max_xmit /* data, length, max */ )) { - return -1; + break; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { - return -1; + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error(cli, &eclass, &ecode); + if (eclass != ERRSRV || ecode != ERRerror) break; + msleep(100); + continue; } + if (total_received == -1) total_received = 0; + /* parse out some important return info */ p = rparam; if (First) { @@ -1880,9 +1993,11 @@ BOOL cli_negprot(struct cli_state *cli) /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - if (IVAL(cli->inbuf,smb_vwv9+1) & 1) - cli->readbraw_supported = - cli->writebraw_supported = True; + cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); + if (cli->capabilities & 1) { + cli->readbraw_supported = True; + cli->writebraw_supported = True; + } } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); @@ -2032,34 +2147,53 @@ void cli_shutdown(struct cli_state *cli) /**************************************************************************** return error codes for the last packet + returns 0 if there was no error and the bext approx of a unix errno + otherwise ****************************************************************************/ -BOOL cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { int flgs2 = SVAL(cli->inbuf,smb_flg2); + char rcls; + int code; if (eclass) *eclass = 0; if (num ) *num = 0; - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) - { + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { /* 32 bit error codes detected */ uint32 nt_err = IVAL(cli->inbuf,smb_rcls); if (num) *num = nt_err; DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); - return (IS_BITS_SET_ALL(nt_err, 0xc0000000)); + if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; + + switch (nt_err & 0xFFFFFF) { + case NT_STATUS_ACCESS_VIOLATION: return EPERM; + } + + /* for all other cases - a default code */ + return EINVAL; } - else - { - /* dos 16 bit error codes detected */ - char rcls = CVAL(cli->inbuf,smb_rcls); - if (rcls != 0) - { - if (eclass) *eclass = rcls; - if (num ) *num = SVAL(cli->inbuf,smb_err); - return True; + + rcls = CVAL(cli->inbuf,smb_rcls); + code = SVAL(cli->inbuf,smb_err); + if (rcls == 0) return 0; + + if (eclass) *eclass = rcls; + if (num ) *num = code; + + if (rcls == ERRDOS) { + switch (code) { + case ERRbadfile: return ENOENT; + case ERRnoaccess: return EPERM; + } + } + if (rcls == ERRSRV) { + switch (code) { + case ERRbadpw: return EPERM; } } - return False; + /* for other cases */ + return EINVAL; } /**************************************************************************** -- cgit From cce5f09a90b5027bafd22f42edab9c256789bce1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 09:39:11 +0000 Subject: added unlink() and rename() support to smbwrapper (This used to be commit b85d96144728e8a29c7c1114462e28bf3b144b80) --- source3/libsmb/clientgen.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7be2717bed..d2a7749490 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -448,7 +448,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(char *, uint32, char *)) +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, char *)) { char *rparam = NULL; char *rdata = NULL; @@ -807,11 +807,10 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } -#if UNUSED_CODE /**************************************************************************** rename a file ****************************************************************************/ -BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) +BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) { char *p; @@ -844,7 +843,6 @@ BOOL cli_mv(struct cli_state *cli, char *fname_src, char *fname_dst) return True; } -#endif /**************************************************************************** delete a file @@ -2167,7 +2165,13 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; switch (nt_err & 0xFFFFFF) { - case NT_STATUS_ACCESS_VIOLATION: return EPERM; + case NT_STATUS_ACCESS_VIOLATION: return EACCES; + case NT_STATUS_NO_SUCH_FILE: return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; + case NT_STATUS_INVALID_HANDLE: return EBADF; + case NT_STATUS_NO_MEMORY: return ENOMEM; + case NT_STATUS_ACCESS_DENIED: return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; } /* for all other cases - a default code */ -- cgit From 4fedb9ddd5440c546145e8c9950ef938c52bdfe0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 11:53:37 +0000 Subject: - always open for reading (otherwise getattrE won't work). - added somemore NT error codes (This used to be commit a0632529133fdaff9d70ac3e0cf6bb021c79438e) --- source3/libsmb/clientgen.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d2a7749490..0a61a74cce 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -953,6 +953,12 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) unsigned openfn=0; unsigned accessmode=0; + /* you must open for RW not just write - otherwise getattrE doesn't + work! */ + if ((flags & O_ACCMODE) == O_WRONLY) { + flags = (flags & ~O_ACCMODE) | O_RDWR; + } + if (flags & O_CREAT) openfn |= (1<<4); if (!(flags & O_EXCL)) { @@ -964,9 +970,9 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) accessmode = (share_mode<<4); - if ((flags & O_RDWR) == O_RDWR) { + if ((flags & O_ACCMODE) == O_RDWR) { accessmode |= 2; - } else if ((flags & O_WRONLY) == O_WRONLY) { + } else if ((flags & O_ACCMODE) == O_WRONLY) { accessmode |= 1; } @@ -1503,8 +1509,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - time_t *c_time, time_t *a_time, time_t *m_time, - uint32 *size, int *mode) + uint32 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time) { int data_len = 0; int param_len = 0; @@ -2172,6 +2178,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case NT_STATUS_NO_MEMORY: return ENOMEM; case NT_STATUS_ACCESS_DENIED: return EACCES; case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; + case NT_STATUS_SHARING_VIOLATION: return EBUSY; } /* for all other cases - a default code */ -- cgit From 03a06267f4674201c107b85abf993688312c5093 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 13:12:08 +0000 Subject: added simple device/inode number support based on a checksum of the filename (This used to be commit 5674fb4e9dc4d92213d763c8cecd26efc23a9720) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0a61a74cce..bd044f4e26 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -448,7 +448,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, char *)) +BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) { char *rparam = NULL; char *rdata = NULL; -- cgit From f2d8f110db994588cb85a9c0c22c0941f4ccca38 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 15:01:11 +0000 Subject: fixed vi on smbwrappper (it was a problem in cli_read()) (This used to be commit 1dcc84b942d4669f978aebdeaf85ea609c2b732f) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bd044f4e26..6132114ac6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1131,7 +1131,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int /**************************************************************************** read from a file ****************************************************************************/ -int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { char *p; int total=0; @@ -1185,7 +1185,7 @@ int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 s /**************************************************************************** write to a file ****************************************************************************/ -int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { char *p; int total=0; -- cgit From 8d4c7326212f23d2a255def7f7e9c992eb752911 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Oct 1998 15:55:18 +0000 Subject: fixed a authentication problem with non-encrypting servers (This used to be commit 06f1af12c37fc759e7315366dd4e82f4e96b042d) --- source3/libsmb/clientgen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6132114ac6..dc60b6951c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -627,8 +627,9 @@ BOOL cli_session_setup(struct cli_state *cli, SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); SMBNTencrypt((uchar *)ntpass,(uchar *)cli->cryptkey,(uchar *)ntpword); } else { - memcpy(pword, pass, passlen); - memcpy(ntpword, ntpass, ntpasslen); + fstrcpy(pword, pass); + fstrcpy(ntpword, ""); + ntpasslen = 0; } } -- cgit From a1e10cfc3cb8416224bbc63fba83e4f50ce75a06 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 03:27:04 +0000 Subject: use const char (This used to be commit 83b7bfa821b88f0826b348ec493141a324e12a86) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index dc60b6951c..1d2ea199c0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -259,7 +259,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, int this_data,this_param; *data_len = *param_len = 0; - + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -1373,7 +1373,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) /**************************************************************************** send a qpathinfo call ****************************************************************************/ -BOOL cli_qpathinfo(struct cli_state *cli, char *fname, +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint32 *mode) { -- cgit From 5ade894f32377ffaed3fc085810892509a6e8c66 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 06:22:08 +0000 Subject: modified cli_read() and cli_write() to issue multiple outstanding read/write requests for large reads. up to max_mux requests may be outstanding. This gives _much_ better throughput and should allow smbsh to saturate just about any network. this is an implementation of the "fast SMB" method I described on the CIFS list a couple of months back. (This used to be commit c728d1c5d6e4626d2f8e318eab4df32acc8cb505) --- source3/libsmb/clientgen.c | 188 ++++++++++++++++++++++++++++++++------------- 1 file changed, 133 insertions(+), 55 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1d2ea199c0..cd6d295094 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1129,108 +1129,185 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int } + +/**************************************************************************** +issue a single SMBread and don't wait for a reply +****************************************************************************/ +static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, + size_t size, int i) +{ + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + SSVAL(cli->outbuf,smb_vwv5,size); + SSVAL(cli->outbuf,smb_vwv6,size); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + send_smb(cli->fd,cli->outbuf); +} + /**************************************************************************** read from a file ****************************************************************************/ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { char *p; - int total=0; - - while (total < size) { - int size1 = MIN(size-total, cli->max_xmit - (smb_size+32)); + int total = -1; + int issued=0; + int received=0; + int mpx = MAX(cli->max_mux-1, 1); + int block = (cli->max_xmit - (smb_size+32)) & ~1023; + int mid; + int blocks = (size + (block-1)) / block; + + while (received < blocks) { int size2; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); - - set_message(cli->outbuf,10,0,True); - - CVAL(cli->outbuf,smb_com) = SMBreadX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset+total); - SSVAL(cli->outbuf,smb_vwv5,size1); - SSVAL(cli->outbuf,smb_vwv6,size1); + while (issued - received < mpx && issued < blocks) { + int size1 = MIN(block, size-issued*block); + cli_issue_read(cli, fnum, offset+issued*block, size1, issued); + issued++; + } - send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { - return total?total:-1; + return total; } + received++; + mid = SVAL(cli->inbuf, smb_mid) - cli->mid; + size2 = SVAL(cli->inbuf, smb_vwv5); + if (CVAL(cli->inbuf,smb_rcls) != 0) { - return total?total:-1; + blocks = MIN(blocks, mid-1); + continue; } - size2 = SVAL(cli->inbuf, smb_vwv5); - if (size2 > size1) { + if (size2 <= 0) { + blocks = MIN(blocks, mid-1); + /* this distinguishes EOF from an error */ + total = MAX(total, 0); + continue; + } + + if (size2 > block) { DEBUG(0,("server returned more than we wanted!\n")); exit(1); } + if (mid >= issued) { + DEBUG(0,("invalid mid from server!\n")); + exit(1); + } p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - if (size2 <= 0) break; + memcpy(buf+mid*block, p, size2); - memcpy(buf+total, p, size2); - - total += size2; + total = MAX(total, mid*block + size2); } + while (received < issued) { + client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + received++; + } + return total; } /**************************************************************************** - write to a file +issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char *buf, + size_t size, int i) { char *p; - int total=0; - - while (total < size) { - int size1 = MIN(size-total, cli->max_xmit - (smb_size+32)); - int size2; - - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); - set_message(cli->outbuf,12,size1,True); + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); - CVAL(cli->outbuf,smb_com) = SMBwriteX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + set_message(cli->outbuf,12,size,True); + + CVAL(cli->outbuf,smb_com) = SMBwriteX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + + SSVAL(cli->outbuf,smb_vwv10,size); + SSVAL(cli->outbuf,smb_vwv11, + smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + memcpy(p, buf, size); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset+total); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + send_smb(cli->fd,cli->outbuf); +} - SSVAL(cli->outbuf,smb_vwv10,size1); - SSVAL(cli->outbuf,smb_vwv11, - smb_buf(cli->outbuf) - smb_base(cli->outbuf)); +/**************************************************************************** + write to a file +****************************************************************************/ +size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +{ + int total = -1; + int issued=0; + int received=0; + int mpx = MAX(cli->max_mux-1, 1); + int block = (cli->max_xmit - (smb_size+32)) & ~1023; + int mid; + int blocks = (size + (block-1)) / block; + + while (received < blocks) { + int size2; - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); - memcpy(p, buf+total, size1); + while (issued - received < mpx && issued < blocks) { + int size1 = MIN(block, size-issued*block); + cli_issue_write(cli, fnum, offset+issued*block, buf + issued*block, + size1, issued); + issued++; + } - send_smb(cli->fd,cli->outbuf); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { - return -1; + return total; } + received++; + mid = SVAL(cli->inbuf, smb_mid) - cli->mid; + size2 = SVAL(cli->inbuf, smb_vwv2); + if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; + blocks = MIN(blocks, mid-1); + continue; } - size2 = SVAL(cli->inbuf, smb_vwv2); - - if (size2 <= 0) break; + if (size2 <= 0) { + blocks = MIN(blocks, mid-1); + /* this distinguishes EOF from an error */ + total = MAX(total, 0); + continue; + } total += size2; + + total = MAX(total, mid*block + size2); } + while (received < issued) { + client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + received++; + } + return total; } @@ -1992,6 +2069,7 @@ BOOL cli_negprot(struct cli_state *cli) if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); + cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; -- cgit From f3db9286f98a8d5ab2310fca73e89f0f2732704e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 06:43:41 +0000 Subject: fix an error code in cli_error() (This used to be commit bbc891727e57172bf6200e10c32498776a77510b) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cd6d295094..4ce86eeb2c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2274,7 +2274,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) if (rcls == ERRDOS) { switch (code) { case ERRbadfile: return ENOENT; - case ERRnoaccess: return EPERM; + case ERRnoaccess: return EACCES; } } if (rcls == ERRSRV) { -- cgit From 52e5dbeb9c4a59bf47d75e5b693146951e16ba44 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 07:51:34 +0000 Subject: use CLI_BUFFER_SIZE instead of BUFFER_SIZE (This used to be commit 98f9bb94fcdd0195158eba0deaebe4679baea44c) --- source3/libsmb/clientgen.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4ce86eeb2c..e871bd7d9d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -415,14 +415,14 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) pstrcpy(p, workstation); strupper(p); p += 16; - SSVAL(p, 0, BUFFER_SIZE); + SSVAL(p, 0, CLI_BUFFER_SIZE); p += 2; - SSVAL(p, 0, BUFFER_SIZE); + SSVAL(p, 0, CLI_BUFFER_SIZE); p += 2; if (cli_api(cli, param, PTR_DIFF(p,param),1024, /* param, length, max */ - NULL, 0, BUFFER_SIZE, /* data, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { @@ -466,12 +466,12 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); - SSVAL(p,2,BUFFER_SIZE); + SSVAL(p,2,CLI_BUFFER_SIZE); p += 4; if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, BUFFER_SIZE, /* data, length, maxlen */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { @@ -533,7 +533,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = skip_string(p,1); SSVAL(p,0,uLevel); - SSVAL(p,2,BUFFER_SIZE); + SSVAL(p,2,CLI_BUFFER_SIZE); p += 4; SIVAL(p,0,stype); p += 4; @@ -543,7 +543,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ - NULL, 0, BUFFER_SIZE, /* data, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { @@ -669,7 +669,7 @@ BOOL cli_session_setup(struct cli_state *cli, cli_setup_packet(cli); CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); @@ -2097,6 +2097,8 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone = TimeDiff(time(NULL)); } + cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); + return True; } @@ -2199,8 +2201,8 @@ BOOL cli_initialise(struct cli_state *cli) cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; cli->timeout = 20000; - cli->bufsize = 0x10000; - cli->max_xmit = cli->bufsize - 4; + cli->bufsize = CLI_BUFFER_SIZE+4; + cli->max_xmit = cli->bufsize; cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); if (!cli->outbuf || !cli->inbuf) -- cgit From 6760e69a68571e01ee57b959193a56278962a23c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 09:42:51 +0000 Subject: added support for printing via smbwrapper You can print using "cp filename /smb/SERVER/PRINTER/jobname" You can list the current printqueue using ls (This used to be commit 080fb61b69620e26e8122705383dc2bd0468a519) --- source3/libsmb/clientgen.c | 100 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e871bd7d9d..0e01370f5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -137,6 +137,29 @@ static void cli_setup_packet(struct cli_state *cli) } +/***************************************************************************** + Convert a character pointer in a cli_call_api() response to a form we can use. + This function contains code to prevent core dumps if the server returns + invalid data. +*****************************************************************************/ +static char *fix_char_ptr(unsigned int datap, unsigned int converter, + char *rdata, int rdrcnt) +{ + if (datap == 0) { /* turn NULL pointers into zero length strings */ + return ""; + } else { + unsigned int offset = datap - converter; + + if (offset >= rdrcnt) { + DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", + datap, converter, rdrcnt)); + return ""; + } else { + return &rdata[offset]; + } + } +} + /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ @@ -739,6 +762,8 @@ BOOL cli_send_tconX(struct cli_state *cli, bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); + fstrcpy(cli->share, share); + if (cli->sec_mode & 1) { passlen = 1; pass = ""; @@ -779,6 +804,8 @@ BOOL cli_send_tconX(struct cli_state *cli, return False; } + fstrcpy(cli->dev, smb_buf(cli->inbuf)); + if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ @@ -2466,3 +2493,76 @@ BOOL cli_establish_connection(struct cli_state *cli, return True; } + + + +/**************************************************************************** +call fn() on each entry in a print queue +****************************************************************************/ +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt, rprcnt; + pstring param; + int result_code=0; + int i = -1; + + bzero(param,sizeof(param)); + + p = param; + SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ + p += 2; + pstrcpy(p,"zWrLeh"); /* parameter description? */ + p = skip_string(p,1); + pstrcpy(p,"WWzWWDDzz"); /* returned data format */ + p = skip_string(p,1); + pstrcpy(p,cli->share); /* name of queue */ + p = skip_string(p,1); + SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ + SSVAL(p,2,1000); /* size of bytes of returned data buffer */ + p += 4; + pstrcpy(p,""); /* subformat */ + p = skip_string(p,1); + + DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) { /* return data, length */ + int converter; + result_code = SVAL(rparam,0); + converter = SVAL(rparam,2); /* conversion factor */ + + if (result_code == 0) { + struct print_job_info job; + + p = rdata; + + for (i = 0; i < SVAL(rparam,4); ++i) { + job.id = SVAL(p,0); + job.priority = SVAL(p,2); + fstrcpy(job.user, + fix_char_ptr(SVAL(p,4), converter, + rdata, rdrcnt)); + job.t = make_unix_date3(p + 12); + job.size = IVAL(p,16); + fstrcpy(job.name,fix_char_ptr(SVAL(p,24), + converter, + rdata, rdrcnt)); + fn(&job); + p += 28; + } + } + } + + /* If any parameters or data were returned, free the storage. */ + if(rparam) free(rparam); + if(rdata) free(rdata); + + return i; +} -- cgit From a1b002fcbe5daa91ce8bc94b73760e2428238315 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 10:14:21 +0000 Subject: add support for unlink() on printer shares in smbwrapper. unlink() will remove the job from the pirnt queue. (This used to be commit 7bd738c30a09a211fd14a8544309efeec17c66f5) --- source3/libsmb/clientgen.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0e01370f5d..e4aa15c6eb 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2495,6 +2495,43 @@ BOOL cli_establish_connection(struct cli_state *cli, } +/**************************************************************************** + cancel a print job + ****************************************************************************/ +int cli_printjob_del(struct cli_state *cli, int job) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt, ret = -1; + pstring param; + + bzero(param,sizeof(param)); + + p = param; + SSVAL(p,0,81); /* DosPrintJobDel() */ + p += 2; + pstrcpy(p,"W"); + p = skip_string(p,1); + pstrcpy(p,""); + p = skip_string(p,1); + SSVAL(p,0,job); + p += 2; + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) { /* return data, length */ + ret = SVAL(rparam,0); + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + + return ret; +} + /**************************************************************************** call fn() on each entry in a print queue -- cgit From 7c3c022a8913aec76a175095475cfcf8a4dfd698 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 10:46:52 +0000 Subject: use *SMBSERVER convention in smbwrapper to allow us to connect to servers that we don't know the netbios name of. (This used to be commit 147d49dade3901835b5d60b02c495bea544ff5e9) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/nmblib.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e4aa15c6eb..20c0c36166 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2134,7 +2134,7 @@ BOOL cli_negprot(struct cli_state *cli) send a session request. see rfc1002.txt 4.3 and 4.3.2 ****************************************************************************/ BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called) + struct nmb_name *calling, struct nmb_name *called) { char *p; int len = 4; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d08003133f..87f483e9fd 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -248,7 +248,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) fstring buf1; char *p; - if (name->name[0] == '*') { + if (strcmp(name->name,"*") == 0) { /* special case for wildcard name */ bzero(buf1,20); buf1[0] = '*'; -- cgit From 1970c92c0a56672308314d39718f994302c95c95 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 11:25:06 +0000 Subject: support NetServerEnum in smbwrapper. You can now do a ls in /smb/ and it will list all servers in your workgroup. You can set your workgroup with the SMBW_WORKGROUP environment variable. (This used to be commit 64699810e2d94e8648a0a3341b1cc826d4e8bfd9) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/namequery.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 20c0c36166..6b07eb65b3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -535,7 +535,7 @@ The callback function takes 3 arguments: the machine name, the server type and the comment. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(char *, uint32, char *)) + void (*fn)(const char *, uint32, const char *)) { char *rparam = NULL; char *rdata = NULL; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f988504bba..a9da735f36 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -420,7 +420,6 @@ void endlmhosts(FILE *fp) or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. *********************************************************/ - BOOL resolve_name(char *name, struct in_addr *return_ip) { int i; @@ -573,3 +572,43 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) return False; } + + + +/******************************************************** +find the IP address of the master browser for a workgroup +*********************************************************/ +BOOL find_master(char *group, struct in_addr *master_ip) +{ + int sock; + struct in_addr *iplist = NULL; + int count, i; + int num_interfaces = iface_count(); + + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()) ); + + if (sock == -1) return False; + + set_socket_options(sock,"SO_BROADCAST"); + + /* + * Lookup the name on all the interfaces, return on + * the first successful match. + */ + for( i = 0; i < num_interfaces; i++) { + struct in_addr sendto_ip; + /* Done this way to fix compiler error on IRIX 5.x */ + sendto_ip = *iface_bcast(*iface_n_ip(i)); + iplist = name_query(sock, group, 0x1D, True, False, + sendto_ip, &count, NULL); + if(iplist != NULL) { + *master_ip = iplist[0]; + free((char *)iplist); + close(sock); + return True; + } + } + close(sock); + return False; +} -- cgit From 40984f6b55212c710f6a7c7b940a785b2b607985 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 12:00:40 +0000 Subject: - modified resolve_name() to take a name_type - cleaned up resolve_name() (split into separate functions for each resolver) - if can't find local master then use #1B name - support listing of foreign workgroups in /smb/ (This used to be commit a4e607c17d1119925c9d0e1d05e0fe81e9a2d1aa) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/namequery.c | 321 ++++++++++++++++++++++++--------------------- 2 files changed, 174 insertions(+), 149 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6b07eb65b3..100e90160d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2196,7 +2196,7 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) fstrcpy(cli->desthost, host); if (!ip || ip_equal(*ip, ipzero)) { - if (!resolve_name( cli->desthost, &dest_ip)) { + if (!resolve_name( cli->desthost, &dest_ip, 0x20)) { return False; } } else { diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a9da735f36..22fb59a27d 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -414,13 +414,161 @@ void endlmhosts(FILE *fp) fclose(fp); } + + +/******************************************************** +resolve via "bcast" method +*********************************************************/ +static BOOL resolve_bcast(char *name, struct in_addr *return_ip, int name_type) +{ + int sock, i; + + /* + * "bcast" means do a broadcast lookup on all the local interfaces. + */ + + DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x20>\n", name)); + + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()) ); + + if (sock != -1) { + struct in_addr *iplist = NULL; + int count; + int num_interfaces = iface_count(); + set_socket_options(sock,"SO_BROADCAST"); + /* + * Lookup the name on all the interfaces, return on + * the first successful match. + */ + for( i = 0; i < num_interfaces; i++) { + struct in_addr sendto_ip; + /* Done this way to fix compiler error on IRIX 5.x */ + sendto_ip = *iface_bcast(*iface_n_ip(i)); + iplist = name_query(sock, name, name_type, True, + False, sendto_ip, &count, NULL); + if(iplist != NULL) { + *return_ip = iplist[0]; + free((char *)iplist); + close(sock); + return True; + } + } + close(sock); + } + + return False; +} + + + +/******************************************************** +resolve via "wins" method +*********************************************************/ +static BOOL resolve_wins(char *name, struct in_addr *return_ip, int name_type) +{ + int sock; + struct in_addr wins_ip; + BOOL wins_ismyip; + + /* + * "wins" means do a unicast lookup to the WINS server. + * Ignore if there is no WINS server specified or if the + * WINS server is one of our interfaces (if we're being + * called from within nmbd - we can't do this call as we + * would then block). + */ + + DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x20>\n", name)); + + if(!*lp_wins_server()) { + DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n")); + return False; + } + + wins_ip = *interpret_addr2(lp_wins_server()); + wins_ismyip = ismyip(wins_ip); + + if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()) ); + + if (sock != -1) { + struct in_addr *iplist = NULL; + int count; + iplist = name_query(sock, name, name_type, False, + True, wins_ip, &count, NULL); + if(iplist != NULL) { + *return_ip = iplist[0]; + free((char *)iplist); + close(sock); + return True; + } + close(sock); + } + } + + return False; +} + + +/******************************************************** +resolve via "lmhosts" method +*********************************************************/ +static BOOL resolve_lmhosts(char *name, struct in_addr *return_ip, int name_type) +{ + /* + * "lmhosts" means parse the local lmhosts file. + */ + + FILE *fp; + pstring lmhost_name; + int name_type2; + + DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n", name)); + + fp = startlmhosts( LMHOSTSFILE ); + if(fp) { + while (getlmhostsent(fp, lmhost_name, &name_type2, return_ip)) { + if (strequal(name, lmhost_name) && + name_type == name_type2) { + endlmhosts(fp); + return True; + } + } + endlmhosts(fp); + } + return False; +} + + +/******************************************************** +resolve via "hosts" method +*********************************************************/ +static BOOL resolve_hosts(char *name, struct in_addr *return_ip) +{ + /* + * "host" means do a localhost, or dns lookup. + */ + struct hostent *hp; + + DEBUG(3,("resolve_name: Attempting host lookup for name %s\n", name)); + + if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + putip((char *)return_ip,(char *)hp->h_addr); + return True; + } + return False; +} + + /******************************************************** Resolve a name into an IP address. Use this function if the string is either an IP address, DNS or host name or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. *********************************************************/ -BOOL resolve_name(char *name, struct in_addr *return_ip) +BOOL resolve_name(char *name, struct in_addr *return_ip, int name_type) { int i; BOOL pure_address = True; @@ -452,122 +600,27 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) if (!ptr || !*ptr) ptr = "host"; while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { - if(strequal(tok, "host") || strequal(tok, "hosts")) { - - /* - * "host" means do a localhost, or dns lookup. - */ - - struct hostent *hp; - - DEBUG(3,("resolve_name: Attempting host lookup for name %s\n", name)); - - if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { - putip((char *)return_ip,(char *)hp->h_addr); - return True; - } - - } else if(strequal( tok, "lmhosts")) { - - /* - * "lmhosts" means parse the local lmhosts file. - */ - - FILE *fp; - pstring lmhost_name; - int name_type; - - DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n", name)); - - fp = startlmhosts( LMHOSTSFILE ); - if(fp) { - while( getlmhostsent(fp, lmhost_name, &name_type, return_ip ) ) { - if( strequal(name, lmhost_name )) { - endlmhosts(fp); - return True; - } - } - endlmhosts(fp); - } - - } else if(strequal( tok, "wins")) { - - int sock; - - /* - * "wins" means do a unicast lookup to the WINS server. - * Ignore if there is no WINS server specified or if the - * WINS server is one of our interfaces (if we're being - * called from within nmbd - we can't do this call as we - * would then block). - */ - - DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x20>\n", name)); - - if(*lp_wins_server()) { - struct in_addr wins_ip = *interpret_addr2(lp_wins_server()); - BOOL wins_ismyip = ismyip(wins_ip); - - if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()) ); - - if (sock != -1) { - struct in_addr *iplist = NULL; - int count; - iplist = name_query(sock, name, 0x20, False, True, wins_ip, &count, NULL); - if(iplist != NULL) { - *return_ip = iplist[0]; - free((char *)iplist); - close(sock); - return True; - } - close(sock); - } - } - } else { - DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n")); - } - } else if(strequal( tok, "bcast")) { - - int sock; - - /* - * "bcast" means do a broadcast lookup on all the local interfaces. - */ - - DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x20>\n", name)); - - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()) ); - - if (sock != -1) { - struct in_addr *iplist = NULL; - int count; - int num_interfaces = iface_count(); - set_socket_options(sock,"SO_BROADCAST"); - /* - * Lookup the name on all the interfaces, return on - * the first successful match. - */ - for( i = 0; i < num_interfaces; i++) { - struct in_addr sendto_ip; - /* Done this way to fix compiler error on IRIX 5.x */ - sendto_ip = *iface_bcast(*iface_n_ip(i)); - iplist = name_query(sock, name, 0x20, True, False, sendto_ip, &count, NULL); - if(iplist != NULL) { - *return_ip = iplist[0]; - free((char *)iplist); - close(sock); - return True; - } - } - close(sock); - } - - } else { - DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); - } + if((strequal(tok, "host") || strequal(tok, "hosts"))) { + if (name_type == 0x20 && resolve_hosts(name, return_ip)) { + return True; + } + } else if(strequal( tok, "lmhosts")) { + if (resolve_lmhosts(name, return_ip, name_type)) { + return True; + } + } else if(strequal( tok, "wins")) { + /* don't resolve 1D via WINS */ + if (name_type != 0x1D && + resolve_wins(name, return_ip, name_type)) { + return True; + } + } else if(strequal( tok, "bcast")) { + if (resolve_bcast(name, return_ip, name_type)) { + return True; + } + } else { + DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); + } } return False; @@ -576,39 +629,11 @@ BOOL resolve_name(char *name, struct in_addr *return_ip) /******************************************************** -find the IP address of the master browser for a workgroup +find the IP address of the master browser or DMB for a workgroup *********************************************************/ BOOL find_master(char *group, struct in_addr *master_ip) { - int sock; - struct in_addr *iplist = NULL; - int count, i; - int num_interfaces = iface_count(); - - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()) ); + if (resolve_name(group, master_ip, 0x1D)) return True; - if (sock == -1) return False; - - set_socket_options(sock,"SO_BROADCAST"); - - /* - * Lookup the name on all the interfaces, return on - * the first successful match. - */ - for( i = 0; i < num_interfaces; i++) { - struct in_addr sendto_ip; - /* Done this way to fix compiler error on IRIX 5.x */ - sendto_ip = *iface_bcast(*iface_n_ip(i)); - iplist = name_query(sock, group, 0x1D, True, False, - sendto_ip, &count, NULL); - if(iplist != NULL) { - *master_ip = iplist[0]; - free((char *)iplist); - close(sock); - return True; - } - } - close(sock); - return False; + return resolve_name(group, master_ip, 0x1B); } -- cgit From 3a8232644e04a4cfdcbe2061f0556b78b4045191 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 14:02:50 +0000 Subject: started basic support for solaris 2.5 in smbwrapper. (This used to be commit e5c7cabae4826bde819b94a48bc4674dcd69da21) --- source3/libsmb/.cvsignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/.cvsignore b/source3/libsmb/.cvsignore index f20330ba4d..6d609cec52 100644 --- a/source3/libsmb/.cvsignore +++ b/source3/libsmb/.cvsignore @@ -1 +1 @@ -*.p +*.po -- cgit From ecb7ee7a034961a38a2922f481a3235c615903bd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Oct 1998 02:45:50 +0000 Subject: handle ENOTDIR errno in cli_error() (This used to be commit f1d82e02ff7f2201de5fb13af4cadec648765017) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 100e90160d..46da08bb3a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2287,6 +2287,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case NT_STATUS_ACCESS_DENIED: return EACCES; case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; case NT_STATUS_SHARING_VIOLATION: return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; } /* for all other cases - a default code */ @@ -2303,6 +2304,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) if (rcls == ERRDOS) { switch (code) { case ERRbadfile: return ENOENT; + case ERRbadpath: return ENOTDIR; case ERRnoaccess: return EACCES; } } -- cgit From bfaff8ed1a3899c9aef7eaa2421d3d6467343ea1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Oct 1998 12:17:01 +0000 Subject: got smbwrapper working on IRIX 6.4. Things got a bit tricky, especially as the headers get the syscall numbers wrong! (This used to be commit a5405f1ab069a3123a819311a87ca84f2c5f0fea) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 46da08bb3a..e395aa3b15 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1343,7 +1343,7 @@ size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ do a SMBgetattrE call ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - int *attr, uint32 *size, + uint32 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { bzero(cli->outbuf,smb_size); -- cgit From 217804ba43bad984e1d1c8a623acea95ed929a4e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Oct 1998 12:36:44 +0000 Subject: ignore *.po32 files (This used to be commit 01de9a50e030da722076c67c235801c36c90bb66) --- source3/libsmb/.cvsignore | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/.cvsignore b/source3/libsmb/.cvsignore index 6d609cec52..07da2225c7 100644 --- a/source3/libsmb/.cvsignore +++ b/source3/libsmb/.cvsignore @@ -1 +1,3 @@ *.po +*.po32 + -- cgit From b4fb4caf9032875fe50725c9b71b6411538ba85f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 5 Oct 1998 15:41:41 +0000 Subject: rpcclient srvsvc commands. (This used to be commit 1a9a22c657c46648adaa98ac1fe394ce4bce11f0) --- source3/libsmb/clientgen.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e395aa3b15..2d49144695 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2259,8 +2259,11 @@ void cli_shutdown(struct cli_state *cli) /**************************************************************************** return error codes for the last packet - returns 0 if there was no error and the bext approx of a unix errno + returns 0 if there was no error and the best approx of a unix errno otherwise + + for 32 bit "warnings", a return code of 0 is expected. + ****************************************************************************/ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { -- cgit From 404f14fb36577ee182fd8a928e6cb7b374e4ecb9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 1998 13:10:06 +0000 Subject: implemented unix semantics for rename in smbwrapper (This used to be commit a5c18f9c82f5f76b00ff29c5668b4f0d3e8d6bd0) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2d49144695..93f7a3d222 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1196,6 +1196,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t int mid; int blocks = (size + (block-1)) / block; + if (size == 0) return 0; + while (received < blocks) { int size2; @@ -1295,6 +1297,8 @@ size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ int mid; int blocks = (size + (block-1)) / block; + if (size == 0) return 0; + while (received < blocks) { int size2; @@ -2309,6 +2313,8 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRbadfile: return ENOENT; case ERRbadpath: return ENOTDIR; case ERRnoaccess: return EACCES; + case ERRfilexists: return EEXIST; + case ERRrename: return EEXIST; } } if (rcls == ERRSRV) { -- cgit From cbb25c71d052c5fc2f4d526625d558f0c33f587e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 6 Oct 1998 13:20:06 +0000 Subject: fixed rename error code from NT servers (This used to be commit e7516901270a4a790a3e346065eb2be8ede16cb3) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 93f7a3d222..70231e3c94 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2295,6 +2295,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; case NT_STATUS_SHARING_VIOLATION: return EBUSY; case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; } /* for all other cases - a default code */ -- cgit From 029144cd8c07aa82100b545574e3af1201426b58 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 7 Oct 1998 00:40:18 +0000 Subject: do an anonymous login if the username/password is rejected. (This used to be commit 0ee3e0c62378bdf7a8e145de0727ea85763af95a) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 70231e3c94..38b4b5ffeb 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -764,6 +764,7 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->share, share); + /* in user level security don't send a password now */ if (cli->sec_mode & 1) { passlen = 1; pass = ""; -- cgit From 48b31ae44fb2a1961bd738b0b3e7a986259168a2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 7 Oct 1998 21:42:24 +0000 Subject: dce/rpc (This used to be commit 6677b888bdb45df00646eb7cc13005b9465ff971) --- source3/libsmb/smbdes.c | 55 +++++++++++++++++++++++++++++++++++++++++++-- source3/libsmb/smbencrypt.c | 12 ++++++++++ 2 files changed, 65 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index eebe0dc54f..e9f2329550 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -357,6 +357,58 @@ void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int for smbhash(out + 8, in + 8, key2, forw); } +void NTLMSSPhash( unsigned char hash[256], unsigned char const key[5]) +{ + unsigned char j = 0; + int ind; + + unsigned char k2[8]; + + memcpy(k2, key, sizeof(key)); + k2[5] = 0xe5; + k2[6] = 0xb8; + k2[6] = 0xb0; + + for (ind = 0; ind < 256; ind++) + { + hash[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (hash[ind] + k2[ind%8]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } +} + +void NTLMSSPcalc( unsigned char hash[256], unsigned char *data, int len) +{ + unsigned char index_i = 0; + unsigned char index_j = 0; + int ind; + + for( ind = 0; ind < len; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] ^= hash[t]; + } +} + void SamOEMhash( unsigned char *data, unsigned char *key, int val) { unsigned char s_box[256]; @@ -380,8 +432,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) s_box[ind] = s_box[j]; s_box[j] = tc; } - - for( ind = 0; ind < (val ? 516 : 16); ind++) + for( ind = 0; ind < val ? 516 : 8; ind++) { unsigned char tc; unsigned char t; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index bf9736d724..44dcbd5e05 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -152,6 +152,18 @@ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) E_P24(p21, c8, p24); } +/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ +void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) +{ + uchar p21[21]; + + memset(p21,'\0',21); + memcpy(p21, passwd, 8); + memset(p21 + 8, 0xbd, 8); + + E_P24(p21, ntlmchalresp, p24); +} + /* Does the NT MD4 hash then des encryption. */ -- cgit From 4750ce1760a39100f71e74ce8b88a925fef4c42f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 02:28:21 +0000 Subject: use 1 second resolution calls if possible (This used to be commit 349469221a84658048790d7567b4fcea43c0b759) --- source3/libsmb/clientgen.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 38b4b5ffeb..657523b3be 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1557,9 +1557,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, /**************************************************************************** send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ -BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, uint32 *size) + time_t *w_time, size_t *size, uint32 *mode) { int data_len = 0; int param_len = 0; @@ -1608,6 +1608,9 @@ BOOL cli_qpathinfo2(struct cli_state *cli, char *fname, if (size) { *size = IVAL(rdata, 40); } + if (mode) { + *mode = IVAL(rdata, 32); + } if (rdata) free(rdata); if (rparam) free(rparam); -- cgit From 788263ba2f749c5bb1546ca6c9363fd508e94280 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 06:21:33 +0000 Subject: - fixed a bunch of warnings and minor errors - got smbtorture to compile - removed %D from some of lukes code - Luke, what is %D? it ain't portable anyway (This used to be commit 91597c12fb593f49b23c7cea5b64dbb89a0428b3) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/namequery.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 657523b3be..d454cbdd3c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -621,7 +621,7 @@ prots[] = /**************************************************************************** -send a session setup +send a session setup ****************************************************************************/ BOOL cli_session_setup(struct cli_state *cli, char *user, diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 22fb59a27d..500618bd8a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -631,7 +631,7 @@ BOOL resolve_name(char *name, struct in_addr *return_ip, int name_type) /******************************************************** find the IP address of the master browser or DMB for a workgroup *********************************************************/ -BOOL find_master(char *group, struct in_addr *master_ip) +BOOL find_master_ip(char *group, struct in_addr *master_ip) { if (resolve_name(group, master_ip, 0x1D)) return True; -- cgit From a813f38e2dc894b548c23dea2bef98cef7d4f4e9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 06:49:00 +0000 Subject: - don't generate 0 params in torture - handle 0 params in ipc.c (This used to be commit c0dc8e87f0d56444a8ddff0817a94065ca295847) --- source3/libsmb/clientgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d454cbdd3c..8aa857df8a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -432,9 +432,9 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) pstrcpy(p,user); strupper(p); p += 21; - p++; - p += 15; - p++; + p++; + p += 15; + p++; pstrcpy(p, workstation); strupper(p); p += 16; -- cgit From d57d00005ee9056f5abf636ef7828098ae02ce2d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 8 Oct 1998 22:48:46 +0000 Subject: fixed bug pointed out by Herb. (This used to be commit 35a5e9ce4fd60806e652f221e25caa0664b69209) --- source3/libsmb/smbdes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index e9f2329550..1d6c6bc0a6 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -432,7 +432,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) s_box[ind] = s_box[j]; s_box[j] = tc; } - for( ind = 0; ind < val ? 516 : 8; ind++) + for( ind = 0; ind < (val ? 516 : 8); ind++) { unsigned char tc; unsigned char t; -- cgit From 6909350ed9b87875ee40191b2e636c6049749195 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 8 Oct 1998 23:57:46 +0000 Subject: dce/rpc (This used to be commit 62fdeef1b79c5c4c9bf0e860881651711bb80b9a) --- source3/libsmb/clientgen.c | 44 +++++++++++++++++++++++++++++++++++--------- source3/libsmb/pwd_cache.c | 20 ++++++++++++++++---- 2 files changed, 51 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8aa857df8a..5ae84f763b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1255,7 +1255,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t /**************************************************************************** issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char *buf, +static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, size_t size, int i) { char *p; @@ -1272,6 +1272,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); SIVAL(cli->outbuf,smb_vwv3,offset); + SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); + SSVAL(cli->outbuf,smb_vwv7,mode); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, @@ -1282,13 +1284,20 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char SSVAL(cli->outbuf,smb_mid,cli->mid + i); + show_msg(cli->outbuf); send_smb(cli->fd,cli->outbuf); } /**************************************************************************** write to a file + write_mode: 0x0001 disallow write cacheing + 0x0002 return bytes remaining + 0x0004 use raw named pipe protocol + 0x0008 start of message mode named pipe protocol ****************************************************************************/ -size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +size_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size) { int total = -1; int issued=0; @@ -1305,7 +1314,9 @@ size_t cli_write(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ while (issued - received < mpx && issued < blocks) { int size1 = MIN(block, size-issued*block); - cli_issue_write(cli, fnum, offset+issued*block, buf + issued*block, + cli_issue_write(cli, fnum, offset+issued*block, + write_mode, + buf + issued*block, size1, issued); issued++; } @@ -2226,9 +2237,12 @@ initialise a client structure BOOL cli_initialise(struct cli_state *cli) { if (cli->initialised) - cli_shutdown(cli); + { + cli_shutdown(cli); + } memset(cli, 0, sizeof(*cli)); + cli->fd = -1; cli->cnum = -1; cli->pid = (uint16)getpid(); @@ -2241,8 +2255,12 @@ BOOL cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); if (!cli->outbuf || !cli->inbuf) - return False; + { + return False; + } + cli->initialised = 1; + return True; } @@ -2252,9 +2270,13 @@ shutdown a client structure void cli_shutdown(struct cli_state *cli) { if (cli->outbuf) - free(cli->outbuf); + { + free(cli->outbuf); + } if (cli->inbuf) - free(cli->inbuf); + { + free(cli->inbuf); + } #ifdef WITH_SSL if (cli->fd != -1) sslutil_disconnect(cli->fd); @@ -2454,7 +2476,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session setup\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } if (do_tcon) @@ -2464,7 +2488,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed tcon_X\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } } diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 92eee015b3..c4c578cde6 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -168,8 +168,14 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_deobfuscate(pwd); - memcpy(lm_pwd, pwd->smb_lm_pwd, 16); - memcpy(nt_pwd, pwd->smb_nt_pwd, 16); + if (lm_pwd != NULL) + { + memcpy(lm_pwd, pwd->smb_lm_pwd, 16); + } + if (nt_pwd != NULL) + { + memcpy(nt_pwd, pwd->smb_nt_pwd, 16); + } pwd_obfuscate(pwd); } @@ -229,7 +235,13 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) { pwd_deobfuscate(pwd); - memcpy(lm_owf, pwd->smb_lm_owf, 24); - memcpy(nt_owf, pwd->smb_nt_owf, 24); + if (lm_owf != NULL) + { + memcpy(lm_owf, pwd->smb_lm_owf, 24); + } + if (nt_owf != NULL) + { + memcpy(nt_owf, pwd->smb_nt_owf, 24); + } pwd_obfuscate(pwd); } -- cgit From 755986764f5a6b0ec25c7f20fde0a80eb4d121ba Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 19:05:19 +0000 Subject: dce/rpc (This used to be commit 32d0f5e4a564686ad6b270dd24423ee49a81f223) --- source3/libsmb/smbdes.c | 26 ++++++++++++++++---------- source3/libsmb/smbencrypt.c | 6 ++++++ 2 files changed, 22 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 1d6c6bc0a6..c0f749ad3b 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -357,17 +357,17 @@ void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int for smbhash(out + 8, in + 8, key2, forw); } -void NTLMSSPhash( unsigned char hash[256], unsigned char const key[5]) +void NTLMSSPhash( unsigned char hash[258], unsigned char key[5]) { - unsigned char j = 0; - int ind; + unsigned char j = 0; + int ind; unsigned char k2[8]; - memcpy(k2, key, sizeof(key)); + memcpy(k2, key, 5); k2[5] = 0xe5; - k2[6] = 0xb8; - k2[6] = 0xb0; + k2[6] = 0x38; + k2[7] = 0xb0; for (ind = 0; ind < 256; ind++) { @@ -384,12 +384,15 @@ void NTLMSSPhash( unsigned char hash[256], unsigned char const key[5]) hash[ind] = hash[j]; hash[j] = tc; } + + hash[256] = 0; + hash[257] = 0; } -void NTLMSSPcalc( unsigned char hash[256], unsigned char *data, int len) +void NTLMSSPcalc( unsigned char hash[258], unsigned char *data, int len) { - unsigned char index_i = 0; - unsigned char index_j = 0; + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; int ind; for( ind = 0; ind < len; ind++) @@ -405,8 +408,11 @@ void NTLMSSPcalc( unsigned char hash[256], unsigned char *data, int len) hash[index_j] = tc; t = hash[index_i] + hash[index_j]; - data[ind] ^= hash[t]; + data[ind] = data[ind] ^ hash[t]; } + + hash[256] = index_i; + hash[257] = index_j; } void SamOEMhash( unsigned char *data, unsigned char *key, int val) diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 44dcbd5e05..a9e680ccdd 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -162,6 +162,12 @@ void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) memset(p21 + 8, 0xbd, 8); E_P24(p21, ntlmchalresp, p24); +#ifdef DEBUG_PASSWORD + DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); + dump_data(100, p21, 21); + dump_data(100, ntlmchalresp, 8); + dump_data(100, p24, 24); +#endif } -- cgit From 4e004a0b5e7521a361444f6d67a3c2910c5688c2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 19:34:57 +0000 Subject: basic client-side ntcreateX function (hard-wired values except filename) (This used to be commit caeb99201a1471bd709b4e8f07c57e5caabf0795) --- source3/libsmb/clientgen.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5ae84f763b..8eb832128c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -973,6 +973,50 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) +/**************************************************************************** +open a file +****************************************************************************/ +int cli_nt_create(struct cli_state *cli, char *fname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,24,1 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBntcreateX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SIVAL(cli->outbuf,smb_ntcreate_Flags, 0x06); + SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f); + SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); + SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); + SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); + SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); + + p = smb_buf(cli->outbuf); + pstrcpy(p,fname); + p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2 + 1); +} + + /**************************************************************************** open a file ****************************************************************************/ -- cgit From 8158620124504a1ece1f1191cb8f273709039bd2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 20:17:11 +0000 Subject: dce/rpc. (This used to be commit e0445419b2d50ae6efef36f4f295ebcfdbf1ad82) --- source3/libsmb/clientgen.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8eb832128c..025ec5e73f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -614,8 +614,8 @@ prots[] = {PROTOCOL_LANMAN1,"LANMAN1.0"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LM 0.12"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {PROTOCOL_NT1,"NT LM 0.12"}, {-1,NULL} }; @@ -1318,7 +1318,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SIVAL(cli->outbuf,smb_vwv3,offset); SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); SSVAL(cli->outbuf,smb_vwv7,mode); - + + SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_ALL(mode, 0x0008) ? size : 0); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); -- cgit From 78c1fd054f25ae2d0fa57669a0db102bc916577c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Oct 1998 23:31:50 +0000 Subject: dce/rpc (This used to be commit 8a7ac4a25d177235a98c0f84f97ee50432fb6359) --- source3/libsmb/clientgen.c | 23 +++++------------------ source3/libsmb/smbencrypt.c | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 025ec5e73f..72d7ca935b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2021,7 +2021,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo unsigned char new_pw_hash[16]; int data_len; int param_len = 0; - int new_pw_len = strlen(new_password); char *rparam = NULL; char *rdata = NULL; int rprcnt, rdrcnt; @@ -2031,11 +2030,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo return False; } - if (new_pw_len > 512) { - DEBUG(0,("cli_oem_change_password: new password for user %s is too long.\n", user)); - return False; - } - SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; pstrcpy(p, "zsT"); @@ -2049,26 +2043,19 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo param_len = PTR_DIFF(p,param); - /* - * Now setup the data area. - * We need to generate a random fill - * for this area to make it harder to - * decrypt. JRA. - */ - generate_random_buffer((unsigned char *)data, sizeof(data), False); - fstrcpy( &data[512 - new_pw_len], new_password); - SIVAL(data, 512, new_pw_len); - /* * Get the Lanman hash of the old password, we - * use this as the key to SamOEMHash(). + * use this as the key to make_oem_passwd_hash(). */ memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); fstrcpy(upper_case_old_pw, old_password); strupper(upper_case_old_pw); E_P16((uchar *)upper_case_old_pw, old_pw_hash); - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); + if (!make_oem_passwd_hash( data, new_password, old_pw_hash)) + { + return False; + } /* * Now place the old password hash in the data. diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index a9e680ccdd..27c19d5836 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -191,3 +191,26 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) } +BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16]) +{ + int new_pw_len = strlen(passwd); + + if (new_pw_len > 512) + { + DEBUG(0,("make_oem_passwd_hash: new password is too long.\n")); + return False; + } + + /* + * Now setup the data area. + * We need to generate a random fill + * for this area to make it harder to + * decrypt. JRA. + */ + generate_random_buffer((unsigned char *)data, 516, False); + fstrcpy( &data[512 - new_pw_len], passwd); + SIVAL(data, 512, new_pw_len); + + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); +} + -- cgit From 827a9d862ebe3d5ce1853999d16bd121fddcc796 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 10 Oct 1998 00:46:28 +0000 Subject: dce/rpc (This used to be commit dfb48aab6153e53a5efd1f8ee518375cc584b101) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/smbencrypt.c | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 72d7ca935b..64e67c5522 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2052,7 +2052,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_passwo strupper(upper_case_old_pw); E_P16((uchar *)upper_case_old_pw, old_pw_hash); - if (!make_oem_passwd_hash( data, new_password, old_pw_hash)) + if (!make_oem_passwd_hash( data, new_password, old_pw_hash, False)) { return False; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 27c19d5836..7caf417ea1 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -190,10 +190,9 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) #endif } - -BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16]) +BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16], BOOL unicode) { - int new_pw_len = strlen(passwd); + int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); if (new_pw_len > 512) { @@ -208,9 +207,20 @@ BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16]) * decrypt. JRA. */ generate_random_buffer((unsigned char *)data, 516, False); - fstrcpy( &data[512 - new_pw_len], passwd); + if (unicode) + { + struni2( (uint16*)(&data[512 - new_pw_len]), passwd); + } + else + { + fstrcpy( &data[512 - new_pw_len], passwd); + } SIVAL(data, 512, new_pw_len); +#ifdef DEBUG_PASSWORD + DEBUG(100,("make_oem_passwd_hash\n")); + dump_data(100, data, 516); +#endif SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); } -- cgit From 935dc98f6670ba630bd2086ef9eddcc94a0562e2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 14 Oct 1998 06:29:20 +0000 Subject: dce/rpc (This used to be commit 69f5f9f88935de1f63ffc9aa19c0629b395e66e6) --- source3/libsmb/pwd_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index c4c578cde6..bbd5f63d4b 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -219,7 +219,7 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) #ifdef DEBUG_PASSWORD DEBUG(100,("lm_owf_passwd: ")); - dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); DEBUG(100,("lm_sess_pwd: ")); dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); #endif -- cgit From 948f81a5920c5204438e41d4fd41a32948ce7321 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 14 Oct 1998 07:00:00 +0000 Subject: warnings spotted by ./configure.developer options (This used to be commit 29434bf195b438f4ab41a10ac5ce03f9c2d2ac2f) --- source3/libsmb/smbencrypt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 7caf417ea1..66eba88f49 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -222,5 +222,7 @@ BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16], BO dump_data(100, data, 516); #endif SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); + + return True; } -- cgit From 2a3cd67074073a38dccb528d2600fb8d88d3b8ed Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 14 Oct 1998 16:12:45 +0000 Subject: 16 changed to 8 by mistake in samoemhash. (This used to be commit ed6ffa4430e3ae6e0c9f49650f53ce79d12af28e) --- source3/libsmb/smbdes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index c0f749ad3b..46b337cda8 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -438,7 +438,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) s_box[ind] = s_box[j]; s_box[j] = tc; } - for( ind = 0; ind < (val ? 516 : 8); ind++) + for( ind = 0; ind < (val ? 516 : 16); ind++) { unsigned char tc; unsigned char t; -- cgit From bc747b8a077d22344aa03bbba202f5137b59284d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 14 Oct 1998 16:45:24 +0000 Subject: set recursion desired for bcast name query (This used to be commit 53805112f1a301f77cda93b68e6fa3054895f20f) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 500618bd8a..e95302fcd0 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -446,7 +446,7 @@ static BOOL resolve_bcast(char *name, struct in_addr *return_ip, int name_type) /* Done this way to fix compiler error on IRIX 5.x */ sendto_ip = *iface_bcast(*iface_n_ip(i)); iplist = name_query(sock, name, name_type, True, - False, sendto_ip, &count, NULL); + True, sendto_ip, &count, NULL); if(iplist != NULL) { *return_ip = iplist[0]; free((char *)iplist); -- cgit From c404bb775414139a4b07a73f79cf069a083acb26 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 15 Oct 1998 23:51:07 +0000 Subject: rpcclient interactive login (with trust account changing if you are root) cli_session_setup handles null sessions correctly (This used to be commit 60c0f22a4e84703467006dfe1971384a6294a9aa) --- source3/libsmb/clientgen.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 64e67c5522..a6ffb57834 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2494,15 +2494,25 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->pwd.cleartext || cli->pwd.null_pwd) { - /* attempt clear-text session */ - fstring passwd; + int pass_len; - pwd_get_cleartext(&(cli->pwd), passwd); + if (cli->pwd.null_pwd) + { + /* attempt null session */ + passwd[0] = 0; + pass_len = 1; + } + else + { + /* attempt clear-text session */ + pwd_get_cleartext(&(cli->pwd), passwd); + pass_len = strlen(passwd); + } /* attempt clear-text session */ if (!cli_session_setup(cli, cli->user_name, - passwd, strlen(passwd), + passwd, pass_len, NULL, 0, cli->domain)) { -- cgit From 070b33489179d07ed76530ad52b828e6e708789d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Oct 1998 00:54:16 +0000 Subject: trans2.h: Added Thursby MAC extension. smbd/trans2.c: Added Thursby MAX extension. libsmb/clientgen.c: Fixed smbtorture lock code. Jeremy. (This used to be commit 514e52e4b4d6c7db7ebe2265e60c77b4f18d11b3) --- source3/libsmb/clientgen.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a6ffb57834..3c2ad3e0ea 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1126,6 +1126,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) { char *p; + int saved_timeout = cli->timeout; bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); @@ -1149,10 +1150,16 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SIVAL(p, 6, len); send_smb(cli->fd,cli->outbuf); + + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; + if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + cli->timeout = saved_timeout; return False; } + cli->timeout = saved_timeout; + if (CVAL(cli->inbuf,smb_rcls) != 0) { return False; } @@ -1315,6 +1322,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); SSVAL(cli->outbuf,smb_vwv7,mode); -- cgit From 62811de4e84f21aafff161dbf151e487660144e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 Oct 1998 17:40:01 +0000 Subject: - use large buffers for netshareenum - handle errmoredata a bit better - fix dev type from tconx for smbw (This used to be commit 2f39409dc1ef012a8a7d315572a489d15df186f7) --- source3/libsmb/clientgen.c | 49 ++++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3c2ad3e0ea..3ed80eb7a6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -489,12 +489,12 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); - SSVAL(p,2,CLI_BUFFER_SIZE); + SSVAL(p,2,0xFFFF); p += 4; if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ + NULL, 0, 0xFFFF, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { @@ -502,20 +502,22 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c int converter=SVAL(rparam,2); int i; - if (res == 0) - { - count=SVAL(rparam,4); - p = rdata; - - for (i=0;ioutbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,CAP_STATUS32); + SSVAL(cli->outbuf,smb_vwv11,0); p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); @@ -805,8 +807,17 @@ BOOL cli_send_tconX(struct cli_state *cli, return False; } - fstrcpy(cli->dev, smb_buf(cli->inbuf)); + fstrcpy(cli->dev, "A:"); + + if (cli->protocol >= PROTOCOL_NT1) { + fstrcpy(cli->dev, smb_buf(cli->inbuf)); + } + + if (strcasecmp(share,"IPC$")==0) { + fstrcpy(cli->dev, "IPC"); + } + /* only grab the device if we have a recent protocol level */ if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ -- cgit From fc62d6bf368c950e1e51bc42771cce8b299df42c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Oct 1998 17:41:13 +0000 Subject: Small tidyups for gcc in 'preen' mode.... Jeremy. (This used to be commit 60dc1a4a00a22088d33369588b0d5eb292cf084a) --- source3/libsmb/smbdes.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 46b337cda8..9d531ef26d 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -22,6 +22,7 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include "includes.h" /* NOTES: -- cgit From d5c190bae83b49de7bb8b626f83fc730f8759270 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Oct 1998 01:05:11 +0000 Subject: return the resolved IP on a cli_connect() call so it can be cached (This used to be commit 4e3f8ef41b8de25dec4c01d5532dca1b567be55a) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3ed80eb7a6..48abbd7a15 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2269,6 +2269,7 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) if (!resolve_name( cli->desthost, &dest_ip, 0x20)) { return False; } + if (ip) *ip = dest_ip; } else { dest_ip = *ip; } -- cgit From 9debf0b1eeeb6766e3f8ad5b62cf41c7194e41ba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Oct 1998 02:48:57 +0000 Subject: improved session reestablishment (This used to be commit 5f96328d32e76785474ffd5cd73f8ddefc46d4f5) --- source3/libsmb/clientgen.c | 118 +++++++++++++++++++++++++++++++-------------- 1 file changed, 82 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 48abbd7a15..7c58a969e7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -27,6 +27,40 @@ extern int DEBUGLEVEL; + +/**************************************************************************** + send an smb to a fd and re-establish if necessary +****************************************************************************/ +static BOOL cli_send_smb(struct cli_state *cli) +{ + size_t len; + size_t nwritten=0; + ssize_t ret; + BOOL reestablished=False; + + len = smb_len(cli->outbuf) + 4; + + while (nwritten < len) { + ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + if (ret <= 0 && errno == EPIPE && !reestablished) { + if (cli_reestablish_connection(cli)) { + reestablished = True; + nwritten=0; + continue; + } + } + if (ret <= 0) { + DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", + len,ret)); + close_sockets(); + exit(1); + } + nwritten += ret; + } + + return True; +} + /***************************************************** RAP error codes - a small start but will be extended. *******************************************************/ @@ -218,7 +252,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); show_msg(cli->outbuf); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ @@ -259,7 +293,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); show_msg(cli->outbuf); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); tot_data += this_ldata; tot_param += this_lparam; @@ -717,7 +751,7 @@ BOOL cli_session_setup(struct cli_state *cli, set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -730,6 +764,8 @@ BOOL cli_session_setup(struct cli_state *cli, /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); + fstrcpy(cli->user_name, user); + return True; } @@ -746,7 +782,7 @@ BOOL cli_ulogoff(struct cli_state *cli) SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -799,7 +835,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -840,7 +876,7 @@ BOOL cli_tdis(struct cli_state *cli) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -872,7 +908,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) *p++ = 4; pstrcpy(p,fname_dst); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -906,7 +942,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) *p++ = 4; pstrcpy(p,fname); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -938,7 +974,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -970,7 +1006,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1015,7 +1051,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) pstrcpy(p,fname); p = skip_string(p,1); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -1086,7 +1122,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) pstrcpy(p,fname); p = skip_string(p,1); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return -1; } @@ -1118,7 +1154,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SSVAL(cli->outbuf,smb_vwv0,fnum); SIVALS(cli->outbuf,smb_vwv1,-1); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1160,7 +1196,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SIVAL(p, 2, offset); SIVAL(p, 6, len); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1206,7 +1242,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 2, offset); SIVAL(p, 6, len); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1242,7 +1278,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); } /**************************************************************************** @@ -1349,7 +1385,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_mid,cli->mid + i); show_msg(cli->outbuf); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); } /**************************************************************************** @@ -1437,7 +1473,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1491,7 +1527,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, *p = 4; pstrcpy(p+1, fname); - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -1542,7 +1578,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) p = skip_string(p,1); *p = 4; - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { return False; } @@ -2149,7 +2185,7 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) return False; @@ -2231,7 +2267,7 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - send_smb(cli->fd,cli->outbuf); + cli_send_smb(cli); DEBUG(5,("Sent session request\n")); if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) @@ -2260,22 +2296,22 @@ open the client sockets ****************************************************************************/ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) { - struct in_addr dest_ip; extern struct in_addr ipzero; fstrcpy(cli->desthost, host); if (!ip || ip_equal(*ip, ipzero)) { - if (!resolve_name( cli->desthost, &dest_ip, 0x20)) { + if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) { return False; } - if (ip) *ip = dest_ip; + if (ip) *ip = cli->dest_ip; } else { - dest_ip = *ip; + cli->dest_ip = *ip; } - cli->fd = open_socket_out(SOCK_STREAM, &dest_ip, 139, cli->timeout); + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + 139, cli->timeout); if (cli->fd == -1) return False; @@ -2424,17 +2460,17 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) } /**************************************************************************** -establishes a connection right up to doing tconX, reading in a password. +re-establishes a connection ****************************************************************************/ BOOL cli_reestablish_connection(struct cli_state *cli) { struct nmb_name calling; struct nmb_name called; fstring dest_host; - struct in_addr dest_ip; fstring share; fstring dev; BOOL do_tcon = False; + int oldfd = cli->fd; if (!cli->initialised || cli->fd == -1) { @@ -2454,16 +2490,26 @@ BOOL cli_reestablish_connection(struct cli_state *cli) memcpy(&called , &(cli->called ), sizeof(called )); memcpy(&calling, &(cli->calling), sizeof(calling)); fstrcpy(dest_host, cli->full_dest_host_name); - dest_ip = cli->dest_ip; DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", - namestr(&calling), namestr(&called), inet_ntoa(dest_ip), - cli->user_name, cli->domain)); + namestr(&calling), namestr(&called), + inet_ntoa(cli->dest_ip), + cli->user_name, cli->domain)); - return cli_establish_connection(cli, - dest_host, &dest_ip, - &calling, &called, - share, dev, False, do_tcon); + cli->fd = -1; + + if (cli_establish_connection(cli, + dest_host, &cli->dest_ip, + &calling, &called, + share, dev, False, do_tcon)) { + if (cli->fd != oldfd) { + if (dup2(cli->fd, oldfd) == oldfd) { + close(cli->fd); + } + } + return True; + } + return False; } /**************************************************************************** -- cgit From 01de6030843f5f402dee8bf72f564a91ae8437ca Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 19 Oct 1998 17:32:10 +0000 Subject: - dce/rpc code - removed debug info in struni2 and unistr2 (security risk) - rpc_pipe function was getting pointer to data then calling realloc *dur* - password check function, the start of "credential checking", user, wks, domain, pass as the credentials (not just user,pass which is incorrect in a domain context) - cli_write needs to return ssize_t not size_t, because total can be -1 if the write fails. - fixed signed / unsigned warnings (how come i don't get those any more when i compile with gcc???) - nt password change added in smbd. yes, jeremy, i verified that the SMBtrans2 version still works. (This used to be commit fcfb40d2b0fc565ee4f66b3a3761c246366a2ef3) --- source3/libsmb/clientgen.c | 3 +-- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7c58a969e7..d3233f59fd 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1195,7 +1195,6 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1395,7 +1394,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 0x0004 use raw named pipe protocol 0x0008 start of message mode named pipe protocol ****************************************************************************/ -size_t cli_write(struct cli_state *cli, +ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, char *buf, off_t offset, size_t size) { diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 66eba88f49..5017b33c07 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -190,7 +190,7 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) #endif } -BOOL make_oem_passwd_hash(char data[516], char *passwd, char old_pw_hash[16], BOOL unicode) +BOOL make_oem_passwd_hash(char data[516], char *passwd, uchar old_pw_hash[16], BOOL unicode) { int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); -- cgit From 1ee499385c1ea0b4add82d3d4513ea997d048af1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Oct 1998 16:55:03 +0000 Subject: libsmb/smbdes.c: #ifdef'ed out code prior to removal. rpc_client/cli_pipe.c: Inlined code removed from smbdes.c rpc_server/srv_samr.c: Fixed unused variable warning. rpc_server/srv_util.c: Inlined code removed from smbdes.c Luke - the above changes are the first part of the changes you and I discussed as being neccessary at the CIFS conference. *PLEASE REVIEW THESE CHANGES* - make sure I haven't broken any of the authenticated DCE/RPC code. smbd/nttrans.c: Fixed to allow NT5.0beta2 to use Samba shares with NT SMB support. smbd/open.c: Fixed mkdir when called from nttrans calls. smbd/server.c: Set correct size for strcpy of global_myworkgroup. Jeremy. (This used to be commit d891421d16ff80998dee429227bd391455f9d1a1) --- source3/libsmb/smbdes.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 9d531ef26d..8a13935cf9 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -358,6 +358,10 @@ void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int for smbhash(out + 8, in + 8, key2, forw); } +#if 0 +/* + * Prepare to remove... JRA. + */ void NTLMSSPhash( unsigned char hash[258], unsigned char key[5]) { unsigned char j = 0; @@ -389,6 +393,7 @@ void NTLMSSPhash( unsigned char hash[258], unsigned char key[5]) hash[256] = 0; hash[257] = 0; } +#endif void NTLMSSPcalc( unsigned char hash[258], unsigned char *data, int len) { -- cgit From 84866d423330b2a21720adef2e9bed5f45d8ff0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Oct 1998 19:15:24 +0000 Subject: Removed previously #ifdef 0 'ed code. Jeremy. (This used to be commit 7feaa13d02f84760d6857115ed253570f41911bb) --- source3/libsmb/smbdes.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 8a13935cf9..5bff1742af 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -358,43 +358,6 @@ void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int for smbhash(out + 8, in + 8, key2, forw); } -#if 0 -/* - * Prepare to remove... JRA. - */ -void NTLMSSPhash( unsigned char hash[258], unsigned char key[5]) -{ - unsigned char j = 0; - int ind; - - unsigned char k2[8]; - - memcpy(k2, key, 5); - k2[5] = 0xe5; - k2[6] = 0x38; - k2[7] = 0xb0; - - for (ind = 0; ind < 256; ind++) - { - hash[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (hash[ind] + k2[ind%8]); - - tc = hash[ind]; - hash[ind] = hash[j]; - hash[j] = tc; - } - - hash[256] = 0; - hash[257] = 0; -} -#endif - void NTLMSSPcalc( unsigned char hash[258], unsigned char *data, int len) { unsigned char index_i = hash[256]; -- cgit From fb556e14f3b47d5a1f465589084e8b30d84af8ca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Oct 1998 08:08:05 +0000 Subject: volker was concerned about unique inode numbers and smbsh. This set of changes uses the unique index number from a SMB_QUERY_FILE_ALL_INFO to try to provide inode numbers. If it is 0 then use the hash of the filename as before. (This used to be commit 2565ccf9de9d5e80fdb5bcadbc7130faba386d95) --- source3/libsmb/clientgen.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d3233f59fd..6a0818d177 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1669,7 +1669,8 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint32 *mode) + time_t *w_time, size_t *size, uint32 *mode, + SMB_INO_T *ino) { int data_len = 0; int param_len = 0; @@ -1721,6 +1722,9 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, if (mode) { *mode = IVAL(rdata, 32); } + if (ino) { + *ino = IVAL(rdata, 64); + } if (rdata) free(rdata); if (rparam) free(rparam); @@ -1733,7 +1737,8 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, uint32 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time) + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino) { int data_len = 0; int param_len = 0; @@ -1745,7 +1750,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, memset(param, 0, param_len); SSVAL(param, 0, fnum); - SSVAL(param, 2, SMB_INFO_STANDARD); + SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); if (!cli_send_trans(cli, SMBtrans2, NULL, 0, /* name, length */ @@ -1768,19 +1773,25 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, } if (c_time) { - *c_time = make_unix_date2(rdata+0); + *c_time = interpret_long_date(rdata+0) - cli->serverzone; } if (a_time) { - *a_time = make_unix_date2(rdata+4); + *a_time = interpret_long_date(rdata+8) - cli->serverzone; } if (m_time) { - *m_time = make_unix_date2(rdata+8); + *m_time = interpret_long_date(rdata+16) - cli->serverzone; + } + if (w_time) { + *w_time = interpret_long_date(rdata+24) - cli->serverzone; } if (size) { - *size = IVAL(rdata, 12); + *size = IVAL(rdata, 40); } if (mode) { - *mode = SVAL(rdata,l1_attrFile); + *mode = IVAL(rdata, 32); + } + if (ino) { + *ino = IVAL(rdata, 64); } if (rdata) free(rdata); -- cgit From 4f2a6adb7cfee8de2c336cf926e29b720a1a8a47 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Oct 1998 03:31:00 +0000 Subject: added a couple more error codes to cli_error() (This used to be commit b2a7f85d597d4d2a71fd38d76aac0464d53df626) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6a0818d177..1e2869c0b8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2440,11 +2440,17 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRnoaccess: return EACCES; case ERRfilexists: return EEXIST; case ERRrename: return EEXIST; + case ERRbadshare: return EBUSY; + case ERRlock: return EBUSY; } } if (rcls == ERRSRV) { switch (code) { case ERRbadpw: return EPERM; + case ERRaccess: return EACCES; + case ERRnoresource: return ENOMEM; + case ERRinvdevice: return ENODEV; + case ERRinvnetname: return ENODEV; } } /* for other cases */ -- cgit From 099dae54dc944a6e0ec11c93e3004b2f097ea84d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 5 Nov 1998 12:42:16 +0000 Subject: don't bother trying QFILEINFO/QUERY_FILE_ALL_INFO with win95 as it totally screws it up, giving garbage for the size fields. (This used to be commit 86f98e0607e8a05ec026b919cc974c1c934b6882) --- source3/libsmb/clientgen.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1e2869c0b8..7168d9cd92 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1746,6 +1746,10 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, pstring param; char *rparam=NULL, *rdata=NULL; + /* if its a win95 server then fail this - win95 totally screws it + up */ + if (cli->win95) return False; + param_len = 4; memset(param, 0, param_len); @@ -1768,7 +1772,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return False; } - if (!rdata || data_len < 22) { + if (!rdata || data_len < 68) { return False; } -- cgit From 4bd1feb68c4f5134293d87433da932c20cded915 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Nov 1998 18:40:51 +0000 Subject: lib/charcnv.c: Improved debug comment. libsmb/namequery.c: Fix to remove 2 second wait is we are doing a unicast and got a reply. smbd/dfree.c: smbd/noquotas.c: smbd/quotas.c: Fixes from Dejan Ilic for the quota code. utils/smbpasswd.c: Fixes to allow smbpasswd to be called from swat. Jeremy. (This used to be commit b5981c0149ad8c6f13ea87db450080616538b5d5) --- source3/libsmb/namequery.c | 117 ++++++++++++++++++++++++++------------------- 1 file changed, 69 insertions(+), 48 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e95302fcd0..0e92e6b5dd 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -247,60 +247,81 @@ struct in_addr *name_query(int fd,char *name,int name_type, BOOL bcast,BOOL recu retries--; while (1) + { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) break; - if (!found && !send_packet(&p)) - return NULL; - GetTimeOfDay(&tval); - retries--; - } + if (!retries) + break; + if (!found && !send_packet(&p)) + return NULL; + GetTimeOfDay(&tval); + retries--; + } - if ((p2=receive_packet(fd,NMB_PACKET,90))) - { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); + if ((p2=receive_packet(fd,NMB_PACKET,90))) + { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) { - /* its not for us - maybe deal with it later - (put it on the queue?) */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || + !nmb2->header.response) + { + /* + * Its not for us - maybe deal with it later + * (put it on the queue?). + */ + if (fn) + fn(p2); + else + free_packet(p2); + continue; + } - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount) { - /* XXXX what do we do with this? could be a redirect, but - we'll discard it for the moment */ - free_packet(p2); - continue; - } + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount) + { + /* + * XXXX what do we do with this? Could be a redirect, but + * we'll discard it for the moment. + */ + free_packet(p2); + continue; + } - ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) * - ((*count)+nmb2->answers->rdlength/6)); - if (ip_list) { - DEBUG(fn?3:2,("Got a positive name query response from %s ( ", - inet_ntoa(p2->ip))); - for (i=0;ianswers->rdlength/6;i++) { - putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUG(fn?3:2,("%s ",inet_ntoa(ip_list[(*count)]))); - (*count)++; - } - DEBUG(fn?3:2,(")\n")); - } - found=True; retries=0; - free_packet(p2); - if (fn) break; - } + ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) * + ((*count)+nmb2->answers->rdlength/6)); + if (ip_list) + { + DEBUG(fn?3:2,("Got a positive name query response from %s ( ", + inet_ntoa(p2->ip))); + for (i=0;ianswers->rdlength/6;i++) + { + putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); + DEBUG(fn?3:2,("%s ",inet_ntoa(ip_list[(*count)]))); + (*count)++; + } + DEBUG(fn?3:2,(")\n")); + } + + found=True; + retries=0; + free_packet(p2); + if (fn) + break; + + /* + * If we're doing a unicast lookup we only + * expect one reply. Don't wait the full 2 + * seconds if we got one. JRA. + */ + if(!bcast && found) + break; } + } return ip_list; } -- cgit From 8c62b28e0ef1e012ebb0713701916d82ffc7661e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 9 Nov 1998 03:45:49 +0000 Subject: converted smbclient to use clientgen.c rather than clientutil.c I did this when I saw yet another bug report complaining about smbclient intermittently missing files. Rather than applying more patches to smbclient it was better to move to the more robust clientgen.c code. The conversion wasn't perfect, I probably lost some features of smbclient while doing it, but at least smbclient should be consistent now. It if fails it should _always_ fail rather than giving people the false impression of a reliable utility. the tar stuff seems to work, but hasn't had much testing as I never use it myself. I'm sure someone will find bugs in my conversion of smbtar.c. It was quite tricky as it did a lot of its own SMB calls. It now uses clientgen.c exclusively. smbclient is still quite messy, but at least it doesn't build its own SMB packets. I haven't touched smbmount as I never use it. Mike, do you want to convert smbmount to use clientgen.c? (This used to be commit e14ca7765ace1b721dad8eca4a527a4e4a8f1ab8) --- source3/libsmb/clientgen.c | 234 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 199 insertions(+), 35 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7168d9cd92..650b9a27a3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -28,6 +28,14 @@ extern int DEBUGLEVEL; +/**************************************************************************** +recv an smb +****************************************************************************/ +static BOOL cli_receive_smb(struct cli_state *cli) +{ + return client_receive_smb(cli->fd,cli->inbuf,cli->timeout); +} + /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ @@ -256,7 +264,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout) || + if (!cli_receive_smb(cli) || CVAL(cli->inbuf,smb_rcls) != 0) { return(False); } @@ -317,7 +325,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, *data_len = *param_len = 0; - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); @@ -371,7 +379,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (total_data <= *data_len && total_param <= *param_len) break; - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); @@ -752,7 +760,7 @@ BOOL cli_session_setup(struct cli_state *cli, } cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); @@ -783,7 +791,7 @@ BOOL cli_ulogoff(struct cli_state *cli) SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; return CVAL(cli->inbuf,smb_rcls) == 0; @@ -836,7 +844,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; if (CVAL(cli->inbuf,smb_rcls) != 0) { @@ -877,7 +885,7 @@ BOOL cli_tdis(struct cli_state *cli) cli_setup_packet(cli); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; return CVAL(cli->inbuf,smb_rcls) == 0; @@ -909,7 +917,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) pstrcpy(p,fname_dst); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -943,7 +951,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) pstrcpy(p,fname); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -975,7 +983,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) pstrcpy(p,dname); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1007,7 +1015,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) pstrcpy(p,dname); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1052,7 +1060,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) p = skip_string(p,1); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return -1; } @@ -1075,7 +1083,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) /* you must open for RW not just write - otherwise getattrE doesn't work! */ - if ((flags & O_ACCMODE) == O_WRONLY) { + if ((flags & O_ACCMODE) == O_WRONLY && strncmp(cli->dev, "LPT", 3)) { flags = (flags & ~O_ACCMODE) | O_RDWR; } @@ -1123,7 +1131,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) p = skip_string(p,1); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return -1; } @@ -1155,7 +1163,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SIVALS(cli->outbuf,smb_vwv1,-1); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1199,7 +1207,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { cli->timeout = saved_timeout; return False; } @@ -1242,7 +1250,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 6, len); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1305,7 +1313,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t issued++; } - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return total; } @@ -1341,7 +1349,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t } while (received < issued) { - client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + cli_receive_smb(cli); received++; } @@ -1395,8 +1403,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 0x0008 start of message mode named pipe protocol ****************************************************************************/ ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size) + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size) { int total = -1; int issued=0; @@ -1420,7 +1428,7 @@ ssize_t cli_write(struct cli_state *cli, issued++; } - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return total; } @@ -1446,7 +1454,7 @@ ssize_t cli_write(struct cli_state *cli, } while (received < issued) { - client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + cli_receive_smb(cli); received++; } @@ -1473,7 +1481,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1527,7 +1535,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, pstrcpy(p+1, fname); cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1578,7 +1586,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) *p = 4; cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + if (!cli_receive_smb(cli)) { return False; } @@ -1914,7 +1922,8 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) /**************************************************************************** do a directory listing, calling fn on each file found ****************************************************************************/ -int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info *)) +int cli_list(struct cli_state *cli,const char *Mask,int attribute, + void (*fn)(file_info *, const char *)) { int max_matches = 512; /* NT uses 260, OS/2 uses 2. Both accept 1. */ @@ -2065,7 +2074,7 @@ int cli_list(struct cli_state *cli,char *Mask,int attribute,void (*fn)(file_info for (p=dirlist,i=0;ioutbuf),0) = 2; cli_send_smb(cli); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; show_msg(cli->inbuf); @@ -2284,7 +2293,7 @@ retry: cli_send_smb(cli); DEBUG(5,("Sent session request\n")); - if (!client_receive_smb(cli->fd,cli->inbuf,cli->timeout)) + if (!cli_receive_smb(cli)) return False; #ifdef WITH_SSL @@ -2336,14 +2345,18 @@ BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) /**************************************************************************** initialise a client structure ****************************************************************************/ -BOOL cli_initialise(struct cli_state *cli) +struct cli_state *cli_initialise(struct cli_state *cli) { - if (cli->initialised) - { + if (!cli) { + cli = (struct cli_state *)malloc(sizeof(*cli)); + if (!cli) return NULL; + } + + if (cli->initialised) { cli_shutdown(cli); } - memset(cli, 0, sizeof(*cli)); + ZERO_STRUCTP(cli); cli->fd = -1; cli->cnum = -1; @@ -2363,7 +2376,7 @@ BOOL cli_initialise(struct cli_state *cli) cli->initialised = 1; - return True; + return cli; } /**************************************************************************** @@ -2773,3 +2786,154 @@ int cli_print_queue(struct cli_state *cli, return i; } + +/**************************************************************************** +check for existance of a dir +****************************************************************************/ +BOOL cli_chkpath(struct cli_state *cli, char *path) +{ + fstring path2; + char *p; + + fstrcpy(path2,path); + trim_string(path2,NULL,"\\"); + if (!*path2) *path2 = '\\'; + + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,0,4 + strlen(path2),True); + SCVAL(cli->outbuf,smb_com,SMBchkpth); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + fstrcpy(p,path2); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL)) return False; + + return True; +} + + +/**************************************************************************** +start a message sequence +****************************************************************************/ +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp) +{ + char *p; + + /* send a SMBsendstrt command */ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBsendstrt; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + pstrcpy(p,username); + p = skip_string(p,1); + *p++ = 4; + pstrcpy(p,host); + p = skip_string(p,1); + + set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL)) return False; + + *grp = SVAL(cli->inbuf,smb_vwv0); + + return True; +} + + +/**************************************************************************** +send a message +****************************************************************************/ +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +{ + char *p; + + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,1,len+3,True); + CVAL(cli->outbuf,smb_com) = SMBsendtxt; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,grp); + + p = smb_buf(cli->outbuf); + *p = 1; + SSVAL(p,1,len); + memcpy(p+3,msg,len); + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL)) return False; + + return True; +} + +/**************************************************************************** +end a message +****************************************************************************/ +BOOL cli_message_end(struct cli_state *cli, int grp) +{ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,1,0,True); + CVAL(cli->outbuf,smb_com) = SMBsendend; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + + SSVAL(cli->outbuf,smb_vwv0,grp); + + cli_setup_packet(cli); + + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL)) return False; + + return True; +} + + +/**************************************************************************** +query disk space +****************************************************************************/ +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) +{ + bzero(cli->outbuf,smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBdskattr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2); + *total = SVAL(cli->inbuf,smb_vwv0); + *avail = SVAL(cli->inbuf,smb_vwv3); + + return True; +} -- cgit From e4f974c611c179a5e7827ec8325e01811db6540b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Nov 1998 20:33:37 +0000 Subject: Makefile.in: Removed rpc_server/srv_ldap_helpers.c per J.F.'s instructions. client/client.c: client/clitar.c: include/client.h: smbwrapper/smbw_dir.c: smbwrapper/smbw_stat.c: smbwrapper/smbw.c: lib/util.c: Converted all use of 'mode' to uint16. smbd/quotas.c: Fixed stupid comment bug I put in there :-(. printing/printing.c: Fix from J.F. to new code. Jeremy. (This used to be commit bacd3e9d2036a804e73644a28fc498f229c8446c) --- source3/libsmb/clientgen.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 650b9a27a3..fc4c7f1d5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1466,7 +1466,7 @@ ssize_t cli_write(struct cli_state *cli, do a SMBgetattrE call ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - uint32 *attr, size_t *size, + uint16 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { bzero(cli->outbuf,smb_size); @@ -1517,7 +1517,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, do a SMBgetatr call ****************************************************************************/ BOOL cli_getatr(struct cli_state *cli, char *fname, - uint32 *attr, size_t *size, time_t *t) + uint16 *attr, size_t *size, time_t *t) { char *p; @@ -1563,7 +1563,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, /**************************************************************************** do a SMBsetatr call ****************************************************************************/ -BOOL cli_setatr(struct cli_state *cli, char *fname, int attr, time_t t) +BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) { char *p; @@ -1602,7 +1602,7 @@ send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint32 *mode) + size_t *size, uint16 *mode) { int data_len = 0; int param_len = 0; @@ -1677,7 +1677,7 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint32 *mode, + time_t *w_time, size_t *size, uint16 *mode, SMB_INO_T *ino) { int data_len = 0; @@ -1724,12 +1724,12 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, if (w_time) { *w_time = interpret_long_date(rdata+24) - cli->serverzone; } + if (mode) { + *mode = SVAL(rdata, 32); + } if (size) { *size = IVAL(rdata, 40); } - if (mode) { - *mode = IVAL(rdata, 32); - } if (ino) { *ino = IVAL(rdata, 64); } @@ -1744,7 +1744,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint32 *mode, size_t *size, + uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { @@ -1796,12 +1796,12 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, if (w_time) { *w_time = interpret_long_date(rdata+24) - cli->serverzone; } + if (mode) { + *mode = SVAL(rdata, 32); + } if (size) { *size = IVAL(rdata, 40); } - if (mode) { - *mode = IVAL(rdata, 32); - } if (ino) { *ino = IVAL(rdata, 64); } @@ -1922,7 +1922,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) /**************************************************************************** do a directory listing, calling fn on each file found ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,int attribute, +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *)) { int max_matches = 512; -- cgit From 10a9addc222b29acdcfe6afed0597dd17551fa5c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 12 Nov 1998 04:17:54 +0000 Subject: Moved some code (NTLMSSPcalc) out of smbdes and inline for paranioa resons and my own piece of mind... Jeremy. (This used to be commit 45131501f23ce1eec2f23fe2c1060cd5a2736ec9) --- source3/libsmb/smbdes.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 5bff1742af..d0e1c6e85f 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -358,32 +358,6 @@ void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int for smbhash(out + 8, in + 8, key2, forw); } -void NTLMSSPcalc( unsigned char hash[258], unsigned char *data, int len) -{ - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; - int ind; - - for( ind = 0; ind < len; ind++) - { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] = data[ind] ^ hash[t]; - } - - hash[256] = index_i; - hash[257] = index_j; -} - void SamOEMhash( unsigned char *data, unsigned char *key, int val) { unsigned char s_box[256]; -- cgit From d85dcf86d59c14cb624bbb69b658fc6aba842593 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 Nov 1998 06:12:19 +0000 Subject: largely rewrote smbpasswd so that the code is understandable. This should allow us to call a function in swat rather than piping to smbpasswd. while doing this I also fixed quite a few "const char *" versus "char *" issues that cropped up while using const to track down bugs in the code. This led to changes in several generic functions. The smbpasswd changes should be correct but they have not been extensively tested. At least if I have introduced bugs then we should be able to fix them more easily than before. (This used to be commit 713864dd0322ae2ae2d83e333d85be35a7eed4ec) --- source3/libsmb/clientgen.c | 6 +++--- source3/libsmb/namequery.c | 12 ++++++------ source3/libsmb/nmblib.c | 2 +- source3/libsmb/smbencrypt.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fc4c7f1d5d..b4ca7a1d77 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2087,8 +2087,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, Send a SamOEMChangePassword command ****************************************************************************/ -BOOL cli_oem_change_password(struct cli_state *cli, char *user, char *new_password, - char *old_password) +BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, + const char *old_password) { char param[16+sizeof(fstring)]; char data[532]; @@ -2317,7 +2317,7 @@ retry: /**************************************************************************** open the client sockets ****************************************************************************/ -BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip) +BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern struct in_addr ipzero; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0e92e6b5dd..f06ecc94e4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -194,7 +194,7 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, returns an array of IP addresses or NULL if none *count will be set to the number of addresses returned ****************************************************************************/ -struct in_addr *name_query(int fd,char *name,int name_type, BOOL bcast,BOOL recurse, +struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *)) { BOOL found=False; @@ -440,7 +440,7 @@ void endlmhosts(FILE *fp) /******************************************************** resolve via "bcast" method *********************************************************/ -static BOOL resolve_bcast(char *name, struct in_addr *return_ip, int name_type) +static BOOL resolve_bcast(const char *name, struct in_addr *return_ip, int name_type) { int sock, i; @@ -486,7 +486,7 @@ static BOOL resolve_bcast(char *name, struct in_addr *return_ip, int name_type) /******************************************************** resolve via "wins" method *********************************************************/ -static BOOL resolve_wins(char *name, struct in_addr *return_ip, int name_type) +static BOOL resolve_wins(const char *name, struct in_addr *return_ip, int name_type) { int sock; struct in_addr wins_ip; @@ -536,7 +536,7 @@ static BOOL resolve_wins(char *name, struct in_addr *return_ip, int name_type) /******************************************************** resolve via "lmhosts" method *********************************************************/ -static BOOL resolve_lmhosts(char *name, struct in_addr *return_ip, int name_type) +static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int name_type) { /* * "lmhosts" means parse the local lmhosts file. @@ -566,7 +566,7 @@ static BOOL resolve_lmhosts(char *name, struct in_addr *return_ip, int name_type /******************************************************** resolve via "hosts" method *********************************************************/ -static BOOL resolve_hosts(char *name, struct in_addr *return_ip) +static BOOL resolve_hosts(const char *name, struct in_addr *return_ip) { /* * "host" means do a localhost, or dns lookup. @@ -589,7 +589,7 @@ static BOOL resolve_hosts(char *name, struct in_addr *return_ip) or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. *********************************************************/ -BOOL resolve_name(char *name, struct in_addr *return_ip, int name_type) +BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) { int i; BOOL pure_address = True; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 87f483e9fd..6314a9076b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -762,7 +762,7 @@ static int build_dgram(char *buf,struct packet_struct *p) /******************************************************************* build a nmb name *******************************************************************/ -void make_nmb_name( struct nmb_name *n, char *name, int type, char *this_scope ) +void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope ) { memset( (char *)n, '\0', sizeof(struct nmb_name) ); StrnCpy( n->name, name, 15 ); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 5017b33c07..9234088404 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -190,7 +190,7 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) #endif } -BOOL make_oem_passwd_hash(char data[516], char *passwd, uchar old_pw_hash[16], BOOL unicode) +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) { int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); -- cgit From 29e36b713468d7e7de301c483fc340ef42b4a9fb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 Nov 1998 07:06:48 +0000 Subject: extracted the password change code from smbpasswd and used it in swat instead of opening pipes and other horrible stuff. (This used to be commit 49bf19710345a59a2d17cd449be1a132885ed821) --- source3/libsmb/passchange.c | 100 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 source3/libsmb/passchange.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c new file mode 100644 index 0000000000..7d89cbd3d7 --- /dev/null +++ b/source3/libsmb/passchange.c @@ -0,0 +1,100 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB client password change routine + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +extern pstring global_myname; +extern pstring scope; + +/************************************************************* +change a password on a remote machine using IPC calls +*************************************************************/ +BOOL remote_password_change(const char *remote_machine, const char *user_name, + const char *old_passwd, const char *new_passwd) +{ + struct nmb_name calling, called; + struct cli_state cli; + struct in_addr ip; + + if(!resolve_name( remote_machine, &ip, 0x20)) { + fprintf(stderr, "unable to find an IP address for machine %s.\n", + remote_machine ); + return False; + } + + ZERO_STRUCT(cli); + + if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { + fprintf(stderr, "unable to connect to SMB server on machine %s. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + return False; + } + + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + if (!cli_session_request(&cli, &calling, &called)) { + fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + cli.protocol = PROTOCOL_NT1; + + if (!cli_negprot(&cli)) { + fprintf(stderr, "machine %s rejected the negotiate protocol. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + /* + * We should connect as the anonymous user here, in case + * the server has "must change password" checked... + * Thanks to for this fix. + */ + + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + fprintf(stderr, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + fprintf(stderr, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + cli_shutdown(&cli); + return True; +} -- cgit From d30b6ab54847164aa3add34f3b50132af58f9453 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 12 Nov 1998 22:17:51 +0000 Subject: .cvsignore: Removed old entries. client/client.c: include/client.h: Added some debug messages that the old client used to generate. These are needed to make scripts such as 'findsmb' work - there may be other changes to keep backwards output compatibility. Do we need a -old-client-compat argument ? libsmb/clientgen.c: Fixed crash bug where malloc'ed data wasn't being cleared - corrupted malloc chains. web/swat.c: John's changes to get rid of "ghost" table entries. (This used to be commit 3c45a3503ea57d17e98eb3e57514161a5c82e45e) --- source3/libsmb/clientgen.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b4ca7a1d77..4eaebfa6ed 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -772,6 +772,20 @@ BOOL cli_session_setup(struct cli_state *cli, /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); + if (cli->protocol >= PROTOCOL_NT1) { + /* + * Save off some of the connected server + * info. + */ + char *server_domain,*server_os,*server_type; + server_os = smb_buf(cli->inbuf); + server_type = skip_string(server_os,1); + server_domain = skip_string(server_type,1); + fstrcpy(cli->server_os, server_os); + fstrcpy(cli->server_type, server_type); + fstrcpy(cli->server_domain, server_domain); + } + fstrcpy(cli->user_name, user); return True; @@ -2349,7 +2363,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) { if (!cli) { cli = (struct cli_state *)malloc(sizeof(*cli)); - if (!cli) return NULL; + if (!cli) + return NULL; + ZERO_STRUCTP(cli); } if (cli->initialised) { -- cgit From ea2fa33f6564389240c4b414e27065a4a01dcfbc Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 12 Nov 1998 23:49:32 +0000 Subject: Removed code that used printf/fprintf in password changin libraries. Now passes strings instead. (This used to be commit 48af29bcc9e8094de6ba057a52dbae3c80ea7a05) --- source3/libsmb/passchange.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 7d89cbd3d7..4cca1927fa 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -29,14 +29,15 @@ extern pstring scope; change a password on a remote machine using IPC calls *************************************************************/ BOOL remote_password_change(const char *remote_machine, const char *user_name, - const char *old_passwd, const char *new_passwd) + const char *old_passwd, const char *new_passwd, + char *err_str, size_t err_str_len) { struct nmb_name calling, called; struct cli_state cli; struct in_addr ip; if(!resolve_name( remote_machine, &ip, 0x20)) { - fprintf(stderr, "unable to find an IP address for machine %s.\n", + slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n", remote_machine ); return False; } @@ -44,7 +45,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, ZERO_STRUCT(cli); if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { - fprintf(stderr, "unable to connect to SMB server on machine %s. Error was : %s.\n", + slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); return False; } @@ -53,7 +54,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, make_nmb_name(&called , remote_machine, 0x20, scope); if (!cli_session_request(&cli, &calling, &called)) { - fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n", + slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); return False; @@ -62,7 +63,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, cli.protocol = PROTOCOL_NT1; if (!cli_negprot(&cli)) { - fprintf(stderr, "machine %s rejected the negotiate protocol. Error was : %s.\n", + slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); return False; @@ -75,21 +76,21 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, */ if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { - fprintf(stderr, "machine %s rejected the session setup. Error was : %s.\n", + slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); return False; } if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { - fprintf(stderr, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", + slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); return False; } if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { - fprintf(stderr, "machine %s rejected the password change: Error was : %s.\n", + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); return False; -- cgit From 24ca89bfb03fb82e975eff94070275ee403cd0f9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 14 Nov 1998 01:04:13 +0000 Subject: Removed acconfig.h configure configure.in include/config.h.in: Made smbwrapper not made by default. nmbd*: Changed all calls to namestr() to nmbd_namestr() to fix broken FreeBSD include file problem...sigh. Jeremy. (This used to be commit 9ee8f39aed8772a05c203161b4ae6b7d90d67481) --- source3/libsmb/clientgen.c | 6 +++--- source3/libsmb/nmblib.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4eaebfa6ed..81f75d2cb2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2541,7 +2541,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) fstrcpy(dest_host, cli->full_dest_host_name); DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", - namestr(&calling), namestr(&called), + nmb_namestr(&calling), nmb_namestr(&called), inet_ntoa(cli->dest_ip), cli->user_name, cli->domain)); @@ -2571,7 +2571,7 @@ BOOL cli_establish_connection(struct cli_state *cli, BOOL do_shutdown, BOOL do_tcon) { DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - namestr(calling), namestr(called), inet_ntoa(*dest_ip), + nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), cli->user_name, cli->domain)); /* establish connection */ @@ -2586,7 +2586,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (!cli_connect(cli, dest_host, dest_ip)) { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - namestr(calling), inet_ntoa(*dest_ip))); + nmb_namestr(calling), inet_ntoa(*dest_ip))); return False; } } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6314a9076b..b91a2944a3 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -66,7 +66,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", hdr, - namestr(&res->rr_name), + nmb_namestr(&res->rr_name), res->rr_type, res->rr_class, res->ttl ) ); @@ -131,7 +131,7 @@ void debug_nmb_packet(struct packet_struct *p) if (nmb->header.qdcount) { DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", - namestr(&nmb->question.question_name), + nmb_namestr(&nmb->question.question_name), nmb->question.question_type, nmb->question.question_class) ); } @@ -289,7 +289,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) /******************************************************************* useful for debugging messages ******************************************************************/ -char *namestr(struct nmb_name *n) +char *nmb_namestr(struct nmb_name *n) { static int i=0; static fstring ret[4]; -- cgit From 3ba68d045c4f1f2c6dea014d11189cbabc3e0eb1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 14 Nov 1998 04:16:07 +0000 Subject: automatically uppercase server and share names (win95 won't handle lowercase share names!) (This used to be commit dddf1d8522707b828cac466c4a9ab2807d098573) --- source3/libsmb/clientgen.c | 1 + source3/libsmb/nmblib.c | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 81f75d2cb2..550f7cc391 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -839,6 +839,7 @@ BOOL cli_send_tconX(struct cli_state *cli, slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); + strupper(fullshare); set_message(cli->outbuf,4, 2 + strlen(fullshare) + passlen + strlen(dev),True); diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b91a2944a3..7f3bcc9642 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -764,12 +764,12 @@ static int build_dgram(char *buf,struct packet_struct *p) *******************************************************************/ void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope ) { - memset( (char *)n, '\0', sizeof(struct nmb_name) ); - StrnCpy( n->name, name, 15 ); - strupper( n->name ); - n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, this_scope, 63 ); - strupper( n->scope ); + memset( (char *)n, '\0', sizeof(struct nmb_name) ); + StrnCpy( n->name, name, 15 ); + strupper( n->name ); + n->name_type = (unsigned int)type & 0xFF; + StrnCpy( n->scope, this_scope, 63 ); + strupper( n->scope ); } /******************************************************************* -- cgit From 13d0b57baa887f8b43b1ad2c41305e27b3528fbe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 16 Nov 1998 01:27:51 +0000 Subject: fixed lmhosts parsing. We were using sizeof(name) where name was char* (This used to be commit 67ba0b1ce335bc80e1c33fa28458ec9ebe5f446a) --- source3/libsmb/namequery.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f06ecc94e4..1398f7bc49 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -344,8 +344,7 @@ FILE *startlmhosts(char *fname) /******************************************************** Parse the next line in the lmhosts file. *********************************************************/ - -BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr) +BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) { pstring line; @@ -370,7 +369,7 @@ BOOL getlmhostsent( FILE *fp, char *name, int *name_type, struct in_addr *ipaddr if (next_token(&ptr,ip ,NULL,sizeof(ip))) ++count; - if (next_token(&ptr,name ,NULL, sizeof(name))) + if (next_token(&ptr,name ,NULL, sizeof(pstring))) ++count; if (next_token(&ptr,flags,NULL, sizeof(flags))) ++count; -- cgit From 74d539f5573a3ed3ff1b96c54752a389da4c3e14 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 17 Nov 1998 16:19:04 +0000 Subject: - group database API. oops and oh dear, the threat has been carried out: the pre-alpha "domain group" etc parameters have disappeared. - interactive debug detection - re-added mem_man (andrew's memory management, detects memory corruption) - american spellings of "initialise" replaced with english spelling of "initialise". - started on "lookup_name()" and "lookup_sid()" functions. proper ones. - moved lots of functions around. created some modules of commonly used code. e.g the password file locking code, which is used in groupfile.c and aliasfile.c and smbpass.c - moved RID_TYPE_MASK up another bit. this is really unfortunate, but there is no other "fast" way to identify users from groups from aliases. i do not believe that this code saves us anything (the multipliers) and puts us at a disadvantage (reduces the useable rid space). the designers of NT aren't silly: if they can get away with a user- interface-speed LsaLookupNames / LsaLookupSids, then so can we. i spoke with isaac at the cifs conference, the only time for example that they do a security context check is on file create. certainly not on individual file reads / writes, which would drastically hit their performance and ours, too. - renamed myworkgroup to global_sam_name, amongst other things, when used in the rpc code. there is also a global_member_name, as we are always responsible for a SAM database, the scope of which is limited by the role of the machine (e.g if a member of a workgroup, your SAM is for _local_ logins only, and its name is the name of your server. you even still have a SID. see LsaQueryInfoPolicy, levels 3 and 5). - updated functionality of groupname.c to be able to cope with names like DOMAIN\group and SERVER\alias. used this code to be able to do aliases as well as groups. this code may actually be better off being used in username mapping, too. - created a connect to serverlist function in clientgen.c and used it in password.c - initialisation in server.c depends on the role of the server. well, it does now. - rpctorture. smbtorture. EXERCISE EXTREME CAUTION. (This used to be commit 0d21e1e6090b933f396c764af535ca3388a562db) --- source3/libsmb/clientgen.c | 199 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 150 insertions(+), 49 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 550f7cc391..bb792b7e2b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -39,18 +39,27 @@ static BOOL cli_receive_smb(struct cli_state *cli) /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ -static BOOL cli_send_smb(struct cli_state *cli) +static BOOL cli_send_smb(struct cli_state *cli, BOOL show) { size_t len; size_t nwritten=0; ssize_t ret; BOOL reestablished=False; + if (show) + { + show_msg(cli->outbuf); + } + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0 && errno == EPIPE && !reestablished) { + if (ret <= 0 && errno == EPIPE && !reestablished) + { + DEBUG(5,("cli_send_smb: write error (%s) - reconnecting\n", + strerror(errno))); + if (cli_reestablish_connection(cli)) { reestablished = True; nwritten=0; @@ -60,8 +69,7 @@ static BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", len,ret)); - close_sockets(); - exit(1); + return False; } nwritten += ret; } @@ -259,8 +267,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ @@ -300,8 +307,7 @@ static BOOL cli_send_trans(struct cli_state *cli, int trans, set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); tot_data += this_ldata; tot_param += this_lparam; @@ -328,8 +334,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (!cli_receive_smb(cli)) return False; - show_msg(cli->inbuf); - /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -382,8 +386,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (!cli_receive_smb(cli)) return False; - show_msg(cli->inbuf); - /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -759,11 +761,12 @@ BOOL cli_session_setup(struct cli_state *cli, set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) + { + DEBUG(10,("cli_session_setup: receive smb failed\n")); return False; - - show_msg(cli->inbuf); + } if (CVAL(cli->inbuf,smb_rcls) != 0) { return False; @@ -804,7 +807,7 @@ BOOL cli_ulogoff(struct cli_state *cli) SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -858,7 +861,7 @@ BOOL cli_send_tconX(struct cli_state *cli, SCVAL(cli->inbuf,smb_rcls, 1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -899,7 +902,7 @@ BOOL cli_tdis(struct cli_state *cli) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) return False; @@ -931,7 +934,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) *p++ = 4; pstrcpy(p,fname_dst); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -965,7 +968,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) *p++ = 4; pstrcpy(p,fname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -997,7 +1000,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1029,7 +1032,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) *p++ = 4; pstrcpy(p,dname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1074,7 +1077,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) pstrcpy(p,fname); p = skip_string(p,1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return -1; } @@ -1145,7 +1148,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) pstrcpy(p,fname); p = skip_string(p,1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return -1; } @@ -1177,7 +1180,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SSVAL(cli->outbuf,smb_vwv0,fnum); SIVALS(cli->outbuf,smb_vwv1,-1); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1218,7 +1221,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli); + cli_send_smb(cli, True); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1264,7 +1267,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1300,7 +1303,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli); + cli_send_smb(cli, True); } /**************************************************************************** @@ -1406,8 +1409,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_mid,cli->mid + i); - show_msg(cli->outbuf); - cli_send_smb(cli); + cli_send_smb(cli, True); } /**************************************************************************** @@ -1495,7 +1497,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1549,7 +1551,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, *p = 4; pstrcpy(p+1, fname); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -1600,7 +1602,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) p = skip_string(p,1); *p = 4; - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -2163,13 +2165,14 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char data_len = 532; - if (cli_send_trans(cli,SMBtrans, + if (!cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ data,data_len,0 /* data, length, max */ - ) == False) { + )) + { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); return False; @@ -2223,11 +2226,11 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) + { return False; - - show_msg(cli->inbuf); + } if (CVAL(cli->inbuf,smb_rcls) != 0 || ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { @@ -2305,7 +2308,7 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - cli_send_smb(cli); + cli_send_smb(cli, False); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) @@ -2401,6 +2404,7 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { + DEBUG(10,("cli_shutdown\n")); if (cli->outbuf) { free(cli->outbuf); @@ -2414,7 +2418,9 @@ void cli_shutdown(struct cli_state *cli) sslutil_disconnect(cli->fd); #endif /* WITH_SSL */ if (cli->fd != -1) - close(cli->fd); + { + close(cli->fd); + } memset(cli, 0, sizeof(*cli)); } @@ -2429,10 +2435,18 @@ void cli_shutdown(struct cli_state *cli) ****************************************************************************/ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); + int flgs2; char rcls; int code; + if (!cli->initialised) + { + DEBUG(0,("cli_error: client state uninitialised!\n")); + return EINVAL; + } + + flgs2 = SVAL(cli->inbuf,smb_flg2); + if (eclass) *eclass = 0; if (num ) *num = 0; @@ -2671,7 +2685,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session setup\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } @@ -2682,19 +2698,104 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed tcon_X\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } } } if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return True; } +/**************************************************************************** + connect to one of multiple servers: don't care which +****************************************************************************/ +BOOL cli_connect_serverlist(struct cli_state *cli, char *p) +{ + extern pstring global_myname; + extern pstring scope; + fstring remote_machine; + struct in_addr dest_ip; + struct nmb_name calling, called; + BOOL connected_ok = True; + + ZERO_STRUCT(cli); + + if (!cli_initialise(cli)) + { + DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); + return False; + } + + /* + * Treat each name in the 'password server =' line as a potential + * PDC/BDC. Contact each in turn and try and authenticate. + */ + + while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) + { + standard_sub_basic(remote_machine); + strupper(remote_machine); + + if (!resolve_name( remote_machine, &dest_ip, 0x20)) + { + DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_machine)); + continue; + } + + if (ismyip(dest_ip)) + { + DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_machine)); + continue; + } + + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + pwd_set_nullpwd(&cli->pwd); + + if (!cli_establish_connection(cli, remote_machine, &dest_ip, + &calling, &called, + "IPC$", "IPC", + False, True)) + { + cli_shutdown(cli); + continue; + } + + if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", + remote_machine)); + cli_shutdown(cli); + continue; + } + + /* + * We have an anonymous connection to IPC$. + */ + + connected_ok = True; + break; + } + + if (!connected_ok) + { + DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n")); + cli_shutdown(cli); + } + + return connected_ok; +} + /**************************************************************************** cancel a print job ****************************************************************************/ @@ -2826,7 +2927,7 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) *p++ = 4; fstrcpy(p,path2); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } @@ -2862,7 +2963,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2895,7 +2996,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) *p = 1; SSVAL(p,1,len); memcpy(p+3,msg,len); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2920,7 +3021,7 @@ BOOL cli_message_end(struct cli_state *cli, int grp) cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; @@ -2943,7 +3044,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli); + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return False; } -- cgit From 768761820e8d7481c586c4e0ab4ac7cb36d18c4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 17 Nov 1998 20:50:07 +0000 Subject: Added the same open()/fopen()/creat()/mmap() -> sys_XXX calls. Tidied up some of the mess (no other word for it). Still doesn't compile cleanly. There are calls with incorrect parameters that don't seem to be doing the right thing. This code still needs surgery :-(. Jeremy. (This used to be commit 18ff93a9abbf68ee8c59c0af3e57c63e4a015dac) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1398f7bc49..149b977746 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -332,7 +332,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO FILE *startlmhosts(char *fname) { - FILE *fp = fopen(fname,"r"); + FILE *fp = sys_fopen(fname,"r"); if (!fp) { DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", fname, strerror(errno))); -- cgit From e204f1d8a3f54cb6bd8549b15a59af9a525b3392 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Nov 1998 04:15:23 +0000 Subject: Changes to make the default prefix /usr/local/samba - as it was in 1.9.18p10. acconfig.h configure configure.in include/config.h.in: Fixes to DEC OSF1. libsmb/nmblib.c: Fixes to nmbd jumps in scope names. Jeremy. (This used to be commit 5ad77769be85e6727319afb0f02e5d94c2f9f16f) --- source3/libsmb/nmblib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7f3bcc9642..14dc5ecee2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -218,10 +218,11 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na /* now the domain parts (if any) */ n = 0; - while ((m=ubuf[offset])) { + while (ubuf[offset]) { /* we can have pointers within the domain part as well */ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + m = ubuf[offset]; if (!got_pointer) ret += m+1; if (n) name->scope[n++] = '.'; if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0); -- cgit From b70700dba2f82d64f85bea51841081b0e4b6f9e9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 26 Nov 1998 06:35:25 +0000 Subject: Replaced ZERO_STRUCT() with ZERO_STRUCTP() in cli_connect_serverlist(). Fix by Matt Chapman (This used to be commit c44b418d6fd16a257af21f6b5b29b1cdf26015b7) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bb792b7e2b..d20ecfa1d9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2727,7 +2727,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) struct nmb_name calling, called; BOOL connected_ok = True; - ZERO_STRUCT(cli); + ZERO_STRUCTP(cli); if (!cli_initialise(cli)) { -- cgit From 7f63a310624c4a30a12a5dac0f94e68102491e6e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 30 Nov 1998 15:32:15 +0000 Subject: andrej spotted problem with connect_serverlist (starts off assuming a connection succeeds...). (This used to be commit c0efc35b27d50c40bc04bfd9fb1d61ea5d32bde5) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d20ecfa1d9..fc0df84d4a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2725,7 +2725,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) fstring remote_machine; struct in_addr dest_ip; struct nmb_name calling, called; - BOOL connected_ok = True; + BOOL connected_ok = False; ZERO_STRUCTP(cli); -- cgit From b31c5281461fa42d277be7403d860feae96f2a9f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 30 Nov 1998 16:00:27 +0000 Subject: another attempt at a fix on connect_serverlist()... (This used to be commit 603c5f6df8c525f30d00da912d408b98378ea538) --- source3/libsmb/clientgen.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fc0df84d4a..5f6408bad1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2727,14 +2727,6 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) struct nmb_name calling, called; BOOL connected_ok = False; - ZERO_STRUCTP(cli); - - if (!cli_initialise(cli)) - { - DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); - return False; - } - /* * Treat each name in the 'password server =' line as a potential * PDC/BDC. Contact each in turn and try and authenticate. @@ -2742,6 +2734,14 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { + ZERO_STRUCTP(cli); + + if (!cli_initialise(cli)) + { + DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); + return False; + } + standard_sub_basic(remote_machine); strupper(remote_machine); -- cgit From 90ce7b9288f23cbf0fe3ce2aecb0b11d283ed531 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 2 Dec 1998 20:03:08 +0000 Subject: ERRmoredata is an acceptable error code, it is not an error. (This used to be commit 9bce7340d60a49594f67cc3c6cc6119b33a5358a) --- source3/libsmb/clientgen.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5f6408bad1..99d868e216 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -328,6 +328,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, int total_data=0; int total_param=0; int this_data,this_param; + uint8 eclass; + uint32 num; *data_len = *param_len = 0; @@ -342,7 +344,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, return(False); } - if (cli_error(cli, NULL, NULL)) + /* DOS error "more data" is an acceptable error code */ + if (cli_error(cli, &eclass, &num) && eclass != ERRDOS && num != ERRmoredata) { return(False); } @@ -393,7 +396,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_error(cli, NULL, NULL)) + /* DOS error "more data" is an acceptable error code */ + if (cli_error(cli, &eclass, &num) && eclass != ERRDOS && num != ERRmoredata) { return(False); } -- cgit From 74576a48fdf71e4264a892fda58302053f809670 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 9 Dec 1998 16:28:04 +0000 Subject: adding some enumerate services code, client and server. (This used to be commit dacf5b152bf74cc3ee9a816911384a5eb0e77afa) --- source3/libsmb/smberr.c | 65 +++++++++++++++++++++++++++++-------------------- 1 file changed, 39 insertions(+), 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index c2d8884d73..4fd9165c69 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -147,35 +147,48 @@ struct /**************************************************************************** return a SMB error string from a SMB buffer ****************************************************************************/ -char *smb_errstr(char *inbuf) +char *smb_err_msg(uint8 class, uint32 num) { - static pstring ret; - int class = CVAL(inbuf,smb_rcls); - int num = SVAL(inbuf,smb_err); - int i,j; + static pstring ret; + int i,j; - for (i=0;err_classes[i].class;i++) - if (err_classes[i].code == class) - { - if (err_classes[i].err_msgs) - { - err_code_struct *err = err_classes[i].err_msgs; - for (j=0;err[j].name;j++) - if (num == err[j].code) + for (i=0;err_classes[i].class;i++) + { + if (err_classes[i].code == class) { - if (DEBUGLEVEL > 0) - slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class, - err[j].name,err[j].message); - else - slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name); - return ret; + err_code_struct *err = err_classes[i].err_msgs; + if (err != NULL) + { + for (j=0;err[j].name;j++) + { + if (num == err[j].code) + { + if (DEBUGLEVEL > 0) + { + slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class, + err[j].name,err[j].message); + } + else + { + slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name); + } + return ret; + } + } + } + } - } - slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num); - return ret; - } - - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); - return(ret); + slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class, num); + return ret; + } + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); + return(ret); +} +/**************************************************************************** +return a SMB error string from a SMB buffer +****************************************************************************/ +char *smb_errstr(char *inbuf) +{ + return smb_err_msg(CVAL(inbuf,smb_rcls), SVAL(inbuf,smb_err)); } -- cgit From a971a74717f1a9d8c966c623b735e079da2f67ae Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 9 Dec 1998 18:59:12 +0000 Subject: bugfix in smb_err_msg (This used to be commit 870bccb174337dec5cc14a5e7740662de56e629c) --- source3/libsmb/smberr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 4fd9165c69..85827dde28 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -176,11 +176,10 @@ char *smb_err_msg(uint8 class, uint32 num) } } } - + slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class, num); + return ret; } - slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class, num); - return ret; } slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); return(ret); -- cgit From e67a8d9d984dbdef307294358d7d9a7f4314ea09 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 14 Dec 1998 21:22:59 +0000 Subject: server_cryptkey() now calling cli_connectserverlist(). stupid microsoft idiotic *SMBSERVER connectionism added to cli_connect_serverlist(). also added check for protocol < LANMAN2. (This used to be commit c2bcb3a286f22ed4f0f55da2a3eb2bff17906fb1) --- source3/libsmb/clientgen.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 99d868e216..5bae8ffa81 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2728,7 +2728,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) extern pstring scope; fstring remote_machine; struct in_addr dest_ip; - struct nmb_name calling, called; + struct nmb_name calling, called, stupid_smbserver_called; BOOL connected_ok = False; /* @@ -2763,19 +2763,28 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) make_nmb_name(&calling, global_myname , 0x0 , scope); make_nmb_name(&called , remote_machine, 0x20, scope); + /* stupid microsoft destruction of the ability of netbios + * to provide multiple netbios servers on one host. + */ + make_nmb_name(&stupid_smbserver_called , "*SMBSERVER", 0x20, scope); pwd_set_nullpwd(&cli->pwd); if (!cli_establish_connection(cli, remote_machine, &dest_ip, &calling, &called, "IPC$", "IPC", + False, True) && + !cli_establish_connection(cli, remote_machine, &dest_ip, + &calling, &stupid_smbserver_called, + "IPC$", "IPC", False, True)) { cli_shutdown(cli); continue; } - if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + if (cli->protocol < PROTOCOL_LANMAN2 || + !IS_BITS_SET_ALL(cli->sec_mode, 1)) { DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", remote_machine)); -- cgit From 2cc786548b4460525ce2e0bf09209eee48a5ea08 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Fri, 15 Jan 1999 05:09:36 +0000 Subject: eclass != ERRDOS && num != ERRmoredata is not the same as !(eclass == ERRDOS && num == ERRmoredata) This was causing smbclient to segfault on receiving certain errors. (This used to be commit 15bd172530af360cf16ad626330dfe2ea92100df) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5bae8ffa81..688764fa73 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -345,7 +345,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, } /* DOS error "more data" is an acceptable error code */ - if (cli_error(cli, &eclass, &num) && eclass != ERRDOS && num != ERRmoredata) + if (cli_error(cli, &eclass, &num) && !(eclass == ERRDOS && num == ERRmoredata)) { return(False); } -- cgit From b4e34006e88308aa0f315648992a15501399cf10 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Mon, 18 Jan 1999 01:35:43 +0000 Subject: In security=user mode we must allow cli_connect_serverlist to connect to our own smbd process, rather than complaining about a password server loop. (This used to be commit 63d7822b9d87d085194de6895d3e271cedcd3c9a) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 688764fa73..e269011402 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2755,7 +2755,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) continue; } - if (ismyip(dest_ip)) + if ((lp_security() != SEC_USER) && (ismyip(dest_ip))) { DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_machine)); continue; -- cgit From f5f913b001ab66c2266e3325f8c91af2486116a2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 25 Jan 1999 01:46:14 +0000 Subject: Putting back the -p flag in smbclient. However, it seems that the -s flag in smbclient is also ignored :-( (This used to be commit f6c78192664d611d4663ed7459a2789315861eec) --- source3/libsmb/clientgen.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e269011402..a1a5bbf0a9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -27,6 +27,19 @@ extern int DEBUGLEVEL; +/* + * set the port that will be used for connections by the client + */ + +int cli_set_port(struct cli_state *cli, int port) +{ + + if (port != 0) + cli -> port = port; + + return cli -> port; /* return it incase caller wants it */ + +} /**************************************************************************** recv an smb @@ -2355,8 +2368,10 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } + if (cli -> port == 0) cli -> port = 139; + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - 139, cli->timeout); + cli -> port, cli->timeout); if (cli->fd == -1) return False; @@ -2382,6 +2397,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) ZERO_STRUCTP(cli); + cli -> port = 0; cli->fd = -1; cli->cnum = -1; cli->pid = (uint16)getpid(); -- cgit From 4af8d7aa2925569d55f33b2844882089c5569691 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 27 Jan 1999 00:08:33 +0000 Subject: - got client code cleartext passwords working again in cli_session_setup. needed this for some tests. - removed code that said "if lm password is not encrypted then encrypt both lm and nt passwords". actually it said "if lm password length is not 24 bytes and we're in security=user mode..." it didn't bother to check whether the nt password was NULL or not, and doing the encryption inside cli_session_setup is the wrong place. - checked all instances where cli_session_setup is called with cleartext passwords that are expected to then be encrypted (see above) with the test "if pwlen != 24...". there was only one: all the others either provide encrypted passwords, do null sessions or use cli_establish_connection. * recommendation: use cli_establish_connection() in smbwrapper/smbw.c (This used to be commit 2a509e9606f8aefbefa6e7b49878726464dbed44) --- source3/libsmb/clientgen.c | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a1a5bbf0a9..428f8e237f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -696,36 +696,42 @@ BOOL cli_session_setup(struct cli_state *cli, fstring pword, ntpword; if (cli->protocol < PROTOCOL_LANMAN1) + { return True; + } - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) + { return False; } - if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { - /* Null session connect. */ - pword[0] = '\0'; - ntpword[0] = '\0'; - } else { - if ((cli->sec_mode & 2) && passlen != 24) { - passlen = 24; - ntpasslen = 24; - SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); - SMBNTencrypt((uchar *)ntpass,(uchar *)cli->cryptkey,(uchar *)ntpword); - } else { - fstrcpy(pword, pass); - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - } - - /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { + if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + /* if in share level security then don't send a password now */ fstrcpy(pword, ""); passlen=1; fstrcpy(ntpword, ""); ntpasslen=1; } + else if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) + { + /* Null session connect. */ + pword[0] = '\0'; + ntpword[0] = '\0'; + } + else if (passlen == 24 && ntpasslen == 24) + { + /* encrypted password send, implicit from 24-byte lengths */ + memcpy(pword, pass, 24); + memcpy(ntpword, ntpass, 24); + } + else + { + /* plain-text password send */ + fstrcpy(pword, pass); + fstrcpy(ntpword, ""); + ntpasslen = 0; + } /* send a session setup command */ bzero(cli->outbuf,smb_size); -- cgit From deb61cb44b846951fe2c3343fd1b92510be9a9f0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 28 Jan 1999 18:40:53 +0000 Subject: returned cli_session_setup to previous behaviour. added a couple of validation checks and also added capability to send plaintext passwords. send "ntpasslen" of zero to do this. sending same plaintext password for pass and ntpass arguments will result in previous behaviour of encrypting password if server supports it. (This used to be commit 17f4c5a785cf20901bcb76510e5ea9b0a6928115) --- source3/libsmb/clientgen.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 428f8e237f..a43731ffcc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -713,25 +713,40 @@ BOOL cli_session_setup(struct cli_state *cli, fstrcpy(ntpword, ""); ntpasslen=1; } - else if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) + else if ((passlen == 0 || passlen == 1) && (pass[0] == '\0')) { /* Null session connect. */ - pword[0] = '\0'; + pword [0] = '\0'; ntpword[0] = '\0'; } else if (passlen == 24 && ntpasslen == 24) { - /* encrypted password send, implicit from 24-byte lengths */ - memcpy(pword, pass, 24); - memcpy(ntpword, ntpass, 24); + if (IS_BITS_SET_ALL(cli->sec_mode, 2)) + { + /* encrypted password, implicit from 24-byte lengths */ + memcpy(pword , pass , 24); + memcpy(ntpword, ntpass, 24); + } + else + { + DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n")); + return False; + } } - else + else if (ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2)) { - /* plain-text password send */ + /* plain-text password: server doesn't support encrypted. */ fstrcpy(pword, pass); fstrcpy(ntpword, ""); ntpasslen = 0; } + else /* passlen != 0 && ntpasslen != 0 && server supports encryption */ + { + /* plain-text password requesting to be encrypted */ + uchar *key = (uchar *)cli->cryptkey; + SMBencrypt ((uchar *)pass , key,(uchar *)pword ); + SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); + } /* send a session setup command */ bzero(cli->outbuf,smb_size); -- cgit From 1cf9521b2de9a6053c658329d54fe178be94de19 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Mon, 1 Feb 1999 05:25:54 +0000 Subject: Must set password length to 24 after we encrypt a password. (This used to be commit af83778abc5fae0df53ed1874181e33bc8de8d94) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a43731ffcc..d40c95b9c1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -746,6 +746,8 @@ BOOL cli_session_setup(struct cli_state *cli, uchar *key = (uchar *)cli->cryptkey; SMBencrypt ((uchar *)pass , key,(uchar *)pword ); SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); + passlen = 24; + ntpasslen = 24; } /* send a session setup command */ -- cgit From 99a9b0f7c4f85f46102457cf4707e8948b77fb3f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 8 Feb 1999 23:40:49 +0000 Subject: UNICODE byte ordering issue: typecast to uint16* replaced with SSVAL() (This used to be commit 9084b7e33dfe717bd8d5604ee71d137e3baef0f5) --- source3/libsmb/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 9234088404..dd801e5982 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -209,7 +209,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ generate_random_buffer((unsigned char *)data, 516, False); if (unicode) { - struni2( (uint16*)(&data[512 - new_pw_len]), passwd); + struni2( &data[512 - new_pw_len], passwd); } else { -- cgit From c6d16eea4394ff1c4d12cb435eebb0686b5ee736 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 11 Feb 1999 18:50:13 +0000 Subject: the UNICODE issue... (This used to be commit 73db80f34183324845407b00f58462ff2d7b47ea) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d40c95b9c1..60498c8fb2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -226,7 +226,7 @@ static char *fix_char_ptr(unsigned int datap, unsigned int converter, /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ -static BOOL cli_send_trans(struct cli_state *cli, int trans, +BOOL cli_send_trans(struct cli_state *cli, int trans, char *name, int pipe_name_len, int fid, int flags, uint16 *setup, int lsetup, int msetup, diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index dd801e5982..ead34aaa3d 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -209,7 +209,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ generate_random_buffer((unsigned char *)data, 516, False); if (unicode) { - struni2( &data[512 - new_pw_len], passwd); + str_to_unistr8( &data[512 - new_pw_len], passwd); } else { -- cgit From fd96929ec1fa27e0affd4c4e9ba307c4ee30b978 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Fri, 12 Feb 1999 00:16:09 +0000 Subject: UNICODE cleanup (see lib/util_unistr.c). No more ugly static library buffers and all functions take a destination string length (especially unistrcpy was rather dangerous; we were only saved by the fact that datagrams are limited in size). (This used to be commit a1d39af1ce1d451b811dbd7c2ba391214851b87e) --- source3/libsmb/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ead34aaa3d..e35cccd734 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -209,7 +209,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ generate_random_buffer((unsigned char *)data, 516, False); if (unicode) { - str_to_unistr8( &data[512 - new_pw_len], passwd); + ascii_to_unibuf(&data[512 - new_pw_len], passwd, new_pw_len); } else { -- cgit From 236cea4efa18094c3445bee310195ac12b6073ee Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 1 Mar 1999 16:31:14 +0000 Subject: Benjamin Kuit's MYSQL SAM Database implementation. Copyright (C) Benjamin Kuit 1999. (This used to be commit fdf61e1dabc2c977ee5cf1e9d60e3380f19840da) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 60498c8fb2..e188cb3b99 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -679,6 +679,8 @@ prots[] = {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, +#if 0 +#endif {-1,NULL} }; -- cgit From b5a5236f207867d52acb8573d69c92a7691b2d3f Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Fri, 19 Mar 1999 15:09:25 +0000 Subject: Implemented encryption algorithm used for a number of RPC buffers. (actually, decryption only currently because I need to get some sleep). Basically another Microsoft twist on DES; the "master key" is the user's NT hash MD4'd and subsets of this are chosen as the 56-bit DES keys. (This used to be commit f09388fa6f41a13ca035b5b2ff40be804608f619) --- source3/libsmb/smbdes.c | 2 +- source3/libsmb/smbencrypt.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index d0e1c6e85f..08bc929f01 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -277,7 +277,7 @@ static void str_to_key(unsigned char *str,unsigned char *key) } -static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) +void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) { int i; char outb[64]; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index e35cccd734..3835c99815 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -226,3 +226,48 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } +int nt_decrypt_string2(STRING2 *out, STRING2 *in, char nt_hash[16]) +{ + uchar bufhdr[8]; + int datalen; + + uchar key[16]; + uchar *keyptr = key; + uchar *keyend = key + sizeof(key); + + uchar *outbuf = (uchar *)out->buffer; + uchar *inbuf = (uchar *)in->buffer; + uchar *inbufend; + + + mdfour(key, nt_hash, 16); + + smbhash(bufhdr, inbuf, keyptr, 0); + datalen = IVAL(bufhdr, 0); + + if ((datalen > in->str_str_len) || (datalen > MAX_STRINGLEN)) + { + DEBUG(0, ("nt_decrypt_string2: failed\n")); + return False; + } + + out->str_max_len = out->str_str_len = datalen; + inbuf += 8; + inbufend = inbuf + datalen; + + while (inbuf < inbufend) + { + keyptr += 7; + if (keyptr + 7 > keyend) + { + keyptr = (keyend - keyptr) + key; + } + + smbhash(outbuf, inbuf, keyptr, 0); + + inbuf += 8; + outbuf += 8; + } + + return True; +} -- cgit From 7a3e8ad0974593e12f62985ae769f808d6fdf4a1 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 19 Mar 1999 20:26:25 +0000 Subject: return type of nt_decrypt_string2 set to BOOL. (This used to be commit 674e4a3a73cd601c647a5069e2af943a6321ac06) --- source3/libsmb/smbencrypt.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 3835c99815..20a8eb0504 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -226,7 +226,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } -int nt_decrypt_string2(STRING2 *out, STRING2 *in, char nt_hash[16]) +BOOL nt_decrypt_string2(STRING2 *out, const STRING2 *in, char nt_hash[16]) { uchar bufhdr[8]; int datalen; @@ -236,9 +236,8 @@ int nt_decrypt_string2(STRING2 *out, STRING2 *in, char nt_hash[16]) uchar *keyend = key + sizeof(key); uchar *outbuf = (uchar *)out->buffer; - uchar *inbuf = (uchar *)in->buffer; - uchar *inbufend; - + const uchar *inbuf = (const uchar *)in->buffer; + const uchar *inbufend; mdfour(key, nt_hash, 16); -- cgit From 5aeb58c2852ac9dba113d29c0f3e9a3b8a81658c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 19 Mar 1999 20:58:24 +0000 Subject: const char* instead of char* for input (This used to be commit b51574174c5bbc554eb1c697cb22b2b73af44306) --- source3/libsmb/smbdes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 08bc929f01..579d0dd8b4 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -277,7 +277,7 @@ static void str_to_key(unsigned char *str,unsigned char *key) } -void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) +void smbhash(unsigned char *out, const uchar *in, unsigned char *key, int forw) { int i; char outb[64]; -- cgit From 99020c9b090449e3113acc2ceb667cb41a63a6b8 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Tue, 23 Mar 1999 14:58:26 +0000 Subject: ERRmoredata is informational and should not be treated as a hard error anywhere. (This used to be commit 71b861f7468d7950bedb61dd18a4b9d830bf8628) --- source3/libsmb/clientgen.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e188cb3b99..bd5d58e4de 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -341,8 +341,6 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, int total_data=0; int total_param=0; int this_data,this_param; - uint8 eclass; - uint32 num; *data_len = *param_len = 0; @@ -357,8 +355,7 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, return(False); } - /* DOS error "more data" is an acceptable error code */ - if (cli_error(cli, &eclass, &num) && !(eclass == ERRDOS && num == ERRmoredata)) + if (cli_error(cli, NULL, NULL)) { return(False); } @@ -409,8 +406,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - /* DOS error "more data" is an acceptable error code */ - if (cli_error(cli, &eclass, &num) && eclass != ERRDOS && num != ERRmoredata) + + if (cli_error(cli, NULL, NULL)) { return(False); } @@ -1381,7 +1378,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t mid = SVAL(cli->inbuf, smb_mid) - cli->mid; size2 = SVAL(cli->inbuf, smb_vwv5); - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_error(cli, NULL, NULL)) + { blocks = MIN(blocks, mid-1); continue; } @@ -2535,6 +2533,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRrename: return EEXIST; case ERRbadshare: return EBUSY; case ERRlock: return EBUSY; + case ERRmoredata: return 0; /* Informational only */ } } if (rcls == ERRSRV) { -- cgit From 1ad002b7497c840f84b17e2a5187079d1140f90b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 24 Mar 1999 21:23:39 +0000 Subject: NULL pointer handling in nt_lm_owf_gen (This used to be commit 68841eeb64df5958a90a6471fd17e6e56fba7c67) --- source3/libsmb/smbencrypt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 20a8eb0504..24945bc142 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -111,7 +111,10 @@ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) char passwd[130]; memset(passwd,'\0',130); - safe_strcpy( passwd, pwd, sizeof(passwd)-1); + if (pwd != NULL) + { + safe_strcpy( passwd, pwd, sizeof(passwd)-1); + } /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); -- cgit From 3b07eff9eaa0bd3255dbbcdeb0fbd95e1a064e97 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 25 Mar 1999 20:56:28 +0000 Subject: fixed issues with "Welcome to SAMBA Domain" for when admin user/pass is used to add workstation to domain. unix account db not modified: only SAM password db is used. (This used to be commit 129a9a4d4b74897ed753a697a3aed9b194c25568) --- source3/libsmb/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 24945bc142..f0bfbd9b84 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -106,7 +106,7 @@ void E_md4hash(uchar *passwd, uchar *p16) } /* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) +void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) { char passwd[130]; -- cgit From 7fe5ba774b27b01b91f0d7cc25abf8383b9afca6 Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Fri, 23 Apr 1999 14:47:45 +0000 Subject: Adding scheduler control pipe (\atsvc), client-side routines, and rpcclient command "at" (compatible with NT's "at" command - see rpcclient commit) - useful for remote NT administration. (This used to be commit cf30a472f702d7b50c3a85e2cf2f55b46a2bd452) --- source3/libsmb/nterr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index d2f9335000..b094050a33 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -514,6 +514,7 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, + { "NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB }, { NULL, 0 } }; @@ -525,7 +526,7 @@ char *get_nt_error_msg(uint32 nt_code) static pstring msg; int idx = 0; - pstrcpy(msg, "Unknown NT error"); + snprintf(msg, sizeof(msg), "%08x", nt_code); nt_code &= 0xFFFF; -- cgit From cae3620b2e8abbe35f0369a82d5461cb596475a3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 24 Jun 1999 18:58:08 +0000 Subject: safe string error reporting functions (found a potential buffer overflow of a pstrcpy into an fstring). (This used to be commit ac0060443de800fec9042b69b299ff2e9128a31c) --- source3/libsmb/clientgen.c | 97 ++++++++++++++++++++++++---------------------- source3/libsmb/nterr.c | 19 ++++++--- source3/libsmb/smberr.c | 39 ++++++++++++++----- 3 files changed, 93 insertions(+), 62 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bd5d58e4de..cb0f2e5c74 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -90,6 +90,26 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) return True; } +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char *cli_errstr(struct cli_state *cli) +{ + static fstring error_message; + cli_safe_errstr(cli, error_message, sizeof(error_message)); + return error_message; +} + +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len) +{ + smb_safe_errstr(cli->inbuf, msg, len); +} + /***************************************************** RAP error codes - a small start but will be extended. *******************************************************/ @@ -112,24 +132,32 @@ struct }; /**************************************************************************** - return a description of an SMB error + return a description of a RAP error ****************************************************************************/ -static char *cli_smb_errstr(struct cli_state *cli) +BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen) { - return smb_errstr(cli->inbuf); + int i; + + slprintf(err_msg, msglen - 1, "RAP code %d", rap_error); + + for (i = 0; rap_errmap[i].message != NULL; i++) + { + if (rap_errmap[i].err == rap_error) + { + safe_strcpy( err_msg, rap_errmap[i].message, msglen); + return True; + } + } + return False; } -/****************************************************** - Return an error message - either an SMB error or a RAP - error. -*******************************************************/ - -char *cli_errstr(struct cli_state *cli) +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen) { - static fstring error_message; uint8 errclass; uint32 errnum; - int i; /* * Errors are of three kinds - smb errors, @@ -142,47 +170,24 @@ char *cli_errstr(struct cli_state *cli) if (errclass != 0) { - return cli_smb_errstr(cli); + cli_safe_smb_errstr(cli, err_msg, msglen); } - - /* - * Was it an NT error ? - */ - - if (cli->nt_error) + else if (cli->nt_error) { - char *nt_msg = get_nt_error_msg(cli->nt_error); - - if (nt_msg == NULL) - { - slprintf(error_message, sizeof(fstring) - 1, "NT code %d", cli->nt_error); - } - else - { - fstrcpy(error_message, nt_msg); - } + /* + * Was it an NT error ? + */ - return error_message; + (void)get_safe_nt_error_msg(cli->nt_error, err_msg, msglen); } - - /* - * Must have been a rap error. - */ - - slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); - - for (i = 0; rap_errmap[i].message != NULL; i++) + else { - if (rap_errmap[i].err == cli->rap_error) - { - fstrcpy( error_message, rap_errmap[i].message); - break; - } - } - - return error_message; + /* + * Must have been a rap error. + */ + (void)get_safe_rap_errstr(cli->rap_error, err_msg, msglen); + } } - /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index b094050a33..9cf1fb8214 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -521,12 +521,11 @@ nt_err_code_struct nt_errs[] = /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -char *get_nt_error_msg(uint32 nt_code) +void get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len) { - static pstring msg; int idx = 0; - snprintf(msg, sizeof(msg), "%08x", nt_code); + snprintf(msg, len, "NT code %08x", nt_code); nt_code &= 0xFFFF; @@ -534,11 +533,19 @@ char *get_nt_error_msg(uint32 nt_code) { if (nt_errs[idx].nt_errcode == nt_code) { - pstrcpy(msg, nt_errs[idx].nt_errstr); - return msg; + safe_strcpy(msg, nt_errs[idx].nt_errstr, len); + return; } idx++; } - return msg; } +/***************************************************************************** + returns an NT error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +char *get_nt_error_msg(uint32 nt_code) +{ + static pstring msg; + get_safe_nt_error_msg(nt_code, msg, sizeof(msg)); + return msg; +} diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 85827dde28..228eee5892 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -143,13 +143,19 @@ struct {0xFF,"ERRCMD",NULL}, {-1,NULL,NULL}}; +char *smb_err_msg(uint8 class, uint32 num) +{ + static pstring ret; + smb_safe_err_msg(class, num, ret, sizeof(ret)); + return ret; +} + /**************************************************************************** return a SMB error string from a SMB buffer ****************************************************************************/ -char *smb_err_msg(uint8 class, uint32 num) +BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len) { - static pstring ret; int i,j; for (i=0;err_classes[i].class;i++) @@ -165,29 +171,42 @@ char *smb_err_msg(uint8 class, uint32 num) { if (DEBUGLEVEL > 0) { - slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class, + slprintf(ret, len - 1, "%s - %s (%s)",err_classes[i].class, err[j].name,err[j].message); } else { - slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name); + slprintf(ret, len - 1, "%s - %s",err_classes[i].class,err[j].name); } - return ret; + return True; } } } - slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class, num); - return ret; + slprintf(ret, len - 1, "%s - %d",err_classes[i].class, num); + return True; } } - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); - return(ret); + + slprintf(ret, len - 1, "Error: Unknown error (%d,%d)",class,num); + return False; } + +/**************************************************************************** +return a SMB error string from a SMB buffer +****************************************************************************/ +BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len) +{ + return smb_safe_err_msg(CVAL(inbuf,smb_rcls), SVAL(inbuf,smb_err), + msg, len); +} + /**************************************************************************** return a SMB error string from a SMB buffer ****************************************************************************/ char *smb_errstr(char *inbuf) { - return smb_err_msg(CVAL(inbuf,smb_rcls), SVAL(inbuf,smb_err)); + static fstring errmsg; + (void)smb_safe_errstr(inbuf, errmsg, sizeof(errmsg)); + return errmsg; } -- cgit From f63e8070488e079c899cde90e8452796f3af4e5f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 24 Jun 1999 19:02:37 +0000 Subject: safe string version of nmb_namestr. (This used to be commit 250621b3cec5fc463d348432d1d0ff5fb59e7a29) --- source3/libsmb/nmblib.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 14dc5ecee2..54b1779f44 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -287,6 +287,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) return(ret); } + /******************************************************************* useful for debugging messages ******************************************************************/ @@ -296,15 +297,23 @@ char *nmb_namestr(struct nmb_name *n) static fstring ret[4]; char *p = ret[i]; - if (!n->scope[0]) - slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); - else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); + nmb_safe_namestr(n, p, sizeof(fstring)); i = (i+1)%4; return(p); } +/******************************************************************* + useful for debugging messages + ******************************************************************/ +void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len) +{ + if (!n->scope[0]) + slprintf(str, len-1, "%s<%02x>",n->name,n->name_type); + else + slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); +} + /******************************************************************* allocate and parse some resource records ******************************************************************/ -- cgit From 1dc6c6c7ca54578d9e6040a9d4d5e509f1ad3af3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 24 Jun 1999 19:09:03 +0000 Subject: use nmb_safe_namestr. (This used to be commit de9a38b0bcb5adcb6e502f2200d3e84bdcbdfc48) --- source3/libsmb/clientgen.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cb0f2e5c74..4f73b6e51b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2634,8 +2634,14 @@ BOOL cli_establish_connection(struct cli_state *cli, char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon) { + fstring callingstr; + fstring calledstr; + + nmb_safe_namestr(calling, callingstr, sizeof(callingstr)); + nmb_safe_namestr(called , calledstr , sizeof(calledstr )); + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), + callingstr, calledstr, inet_ntoa(*dest_ip), cli->user_name, cli->domain)); /* establish connection */ @@ -2650,7 +2656,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (!cli_connect(cli, dest_host, dest_ip)) { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(calling), inet_ntoa(*dest_ip))); + callingstr, inet_ntoa(*dest_ip))); return False; } } @@ -2763,7 +2769,6 @@ BOOL cli_establish_connection(struct cli_state *cli, return True; } - /**************************************************************************** connect to one of multiple servers: don't care which ****************************************************************************/ -- cgit From 73891ca8e4f6cca6aa8bb0ae043f660a64baa056 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Jun 1999 18:47:06 +0000 Subject: improving authentication code (tidyup). (This used to be commit ab1a6aa42db5217f025941fb5107436556bc23b7) --- source3/libsmb/clientgen.c | 259 +++++++++++++++++++++++++++++------------- source3/libsmb/pwd_cache.c | 82 ++++++++++++-- source3/libsmb/smbencrypt.c | 271 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 483 insertions(+), 129 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4f73b6e51b..8d3508d98f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2,7 +2,8 @@ Unix SMB/Netbios implementation. Version 1.9. SMB client generic functions - Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Tridgell 1994-1999 + Copyright (C) Luke Kenneth Casson Leighton 1996-1999 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -690,70 +691,25 @@ prots[] = /**************************************************************************** send a session setup ****************************************************************************/ -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) +BOOL cli_session_setup_x(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *user_domain) { char *p; - fstring pword, ntpword; + +#ifdef DEBUG_PASSWORD + DEBUG(100,("cli_session_setup. pass, ntpass\n")); + dump_data(100, pass, passlen); + dump_data(100, ntpass, ntpasslen); +#endif if (cli->protocol < PROTOCOL_LANMAN1) { return True; } - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) - { - return False; - } - - if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) - { - /* if in share level security then don't send a password now */ - fstrcpy(pword, ""); - passlen=1; - fstrcpy(ntpword, ""); - ntpasslen=1; - } - else if ((passlen == 0 || passlen == 1) && (pass[0] == '\0')) - { - /* Null session connect. */ - pword [0] = '\0'; - ntpword[0] = '\0'; - } - else if (passlen == 24 && ntpasslen == 24) - { - if (IS_BITS_SET_ALL(cli->sec_mode, 2)) - { - /* encrypted password, implicit from 24-byte lengths */ - memcpy(pword , pass , 24); - memcpy(ntpword, ntpass, 24); - } - else - { - DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n")); - return False; - } - } - else if (ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2)) - { - /* plain-text password: server doesn't support encrypted. */ - fstrcpy(pword, pass); - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - else /* passlen != 0 && ntpasslen != 0 && server supports encryption */ - { - /* plain-text password requesting to be encrypted */ - uchar *key = (uchar *)cli->cryptkey; - SMBencrypt ((uchar *)pass , key,(uchar *)pword ); - SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); - passlen = 24; - ntpasslen = 24; - } - /* send a session setup command */ bzero(cli->outbuf,smb_size); @@ -770,7 +726,7 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); + memcpy(p,pass,passlen); p += passlen; pstrcpy(p,user); strupper(p); @@ -790,17 +746,17 @@ BOOL cli_session_setup(struct cli_state *cli, SSVAL(cli->outbuf,smb_vwv8,ntpasslen); SSVAL(cli->outbuf,smb_vwv11,0); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); + memcpy(p,pass,passlen); p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpword,ntpasslen); + memcpy(p,ntpass,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); pstrcpy(p,user); strupper(p); p = skip_string(p,1); - pstrcpy(p,workgroup); - strupper(p); + pstrcpy(p,user_domain); p = skip_string(p,1); pstrcpy(p,"Unix");p = skip_string(p,1); + CVAL(p, 0) = 0; p++; pstrcpy(p,"Samba");p = skip_string(p,1); set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } @@ -833,11 +789,127 @@ BOOL cli_session_setup(struct cli_state *cli, fstrcpy(cli->server_domain, server_domain); } - fstrcpy(cli->user_name, user); - return True; } +static BOOL cli_calc_session_pwds(struct cli_state *cli, + char *pword, char *ntpword, + char *pass, int *passlen, + char *ntpass, int *ntpasslen, + BOOL ntlmv2) +{ +#ifdef DEBUG_PASSWORD + DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n")); + dump_data(100, pass, *passlen); + dump_data(100, ntpass, *ntpasslen); +#endif + if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + /* if in share level security then don't send a password now */ + fstrcpy(pword, ""); + *passlen=1; + fstrcpy(ntpword, ""); + *ntpasslen=1; + } + else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0')) + { + /* Null session connect. */ + pword [0] = '\0'; + ntpword[0] = '\0'; + } + else if (*passlen == 24 && *ntpasslen >= 24) + { + if (IS_BITS_SET_ALL(cli->sec_mode, 2)) + { + /* encrypted password, implicit from 24-byte lengths */ + memcpy(pword , pass , *passlen); + memcpy(ntpword, ntpass, *ntpasslen); + } + else + { + DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n")); + return False; + } + } + else if (*ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2)) + { + /* plain-text password: server doesn't support encrypted. */ + fstrcpy(pword, pass); + fstrcpy(ntpword, ""); + *ntpasslen = 0; + } + else /* passlen != 0 && ntpasslen != 0 && server supports encryption */ + { + if (ntlmv2) + { + /* plain-text password requesting to be encrypted */ + uchar *srv_key = (uchar *)cli->cryptkey; + uchar nt_owf[16]; + uchar kr[16]; + + SMBgenclientchals(cli->lm_cli_chal, + cli->nt_cli_chal, + &cli->nt_cli_chal_len, + cli->calling.name, + cli->domain); + + nt_owf_gen(pword, nt_owf); + ntv2_owf_gen(nt_owf, cli->user_name, cli->domain, kr); + + /* lm # */ + memcpy(pword, cli->lm_cli_chal, 8); + SMBOWFencrypt_ntv2(kr, + srv_key, 8, + cli->lm_cli_chal, 8, + &pword[8]); + *passlen = 24; + + /* nt # */ + memcpy(ntpword, cli->lm_cli_chal, cli->nt_cli_chal_len); + SMBOWFencrypt_ntv2(kr, + srv_key, 8, + cli->nt_cli_chal, cli->nt_cli_chal_len, + &ntpword[cli->nt_cli_chal_len]); + *ntpasslen = cli->nt_cli_chal_len + 16; + } + else + { + /* plain-text password requesting to be encrypted */ + uchar *key = (uchar *)cli->cryptkey; + SMBencrypt ((uchar *)pass , key,(uchar *)pword ); + SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); + *passlen = 24; + *ntpasslen = 24; + } + } + return True; +} + +/**************************************************************************** +send a session setup +****************************************************************************/ +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *user_domain) +{ + fstring pword, ntpword; + + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) + { + return False; + } + + fstrcpy(cli->user_name, user); + + return cli_calc_session_pwds(cli, pword, ntpword, + pass, &passlen, + ntpass, &ntpasslen, cli->use_ntlmv2) && + cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen, + user_domain); +} + /**************************************************************************** Send a uloggoff. *****************************************************************************/ @@ -2614,9 +2686,12 @@ BOOL cli_reestablish_connection(struct cli_state *cli) if (cli_establish_connection(cli, dest_host, &cli->dest_ip, &calling, &called, - share, dev, False, do_tcon)) { - if (cli->fd != oldfd) { - if (dup2(cli->fd, oldfd) == oldfd) { + share, dev, False, do_tcon)) + { + if (cli->fd != oldfd) + { + if (dup2(cli->fd, oldfd) == oldfd) + { close(cli->fd); } } @@ -2640,9 +2715,10 @@ BOOL cli_establish_connection(struct cli_state *cli, nmb_safe_namestr(calling, callingstr, sizeof(callingstr)); nmb_safe_namestr(called , calledstr , sizeof(calledstr )); - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n", callingstr, calledstr, inet_ntoa(*dest_ip), - cli->user_name, cli->domain)); + cli->user_name, cli->domain, + cli->use_ntlmv2 ? "v2" : "v1")); /* establish connection */ @@ -2665,7 +2741,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session request\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } @@ -2673,7 +2751,9 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed negprot\n")); if (do_shutdown) - cli_shutdown(cli); + { + cli_shutdown(cli); + } return False; } @@ -2725,20 +2805,45 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt encrypted session */ - unsigned char nt_sess_pwd[24]; unsigned char lm_sess_pwd[24]; + unsigned char nt_sess_pwd[128]; + size_t nt_sess_pwd_len; + extern pstring global_myname; + + if (cli->use_ntlmv2 != False) + { + DEBUG(10,("cli_establish_connection: NTLMv2\n")); + pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, + cli->user_name, global_myname, cli->domain); + } + else + { + DEBUG(10,("cli_establish_connection: NTLMv1\n")); + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + } - /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd, + &nt_sess_pwd_len); /* attempt encrypted session */ - if (!cli_session_setup(cli, cli->user_name, + if (!cli_session_setup_x(cli, cli->user_name, (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, sizeof(nt_sess_pwd), + (char*)nt_sess_pwd, nt_sess_pwd_len, cli->domain)) { DEBUG(1,("failed session setup\n")); + + if (cli->use_ntlmv2 == Auto) + { + DEBUG(10,("NTLMv2 failed. Using NTLMv1\n")); + cli->use_ntlmv2 = False; + return cli_establish_connection(cli, + dest_host, dest_ip, + calling, called, + service, service_type, + do_shutdown, do_tcon); + } + if (do_shutdown) { cli_shutdown(cli); diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index bbd5f63d4b..655df5be8a 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -197,27 +197,83 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) /**************************************************************************** makes lm and nt OWF crypts ****************************************************************************/ -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) +void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], + const char *user, const char *server, const char *domain) { + uchar kr[16]; + + DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n", + user, server, domain)); + pwd_deobfuscate(pwd); + SMBgenclientchals(pwd->lm_cli_chal, + pwd->nt_cli_chal, + &pwd->nt_cli_chal_len, + server, domain); + + ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr); + + /* lm # */ + SMBOWFencrypt_ntv2(kr, + srv_key, 8, + pwd->lm_cli_chal, 8, + pwd->smb_lm_owf); + memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8); + + /* nt # */ + SMBOWFencrypt_ntv2(kr, + srv_key, 8, + pwd->nt_cli_chal, pwd->nt_cli_chal_len, + pwd->smb_nt_owf); + memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len); + pwd->nt_owf_len = pwd->nt_cli_chal_len + 16; + #ifdef DEBUG_PASSWORD - DEBUG(100,("client cryptkey: ")); - dump_data(100, cryptkey, 8); -#endif + DEBUG(100,("server cryptkey: ")); + dump_data(100, srv_key, 8); - SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); + DEBUG(100,("client lmv2 cryptkey: ")); + dump_data(100, pwd->lm_cli_chal, 8); -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_owf_passwd: ")); - dump_data(100, pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + DEBUG(100,("client ntv2 cryptkey: ")); + dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len); + + DEBUG(100,("ntv2_owf_passwd: ")); + dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len); DEBUG(100,("nt_sess_pwd: ")); dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); + + DEBUG(100,("lmv2_owf_passwd: ")); + dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); + DEBUG(100,("lm_sess_pwd: ")); + dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); #endif + pwd->crypted = True; + + pwd_obfuscate(pwd); +} + +/**************************************************************************** + makes lm and nt OWF crypts + ****************************************************************************/ +void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) +{ + pwd_deobfuscate(pwd); SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); + SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); + pwd->nt_owf_len = 24; #ifdef DEBUG_PASSWORD + DEBUG(100,("client cryptkey: ")); + dump_data(100, cryptkey, 8); + + DEBUG(100,("nt_owf_passwd: ")); + dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len); + DEBUG(100,("nt_sess_pwd: ")); + dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); + DEBUG(100,("lm_owf_passwd: ")); dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); DEBUG(100,("lm_sess_pwd: ")); @@ -232,7 +288,8 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) /**************************************************************************** gets lm and nt crypts ****************************************************************************/ -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) +void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], + uchar *nt_owf, size_t *nt_owf_len) { pwd_deobfuscate(pwd); if (lm_owf != NULL) @@ -241,7 +298,12 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) } if (nt_owf != NULL) { - memcpy(nt_owf, pwd->smb_nt_owf, 24); + memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len); + } + if (nt_owf_len != NULL) + { + *nt_owf_len = pwd->nt_owf_len; } pwd_obfuscate(pwd); } + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index f0bfbd9b84..852e5327cf 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -32,19 +32,30 @@ extern int DEBUGLEVEL; encrypted password into p24 */ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) { - uchar p14[15], p21[21]; + uchar p21[21]; - memset(p21,'\0',21); - memset(p14,'\0',14); - StrnCpy((char *)p14,(char *)passwd,14); + lm_owf_gen(passwd, p21); + SMBOWFencrypt(p21, c8, p24); - strupper((char *)p14); - E_P16(p14, p21); +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); +#endif +} +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) +{ + uchar p21[21]; + + memset(p21,'\0',21); + + nt_owf_gen(passwd, p21); SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD - DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); + DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); dump_data(100, p21, 16); dump_data(100, c8, 8); dump_data(100, p24, 24); @@ -67,7 +78,23 @@ static int _my_wcslen(int16 *str) * format. */ -static int _my_mbstowcs(int16 *dst, uchar *src, int len) +static int _my_mbstowcsupper(int16 *dst, const uchar *src, int len) +{ + int i; + int16 val; + + for(i = 0; i < len; i++) { + val = toupper(*src); + SSVAL(dst,0,val); + dst++; + src++; + if(val == 0) + break; + } + return i; +} + +static int _my_mbstowcs(int16 *dst, const uchar *src, int len) { int i; int16 val; @@ -105,27 +132,17 @@ void E_md4hash(uchar *passwd, uchar *p16) mdfour(p16, (unsigned char *)wpwd, len); } -/* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) +/* Does the LM owf of a user's password */ +void lm_owf_gen(const char *pwd, uchar p16[16]) { - char passwd[130]; + char passwd[15]; - memset(passwd,'\0',130); + memset(passwd,'\0',15); if (pwd != NULL) { safe_strcpy( passwd, pwd, sizeof(passwd)-1); } - /* Calculate the MD4 hash (NT compatible) of the password */ - memset(nt_p16, '\0', 16); - E_md4hash((uchar *)passwd, nt_p16); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); - dump_data(120, passwd, strlen(passwd)); - dump_data(100, nt_p16, 16); -#endif - /* Mangle the passwords into Lanman format */ passwd[14] = '\0'; strupper(passwd); @@ -144,6 +161,37 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) bzero(passwd, sizeof(passwd)); } +/* Does both the NT and LM owfs of a user's password */ +void nt_owf_gen(const char *pwd, uchar nt_p16[16]) +{ + char passwd[130]; + + memset(passwd,'\0',130); + if (pwd != NULL) + { + safe_strcpy( passwd, pwd, sizeof(passwd)-1); + } + + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + E_md4hash((uchar *)passwd, nt_p16); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); + dump_data(120, passwd, strlen(passwd)); + dump_data(100, nt_p16, 16); +#endif + /* clear out local copy of user's password (just being paranoid). */ + bzero(passwd, sizeof(passwd)); +} + +/* Does both the NT and LM owfs of a user's password */ +void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16]) +{ + nt_owf_gen(pwd, nt_p16); + lm_owf_gen(pwd, lm_p16); +} + /* Does the des encryption from the NT or LM MD4 hash. */ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) { @@ -155,6 +203,165 @@ void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) E_P24(p21, c8, p24); } +void SMBOWFencrypt_ntv2(const uchar kr[16], + const uchar *srv_chal, int srv_chal_len, + const uchar *cli_chal, int cli_chal_len, + char resp_buf[16]) +{ + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(srv_chal, srv_chal_len, &ctx); + hmac_md5_update(cli_chal, cli_chal_len, &ctx); + hmac_md5_final(resp_buf, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); + dump_data(100, srv_chal, srv_chal_len); + dump_data(100, cli_chal, cli_chal_len); + dump_data(100, resp_buf, 16); +#endif +} + +#if 0 +static char np_cli_chal[58] = +{ + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0x20, 0xd0, 0xb6, 0xc2, 0x92, 0xBE, 0x01, + 0x05, 0x83, 0x32, 0xec, 0xfa, 0xe4, 0xf3, 0x6d, + 0x6f, 0x00, 0x6e, 0x00, 0x02, 0x00, 0x12, 0x00, + 0x52, 0x00, 0x4f, 0x00, 0x43, 0x00, 0x4b, 0x00, + 0x4e, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x4c, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, + 0x00, 0x00 +}; +#endif + +void SMBgenclientchals(char *lm_cli_chal, + char *nt_cli_chal, int *nt_cli_chal_len, + const char *srv, const char *domain) +{ + NTTIME nt_time; + int srv_len = strlen(srv); + int dom_len = strlen(domain); + + generate_random_buffer(lm_cli_chal, 8, False); + unix_to_nt_time(&nt_time, time(NULL)); + + CVAL(nt_cli_chal,0) = 0x1; + CVAL(nt_cli_chal,1) = 0x1; + SSVAL(nt_cli_chal, 2, 0x0); + SIVAL(nt_cli_chal, 4, 0x0); + SIVAL(nt_cli_chal, 8, nt_time.low); + SIVAL(nt_cli_chal, 12, nt_time.high); + memcpy(nt_cli_chal+16, lm_cli_chal, 8); + /* fill in offset 24, size of structure, later */ + + *nt_cli_chal_len = 28; + + SSVAL(nt_cli_chal, *nt_cli_chal_len, 2); + *nt_cli_chal_len += 2; + SSVAL(nt_cli_chal, *nt_cli_chal_len, dom_len*2); + *nt_cli_chal_len += 2; + ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), domain, dom_len*2); + *nt_cli_chal_len += dom_len*2; + *nt_cli_chal_len += 4 - ((*nt_cli_chal_len) % 4); + + SSVAL(nt_cli_chal, *nt_cli_chal_len, 2); + *nt_cli_chal_len += 2; + SSVAL(nt_cli_chal, 30, srv_len*2); + *nt_cli_chal_len += 2; + ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), srv, srv_len*2); + *nt_cli_chal_len += srv_len*2; + + SSVAL(nt_cli_chal, 24, (*nt_cli_chal_len)+16); + SSVAL(nt_cli_chal, 26, (*nt_cli_chal_len)+15); + + DEBUG(100,("SMBgenclientchals: srv %s, dom %s\n", srv, domain)); + dump_data(100, nt_cli_chal, *nt_cli_chal_len); +} + +void ntv2_owf_gen(const uchar owf[16], + const char *user_n, + const char *domain_n, + uchar kr_buf[16]) +{ + pstring user_u; + pstring dom_u; + HMACMD5Context ctx; + + int user_l = strlen(user_n ); + int domain_l = strlen(domain_n); + + _my_mbstowcsupper((int16*)user_u, user_n , user_l*2 ); + _my_mbstowcs((int16*)dom_u , domain_n, domain_l*2); + + hmac_md5_init_limK_to_64(owf, 16, &ctx); + hmac_md5_update(user_u, user_l*2, &ctx); + hmac_md5_update(dom_u, domain_l*2, &ctx); + hmac_md5_final(kr_buf, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("ntv2_owf_gen: user, domain, owfkey, kr\n")); + dump_data(100, user_u, user_l*2); + dump_data(100, dom_u, domain_l*2); + dump_data(100, owf, 16); + dump_data(100, kr_buf, 16); +#endif +} + +#if 0 +static void main() +{ + char *kr; + int kr_len; + char *cli_chal; + int cli_chal_len; + char *resp; + int resp_len; + char *k_x; + int k_x_len; + + char k_u[16]; + int k_u_len = sizeof(k_u); + + char sesk[16]; + int sesk_len; + + char buf[1024]; + + int flgs = NTLMSSP_NP | NTLMSSP_N2; + + gen_client_chal(flgs, "BROOKFIELDS1", "TEST1", &cli_chal, &cli_chal_len); + gen_owf(flgs, "test", "ADMINISTRATOR", "BROOKFIELDS1", &kr, &kr_len); + gen_resp(flgs, kr, kr_len, srv_chal, 8, cli_chal, cli_chal_len, + &resp, &resp_len); + + gen_sesskey(flgs, kr, kr_len, resp, resp_len, &k_x, &k_x_len); + + printf("lm_resp:\n"); dump_data(lm_resp, 16); printf("\n"); + printf("np_resp:\n"); dump_data(np_resp, 16); printf("\n"); + printf("resp:\n"); dump_data(resp, 16); printf("\n"); + +#if 0 + printf("np_sesk:\n"); dump_data(np_sess_key, 16); printf("\n"); + if (flgs & NTLMSSP_NP) + { + oem_hash(k_x, k_x_len, k_u, np_sess_key, k_u_len); + sesk_len = k_u_len; + } + else + { + memcpy(sesk, k_x, k_x_len); + sesk_len = k_x_len; + } + + oem_hash(sesk, sesk_len, buf, cli_req, sizeof(cli_req)); + printf("cli_req:\n"); dump_data(buf, sizeof(cli_req)); printf("\n"); +#endif +} +#endif + /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) { @@ -173,26 +380,6 @@ void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) #endif } - -/* Does the NT MD4 hash then des encryption. */ - -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) -{ - uchar p21[21]; - - memset(p21,'\0',21); - - E_md4hash(passwd, p21); - SMBOWFencrypt(p21, c8, p24); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); -#endif -} - BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) { int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); -- cgit From 8e145947988d4ac8d025dcd876fae14c75db9527 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Jun 1999 19:39:23 +0000 Subject: smbclient modified to use cli_establish_connection(). smbclient therefore now uses improved authentication. smbclient now "broken" for "scripts" based on DEBUG() output. cli_establish_connection() requires modification to support old scripts. (This used to be commit b0539d43407cb2b0bab7977908de09b21b145218) --- source3/libsmb/clientgen.c | 11 +++++++++++ source3/libsmb/smbencrypt.c | 16 +++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d3508d98f..cc51ab0c4b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -754,6 +754,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, strupper(p); p = skip_string(p,1); pstrcpy(p,user_domain); + strupper(p); p = skip_string(p,1); pstrcpy(p,"Unix");p = skip_string(p,1); CVAL(p, 0) = 0; p++; @@ -2851,6 +2852,16 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } + DEBUG(1,("session setup ok\n")); + + if (*cli->server_domain || *cli->server_os || *cli->server_type) + { + DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + cli->server_domain, + cli->server_os, + cli->server_type)); + } + if (do_tcon) { if (!cli_send_tconX(cli, service, service_type, diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 852e5327cf..abee4f3f19 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -239,11 +239,17 @@ static char np_cli_chal[58] = void SMBgenclientchals(char *lm_cli_chal, char *nt_cli_chal, int *nt_cli_chal_len, - const char *srv, const char *domain) + const char *srv, const char *dom) { NTTIME nt_time; int srv_len = strlen(srv); - int dom_len = strlen(domain); + int dom_len = strlen(dom); + fstring server; + fstring domain; + fstrcpy(server, srv); + fstrcpy(domain, dom); + strupper(server); + strupper(domain); generate_random_buffer(lm_cli_chal, 8, False); unix_to_nt_time(&nt_time, time(NULL)); @@ -271,13 +277,13 @@ void SMBgenclientchals(char *lm_cli_chal, *nt_cli_chal_len += 2; SSVAL(nt_cli_chal, 30, srv_len*2); *nt_cli_chal_len += 2; - ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), srv, srv_len*2); + ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), server, srv_len*2); *nt_cli_chal_len += srv_len*2; SSVAL(nt_cli_chal, 24, (*nt_cli_chal_len)+16); SSVAL(nt_cli_chal, 26, (*nt_cli_chal_len)+15); - DEBUG(100,("SMBgenclientchals: srv %s, dom %s\n", srv, domain)); + DEBUG(100,("SMBgenclientchals: srv %s, dom %s\n", server, domain)); dump_data(100, nt_cli_chal, *nt_cli_chal_len); } @@ -294,7 +300,7 @@ void ntv2_owf_gen(const uchar owf[16], int domain_l = strlen(domain_n); _my_mbstowcsupper((int16*)user_u, user_n , user_l*2 ); - _my_mbstowcs((int16*)dom_u , domain_n, domain_l*2); + _my_mbstowcsupper((int16*)dom_u , domain_n, domain_l*2); hmac_md5_init_limK_to_64(owf, 16, &ctx); hmac_md5_update(user_u, user_l*2, &ctx); -- cgit From c31d5972a832ecd7203e871084acbe49abc02055 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Jun 1999 20:51:29 +0000 Subject: removed old code/comments. (This used to be commit bc8c46bc088298d6247830b673790032e59d7f6a) --- source3/libsmb/smbencrypt.c | 66 --------------------------------------------- 1 file changed, 66 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index abee4f3f19..b833cbd377 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -223,20 +223,6 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], #endif } -#if 0 -static char np_cli_chal[58] = -{ - 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xf0, 0x20, 0xd0, 0xb6, 0xc2, 0x92, 0xBE, 0x01, - 0x05, 0x83, 0x32, 0xec, 0xfa, 0xe4, 0xf3, 0x6d, - 0x6f, 0x00, 0x6e, 0x00, 0x02, 0x00, 0x12, 0x00, - 0x52, 0x00, 0x4f, 0x00, 0x43, 0x00, 0x4b, 0x00, - 0x4e, 0x00, 0x52, 0x00, 0x4f, 0x00, 0x4c, 0x00, - 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x65, 0x00, - 0x00, 0x00 -}; -#endif - void SMBgenclientchals(char *lm_cli_chal, char *nt_cli_chal, int *nt_cli_chal_len, const char *srv, const char *dom) @@ -316,58 +302,6 @@ void ntv2_owf_gen(const uchar owf[16], #endif } -#if 0 -static void main() -{ - char *kr; - int kr_len; - char *cli_chal; - int cli_chal_len; - char *resp; - int resp_len; - char *k_x; - int k_x_len; - - char k_u[16]; - int k_u_len = sizeof(k_u); - - char sesk[16]; - int sesk_len; - - char buf[1024]; - - int flgs = NTLMSSP_NP | NTLMSSP_N2; - - gen_client_chal(flgs, "BROOKFIELDS1", "TEST1", &cli_chal, &cli_chal_len); - gen_owf(flgs, "test", "ADMINISTRATOR", "BROOKFIELDS1", &kr, &kr_len); - gen_resp(flgs, kr, kr_len, srv_chal, 8, cli_chal, cli_chal_len, - &resp, &resp_len); - - gen_sesskey(flgs, kr, kr_len, resp, resp_len, &k_x, &k_x_len); - - printf("lm_resp:\n"); dump_data(lm_resp, 16); printf("\n"); - printf("np_resp:\n"); dump_data(np_resp, 16); printf("\n"); - printf("resp:\n"); dump_data(resp, 16); printf("\n"); - -#if 0 - printf("np_sesk:\n"); dump_data(np_sess_key, 16); printf("\n"); - if (flgs & NTLMSSP_NP) - { - oem_hash(k_x, k_x_len, k_u, np_sess_key, k_u_len); - sesk_len = k_u_len; - } - else - { - memcpy(sesk, k_x, k_x_len); - sesk_len = k_x_len; - } - - oem_hash(sesk, sesk_len, buf, cli_req, sizeof(cli_req)); - printf("cli_req:\n"); dump_data(buf, sizeof(cli_req)); printf("\n"); -#endif -} -#endif - /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) { -- cgit From 820c38221126392955eb221c72aa02189fa91c7e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 8 Jul 1999 19:44:06 +0000 Subject: fixed problem with NULL ntpasswd parameters causing crash in static cli_calc_session_pwds(). this code used to be inside cli_session_setup() itself and worked on non-NULL local variables. (This used to be commit 7aff19ba57fd91572da7cbe16f118d11226590e3) --- source3/libsmb/clientgen.c | 52 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cc51ab0c4b..78c09d53e9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -765,7 +765,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { - DEBUG(10,("cli_session_setup: receive smb failed\n")); + DEBUG(10,("cli_session_setup_x: receive smb failed\n")); return False; } @@ -799,26 +799,59 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, char *ntpass, int *ntpasslen, BOOL ntlmv2) { + BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL; + + if (pass == NULL || passlen == NULL) + { + DEBUG(0,("cli_calc_session_pwds: pass and passlen are NULL\n")); + return False; + } + if ((ntpass != NULL || ntpasslen != NULL) && + (ntpass == NULL || ntpasslen == NULL)) + { + DEBUG(0,("cli_calc_session_pwds: ntpasswd pointers invalid\n")); + return False; + } + #ifdef DEBUG_PASSWORD DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n")); dump_data(100, pass, *passlen); - dump_data(100, ntpass, *ntpasslen); + if (ntpass_ok) + { + dump_data(100, ntpass, *ntpasslen); + } #endif if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) { /* if in share level security then don't send a password now */ - fstrcpy(pword, ""); + pword[0] = '\0'; *passlen=1; - fstrcpy(ntpword, ""); - *ntpasslen=1; + if (ntpass_ok) + { + ntpword[0] = '\0'; + *ntpasslen=1; + } + return True; } else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0')) { /* Null session connect. */ pword [0] = '\0'; - ntpword[0] = '\0'; + if (ntpass_ok) + { + ntpword[0] = '\0'; + *ntpasslen=1; + } + + return True; } - else if (*passlen == 24 && *ntpasslen >= 24) + + if (!ntpass_ok) + { + return False; + } + + if (*passlen == 24 && *ntpasslen >= 24) { if (IS_BITS_SET_ALL(cli->sec_mode, 2)) { @@ -828,7 +861,7 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, } else { - DEBUG(0,("cli_session_setup: encrypted passwords not supported by server\n")); + DEBUG(0,("cli_calc_session_pwds: encrypted passwords not supported by server\n")); return False; } } @@ -839,8 +872,9 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, fstrcpy(ntpword, ""); *ntpasslen = 0; } - else /* passlen != 0 && ntpasslen != 0 && server supports encryption */ + else if (ntpasslen != NULL) { + /* passlen != 0, ntpasslen != 0 && server supports encryption */ if (ntlmv2) { /* plain-text password requesting to be encrypted */ -- cgit From 6919a92aee585d1d64b89ec359d038e5a6fa9b7e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 9 Jul 1999 03:55:15 +0000 Subject: When making anonymous connections, must pass pointers to real nt password and password length variables not constants. (This used to be commit 236022071f2f6df0c583fd88d9802d9b3ea6f73e) --- source3/libsmb/clientgen.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 78c09d53e9..2d19473feb 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2794,14 +2794,14 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->pwd.cleartext || cli->pwd.null_pwd) { - fstring passwd; - int pass_len; + fstring passwd, ntpasswd; + int pass_len, ntpass_len; if (cli->pwd.null_pwd) { /* attempt null session */ - passwd[0] = 0; - pass_len = 1; + passwd[0] = ntpasswd[0] = 0; + pass_len = ntpass_len = 1; } else { @@ -2813,7 +2813,7 @@ BOOL cli_establish_connection(struct cli_state *cli, /* attempt clear-text session */ if (!cli_session_setup(cli, cli->user_name, passwd, pass_len, - NULL, 0, + ntpasswd, ntpass_len, cli->domain)) { DEBUG(1,("failed session setup\n")); -- cgit From 50429f60566839faf647cd4c36b66903c7b855ab Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 11 Jul 1999 19:26:27 +0000 Subject: anon passwd connection: passlen=1; ntpasslen=0. (This used to be commit 12ee037d44a603ce50982d5b90e08c30339de750) --- source3/libsmb/clientgen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2d19473feb..beb73e736b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -840,7 +840,7 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, if (ntpass_ok) { ntpword[0] = '\0'; - *ntpasslen=1; + *ntpasslen=0; } return True; @@ -2403,7 +2403,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (cli->capabilities & 1) { + if (cli->capabilities & CAP_RAW_MODE) { cli->readbraw_supported = True; cli->writebraw_supported = True; } @@ -2550,6 +2550,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) } cli->initialised = 1; + cli->capabilities = CAP_DFS; return cli; } @@ -2795,7 +2796,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->pwd.cleartext || cli->pwd.null_pwd) { fstring passwd, ntpasswd; - int pass_len, ntpass_len; + int pass_len = 0, ntpass_len = 0; if (cli->pwd.null_pwd) { -- cgit From 6a5a4e818684a616306d2954d1a2612113b314a6 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 21 Jul 1999 00:32:09 +0000 Subject: BDC support. (This used to be commit 2331aa32ab36c3ee5fd8cfbe972e57299939e33d) --- source3/libsmb/smbdes.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 579d0dd8b4..fa7d64cec8 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -365,6 +365,10 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) unsigned char index_j = 0; unsigned char j = 0; int ind; + int len = 0; + if (val == 1) len = 516; + if (val == 0) len = 16; + if (val == 2) len = 68; for (ind = 0; ind < 256; ind++) { @@ -381,7 +385,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) s_box[ind] = s_box[j]; s_box[j] = tc; } - for( ind = 0; ind < (val ? 516 : 16); ind++) + for( ind = 0; ind < len; ind++) { unsigned char tc; unsigned char t; -- cgit From 0091c7768dc37c22206b345b306441583204dcba Mon Sep 17 00:00:00 2001 From: Matthew Chapman Date: Thu, 22 Jul 1999 10:54:18 +0000 Subject: BDC support. Algorithm based on previous work of Jeremy's. (This used to be commit f0c71a804dc869a73eb6af6e0ac9f4fb64dd1f68) --- source3/libsmb/smbdes.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index fa7d64cec8..ba214a2eb0 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -401,3 +401,16 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) data[ind] = data[ind] ^ s_box[t]; } } + +void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw) +{ + unsigned char s[14]; + + s[0] = s[4] = s[8] = s[12] = (unsigned char)(rid & 0xFF); + s[1] = s[5] = s[9] = s[13] = (unsigned char)((rid >> 8) & 0xFF); + s[2] = s[6] = s[10] = (unsigned char)((rid >> 16) & 0xFF); + s[3] = s[7] = s[11] = (unsigned char)((rid >> 24) & 0xFF); + + smbhash(out, in, s, forw); + smbhash(out+8, in+8, s+7, forw); +} -- cgit From 80d714e75b48b6ed75de48ea0ca878736eb9b259 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 3 Aug 1999 17:21:34 +0000 Subject: close socket issues: - ssl close from cli_reestablish_connection() not called. - ntlmv2 fall-back to ntlmv1 failed. (This used to be commit fdc275353de85fde0c348320e4d64ba66365b73b) --- source3/libsmb/clientgen.c | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index beb73e736b..765160ffe4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2555,6 +2555,24 @@ struct cli_state *cli_initialise(struct cli_state *cli) return cli; } +/**************************************************************************** +close the socket descriptor +****************************************************************************/ +void cli_close_socket(struct cli_state *cli) +{ +#ifdef WITH_SSL + if (cli->fd != -1) + { + sslutil_disconnect(cli->fd); + } +#endif /* WITH_SSL */ + if (cli->fd != -1) + { + close(cli->fd); + } + cli->fd = -1; +} + /**************************************************************************** shutdown a client structure ****************************************************************************/ @@ -2569,14 +2587,7 @@ void cli_shutdown(struct cli_state *cli) { free(cli->inbuf); } -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ - if (cli->fd != -1) - { - close(cli->fd); - } + cli_close_socket(cli); memset(cli, 0, sizeof(*cli)); } @@ -2702,15 +2713,19 @@ BOOL cli_reestablish_connection(struct cli_state *cli) /* copy the parameters necessary to re-establish the connection */ if (cli->cnum != 0) + { + do_tcon = True; + } + + if (do_tcon) { fstrcpy(share, cli->share); fstrcpy(dev , cli->dev); - do_tcon = True; } memcpy(&called , &(cli->called ), sizeof(called )); memcpy(&calling, &(cli->calling), sizeof(calling)); - fstrcpy(dest_host, cli->full_dest_host_name); + fstrcpy(dest_host, cli->desthost); DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", nmb_namestr(&calling), nmb_namestr(&called), @@ -2728,7 +2743,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) { if (dup2(cli->fd, oldfd) == oldfd) { - close(cli->fd); + cli_close_socket(cli); } } return True; @@ -2873,6 +2888,13 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(10,("NTLMv2 failed. Using NTLMv1\n")); cli->use_ntlmv2 = False; + if (do_tcon) + { + fstrcpy(cli->share, service); + fstrcpy(cli->dev, service_type); + } + fstrcpy(cli->desthost, dest_host); + cli_close_socket(cli); return cli_establish_connection(cli, dest_host, dest_ip, calling, called, -- cgit From ebfa9fa928c7efc2313deb576373da7c536a2aad Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 3 Aug 1999 17:43:12 +0000 Subject: attempting a connection to port 445 first, followed by a connection to 139 if this fails. (This used to be commit 5f821e65015c27f5306c3a707841cd0228509974) --- source3/libsmb/clientgen.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 765160ffe4..1913ccd79b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -36,9 +36,9 @@ int cli_set_port(struct cli_state *cli, int port) { if (port != 0) - cli -> port = port; + cli->port = port; - return cli -> port; /* return it incase caller wants it */ + return cli->port; /* return it incase caller wants it */ } @@ -2442,6 +2442,11 @@ BOOL cli_session_request(struct cli_state *cli, memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); + if (cli->port == 445) + { + return True; + } + /* put in the destination name */ p = cli->outbuf+len; name_mangle(cli->called .name, p, cli->called .name_type); @@ -2490,6 +2495,7 @@ open the client sockets BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern struct in_addr ipzero; + int port = cli->port; fstrcpy(cli->desthost, host); @@ -2503,12 +2509,23 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } - if (cli -> port == 0) cli -> port = 139; + if (port == 0) port = 445; cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - cli -> port, cli->timeout); + port, cli->timeout); if (cli->fd == -1) - return False; + { + if (cli->port != 0) + { + return False; + } + port = 139; + + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + port, cli->timeout); + if (cli->fd == -1) return False; + } + return True; } @@ -2532,7 +2549,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) ZERO_STRUCTP(cli); - cli -> port = 0; + cli->port = 0; cli->fd = -1; cli->cnum = -1; cli->pid = (uint16)getpid(); -- cgit From 9c593512155a4e1d9eb01ac63d4458df59b7357d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 3 Aug 1999 18:03:08 +0000 Subject: bug-fix in connection to port 445. cool! it works! (This used to be commit 062b9302c1c7a21df74571ead5f89ce002820d53) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1913ccd79b..ecab198c94 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2526,6 +2526,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) if (cli->fd == -1) return False; } + cli->port = port; return True; } -- cgit From f221bfa4ace27b898c9326b1d81df59e0ceba032 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 18 Aug 1999 20:10:12 +0000 Subject: debug info display (netbios layer). (This used to be commit 5c974cc4a4cdcb9fd3fe01e93aa577b81cf2d18b) --- source3/libsmb/clientgen.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ecab198c94..efed3555ba 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -60,13 +60,21 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) ssize_t ret; BOOL reestablished=False; + len = smb_len(cli->outbuf) + 4; + if (show) { - show_msg(cli->outbuf); + uint8 msg_type = CVAL(cli->outbuf, 0); + if (msg_type == 0) + { + show_msg(cli->outbuf); + } + else + { + dump_data(10, cli->outbuf, len); + } } - len = smb_len(cli->outbuf) + 4; - while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0 && errno == EPIPE && !reestablished) @@ -2465,7 +2473,7 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - cli_send_smb(cli, False); + cli_send_smb(cli, True); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) -- cgit From b9b4c1d56349824616f2fcaff57cedbc52168059 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 15 Sep 1999 17:30:02 +0000 Subject: #defines for port 445 to SMB_PORT2 (This used to be commit a8d4560e0064a67a234eae89a564b79d2426d9a9) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index efed3555ba..3e31b980c4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2517,7 +2517,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } - if (port == 0) port = 445; + if (port == 0) port = SMB_PORT2; cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, cli->timeout); @@ -2527,7 +2527,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { return False; } - port = 139; + port = SMB_PORT; cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, cli->timeout); -- cgit From 701f9ed2c97ad50a4258e278a3674b8f5a747d8e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 16 Sep 1999 22:46:45 +0000 Subject: reading in smb server domain name from SMBnegprot response (This used to be commit 25025f450531c66c0fd9f7eed886cb288d76d025) --- source3/libsmb/clientgen.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3e31b980c4..6d704dc144 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2400,7 +2400,10 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if (cli->protocol >= PROTOCOL_NT1) { + if (cli->protocol >= PROTOCOL_NT1) + { + char *buf = smb_buf(cli->inbuf); + int bcc = SVAL(cli->inbuf,smb_vwv+2*(CVAL(cli->inbuf,smb_wct))); /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); @@ -2409,13 +2412,26 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + memcpy(cli->cryptkey, buf,8); + if (bcc > 8) + { + unibuf_to_ascii(cli->server_domain, buf+8, + sizeof(cli->server_domain)); + } + else + { + cli->server_domain[0] = 0; + } cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); if (cli->capabilities & CAP_RAW_MODE) { cli->readbraw_supported = True; cli->writebraw_supported = True; } - } else if (cli->protocol >= PROTOCOL_LANMAN1) { + DEBUG(5,("server's domain: %s bcc: %d\n", + cli->server_domain, bcc)); + } + else if (cli->protocol >= PROTOCOL_LANMAN1) + { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); @@ -2834,6 +2850,12 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } + if (cli->domain[0] == 0) + { + safe_strcpy(cli->domain, cli->server_domain, + sizeof(cli->domain)); + } + if (cli->pwd.cleartext || cli->pwd.null_pwd) { fstring passwd, ntpasswd; @@ -2885,13 +2907,12 @@ BOOL cli_establish_connection(struct cli_state *cli, unsigned char lm_sess_pwd[24]; unsigned char nt_sess_pwd[128]; size_t nt_sess_pwd_len; - extern pstring global_myname; if (cli->use_ntlmv2 != False) { DEBUG(10,("cli_establish_connection: NTLMv2\n")); pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, - cli->user_name, global_myname, cli->domain); + cli->user_name, calling->name, cli->domain); } else { -- cgit From cba7662da1fd9ed8bd9f9969417adf1fe5f0d33b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 7 Oct 1999 22:10:29 +0000 Subject: - added rudimentary CAP_UNICODE support because i thought it was part of a problem i was having. - added rudimentary CAP_STATUS32 support for same reason. - added hard-coded, copy-the-same-data-from-over-the-wire version of CAP_EXTENDED_SECURITY, which is a security-blob to encapsulate GSSAPI which encodes SPNEGO which is used to negotiate Kerberos or NTLMSSP. i have implemented NTLMSSP which negotiates NTLMv1 or NTLMv2 and 40-bit or 128-bit etc. i have implemented NTLMv1 / 40-bit. *whew*. (This used to be commit e5b80bd2f76fda70e41e4a9007eb035dab92ed8e) --- source3/libsmb/clientgen.c | 466 ++++++++++++++++++++++++++++++++++++++------- source3/libsmb/pwd_cache.c | 21 ++ 2 files changed, 417 insertions(+), 70 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6d704dc144..8db5bd6e00 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -42,6 +42,56 @@ int cli_set_port(struct cli_state *cli, int port) } +/**************************************************************************** +copy a string (unicode or otherwise) into an SMB buffer. skips a string +plus points to next +****************************************************************************/ +static char *cli_put_string(struct cli_state *cli, char *p, const char *str, + BOOL skip_end) +{ + uint16 flgs2 = SVAL(cli->outbuf, smb_flg2); + if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) + { + p = align2(p, cli->outbuf); + p = ascii_to_unibuf(p, str, 1024); + if (skip_end) + { + CVAL(p, 0) = 0; p++; + CVAL(p, 0) = 0; p++; + } + return p; + } + else + { + pstrcpy(p, str); + p = skip_string(p, 1); + if (skip_end) + { + CVAL(p, 0) = 0; p++; + } + return p; + } +} + +/**************************************************************************** +copy a string (unicode or otherwise) into an SMB buffer. skips a string +plus points to next +****************************************************************************/ +static const char *cli_get_string(struct cli_state *cli, const char *p, + char *str, size_t str_len) +{ + uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); + if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) + { + return unibuf_to_ascii(str, p, str_len); + } + else + { + safe_strcpy(str, p, str_len-1); + return skip_string(p, 1); + } +} + /**************************************************************************** recv an smb ****************************************************************************/ @@ -202,14 +252,24 @@ setup basics in a outgoing packet ****************************************************************************/ static void cli_setup_packet(struct cli_state *cli) { + uint16 flgs2 = 0; + flgs2 |= FLAGS2_LONG_PATH_COMPONENTS; + flgs2 |= FLAGS2_32_BIT_ERROR_CODES; +#if 0 + flgs2 |= FLAGS2_UNICODE_STRINGS; +#endif + flgs2 |= FLAGS2_EXT_SEC; + cli->rap_error = 0; cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); - if (cli->protocol > PROTOCOL_CORE) { + + if (cli->protocol > PROTOCOL_CORE) + { SCVAL(cli->outbuf,smb_flg,0x8); - SSVAL(cli->outbuf,smb_flg2,0x1); + SSVAL(cli->outbuf,smb_flg2,flgs2); } } @@ -705,7 +765,13 @@ BOOL cli_session_setup_x(struct cli_state *cli, char *ntpass, int ntpasslen, char *user_domain) { + uint8 eclass; + uint32 ecode; char *p; + BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY; + + DEBUG(100,("cli_session_setup. extended security: %s\n", + BOOLSTR(esec))); #ifdef DEBUG_PASSWORD DEBUG(100,("cli_session_setup. pass, ntpass\n")); @@ -739,7 +805,31 @@ BOOL cli_session_setup_x(struct cli_state *cli, pstrcpy(p,user); strupper(p); } - else + else if (esec) + { + set_message(cli->outbuf,12,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + SIVAL(cli->outbuf,smb_vwv10, CAP_EXTENDED_SECURITY|CAP_STATUS32|CAP_UNICODE); + p = smb_buf(cli->outbuf); + memcpy(p,pass,passlen); + p += passlen; + + p = cli_put_string(cli, p, "Unix", False); + p = cli_put_string(cli, p, "Samba", False); + p = cli_put_string(cli, p, "", False); + p++; + + set_message(cli->outbuf,12,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + } + else { set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; @@ -758,44 +848,65 @@ BOOL cli_session_setup_x(struct cli_state *cli, p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpass,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - pstrcpy(p,user); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,user_domain); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,"Unix");p = skip_string(p,1); - CVAL(p, 0) = 0; p++; - pstrcpy(p,"Samba");p = skip_string(p,1); + strupper(user); + p = cli_put_string(cli, p, user, False); + strupper(user_domain); + p = cli_put_string(cli, p, user_domain, False); + p = cli_put_string(cli, p, "Unix", True); + p = cli_put_string(cli, p, "Samba", False); + set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - cli_send_smb(cli, True); - if (!cli_receive_smb(cli)) + cli_send_smb(cli, True); + if (!cli_receive_smb(cli)) { DEBUG(10,("cli_session_setup_x: receive smb failed\n")); return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } + if (cli_error(cli, &eclass, &ecode)) + { + uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); + if (IS_BITS_CLR_ALL(flgs2, FLAGS2_32_BIT_ERROR_CODES)) + { + if (ecode != ERRmoredata || !esec) + { + return False; + } + } + else if (ecode != 0xC0000016) /* STATUS_MORE_PROCESSING_REQD */ + { + return False; + } + } + + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); - - if (cli->protocol >= PROTOCOL_NT1) { - /* - * Save off some of the connected server - * info. - */ - char *server_domain,*server_os,*server_type; - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); - fstrcpy(cli->server_os, server_os); - fstrcpy(cli->server_type, server_type); - fstrcpy(cli->server_domain, server_domain); + if (cli->protocol >= PROTOCOL_NT1) + { + if (esec) + { + } + else + { + /* + * Save off some of the connected server + * info. + */ + char *server_domain; + char *server_os; + char *server_type; + + server_os = smb_buf(cli->inbuf); + server_type = skip_string(server_os,1); + server_domain = skip_string(server_type,1); + + fstrcpy(cli->server_os, server_os); + fstrcpy(cli->server_type, server_type); + fstrcpy(cli->server_domain, server_domain); + } } return True; @@ -1003,8 +1114,7 @@ BOOL cli_send_tconX(struct cli_state *cli, "\\\\%s\\%s", cli->desthost, share); strupper(fullshare); - set_message(cli->outbuf,4, - 2 + strlen(fullshare) + passlen + strlen(dev),True); + set_message(cli->outbuf,4, 0, True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -1014,9 +1124,11 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - fstrcpy(p,fullshare); - p = skip_string(p,1); - pstrcpy(p,dev); + p = cli_put_string(cli, p, fullshare, False); + fstrcpy(p, dev); + p = skip_string(p, 1); + + set_message(cli->outbuf,4,PTR_DIFF(p, smb_buf(cli->outbuf)),False); SCVAL(cli->inbuf,smb_rcls, 1); @@ -1030,8 +1142,10 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->dev, "A:"); - if (cli->protocol >= PROTOCOL_NT1) { - fstrcpy(cli->dev, smb_buf(cli->inbuf)); + if (cli->protocol >= PROTOCOL_NT1) + { + cli_get_string(cli, smb_buf(cli->inbuf), + cli->dev, sizeof(cli->dev)); } if (strcasecmp(share,"IPC$")==0) { @@ -1039,8 +1153,8 @@ BOOL cli_send_tconX(struct cli_state *cli, } /* only grab the device if we have a recent protocol level */ - if (cli->protocol >= PROTOCOL_NT1 && - smb_buflen(cli->inbuf) == 3) { + if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) + { /* almost certainly win95 - enable bug fixes */ cli->win95 = True; } @@ -1304,8 +1418,9 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) SSVAL(cli->outbuf,smb_vwv8,openfn); p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - p = skip_string(p,1); + p = cli_put_string(cli, p, fname, False); + + set_message(cli->outbuf,15,PTR_DIFF(p, smb_buf(cli->outbuf)),False); cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { @@ -2412,23 +2527,37 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - memcpy(cli->cryptkey, buf,8); - if (bcc > 8) + + cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); + if (IS_BITS_SET_ALL(cli->capabilities, CAP_RAW_MODE)) { - unibuf_to_ascii(cli->server_domain, buf+8, - sizeof(cli->server_domain)); + cli->readbraw_supported = True; + cli->writebraw_supported = True; } - else + + if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) { + /* oops, some kerberos-related nonsense. */ + /* expect to have to use NTLMSSP-over-SMB */ + DEBUG(10,("unknown kerberos-related (?) blob\n")); + memset(cli->cryptkey, 0, 8); cli->server_domain[0] = 0; } - cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (cli->capabilities & CAP_RAW_MODE) { - cli->readbraw_supported = True; - cli->writebraw_supported = True; + else + { + memcpy(cli->cryptkey, buf,8); + if (bcc > 8) + { + unibuf_to_ascii(cli->server_domain, buf+8, + sizeof(cli->server_domain)); + } + else + { + cli->server_domain[0] = 0; + } + DEBUG(5,("server's domain: %s bcc: %d\n", + cli->server_domain, bcc)); } - DEBUG(5,("server's domain: %s bcc: %d\n", - cli->server_domain, bcc)); } else if (cli->protocol >= PROTOCOL_LANMAN1) { @@ -2659,24 +2788,26 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) if (eclass) *eclass = 0; if (num ) *num = 0; - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + { /* 32 bit error codes detected */ uint32 nt_err = IVAL(cli->inbuf,smb_rcls); if (num) *num = nt_err; DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; - switch (nt_err & 0xFFFFFF) { - case NT_STATUS_ACCESS_VIOLATION: return EACCES; - case NT_STATUS_NO_SUCH_FILE: return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; - case NT_STATUS_INVALID_HANDLE: return EBADF; - case NT_STATUS_NO_MEMORY: return ENOMEM; - case NT_STATUS_ACCESS_DENIED: return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION: return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; + switch (nt_err & 0xFFFFFF) + { + case NT_STATUS_ACCESS_VIOLATION : return EACCES; + case NT_STATUS_NO_SUCH_FILE : return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE : return ENODEV; + case NT_STATUS_INVALID_HANDLE : return EBADF; + case NT_STATUS_NO_MEMORY : return ENOMEM; + case NT_STATUS_ACCESS_DENIED : return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; + case NT_STATUS_SHARING_VIOLATION : return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID : return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; } /* for all other cases - a default code */ @@ -2856,7 +2987,202 @@ BOOL cli_establish_connection(struct cli_state *cli, sizeof(cli->domain)); } - if (cli->pwd.cleartext || cli->pwd.null_pwd) + if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) + { + /* common to both session setups */ + char pwd_buf[128]; + int buf_len; + char *p; + char *e = pwd_buf + sizeof(pwd_buf); + + /* 1st session setup */ + char pwd_data[34] = + { + 0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, + 0x05, 0x02, 0xa0, 0x36, 0x30, 0x34, 0xa0, 0x0e, + 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, + 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22, + 0x04, 0x20 + }; + /* 2nd session setup */ +#if 0 + char pwd_data_2[8] = + { + 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b + }; +#endif + char pwd_data_2[8] = + { + 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b + }; + prs_struct auth_resp; + int resp_len; + char *p_gssapi; + char *p_oem; + char *p_gssapi_end; + uint16 gssapi_len; + + memset(pwd_buf, 0, sizeof(pwd_buf)); + memcpy(pwd_buf, pwd_data, sizeof(pwd_data)); + p = pwd_buf + sizeof(pwd_data); + + safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1); + p = skip_string(p, 1); + CVAL(p, 0) = 0x1; + p += 4; + if (cli->ntlmssp_cli_flgs == 0) + { + cli->ntlmssp_cli_flgs = + NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_OEM | + NTLMSSP_NEGOTIATE_SIGN | + NTLMSSP_NEGOTIATE_SEAL | + NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN | + NTLMSSP_NEGOTIATE_00001000 | + NTLMSSP_NEGOTIATE_00002000; +#if 0 + cli->ntlmssp_cli_flgs = 0x80008207; +#endif + } + SIVAL(p, 0, cli->ntlmssp_cli_flgs); + p += 4; + p += 16; /* skip some NULL space */ + CVAL(p, 0) = 0; p++; /* alignment */ + + buf_len = PTR_DIFF(p, pwd_buf); + + /* first session negotiation stage */ + if (!cli_session_setup_x(cli, cli->user_name, + pwd_buf, buf_len, + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) + { + cli_shutdown(cli); + } + return False; + } + + DEBUG(1,("1st session setup ok\n")); + + if (*cli->server_domain || *cli->server_os || *cli->server_type) + { + DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + cli->server_domain, + cli->server_os, + cli->server_type)); + } + + p = smb_buf(cli->inbuf) + 0x2f; + cli->ntlmssp_cli_flgs = IVAL(p, 0); /* 0x80808a05; */ + p += 4; + memcpy(cli->cryptkey, p, 8); +#ifdef DEBUG_PASSWORD + DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n", + cli->ntlmssp_cli_flgs)); + + DEBUG(100,("cli_session_setup_x: crypt key\n")); + dump_data(100, cli->cryptkey, 8); +#endif + prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); + + pwd_make_lm_nt_owf(&cli->pwd, cli->cryptkey); + + create_ntlmssp_resp(&cli->pwd, cli->domain, + cli->user_name, cli->calling.name, + cli->ntlmssp_cli_flgs, + &auth_resp); + prs_link(NULL, &auth_resp, NULL); + + memset(pwd_buf, 0, sizeof(pwd_buf)); + p = pwd_buf; + + CVAL(p, 0) = 0xa1; p++; + CVAL(p, 0) = 0x82; p++; + p_gssapi = p; p+= 2; + CVAL(p, 0) = 0x30; p++; + CVAL(p, 0) = 0x82; p++; + p += 2; + + CVAL(p, 0) = 0xa2; p++; + CVAL(p, 0) = 0x82; p++; + p_oem = p; p+= 2; + CVAL(p, 0) = 0x04; p++; + CVAL(p, 0) = 0x82; p++; + p += 2; + + p_gssapi_end = p; + + safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1); + p = skip_string(p, 1); + CVAL(p, 0) = 0x3; + p += 4; + + resp_len = mem_buf_len(auth_resp.data); + mem_buf_copy(p, auth_resp.data, 0, resp_len); + prs_mem_free(&auth_resp); + + p += resp_len; + + buf_len = PTR_DIFF(p, pwd_buf); + gssapi_len = PTR_DIFF(p, p_gssapi_end) + 12; + + *p_gssapi++ = (gssapi_len >> 8) & 0xff; + *p_gssapi++ = gssapi_len & 0xff; + + p_gssapi += 2; + gssapi_len -= 4; + + *p_gssapi++ = (gssapi_len >> 8) & 0xff; + *p_gssapi++ = gssapi_len & 0xff; + + gssapi_len -= 4; + + *p_oem++ = (gssapi_len >> 8) & 0xff; + *p_oem++ = gssapi_len & 0xff; + + p_oem += 2; + gssapi_len -= 4; + + *p_oem++ = (gssapi_len >> 8) & 0xff; + *p_oem++ = gssapi_len & 0xff; + + /* second session negotiation stage */ + if (!cli_session_setup_x(cli, cli->user_name, + pwd_buf, buf_len, + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) + { + cli_shutdown(cli); + } + return False; + } + + DEBUG(1,("2nd session setup ok\n")); + + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + NULL, 0)) + + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) + { + cli_shutdown(cli); + } + return False; + } + } + } + else if (cli->pwd.cleartext || cli->pwd.null_pwd) { fstring passwd, ntpasswd; int pass_len = 0, ntpass_len = 0; @@ -2925,9 +3251,9 @@ BOOL cli_establish_connection(struct cli_state *cli, /* attempt encrypted session */ if (!cli_session_setup_x(cli, cli->user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, nt_sess_pwd_len, - cli->domain)) + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + (char*)nt_sess_pwd, nt_sess_pwd_len, + cli->domain)) { DEBUG(1,("failed session setup\n")); diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 655df5be8a..c8b0e6a442 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -34,6 +34,7 @@ void pwd_init(struct pwd_info *pwd) bzero(pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); bzero(pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); bzero(pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + pwd->nt_owf_len = 0; pwd->null_pwd = True; /* safest option... */ pwd->cleartext = False; @@ -259,6 +260,14 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], ****************************************************************************/ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) { + if (pwd->null_pwd) + { +#ifdef DEBUG_PASSWORD + DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n")); +#endif + pwd->nt_owf_len = 0; + return; + } pwd_deobfuscate(pwd); SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); @@ -291,6 +300,18 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar *nt_owf, size_t *nt_owf_len) { + if (pwd->null_pwd) + { +#ifdef DEBUG_PASSWORD + DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n")); +#endif + if (nt_owf_len != NULL) + { + *nt_owf_len = 0; + } + return; + } + pwd_deobfuscate(pwd); if (lm_owf != NULL) { -- cgit From 09e6f6eb9cdd14dcd63c828eddef92abdcc5819c Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 14 Oct 1999 18:49:24 +0000 Subject: adding CAP_EXTENDED_SECURITY support in a hurry last week. forgot to deal with linking issues in other binaries (This used to be commit 57f95a01988fb4035b2e4448f4fd3ef0d652c106) --- source3/libsmb/smbencrypt.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b833cbd377..b4f2cb1601 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -400,3 +400,32 @@ BOOL nt_decrypt_string2(STRING2 *out, const STRING2 *in, char nt_hash[16]) return True; } + +/******************************************************************* + creates a DCE/RPC bind authentication response + + - initialises the parse structure. + - dynamically allocates the header data structure + - caller is expected to free the header data structure once used. + + ********************************************************************/ +void create_ntlmssp_resp(struct pwd_info *pwd, + char *domain, char *user_name, char *my_name, + uint32 ntlmssp_cli_flgs, + prs_struct *auth_resp) +{ + RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; + unsigned char lm_owf[24]; + unsigned char nt_owf[128]; + size_t nt_owf_len; + + pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len); + + make_rpc_auth_ntlmssp_resp(&ntlmssp_resp, + lm_owf, nt_owf, nt_owf_len, + domain, user_name, my_name, + ntlmssp_cli_flgs); + + smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0); + mem_realloc_data(auth_resp->data, auth_resp->offset); +} -- cgit From 81711b9c5aec21bfe94cbde3349268a89dac53c6 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 14 Oct 1999 19:45:52 +0000 Subject: const issues (This used to be commit 858f79b362dce8aa06013533209bc982cb99d33d) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8db5bd6e00..f50cd19c38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -77,7 +77,7 @@ static char *cli_put_string(struct cli_state *cli, char *p, const char *str, copy a string (unicode or otherwise) into an SMB buffer. skips a string plus points to next ****************************************************************************/ -static const char *cli_get_string(struct cli_state *cli, const char *p, +static const char *cli_get_string(struct cli_state *cli, char *p, char *str, size_t str_len) { uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); -- cgit From 87d92a1f1182a6b4e4dbe91d7f574c7ac8aecb21 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 19 Oct 1999 19:55:43 +0000 Subject: need status codes from cli_net_req_chal() and cli_net_auth2(). this format is what i would like _all_ these functions to be (returning status codes, not BOOL) but that's a horrendous amount of work at the moment :) (This used to be commit 02f240604241367f146b26934ad1a1b2563430de) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f50cd19c38..90ea3d12bf 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1596,7 +1596,8 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t if (size == 0) return 0; - while (received < blocks) { + while (received < blocks) + { int size2; while (issued - received < mpx && issued < blocks) { -- cgit From 6af79fb09dc17f4d441dac6e29689c4ee9be5aa7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 21 Oct 1999 15:38:59 +0000 Subject: split modify_trust_account_password into a separate module. (This used to be commit 479fc93bd03fb961dd1e8093a911cf0a3be7071f) --- source3/libsmb/clienttrust.c | 211 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 211 insertions(+) create mode 100644 source3/libsmb/clienttrust.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clienttrust.c b/source3/libsmb/clienttrust.c new file mode 100644 index 0000000000..1a2d7a7faa --- /dev/null +++ b/source3/libsmb/clienttrust.c @@ -0,0 +1,211 @@ +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Andrew Tridgell 1992-1997, + * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, + * Copyright (C) Paul Ashton 1997. + * Copyright (C) Jeremy Allison 1998. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + +extern int DEBUGLEVEL; +extern pstring scope; +extern pstring global_myname; + +/********************************************************* + Change the domain password on the PDC. +**********************************************************/ + +static BOOL modify_trust_password( char *domain, char *remote_machine, + unsigned char orig_trust_passwd_hash[16], + unsigned char new_trust_passwd_hash[16], + uint16 sec_chan) +{ + uint16 nt_pipe_fnum; + struct cli_state cli; + struct nmb_name calling, called; + + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + ZERO_STRUCT(cli); + if(cli_initialise(&cli) == NULL) + { + DEBUG(0,("modify_trust_password: unable to initialize client \ +connection.\n")); + return False; + } + + if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) + { + DEBUG(0,("modify_trust_password: Can't resolve address for \ +%s\n", remote_machine)); + return False; + } + + if (ismyip(cli.dest_ip)) + { + DEBUG(0,("modify_trust_password: Machine %s is one of our \ +addresses. Cannot add to ourselves.\n", remote_machine)); + return False; + } + + cli.protocol = PROTOCOL_NT1; + + pwd_set_nullpwd(&cli.pwd); + + if (!cli_establish_connection(&cli, remote_machine, &cli.dest_ip, + &calling, &called, + "IPC$", "IPC", False, True)) + { + fstring errstr; + cli_safe_errstr(&cli, errstr, sizeof(errstr)); + DEBUG(0,("modify_trust_password: machine %s rejected the SMB \ +session. Error was : %s.\n", remote_machine, errstr )); + cli_shutdown(&cli); + return False; + } + + + if (cli.protocol != PROTOCOL_NT1) + { + DEBUG(0,("modify_trust_password: machine %s didn't negotiate \ +NT protocol.\n", remote_machine)); + cli_shutdown(&cli); + return False; + } + + if (!(IS_BITS_SET_ALL(cli.sec_mode, 1))) + { + DEBUG(0,("modify_trust_password: machine %s isn't in user \ +level security mode\n", remote_machine)); + cli_shutdown(&cli); + return False; + } + + /* + * Ok - we have an anonymous connection to the IPC$ share. + * Now start the NT Domain stuff :-). + */ + + if (!cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum)) + { + fstring errstr; + cli_safe_errstr(&cli, errstr, sizeof(errstr)); + DEBUG(0,("modify_trust_password: unable to open the domain \ +client session to server %s. Error was : %s.\n", remote_machine, errstr )); + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + if (cli_nt_setup_creds(&cli, nt_pipe_fnum, + cli.mach_acct, global_myname, + orig_trust_passwd_hash, sec_chan) != 0x0) + { + fstring errstr; + cli_safe_errstr(&cli, errstr, sizeof(errstr)); + DEBUG(0,("modify_trust_password: unable to setup the PDC \ +credentials to server %s. Error was : %s.\n", remote_machine, errstr )); + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + if (!cli_nt_srv_pwset( &cli, nt_pipe_fnum, new_trust_passwd_hash, + sec_chan ) ) + { + fstring errstr; + cli_safe_errstr(&cli, errstr, sizeof(errstr)); + DEBUG(0,("modify_trust_password: unable to change password for \ +workstation %s in domain %s to Domain controller %s. Error was %s.\n", + global_myname, domain, remote_machine, errstr )); + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + + return True; +} + +/************************************************************************ + Change the trust account password for a domain. + The user of this function must have locked the trust password file for + update. +************************************************************************/ + +BOOL change_trust_account_password(char *domain, char *remote_machine_list, + uint16 sec_chan) +{ + fstring remote_machine; + unsigned char old_trust_passwd_hash[16]; + unsigned char new_trust_passwd_hash[16]; + time_t lct; + BOOL res; + + if(!get_trust_account_password( old_trust_passwd_hash, &lct)) { + DEBUG(0,("change_trust_account_password: unable to read the machine \ +account password for domain %s.\n", domain)); + return False; + } + + /* + * Create the new (random) password. + */ + generate_random_buffer( new_trust_passwd_hash, 16, True); + + while(remote_machine_list && + next_token(&remote_machine_list, remote_machine, + LIST_SEP, sizeof(remote_machine))) { + strupper(remote_machine); + if(modify_trust_password( domain, remote_machine, + old_trust_passwd_hash, new_trust_passwd_hash, sec_chan)) { + DEBUG(0,("%s : change_trust_account_password: Changed password for \ +domain %s.\n", timestring(), domain)); + /* + * Return the result of trying to write the new password + * back into the trust account file. + */ + res = set_trust_account_password(new_trust_passwd_hash); + memset(new_trust_passwd_hash, 0, 16); + memset(old_trust_passwd_hash, 0, 16); + return res; + } + } + + memset(new_trust_passwd_hash, 0, 16); + memset(old_trust_passwd_hash, 0, 16); + + DEBUG(0,("%s : change_trust_account_password: Failed to change password for \ +domain %s.\n", timestring(), domain)); + return False; +} + -- cgit From 8e1f542ddf97fef925a88e2c3d9c1e82fb2f6683 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 25 Oct 1999 16:22:08 +0000 Subject: one of those wonderful moments when running against a different MSRPC implementation (NT5) when you discover that your code is trash. samr_enum_dom_users(), samr_enum_dom_aliases() and samr_enum_dom_groups() all take a HANDLE for multiple-call enumeration purposes. (This used to be commit 19490d8b4fb8a103f3df4e6104f6f22937b0c518) --- source3/libsmb/clientgen.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 90ea3d12bf..d792eeeaa1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -255,10 +255,10 @@ static void cli_setup_packet(struct cli_state *cli) uint16 flgs2 = 0; flgs2 |= FLAGS2_LONG_PATH_COMPONENTS; flgs2 |= FLAGS2_32_BIT_ERROR_CODES; + flgs2 |= FLAGS2_EXT_SEC; #if 0 flgs2 |= FLAGS2_UNICODE_STRINGS; #endif - flgs2 |= FLAGS2_EXT_SEC; cli->rap_error = 0; cli->nt_error = 0; @@ -750,8 +750,6 @@ prots[] = {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, -#if 0 -#endif {-1,NULL} }; @@ -842,7 +840,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,0); + SIVAL(cli->outbuf,smb_vwv11, CAP_STATUS32); p = smb_buf(cli->outbuf); memcpy(p,pass,passlen); p += SVAL(cli->outbuf,smb_vwv7); @@ -3091,7 +3089,17 @@ BOOL cli_establish_connection(struct cli_state *cli, #endif prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); - pwd_make_lm_nt_owf(&cli->pwd, cli->cryptkey); + if (cli->use_ntlmv2 != False) + { + DEBUG(10,("cli_establish_connection: NTLMv2\n")); + pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, + cli->user_name, calling->name, cli->domain); + } + else + { + DEBUG(10,("cli_establish_connection: NTLMv1\n")); + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + } create_ntlmssp_resp(&cli->pwd, cli->domain, cli->user_name, cli->calling.name, -- cgit From 2adba4bfbbe360cd8c1eca1b90354fd63c503dd0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 25 Oct 1999 16:23:42 +0000 Subject: the new CAP_EXTENDED_SECURITY code needed to support NTLMv2. also removed switching on CAP_STATUS32 from non-CAP_EXTENDED_SECURITY code (enabled for test purposes only) (This used to be commit 96d8e14f50fda8047d209fa0b94b98a95ce51f21) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d792eeeaa1..4bffb5aa3e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -840,7 +840,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SIVAL(cli->outbuf,smb_vwv11, CAP_STATUS32); + SIVAL(cli->outbuf,smb_vwv11, 0); p = smb_buf(cli->outbuf); memcpy(p,pass,passlen); p += SVAL(cli->outbuf,smb_vwv7); -- cgit From cae821d45926157a250e9fa047e0c8aa8c0c2c54 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 4 Nov 1999 00:09:15 +0000 Subject: adding experimental set user password command to rpcclient, it returns error wrong password against nt. ???? (This used to be commit b3f16e6b5aa5ba1b6afa38ad698646c8e765ec90) --- source3/libsmb/smbencrypt.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b4f2cb1601..b25e27550c 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -429,3 +429,69 @@ void create_ntlmssp_resp(struct pwd_info *pwd, smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0); mem_realloc_data(auth_resp->data, auth_resp->offset); } + +/*********************************************************** + decode a password buffer +************************************************************/ +BOOL decode_pw_buffer(const char buffer[516], char *new_passwd, + int new_passwd_size, BOOL nt_pass_set) +{ + /* + * The length of the new password is in the last 4 bytes of + * the data buffer. + */ + + uint32 new_pw_len = IVAL(buffer, 512); + if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1) + { + DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len)); + return False; + } + + if (nt_pass_set) + { + /* + * nt passwords are in unicode + */ + int uni_pw_len = new_pw_len; + new_pw_len /= 2; + unibuf_to_ascii(new_passwd, &buffer[512-uni_pw_len], new_pw_len); + } + else + { + memcpy(new_passwd, &buffer[512-new_pw_len], new_pw_len); + new_passwd[new_pw_len] = '\0'; + } + + return True; +} + +/*********************************************************** + encode a password buffer +************************************************************/ +BOOL encode_pw_buffer(char buffer[516], const char *new_pass, + int new_pw_len, BOOL nt_pass_set) +{ + if (nt_pass_set) + { + /* + * nt passwords are in unicode. last char overwrites NULL + * in ascii_to_unibuf, so use SIVAL *afterwards*. + */ + new_pw_len *= 2; + ascii_to_unibuf(&buffer[512-new_pw_len], new_pass, new_pw_len); + } + else + { + memcpy(&buffer[512-new_pw_len], new_pass, new_pw_len); + } + + /* + * The length of the new password is in the last 4 bytes of + * the data buffer. + */ + + SIVAL(buffer, 512, new_pw_len); + + return True; +} -- cgit From fe8383382d5b8221093a5340705c4e5b3731a249 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 4 Nov 1999 21:41:36 +0000 Subject: samuserset -p password. YESSSSS :) you have to use "ntlmv1" at the moment (i.e set client ntlmv2 = no). (This used to be commit f52504c553becc64b89d546a57b1bd9cf1bc5b5c) --- source3/libsmb/smbencrypt.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b25e27550c..46e979fd18 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -442,6 +442,11 @@ BOOL decode_pw_buffer(const char buffer[516], char *new_passwd, */ uint32 new_pw_len = IVAL(buffer, 512); + +#ifdef DEBUG_PASSWORD + dump_data(100, buffer, 516); +#endif + if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1) { DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len)); @@ -472,6 +477,8 @@ BOOL decode_pw_buffer(const char buffer[516], char *new_passwd, BOOL encode_pw_buffer(char buffer[516], const char *new_pass, int new_pw_len, BOOL nt_pass_set) { + generate_random_buffer(buffer, 516, True); + if (nt_pass_set) { /* @@ -493,5 +500,9 @@ BOOL encode_pw_buffer(char buffer[516], const char *new_pass, SIVAL(buffer, 512, new_pw_len); +#ifdef DEBUG_PASSWORD + dump_data(100, buffer, 516); +#endif + return True; } -- cgit From 32dedee7f006351c505801dc207dbc46ca08044a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 5 Nov 1999 18:40:38 +0000 Subject: experimental spoolss rpcclient commands (This used to be commit c86edef90e7c96d5a99be29e2d2a3679ed26d97d) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4bffb5aa3e..b153654591 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -998,6 +998,7 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, uchar *srv_key = (uchar *)cli->cryptkey; uchar nt_owf[16]; uchar kr[16]; + HMACMD5Context ctx; SMBgenclientchals(cli->lm_cli_chal, cli->nt_cli_chal, @@ -1023,6 +1024,11 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, cli->nt_cli_chal, cli->nt_cli_chal_len, &ntpword[cli->nt_cli_chal_len]); *ntpasslen = cli->nt_cli_chal_len + 16; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, &ctx); + hmac_md5_final(cli->sess_key, &ctx); + } else { -- cgit From ccc8585567804d6a7e6f684a97d58871e2fd9f8a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 18 Nov 1999 00:26:11 +0000 Subject: added regqueryval command (experimental) to get reg_io_q_info() and reg_io_r_info() working properly. previously they weren't well understood (well, they were the first of the registry functions i did, back in december 97, ok??? :-) set ntversion to 0x1 in SAMQUERY, so that we reply same as NT4 srv. (This used to be commit 98ddeaf442cb30972cb281bf0489a6e5f7eb2883) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 54b1779f44..9dca4731ad 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -742,7 +742,7 @@ static int build_dgram(char *buf,struct packet_struct *p) /* put in the header */ ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2); if (dgram->header.flags.more) ubuf[1] |= 1; if (dgram->header.flags.first) ubuf[1] |= 2; RSSVAL(ubuf,2,dgram->header.dgm_id); -- cgit From 3365a2fd234966ecfcd06d2295cbd085c7bbd8c6 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 19 Nov 1999 01:37:16 +0000 Subject: The First Necessary UNICODE String Support. the random workstation trust account password is TOTAL garbage. i mean, complete garbage. it's nowhere CLOSE to being a UNICODE string. therefore we can't just take every second character. created nt_owf_genW() which creates NT#(password) instead of NT#(Unicode(pw)). followed through to the password setting in srv_samr.c (This used to be commit 172601b84ae94044b27ded917d4e0e21e47a5a66) --- source3/libsmb/smbencrypt.c | 86 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 46e979fd18..659dba6562 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -132,6 +132,35 @@ void E_md4hash(uchar *passwd, uchar *p16) mdfour(p16, (unsigned char *)wpwd, len); } +/* Does the LM owf of a user's password */ +void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16]) +{ + char passwd[15]; + + memset(passwd,'\0',15); + if (pwd != NULL) + { + unistr2_to_ascii( passwd, pwd, sizeof(passwd)-1); + } + + /* Mangle the passwords into Lanman format */ + passwd[14] = '\0'; + strupper(passwd); + + /* Calculate the SMB (lanman) hash functions of the password */ + + memset(p16, '\0', 16); + E_P16((uchar *) passwd, (uchar *)p16); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); + dump_data(120, passwd, strlen(passwd)); + dump_data(100, p16, 16); +#endif + /* clear out local copy of user's password (just being paranoid). */ + bzero(passwd, sizeof(passwd)); +} + /* Does the LM owf of a user's password */ void lm_owf_gen(const char *pwd, uchar p16[16]) { @@ -161,6 +190,30 @@ void lm_owf_gen(const char *pwd, uchar p16[16]) bzero(passwd, sizeof(passwd)); } +/* Does both the NT and LM owfs of a user's password */ +void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]) +{ + UNISTR2 passwd; + + memset(&passwd,'\0',sizeof(passwd)); + if (pwd != NULL) + { + copy_unistr2(&passwd, pwd); + } + + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + mdfour(nt_p16, (unsigned char *)passwd.buffer, passwd.uni_str_len * 2); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_owf_gen: pwd, nt#\n")); + dump_data(120, (const char*)passwd.buffer, passwd.uni_str_len * 2); + dump_data(100, nt_p16, 16); +#endif + /* clear out local copy of user's password (just being paranoid). */ + memset(&passwd, 0, sizeof(passwd)); +} + /* Does both the NT and LM owfs of a user's password */ void nt_owf_gen(const char *pwd, uchar nt_p16[16]) { @@ -177,7 +230,7 @@ void nt_owf_gen(const char *pwd, uchar nt_p16[16]) E_md4hash((uchar *)passwd, nt_p16); #ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); + DEBUG(100,("nt_owf_gen: pwd, nt#\n")); dump_data(120, passwd, strlen(passwd)); dump_data(100, nt_p16, 16); #endif @@ -185,6 +238,13 @@ void nt_owf_gen(const char *pwd, uchar nt_p16[16]) bzero(passwd, sizeof(passwd)); } +/* Does both the NT and LM owfs of a user's UNICODE password */ +void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16]) +{ + nt_owf_genW(pwd, nt_p16); + lm_owf_genW(pwd, lm_p16); +} + /* Does both the NT and LM owfs of a user's password */ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16]) { @@ -434,39 +494,27 @@ void create_ntlmssp_resp(struct pwd_info *pwd, decode a password buffer ************************************************************/ BOOL decode_pw_buffer(const char buffer[516], char *new_passwd, - int new_passwd_size, BOOL nt_pass_set) + int new_passwd_size, uint32 *new_pw_len) { /* * The length of the new password is in the last 4 bytes of * the data buffer. */ - uint32 new_pw_len = IVAL(buffer, 512); + (*new_pw_len) = IVAL(buffer, 512); #ifdef DEBUG_PASSWORD dump_data(100, buffer, 516); #endif - if (new_pw_len < 0 || new_pw_len > new_passwd_size - 1) + if ((*new_pw_len) < 0 || (*new_pw_len) > new_passwd_size - 1) { - DEBUG(0,("check_oem_password: incorrect password length (%d).\n", new_pw_len)); + DEBUG(0,("check_oem_password: incorrect password length (%d).\n", (*new_pw_len))); return False; } - if (nt_pass_set) - { - /* - * nt passwords are in unicode - */ - int uni_pw_len = new_pw_len; - new_pw_len /= 2; - unibuf_to_ascii(new_passwd, &buffer[512-uni_pw_len], new_pw_len); - } - else - { - memcpy(new_passwd, &buffer[512-new_pw_len], new_pw_len); - new_passwd[new_pw_len] = '\0'; - } + memcpy(new_passwd, &buffer[512-(*new_pw_len)], (*new_pw_len)); + new_passwd[(*new_pw_len)] = '\0'; return True; } -- cgit From dab1a1227873f1a88dc7a4b8f63edcccd60ada85 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 19:24:01 +0000 Subject: you know what? this sort of thing makes me laugh. hmm, what functions have we got. and what data do we have. hmm.. i wonder what the NTLMv2 user session key can be... hmmm... weell.... there's some hidden data here, generated from the user password that doesn't go over-the-wire, so that's _got_ to be involved. and... that bit of data took a lot of computation to produce, so it's probably _also_ involved... and md4 no, md5? no, how about hmac_md5 yes let's try that one (the other's didn't work) oh goodie, it worked! i love it when this sort of thing happens. took all of fifteen minutes to guess it. tried concatenating client and server challenges. tried concatenating _random_ bits of client and server challenges. tried md5 of the above. tried hmac_md5 of the above. eventually, it boils down to this: kr = MD4(NT#,username,domainname) hmacntchal=hmac_md5(kr, nt server challenge) sess_key = hmac_md5(kr, hmacntchal); (This used to be commit ab174759cd210fe1be888d0c589a5b2669f7ff1e) --- source3/libsmb/clientgen.c | 9 +++++++-- source3/libsmb/pwd_cache.c | 33 ++++++++++++++++++++++++++++++++- source3/libsmb/smbencrypt.c | 2 +- 3 files changed, 40 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b153654591..26a5f25c7d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1026,8 +1026,13 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, *ntpasslen = cli->nt_cli_chal_len + 16; hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, &ctx); + hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, + &ctx); hmac_md5_final(cli->sess_key, &ctx); +#if DEBUG_PASSWORD + DEBUG(100,("session key:\n")); + dump_data(100, cli->sess_key, sizeof(cli->sess_key)); +#endif } else @@ -3262,7 +3267,7 @@ BOOL cli_establish_connection(struct cli_state *cli, } pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd, - &nt_sess_pwd_len); + &nt_sess_pwd_len, cli->sess_key); /* attempt encrypted session */ if (!cli_session_setup_x(cli, cli->user_name, diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index c8b0e6a442..c404ccb83f 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -34,6 +34,7 @@ void pwd_init(struct pwd_info *pwd) bzero(pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); bzero(pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); bzero(pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + bzero(pwd->sess_key , sizeof(pwd->sess_key )); pwd->nt_owf_len = 0; pwd->null_pwd = True; /* safest option... */ @@ -202,6 +203,8 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], const char *user, const char *server, const char *domain) { uchar kr[16]; + struct MD5Context ctx5; + HMACMD5Context ctx; DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n", user, server, domain)); @@ -230,6 +233,18 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len); pwd->nt_owf_len = pwd->nt_cli_chal_len + 16; + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(pwd->smb_nt_owf, 16, &ctx); + hmac_md5_final(pwd->sess_key, &ctx); +#if 0 + MD5Init(&ctx5); + MD5Update(&ctx5, pwd->smb_nt_owf, 16); + MD5Final(pwd->sess_key, &ctx5); +#endif + +#if DEBUG_PASSWORD +#endif + #ifdef DEBUG_PASSWORD DEBUG(100,("server cryptkey: ")); dump_data(100, srv_key, 8); @@ -249,6 +264,9 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); DEBUG(100,("lm_sess_pwd: ")); dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); + + DEBUG(100,("session key:\n")); + dump_data(100, pwd->sess_key, sizeof(pwd->sess_key)); #endif pwd->crypted = True; @@ -270,6 +288,11 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) } pwd_deobfuscate(pwd); + /* generate session key */ + mdfour(pwd->sess_key, pwd->smb_nt_pwd, 16); + + /* generate 24-byte hashes */ + SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); pwd->nt_owf_len = 24; @@ -287,6 +310,9 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); DEBUG(100,("lm_sess_pwd: ")); dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); + + DEBUG(100,("session key:\n")); + dump_data(100, pwd->sess_key, sizeof(pwd->sess_key)); #endif pwd->crypted = True; @@ -298,7 +324,8 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) gets lm and nt crypts ****************************************************************************/ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], - uchar *nt_owf, size_t *nt_owf_len) + uchar *nt_owf, size_t *nt_owf_len, + uchar *sess_key) { if (pwd->null_pwd) { @@ -321,6 +348,10 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], { memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len); } + if (sess_key != NULL) + { + memcpy(sess_key, pwd->sess_key, 16); + } if (nt_owf_len != NULL) { *nt_owf_len = pwd->nt_owf_len; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 659dba6562..6bc0e71f6f 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -479,7 +479,7 @@ void create_ntlmssp_resp(struct pwd_info *pwd, unsigned char nt_owf[128]; size_t nt_owf_len; - pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len); + pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len, NULL); make_rpc_auth_ntlmssp_resp(&ntlmssp_resp, lm_owf, nt_owf, nt_owf_len, -- cgit From 32b9508d066f002e778873edc19266a6d897f922 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 19:59:56 +0000 Subject: implement server-side generation of NTLMv2 session key. YESSS :-) (This used to be commit 1092b4f6fbdf3770c0dab756b982a562def1738e) --- source3/libsmb/pwd_cache.c | 17 +++-------------- source3/libsmb/smbencrypt.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index c404ccb83f..b360dbd199 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -203,8 +203,6 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], const char *user, const char *server, const char *domain) { uchar kr[16]; - struct MD5Context ctx5; - HMACMD5Context ctx; DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n", user, server, domain)); @@ -233,14 +231,7 @@ void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len); pwd->nt_owf_len = pwd->nt_cli_chal_len + 16; - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(pwd->smb_nt_owf, 16, &ctx); - hmac_md5_final(pwd->sess_key, &ctx); -#if 0 - MD5Init(&ctx5); - MD5Update(&ctx5, pwd->smb_nt_owf, 16); - MD5Final(pwd->sess_key, &ctx5); -#endif + SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, pwd->sess_key); #if DEBUG_PASSWORD #endif @@ -288,15 +279,13 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) } pwd_deobfuscate(pwd); - /* generate session key */ - mdfour(pwd->sess_key, pwd->smb_nt_pwd, 16); - /* generate 24-byte hashes */ - SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); pwd->nt_owf_len = 24; + SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, pwd->sess_key); + #ifdef DEBUG_PASSWORD DEBUG(100,("client cryptkey: ")); dump_data(100, cryptkey, 8); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6bc0e71f6f..3227caaa95 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -283,6 +283,34 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], #endif } +void SMBsesskeygen_ntv2(const uchar kr[16], + const uchar *nt_resp, + char sess_key[16]) +{ + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(nt_resp, 16, &ctx); + hmac_md5_final(sess_key, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBsesskeygen_ntv2:\n")); + dump_data(100, sess_key, 16); +#endif +} + +void SMBsesskeygen_ntv1(const uchar kr[16], + const uchar *nt_resp, + char sess_key[16]) +{ + mdfour(sess_key, kr, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("SMBsesskeygen_ntv2:\n")); + dump_data(100, sess_key, 16); +#endif +} + void SMBgenclientchals(char *lm_cli_chal, char *nt_cli_chal, int *nt_cli_chal_len, const char *srv, const char *dom) -- cgit From f8b82a7b9507e11595bc924def179dc1d7d79a54 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 24 Nov 1999 20:24:33 +0000 Subject: first stages of removing struct cli_state* and uint16 fnum from all msrpc client code. the intent is to hide / abstract / associate connection info behind policy handles. this makes the msrpc functions look more and more like their nt equivalents. who-hou! (This used to be commit c01b18e632aede6fce7264ef6971d7ddba945cfb) --- source3/libsmb/clientgen.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 26a5f25c7d..61ce3f9900 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -25,7 +25,6 @@ #include "includes.h" #include "trans2.h" - extern int DEBUGLEVEL; /* @@ -1331,7 +1330,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) /**************************************************************************** open a file ****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname) +int cli_nt_create(struct cli_state *cli, const char *fname) { char *p; @@ -1375,7 +1374,8 @@ int cli_nt_create(struct cli_state *cli, char *fname) /**************************************************************************** open a file ****************************************************************************/ -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) +int cli_open(struct cli_state *cli, const char *fname, + int flags, int share_mode) { char *p; unsigned openfn=0; @@ -3684,3 +3684,4 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } + -- cgit From 2803a72751cf511aa0b5e6745e1b169faa66f68a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 24 Nov 1999 22:45:09 +0000 Subject: ok. *whew*. this is the first completed part of the restructure. verified that lsaquery, lsalookupsids work, and found some bugs in the parameters of these commands :-) soo... we now have an lsa_* api that has the same arguments as the nt Lsa* api! cool! the only significant coding difference is the introduction of a user_credentials structure, containing user, domain, pass and ntlmssp flags. (This used to be commit 57bff6fe82d777e599d535f076efb2328ba1188b) --- source3/libsmb/clientgen.c | 77 +++++++++++++++++++++++++++----------------- source3/libsmb/clienttrust.c | 2 +- 2 files changed, 48 insertions(+), 31 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 61ce3f9900..94cd89e342 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,6 +31,14 @@ extern int DEBUGLEVEL; * set the port that will be used for connections by the client */ +void copy_user_creds(struct user_credentials *to, const struct user_credentials *from) +{ + safe_strcpy(to->domain , from->domain , sizeof(from->domain )-1); + safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1); + memcpy(&to->pwd, &from->pwd, sizeof(from->pwd)); + to->ntlmssp_flags = from->ntlmssp_flags; +}; + int cli_set_port(struct cli_state *cli, int port) { @@ -585,7 +593,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->rap_error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privilages = SVAL(p, 24); + cli->privileges = SVAL(p, 24); fstrcpy(cli->eff_name,p+2); } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); @@ -1003,10 +1011,10 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, cli->nt_cli_chal, &cli->nt_cli_chal_len, cli->calling.name, - cli->domain); + cli->usr.domain); nt_owf_gen(pword, nt_owf); - ntv2_owf_gen(nt_owf, cli->user_name, cli->domain, kr); + ntv2_owf_gen(nt_owf, cli->usr.user_name, cli->usr.domain, kr); /* lm # */ memcpy(pword, cli->lm_cli_chal, 8); @@ -1063,7 +1071,7 @@ BOOL cli_session_setup(struct cli_state *cli, return False; } - fstrcpy(cli->user_name, user); + fstrcpy(cli->usr.user_name, user); return cli_calc_session_pwds(cli, pword, ntpword, pass, &passlen, @@ -2695,6 +2703,15 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } +/**************************************************************************** +initialise a client structure +****************************************************************************/ +void cli_init_creds(struct cli_state *cli, const struct user_credentials *usr) +{ + copy_user_creds(&cli->usr, usr); + cli->ntlmssp_cli_flgs = usr->ntlmssp_flags; +} + /**************************************************************************** initialise a client structure ****************************************************************************/ @@ -2913,7 +2930,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", nmb_namestr(&calling), nmb_namestr(&called), inet_ntoa(cli->dest_ip), - cli->user_name, cli->domain)); + cli->usr.user_name, cli->usr.domain)); cli->fd = -1; @@ -2951,7 +2968,7 @@ BOOL cli_establish_connection(struct cli_state *cli, DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n", callingstr, calledstr, inet_ntoa(*dest_ip), - cli->user_name, cli->domain, + cli->usr.user_name, cli->usr.domain, cli->use_ntlmv2 ? "v2" : "v1")); /* establish connection */ @@ -2991,10 +3008,10 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } - if (cli->domain[0] == 0) + if (cli->usr.domain[0] == 0) { - safe_strcpy(cli->domain, cli->server_domain, - sizeof(cli->domain)); + safe_strcpy(cli->usr.domain, cli->server_domain, + sizeof(cli->usr.domain)); } if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) @@ -3064,10 +3081,10 @@ BOOL cli_establish_connection(struct cli_state *cli, buf_len = PTR_DIFF(p, pwd_buf); /* first session negotiation stage */ - if (!cli_session_setup_x(cli, cli->user_name, + if (!cli_session_setup_x(cli, cli->usr.user_name, pwd_buf, buf_len, NULL, 0, - cli->domain)) + cli->usr.domain)) { DEBUG(1,("failed session setup\n")); if (do_shutdown) @@ -3103,17 +3120,17 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->use_ntlmv2 != False) { DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, - cli->user_name, calling->name, cli->domain); + pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, + cli->usr.user_name, calling->name, cli->usr.domain); } else { DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); } - create_ntlmssp_resp(&cli->pwd, cli->domain, - cli->user_name, cli->calling.name, + create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain, + cli->usr.user_name, cli->calling.name, cli->ntlmssp_cli_flgs, &auth_resp); prs_link(NULL, &auth_resp, NULL); @@ -3172,10 +3189,10 @@ BOOL cli_establish_connection(struct cli_state *cli, *p_oem++ = gssapi_len & 0xff; /* second session negotiation stage */ - if (!cli_session_setup_x(cli, cli->user_name, + if (!cli_session_setup_x(cli, cli->usr.user_name, pwd_buf, buf_len, NULL, 0, - cli->domain)) + cli->usr.domain)) { DEBUG(1,("failed session setup\n")); if (do_shutdown) @@ -3202,12 +3219,12 @@ BOOL cli_establish_connection(struct cli_state *cli, } } } - else if (cli->pwd.cleartext || cli->pwd.null_pwd) + else if (cli->usr.pwd.cleartext || cli->usr.pwd.null_pwd) { fstring passwd, ntpasswd; int pass_len = 0, ntpass_len = 0; - if (cli->pwd.null_pwd) + if (cli->usr.pwd.null_pwd) { /* attempt null session */ passwd[0] = ntpasswd[0] = 0; @@ -3216,15 +3233,15 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt clear-text session */ - pwd_get_cleartext(&(cli->pwd), passwd); + pwd_get_cleartext(&(cli->usr.pwd), passwd); pass_len = strlen(passwd); } /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->user_name, + if (!cli_session_setup(cli, cli->usr.user_name, passwd, pass_len, ntpasswd, ntpass_len, - cli->domain)) + cli->usr.domain)) { DEBUG(1,("failed session setup\n")); if (do_shutdown) @@ -3257,23 +3274,23 @@ BOOL cli_establish_connection(struct cli_state *cli, if (cli->use_ntlmv2 != False) { DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->pwd), cli->cryptkey, - cli->user_name, calling->name, cli->domain); + pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, + cli->usr.user_name, calling->name, cli->usr.domain); } else { DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); } - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd, + pwd_get_lm_nt_owf(&(cli->usr.pwd), lm_sess_pwd, nt_sess_pwd, &nt_sess_pwd_len, cli->sess_key); /* attempt encrypted session */ - if (!cli_session_setup_x(cli, cli->user_name, + if (!cli_session_setup_x(cli, cli->usr.user_name, (char*)lm_sess_pwd, sizeof(lm_sess_pwd), (char*)nt_sess_pwd, nt_sess_pwd_len, - cli->domain)) + cli->usr.domain)) { DEBUG(1,("failed session setup\n")); @@ -3384,7 +3401,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) */ make_nmb_name(&stupid_smbserver_called , "*SMBSERVER", 0x20, scope); - pwd_set_nullpwd(&cli->pwd); + pwd_set_nullpwd(&cli->usr.pwd); if (!cli_establish_connection(cli, remote_machine, &dest_ip, &calling, &called, diff --git a/source3/libsmb/clienttrust.c b/source3/libsmb/clienttrust.c index 1a2d7a7faa..81855585e6 100644 --- a/source3/libsmb/clienttrust.c +++ b/source3/libsmb/clienttrust.c @@ -73,7 +73,7 @@ addresses. Cannot add to ourselves.\n", remote_machine)); cli.protocol = PROTOCOL_NT1; - pwd_set_nullpwd(&cli.pwd); + pwd_set_nullpwd(&cli.usr.pwd); if (!cli_establish_connection(&cli, remote_machine, &cli.dest_ip, &calling, &called, -- cgit From 30e8faaa8dac9eca2383ec0cda9cd2c9fc65d466 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 25 Nov 1999 05:34:12 +0000 Subject: previous commit added an abstraction function that didn't even have struct cli_state, uint16 fnum into the code: rpc_hnd_api_req(). modified cli_lsarpc.c to use this. the rest is const issues. (This used to be commit c1ea396de21309c4cf19fd92f2573f5257c24588) --- source3/libsmb/smbdes.c | 4 ++-- source3/libsmb/smbencrypt.c | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index ba214a2eb0..e60b93d6a2 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -259,7 +259,7 @@ static void dohash(char *out, char *in, char *key, int forw) permute(out, rl, perm6, 64); } -static void str_to_key(unsigned char *str,unsigned char *key) +static void str_to_key(const uchar *str, uchar *key) { int i; @@ -277,7 +277,7 @@ static void str_to_key(unsigned char *str,unsigned char *key) } -void smbhash(unsigned char *out, const uchar *in, unsigned char *key, int forw) +void smbhash(unsigned char *out, const uchar *in, const uchar *key, int forw) { int i; char outb[64]; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 3227caaa95..ace6cdc300 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -444,21 +444,18 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } -BOOL nt_decrypt_string2(STRING2 *out, const STRING2 *in, char nt_hash[16]) +BOOL nt_decrypt_string2(STRING2 *out, const STRING2 *in, const uchar *key) { uchar bufhdr[8]; int datalen; - uchar key[16]; - uchar *keyptr = key; - uchar *keyend = key + sizeof(key); + const uchar *keyptr = key; + const uchar *keyend = key + 16; uchar *outbuf = (uchar *)out->buffer; const uchar *inbuf = (const uchar *)in->buffer; const uchar *inbufend; - mdfour(key, nt_hash, 16); - smbhash(bufhdr, inbuf, keyptr, 0); datalen = IVAL(bufhdr, 0); -- cgit From 9b683054751866af4fb2ac79c092392e31effaff Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 26 Nov 1999 23:04:19 +0000 Subject: whoa. _major_ restructure of rpcclient. fixed some buuugs, created a few. found out that getopt() _must_ have optind set to 0 before reuse. still haven't decided what to do with the net* api yet... (This used to be commit 29c480085e786905bfd92ea3cd93658f94e96e47) --- source3/libsmb/namequery.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 149b977746..114f656d8c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -23,6 +23,7 @@ #include "includes.h" extern pstring scope; +extern pstring global_myname; extern int DEBUGLEVEL; /* nmbd.c sets this to True. */ @@ -646,7 +647,30 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) return False; } +/******************************************************** + resolve a name of format \\server_name or \\ipaddress + into a name. also, cut the \\ from the front for us. +*********************************************************/ +BOOL resolve_srv_name(const char* srv_name, fstring dest_host, + struct in_addr *ip) +{ + DEBUG(10,("resolve_srv_name: %s\n", srv_name)); + if (srv_name == NULL || strequal("\\\\.", srv_name)) + { + fstrcpy(dest_host, global_myname); + ip = interpret_addr2("127.0.0.1"); + return True; + } + + if (!strnequal("\\\\", srv_name, 2)) + { + return False; + } + + fstrcpy(dest_host, &srv_name[2]); + return resolve_name(dest_host, ip, 0x20); +} /******************************************************** find the IP address of the master browser or DMB for a workgroup -- cgit From b9b04afc354edc56c9dad8a861b4e4c8854e3d8e Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 27 Nov 1999 22:14:37 +0000 Subject: modified cli_connect_serverlist to take server list of format \\server_name \\other_server etc. (This used to be commit 4fd4aeb57455792bd8eaf81f8fa45bca6bd3e2e2) --- source3/libsmb/clientgen.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 94cd89e342..06fa97df0c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -3360,6 +3360,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) extern pstring global_myname; extern pstring scope; fstring remote_machine; + fstring desthost; struct in_addr dest_ip; struct nmb_name calling, called, stupid_smbserver_called; BOOL connected_ok = False; @@ -3382,7 +3383,7 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) standard_sub_basic(remote_machine); strupper(remote_machine); - if (!resolve_name( remote_machine, &dest_ip, 0x20)) + if (!resolve_srv_name( remote_machine, desthost, &dest_ip)) { DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_machine)); continue; @@ -3394,8 +3395,8 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) continue; } - make_nmb_name(&calling, global_myname , 0x0 , scope); - make_nmb_name(&called , remote_machine, 0x20, scope); + make_nmb_name(&calling, global_myname, 0x0 , scope); + make_nmb_name(&called , desthost , 0x20, scope); /* stupid microsoft destruction of the ability of netbios * to provide multiple netbios servers on one host. */ @@ -3403,11 +3404,11 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) pwd_set_nullpwd(&cli->usr.pwd); - if (!cli_establish_connection(cli, remote_machine, &dest_ip, + if (!cli_establish_connection(cli, desthost, &dest_ip, &calling, &called, "IPC$", "IPC", False, True) && - !cli_establish_connection(cli, remote_machine, &dest_ip, + !cli_establish_connection(cli, desthost, &dest_ip, &calling, &stupid_smbserver_called, "IPC$", "IPC", False, True)) -- cgit From 9fef73c27e07dbf658681e6c1027602328ed0add Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 27 Nov 1999 22:34:12 +0000 Subject: updated \PIPE\wkssvc commands to use new abstracted connection system. modified resolve_srv_name() to return dest host of *SMBSERVER if server name is \\ip.add.ress.format (This used to be commit 3204829225792974c8b20efb6ba6e24661a4f658) --- source3/libsmb/namequery.c | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 114f656d8c..e774dbae15 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -589,10 +589,24 @@ static BOOL resolve_hosts(const char *name, struct in_addr *return_ip) or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. *********************************************************/ -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) +BOOL is_ip_address(const char *name) { int i; - BOOL pure_address = True; + for (i=0; name[i]; i++) + if (!(isdigit((int)name[i]) || name[i] == '.')) + return False; + + return True; +} + +/******************************************************** + Resolve a name into an IP address. Use this function if + the string is either an IP address, DNS or host name + or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. +*********************************************************/ +BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) +{ pstring name_resolve_list; fstring tok; char *ptr; @@ -606,12 +620,8 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) return True; } - for (i=0; pure_address && name[i]; i++) - if (!(isdigit((int)name[i]) || name[i] == '.')) - pure_address = False; - /* if it's in the form of an IP address then get the lib to interpret it */ - if (pure_address) { + if (is_ip_address(name)) { return_ip->s_addr = inet_addr(name); return True; } @@ -654,6 +664,7 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) BOOL resolve_srv_name(const char* srv_name, fstring dest_host, struct in_addr *ip) { + BOOL ret; DEBUG(10,("resolve_srv_name: %s\n", srv_name)); if (srv_name == NULL || strequal("\\\\.", srv_name)) @@ -669,7 +680,14 @@ BOOL resolve_srv_name(const char* srv_name, fstring dest_host, } fstrcpy(dest_host, &srv_name[2]); - return resolve_name(dest_host, ip, 0x20); + ret = resolve_name(dest_host, ip, 0x20); + + if (is_ip_address(dest_host)) + { + fstrcpy(dest_host, "*SMBSERVER"); + } + + return ret; } /******************************************************** -- cgit From e302cb2b189f679bcf7efe60d5ae9fb4218c1411 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 29 Nov 1999 19:46:57 +0000 Subject: first attempt at getting \PIPE\NETLOGON working. it's pretty horrible. (This used to be commit 44dd3efa6380544e9a515e91960f9271498cefaf) --- source3/libsmb/clienttrust.c | 108 +++++-------------------------------------- 1 file changed, 12 insertions(+), 96 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clienttrust.c b/source3/libsmb/clienttrust.c index 81855585e6..b223750529 100644 --- a/source3/libsmb/clienttrust.c +++ b/source3/libsmb/clienttrust.c @@ -42,117 +42,33 @@ static BOOL modify_trust_password( char *domain, char *remote_machine, unsigned char new_trust_passwd_hash[16], uint16 sec_chan) { - uint16 nt_pipe_fnum; - struct cli_state cli; struct nmb_name calling, called; + fstring trust_acct; + fstring srv_name; - make_nmb_name(&calling, global_myname , 0x0 , scope); - make_nmb_name(&called , remote_machine, 0x20, scope); - - ZERO_STRUCT(cli); - if(cli_initialise(&cli) == NULL) - { - DEBUG(0,("modify_trust_password: unable to initialize client \ -connection.\n")); - return False; - } - - if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) - { - DEBUG(0,("modify_trust_password: Can't resolve address for \ -%s\n", remote_machine)); - return False; - } - - if (ismyip(cli.dest_ip)) - { - DEBUG(0,("modify_trust_password: Machine %s is one of our \ -addresses. Cannot add to ourselves.\n", remote_machine)); - return False; - } + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, remote_machine); + strupper(srv_name); - cli.protocol = PROTOCOL_NT1; + fstrcpy(trust_acct, global_myname); + fstrcat(trust_acct, "$"); - pwd_set_nullpwd(&cli.usr.pwd); - - if (!cli_establish_connection(&cli, remote_machine, &cli.dest_ip, - &calling, &called, - "IPC$", "IPC", False, True)) - { - fstring errstr; - cli_safe_errstr(&cli, errstr, sizeof(errstr)); - DEBUG(0,("modify_trust_password: machine %s rejected the SMB \ -session. Error was : %s.\n", remote_machine, errstr )); - cli_shutdown(&cli); - return False; - } - - - if (cli.protocol != PROTOCOL_NT1) - { - DEBUG(0,("modify_trust_password: machine %s didn't negotiate \ -NT protocol.\n", remote_machine)); - cli_shutdown(&cli); - return False; - } - - if (!(IS_BITS_SET_ALL(cli.sec_mode, 1))) - { - DEBUG(0,("modify_trust_password: machine %s isn't in user \ -level security mode\n", remote_machine)); - cli_shutdown(&cli); - return False; - } - - /* - * Ok - we have an anonymous connection to the IPC$ share. - * Now start the NT Domain stuff :-). - */ - - if (!cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum)) - { - fstring errstr; - cli_safe_errstr(&cli, errstr, sizeof(errstr)); - DEBUG(0,("modify_trust_password: unable to open the domain \ -client session to server %s. Error was : %s.\n", remote_machine, errstr )); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); - if (cli_nt_setup_creds(&cli, nt_pipe_fnum, - cli.mach_acct, global_myname, + if (cli_nt_setup_creds(srv_name, global_myname, trust_acct, orig_trust_passwd_hash, sec_chan) != 0x0) { - fstring errstr; - cli_safe_errstr(&cli, errstr, sizeof(errstr)); - DEBUG(0,("modify_trust_password: unable to setup the PDC \ -credentials to server %s. Error was : %s.\n", remote_machine, errstr )); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); return False; } - if (!cli_nt_srv_pwset( &cli, nt_pipe_fnum, new_trust_passwd_hash, + if (!cli_nt_srv_pwset( srv_name, global_myname, trust_acct, + new_trust_passwd_hash, sec_chan ) ) { - fstring errstr; - cli_safe_errstr(&cli, errstr, sizeof(errstr)); - DEBUG(0,("modify_trust_password: unable to change password for \ -workstation %s in domain %s to Domain controller %s. Error was %s.\n", - global_myname, domain, remote_machine, errstr )); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); return False; } - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return True; } -- cgit From 0d44ff9a765f2e89be8b0ee99ec7c907e7c225c3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 29 Nov 1999 21:47:14 +0000 Subject: attempting to resolve the issue that multiple servers often specified in parameters to connect to \PIPE\NETLOGON. (This used to be commit d1986ade30bdcac1f49707221a3e5a5ae597ce62) --- source3/libsmb/clienttrust.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clienttrust.c b/source3/libsmb/clienttrust.c index b223750529..d9d3392d0b 100644 --- a/source3/libsmb/clienttrust.c +++ b/source3/libsmb/clienttrust.c @@ -57,7 +57,8 @@ static BOOL modify_trust_password( char *domain, char *remote_machine, make_nmb_name(&called , remote_machine, 0x20, scope); if (cli_nt_setup_creds(srv_name, global_myname, trust_acct, - orig_trust_passwd_hash, sec_chan) != 0x0) + orig_trust_passwd_hash, sec_chan, + srv_name) != 0x0) { return False; } -- cgit From 8d0660607f2c2d95e1319e04d0d573d9115c4dc0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 29 Nov 1999 23:56:09 +0000 Subject: this is going to sound _really_ weird, ok, but i had to implement equivalents of NetUseAdd and NetUseDel! (This used to be commit 86f4b1d3cc3887c4bb7bd6433f5f932f7db1b88e) --- source3/libsmb/pwd_cache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index b360dbd199..8f030a1a08 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -45,14 +45,14 @@ void pwd_init(struct pwd_info *pwd) /**************************************************************************** de-obfuscates a password ****************************************************************************/ -static void pwd_deobfuscate(struct pwd_info *pwd) +static void pwd_deobfuscate(const struct pwd_info *pwd) { } /**************************************************************************** obfuscates a password ****************************************************************************/ -static void pwd_obfuscate(struct pwd_info *pwd) +static void pwd_obfuscate(const struct pwd_info *pwd) { } @@ -167,7 +167,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) /**************************************************************************** gets lm and nt hashed passwords ****************************************************************************/ -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) +void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_deobfuscate(pwd); if (lm_pwd != NULL) -- cgit From 6ddfc68e0496dc41f8c9a022a0b04a2066b43c9d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 02:15:14 +0000 Subject: sys_select added one more argument (read, write selectors). (This used to be commit e4d92ff9dfc51735e6932748f66a7c20b2c1cb6a) --- source3/libsmb/clientgen.c | 72 +++++++++---------------------- source3/libsmb/nmblib.c | 2 +- source3/libsmb/smbencrypt.c | 102 ++++++++++++++++++++++---------------------- 3 files changed, 71 insertions(+), 105 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 06fa97df0c..f3bd08895d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -918,9 +918,11 @@ BOOL cli_session_setup_x(struct cli_state *cli, } static BOOL cli_calc_session_pwds(struct cli_state *cli, + char *myhostname, char *pword, char *ntpword, char *pass, int *passlen, char *ntpass, int *ntpasslen, + char *sess_key, BOOL ntlmv2) { BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL; @@ -998,59 +1000,23 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, } else if (ntpasslen != NULL) { - /* passlen != 0, ntpasslen != 0 && server supports encryption */ - if (ntlmv2) + if (cli->use_ntlmv2 != False) { - /* plain-text password requesting to be encrypted */ - uchar *srv_key = (uchar *)cli->cryptkey; - uchar nt_owf[16]; - uchar kr[16]; - HMACMD5Context ctx; - - SMBgenclientchals(cli->lm_cli_chal, - cli->nt_cli_chal, - &cli->nt_cli_chal_len, - cli->calling.name, - cli->usr.domain); - - nt_owf_gen(pword, nt_owf); - ntv2_owf_gen(nt_owf, cli->usr.user_name, cli->usr.domain, kr); - - /* lm # */ - memcpy(pword, cli->lm_cli_chal, 8); - SMBOWFencrypt_ntv2(kr, - srv_key, 8, - cli->lm_cli_chal, 8, - &pword[8]); - *passlen = 24; - - /* nt # */ - memcpy(ntpword, cli->lm_cli_chal, cli->nt_cli_chal_len); - SMBOWFencrypt_ntv2(kr, - srv_key, 8, - cli->nt_cli_chal, cli->nt_cli_chal_len, - &ntpword[cli->nt_cli_chal_len]); - *ntpasslen = cli->nt_cli_chal_len + 16; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(cli->nt_cli_chal, cli->nt_cli_chal_len, - &ctx); - hmac_md5_final(cli->sess_key, &ctx); -#if DEBUG_PASSWORD - DEBUG(100,("session key:\n")); - dump_data(100, cli->sess_key, sizeof(cli->sess_key)); -#endif - + DEBUG(10,("cli_establish_connection: NTLMv2\n")); + pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, + cli->usr.user_name, myhostname, + cli->usr.domain); } else { - /* plain-text password requesting to be encrypted */ - uchar *key = (uchar *)cli->cryptkey; - SMBencrypt ((uchar *)pass , key,(uchar *)pword ); - SMBNTencrypt((uchar *)ntpass, key,(uchar *)ntpword); - *passlen = 24; - *ntpasslen = 24; + DEBUG(10,("cli_establish_connection: NTLMv1\n")); + pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); } + + pwd_get_lm_nt_owf(&(cli->usr.pwd), pass, ntpass, + ntpasslen, sess_key); + + *passlen = 24; } return True; } @@ -1059,7 +1025,7 @@ static BOOL cli_calc_session_pwds(struct cli_state *cli, send a session setup ****************************************************************************/ BOOL cli_session_setup(struct cli_state *cli, - char *user, + char *myhostname, char *user, char *pass, int passlen, char *ntpass, int ntpasslen, char *user_domain) @@ -1073,9 +1039,10 @@ BOOL cli_session_setup(struct cli_state *cli, fstrcpy(cli->usr.user_name, user); - return cli_calc_session_pwds(cli, pword, ntpword, + return cli_calc_session_pwds(cli, myhostname, pword, ntpword, pass, &passlen, - ntpass, &ntpasslen, cli->use_ntlmv2) && + ntpass, &ntpasslen, cli->sess_key, + cli->use_ntlmv2) && cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen, user_domain); } @@ -3238,7 +3205,8 @@ BOOL cli_establish_connection(struct cli_state *cli, } /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->usr.user_name, + if (!cli_session_setup(cli, calling->name, + cli->usr.user_name, passwd, pass_len, ntpasswd, ntpass_len, cli->usr.domain)) diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9dca4731ad..ba951a809a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -908,7 +908,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - sys_select(fd+1,&fds,&timeout); + sys_select(fd+1,&fds,NULL, &timeout); if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ace6cdc300..34e6f43975 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -24,17 +24,15 @@ extern int DEBUGLEVEL; -#include "byteorder.h" - /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) +void SMBencrypt(uchar *pwrd, uchar *c8, uchar *p24) { uchar p21[21]; - lm_owf_gen(passwd, p21); + lm_owf_gen(pwrd, p21); SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD @@ -45,13 +43,13 @@ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) #endif } -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) +void SMBNTencrypt(uchar *pwrd, uchar *c8, uchar *p24) { uchar p21[21]; memset(p21,'\0',21); - nt_owf_gen(passwd, p21); + nt_owf_gen(pwrd, p21); SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD @@ -114,17 +112,17 @@ static int _my_mbstowcs(int16 *dst, const uchar *src, int len) * Creates the MD4 Hash of the users password in NT UNICODE. */ -void E_md4hash(uchar *passwd, uchar *p16) +void E_md4hash(uchar *pwrd, uchar *p16) { int len; int16 wpwd[129]; /* Password cannot be longer than 128 characters */ - len = strlen((char *)passwd); + len = strlen((char *)pwrd); if(len > 128) len = 128; /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); + _my_mbstowcs(wpwd, pwrd, len); wpwd[len] = 0; /* Ensure string is null terminated */ /* Calculate length in bytes */ len = _my_wcslen(wpwd) * sizeof(int16); @@ -135,107 +133,107 @@ void E_md4hash(uchar *passwd, uchar *p16) /* Does the LM owf of a user's password */ void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16]) { - char passwd[15]; + char pwrd[15]; - memset(passwd,'\0',15); + memset(pwrd,'\0',15); if (pwd != NULL) { - unistr2_to_ascii( passwd, pwd, sizeof(passwd)-1); + unistr2_to_ascii( pwrd, pwd, sizeof(pwrd)-1); } /* Mangle the passwords into Lanman format */ - passwd[14] = '\0'; - strupper(passwd); + pwrd[14] = '\0'; + strupper(pwrd); /* Calculate the SMB (lanman) hash functions of the password */ memset(p16, '\0', 16); - E_P16((uchar *) passwd, (uchar *)p16); + E_P16((uchar *) pwrd, (uchar *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwrd, strlen(pwrd)); dump_data(100, p16, 16); #endif /* clear out local copy of user's password (just being paranoid). */ - bzero(passwd, sizeof(passwd)); + bzero(pwrd, sizeof(pwrd)); } /* Does the LM owf of a user's password */ void lm_owf_gen(const char *pwd, uchar p16[16]) { - char passwd[15]; + char pwrd[15]; - memset(passwd,'\0',15); + memset(pwrd,'\0',15); if (pwd != NULL) { - safe_strcpy( passwd, pwd, sizeof(passwd)-1); + safe_strcpy( pwrd, pwd, sizeof(pwrd)-1); } /* Mangle the passwords into Lanman format */ - passwd[14] = '\0'; - strupper(passwd); + pwrd[14] = '\0'; + strupper(pwrd); /* Calculate the SMB (lanman) hash functions of the password */ memset(p16, '\0', 16); - E_P16((uchar *) passwd, (uchar *)p16); + E_P16((uchar *) pwrd, (uchar *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwrd, strlen(pwrd)); dump_data(100, p16, 16); #endif /* clear out local copy of user's password (just being paranoid). */ - bzero(passwd, sizeof(passwd)); + bzero(pwrd, sizeof(pwrd)); } /* Does both the NT and LM owfs of a user's password */ void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]) { - UNISTR2 passwd; + UNISTR2 pwrd; - memset(&passwd,'\0',sizeof(passwd)); + memset(&pwrd,'\0',sizeof(pwrd)); if (pwd != NULL) { - copy_unistr2(&passwd, pwd); + copy_unistr2(&pwrd, pwd); } /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - mdfour(nt_p16, (unsigned char *)passwd.buffer, passwd.uni_str_len * 2); + mdfour(nt_p16, (unsigned char *)pwrd.buffer, pwrd.uni_str_len * 2); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_owf_gen: pwd, nt#\n")); - dump_data(120, (const char*)passwd.buffer, passwd.uni_str_len * 2); + dump_data(120, (const char*)pwrd.buffer, pwrd.uni_str_len * 2); dump_data(100, nt_p16, 16); #endif /* clear out local copy of user's password (just being paranoid). */ - memset(&passwd, 0, sizeof(passwd)); + memset(&pwrd, 0, sizeof(pwrd)); } /* Does both the NT and LM owfs of a user's password */ void nt_owf_gen(const char *pwd, uchar nt_p16[16]) { - char passwd[130]; + char pwrd[130]; - memset(passwd,'\0',130); + memset(pwrd,'\0',130); if (pwd != NULL) { - safe_strcpy( passwd, pwd, sizeof(passwd)-1); + safe_strcpy( pwrd, pwd, sizeof(pwrd)-1); } /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash((uchar *)passwd, nt_p16); + E_md4hash((uchar *)pwrd, nt_p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_owf_gen: pwd, nt#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwrd, strlen(pwrd)); dump_data(100, nt_p16, 16); #endif /* clear out local copy of user's password (just being paranoid). */ - bzero(passwd, sizeof(passwd)); + bzero(pwrd, sizeof(pwrd)); } /* Does both the NT and LM owfs of a user's UNICODE password */ @@ -253,13 +251,13 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16]) } /* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) +void SMBOWFencrypt(uchar pwrd[16], uchar *c8, uchar p24[24]) { uchar p21[21]; memset(p21,'\0',21); - memcpy(p21, passwd, 16); + memcpy(p21, pwrd, 16); E_P24(p21, c8, p24); } @@ -391,12 +389,12 @@ void ntv2_owf_gen(const uchar owf[16], } /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) +void NTLMSSPOWFencrypt(uchar pwrd[8], uchar *ntlmchalresp, uchar p24[24]) { uchar p21[21]; memset(p21,'\0',21); - memcpy(p21, passwd, 8); + memcpy(p21, pwrd, 8); memset(p21 + 8, 0xbd, 8); E_P24(p21, ntlmchalresp, p24); @@ -408,13 +406,13 @@ void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) #endif } -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) +BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16], BOOL unicode) { - int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); + int new_pw_len = strlen(pwrd) * (unicode ? 2 : 1); if (new_pw_len > 512) { - DEBUG(0,("make_oem_passwd_hash: new password is too long.\n")); + DEBUG(0,("make_oem_pwrd_hash: new password is too long.\n")); return False; } @@ -427,16 +425,16 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ generate_random_buffer((unsigned char *)data, 516, False); if (unicode) { - ascii_to_unibuf(&data[512 - new_pw_len], passwd, new_pw_len); + ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len); } else { - fstrcpy( &data[512 - new_pw_len], passwd); + fstrcpy( &data[512 - new_pw_len], pwrd); } SIVAL(data, 512, new_pw_len); #ifdef DEBUG_PASSWORD - DEBUG(100,("make_oem_passwd_hash\n")); + DEBUG(100,("make_oem_pwrd_hash\n")); dump_data(100, data, 516); #endif SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); @@ -518,8 +516,8 @@ void create_ntlmssp_resp(struct pwd_info *pwd, /*********************************************************** decode a password buffer ************************************************************/ -BOOL decode_pw_buffer(const char buffer[516], char *new_passwd, - int new_passwd_size, uint32 *new_pw_len) +BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, + int new_pwrd_size, uint32 *new_pw_len) { /* * The length of the new password is in the last 4 bytes of @@ -532,14 +530,14 @@ BOOL decode_pw_buffer(const char buffer[516], char *new_passwd, dump_data(100, buffer, 516); #endif - if ((*new_pw_len) < 0 || (*new_pw_len) > new_passwd_size - 1) + if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) { DEBUG(0,("check_oem_password: incorrect password length (%d).\n", (*new_pw_len))); return False; } - memcpy(new_passwd, &buffer[512-(*new_pw_len)], (*new_pw_len)); - new_passwd[(*new_pw_len)] = '\0'; + memcpy(new_pwrd, &buffer[512-(*new_pw_len)], (*new_pw_len)); + new_pwrd[(*new_pw_len)] = '\0'; return True; } -- cgit From 106fe88be01f7ac7d1369e97a6468dcd80c0a813 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 16:39:51 +0000 Subject: 1) when no domain used in ntlogin test command, should use default one from previous lsaquery command. over-ridden from DOMAIN\username 2) initialisation of cli_state is a little more specific: sets use_ntlmv2 to Auto. this can always be over-ridden. 3) fixed reusage of ntlmssp_cli_flgs which was being a pain 4) added pwd_compare() function then fixed bug in cli_use where NULL domain name was making connections multiply unfruitfully 5) type-casting of mallocs and Reallocs that cause ansi-c compilers to bitch (This used to be commit 301a6efaf67ddc96e6dcfd21b45a82863ff8f39a) --- source3/libsmb/clientgen.c | 36 +++++++++++++++----------- source3/libsmb/pwd_cache.c | 63 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 79 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f3bd08895d..5a0363185f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2675,8 +2675,18 @@ initialise a client structure ****************************************************************************/ void cli_init_creds(struct cli_state *cli, const struct user_credentials *usr) { - copy_user_creds(&cli->usr, usr); - cli->ntlmssp_cli_flgs = usr->ntlmssp_flags; + if (usr != NULL) + { + copy_user_creds(&cli->usr, usr); + cli->ntlmssp_cli_flgs = usr->ntlmssp_flags; + } + else + { + cli->usr.domain[0] = 0; + cli->usr.user_name[0] = 0; + pwd_set_nullpwd(&cli->usr.pwd); + cli->ntlmssp_cli_flgs = 0; + } } /**************************************************************************** @@ -2715,7 +2725,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) } cli->initialised = 1; - cli->capabilities = CAP_DFS; + cli->capabilities = CAP_DFS | CAP_NT_SMBS | CAP_STATUS32; + cli->use_ntlmv2 = Auto; + + cli_init_creds(cli, NULL); return cli; } @@ -2984,6 +2997,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) { /* common to both session setups */ + uint32 ntlmssp_flgs; char pwd_buf[128]; int buf_len; char *p; @@ -3024,9 +3038,7 @@ BOOL cli_establish_connection(struct cli_state *cli, p = skip_string(p, 1); CVAL(p, 0) = 0x1; p += 4; - if (cli->ntlmssp_cli_flgs == 0) - { - cli->ntlmssp_cli_flgs = + ntlmssp_flgs = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_SIGN | @@ -3036,11 +3048,7 @@ BOOL cli_establish_connection(struct cli_state *cli, NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_00001000 | NTLMSSP_NEGOTIATE_00002000; -#if 0 - cli->ntlmssp_cli_flgs = 0x80008207; -#endif - } - SIVAL(p, 0, cli->ntlmssp_cli_flgs); + SIVAL(p, 0, ntlmssp_flgs); p += 4; p += 16; /* skip some NULL space */ CVAL(p, 0) = 0; p++; /* alignment */ @@ -3072,12 +3080,12 @@ BOOL cli_establish_connection(struct cli_state *cli, } p = smb_buf(cli->inbuf) + 0x2f; - cli->ntlmssp_cli_flgs = IVAL(p, 0); /* 0x80808a05; */ + ntlmssp_flgs = IVAL(p, 0); /* 0x80808a05; */ p += 4; memcpy(cli->cryptkey, p, 8); #ifdef DEBUG_PASSWORD DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n", - cli->ntlmssp_cli_flgs)); + ntlmssp_flgs)); DEBUG(100,("cli_session_setup_x: crypt key\n")); dump_data(100, cli->cryptkey, 8); @@ -3098,7 +3106,7 @@ BOOL cli_establish_connection(struct cli_state *cli, create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain, cli->usr.user_name, cli->calling.name, - cli->ntlmssp_cli_flgs, + ntlmssp_flgs, &auth_resp); prs_link(NULL, &auth_resp, NULL); diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 8f030a1a08..9680349a86 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -29,12 +29,12 @@ initialises a password structure ****************************************************************************/ void pwd_init(struct pwd_info *pwd) { - bzero(pwd->password , sizeof(pwd->password )); - bzero(pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); - bzero(pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); - bzero(pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); - bzero(pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); - bzero(pwd->sess_key , sizeof(pwd->sess_key )); + ZERO_STRUCT(pwd->password ); + ZERO_STRUCT(pwd->smb_lm_pwd); + ZERO_STRUCT(pwd->smb_nt_pwd); + ZERO_STRUCT(pwd->smb_lm_owf); + ZERO_STRUCT(pwd->smb_nt_owf); + ZERO_STRUCT(pwd->sess_key ); pwd->nt_owf_len = 0; pwd->null_pwd = True; /* safest option... */ @@ -63,6 +63,57 @@ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) { } +/**************************************************************************** +compares two passwords. hmm, not as trivial as expected. hmm. +****************************************************************************/ +BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) +{ + pwd_deobfuscate(pwd1); + pwd_deobfuscate(pwd2); + if (pwd1->cleartext && pwd2->cleartext) + { + if (strequal(pwd1->password, pwd2->password)) + { + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return True; + } + } + if (pwd1->null_pwd && pwd2->null_pwd) + { + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return True; + } + if (pwd1->crypted || pwd2->crypted) + { + DEBUG(5,("pwd_compare: cannot compare crypted passwords\n")); + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return False; + } + + if (!pwd1->crypted && !pwd2->crypted && + !pwd1->null_pwd && !pwd2->null_pwd && + !pwd1->cleartext && !pwd2->cleartext) + { + if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) + { + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return True; + } + if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) + { + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return True; + } + } + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return False; +} /**************************************************************************** reads a password ****************************************************************************/ -- cgit From a76fee73337aca00973ca744f3c41906a72e5855 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 22:06:53 +0000 Subject: more cli_session_setup() calls. what the heck are these doing??? they should all be replaced with cli_establish_connection(). created cli_use_wait_keyboard() which waits on multiple cli_states and swallows session keepalives. (This used to be commit fcc39b3f4f2f8d04d3fab09db048b4f3dc1e97d5) --- source3/libsmb/passchange.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 4cca1927fa..b5552d4cea 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -75,7 +75,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, * Thanks to for this fix. */ - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + if (!cli_session_setup(&cli, global_myname, "", "", 0, "", 0, "")) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); -- cgit From bd4bea62ada937c58d38f6bf7af88c4cfb4115cc Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 2 Dec 1999 01:16:05 +0000 Subject: clearing up connection-related stuff. password credentials were messing up. added a complicated prompt which i don't like, but it tells you domain\user@hostname$ (This used to be commit 338d08f69b0eeefa0f3f2c0217ef17ea3e815e1f) --- source3/libsmb/pwd_cache.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 9680349a86..548777d434 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -85,16 +85,8 @@ BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) pwd_obfuscate(pwd2); return True; } - if (pwd1->crypted || pwd2->crypted) - { - DEBUG(5,("pwd_compare: cannot compare crypted passwords\n")); - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); - return False; - } - if (!pwd1->crypted && !pwd2->crypted && - !pwd1->null_pwd && !pwd2->null_pwd && + if (!pwd1->null_pwd && !pwd2->null_pwd && !pwd1->cleartext && !pwd2->cleartext) { if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) -- cgit From e9b8c7743a45b4d045892f9039075fb8cfbd84e5 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 2 Dec 1999 16:31:24 +0000 Subject: default SID map now reads in "trusted domains" from smb.conf. (This used to be commit f0946d1ccafeb5f541935b41f2d54bcbc06797ed) --- source3/libsmb/namequery.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e774dbae15..8aaeb165cd 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -665,6 +665,8 @@ BOOL resolve_srv_name(const char* srv_name, fstring dest_host, struct in_addr *ip) { BOOL ret; + const char *sv_name = srv_name; + DEBUG(10,("resolve_srv_name: %s\n", srv_name)); if (srv_name == NULL || strequal("\\\\.", srv_name)) @@ -674,12 +676,12 @@ BOOL resolve_srv_name(const char* srv_name, fstring dest_host, return True; } - if (!strnequal("\\\\", srv_name, 2)) + if (strnequal("\\\\", srv_name, 2)) { - return False; + sv_name = &srv_name[2]; } - fstrcpy(dest_host, &srv_name[2]); + fstrcpy(dest_host, sv_name); ret = resolve_name(dest_host, ip, 0x20); if (is_ip_address(dest_host)) -- cgit From 5988d0cdae19d014a5a011de83c48326e82860b6 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 2 Dec 1999 18:49:28 +0000 Subject: added get_any_dc_name() function. (This used to be commit 455e17dbb7d451b462004f302f5c68770f17b65e) --- source3/libsmb/clientgen.c | 154 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 32 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5a0363185f..7124211286 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2935,7 +2935,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) establishes a connection right up to doing tconX, reading in a password. ****************************************************************************/ BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, + const char *dest_host, struct in_addr *dest_ip, struct nmb_name *calling, struct nmb_name *called, char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon) @@ -3328,17 +3328,104 @@ BOOL cli_establish_connection(struct cli_state *cli, return True; } +BOOL cli_connect_auth(struct cli_state *cli, + const char* desthost, + struct in_addr *dest_ip, + const struct user_credentials *usr) +{ + extern pstring global_myname; + extern pstring scope; + struct nmb_name calling, called; + if (!cli_initialise(cli)) + { + DEBUG(0,("unable to initialise client connection.\n")); + return False; + } + + make_nmb_name(&calling, global_myname, 0x0 , scope); + make_nmb_name(&called , desthost , 0x20, scope); + + cli_init_creds(cli, usr); + + if (!cli_establish_connection(cli, desthost, dest_ip, + &calling, &called, + "IPC$", "IPC", + False, True)) + { + cli_shutdown(cli); + return False; + } + + return True; +} + +/**************************************************************************** + connect to one of multiple servers: don't care which +****************************************************************************/ +BOOL cli_connect_servers_auth(struct cli_state *cli, + char *p, + const struct user_credentials *usr) +{ + fstring remote_host; + BOOL connected_ok = False; + + /* + * Treat each name in the 'password server =' line as a potential + * PDC/BDC. Contact each in turn and try and authenticate. + */ + + while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host))) + { + fstring desthost; + struct in_addr dest_ip; + strupper(remote_host); + + if (!resolve_srv_name( remote_host, desthost, &dest_ip)) + { + DEBUG(1,("Can't resolve address for %s\n", remote_host)); + continue; + } + + if (!cli_connect_auth(cli, desthost, &dest_ip, usr) && + !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, usr)) + { + continue; + } + + if (cli->protocol < PROTOCOL_LANMAN2 || + !IS_BITS_SET_ALL(cli->sec_mode, 1)) + { + DEBUG(1,("machine %s not in user level security mode\n", + remote_host)); + cli_shutdown(cli); + continue; + } + + /* + * We have an anonymous connection to IPC$. + */ + + connected_ok = True; + break; + } + + if (!connected_ok) + { + DEBUG(0,("Domain password server not available.\n")); + cli_shutdown(cli); + } + + return connected_ok; +} + /**************************************************************************** connect to one of multiple servers: don't care which ****************************************************************************/ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) { - extern pstring global_myname; - extern pstring scope; - fstring remote_machine; + fstring remote_host; fstring desthost; struct in_addr dest_ip; - struct nmb_name calling, called, stupid_smbserver_called; BOOL connected_ok = False; /* @@ -3346,58 +3433,43 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) * PDC/BDC. Contact each in turn and try and authenticate. */ - while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) + while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host))) { ZERO_STRUCTP(cli); if (!cli_initialise(cli)) { - DEBUG(0,("cli_connect_serverlist: unable to initialize client connection.\n")); + DEBUG(0,("cli_connect_serverlist: unable to initialise client connection.\n")); return False; } - standard_sub_basic(remote_machine); - strupper(remote_machine); + standard_sub_basic(remote_host); + strupper(remote_host); - if (!resolve_srv_name( remote_machine, desthost, &dest_ip)) + if (!resolve_srv_name( remote_host, desthost, &dest_ip)) { - DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_machine)); + DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_host)); continue; } if ((lp_security() != SEC_USER) && (ismyip(dest_ip))) { - DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_machine)); + DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_host)); continue; } - make_nmb_name(&calling, global_myname, 0x0 , scope); - make_nmb_name(&called , desthost , 0x20, scope); - /* stupid microsoft destruction of the ability of netbios - * to provide multiple netbios servers on one host. - */ - make_nmb_name(&stupid_smbserver_called , "*SMBSERVER", 0x20, scope); - - pwd_set_nullpwd(&cli->usr.pwd); - - if (!cli_establish_connection(cli, desthost, &dest_ip, - &calling, &called, - "IPC$", "IPC", - False, True) && - !cli_establish_connection(cli, desthost, &dest_ip, - &calling, &stupid_smbserver_called, - "IPC$", "IPC", - False, True)) + if (!cli_connect_auth(cli, remote_host , &dest_ip, NULL) && + !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, NULL)) { - cli_shutdown(cli); continue; - } + } + if (cli->protocol < PROTOCOL_LANMAN2 || !IS_BITS_SET_ALL(cli->sec_mode, 1)) { DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", - remote_machine)); + remote_host)); cli_shutdown(cli); continue; } @@ -3679,3 +3751,21 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } +BOOL get_any_dc_name(const char *domain, char *srv_name) +{ + struct cli_state cli; + + if (!cli_connect_servers_auth(&cli, + get_trusted_serverlist(domain), NULL)) + { + return False; + } + + fstrcpy(srv_name, "\\\\"); + fstrcat(srv_name, cli.desthost); + strupper(srv_name); + + cli_shutdown(&cli); + + return True; +} -- cgit From 98e28ee14ce7ffe93777315891a6626ac7a0828a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 2 Dec 1999 19:03:23 +0000 Subject: cleaning up: removing those horrible references to server list functions (cli_net_use_addlist()). needed originally because there was no get_dc_any_name() function. (This used to be commit 3a2b920ea2e6704b2574f404e1e41c7cfc0f96b2) --- source3/libsmb/clienttrust.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clienttrust.c b/source3/libsmb/clienttrust.c index d9d3392d0b..b223750529 100644 --- a/source3/libsmb/clienttrust.c +++ b/source3/libsmb/clienttrust.c @@ -57,8 +57,7 @@ static BOOL modify_trust_password( char *domain, char *remote_machine, make_nmb_name(&called , remote_machine, 0x20, scope); if (cli_nt_setup_creds(srv_name, global_myname, trust_acct, - orig_trust_passwd_hash, sec_chan, - srv_name) != 0x0) + orig_trust_passwd_hash, sec_chan) != 0x0) { return False; } -- cgit From 848ed55e22d30bcc072b197574bf1e1cc6c05c84 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 2 Dec 1999 20:16:34 +0000 Subject: new get_any_dc_name() function allows lookups of trusted domains from lp_trusted_domains() parameter, so trusted domain logins should work, right, if you put user = TRUSTED_DOMAIN\NTuser in "domain name map", right? right - as _long_ as you're not using NTLMv2, because the damn NT username gets mapped to the damn unix name too early, and NTLMv2 challenge-responses are based on the client's user name, client's domain name, client's host name etc damn etc. so it becomes necessary to stop using char* username because this allows for massive amounts of confusion as to which username is being referred to. the underlying unix username on the local unix system that is associated with the smbd process that represents the NT username? or the NT username itself? (This used to be commit dd3ccdd7d996c107766cdad3c403e8b8947b9e65) --- source3/libsmb/clientgen.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7124211286..5f898a8b0e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,8 +31,18 @@ extern int DEBUGLEVEL; * set the port that will be used for connections by the client */ -void copy_user_creds(struct user_credentials *to, const struct user_credentials *from) +void copy_user_creds(struct user_credentials *to, + const struct user_credentials *from) { + if (from == NULL) + { + to->domain[0] = 0; + to->user_name[0] = 0; + pwd_set_nullpwd(&to->pwd); + to->ntlmssp_flags = 0; + + return; + } safe_strcpy(to->domain , from->domain , sizeof(from->domain )-1); safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1); memcpy(&to->pwd, &from->pwd, sizeof(from->pwd)); @@ -2675,18 +2685,7 @@ initialise a client structure ****************************************************************************/ void cli_init_creds(struct cli_state *cli, const struct user_credentials *usr) { - if (usr != NULL) - { - copy_user_creds(&cli->usr, usr); - cli->ntlmssp_cli_flgs = usr->ntlmssp_flags; - } - else - { - cli->usr.domain[0] = 0; - cli->usr.user_name[0] = 0; - pwd_set_nullpwd(&cli->usr.pwd); - cli->ntlmssp_cli_flgs = 0; - } + copy_user_creds(&cli->usr, usr); } /**************************************************************************** @@ -3336,6 +3335,8 @@ BOOL cli_connect_auth(struct cli_state *cli, extern pstring global_myname; extern pstring scope; struct nmb_name calling, called; + + ZERO_STRUCTP(cli); if (!cli_initialise(cli)) { DEBUG(0,("unable to initialise client connection.\n")); @@ -3412,7 +3413,6 @@ BOOL cli_connect_servers_auth(struct cli_state *cli, if (!connected_ok) { DEBUG(0,("Domain password server not available.\n")); - cli_shutdown(cli); } return connected_ok; @@ -3485,7 +3485,6 @@ BOOL cli_connect_serverlist(struct cli_state *cli, char *p) if (!connected_ok) { DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n")); - cli_shutdown(cli); } return connected_ok; -- cgit From 7d01f964ff3c1a11bd72d987312f9826fee1c124 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 3 Dec 1999 18:16:08 +0000 Subject: cool! a unix socket smb redirector. code based on smbfilter and ideas from ssh-agent. the intent is to be able to share smb sessions using cli_net_use_add() across multiple processes, where one process knows the target server name, user name and domain, but not the smb password. (This used to be commit 294b653f2e9cdc1864ec638ae8b4300df25723cf) --- source3/libsmb/clientgen.c | 111 +++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/pwd_cache.c | 8 ++++ 2 files changed, 119 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5f898a8b0e..218ab67758 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2930,6 +2930,104 @@ BOOL cli_reestablish_connection(struct cli_state *cli) return False; } +static int cli_init_redirect(struct cli_state *cli, + const char* srv_name, struct in_addr *destip, + const struct user_credentials *usr) +{ + int sock; + struct sockaddr_un sa; + fstring ip_name; + struct cli_state cli_redir; + + pstring data; + uint32 len; + char *p; + char *in = cli->inbuf; + char *out = cli->outbuf; + + if (strequal(srv_name, "*SMBSERVER")) + { + fstrcpy(ip_name, "\\\\"); + inet_aton(&ip_name[2], destip); + srv_name = ip_name; + } + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + + if (sock < 0) + { + DEBUG(0, ("unix socket open failed\n")); + return sock; + } + + ZERO_STRUCT(sa); + sa.sun_family = AF_UNIX; + safe_strcpy(sa.sun_path, "/tmp/smb-agent/smb.sock", + sizeof(sa.sun_path)-1); + + DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); + + if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) + { + DEBUG(0,("socket connect to %s failed\n", sa.sun_path)); + close(sock); + return False; + } + + DEBUG(10,("connect succeeded\n")); + + ZERO_STRUCT(data); + + p = &data[4]; + safe_strcpy(p, srv_name, 16); + p = skip_string(p, 1); + safe_strcpy(p, usr != NULL ? usr->user_name : "", 16); + p = skip_string(p, 1); + safe_strcpy(p, usr != NULL ? usr->domain : "", 16); + p = skip_string(p, 1); + + if (usr != NULL && !pwd_is_nullpwd(&usr->pwd)) + { + uchar lm16[16]; + uchar nt16[16]; + + pwd_get_lm_nt_16(&usr->pwd, lm16, nt16); + memcpy(p, lm16, 16); + p += 16; + memcpy(p, nt16, 16); + p += 16; + } + + len = PTR_DIFF(p, data); + SIVAL(data, 0, len); + + printf("data len: %d\n", len); + out_data(stdout, data, len, 80); + + if (write(sock, data, len) <= 0) + { + DEBUG(0,("write failed\n")); + close(sock); + return False; + } + + len = read(sock, &cli_redir, sizeof(cli_redir)); + + if (len != sizeof(cli_redir)) + { + DEBUG(0,("read failed\n")); + close(sock); + return False; + } + + memcpy(cli, &cli_redir, sizeof(cli_redir)); + cli->inbuf = in; + cli->outbuf = out; + cli->fd = sock; + + return sock; +} + /**************************************************************************** establishes a connection right up to doing tconX, reading in a password. ****************************************************************************/ @@ -2957,6 +3055,19 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } + if (cli->fd == -1 && cli->redirect) + { + if (cli_init_redirect(cli, dest_host, dest_ip, &cli->usr)) + { + DEBUG(10,("cli_establish_connection: redirected OK\n")); + return True; + } + else + { + DEBUG(10,("redirect FAILED\n")); + return False; + } + } if (cli->fd == -1) { if (!cli_connect(cli, dest_host, dest_ip)) diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 548777d434..dd42114343 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -42,6 +42,14 @@ void pwd_init(struct pwd_info *pwd) pwd->crypted = False; } +/**************************************************************************** +returns NULL password flag +****************************************************************************/ +BOOL pwd_is_nullpwd(const struct pwd_info *pwd) +{ + return pwd->null_pwd; +} + /**************************************************************************** de-obfuscates a password ****************************************************************************/ -- cgit From 6eebe18fa9682f570127b08fb116ab561223de22 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 3 Dec 1999 19:55:34 +0000 Subject: smb-agent improvements. added -D (daemon) option. smb agent is restricted to connections from the current user (socket is created with current user uid). (This used to be commit 5af076e4b7ee13eebe0b89748e3f5a1ef21f8c73) --- source3/libsmb/clientgen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 218ab67758..176be9948b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2938,6 +2938,7 @@ static int cli_init_redirect(struct cli_state *cli, struct sockaddr_un sa; fstring ip_name; struct cli_state cli_redir; + fstring path; pstring data; uint32 len; @@ -2945,6 +2946,8 @@ static int cli_init_redirect(struct cli_state *cli, char *in = cli->inbuf; char *out = cli->outbuf; + slprintf(path, sizeof(path)-1, "/tmp/smb-agent/smb.%d", getuid()); + if (strequal(srv_name, "*SMBSERVER")) { fstrcpy(ip_name, "\\\\"); @@ -2962,8 +2965,7 @@ static int cli_init_redirect(struct cli_state *cli, ZERO_STRUCT(sa); sa.sun_family = AF_UNIX; - safe_strcpy(sa.sun_path, "/tmp/smb-agent/smb.sock", - sizeof(sa.sun_path)-1); + safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); -- cgit From c2a3b11b0738f57accafe19c84b682f761fa9631 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 3 Dec 1999 22:02:03 +0000 Subject: starting "connection reuse" system in smb-agent. added version number which isn't actually used right now :-) (This used to be commit d54a64ae3ab7cdc1ac67fb49f7255e6a106d624e) --- source3/libsmb/clientgen.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 176be9948b..3695680301 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -40,6 +40,7 @@ void copy_user_creds(struct user_credentials *to, to->user_name[0] = 0; pwd_set_nullpwd(&to->pwd); to->ntlmssp_flags = 0; + to->reuse = False; return; } @@ -47,6 +48,7 @@ void copy_user_creds(struct user_credentials *to, safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1); memcpy(&to->pwd, &from->pwd, sizeof(from->pwd)); to->ntlmssp_flags = from->ntlmssp_flags; + to->reuse = from->reuse; }; int cli_set_port(struct cli_state *cli, int port) @@ -785,6 +787,12 @@ BOOL cli_session_setup_x(struct cli_state *cli, char *p; BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY; + if (cli->usr.reuse) + { + DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n")); + return True; + } + DEBUG(100,("cli_session_setup. extended security: %s\n", BOOLSTR(esec))); @@ -1063,6 +1071,12 @@ BOOL cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { + if (cli->usr.reuse) + { + DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n")); + return True; + } + bzero(cli->outbuf,smb_size); set_message(cli->outbuf,2,0,True); CVAL(cli->outbuf,smb_com) = SMBulogoffX; @@ -2981,6 +2995,12 @@ static int cli_init_redirect(struct cli_state *cli, ZERO_STRUCT(data); p = &data[4]; + SSVAL(p, 0, 0); + p += 2; + + SSVAL(p, 0, usr->reuse ? AGENT_CMD_CON_REUSE : AGENT_CMD_CON); + p += 2; + safe_strcpy(p, srv_name, 16); p = skip_string(p, 1); safe_strcpy(p, usr != NULL ? usr->user_name : "", 16); -- cgit From 0ca1f87930a57dfd2510b98443423d8a67cfa70b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 3 Dec 1999 23:36:53 +0000 Subject: argh! smb-agent redirection client reusage is a nightmare! moved smb-agent over to a single-process model instead of fork() in order to reuse client connections. except, of course, you can't do a select() on the same socket connections! argh! (This used to be commit e9e5a34de8e8f9a69e817aceb8c16284334d4642) --- source3/libsmb/clientgen.c | 9 ++++++--- source3/libsmb/pwd_cache.c | 10 ++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3695680301..985d1c496d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2960,7 +2960,7 @@ static int cli_init_redirect(struct cli_state *cli, char *in = cli->inbuf; char *out = cli->outbuf; - slprintf(path, sizeof(path)-1, "/tmp/smb-agent/smb.%d", getuid()); + slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid()); if (strequal(srv_name, "*SMBSERVER")) { @@ -3023,8 +3023,10 @@ static int cli_init_redirect(struct cli_state *cli, len = PTR_DIFF(p, data); SIVAL(data, 0, len); - printf("data len: %d\n", len); - out_data(stdout, data, len, 80); +#ifdef DEBUG_PASSWORD + DEBUG(100,("data len: %d\n", len)); + dump_data(100, data, len); +#endif if (write(sock, data, len) <= 0) { @@ -3046,6 +3048,7 @@ static int cli_init_redirect(struct cli_state *cli, cli->inbuf = in; cli->outbuf = out; cli->fd = sock; + cli->usr.reuse = False; return sock; } diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index dd42114343..29cf77dd55 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -97,12 +97,22 @@ BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) if (!pwd1->null_pwd && !pwd2->null_pwd && !pwd1->cleartext && !pwd2->cleartext) { +#ifdef DEBUG_PASSWORD + DEBUG(100,("pwd compare: nt#\n")); + dump_data(100, pwd1->smb_nt_pwd, 16); + dump_data(100, pwd2->smb_nt_pwd, 16); +#endif if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) { pwd_obfuscate(pwd1); pwd_obfuscate(pwd2); return True; } +#ifdef DEBUG_PASSWORD + DEBUG(100,("pwd compare: lm#\n")); + dump_data(100, pwd1->smb_lm_pwd, 16); + dump_data(100, pwd2->smb_lm_pwd, 16); +#endif if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) { pwd_obfuscate(pwd1); -- cgit From 8a8a7da5186596ee86b0b188156bca7d5e664784 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 00:49:13 +0000 Subject: argh! you wouldn't believe what i had to do: use the mid (multiplex id) to redirect multiple socket-based connnections onto a single client state. argh! (This used to be commit 06390e792cd8aa57a91c3a3d1d267fd1bcdc17a1) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 985d1c496d..fea105887f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1597,7 +1597,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t int total = -1; int issued=0; int received=0; - int mpx = MAX(cli->max_mux-1, 1); + int mpx = MIN(MAX(cli->max_mux-1, 1), MAX_MAX_MUX_LIMIT); int block = (cli->max_xmit - (smb_size+32)) & ~1023; int mid; int blocks = (size + (block-1)) / block; -- cgit From f521205cb3d188fdcadcbd205dcfda4a7dcb89a0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 19:14:37 +0000 Subject: jeremy is going to hate me for this. created an "nmb-agent" utility that, yes: it connects to the 137 socket and accepts unix socket connections which it redirects onto port 137. it uses the name_trn_id field to filter requests to the correct location. name_query() and name_status() are the first victims to use this feature (by specifying a file descriptor of -1). (This used to be commit d923bc8da2cf996408194d98381409191dd81a16) --- source3/libsmb/clientgen.c | 19 +----- source3/libsmb/namequery.c | 74 ++++++++++++++++------ source3/libsmb/nmblib.c | 151 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 205 insertions(+), 39 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fea105887f..86edfa8bec 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2949,7 +2949,6 @@ static int cli_init_redirect(struct cli_state *cli, const struct user_credentials *usr) { int sock; - struct sockaddr_un sa; fstring ip_name; struct cli_state cli_redir; fstring path; @@ -2969,29 +2968,13 @@ static int cli_init_redirect(struct cli_state *cli, srv_name = ip_name; } - sock = socket(AF_UNIX, SOCK_STREAM, 0); + sock = open_pipe_sock(path); if (sock < 0) { - DEBUG(0, ("unix socket open failed\n")); return sock; } - ZERO_STRUCT(sa); - sa.sun_family = AF_UNIX; - safe_strcpy(sa.sun_path, path, sizeof(sa.sun_path)-1); - - DEBUG(10, ("socket open succeeded. file name: %s\n", sa.sun_path)); - - if (connect(sock, (struct sockaddr*) &sa, sizeof(sa)) < 0) - { - DEBUG(0,("socket connect to %s failed\n", sa.sun_path)); - close(sock); - return False; - } - - DEBUG(10,("connect succeeded\n")); - ZERO_STRUCT(data); p = &data[4]; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8aaeb165cd..79fb27bd6f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -29,6 +29,8 @@ extern int DEBUGLEVEL; /* nmbd.c sets this to True. */ BOOL global_in_nmbd = False; + static int name_trn_id = 0; + /**************************************************************************** interpret a node status response ****************************************************************************/ @@ -99,8 +101,19 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; - static int name_trn_id = 0; + int packet_type = NMB_PACKET; + + if (fd == -1) + { + retries = 1; + packet_type = NMB_SOCK_PACKET; + fd = get_nmb_sock(); + if (fd < 0) + { + return False; + } + } bzero((char *)&p,sizeof(p)); if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + @@ -130,12 +143,15 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, p.port = NMB_PORT; p.fd = fd; p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; + p.packet_type = packet_type; GetTimeOfDay(&tval); if (!send_packet(&p)) + { + if (packet_type == NMB_SOCK_PACKET) close(fd); return(False); + } retries--; @@ -146,12 +162,15 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, if (TvalDiff(&tval,&tval2) > retry_time) { if (!retries) break; if (!found && !send_packet(&p)) + { + if (packet_type == NMB_SOCK_PACKET) close(fd); return False; + } GetTimeOfDay(&tval); retries--; } - if ((p2=receive_packet(fd,NMB_PACKET,90))) + if ((p2=receive_packet(fd,packet_type,90))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); @@ -179,6 +198,7 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, _interpret_node_status(&nmb2->answers->rdata[0], master,rname); free_packet(p2); + if (packet_type == NMB_SOCK_PACKET) close(fd); return(True); } } @@ -186,6 +206,7 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, DEBUG(0,("No status response (this is not unusual)\n")); +if (packet_type == NMB_SOCK_PACKET) close(fd); return(False); } @@ -205,8 +226,20 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; - static int name_trn_id = 0; struct in_addr *ip_list = NULL; + BOOL packet_type = NMB_PACKET; + + if (fd == -1) + { + retries = 0; + packet_type = NMB_SOCK_PACKET; + fd = get_nmb_sock(); + + if (fd < 0) + { + return NULL; + } + } bzero((char *)&p,sizeof(p)); (*count) = 0; @@ -238,30 +271,34 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO p.port = NMB_PORT; p.fd = fd; p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; + p.packet_type = packet_type; GetTimeOfDay(&tval); if (!send_packet(&p)) + { + if (packet_type == NMB_SOCK_PACKET) close(fd); return NULL; + } - retries--; - - while (1) + while (retries >= 0) { struct timeval tval2; + + retries--; + GetTimeOfDay(&tval2); if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; if (!found && !send_packet(&p)) + { + if (packet_type == NMB_SOCK_PACKET) close(fd); return NULL; + } GetTimeOfDay(&tval); - retries--; } - if ((p2=receive_packet(fd,NMB_PACKET,90))) + if ((p2=receive_packet(fd,packet_type,90))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); @@ -269,6 +306,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response) { + DEBUG(10,("packet not for us (received %d, expected %d\n", + nmb2->header.name_trn_id, nmb->header.name_trn_id)); /* * Its not for us - maybe deal with it later * (put it on the queue?). @@ -314,16 +353,15 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO if (fn) break; - /* - * If we're doing a unicast lookup we only - * expect one reply. Don't wait the full 2 - * seconds if we got one. JRA. - */ - if(!bcast && found) + if(found) + { + DEBUG(10,("returning OK\n")); break; + } } } + if (packet_type == NMB_SOCK_PACKET) close(fd); return ip_list; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ba951a809a..127cfeb130 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -651,15 +651,38 @@ void free_packet(struct packet_struct *packet) struct packet_struct *read_packet(int fd,enum packet_type packet_type) { extern struct in_addr lastip; + struct nmb_state con; extern int lastport; struct packet_struct *packet; char buf[MAX_DGRAM_SIZE]; int length; BOOL ok=False; - length = read_udp_socket(fd,buf,sizeof(buf)); + if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) + { + uint16 trn_id = 0; + if (!read_nmb_sock(fd, &con)) + { + return False; + } + if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) + { + return False; + } + } + + length = read_udp_socket(fd,buf,sizeof(buf)); + + dump_data(100, buf, length); + if (length < MIN_DGRAM_SIZE) return(NULL); + if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) + { + lastip = con.ip; + lastport = con.port; + } + packet = (struct packet_struct *)malloc(sizeof(*packet)); if (!packet) return(NULL); @@ -674,15 +697,17 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) switch (packet_type) { case NMB_PACKET: + case NMB_SOCK_PACKET: ok = parse_nmb(buf,length,&packet->packet.nmb); break; case DGRAM_PACKET: + case DGRAM_SOCK_PACKET: ok = parse_dgram(buf,length,&packet->packet.dgram); break; } if (!ok) { - DEBUG(10,("parse_nmb: discarding packet id = %d\n", + DEBUG(10,("read_packet: discarding packet id = %d\n", packet->packet.nmb.header.name_trn_id)); free(packet); return(NULL); @@ -880,18 +905,65 @@ BOOL send_packet(struct packet_struct *p) switch (p->packet_type) { case NMB_PACKET: + case NMB_SOCK_PACKET: len = build_nmb(buf,p); debug_nmb_packet(p); break; case DGRAM_PACKET: + case DGRAM_SOCK_PACKET: len = build_dgram(buf,p); break; } if (!len) return(False); - return(send_udp(p->fd,buf,len,p->ip,p->port)); + switch (p->packet_type) + { + case DGRAM_PACKET: + case NMB_PACKET: + return(send_udp(p->fd,buf,len,p->ip,p->port)); + break; + + case NMB_SOCK_PACKET: + case DGRAM_SOCK_PACKET: + { + fstring qbuf; + struct nmb_state nmb; + int qlen; + uint16 trn_id; + char *q = qbuf + 4; + + nmb.ip = p->ip; + nmb.port = p->port; + + SSVAL(q, 0, 0); + q += 2; + SSVAL(q, 0, 0); + q += 2; + memcpy(q, &nmb, sizeof(nmb)); + q += sizeof(nmb); + + qlen = PTR_DIFF(q, qbuf); + SIVAL(qbuf, 0, qlen); + + dump_data(100, qbuf, qlen); + + if (write(p->fd,qbuf,qlen) != qlen) + { + return False; + } + qlen = read(p->fd, &trn_id, sizeof(trn_id)); + + if (qlen != sizeof(trn_id)) + { + return False; + } + return write(p->fd,buf,len) == len; + } + } + + return False; } /**************************************************************************** @@ -961,3 +1033,76 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } + +BOOL read_nmb_sock(int c, struct nmb_state *con) +{ + fstring buf; + char *p = buf; + int rl; + uint32 len; + uint16 version; + uint16 command; + + ZERO_STRUCTP(con); + + rl = read(c, &buf, sizeof(len)); + + if (rl < 0) + { + DEBUG(0,("read_nmb_sock: error\n")); + return False; + } + if (rl != sizeof(len)) + { + DEBUG(0,("Unable to read length\n")); + dump_data(0, buf, sizeof(len)); + return False; + } + + len = IVAL(buf, 0); + + if (len > sizeof(buf)) + { + DEBUG(0,("length %d too long\n", len)); + return False; + } + + rl = read(c, buf, len); + + if (rl < 0) + { + DEBUG(0,("Unable to read from connection\n")); + return False; + } + +#ifdef DEBUG_PASSWORD + dump_data(100, buf, rl); +#endif + version = SVAL(p, 0); + p += 2; + command = SVAL(p, 0); + p += 2; + + memcpy(con, p, sizeof(*con)); + p += sizeof(*con); + + DEBUG(10,("read_nmb_sock: ip %s port: %d\n", + inet_ntoa(con->ip), con->port)); + + if (PTR_DIFF(p, buf) != rl) + { + DEBUG(0,("Buffer size %d %d!\n", + PTR_DIFF(p, buf), rl)); + return False; + } + + return True; +} + +int get_nmb_sock(void) +{ + fstring path; + slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent"); + + return open_pipe_sock(path); +} -- cgit From 97913d82f56388eee7d8fa8c204a1fa8c9754b88 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 22:22:37 +0000 Subject: argh. trying to get the nmb agent code to filter out "self" packets. (This used to be commit 84d7cc63239ea67481f6382da58d0678a21011fb) --- source3/libsmb/namequery.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 79fb27bd6f..0d9cc54f21 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -273,20 +273,12 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO p.timestamp = time(NULL); p.packet_type = packet_type; - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - { - if (packet_type == NMB_SOCK_PACKET) close(fd); - return NULL; - } + ZERO_STRUCT(tval); while (retries >= 0) { struct timeval tval2; - retries--; - GetTimeOfDay(&tval2); if (TvalDiff(&tval,&tval2) > retry_time) { @@ -319,6 +311,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO continue; } + retries--; + if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || nmb2->header.rcode || -- cgit From ddda7722a673cefc89a55133f99c07dd153b1f19 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 4 Dec 1999 23:40:21 +0000 Subject: argh! how horrible! spent ages working out why packets weren't being received properly when a UDP "retry" occurs. it's because reads and writes must be interleaved / matched. scenario: nmblookup connects to agent, sends request. agent receives request, broadcasts it on 137. agent RECEIVES 137 broadcast, sends it to nmblookup agent receives RESPONSE to 137 broadcast, sends it to nmblookup. if reads are not equally interspersed with writes, then second send will fail. if you think this is odd behaviour and that the agent should be filtering its own UDP traffic, think again. agent will be, potentially, redirecting nmbd traffic (including WINS server) not just client programs. (This used to be commit 43e158c4261e51678d6e7f77ceb4a1c7281a2525) --- source3/libsmb/namequery.c | 28 +++++++++++++--------------- source3/libsmb/nmblib.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0d9cc54f21..406a5721c9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -102,6 +102,7 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; int packet_type = NMB_PACKET; + BOOL first_time = True; if (fd == -1) { @@ -147,27 +148,19 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, GetTimeOfDay(&tval); - if (!send_packet(&p)) - { - if (packet_type == NMB_SOCK_PACKET) close(fd); - return(False); - } - - retries--; - while (1) { struct timeval tval2; GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) break; + if (first_time || TvalDiff(&tval,&tval2) > retry_time) + { + first_time = False; if (!found && !send_packet(&p)) { if (packet_type == NMB_SOCK_PACKET) close(fd); return False; } GetTimeOfDay(&tval); - retries--; } if ((p2=receive_packet(fd,packet_type,90))) @@ -196,6 +189,8 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, continue; } + retries--; + _interpret_node_status(&nmb2->answers->rdata[0], master,rname); free_packet(p2); if (packet_type == NMB_SOCK_PACKET) close(fd); @@ -221,17 +216,18 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO { BOOL found=False; int i, retries = 3; - int retry_time = bcast?250:2000; + int retry_time = bcast?2000:2000; struct timeval tval; struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; struct in_addr *ip_list = NULL; BOOL packet_type = NMB_PACKET; + BOOL first_send = True; if (fd == -1) { - retries = 0; + retries = 1; packet_type = NMB_SOCK_PACKET; fd = get_nmb_sock(); @@ -273,15 +269,16 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO p.timestamp = time(NULL); p.packet_type = packet_type; - ZERO_STRUCT(tval); + GetTimeOfDay(&tval); while (retries >= 0) { struct timeval tval2; GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) + if (first_send ) /* || TvalDiff(&tval,&tval2) > retry_time) */ { + first_send = False; if (!found && !send_packet(&p)) { if (packet_type == NMB_SOCK_PACKET) close(fd); @@ -308,6 +305,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO fn(p2); else free_packet(p2); + continue; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 127cfeb130..006cb5f5ee 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -672,9 +672,18 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) } length = read_udp_socket(fd,buf,sizeof(buf)); - + dump_data(100, buf, length); + if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) + { + uint16 trn_id = 0; + if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) + { + return False; + } + } + if (length < MIN_DGRAM_SIZE) return(NULL); if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) @@ -900,6 +909,8 @@ BOOL send_packet(struct packet_struct *p) char buf[1024]; int len=0; + DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type)); + bzero(buf,sizeof(buf)); switch (p->packet_type) @@ -951,15 +962,25 @@ BOOL send_packet(struct packet_struct *p) if (write(p->fd,qbuf,qlen) != qlen) { + DEBUG(0,("send_packet: write hdr failed\n")); return False; } - qlen = read(p->fd, &trn_id, sizeof(trn_id)); - - if (qlen != sizeof(trn_id)) + if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) + { + DEBUG(0,("send_packet: 1st ack failed\n")); + return False; + } + if (write(p->fd,buf,len) != len) + { + DEBUG(0,("send_packet: write packet failed\n")); + return False; + } + if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) { + DEBUG(0,("send_packet: 2nd ack failed\n")); return False; } - return write(p->fd,buf,len) == len; + return True; } } @@ -980,6 +1001,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); + DEBUG(100,("receive_packet: %d %d\n", fd, type)); sys_select(fd+1,&fds,NULL, &timeout); if (FD_ISSET(fd,&fds)) -- cgit From 7c53f158bab61bca704340ce70f4039a178d0fde Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 5 Dec 1999 02:22:28 +0000 Subject: reenabled retry_time (commented out accidentally in name_status) (This used to be commit bf9422832c335c8d283273eb1d0008ac15cd3531) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 406a5721c9..299145ceff 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -276,7 +276,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO struct timeval tval2; GetTimeOfDay(&tval2); - if (first_send ) /* || TvalDiff(&tval,&tval2) > retry_time) */ + if (first_send || TvalDiff(&tval,&tval2) > retry_time) { first_send = False; if (!found && !send_packet(&p)) -- cgit From 4ab9d91428b66bd2fe407b0dba94f4130160b576 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 8 Dec 1999 21:43:03 +0000 Subject: ABOUT TIME!!!!!!!! damn, this one is bad. started, at least two days ago, to add an authentication mechanism to the smbd<->msrpc redirector/relay, such that sufficient unix / nt information could be transferred across the unix socket to do a become_user() on the other side of the socket. it is necessary that the msrpc daemon inherit the same unix and nt credentials as the smbd process from which it was spawned, until such time as the msrpc daemon receives an authentication request of its own, whereupon the msrpc daemon is responsible for authenticating the new credentials and doing yet another become_user() etc sequence. (This used to be commit 30c7fdd6ef10ecd35594311c1b250b95ff895489) --- source3/libsmb/clientgen.c | 76 ++++++++++++---------------------------------- 1 file changed, 20 insertions(+), 56 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 86edfa8bec..49772cd37a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,26 +31,6 @@ extern int DEBUGLEVEL; * set the port that will be used for connections by the client */ -void copy_user_creds(struct user_credentials *to, - const struct user_credentials *from) -{ - if (from == NULL) - { - to->domain[0] = 0; - to->user_name[0] = 0; - pwd_set_nullpwd(&to->pwd); - to->ntlmssp_flags = 0; - to->reuse = False; - - return; - } - safe_strcpy(to->domain , from->domain , sizeof(from->domain )-1); - safe_strcpy(to->user_name, from->user_name, sizeof(from->user_name)-1); - memcpy(&to->pwd, &from->pwd, sizeof(from->pwd)); - to->ntlmssp_flags = from->ntlmssp_flags; - to->reuse = from->reuse; -}; - int cli_set_port(struct cli_state *cli, int port) { @@ -787,7 +767,7 @@ BOOL cli_session_setup_x(struct cli_state *cli, char *p; BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY; - if (cli->usr.reuse) + if (cli->reuse) { DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n")); return True; @@ -1071,7 +1051,7 @@ BOOL cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { - if (cli->usr.reuse) + if (cli->reuse) { DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n")); return True; @@ -2697,9 +2677,9 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) /**************************************************************************** initialise a client structure ****************************************************************************/ -void cli_init_creds(struct cli_state *cli, const struct user_credentials *usr) +void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { - copy_user_creds(&cli->usr, usr); + copy_nt_creds(&cli->usr, usr); } /**************************************************************************** @@ -2946,18 +2926,19 @@ BOOL cli_reestablish_connection(struct cli_state *cli) static int cli_init_redirect(struct cli_state *cli, const char* srv_name, struct in_addr *destip, - const struct user_credentials *usr) + const struct ntuser_creds *usr) { int sock; fstring ip_name; struct cli_state cli_redir; fstring path; - pstring data; uint32 len; - char *p; + char *data; char *in = cli->inbuf; char *out = cli->outbuf; + prs_struct ps; + uint16 command; slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid()); @@ -2975,42 +2956,25 @@ static int cli_init_redirect(struct cli_state *cli, return sock; } - ZERO_STRUCT(data); - - p = &data[4]; - SSVAL(p, 0, 0); - p += 2; - - SSVAL(p, 0, usr->reuse ? AGENT_CMD_CON_REUSE : AGENT_CMD_CON); - p += 2; - - safe_strcpy(p, srv_name, 16); - p = skip_string(p, 1); - safe_strcpy(p, usr != NULL ? usr->user_name : "", 16); - p = skip_string(p, 1); - safe_strcpy(p, usr != NULL ? usr->domain : "", 16); - p = skip_string(p, 1); + command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON; - if (usr != NULL && !pwd_is_nullpwd(&usr->pwd)) + if (!create_ntuser_creds(&ps, srv_name, 0x0, command, usr, cli->reuse)) { - uchar lm16[16]; - uchar nt16[16]; - - pwd_get_lm_nt_16(&usr->pwd, lm16, nt16); - memcpy(p, lm16, 16); - p += 16; - memcpy(p, nt16, 16); - p += 16; + DEBUG(0,("could not parse credentials\n")); + close(sock); + return False; } - len = PTR_DIFF(p, data); - SIVAL(data, 0, len); + len = ps.offset; + data = mem_data(&ps.data, 0); #ifdef DEBUG_PASSWORD DEBUG(100,("data len: %d\n", len)); dump_data(100, data, len); #endif + SIVAL(data, 0, len); + if (write(sock, data, len) <= 0) { DEBUG(0,("write failed\n")); @@ -3031,7 +2995,7 @@ static int cli_init_redirect(struct cli_state *cli, cli->inbuf = in; cli->outbuf = out; cli->fd = sock; - cli->usr.reuse = False; + cli->reuse = False; return sock; } @@ -3449,7 +3413,7 @@ BOOL cli_establish_connection(struct cli_state *cli, BOOL cli_connect_auth(struct cli_state *cli, const char* desthost, struct in_addr *dest_ip, - const struct user_credentials *usr) + const struct ntuser_creds *usr) { extern pstring global_myname; extern pstring scope; @@ -3484,7 +3448,7 @@ BOOL cli_connect_auth(struct cli_state *cli, ****************************************************************************/ BOOL cli_connect_servers_auth(struct cli_state *cli, char *p, - const struct user_credentials *usr) + const struct ntuser_creds *usr) { fstring remote_host; BOOL connected_ok = False; -- cgit From 12ca139d5cb79f7e61a84d7dfe8a4c64ed56d82b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 9 Dec 1999 07:06:12 +0000 Subject: OK. This code works on a RedHat 6.0 system. However smbpasswd time out of sending the session setup on Solaris 2.6. No idea. I'll work on it some tomorrow. This is to fix the "Unable to setup password vectors" thingy. Also changed an inet_aton() to inet_addr() as the former is not very portable :-) Luke, I set the redir flag to false because the connection to the smb-agent was failing and smbpasswd bombed. Double check me on this one. -jc (This used to be commit e1d2b174caf5f0c48a8fac25778f72a868ec6eb7) --- source3/libsmb/clientgen.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 49772cd37a..50bf54d02c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1337,7 +1337,9 @@ int cli_nt_create(struct cli_state *cli, const char *fname) pstrcpy(p,fname); p = skip_string(p,1); - cli_send_smb(cli, True); + if (!cli_send_smb(cli, True)) { + return -1; + } if (!cli_receive_smb(cli)) { return -1; } @@ -2945,7 +2947,7 @@ static int cli_init_redirect(struct cli_state *cli, if (strequal(srv_name, "*SMBSERVER")) { fstrcpy(ip_name, "\\\\"); - inet_aton(&ip_name[2], destip); + destip->s_addr = inet_addr(&ip_name[2]); srv_name = ip_name; } -- cgit From 0ce128e3550794d4dbbd1def00e87c020f72c992 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 01:25:49 +0000 Subject: delineation between smb and msrpc more marked. smbd now constructs pdus, and then feeds them over either a "local" function call or a "remote" function call to an msrpc service. the "remote" msrpc daemon, on the other side of a unix socket, then calls the same "local" function that smbd would, if the msrpc service were being run from inside smbd. this allows a transition from local msrpc services (inside the same smbd process) to remote (over a unix socket). removed reference to pipes_struct in msrpc services. all msrpc processing functions take rpcsrv_struct which is a structure containing state info for the msrpc functions to decode and create pdus. created become_vuser() which does everything not related to connection_struct that become_user() does. removed, as best i could, connection_struct dependencies from the nt spoolss printing code. todo: remove dcinfo from rpcsrv_struct because this stores NETLOGON-specific info on a per-connection basis, and if the connection dies then so does the info, and that's a fairly serious problem. had to put pretty much everything that is in user_struct into parse_creds.c to feed unix user info over to the msrpc daemons. why? because it's expensive to do unix password/group database lookups, and it's definitely expensive to do nt user profile lookups, not to mention pretty difficult and if you did either of these it would introduce a complication / unnecessary interdependency. so, send uid/gid/num_groups/gid_t* + SID+num_rids+domain_group_rids* + unix username + nt username + nt domain + user session key etc. this is the MINIMUM info identified so far that's actually implemented. missing bits include the called and calling netbios names etc. (basically, anything that can be loaded into standard_sub() and standard_sub_basic()...) (This used to be commit aa3c659a8dba0437c17c60055a6ed30fdfecdb6d) --- source3/libsmb/clientgen.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 50bf54d02c..27efc132c0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2926,7 +2926,7 @@ BOOL cli_reestablish_connection(struct cli_state *cli) return False; } -static int cli_init_redirect(struct cli_state *cli, +static BOOL cli_init_redirect(struct cli_state *cli, const char* srv_name, struct in_addr *destip, const struct ntuser_creds *usr) { @@ -2955,7 +2955,7 @@ static int cli_init_redirect(struct cli_state *cli, if (sock < 0) { - return sock; + return False; } command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON; @@ -3038,8 +3038,7 @@ BOOL cli_establish_connection(struct cli_state *cli, } else { - DEBUG(10,("redirect FAILED\n")); - return False; + DEBUG(10,("redirect FAILED, make direct connection\n")); } } if (cli->fd == -1) -- cgit From 4f8a24522c683761c6f2ee23dba56f6c7913377b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 20:03:42 +0000 Subject: final part of "first" phase converting over to msrpc daemon architecture. done a minimal amout of clean-up in the Makefile, removing unnecessary modules from the link stage. this is not complete, yet, and will involve some changes, for example to smbd, to remove dependencies on the password database API that shouldn't be there. for example, smbd should not ever call getsmbpwXXX() it should call the Samr or Lsa API. this first implementation has minor problems with not reinstantiating the same services as the caller. the "homes" service is a good example. (This used to be commit caa50525220b0d0250fa139367593c2de2c12135) --- source3/libsmb/clientgen.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 27efc132c0..62c7429b59 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1337,9 +1337,7 @@ int cli_nt_create(struct cli_state *cli, const char *fname) pstrcpy(p,fname); p = skip_string(p,1); - if (!cli_send_smb(cli, True)) { - return -1; - } + cli_send_smb(cli, True); if (!cli_receive_smb(cli)) { return -1; } @@ -2947,7 +2945,7 @@ static BOOL cli_init_redirect(struct cli_state *cli, if (strequal(srv_name, "*SMBSERVER")) { fstrcpy(ip_name, "\\\\"); - destip->s_addr = inet_addr(&ip_name[2]); + inet_aton(&ip_name[2], destip); srv_name = ip_name; } -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/libsmb/clientgen.c | 1916 +++++++++++++++---------------------------- source3/libsmb/namequery.c | 827 ++++++++++++------- source3/libsmb/nmblib.c | 288 ++----- source3/libsmb/nterr.c | 20 +- source3/libsmb/passchange.c | 4 +- source3/libsmb/pwd_cache.c | 217 +---- source3/libsmb/smbdes.c | 23 +- source3/libsmb/smbencrypt.c | 481 ++--------- source3/libsmb/smberr.c | 85 +- 9 files changed, 1423 insertions(+), 2438 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 62c7429b59..4f620bc5f4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2,8 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. SMB client generic functions - Copyright (C) Andrew Tridgell 1994-1999 - Copyright (C) Luke Kenneth Casson Leighton 1996-1999 + Copyright (C) Andrew Tridgell 1994-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,84 +24,52 @@ #include "includes.h" #include "trans2.h" + extern int DEBUGLEVEL; +extern pstring user_socket_options; +extern pstring scope; -/* - * set the port that will be used for connections by the client - */ +static void cli_process_oplock(struct cli_state *cli); +/* + * Change the port number used to call on + */ int cli_set_port(struct cli_state *cli, int port) { - - if (port != 0) + if (port > 0) cli->port = port; - return cli->port; /* return it incase caller wants it */ - + return cli->port; } /**************************************************************************** -copy a string (unicode or otherwise) into an SMB buffer. skips a string -plus points to next +recv an smb ****************************************************************************/ -static char *cli_put_string(struct cli_state *cli, char *p, const char *str, - BOOL skip_end) +static BOOL cli_receive_smb(struct cli_state *cli) { - uint16 flgs2 = SVAL(cli->outbuf, smb_flg2); - if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) - { - p = align2(p, cli->outbuf); - p = ascii_to_unibuf(p, str, 1024); - if (skip_end) - { - CVAL(p, 0) = 0; p++; - CVAL(p, 0) = 0; p++; - } - return p; - } - else - { - pstrcpy(p, str); - p = skip_string(p, 1); - if (skip_end) - { - CVAL(p, 0) = 0; p++; + BOOL ret; + again: + ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + + if (ret) { + /* it might be an oplock break request */ + if (CVAL(cli->inbuf,smb_com) == SMBlockingX && + SVAL(cli->inbuf,smb_vwv6) == 0 && + SVAL(cli->inbuf,smb_vwv7) == 0) { + if (cli->use_oplocks) cli_process_oplock(cli); + /* try to prevent loops */ + CVAL(cli->inbuf,smb_com) = 0xFF; + goto again; } - return p; - } -} - -/**************************************************************************** -copy a string (unicode or otherwise) into an SMB buffer. skips a string -plus points to next -****************************************************************************/ -static const char *cli_get_string(struct cli_state *cli, char *p, - char *str, size_t str_len) -{ - uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); - if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS)) - { - return unibuf_to_ascii(str, p, str_len); } - else - { - safe_strcpy(str, p, str_len-1); - return skip_string(p, 1); - } -} -/**************************************************************************** -recv an smb -****************************************************************************/ -static BOOL cli_receive_smb(struct cli_state *cli) -{ - return client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + return ret; } /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ -static BOOL cli_send_smb(struct cli_state *cli, BOOL show) +static BOOL cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; @@ -111,26 +78,9 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) len = smb_len(cli->outbuf) + 4; - if (show) - { - uint8 msg_type = CVAL(cli->outbuf, 0); - if (msg_type == 0) - { - show_msg(cli->outbuf); - } - else - { - dump_data(10, cli->outbuf, len); - } - } - while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0 && errno == EPIPE && !reestablished) - { - DEBUG(5,("cli_send_smb: write error (%s) - reconnecting\n", - strerror(errno))); - + if (ret <= 0 && errno == EPIPE && !reestablished) { if (cli_reestablish_connection(cli)) { reestablished = True; nwritten=0; @@ -139,8 +89,9 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) } if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", - len,ret)); - return False; + (int)len,(int)ret)); + close_sockets(); + exit(1); } nwritten += ret; } @@ -148,26 +99,62 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show) return True; } -/****************************************************** - Return an error message - either an SMB error or a RAP - error. -*******************************************************/ - -char *cli_errstr(struct cli_state *cli) -{ - static fstring error_message; - cli_safe_errstr(cli, error_message, sizeof(error_message)); - return error_message; +/**************************************************************************** +setup basics in a outgoing packet +****************************************************************************/ +static void cli_setup_packet(struct cli_state *cli) +{ + cli->rap_error = 0; + cli->nt_error = 0; + SSVAL(cli->outbuf,smb_pid,cli->pid); + SSVAL(cli->outbuf,smb_uid,cli->vuid); + SSVAL(cli->outbuf,smb_mid,cli->mid); + if (cli->protocol > PROTOCOL_CORE) { + SCVAL(cli->outbuf,smb_flg,0x8); + SSVAL(cli->outbuf,smb_flg2,0x1); + } } + + /**************************************************************************** - return a description of an SMB error +process an oplock break request from the server ****************************************************************************/ -void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len) +static void cli_process_oplock(struct cli_state *cli) { - smb_safe_errstr(cli->inbuf, msg, len); + char *oldbuf = cli->outbuf; + pstring buf; + int fnum; + + fnum = SVAL(cli->inbuf,smb_vwv2); + + /* damn, we really need to keep a record of open files so we + can detect a oplock break and a close crossing on the + wire. for now this swallows the errors */ + if (fnum == 0) return; + + cli->outbuf = buf; + + memset(buf,'\0',smb_size); + set_message(buf,8,0,True); + + CVAL(buf,smb_com) = SMBlockingX; + SSVAL(buf,smb_tid, cli->cnum); + cli_setup_packet(cli); + SSVAL(buf,smb_vwv0,0xFF); + SSVAL(buf,smb_vwv1,0); + SSVAL(buf,smb_vwv2,fnum); + SSVAL(buf,smb_vwv3,2); /* oplock break ack */ + SIVAL(buf,smb_vwv4,0); /* timoeut */ + SSVAL(buf,smb_vwv6,0); /* unlockcount */ + SSVAL(buf,smb_vwv7,0); /* lockcount */ + + cli_send_smb(cli); + + cli->outbuf = oldbuf; } + /***************************************************** RAP error codes - a small start but will be extended. *******************************************************/ @@ -186,36 +173,36 @@ struct {2244, "This password cannot be used now (password history conflict)." }, {2245, "The password is shorter than required." }, {2246, "The password of this user is too recent to change."}, + + /* these really shouldn't be here ... */ + {0x80, "Not listening on called name"}, + {0x81, "Not listening for calling name"}, + {0x82, "Called name not present"}, + {0x83, "Called name present, but insufficient resources"}, + {0, NULL} }; /**************************************************************************** - return a description of a RAP error + return a description of an SMB error ****************************************************************************/ -BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen) +static char *cli_smb_errstr(struct cli_state *cli) { - int i; - - slprintf(err_msg, msglen - 1, "RAP code %d", rap_error); - - for (i = 0; rap_errmap[i].message != NULL; i++) - { - if (rap_errmap[i].err == rap_error) - { - safe_strcpy( err_msg, rap_errmap[i].message, msglen); - return True; - } - } - return False; + return smb_errstr(cli->inbuf); } -/**************************************************************************** - return a description of an SMB error -****************************************************************************/ -void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen) +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char *cli_errstr(struct cli_state *cli) { + static fstring error_message; uint8 errclass; uint32 errnum; + uint32 nt_rpc_error; + int i; /* * Errors are of three kinds - smb errors, @@ -224,54 +211,50 @@ void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen) * errors, whose error code is in cli.rap_error. */ - cli_error(cli, &errclass, &errnum); + cli_error(cli, &errclass, &errnum, &nt_rpc_error); if (errclass != 0) { - cli_safe_smb_errstr(cli, err_msg, msglen); + return cli_smb_errstr(cli); } - else if (cli->nt_error) - { - /* - * Was it an NT error ? - */ - (void)get_safe_nt_error_msg(cli->nt_error, err_msg, msglen); - } - else + /* + * Was it an NT error ? + */ + + if (nt_rpc_error) { - /* - * Must have been a rap error. - */ - (void)get_safe_rap_errstr(cli->rap_error, err_msg, msglen); + char *nt_msg = get_nt_error_msg(nt_rpc_error); + + if (nt_msg == NULL) + { + slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error); + } + else + { + fstrcpy(error_message, nt_msg); + } + + return error_message; } -} -/**************************************************************************** -setup basics in a outgoing packet -****************************************************************************/ -static void cli_setup_packet(struct cli_state *cli) -{ - uint16 flgs2 = 0; - flgs2 |= FLAGS2_LONG_PATH_COMPONENTS; - flgs2 |= FLAGS2_32_BIT_ERROR_CODES; - flgs2 |= FLAGS2_EXT_SEC; -#if 0 - flgs2 |= FLAGS2_UNICODE_STRINGS; -#endif - cli->rap_error = 0; - cli->nt_error = 0; - SSVAL(cli->outbuf,smb_pid,cli->pid); - SSVAL(cli->outbuf,smb_uid,cli->vuid); - SSVAL(cli->outbuf,smb_mid,cli->mid); + /* + * Must have been a rap error. + */ - if (cli->protocol > PROTOCOL_CORE) + slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); + + for (i = 0; rap_errmap[i].message != NULL; i++) { - SCVAL(cli->outbuf,smb_flg,0x8); - SSVAL(cli->outbuf,smb_flg2,flgs2); - } -} + if (rap_errmap[i].err == cli->rap_error) + { + fstrcpy( error_message, rap_errmap[i].message); + break; + } + } + return error_message; +} /***************************************************************************** Convert a character pointer in a cli_call_api() response to a form we can use. @@ -299,7 +282,7 @@ static char *fix_char_ptr(unsigned int datap, unsigned int converter, /**************************************************************************** send a SMB trans or trans2 request ****************************************************************************/ -BOOL cli_send_trans(struct cli_state *cli, int trans, +static BOOL cli_send_trans(struct cli_state *cli, int trans, char *name, int pipe_name_len, int fid, int flags, uint16 *setup, int lsetup, int msetup, @@ -315,7 +298,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,14+lsetup,0,True); CVAL(cli->outbuf,smb_com) = trans; SSVAL(cli->outbuf,smb_tid, cli->cnum); @@ -353,7 +336,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - cli_send_smb(cli, True); + show_msg(cli->outbuf); + cli_send_smb(cli); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ @@ -387,13 +371,14 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, if (trans==SMBtrans2) SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ if (this_lparam) /* param[] */ - memcpy(outparam,param,this_lparam); + memcpy(outparam,param+tot_param,this_lparam); if (this_ldata) /* data[] */ - memcpy(outdata,data,this_ldata); + memcpy(outdata,data+tot_data,this_ldata); set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - cli_send_smb(cli, True); + show_msg(cli->outbuf); + cli_send_smb(cli); tot_data += this_ldata; tot_param += this_lparam; @@ -414,12 +399,16 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, int total_data=0; int total_param=0; int this_data,this_param; - + uint8 eclass; + uint32 ecode; + *data_len = *param_len = 0; if (!cli_receive_smb(cli)) return False; + show_msg(cli->inbuf); + /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -428,9 +417,16 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, return(False); } - if (cli_error(cli, NULL, NULL)) + /* + * An NT RPC pipe call can return ERRDOS, ERRmoredata + * to a trans call. This is not an error and should not + * be treated as such. + */ + + if (cli_error(cli, &eclass, &ecode, NULL)) { - return(False); + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return(False); } /* parse out the lengths */ @@ -472,6 +468,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, if (!cli_receive_smb(cli)) return False; + show_msg(cli->inbuf); + /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -479,10 +477,10 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - - if (cli_error(cli, NULL, NULL)) + if (cli_error(cli, &eclass, &ecode, NULL)) { - return(False); + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return(False); } } @@ -642,6 +640,8 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c int type = SVAL(p,14); int comment_offset = IVAL(p,16) & 0xFFFF; char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + dos_to_unix(sname,True); + dos_to_unix(cmnt,True); fn(sname, type, cmnt); } } else { @@ -719,6 +719,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + dos_to_unix(sname, True); + dos_to_unix(cmnt, True); fn(sname, stype, cmnt); } } @@ -754,41 +756,76 @@ prots[] = /**************************************************************************** -send a session setup + Send a session setup. The username is in UNIX character format and must be + converted to DOS codepage format before sending. If the password is in + plaintext, the same should be done. ****************************************************************************/ -BOOL cli_session_setup_x(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *user_domain) + +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup) { - uint8 eclass; - uint32 ecode; char *p; - BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY; + fstring pword, ntpword; - if (cli->reuse) - { - DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n")); + if (cli->protocol < PROTOCOL_LANMAN1) return True; - } - DEBUG(100,("cli_session_setup. extended security: %s\n", - BOOLSTR(esec))); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("cli_session_setup. pass, ntpass\n")); - dump_data(100, pass, passlen); - dump_data(100, ntpass, ntpasslen); -#endif + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + return False; + } - if (cli->protocol < PROTOCOL_LANMAN1) - { - return True; + if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { + /* Null session connect. */ + pword[0] = '\0'; + ntpword[0] = '\0'; + } else { + if ((cli->sec_mode & 2) && passlen != 24) { + /* + * Encrypted mode needed, and non encrypted password supplied. + */ + passlen = 24; + ntpasslen = 24; + fstrcpy(pword, pass); + unix_to_dos(pword,True); + fstrcpy(ntpword, ntpass);; + unix_to_dos(ntpword,True); + SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword); + SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword); + } else if ((cli->sec_mode & 2) && passlen == 24) { + /* + * Encrypted mode needed, and encrypted password supplied. + */ + memcpy(pword, pass, passlen); + if(ntpasslen == 24) { + memcpy(ntpword, ntpass, ntpasslen); + } else { + fstrcpy(ntpword, ""); + ntpasslen = 0; + } + } else { + /* + * Plaintext mode needed, assume plaintext supplied. + */ + fstrcpy(pword, pass); + unix_to_dos(pword,True); + fstrcpy(ntpword, ""); + ntpasslen = 0; + } } + /* if in share level security then don't send a password now */ + if (!(cli->sec_mode & 1)) { + fstrcpy(pword, ""); + passlen=1; + fstrcpy(ntpword, ""); + ntpasslen=1; + } + /* send a session setup command */ - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); if (cli->protocol < PROTOCOL_NT1) { @@ -803,36 +840,13 @@ BOOL cli_session_setup_x(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); p = smb_buf(cli->outbuf); - memcpy(p,pass,passlen); + memcpy(p,pword,passlen); p += passlen; pstrcpy(p,user); + unix_to_dos(p,True); strupper(p); } - else if (esec) - { - set_message(cli->outbuf,12,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - SIVAL(cli->outbuf,smb_vwv10, CAP_EXTENDED_SECURITY|CAP_STATUS32|CAP_UNICODE); - p = smb_buf(cli->outbuf); - memcpy(p,pass,passlen); - p += passlen; - - p = cli_put_string(cli, p, "Unix", False); - p = cli_put_string(cli, p, "Samba", False); - p = cli_put_string(cli, p, "", False); - p++; - - set_message(cli->outbuf,12,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - } - else + else { set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; @@ -845,228 +859,76 @@ BOOL cli_session_setup_x(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SIVAL(cli->outbuf,smb_vwv11, 0); + SSVAL(cli->outbuf,smb_vwv11,0); p = smb_buf(cli->outbuf); - memcpy(p,pass,passlen); + memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpass,ntpasslen); + memcpy(p,ntpword,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - strupper(user); - p = cli_put_string(cli, p, user, False); - strupper(user_domain); - p = cli_put_string(cli, p, user_domain, False); - p = cli_put_string(cli, p, "Unix", True); - p = cli_put_string(cli, p, "Samba", False); - + pstrcpy(p,user); + unix_to_dos(p,True); + strupper(p); + p = skip_string(p,1); + pstrcpy(p,workgroup); + strupper(p); + p = skip_string(p,1); + pstrcpy(p,"Unix");p = skip_string(p,1); + pstrcpy(p,"Samba");p = skip_string(p,1); set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } - cli_send_smb(cli, True); - if (!cli_receive_smb(cli)) - { - DEBUG(10,("cli_session_setup_x: receive smb failed\n")); + cli_send_smb(cli); + if (!cli_receive_smb(cli)) return False; - } - - if (cli_error(cli, &eclass, &ecode)) - { - uint16 flgs2 = SVAL(cli->inbuf,smb_flg2); - if (IS_BITS_CLR_ALL(flgs2, FLAGS2_32_BIT_ERROR_CODES)) - { - if (ecode != ERRmoredata || !esec) - { - return False; - } - } - else if (ecode != 0xC0000016) /* STATUS_MORE_PROCESSING_REQD */ - { - return False; - } - } - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); - - if (cli->protocol >= PROTOCOL_NT1) - { - if (esec) - { - } - else - { - /* - * Save off some of the connected server - * info. - */ - char *server_domain; - char *server_os; - char *server_type; + show_msg(cli->inbuf); - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } - fstrcpy(cli->server_os, server_os); - fstrcpy(cli->server_type, server_type); - fstrcpy(cli->server_domain, server_domain); - } + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); + + if (cli->protocol >= PROTOCOL_NT1) { + /* + * Save off some of the connected server + * info. + */ + char *server_domain,*server_os,*server_type; + server_os = smb_buf(cli->inbuf); + server_type = skip_string(server_os,1); + server_domain = skip_string(server_type,1); + fstrcpy(cli->server_os, server_os); + dos_to_unix(cli->server_os, True); + fstrcpy(cli->server_type, server_type); + dos_to_unix(cli->server_type, True); + fstrcpy(cli->server_domain, server_domain); + dos_to_unix(cli->server_domain, True); } + fstrcpy(cli->user_name, user); + dos_to_unix(cli->user_name, True); + return True; } -static BOOL cli_calc_session_pwds(struct cli_state *cli, - char *myhostname, - char *pword, char *ntpword, - char *pass, int *passlen, - char *ntpass, int *ntpasslen, - char *sess_key, - BOOL ntlmv2) +/**************************************************************************** + Send a uloggoff. +*****************************************************************************/ + +BOOL cli_ulogoff(struct cli_state *cli) { - BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL; + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,2,0,True); + CVAL(cli->outbuf,smb_com) = SMBulogoffX; + cli_setup_packet(cli); + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - if (pass == NULL || passlen == NULL) - { - DEBUG(0,("cli_calc_session_pwds: pass and passlen are NULL\n")); - return False; - } - if ((ntpass != NULL || ntpasslen != NULL) && - (ntpass == NULL || ntpasslen == NULL)) - { - DEBUG(0,("cli_calc_session_pwds: ntpasswd pointers invalid\n")); - return False; - } - -#ifdef DEBUG_PASSWORD - DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n")); - dump_data(100, pass, *passlen); - if (ntpass_ok) - { - dump_data(100, ntpass, *ntpasslen); - } -#endif - if (!IS_BITS_SET_ALL(cli->sec_mode, 1)) - { - /* if in share level security then don't send a password now */ - pword[0] = '\0'; - *passlen=1; - if (ntpass_ok) - { - ntpword[0] = '\0'; - *ntpasslen=1; - } - return True; - } - else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0')) - { - /* Null session connect. */ - pword [0] = '\0'; - if (ntpass_ok) - { - ntpword[0] = '\0'; - *ntpasslen=0; - } - - return True; - } - - if (!ntpass_ok) - { - return False; - } - - if (*passlen == 24 && *ntpasslen >= 24) - { - if (IS_BITS_SET_ALL(cli->sec_mode, 2)) - { - /* encrypted password, implicit from 24-byte lengths */ - memcpy(pword , pass , *passlen); - memcpy(ntpword, ntpass, *ntpasslen); - } - else - { - DEBUG(0,("cli_calc_session_pwds: encrypted passwords not supported by server\n")); - return False; - } - } - else if (*ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2)) - { - /* plain-text password: server doesn't support encrypted. */ - fstrcpy(pword, pass); - fstrcpy(ntpword, ""); - *ntpasslen = 0; - } - else if (ntpasslen != NULL) - { - if (cli->use_ntlmv2 != False) - { - DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, - cli->usr.user_name, myhostname, - cli->usr.domain); - } - else - { - DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); - } - - pwd_get_lm_nt_owf(&(cli->usr.pwd), pass, ntpass, - ntpasslen, sess_key); - - *passlen = 24; - } - return True; -} - -/**************************************************************************** -send a session setup -****************************************************************************/ -BOOL cli_session_setup(struct cli_state *cli, - char *myhostname, char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *user_domain) -{ - fstring pword, ntpword; - - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) - { - return False; - } - - fstrcpy(cli->usr.user_name, user); - - return cli_calc_session_pwds(cli, myhostname, pword, ntpword, - pass, &passlen, - ntpass, &ntpasslen, cli->sess_key, - cli->use_ntlmv2) && - cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen, - user_domain); -} - -/**************************************************************************** - Send a uloggoff. -*****************************************************************************/ - -BOOL cli_ulogoff(struct cli_state *cli) -{ - if (cli->reuse) - { - DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n")); - return True; - } - - bzero(cli->outbuf,smb_size); - set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBulogoffX; - cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - - cli_send_smb(cli, True); - if (!cli_receive_smb(cli)) - return False; + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; return CVAL(cli->inbuf,smb_rcls) == 0; } @@ -1077,10 +939,10 @@ send a tconX BOOL cli_send_tconX(struct cli_state *cli, char *share, char *dev, char *pass, int passlen) { - fstring fullshare, pword; + fstring fullshare, pword, dos_pword; char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); fstrcpy(cli->share, share); @@ -1091,17 +953,32 @@ BOOL cli_send_tconX(struct cli_state *cli, } if ((cli->sec_mode & 2) && *pass && passlen != 24) { + /* + * Non-encrypted passwords - convert to DOS codepage before encryption. + */ passlen = 24; - SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + fstrcpy(dos_pword,pass); + unix_to_dos(dos_pword,True); + SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); } else { - memcpy(pword, pass, passlen); + if(!(cli->sec_mode & 2)) { + /* + * Non-encrypted passwords - convert to DOS codepage before using. + */ + fstrcpy(pword,pass); + unix_to_dos(pword,True); + } else { + memcpy(pword, pass, passlen); + } } slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); + unix_to_dos(fullshare, True); strupper(fullshare); - set_message(cli->outbuf,4, 0, True); + set_message(cli->outbuf,4, + 2 + strlen(fullshare) + passlen + strlen(dev),True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -1111,15 +988,14 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p = cli_put_string(cli, p, fullshare, False); - fstrcpy(p, dev); - p = skip_string(p, 1); - - set_message(cli->outbuf,4,PTR_DIFF(p, smb_buf(cli->outbuf)),False); + fstrcpy(p,fullshare); + p = skip_string(p,1); + pstrcpy(p,dev); + unix_to_dos(p,True); SCVAL(cli->inbuf,smb_rcls, 1); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; @@ -1129,10 +1005,8 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->dev, "A:"); - if (cli->protocol >= PROTOCOL_NT1) - { - cli_get_string(cli, smb_buf(cli->inbuf), - cli->dev, sizeof(cli->dev)); + if (cli->protocol >= PROTOCOL_NT1) { + fstrcpy(cli->dev, smb_buf(cli->inbuf)); } if (strcasecmp(share,"IPC$")==0) { @@ -1140,8 +1014,8 @@ BOOL cli_send_tconX(struct cli_state *cli, } /* only grab the device if we have a recent protocol level */ - if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) - { + if (cli->protocol >= PROTOCOL_NT1 && + smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ cli->win95 = True; } @@ -1156,13 +1030,13 @@ send a tree disconnect ****************************************************************************/ BOOL cli_tdis(struct cli_state *cli) { - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBtdis; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; @@ -1176,8 +1050,8 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); @@ -1190,11 +1064,13 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,fname_src); + unix_to_dos(p,True); p = skip_string(p,1); *p++ = 4; pstrcpy(p,fname_dst); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1213,8 +1089,8 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,1, 2 + strlen(fname),True); @@ -1227,8 +1103,9 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,fname); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1247,8 +1124,8 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,0, 2 + strlen(dname),True); @@ -1259,8 +1136,9 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,dname); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1279,8 +1157,8 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,0, 2 + strlen(dname),True); @@ -1291,8 +1169,9 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,dname); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1309,12 +1188,12 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) /**************************************************************************** open a file ****************************************************************************/ -int cli_nt_create(struct cli_state *cli, const char *fname) +int cli_nt_create(struct cli_state *cli, char *fname) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,24,1 + strlen(fname),True); @@ -1335,9 +1214,10 @@ int cli_nt_create(struct cli_state *cli, const char *fname) p = smb_buf(cli->outbuf); pstrcpy(p,fname); + unix_to_dos(p,True); p = skip_string(p,1); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return -1; } @@ -1353,8 +1233,7 @@ int cli_nt_create(struct cli_state *cli, const char *fname) /**************************************************************************** open a file ****************************************************************************/ -int cli_open(struct cli_state *cli, const char *fname, - int flags, int share_mode) +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) { char *p; unsigned openfn=0; @@ -1389,8 +1268,8 @@ int cli_open(struct cli_state *cli, const char *fname, } #endif /* O_SYNC */ - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,15,1 + strlen(fname),True); @@ -1404,13 +1283,21 @@ int cli_open(struct cli_state *cli, const char *fname, SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); SSVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv8,openfn); + + if (cli->use_oplocks) { + /* if using oplocks then ask for a batch oplock via + core and extended methods */ + CVAL(cli->outbuf,smb_flg) |= + FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; + SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); + } p = smb_buf(cli->outbuf); - p = cli_put_string(cli, p, fname, False); - - set_message(cli->outbuf,15,PTR_DIFF(p, smb_buf(cli->outbuf)),False); + pstrcpy(p,fname); + unix_to_dos(p,True); + p = skip_string(p,1); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return -1; } @@ -1430,8 +1317,8 @@ int cli_open(struct cli_state *cli, const char *fname, ****************************************************************************/ BOOL cli_close(struct cli_state *cli, int fnum) { - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,3,0,True); @@ -1442,7 +1329,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) SSVAL(cli->outbuf,smb_vwv0,fnum); SIVALS(cli->outbuf,smb_vwv1,-1); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1463,8 +1350,8 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti char *p; int saved_timeout = cli->timeout; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0', smb_size); set_message(cli->outbuf,8,10,True); @@ -1483,7 +1370,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli, True); + cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; @@ -1508,8 +1395,8 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,8,10,True); @@ -1529,7 +1416,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int SIVAL(p, 2, offset); SIVAL(p, 6, len); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1549,8 +1436,8 @@ issue a single SMBread and don't wait for a reply static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,10,0,True); @@ -1565,7 +1452,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli, True); + cli_send_smb(cli); } /**************************************************************************** @@ -1577,15 +1464,24 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t int total = -1; int issued=0; int received=0; - int mpx = MIN(MAX(cli->max_mux-1, 1), MAX_MAX_MUX_LIMIT); +/* + * There is a problem in this code when mpx is more than one. + * for some reason files can get corrupted when being read. + * Until we understand this fully I am serializing reads (one + * read/one reply) for now. JRA. + */ +#if 0 + int mpx = MAX(cli->max_mux-1, 1); +#else + int mpx = 1; +#endif int block = (cli->max_xmit - (smb_size+32)) & ~1023; int mid; int blocks = (size + (block-1)) / block; if (size == 0) return 0; - while (received < blocks) - { + while (received < blocks) { int size2; while (issued - received < mpx && issued < blocks) { @@ -1602,8 +1498,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t mid = SVAL(cli->inbuf, smb_mid) - cli->mid; size2 = SVAL(cli->inbuf, smb_vwv5); - if (cli_error(cli, NULL, NULL)) - { + if (CVAL(cli->inbuf,smb_rcls) != 0) { blocks = MIN(blocks, mid-1); continue; } @@ -1647,8 +1542,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,12,size,True); @@ -1673,7 +1568,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli, True); + show_msg(cli->outbuf); + cli_send_smb(cli); } /**************************************************************************** @@ -1687,58 +1583,98 @@ ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, char *buf, off_t offset, size_t size) { - int total = -1; - int issued=0; - int received=0; + int bwritten = 0; + int issued = 0; + int received = 0; int mpx = MAX(cli->max_mux-1, 1); int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int mid; int blocks = (size + (block-1)) / block; - if (size == 0) return 0; - while (received < blocks) { - int size2; - while (issued - received < mpx && issued < blocks) { - int size1 = MIN(block, size-issued*block); - cli_issue_write(cli, fnum, offset+issued*block, + while ((issued - received < mpx) && (issued < blocks)) + { + int bsent = issued * block; + int size1 = MIN(block, size - bsent); + + cli_issue_write(cli, fnum, offset + bsent, write_mode, - buf + issued*block, + buf + bsent, size1, issued); issued++; } - if (!cli_receive_smb(cli)) { - return total; + if (!cli_receive_smb(cli)) + { + return bwritten; } received++; - mid = SVAL(cli->inbuf, smb_mid) - cli->mid; - size2 = SVAL(cli->inbuf, smb_vwv2); - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - blocks = MIN(blocks, mid-1); - continue; - } - if (size2 <= 0) { - blocks = MIN(blocks, mid-1); - /* this distinguishes EOF from an error */ - total = MAX(total, 0); - continue; + if (CVAL(cli->inbuf,smb_rcls) != 0) + { + break; } - total += size2; - - total = MAX(total, mid*block + size2); + bwritten += SVAL(cli->inbuf, smb_vwv2); } - while (received < issued) { - cli_receive_smb(cli); + while (received < issued && cli_receive_smb(cli)) + { received++; } + return bwritten; +} + + +/**************************************************************************** + write to a file using a SMBwrite and not bypassing 0 byte writes +****************************************************************************/ +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1) +{ + char *p; + ssize_t total = 0; + + do { + size_t size = MIN(size1, cli->max_xmit - 48); + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,5, 3 + size,True); + + CVAL(cli->outbuf,smb_com) = SMBwrite; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SSVAL(cli->outbuf,smb_vwv1,size); + SIVAL(cli->outbuf,smb_vwv2,offset); + SSVAL(cli->outbuf,smb_vwv4,0); + + p = smb_buf(cli->outbuf); + *p++ = 1; + SSVAL(p, 0, size); + memcpy(p+2, buf, size); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + size = SVAL(cli->inbuf,smb_vwv0); + if (size == 0) break; + + size1 -= size; + total += size; + } while (size1); + return total; } @@ -1750,10 +1686,10 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, uint16 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) { - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + set_message(cli->outbuf,1,0,True); CVAL(cli->outbuf,smb_com) = SMBgetattrE; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1761,7 +1697,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, SSVAL(cli->outbuf,smb_vwv0,fd); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1802,8 +1738,8 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,0,strlen(fname)+2,True); @@ -1814,8 +1750,9 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, p = smb_buf(cli->outbuf); *p = 4; pstrcpy(p+1, fname); + unix_to_dos(p+1,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1848,8 +1785,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) { char *p; - bzero(cli->outbuf,smb_size); - bzero(cli->inbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,8,strlen(fname)+4,True); @@ -1863,10 +1800,11 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) p = smb_buf(cli->outbuf); *p = 4; pstrcpy(p+1, fname); + unix_to_dos(p+1,True); p = skip_string(p,1); *p = 4; - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -1899,6 +1837,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, memset(param, 0, param_len); SSVAL(param, 0, SMB_INFO_STANDARD); pstrcpy(¶m[6], fname); + unix_to_dos(¶m[6],True); do { ret = (cli_send_trans(cli, SMBtrans2, @@ -1916,7 +1855,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; - cli_error(cli, &eclass, &ecode); + cli_error(cli, &eclass, &ecode, NULL); if (eclass != ERRSRV || ecode != ERRerror) break; msleep(100); } @@ -1972,6 +1911,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, memset(param, 0, param_len); SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); pstrcpy(¶m[6], fname); + unix_to_dos(¶m[6],True); if (!cli_send_trans(cli, SMBtrans2, NULL, 0, /* name, length */ @@ -2009,7 +1949,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, *mode = SVAL(rdata, 32); } if (size) { - *size = IVAL(rdata, 40); + *size = IVAL(rdata, 48); } if (ino) { *ino = IVAL(rdata, 64); @@ -2081,7 +2021,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, *mode = SVAL(rdata, 32); } if (size) { - *size = IVAL(rdata, 40); + *size = IVAL(rdata, 48); } if (ino) { *ino = IVAL(rdata, 64); @@ -2117,6 +2057,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); pstrcpy(finfo->name,p+27); + dos_to_unix(finfo->name,True); } return(28 + CVAL(p,26)); @@ -2129,6 +2070,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); pstrcpy(finfo->name,p+31); + dos_to_unix(finfo->name,True); } return(32 + CVAL(p,30)); @@ -2142,6 +2084,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); pstrcpy(finfo->name,p+33); + dos_to_unix(finfo->name,True); } return(SVAL(p,4)+4); @@ -2154,6 +2097,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); pstrcpy(finfo->name,p+37); + dos_to_unix(finfo->name,True); } return(SVAL(p,4)+4); @@ -2189,7 +2133,8 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) p += 4; /* EA size */ p += 2; /* short name len? */ p += 24; /* short name? */ - StrnCpy(finfo->name,p,namelen); + StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); + dos_to_unix(finfo->name,True); return(ret); } return(SVAL(p,0)); @@ -2217,7 +2162,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, int dirlist_len = 0; int total_received = -1; BOOL First = True; - int ff_resume_key = 0; int ff_searchcount=0; int ff_eos=0; int ff_lastname=0; @@ -2230,6 +2174,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, pstring param; pstrcpy(mask,Mask); + unix_to_dos(mask,True); while (ff_eos == 0) { loop_count++; @@ -2253,12 +2198,12 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,0,ff_dir_handle); SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); - SIVAL(param,6,ff_resume_key); /* ff_resume_key */ + SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ pstrcpy(param+12,mask); - DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_resume_key,ff_lastname,mask)); + DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", + ff_dir_handle,ff_lastname,mask)); } if (!cli_send_trans(cli, SMBtrans2, @@ -2279,7 +2224,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; - cli_error(cli, &eclass, &ecode); + cli_error(cli, &eclass, &ecode, NULL); if (eclass != ERRSRV || ecode != ERRerror) break; msleep(100); continue; @@ -2311,19 +2256,19 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, switch(info_level) { case 260: - ff_resume_key =0; StrnCpy(mask,p+ff_lastname, - data_len-ff_lastname); + MIN(sizeof(mask)-1,data_len-ff_lastname)); break; case 1: pstrcpy(mask,p + ff_lastname + 1); - ff_resume_key = 0; break; } } else { pstrcpy(mask,""); } - + + dos_to_unix(mask, True); + /* and add them to the dirlist pool */ dirlist = Realloc(dirlist,dirlist_len + data_len); @@ -2347,8 +2292,10 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, if (rdata) free(rdata); rdata = NULL; if (rparam) free(rparam); rparam = NULL; - DEBUG(3,("received %d entries (eos=%d resume=%d)\n", - ff_searchcount,ff_eos,ff_resume_key)); + DEBUG(3,("received %d entries (eos=%d)\n", + ff_searchcount,ff_eos)); + + if (ff_searchcount > 0) loop_count = 0; First = False; } @@ -2383,6 +2330,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *rparam = NULL; char *rdata = NULL; int rprcnt, rdrcnt; + pstring dos_new_password; if (strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); @@ -2408,19 +2356,22 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char */ memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); fstrcpy(upper_case_old_pw, old_password); + unix_to_dos(upper_case_old_pw,True); strupper(upper_case_old_pw); E_P16((uchar *)upper_case_old_pw, old_pw_hash); - if (!make_oem_passwd_hash( data, new_password, old_pw_hash, False)) - { - return False; - } + pstrcpy(dos_new_password, new_password); + unix_to_dos(dos_new_password, True); + + if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) + return False; /* * Now place the old password hash in the data. */ memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); fstrcpy(upper_case_new_pw, new_password); + unix_to_dos(upper_case_new_pw,True); strupper(upper_case_new_pw); E_P16((uchar *)upper_case_new_pw, new_pw_hash); @@ -2429,14 +2380,13 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char data_len = 532; - if (!cli_send_trans(cli,SMBtrans, + if (cli_send_trans(cli,SMBtrans, PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ data,data_len,0 /* data, length, max */ - )) - { + ) == False) { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); return False; @@ -2466,7 +2416,7 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ for (plength=0,numprots=0; @@ -2482,6 +2432,7 @@ BOOL cli_negprot(struct cli_state *cli) numprots++) { *p++ = 2; pstrcpy(p,prots[numprots].name); + unix_to_dos(p,True); p += strlen(p) + 1; } @@ -2490,11 +2441,11 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) - { return False; - } + + show_msg(cli->inbuf); if (CVAL(cli->inbuf,smb_rcls) != 0 || ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { @@ -2504,56 +2455,28 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if (cli->protocol >= PROTOCOL_NT1) - { - char *buf = smb_buf(cli->inbuf); - int bcc = SVAL(cli->inbuf,smb_vwv+2*(CVAL(cli->inbuf,smb_wct))); + if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); - cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60; + cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1); + cli->serverzone *= 60; /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (IS_BITS_SET_ALL(cli->capabilities, CAP_RAW_MODE)) - { + if (cli->capabilities & 1) { cli->readbraw_supported = True; cli->writebraw_supported = True; } - - if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) - { - /* oops, some kerberos-related nonsense. */ - /* expect to have to use NTLMSSP-over-SMB */ - DEBUG(10,("unknown kerberos-related (?) blob\n")); - memset(cli->cryptkey, 0, 8); - cli->server_domain[0] = 0; - } - else - { - memcpy(cli->cryptkey, buf,8); - if (bcc > 8) - { - unibuf_to_ascii(cli->server_domain, buf+8, - sizeof(cli->server_domain)); - } - else - { - cli->server_domain[0] = 0; - } - DEBUG(5,("server's domain: %s bcc: %d\n", - cli->server_domain, bcc)); - } - } - else if (cli->protocol >= PROTOCOL_LANMAN1) - { + } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); - cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; + cli->serverzone = SVALS(cli->inbuf,smb_vwv10); + cli->serverzone *= 60; /* this time is converted to GMT by make_unix_date */ cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); @@ -2584,11 +2507,6 @@ BOOL cli_session_request(struct cli_state *cli, memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); - if (cli->port == 445) - { - return True; - } - /* put in the destination name */ p = cli->outbuf+len; name_mangle(cli->called .name, p, cli->called .name_type); @@ -2607,12 +2525,41 @@ BOOL cli_session_request(struct cli_state *cli, retry: #endif /* WITH_SSL */ - cli_send_smb(cli, True); + cli_send_smb(cli); DEBUG(5,("Sent session request\n")); if (!cli_receive_smb(cli)) return False; + if (CVAL(cli->inbuf,0) == 0x84) { + /* C. Hoch 9/14/95 Start */ + /* For information, here is the response structure. + * We do the byte-twiddling to for portability. + struct RetargetResponse{ + unsigned char type; + unsigned char flags; + int16 length; + int32 ip_addr; + int16 port; + }; + */ + int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); + /* SESSION RETARGET */ + putip((char *)&cli->dest_ip,cli->inbuf+4); + + close_sockets(); + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); + if (cli->fd == -1) + return False; + + DEBUG(3,("Retargeted\n")); + + set_socket_options(cli->fd,user_socket_options); + + /* Try again */ + return cli_session_request(cli, calling, called); + } /* C. Hoch 9/14/95 End */ + #ifdef WITH_SSL if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ if (!sslutil_fd_is_ssl(cli->fd)){ @@ -2624,7 +2571,7 @@ retry: if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ - cli->rap_error = CVAL(cli->inbuf,0); + cli->rap_error = CVAL(cli->inbuf,4); return False; } return(True); @@ -2637,7 +2584,6 @@ open the client sockets BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern struct in_addr ipzero; - int port = cli->port; fstrcpy(cli->desthost, host); @@ -2650,38 +2596,19 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) cli->dest_ip = *ip; } - - if (port == 0) port = SMB_PORT2; + if (cli->port == 0) cli->port = 139; /* Set to default */ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - port, cli->timeout); + cli->port, cli->timeout); if (cli->fd == -1) - { - if (cli->port != 0) - { - return False; - } - port = SMB_PORT; - - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - port, cli->timeout); - if (cli->fd == -1) return False; - } + return False; - cli->port = port; + set_socket_options(cli->fd,user_socket_options); return True; } -/**************************************************************************** -initialise a client structure -****************************************************************************/ -void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) -{ - copy_nt_creds(&cli->usr, usr); -} - /**************************************************************************** initialise a client structure ****************************************************************************/ @@ -2707,7 +2634,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->mid = 1; cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; - cli->timeout = 20000; + cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; cli->outbuf = (char *)malloc(cli->bufsize); @@ -2717,39 +2644,19 @@ struct cli_state *cli_initialise(struct cli_state *cli) return False; } - cli->initialised = 1; - cli->capabilities = CAP_DFS | CAP_NT_SMBS | CAP_STATUS32; - cli->use_ntlmv2 = Auto; + memset(cli->outbuf, '\0', cli->bufsize); + memset(cli->inbuf, '\0', cli->bufsize); - cli_init_creds(cli, NULL); + cli->initialised = 1; return cli; } -/**************************************************************************** -close the socket descriptor -****************************************************************************/ -void cli_close_socket(struct cli_state *cli) -{ -#ifdef WITH_SSL - if (cli->fd != -1) - { - sslutil_disconnect(cli->fd); - } -#endif /* WITH_SSL */ - if (cli->fd != -1) - { - close(cli->fd); - } - cli->fd = -1; -} - /**************************************************************************** shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { - DEBUG(10,("cli_shutdown\n")); if (cli->outbuf) { free(cli->outbuf); @@ -2758,7 +2665,12 @@ void cli_shutdown(struct cli_state *cli) { free(cli->inbuf); } - cli_close_socket(cli); +#ifdef WITH_SSL + if (cli->fd != -1) + sslutil_disconnect(cli->fd); +#endif /* WITH_SSL */ + if (cli->fd != -1) + close(cli->fd); memset(cli, 0, sizeof(*cli)); } @@ -2771,43 +2683,34 @@ void cli_shutdown(struct cli_state *cli) for 32 bit "warnings", a return code of 0 is expected. ****************************************************************************/ -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) { - int flgs2; + int flgs2 = SVAL(cli->inbuf,smb_flg2); char rcls; int code; - if (!cli->initialised) - { - DEBUG(0,("cli_error: client state uninitialised!\n")); - return EINVAL; - } - - flgs2 = SVAL(cli->inbuf,smb_flg2); - if (eclass) *eclass = 0; if (num ) *num = 0; + if (nt_rpc_error) *nt_rpc_error = cli->nt_error; - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) - { + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { /* 32 bit error codes detected */ uint32 nt_err = IVAL(cli->inbuf,smb_rcls); if (num) *num = nt_err; DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; - switch (nt_err & 0xFFFFFF) - { - case NT_STATUS_ACCESS_VIOLATION : return EACCES; - case NT_STATUS_NO_SUCH_FILE : return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE : return ENODEV; - case NT_STATUS_INVALID_HANDLE : return EBADF; - case NT_STATUS_NO_MEMORY : return ENOMEM; - case NT_STATUS_ACCESS_DENIED : return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION : return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID : return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; + switch (nt_err & 0xFFFFFF) { + case NT_STATUS_ACCESS_VIOLATION: return EACCES; + case NT_STATUS_NO_SUCH_FILE: return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; + case NT_STATUS_INVALID_HANDLE: return EBADF; + case NT_STATUS_NO_MEMORY: return ENOMEM; + case NT_STATUS_ACCESS_DENIED: return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; + case NT_STATUS_SHARING_VIOLATION: return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; } /* for all other cases - a default code */ @@ -2830,7 +2733,6 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num) case ERRrename: return EEXIST; case ERRbadshare: return EBUSY; case ERRlock: return EBUSY; - case ERRmoredata: return 0; /* Informational only */ } } if (rcls == ERRSRV) { @@ -2886,37 +2788,30 @@ BOOL cli_reestablish_connection(struct cli_state *cli) /* copy the parameters necessary to re-establish the connection */ if (cli->cnum != 0) - { - do_tcon = True; - } - - if (do_tcon) { fstrcpy(share, cli->share); fstrcpy(dev , cli->dev); + do_tcon = True; } memcpy(&called , &(cli->called ), sizeof(called )); memcpy(&calling, &(cli->calling), sizeof(calling)); - fstrcpy(dest_host, cli->desthost); + fstrcpy(dest_host, cli->full_dest_host_name); DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", nmb_namestr(&calling), nmb_namestr(&called), inet_ntoa(cli->dest_ip), - cli->usr.user_name, cli->usr.domain)); + cli->user_name, cli->domain)); cli->fd = -1; if (cli_establish_connection(cli, dest_host, &cli->dest_ip, &calling, &called, - share, dev, False, do_tcon)) - { - if (cli->fd != oldfd) - { - if (dup2(cli->fd, oldfd) == oldfd) - { - cli_close_socket(cli); + share, dev, False, do_tcon)) { + if (cli->fd != oldfd) { + if (dup2(cli->fd, oldfd) == oldfd) { + close(cli->fd); } } return True; @@ -2924,101 +2819,18 @@ BOOL cli_reestablish_connection(struct cli_state *cli) return False; } -static BOOL cli_init_redirect(struct cli_state *cli, - const char* srv_name, struct in_addr *destip, - const struct ntuser_creds *usr) -{ - int sock; - fstring ip_name; - struct cli_state cli_redir; - fstring path; - - uint32 len; - char *data; - char *in = cli->inbuf; - char *out = cli->outbuf; - prs_struct ps; - uint16 command; - - slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid()); - - if (strequal(srv_name, "*SMBSERVER")) - { - fstrcpy(ip_name, "\\\\"); - inet_aton(&ip_name[2], destip); - srv_name = ip_name; - } - - sock = open_pipe_sock(path); - - if (sock < 0) - { - return False; - } - - command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON; - - if (!create_ntuser_creds(&ps, srv_name, 0x0, command, usr, cli->reuse)) - { - DEBUG(0,("could not parse credentials\n")); - close(sock); - return False; - } - - len = ps.offset; - data = mem_data(&ps.data, 0); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("data len: %d\n", len)); - dump_data(100, data, len); -#endif - - SIVAL(data, 0, len); - - if (write(sock, data, len) <= 0) - { - DEBUG(0,("write failed\n")); - close(sock); - return False; - } - - len = read(sock, &cli_redir, sizeof(cli_redir)); - - if (len != sizeof(cli_redir)) - { - DEBUG(0,("read failed\n")); - close(sock); - return False; - } - - memcpy(cli, &cli_redir, sizeof(cli_redir)); - cli->inbuf = in; - cli->outbuf = out; - cli->fd = sock; - cli->reuse = False; - - return sock; -} - /**************************************************************************** establishes a connection right up to doing tconX, reading in a password. ****************************************************************************/ BOOL cli_establish_connection(struct cli_state *cli, - const char *dest_host, struct in_addr *dest_ip, + char *dest_host, struct in_addr *dest_ip, struct nmb_name *calling, struct nmb_name *called, char *service, char *service_type, BOOL do_shutdown, BOOL do_tcon) { - fstring callingstr; - fstring calledstr; - - nmb_safe_namestr(calling, callingstr, sizeof(callingstr)); - nmb_safe_namestr(called , calledstr , sizeof(calledstr )); - - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n", - callingstr, calledstr, inet_ntoa(*dest_ip), - cli->usr.user_name, cli->usr.domain, - cli->use_ntlmv2 ? "v2" : "v1")); + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), + cli->user_name, cli->domain)); /* establish connection */ @@ -3027,24 +2839,12 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } - if (cli->fd == -1 && cli->redirect) - { - if (cli_init_redirect(cli, dest_host, dest_ip, &cli->usr)) - { - DEBUG(10,("cli_establish_connection: redirected OK\n")); - return True; - } - else - { - DEBUG(10,("redirect FAILED, make direct connection\n")); - } - } if (cli->fd == -1) { if (!cli_connect(cli, dest_host, dest_ip)) { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - callingstr, inet_ntoa(*dest_ip))); + nmb_namestr(calling), inet_ntoa(*dest_ip))); return False; } } @@ -3053,9 +2853,7 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session request\n")); if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return False; } @@ -3063,242 +2861,33 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed negprot\n")); if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return False; } - if (cli->usr.domain[0] == 0) + if (cli->pwd.cleartext || cli->pwd.null_pwd) { - safe_strcpy(cli->usr.domain, cli->server_domain, - sizeof(cli->usr.domain)); - } + fstring passwd; + int pass_len; - if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY)) - { - /* common to both session setups */ - uint32 ntlmssp_flgs; - char pwd_buf[128]; - int buf_len; - char *p; - char *e = pwd_buf + sizeof(pwd_buf); - - /* 1st session setup */ - char pwd_data[34] = - { - 0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05, - 0x05, 0x02, 0xa0, 0x36, 0x30, 0x34, 0xa0, 0x0e, - 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, - 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22, - 0x04, 0x20 - }; - /* 2nd session setup */ -#if 0 - char pwd_data_2[8] = - { - 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b - }; -#endif - char pwd_data_2[8] = - { - 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b - }; - prs_struct auth_resp; - int resp_len; - char *p_gssapi; - char *p_oem; - char *p_gssapi_end; - uint16 gssapi_len; - - memset(pwd_buf, 0, sizeof(pwd_buf)); - memcpy(pwd_buf, pwd_data, sizeof(pwd_data)); - p = pwd_buf + sizeof(pwd_data); - - safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1); - p = skip_string(p, 1); - CVAL(p, 0) = 0x1; - p += 4; - ntlmssp_flgs = - NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_OEM | - NTLMSSP_NEGOTIATE_SIGN | - NTLMSSP_NEGOTIATE_SEAL | - NTLMSSP_NEGOTIATE_LM_KEY | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_ALWAYS_SIGN | - NTLMSSP_NEGOTIATE_00001000 | - NTLMSSP_NEGOTIATE_00002000; - SIVAL(p, 0, ntlmssp_flgs); - p += 4; - p += 16; /* skip some NULL space */ - CVAL(p, 0) = 0; p++; /* alignment */ - - buf_len = PTR_DIFF(p, pwd_buf); - - /* first session negotiation stage */ - if (!cli_session_setup_x(cli, cli->usr.user_name, - pwd_buf, buf_len, - NULL, 0, - cli->usr.domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - - DEBUG(1,("1st session setup ok\n")); - - if (*cli->server_domain || *cli->server_os || *cli->server_type) - { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - cli->server_domain, - cli->server_os, - cli->server_type)); - } - - p = smb_buf(cli->inbuf) + 0x2f; - ntlmssp_flgs = IVAL(p, 0); /* 0x80808a05; */ - p += 4; - memcpy(cli->cryptkey, p, 8); -#ifdef DEBUG_PASSWORD - DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n", - ntlmssp_flgs)); - - DEBUG(100,("cli_session_setup_x: crypt key\n")); - dump_data(100, cli->cryptkey, 8); -#endif - prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False); - - if (cli->use_ntlmv2 != False) - { - DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, - cli->usr.user_name, calling->name, cli->usr.domain); - } - else - { - DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); - } - - create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain, - cli->usr.user_name, cli->calling.name, - ntlmssp_flgs, - &auth_resp); - prs_link(NULL, &auth_resp, NULL); - - memset(pwd_buf, 0, sizeof(pwd_buf)); - p = pwd_buf; - - CVAL(p, 0) = 0xa1; p++; - CVAL(p, 0) = 0x82; p++; - p_gssapi = p; p+= 2; - CVAL(p, 0) = 0x30; p++; - CVAL(p, 0) = 0x82; p++; - p += 2; - - CVAL(p, 0) = 0xa2; p++; - CVAL(p, 0) = 0x82; p++; - p_oem = p; p+= 2; - CVAL(p, 0) = 0x04; p++; - CVAL(p, 0) = 0x82; p++; - p += 2; - - p_gssapi_end = p; - - safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1); - p = skip_string(p, 1); - CVAL(p, 0) = 0x3; - p += 4; - - resp_len = mem_buf_len(auth_resp.data); - mem_buf_copy(p, auth_resp.data, 0, resp_len); - prs_mem_free(&auth_resp); - - p += resp_len; - - buf_len = PTR_DIFF(p, pwd_buf); - gssapi_len = PTR_DIFF(p, p_gssapi_end) + 12; - - *p_gssapi++ = (gssapi_len >> 8) & 0xff; - *p_gssapi++ = gssapi_len & 0xff; - - p_gssapi += 2; - gssapi_len -= 4; - - *p_gssapi++ = (gssapi_len >> 8) & 0xff; - *p_gssapi++ = gssapi_len & 0xff; - - gssapi_len -= 4; - - *p_oem++ = (gssapi_len >> 8) & 0xff; - *p_oem++ = gssapi_len & 0xff; - - p_oem += 2; - gssapi_len -= 4; - - *p_oem++ = (gssapi_len >> 8) & 0xff; - *p_oem++ = gssapi_len & 0xff; - - /* second session negotiation stage */ - if (!cli_session_setup_x(cli, cli->usr.user_name, - pwd_buf, buf_len, - NULL, 0, - cli->usr.domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - - DEBUG(1,("2nd session setup ok\n")); - - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - NULL, 0)) - - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - } - } - else if (cli->usr.pwd.cleartext || cli->usr.pwd.null_pwd) - { - fstring passwd, ntpasswd; - int pass_len = 0, ntpass_len = 0; - - if (cli->usr.pwd.null_pwd) + if (cli->pwd.null_pwd) { /* attempt null session */ - passwd[0] = ntpasswd[0] = 0; - pass_len = ntpass_len = 1; + passwd[0] = 0; + pass_len = 1; } else { /* attempt clear-text session */ - pwd_get_cleartext(&(cli->usr.pwd), passwd); + pwd_get_cleartext(&(cli->pwd), passwd); pass_len = strlen(passwd); } /* attempt clear-text session */ - if (!cli_session_setup(cli, calling->name, - cli->usr.user_name, + if (!cli_session_setup(cli, cli->user_name, passwd, pass_len, - ntpasswd, ntpass_len, - cli->usr.domain)) + NULL, 0, + cli->domain)) { DEBUG(1,("failed session setup\n")); if (do_shutdown) @@ -3324,68 +2913,25 @@ BOOL cli_establish_connection(struct cli_state *cli, else { /* attempt encrypted session */ + unsigned char nt_sess_pwd[24]; unsigned char lm_sess_pwd[24]; - unsigned char nt_sess_pwd[128]; - size_t nt_sess_pwd_len; - - if (cli->use_ntlmv2 != False) - { - DEBUG(10,("cli_establish_connection: NTLMv2\n")); - pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey, - cli->usr.user_name, calling->name, cli->usr.domain); - } - else - { - DEBUG(10,("cli_establish_connection: NTLMv1\n")); - pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey); - } - pwd_get_lm_nt_owf(&(cli->usr.pwd), lm_sess_pwd, nt_sess_pwd, - &nt_sess_pwd_len, cli->sess_key); + /* creates (storing a copy of) and then obtains a 24 byte password OWF */ + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); /* attempt encrypted session */ - if (!cli_session_setup_x(cli, cli->usr.user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, nt_sess_pwd_len, - cli->usr.domain)) + if (!cli_session_setup(cli, cli->user_name, + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + (char*)nt_sess_pwd, sizeof(nt_sess_pwd), + cli->domain)) { DEBUG(1,("failed session setup\n")); - - if (cli->use_ntlmv2 == Auto) - { - DEBUG(10,("NTLMv2 failed. Using NTLMv1\n")); - cli->use_ntlmv2 = False; - if (do_tcon) - { - fstrcpy(cli->share, service); - fstrcpy(cli->dev, service_type); - } - fstrcpy(cli->desthost, dest_host); - cli_close_socket(cli); - return cli_establish_connection(cli, - dest_host, dest_ip, - calling, called, - service, service_type, - do_shutdown, do_tcon); - } - if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return False; } - DEBUG(1,("session setup ok\n")); - - if (*cli->server_domain || *cli->server_os || *cli->server_type) - { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - cli->server_domain, - cli->server_os, - cli->server_type)); - } - if (do_tcon) { if (!cli_send_tconX(cli, service, service_type, @@ -3393,184 +2939,18 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed tcon_X\n")); if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return False; } } } if (do_shutdown) - { - cli_shutdown(cli); - } + cli_shutdown(cli); return True; } -BOOL cli_connect_auth(struct cli_state *cli, - const char* desthost, - struct in_addr *dest_ip, - const struct ntuser_creds *usr) -{ - extern pstring global_myname; - extern pstring scope; - struct nmb_name calling, called; - - ZERO_STRUCTP(cli); - if (!cli_initialise(cli)) - { - DEBUG(0,("unable to initialise client connection.\n")); - return False; - } - - make_nmb_name(&calling, global_myname, 0x0 , scope); - make_nmb_name(&called , desthost , 0x20, scope); - - cli_init_creds(cli, usr); - - if (!cli_establish_connection(cli, desthost, dest_ip, - &calling, &called, - "IPC$", "IPC", - False, True)) - { - cli_shutdown(cli); - return False; - } - - return True; -} - -/**************************************************************************** - connect to one of multiple servers: don't care which -****************************************************************************/ -BOOL cli_connect_servers_auth(struct cli_state *cli, - char *p, - const struct ntuser_creds *usr) -{ - fstring remote_host; - BOOL connected_ok = False; - - /* - * Treat each name in the 'password server =' line as a potential - * PDC/BDC. Contact each in turn and try and authenticate. - */ - - while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host))) - { - fstring desthost; - struct in_addr dest_ip; - strupper(remote_host); - - if (!resolve_srv_name( remote_host, desthost, &dest_ip)) - { - DEBUG(1,("Can't resolve address for %s\n", remote_host)); - continue; - } - - if (!cli_connect_auth(cli, desthost, &dest_ip, usr) && - !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, usr)) - { - continue; - } - - if (cli->protocol < PROTOCOL_LANMAN2 || - !IS_BITS_SET_ALL(cli->sec_mode, 1)) - { - DEBUG(1,("machine %s not in user level security mode\n", - remote_host)); - cli_shutdown(cli); - continue; - } - - /* - * We have an anonymous connection to IPC$. - */ - - connected_ok = True; - break; - } - - if (!connected_ok) - { - DEBUG(0,("Domain password server not available.\n")); - } - - return connected_ok; -} - -/**************************************************************************** - connect to one of multiple servers: don't care which -****************************************************************************/ -BOOL cli_connect_serverlist(struct cli_state *cli, char *p) -{ - fstring remote_host; - fstring desthost; - struct in_addr dest_ip; - BOOL connected_ok = False; - - /* - * Treat each name in the 'password server =' line as a potential - * PDC/BDC. Contact each in turn and try and authenticate. - */ - - while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host))) - { - ZERO_STRUCTP(cli); - - if (!cli_initialise(cli)) - { - DEBUG(0,("cli_connect_serverlist: unable to initialise client connection.\n")); - return False; - } - - standard_sub_basic(remote_host); - strupper(remote_host); - - if (!resolve_srv_name( remote_host, desthost, &dest_ip)) - { - DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_host)); - continue; - } - - if ((lp_security() != SEC_USER) && (ismyip(dest_ip))) - { - DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_host)); - continue; - } - - if (!cli_connect_auth(cli, remote_host , &dest_ip, NULL) && - !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, NULL)) - { - continue; - } - - - if (cli->protocol < PROTOCOL_LANMAN2 || - !IS_BITS_SET_ALL(cli->sec_mode, 1)) - { - DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n", - remote_host)); - cli_shutdown(cli); - continue; - } - - /* - * We have an anonymous connection to IPC$. - */ - - connected_ok = True; - break; - } - - if (!connected_ok) - { - DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n")); - } - - return connected_ok; -} /**************************************************************************** cancel a print job @@ -3583,7 +2963,7 @@ int cli_printjob_del(struct cli_state *cli, int job) int rdrcnt,rprcnt, ret = -1; pstring param; - bzero(param,sizeof(param)); + memset(param,'\0',sizeof(param)); p = param; SSVAL(p,0,81); /* DosPrintJobDel() */ @@ -3624,7 +3004,7 @@ int cli_print_queue(struct cli_state *cli, int result_code=0; int i = -1; - bzero(param,sizeof(param)); + memset(param,'\0',sizeof(param)); p = param; SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ @@ -3686,29 +3066,29 @@ check for existance of a dir ****************************************************************************/ BOOL cli_chkpath(struct cli_state *cli, char *path) { - fstring path2; + pstring path2; char *p; - fstrcpy(path2,path); + safe_strcpy(path2,path,sizeof(pstring)); trim_string(path2,NULL,"\\"); if (!*path2) *path2 = '\\'; - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,4 + strlen(path2),True); SCVAL(cli->outbuf,smb_com,SMBchkpth); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - p = smb_buf(cli->outbuf); *p++ = 4; - fstrcpy(p,path2); + safe_strcpy(p,path2,strlen(path2)); + unix_to_dos(p,True); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, NULL, NULL, NULL)) return False; return True; } @@ -3723,7 +3103,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, char *p; /* send a SMBsendstrt command */ - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBsendstrt; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -3732,20 +3112,22 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,username); + unix_to_dos(p,True); p = skip_string(p,1); *p++ = 4; pstrcpy(p,host); + unix_to_dos(p,True); p = skip_string(p,1); set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, NULL, NULL, NULL)) return False; *grp = SVAL(cli->inbuf,smb_vwv0); @@ -3760,7 +3142,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) { char *p; - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,1,len+3,True); CVAL(cli->outbuf,smb_com) = SMBsendtxt; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -3772,13 +3154,13 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) *p = 1; SSVAL(p,1,len); memcpy(p+3,msg,len); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, NULL, NULL, NULL)) return False; return True; } @@ -3788,7 +3170,7 @@ end a message ****************************************************************************/ BOOL cli_message_end(struct cli_state *cli, int grp) { - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,1,0,True); CVAL(cli->outbuf,smb_com) = SMBsendend; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -3797,13 +3179,13 @@ BOOL cli_message_end(struct cli_state *cli, int grp) cli_setup_packet(cli); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } - if (cli_error(cli, NULL, NULL)) return False; + if (cli_error(cli, NULL, NULL, NULL)) return False; return True; } @@ -3814,13 +3196,13 @@ query disk space ****************************************************************************/ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { - bzero(cli->outbuf,smb_size); + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBdskattr; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - cli_send_smb(cli, True); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; } @@ -3832,21 +3214,49 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } -BOOL get_any_dc_name(const char *domain, char *srv_name) +/**************************************************************************** + Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. +****************************************************************************/ + +BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, + struct in_addr *pdest_ip) { - struct cli_state cli; + struct nmb_name calling, called; - if (!cli_connect_servers_auth(&cli, - get_trusted_serverlist(domain), NULL)) - { - return False; - } + make_nmb_name(&calling, srchost, 0x0, scope); - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, cli.desthost); - strupper(srv_name); + /* + * If the called name is an IP address + * then use *SMBSERVER immediately. + */ - cli_shutdown(&cli); + if(is_ipaddress(desthost)) + make_nmb_name(&called, "*SMBSERVER", 0x20, scope); + else + make_nmb_name(&called, desthost, 0x20, scope); - return True; + if (!cli_session_request(cli, &calling, &called)) { + struct nmb_name smbservername; + + /* + * If the name wasn't *SMBSERVER then + * try with *SMBSERVER if the first name fails. + */ + + cli_shutdown(cli); + + make_nmb_name(&smbservername , "*SMBSERVER", 0x20, scope); + + if (!nmb_name_equal(&called, &smbservername) || + !cli_initialise(cli) || + !cli_connect(cli, desthost, pdest_ip) || + !cli_session_request(cli, &calling, &smbservername)) { + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER.\n", + desthost)); + cli_shutdown(cli); + return False; + } + } + + return True; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 299145ceff..abb9b7d42f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -23,17 +23,15 @@ #include "includes.h" extern pstring scope; -extern pstring global_myname; extern int DEBUGLEVEL; /* nmbd.c sets this to True. */ BOOL global_in_nmbd = False; - static int name_trn_id = 0; - /**************************************************************************** -interpret a node status response + Interpret a node status response. ****************************************************************************/ + static void _interpret_node_status(char *p, char *master,char *rname) { int numnames = CVAL(p,0); @@ -43,55 +41,54 @@ static void _interpret_node_status(char *p, char *master,char *rname) if (master) *master = 0; p += 1; - while (numnames--) - { - char qname[17]; - int type; - fstring flags; - int i; - *flags = 0; - StrnCpy(qname,p,15); - type = CVAL(p,15); - p += 16; - - fstrcat(flags, (p[0] & 0x80) ? " " : " "); - if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B "); - if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P "); - if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M "); - if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H "); - if (p[0] & 0x10) fstrcat(flags," "); - if (p[0] & 0x08) fstrcat(flags," "); - if (p[0] & 0x04) fstrcat(flags," "); - if (p[0] & 0x02) fstrcat(flags," "); - - if (master && !*master && type == 0x1d) { - StrnCpy(master,qname,15); - trim_string(master,NULL," "); - } + while (numnames--) { + char qname[17]; + int type; + fstring flags; + int i; + *flags = 0; + StrnCpy(qname,p,15); + type = CVAL(p,15); + p += 16; + + fstrcat(flags, (p[0] & 0x80) ? " " : " "); + if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B "); + if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P "); + if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M "); + if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H "); + if (p[0] & 0x10) fstrcat(flags," "); + if (p[0] & 0x08) fstrcat(flags," "); + if (p[0] & 0x04) fstrcat(flags," "); + if (p[0] & 0x02) fstrcat(flags," "); + + if (master && !*master && type == 0x1d) { + StrnCpy(master,qname,15); + trim_string(master,NULL," "); + } - if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { - StrnCpy(rname,qname,15); - trim_string(rname,NULL," "); - } + if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { + StrnCpy(rname,qname,15); + trim_string(rname,NULL," "); + } - for (i = strlen( qname) ; --i >= 0 ; ) { - if (!isprint((int)qname[i])) qname[i] = '.'; - } - DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags)); - p+=2; + for (i = strlen( qname) ; --i >= 0 ; ) { + if (!isprint((int)qname[i])) qname[i] = '.'; } + DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags)); + p+=2; + } + DEBUG(1,("num_good_sends=%d num_good_receives=%d\n", IVAL(p,20),IVAL(p,24))); } - /**************************************************************************** - do a netbios name status query on a host + Internal function handling a netbios name status query on a host. +**************************************************************************/ - the "master" parameter is a hack used for finding workgroups. - **************************************************************************/ -BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname, +static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname, BOOL verbose, + void (*fn_interpret_node_status)(char *, char *,char *), void (*fn)(struct packet_struct *)) { BOOL found=False; @@ -101,21 +98,9 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; - int packet_type = NMB_PACKET; - BOOL first_time = True; + static int name_trn_id = 0; - if (fd == -1) - { - retries = 1; - packet_type = NMB_SOCK_PACKET; - fd = get_nmb_sock(); - - if (fd < 0) - { - return False; - } - } - bzero((char *)&p,sizeof(p)); + memset((char *)&p,'\0',sizeof(p)); if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100); @@ -144,39 +129,40 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, p.port = NMB_PORT; p.fd = fd; p.timestamp = time(NULL); - p.packet_type = packet_type; + p.packet_type = NMB_PACKET; GetTimeOfDay(&tval); - while (1) - { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (first_time || TvalDiff(&tval,&tval2) > retry_time) - { - first_time = False; - if (!found && !send_packet(&p)) - { - if (packet_type == NMB_SOCK_PACKET) close(fd); - return False; - } - GetTimeOfDay(&tval); - } + if (!send_packet(&p)) + return(False); + + retries--; + + while (1) { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!found && !send_packet(&p)) + return False; + GetTimeOfDay(&tval); + retries--; + } - if ((p2=receive_packet(fd,packet_type,90))) - { - struct nmb_packet *nmb2 = &p2->packet.nmb; + if ((p2=receive_packet(fd,NMB_PACKET,90))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) { - /* its not for us - maybe deal with it later */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } + if (nmb->header.name_trn_id != nmb2->header.name_trn_id || + !nmb2->header.response) { + /* its not for us - maybe deal with it later */ + if (fn) + fn(p2); + else + free_packet(p2); + continue; + } if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || @@ -189,55 +175,53 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, continue; } - retries--; - - _interpret_node_status(&nmb2->answers->rdata[0], master,rname); + if(fn_interpret_node_status) + (*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname); free_packet(p2); - if (packet_type == NMB_SOCK_PACKET) close(fd); return(True); } - } - + } - DEBUG(0,("No status response (this is not unusual)\n")); + if(verbose) + DEBUG(0,("No status response (this is not unusual)\n")); -if (packet_type == NMB_SOCK_PACKET) close(fd); return(False); } +/**************************************************************************** + Do a netbios name status query on a host. + The "master" parameter is a hack used for finding workgroups. +**************************************************************************/ + +BOOL name_status(int fd,char *name,int name_type,BOOL recurse, + struct in_addr to_ip,char *master,char *rname, + void (*fn)(struct packet_struct *)) +{ + return internal_name_status(fd,name,name_type,recurse, + to_ip,master,rname,True, + _interpret_node_status, fn); +} /**************************************************************************** - do a netbios name query to find someones IP - returns an array of IP addresses or NULL if none - *count will be set to the number of addresses returned - ****************************************************************************/ + Do a netbios name query to find someones IP. + Returns an array of IP addresses or NULL if none. + *count will be set to the number of addresses returned. +****************************************************************************/ + struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *)) { BOOL found=False; int i, retries = 3; - int retry_time = bcast?2000:2000; + int retry_time = bcast?250:2000; struct timeval tval; struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; + static int name_trn_id = 0; struct in_addr *ip_list = NULL; - BOOL packet_type = NMB_PACKET; - BOOL first_send = True; - - if (fd == -1) - { - retries = 1; - packet_type = NMB_SOCK_PACKET; - fd = get_nmb_sock(); - - if (fd < 0) - { - return NULL; - } - } - bzero((char *)&p,sizeof(p)); + memset((char *)&p,'\0',sizeof(p)); (*count) = 0; if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + @@ -267,27 +251,30 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO p.port = NMB_PORT; p.fd = fd; p.timestamp = time(NULL); - p.packet_type = packet_type; + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); - GetTimeOfDay(&tval); + if (!send_packet(&p)) + return NULL; - while (retries >= 0) + retries--; + + while (1) { struct timeval tval2; - GetTimeOfDay(&tval2); - if (first_send || TvalDiff(&tval,&tval2) > retry_time) + if (TvalDiff(&tval,&tval2) > retry_time) { - first_send = False; + if (!retries) + break; if (!found && !send_packet(&p)) - { - if (packet_type == NMB_SOCK_PACKET) close(fd); return NULL; - } GetTimeOfDay(&tval); + retries--; } - if ((p2=receive_packet(fd,packet_type,90))) + if ((p2=receive_packet(fd,NMB_PACKET,90))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); @@ -295,8 +282,6 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO if (nmb->header.name_trn_id != nmb2->header.name_trn_id || !nmb2->header.response) { - DEBUG(10,("packet not for us (received %d, expected %d\n", - nmb2->header.name_trn_id, nmb->header.name_trn_id)); /* * Its not for us - maybe deal with it later * (put it on the queue?). @@ -305,12 +290,9 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO fn(p2); else free_packet(p2); - continue; } - retries--; - if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || nmb2->header.rcode || @@ -345,15 +327,16 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO if (fn) break; - if(found) - { - DEBUG(10,("returning OK\n")); + /* + * If we're doing a unicast lookup we only + * expect one reply. Don't wait the full 2 + * seconds if we got one. JRA. + */ + if(!bcast && found) break; - } } } - if (packet_type == NMB_SOCK_PACKET) close(fd); return ip_list; } @@ -375,6 +358,7 @@ FILE *startlmhosts(char *fname) /******************************************************** Parse the next line in the lmhosts file. *********************************************************/ + BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) { pstring line; @@ -439,7 +423,7 @@ BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipad char *endptr; ptr++; - *name_type = (int)strtol(ptr, &endptr,0); + *name_type = (int)strtol(ptr, &endptr, 16); if(!*ptr || (endptr == ptr)) { @@ -465,108 +449,107 @@ void endlmhosts(FILE *fp) fclose(fp); } - - /******************************************************** -resolve via "bcast" method + Resolve via "bcast" method. *********************************************************/ -static BOOL resolve_bcast(const char *name, struct in_addr *return_ip, int name_type) + +static BOOL resolve_bcast(const char *name, int name_type, + struct in_addr **return_ip_list, int *return_count) { int sock, i; + int num_interfaces = iface_count(); + + *return_ip_list = NULL; + *return_count = 0; /* * "bcast" means do a broadcast lookup on all the local interfaces. */ - DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x20>\n", name)); + DEBUG(3,("resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type)); sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()) ); - - if (sock != -1) { - struct in_addr *iplist = NULL; - int count; - int num_interfaces = iface_count(); - set_socket_options(sock,"SO_BROADCAST"); - /* - * Lookup the name on all the interfaces, return on - * the first successful match. - */ - for( i = 0; i < num_interfaces; i++) { - struct in_addr sendto_ip; - /* Done this way to fix compiler error on IRIX 5.x */ - sendto_ip = *iface_bcast(*iface_n_ip(i)); - iplist = name_query(sock, name, name_type, True, - True, sendto_ip, &count, NULL); - if(iplist != NULL) { - *return_ip = iplist[0]; - free((char *)iplist); - close(sock); - return True; - } + interpret_addr(lp_socket_address()), True ); + + if (sock == -1) return False; + + set_socket_options(sock,"SO_BROADCAST"); + /* + * Lookup the name on all the interfaces, return on + * the first successful match. + */ + for( i = num_interfaces-1; i >= 0; i--) { + struct in_addr sendto_ip; + /* Done this way to fix compiler error on IRIX 5.x */ + sendto_ip = *iface_bcast(*iface_n_ip(i)); + *return_ip_list = name_query(sock, name, name_type, True, + True, sendto_ip, return_count, NULL); + if(*return_ip_list != NULL) { + close(sock); + return True; } - close(sock); } + close(sock); return False; } - - /******************************************************** -resolve via "wins" method + Resolve via "wins" method. *********************************************************/ -static BOOL resolve_wins(const char *name, struct in_addr *return_ip, int name_type) + +static BOOL resolve_wins(const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) { - int sock; - struct in_addr wins_ip; - BOOL wins_ismyip; + int sock; + struct in_addr wins_ip; + BOOL wins_ismyip; - /* - * "wins" means do a unicast lookup to the WINS server. - * Ignore if there is no WINS server specified or if the - * WINS server is one of our interfaces (if we're being - * called from within nmbd - we can't do this call as we - * would then block). - */ + *return_iplist = NULL; + *return_count = 0; + + /* + * "wins" means do a unicast lookup to the WINS server. + * Ignore if there is no WINS server specified or if the + * WINS server is one of our interfaces (if we're being + * called from within nmbd - we can't do this call as we + * would then block). + */ - DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x20>\n", name)); + DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); - if(!*lp_wins_server()) { - DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n")); - return False; - } + if(!*lp_wins_server()) { + DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS server present.\n")); + return False; + } - wins_ip = *interpret_addr2(lp_wins_server()); - wins_ismyip = ismyip(wins_ip); + wins_ip = *interpret_addr2(lp_wins_server()); + wins_ismyip = ismyip(wins_ip); - if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()) ); + if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()), True ); - if (sock != -1) { - struct in_addr *iplist = NULL; - int count; - iplist = name_query(sock, name, name_type, False, - True, wins_ip, &count, NULL); - if(iplist != NULL) { - *return_ip = iplist[0]; - free((char *)iplist); - close(sock); - return True; - } - close(sock); - } - } + if (sock != -1) { + *return_iplist = name_query(sock, name, name_type, False, + True, wins_ip, return_count, NULL); + if(*return_iplist != NULL) { + close(sock); + return True; + } + close(sock); + } + } - return False; + return False; } - /******************************************************** -resolve via "lmhosts" method + Resolve via "lmhosts" method. *********************************************************/ -static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int name_type) + +static BOOL resolve_lmhosts(const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) { /* * "lmhosts" means parse the local lmhosts file. @@ -575,15 +558,27 @@ static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int nam FILE *fp; pstring lmhost_name; int name_type2; + struct in_addr return_ip; + + *return_iplist = NULL; + *return_count = 0; - DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n", name)); + DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type)); fp = startlmhosts( LMHOSTSFILE ); if(fp) { - while (getlmhostsent(fp, lmhost_name, &name_type2, return_ip)) { + while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) { if (strequal(name, lmhost_name) && - name_type == name_type2) { + ((name_type2 == -1) || (name_type == name_type2)) + ) { endlmhosts(fp); + *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); + if(*return_iplist == NULL) { + DEBUG(3,("resolve_lmhosts: malloc fail !\n")); + return False; + } + **return_iplist = return_ip; + *return_count = 1; return True; } } @@ -594,89 +589,94 @@ static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int nam /******************************************************** -resolve via "hosts" method + Resolve via "hosts" method. *********************************************************/ -static BOOL resolve_hosts(const char *name, struct in_addr *return_ip) + +static BOOL resolve_hosts(const char *name, + struct in_addr **return_iplist, int *return_count) { /* * "host" means do a localhost, or dns lookup. */ struct hostent *hp; - DEBUG(3,("resolve_name: Attempting host lookup for name %s\n", name)); + *return_iplist = NULL; + *return_count = 0; + + DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name)); if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { - putip((char *)return_ip,(char *)hp->h_addr); + struct in_addr return_ip; + putip((char *)&return_ip,(char *)hp->h_addr); + *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); + if(*return_iplist == NULL) { + DEBUG(3,("resolve_hosts: malloc fail !\n")); + return False; + } + **return_iplist = return_ip; + *return_count = 1; return True; } return False; } - /******************************************************** - Resolve a name into an IP address. Use this function if - the string is either an IP address, DNS or host name - or NetBIOS name. This uses the name switch in the + Internal interface to resolve a name into an IP address. + Use this function if the string is either an IP address, DNS + or host name or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. *********************************************************/ -BOOL is_ip_address(const char *name) -{ - int i; - for (i=0; name[i]; i++) - if (!(isdigit((int)name[i]) || name[i] == '.')) - return False; - - return True; -} -/******************************************************** - Resolve a name into an IP address. Use this function if - the string is either an IP address, DNS or host name - or NetBIOS name. This uses the name switch in the - smb.conf to determine the order of name resolution. -*********************************************************/ -BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) +static BOOL internal_resolve_name(const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) { pstring name_resolve_list; fstring tok; char *ptr; - - if (strcmp(name,"0.0.0.0") == 0) { - return_ip->s_addr = 0; - return True; - } - if (strcmp(name,"255.255.255.255") == 0) { - return_ip->s_addr = 0xFFFFFFFF; - return True; - } - - /* if it's in the form of an IP address then get the lib to interpret it */ - if (is_ip_address(name)) { - return_ip->s_addr = inet_addr(name); + BOOL allones = (strcmp(name,"255.255.255.255") == 0); + BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); + BOOL is_address = is_ipaddress(name); + *return_iplist = NULL; + *return_count = 0; + + if (allzeros || allones || is_address) { + *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); + if(*return_iplist == NULL) { + DEBUG(3,("internal_resolve_name: malloc fail !\n")); + return False; + } + if(is_address) { + /* if it's in the form of an IP address then get the lib to interpret it */ + (*return_iplist)->s_addr = inet_addr(name); + } else { + (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0; + *return_count = 1; + } return True; } - + pstrcpy(name_resolve_list, lp_name_resolve_order()); ptr = name_resolve_list; - if (!ptr || !*ptr) ptr = "host"; + if (!ptr || !*ptr) + ptr = "host"; while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (name_type == 0x20 && resolve_hosts(name, return_ip)) { + if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) { return True; } } else if(strequal( tok, "lmhosts")) { - if (resolve_lmhosts(name, return_ip, name_type)) { + if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { return True; } } else if(strequal( tok, "wins")) { /* don't resolve 1D via WINS */ if (name_type != 0x1D && - resolve_wins(name, return_ip, name_type)) { + resolve_wins(name, name_type, return_iplist, return_count)) { return True; } } else if(strequal( tok, "bcast")) { - if (resolve_bcast(name, return_ip, name_type)) { + if (resolve_bcast(name, name_type, return_iplist, return_count)) { return True; } } else { @@ -684,50 +684,319 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) } } + if((*return_iplist) != NULL) { + free((char *)(*return_iplist)); + *return_iplist = NULL; + } return False; } /******************************************************** - resolve a name of format \\server_name or \\ipaddress - into a name. also, cut the \\ from the front for us. + Internal interface to resolve a name into one IP address. + Use this function if the string is either an IP address, DNS + or host name or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. *********************************************************/ -BOOL resolve_srv_name(const char* srv_name, fstring dest_host, - struct in_addr *ip) -{ - BOOL ret; - const char *sv_name = srv_name; - DEBUG(10,("resolve_srv_name: %s\n", srv_name)); +BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) +{ + struct in_addr *ip_list = NULL; + int count = 0; - if (srv_name == NULL || strequal("\\\\.", srv_name)) - { - fstrcpy(dest_host, global_myname); - ip = interpret_addr2("127.0.0.1"); + if(internal_resolve_name(name, name_type, &ip_list, &count)) { + *return_ip = ip_list[0]; + free((char *)ip_list); return True; } + if(ip_list != NULL) + free((char *)ip_list); + return False; +} - if (strnequal("\\\\", srv_name, 2)) - { - sv_name = &srv_name[2]; - } +/******************************************************** + Find the IP address of the master browser or DMB for a workgroup. +*********************************************************/ - fstrcpy(dest_host, sv_name); - ret = resolve_name(dest_host, ip, 0x20); - - if (is_ip_address(dest_host)) - { - fstrcpy(dest_host, "*SMBSERVER"); +BOOL find_master_ip(char *group, struct in_addr *master_ip) +{ + struct in_addr *ip_list = NULL; + int count = 0; + + if (internal_resolve_name(group, 0x1D, &ip_list, &count)) { + *master_ip = ip_list[0]; + free((char *)ip_list); + return True; } - - return ret; + if(internal_resolve_name(group, 0x1B, &ip_list, &count)) { + *master_ip = ip_list[0]; + free((char *)ip_list); + return True; + } + + if(ip_list != NULL) + free((char *)ip_list); + return False; } /******************************************************** -find the IP address of the master browser or DMB for a workgroup + Internal function to extract the MACHINE<0x20> name. *********************************************************/ -BOOL find_master_ip(char *group, struct in_addr *master_ip) + +static void _lookup_pdc_name(char *p, char *master,char *rname) +{ + int numnames = CVAL(p,0); + + *rname = '\0'; + + p += 1; + while (numnames--) { + int type = CVAL(p,15); + if(type == 0x20) { + StrnCpy(rname,p,15); + trim_string(rname,NULL," "); + return; + } + p += 18; + } +} + +/******************************************************** + Lookup a PDC name given a Domain name and IP address. +*********************************************************/ + +BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name) { - if (resolve_name(group, master_ip, 0x1D)) return True; +#if !defined(I_HATE_WINDOWS_REPLY_CODE) + + fstring pdc_name; + BOOL ret; + + /* + * Due to the fact win WinNT *sucks* we must do a node status + * query here... JRA. + */ - return resolve_name(group, master_ip, 0x1B); + int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); + + if(sock == -1) + return False; + + *pdc_name = '\0'; + + ret = internal_name_status(sock,"*SMBSERVER",0x20,True, + *pdc_ip,NULL,pdc_name,False, + _lookup_pdc_name,NULL); + + close(sock); + + if(ret && *pdc_name) { + fstrcpy(ret_name, pdc_name); + return True; + } + + return False; + +#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */ + /* + * Sigh. I *love* this code, it took me ages to get right and it's + * completely *USELESS* because NT 4.x refuses to send the mailslot + * reply back to the correct port (it always uses 138). + * I hate NT when it does these things... JRA. + */ + + int retries = 3; + int retry_time = 2000; + struct timeval tval; + struct packet_struct p; + struct dgram_packet *dgram = &p.packet.dgram; + char *ptr,*p2; + char tmp[4]; + int len; + struct sockaddr_in sock_name; + int sock_len = sizeof(sock_name); + const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON"; + static int name_trn_id = 0; + char buffer[1024]; + char *bufp; + int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); + + if(sock == -1) + return False; + + /* Find out the transient UDP port we have been allocated. */ + if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) { + DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n", + strerror(errno))); + close(sock); + return False; + } + + /* + * Create the request data. + */ + + memset(buffer,'\0',sizeof(buffer)); + bufp = buffer; + SSVAL(bufp,0,QUERYFORPDC); + bufp += 2; + fstrcpy(bufp,srcname); + bufp += (strlen(bufp) + 1); + fstrcpy(bufp,"\\MAILSLOT\\NET\\GETDC411"); + bufp += (strlen(bufp) + 1); + bufp = align2(bufp, buffer); + dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1); + bufp = skip_unicode_string(bufp, 1); + SIVAL(bufp,0,1); + SSVAL(bufp,4,0xFFFF); + SSVAL(bufp,6,0xFFFF); + bufp += 8; + len = PTR_DIFF(bufp,buffer); + + if (!name_trn_id) + name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100); + name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; + + memset((char *)&p,'\0',sizeof(p)); + + /* DIRECT GROUP or UNIQUE datagram. */ + dgram->header.msg_type = 0x10; + dgram->header.flags.node_type = M_NODE; + dgram->header.flags.first = True; + dgram->header.flags.more = False; + dgram->header.dgm_id = name_trn_id; + dgram->header.source_ip = sock_name.sin_addr; + dgram->header.source_port = ntohs(sock_name.sin_port); + dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ + dgram->header.packet_offset = 0; + + make_nmb_name(&dgram->source_name,srcname,0,scope); + make_nmb_name(&dgram->dest_name,domain,0x1B,scope); + + ptr = &dgram->data[0]; + + /* Setup the smb part. */ + ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ + memcpy(tmp,ptr,4); + set_message(ptr,17,17 + len,True); + memcpy(ptr,tmp,4); + + CVAL(ptr,smb_com) = SMBtrans; + SSVAL(ptr,smb_vwv1,len); + SSVAL(ptr,smb_vwv11,len); + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); + SSVAL(ptr,smb_vwv13,3); + SSVAL(ptr,smb_vwv14,1); + SSVAL(ptr,smb_vwv15,1); + SSVAL(ptr,smb_vwv16,2); + p2 = smb_buf(ptr); + pstrcpy(p2,mailslot); + p2 = skip_string(p2,1); + + memcpy(p2,buffer,len); + p2 += len; + + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ + + p.ip = *pdc_ip; + p.port = DGRAM_PORT; + p.fd = sock; + p.timestamp = time(NULL); + p.packet_type = DGRAM_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) { + DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); + close(sock); + return False; + } + + retries--; + + while (1) { + struct timeval tval2; + struct packet_struct *p_ret; + + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!send_packet(&p)) { + DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); + close(sock); + return False; + } + GetTimeOfDay(&tval); + retries--; + } + + if ((p_ret = receive_packet(sock,NMB_PACKET,90))) { + struct nmb_packet *nmb2 = &p_ret->packet.nmb; + struct dgram_packet *dgram2 = &p_ret->packet.dgram; + char *buf; + char *buf2; + + debug_nmb_packet(p_ret); + + if (memcmp(&p.ip, &p_ret->ip, sizeof(p.ip))) { + /* + * Not for us. + */ + DEBUG(0,("lookup_pdc_name: datagram return IP %s doesn't match\n", inet_ntoa(p_ret->ip) )); + free_packet(p_ret); + continue; + } + + buf = &dgram2->data[0]; + buf -= 4; + + if (CVAL(buf,smb_com) != SMBtrans) { + DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)CVAL(buf,smb_com), + (unsigned int)SMBtrans )); + free_packet(p_ret); + continue; + } + + len = SVAL(buf,smb_vwv11); + buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); + + if (len <= 0) { + DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len )); + free_packet(p_ret); + continue; + } + + DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n", + nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name), + inet_ntoa(p_ret->ip), smb_buf(buf),CVAL(buf2,0),len)); + + if(SVAL(buf,0) != QUERYFORPDC_R) { + DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", + (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R )); + free_packet(p_ret); + continue; + } + + buf += 2; + /* Note this is safe as it is a bounded strcpy. */ + fstrcpy(ret_name, buf); + ret_name[sizeof(fstring)-1] = '\0'; + close(sock); + free_packet(p_ret); + return True; + } + } + + close(sock); + return False; +#endif /* I_HATE_WINDOWS_REPLY_CODE */ +} + +/******************************************************** + Get the IP address list of the PDC/BDC's of a Domain. +*********************************************************/ + +BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count) +{ + return internal_resolve_name(group, 0x1C, ip_list, count); } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 006cb5f5ee..3b14fd2c6b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -179,27 +179,34 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na unsigned char *ubuf = (unsigned char *)inbuf; int ret = 0; BOOL got_pointer=False; + int loop_count=0; - if (length - offset < 2) return(0); + if (length - offset < 2) + return(0); /* handle initial name pointers */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); m = ubuf[offset]; - if (!m) return(0); - if ((m & 0xC0) || offset+m+2 > length) return(0); + if (!m) + return(0); + if ((m & 0xC0) || offset+m+2 > length) + return(0); - bzero((char *)name,sizeof(*name)); + memset((char *)name,'\0',sizeof(*name)); /* the "compressed" part */ - if (!got_pointer) ret += m + 2; + if (!got_pointer) + ret += m + 2; offset++; - while (m) { + while (m > 0) { unsigned char c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0); + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) + return(0); name->name[n++] = (c1<<4) | c2; m -= 2; } @@ -213,21 +220,38 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na /* remove trailing spaces */ name->name[15] = 0; n = 14; - while (n && name->name[n]==' ') name->name[n--] = 0; + while (n && name->name[n]==' ') + name->name[n--] = 0; } /* now the domain parts (if any) */ n = 0; while (ubuf[offset]) { /* we can have pointers within the domain part as well */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); m = ubuf[offset]; - if (!got_pointer) ret += m+1; - if (n) name->scope[n++] = '.'; - if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0); + /* + * Don't allow null domain parts. + */ + if (!m) + return(0); + if (!got_pointer) + ret += m+1; + if (n) + name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) + return(0); offset++; - while (m--) name->scope[n++] = (char)ubuf[offset++]; + while (m--) + name->scope[n++] = (char)ubuf[offset++]; + + /* + * Watch for malicious loops. + */ + if (loop_count++ == 10) + return 0; } name->scope[n++] = 0; @@ -251,7 +275,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) if (strcmp(name->name,"*") == 0) { /* special case for wildcard name */ - bzero(buf1,20); + memset(buf1,'\0',20); buf1[0] = '*'; buf1[15] = name->name_type; } else { @@ -287,7 +311,6 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) return(ret); } - /******************************************************************* useful for debugging messages ******************************************************************/ @@ -297,23 +320,15 @@ char *nmb_namestr(struct nmb_name *n) static fstring ret[4]; char *p = ret[i]; - nmb_safe_namestr(n, p, sizeof(fstring)); + if (!n->scope[0]) + slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); + else + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); i = (i+1)%4; return(p); } -/******************************************************************* - useful for debugging messages - ******************************************************************/ -void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len) -{ - if (!n->scope[0]) - slprintf(str, len-1, "%s<%02x>",n->name,n->name_type); - else - slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); -} - /******************************************************************* allocate and parse some resource records ******************************************************************/ @@ -324,13 +339,14 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, *recs = (struct res_rec *)malloc(sizeof(**recs)*count); if (!*recs) return(False); - bzero(*recs,sizeof(**recs)*count); + memset((char *)*recs,'\0',sizeof(**recs)*count); for (i=0;i length) { free(*recs); + *recs = NULL; return(False); } (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); @@ -341,6 +357,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || (*offset)+(*recs)[i].rdlength > length) { free(*recs); + *recs = NULL; return(False); } memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); @@ -405,7 +422,7 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) int offset; int flags; - bzero((char *)dgram,sizeof(*dgram)); + memset((char *)dgram,'\0',sizeof(*dgram)); if (length < 14) return(False); @@ -447,7 +464,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) { int nm_flags,offset; - bzero((char *)nmb,sizeof(*nmb)); + memset((char *)nmb,'\0',sizeof(*nmb)); if (length < 12) return(False); @@ -563,12 +580,18 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) free_and_exit: - if(copy_nmb->answers) + if(copy_nmb->answers) { free((char *)copy_nmb->answers); - if(copy_nmb->nsrecs) + copy_nmb->answers = NULL; + } + if(copy_nmb->nsrecs) { free((char *)copy_nmb->nsrecs); - if(copy_nmb->additional) + copy_nmb->nsrecs = NULL; + } + if(copy_nmb->additional) { free((char *)copy_nmb->additional); + copy_nmb->additional = NULL; + } free((char *)pkt_copy); DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); @@ -617,9 +640,18 @@ struct packet_struct *copy_packet(struct packet_struct *packet) ******************************************************************/ static void free_nmb_packet(struct nmb_packet *nmb) { - if (nmb->answers) free(nmb->answers); - if (nmb->nsrecs) free(nmb->nsrecs); - if (nmb->additional) free(nmb->additional); + if (nmb->answers) { + free(nmb->answers); + nmb->answers = NULL; + } + if (nmb->nsrecs) { + free(nmb->nsrecs); + nmb->nsrecs = NULL; + } + if (nmb->additional) { + free(nmb->additional); + nmb->additional = NULL; + } } /******************************************************************* @@ -641,6 +673,7 @@ void free_packet(struct packet_struct *packet) free_nmb_packet(&packet->packet.nmb); else if (packet->packet_type == DGRAM_PACKET) free_dgram_packet(&packet->packet.dgram); + ZERO_STRUCTPN(packet); free(packet); } @@ -651,47 +684,15 @@ void free_packet(struct packet_struct *packet) struct packet_struct *read_packet(int fd,enum packet_type packet_type) { extern struct in_addr lastip; - struct nmb_state con; extern int lastport; struct packet_struct *packet; char buf[MAX_DGRAM_SIZE]; int length; BOOL ok=False; - if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) - { - uint16 trn_id = 0; - if (!read_nmb_sock(fd, &con)) - { - return False; - } - if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) - { - return False; - } - } - - length = read_udp_socket(fd,buf,sizeof(buf)); - - dump_data(100, buf, length); - - if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) - { - uint16 trn_id = 0; - if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) - { - return False; - } - } - + length = read_udp_socket(fd,buf,sizeof(buf)); if (length < MIN_DGRAM_SIZE) return(NULL); - if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET) - { - lastip = con.ip; - lastport = con.port; - } - packet = (struct packet_struct *)malloc(sizeof(*packet)); if (!packet) return(NULL); @@ -706,19 +707,17 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) switch (packet_type) { case NMB_PACKET: - case NMB_SOCK_PACKET: ok = parse_nmb(buf,length,&packet->packet.nmb); break; case DGRAM_PACKET: - case DGRAM_SOCK_PACKET: ok = parse_dgram(buf,length,&packet->packet.dgram); break; } if (!ok) { DEBUG(10,("read_packet: discarding packet id = %d\n", packet->packet.nmb.header.name_trn_id)); - free(packet); + free_packet(packet); return(NULL); } @@ -740,7 +739,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) struct sockaddr_in sock_out; /* set the address and port */ - bzero((char *)&sock_out,sizeof(sock_out)); + memset((char *)&sock_out,'\0',sizeof(sock_out)); putip((char *)&sock_out.sin_addr,(char *)&ip); sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; @@ -776,7 +775,7 @@ static int build_dgram(char *buf,struct packet_struct *p) /* put in the header */ ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2); + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); if (dgram->header.flags.more) ubuf[1] |= 1; if (dgram->header.flags.first) ubuf[1] |= 2; RSSVAL(ubuf,2,dgram->header.dgm_id); @@ -909,82 +908,23 @@ BOOL send_packet(struct packet_struct *p) char buf[1024]; int len=0; - DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type)); - - bzero(buf,sizeof(buf)); + memset(buf,'\0',sizeof(buf)); switch (p->packet_type) { case NMB_PACKET: - case NMB_SOCK_PACKET: len = build_nmb(buf,p); debug_nmb_packet(p); break; case DGRAM_PACKET: - case DGRAM_SOCK_PACKET: len = build_dgram(buf,p); break; } if (!len) return(False); - switch (p->packet_type) - { - case DGRAM_PACKET: - case NMB_PACKET: - return(send_udp(p->fd,buf,len,p->ip,p->port)); - break; - - case NMB_SOCK_PACKET: - case DGRAM_SOCK_PACKET: - { - fstring qbuf; - struct nmb_state nmb; - int qlen; - uint16 trn_id; - char *q = qbuf + 4; - - nmb.ip = p->ip; - nmb.port = p->port; - - SSVAL(q, 0, 0); - q += 2; - SSVAL(q, 0, 0); - q += 2; - memcpy(q, &nmb, sizeof(nmb)); - q += sizeof(nmb); - - qlen = PTR_DIFF(q, qbuf); - SIVAL(qbuf, 0, qlen); - - dump_data(100, qbuf, qlen); - - if (write(p->fd,qbuf,qlen) != qlen) - { - DEBUG(0,("send_packet: write hdr failed\n")); - return False; - } - if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) - { - DEBUG(0,("send_packet: 1st ack failed\n")); - return False; - } - if (write(p->fd,buf,len) != len) - { - DEBUG(0,("send_packet: write packet failed\n")); - return False; - } - if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id)) - { - DEBUG(0,("send_packet: 2nd ack failed\n")); - return False; - } - return True; - } - } - - return False; + return(send_udp(p->fd,buf,len,p->ip,p->port)); } /**************************************************************************** @@ -1001,8 +941,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - DEBUG(100,("receive_packet: %d %d\n", fd, type)); - sys_select(fd+1,&fds,NULL, &timeout); + sys_select(fd+1,&fds,&timeout); if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); @@ -1055,76 +994,3 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } - -BOOL read_nmb_sock(int c, struct nmb_state *con) -{ - fstring buf; - char *p = buf; - int rl; - uint32 len; - uint16 version; - uint16 command; - - ZERO_STRUCTP(con); - - rl = read(c, &buf, sizeof(len)); - - if (rl < 0) - { - DEBUG(0,("read_nmb_sock: error\n")); - return False; - } - if (rl != sizeof(len)) - { - DEBUG(0,("Unable to read length\n")); - dump_data(0, buf, sizeof(len)); - return False; - } - - len = IVAL(buf, 0); - - if (len > sizeof(buf)) - { - DEBUG(0,("length %d too long\n", len)); - return False; - } - - rl = read(c, buf, len); - - if (rl < 0) - { - DEBUG(0,("Unable to read from connection\n")); - return False; - } - -#ifdef DEBUG_PASSWORD - dump_data(100, buf, rl); -#endif - version = SVAL(p, 0); - p += 2; - command = SVAL(p, 0); - p += 2; - - memcpy(con, p, sizeof(*con)); - p += sizeof(*con); - - DEBUG(10,("read_nmb_sock: ip %s port: %d\n", - inet_ntoa(con->ip), con->port)); - - if (PTR_DIFF(p, buf) != rl) - { - DEBUG(0,("Buffer size %d %d!\n", - PTR_DIFF(p, buf), rl)); - return False; - } - - return True; -} - -int get_nmb_sock(void) -{ - fstring path; - slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent"); - - return open_pipe_sock(path); -} diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 9cf1fb8214..d2f9335000 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -514,18 +514,18 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, - { "NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB }, { NULL, 0 } }; /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -void get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len) +char *get_nt_error_msg(uint32 nt_code) { + static pstring msg; int idx = 0; - snprintf(msg, len, "NT code %08x", nt_code); + pstrcpy(msg, "Unknown NT error"); nt_code &= 0xFFFF; @@ -533,19 +533,11 @@ void get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len) { if (nt_errs[idx].nt_errcode == nt_code) { - safe_strcpy(msg, nt_errs[idx].nt_errstr, len); - return; + pstrcpy(msg, nt_errs[idx].nt_errstr); + return msg; } idx++; } -} - -/***************************************************************************** - returns an NT error message. not amazingly helpful, but better than a number. - *****************************************************************************/ -char *get_nt_error_msg(uint32 nt_code) -{ - static pstring msg; - get_safe_nt_error_msg(nt_code, msg, sizeof(msg)); return msg; } + diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index b5552d4cea..b0b1188f32 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -36,6 +36,8 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, struct cli_state cli; struct in_addr ip; + *err_str = '\0'; + if(!resolve_name( remote_machine, &ip, 0x20)) { slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n", remote_machine ); @@ -75,7 +77,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, * Thanks to for this fix. */ - if (!cli_session_setup(&cli, global_myname, "", "", 0, "", 0, "")) { + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 29cf77dd55..94b60d3ff0 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -29,38 +29,28 @@ initialises a password structure ****************************************************************************/ void pwd_init(struct pwd_info *pwd) { - ZERO_STRUCT(pwd->password ); - ZERO_STRUCT(pwd->smb_lm_pwd); - ZERO_STRUCT(pwd->smb_nt_pwd); - ZERO_STRUCT(pwd->smb_lm_owf); - ZERO_STRUCT(pwd->smb_nt_owf); - ZERO_STRUCT(pwd->sess_key ); - pwd->nt_owf_len = 0; + memset((char *)pwd->password , '\0', sizeof(pwd->password )); + memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd)); + memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd)); + memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf)); + memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf)); pwd->null_pwd = True; /* safest option... */ pwd->cleartext = False; pwd->crypted = False; } -/**************************************************************************** -returns NULL password flag -****************************************************************************/ -BOOL pwd_is_nullpwd(const struct pwd_info *pwd) -{ - return pwd->null_pwd; -} - /**************************************************************************** de-obfuscates a password ****************************************************************************/ -static void pwd_deobfuscate(const struct pwd_info *pwd) +static void pwd_deobfuscate(struct pwd_info *pwd) { } /**************************************************************************** obfuscates a password ****************************************************************************/ -static void pwd_obfuscate(const struct pwd_info *pwd) +static void pwd_obfuscate(struct pwd_info *pwd) { } @@ -71,59 +61,6 @@ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) { } -/**************************************************************************** -compares two passwords. hmm, not as trivial as expected. hmm. -****************************************************************************/ -BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) -{ - pwd_deobfuscate(pwd1); - pwd_deobfuscate(pwd2); - if (pwd1->cleartext && pwd2->cleartext) - { - if (strequal(pwd1->password, pwd2->password)) - { - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); - return True; - } - } - if (pwd1->null_pwd && pwd2->null_pwd) - { - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); - return True; - } - - if (!pwd1->null_pwd && !pwd2->null_pwd && - !pwd1->cleartext && !pwd2->cleartext) - { -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd compare: nt#\n")); - dump_data(100, pwd1->smb_nt_pwd, 16); - dump_data(100, pwd2->smb_nt_pwd, 16); -#endif - if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) - { - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); - return True; - } -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd compare: lm#\n")); - dump_data(100, pwd1->smb_lm_pwd, 16); - dump_data(100, pwd2->smb_lm_pwd, 16); -#endif - if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) - { - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); - return True; - } - } - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); - return False; -} /**************************************************************************** reads a password ****************************************************************************/ @@ -169,6 +106,7 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) { pwd_init(pwd); fstrcpy(pwd->password, clr); + unix_to_dos(pwd->password,True); pwd->cleartext = True; pwd->null_pwd = False; pwd->crypted = False; @@ -185,6 +123,7 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) if (pwd->cleartext) { fstrcpy(clr, pwd->password); + dos_to_unix(clr, True); } else { @@ -206,7 +145,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) } else { - bzero(pwd->smb_lm_pwd, 16); + memset((char *)pwd->smb_lm_pwd, '\0', 16); } if (nt_pwd) @@ -215,7 +154,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) } else { - bzero(pwd->smb_nt_pwd, 16); + memset((char *)pwd->smb_nt_pwd, '\0', 16); } pwd->null_pwd = False; @@ -228,7 +167,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) /**************************************************************************** gets lm and nt hashed passwords ****************************************************************************/ -void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) +void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_deobfuscate(pwd); if (lm_pwd != NULL) @@ -247,9 +186,14 @@ void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd ****************************************************************************/ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) { + pstring dos_passwd; + pwd_init(pwd); - nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pstrcpy(dos_passwd, clr); + unix_to_dos(dos_passwd, True); + + nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); pwd->null_pwd = False; pwd->cleartext = False; pwd->crypted = False; @@ -260,109 +204,31 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) /**************************************************************************** makes lm and nt OWF crypts ****************************************************************************/ -void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8], - const char *user, const char *server, const char *domain) +void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) { - uchar kr[16]; - - DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n", - user, server, domain)); - pwd_deobfuscate(pwd); - SMBgenclientchals(pwd->lm_cli_chal, - pwd->nt_cli_chal, - &pwd->nt_cli_chal_len, - server, domain); - - ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr); - - /* lm # */ - SMBOWFencrypt_ntv2(kr, - srv_key, 8, - pwd->lm_cli_chal, 8, - pwd->smb_lm_owf); - memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8); - - /* nt # */ - SMBOWFencrypt_ntv2(kr, - srv_key, 8, - pwd->nt_cli_chal, pwd->nt_cli_chal_len, - pwd->smb_nt_owf); - memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len); - pwd->nt_owf_len = pwd->nt_cli_chal_len + 16; - - SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, pwd->sess_key); - -#if DEBUG_PASSWORD -#endif - #ifdef DEBUG_PASSWORD - DEBUG(100,("server cryptkey: ")); - dump_data(100, srv_key, 8); - - DEBUG(100,("client lmv2 cryptkey: ")); - dump_data(100, pwd->lm_cli_chal, 8); - - DEBUG(100,("client ntv2 cryptkey: ")); - dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len); - - DEBUG(100,("ntv2_owf_passwd: ")); - dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len); - DEBUG(100,("nt_sess_pwd: ")); - dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); - - DEBUG(100,("lmv2_owf_passwd: ")); - dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); - DEBUG(100,("lm_sess_pwd: ")); - dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); - - DEBUG(100,("session key:\n")); - dump_data(100, pwd->sess_key, sizeof(pwd->sess_key)); + DEBUG(100,("client cryptkey: ")); + dump_data(100, (char *)cryptkey, 8); #endif - pwd->crypted = True; - pwd_obfuscate(pwd); -} + SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); -/**************************************************************************** - makes lm and nt OWF crypts - ****************************************************************************/ -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) -{ - if (pwd->null_pwd) - { #ifdef DEBUG_PASSWORD - DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n")); + DEBUG(100,("nt_owf_passwd: ")); + dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); + DEBUG(100,("nt_sess_pwd: ")); + dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); #endif - pwd->nt_owf_len = 0; - return; - } - pwd_deobfuscate(pwd); - /* generate 24-byte hashes */ SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); - SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); - pwd->nt_owf_len = 24; - - SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, pwd->sess_key); #ifdef DEBUG_PASSWORD - DEBUG(100,("client cryptkey: ")); - dump_data(100, cryptkey, 8); - - DEBUG(100,("nt_owf_passwd: ")); - dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len); - DEBUG(100,("nt_sess_pwd: ")); - dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); - DEBUG(100,("lm_owf_passwd: ")); - dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); + dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); DEBUG(100,("lm_sess_pwd: ")); - dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); - - DEBUG(100,("session key:\n")); - dump_data(100, pwd->sess_key, sizeof(pwd->sess_key)); + dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); #endif pwd->crypted = True; @@ -373,22 +239,8 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) /**************************************************************************** gets lm and nt crypts ****************************************************************************/ -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], - uchar *nt_owf, size_t *nt_owf_len, - uchar *sess_key) +void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) { - if (pwd->null_pwd) - { -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n")); -#endif - if (nt_owf_len != NULL) - { - *nt_owf_len = 0; - } - return; - } - pwd_deobfuscate(pwd); if (lm_owf != NULL) { @@ -396,16 +248,7 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], } if (nt_owf != NULL) { - memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len); - } - if (sess_key != NULL) - { - memcpy(sess_key, pwd->sess_key, 16); - } - if (nt_owf_len != NULL) - { - *nt_owf_len = pwd->nt_owf_len; + memcpy(nt_owf, pwd->smb_nt_owf, 24); } pwd_obfuscate(pwd); } - diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index e60b93d6a2..d0e1c6e85f 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -259,7 +259,7 @@ static void dohash(char *out, char *in, char *key, int forw) permute(out, rl, perm6, 64); } -static void str_to_key(const uchar *str, uchar *key) +static void str_to_key(unsigned char *str,unsigned char *key) { int i; @@ -277,7 +277,7 @@ static void str_to_key(const uchar *str, uchar *key) } -void smbhash(unsigned char *out, const uchar *in, const uchar *key, int forw) +static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) { int i; char outb[64]; @@ -365,10 +365,6 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) unsigned char index_j = 0; unsigned char j = 0; int ind; - int len = 0; - if (val == 1) len = 516; - if (val == 0) len = 16; - if (val == 2) len = 68; for (ind = 0; ind < 256; ind++) { @@ -385,7 +381,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) s_box[ind] = s_box[j]; s_box[j] = tc; } - for( ind = 0; ind < len; ind++) + for( ind = 0; ind < (val ? 516 : 16); ind++) { unsigned char tc; unsigned char t; @@ -401,16 +397,3 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) data[ind] = data[ind] ^ s_box[t]; } } - -void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw) -{ - unsigned char s[14]; - - s[0] = s[4] = s[8] = s[12] = (unsigned char)(rid & 0xFF); - s[1] = s[5] = s[9] = s[13] = (unsigned char)((rid >> 8) & 0xFF); - s[2] = s[6] = s[10] = (unsigned char)((rid >> 16) & 0xFF); - s[3] = s[7] = s[11] = (unsigned char)((rid >> 24) & 0xFF); - - smbhash(out, in, s, forw); - smbhash(out+8, in+8, s+7, forw); -} diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 34e6f43975..b927e193dd 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -24,39 +24,30 @@ extern int DEBUGLEVEL; +#include "byteorder.h" + /* This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(uchar *pwrd, uchar *c8, uchar *p24) +void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) { - uchar p21[21]; + uchar p14[15], p21[21]; - lm_owf_gen(pwrd, p21); - SMBOWFencrypt(p21, c8, p24); + memset(p21,'\0',21); + memset(p14,'\0',14); + StrnCpy((char *)p14,(char *)passwd,14); -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); -#endif -} + strupper((char *)p14); + E_P16(p14, p21); -void SMBNTencrypt(uchar *pwrd, uchar *c8, uchar *p24) -{ - uchar p21[21]; - - memset(p21,'\0',21); - - nt_owf_gen(pwrd, p21); SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD - DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); - dump_data(100, p21, 16); - dump_data(100, c8, 8); - dump_data(100, p24, 24); + DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); + dump_data(100, (char *)p21, 16); + dump_data(100, (char *)c8, 8); + dump_data(100, (char *)p24, 24); #endif } @@ -76,23 +67,7 @@ static int _my_wcslen(int16 *str) * format. */ -static int _my_mbstowcsupper(int16 *dst, const uchar *src, int len) -{ - int i; - int16 val; - - for(i = 0; i < len; i++) { - val = toupper(*src); - SSVAL(dst,0,val); - dst++; - src++; - if(val == 0) - break; - } - return i; -} - -static int _my_mbstowcs(int16 *dst, const uchar *src, int len) +static int _my_mbstowcs(int16 *dst, uchar *src, int len) { int i; int16 val; @@ -112,17 +87,17 @@ static int _my_mbstowcs(int16 *dst, const uchar *src, int len) * Creates the MD4 Hash of the users password in NT UNICODE. */ -void E_md4hash(uchar *pwrd, uchar *p16) +void E_md4hash(uchar *passwd, uchar *p16) { int len; int16 wpwd[129]; /* Password cannot be longer than 128 characters */ - len = strlen((char *)pwrd); + len = strlen((char *)passwd); if(len > 128) len = 128; /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, pwrd, len); + _my_mbstowcs(wpwd, passwd, len); wpwd[len] = 0; /* Ensure string is null terminated */ /* Calculate length in bytes */ len = _my_wcslen(wpwd) * sizeof(int16); @@ -130,289 +105,98 @@ void E_md4hash(uchar *pwrd, uchar *p16) mdfour(p16, (unsigned char *)wpwd, len); } -/* Does the LM owf of a user's password */ -void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16]) +/* Does both the NT and LM owfs of a user's password */ +void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) { - char pwrd[15]; - - memset(pwrd,'\0',15); - if (pwd != NULL) - { - unistr2_to_ascii( pwrd, pwd, sizeof(pwrd)-1); - } + char passwd[130]; - /* Mangle the passwords into Lanman format */ - pwrd[14] = '\0'; - strupper(pwrd); - - /* Calculate the SMB (lanman) hash functions of the password */ + memset(passwd,'\0',130); + safe_strcpy( passwd, pwd, sizeof(passwd)-1); - memset(p16, '\0', 16); - E_P16((uchar *) pwrd, (uchar *)p16); + /* Calculate the MD4 hash (NT compatible) of the password */ + memset(nt_p16, '\0', 16); + E_md4hash((uchar *)passwd, nt_p16); #ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, pwrd, strlen(pwrd)); - dump_data(100, p16, 16); + DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); + dump_data(120, passwd, strlen(passwd)); + dump_data(100, (char *)nt_p16, 16); #endif - /* clear out local copy of user's password (just being paranoid). */ - bzero(pwrd, sizeof(pwrd)); -} - -/* Does the LM owf of a user's password */ -void lm_owf_gen(const char *pwd, uchar p16[16]) -{ - char pwrd[15]; - - memset(pwrd,'\0',15); - if (pwd != NULL) - { - safe_strcpy( pwrd, pwd, sizeof(pwrd)-1); - } /* Mangle the passwords into Lanman format */ - pwrd[14] = '\0'; - strupper(pwrd); + passwd[14] = '\0'; + strupper(passwd); /* Calculate the SMB (lanman) hash functions of the password */ memset(p16, '\0', 16); - E_P16((uchar *) pwrd, (uchar *)p16); + E_P16((uchar *) passwd, (uchar *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, pwrd, strlen(pwrd)); - dump_data(100, p16, 16); -#endif - /* clear out local copy of user's password (just being paranoid). */ - bzero(pwrd, sizeof(pwrd)); -} - -/* Does both the NT and LM owfs of a user's password */ -void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]) -{ - UNISTR2 pwrd; - - memset(&pwrd,'\0',sizeof(pwrd)); - if (pwd != NULL) - { - copy_unistr2(&pwrd, pwd); - } - - /* Calculate the MD4 hash (NT compatible) of the password */ - memset(nt_p16, '\0', 16); - mdfour(nt_p16, (unsigned char *)pwrd.buffer, pwrd.uni_str_len * 2); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_owf_gen: pwd, nt#\n")); - dump_data(120, (const char*)pwrd.buffer, pwrd.uni_str_len * 2); - dump_data(100, nt_p16, 16); -#endif - /* clear out local copy of user's password (just being paranoid). */ - memset(&pwrd, 0, sizeof(pwrd)); -} - -/* Does both the NT and LM owfs of a user's password */ -void nt_owf_gen(const char *pwd, uchar nt_p16[16]) -{ - char pwrd[130]; - - memset(pwrd,'\0',130); - if (pwd != NULL) - { - safe_strcpy( pwrd, pwd, sizeof(pwrd)-1); - } - - /* Calculate the MD4 hash (NT compatible) of the password */ - memset(nt_p16, '\0', 16); - E_md4hash((uchar *)pwrd, nt_p16); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_owf_gen: pwd, nt#\n")); - dump_data(120, pwrd, strlen(pwrd)); - dump_data(100, nt_p16, 16); + dump_data(120, passwd, strlen(passwd)); + dump_data(100, (char *)p16, 16); #endif /* clear out local copy of user's password (just being paranoid). */ - bzero(pwrd, sizeof(pwrd)); -} - -/* Does both the NT and LM owfs of a user's UNICODE password */ -void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16]) -{ - nt_owf_genW(pwd, nt_p16); - lm_owf_genW(pwd, lm_p16); -} - -/* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16]) -{ - nt_owf_gen(pwd, nt_p16); - lm_owf_gen(pwd, lm_p16); + memset(passwd, '\0', sizeof(passwd)); } /* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(uchar pwrd[16], uchar *c8, uchar p24[24]) +void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) { uchar p21[21]; memset(p21,'\0',21); - memcpy(p21, pwrd, 16); + memcpy(p21, passwd, 16); E_P24(p21, c8, p24); } -void SMBOWFencrypt_ntv2(const uchar kr[16], - const uchar *srv_chal, int srv_chal_len, - const uchar *cli_chal, int cli_chal_len, - char resp_buf[16]) -{ - HMACMD5Context ctx; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(srv_chal, srv_chal_len, &ctx); - hmac_md5_update(cli_chal, cli_chal_len, &ctx); - hmac_md5_final(resp_buf, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); - dump_data(100, srv_chal, srv_chal_len); - dump_data(100, cli_chal, cli_chal_len); - dump_data(100, resp_buf, 16); -#endif -} - -void SMBsesskeygen_ntv2(const uchar kr[16], - const uchar *nt_resp, - char sess_key[16]) -{ - HMACMD5Context ctx; - - hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(nt_resp, 16, &ctx); - hmac_md5_final(sess_key, &ctx); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("SMBsesskeygen_ntv2:\n")); - dump_data(100, sess_key, 16); -#endif -} - -void SMBsesskeygen_ntv1(const uchar kr[16], - const uchar *nt_resp, - char sess_key[16]) +/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ +void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) { - mdfour(sess_key, kr, 16); + uchar p21[21]; + + memset(p21,'\0',21); + memcpy(p21, passwd, 8); + memset(p21 + 8, 0xbd, 8); + E_P24(p21, ntlmchalresp, p24); #ifdef DEBUG_PASSWORD - DEBUG(100,("SMBsesskeygen_ntv2:\n")); - dump_data(100, sess_key, 16); + DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); + dump_data(100, (char *)p21, 21); + dump_data(100, (char *)ntlmchalresp, 8); + dump_data(100, (char *)p24, 24); #endif } -void SMBgenclientchals(char *lm_cli_chal, - char *nt_cli_chal, int *nt_cli_chal_len, - const char *srv, const char *dom) -{ - NTTIME nt_time; - int srv_len = strlen(srv); - int dom_len = strlen(dom); - fstring server; - fstring domain; - fstrcpy(server, srv); - fstrcpy(domain, dom); - strupper(server); - strupper(domain); - - generate_random_buffer(lm_cli_chal, 8, False); - unix_to_nt_time(&nt_time, time(NULL)); - - CVAL(nt_cli_chal,0) = 0x1; - CVAL(nt_cli_chal,1) = 0x1; - SSVAL(nt_cli_chal, 2, 0x0); - SIVAL(nt_cli_chal, 4, 0x0); - SIVAL(nt_cli_chal, 8, nt_time.low); - SIVAL(nt_cli_chal, 12, nt_time.high); - memcpy(nt_cli_chal+16, lm_cli_chal, 8); - /* fill in offset 24, size of structure, later */ - - *nt_cli_chal_len = 28; - - SSVAL(nt_cli_chal, *nt_cli_chal_len, 2); - *nt_cli_chal_len += 2; - SSVAL(nt_cli_chal, *nt_cli_chal_len, dom_len*2); - *nt_cli_chal_len += 2; - ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), domain, dom_len*2); - *nt_cli_chal_len += dom_len*2; - *nt_cli_chal_len += 4 - ((*nt_cli_chal_len) % 4); - - SSVAL(nt_cli_chal, *nt_cli_chal_len, 2); - *nt_cli_chal_len += 2; - SSVAL(nt_cli_chal, 30, srv_len*2); - *nt_cli_chal_len += 2; - ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), server, srv_len*2); - *nt_cli_chal_len += srv_len*2; - - SSVAL(nt_cli_chal, 24, (*nt_cli_chal_len)+16); - SSVAL(nt_cli_chal, 26, (*nt_cli_chal_len)+15); - - DEBUG(100,("SMBgenclientchals: srv %s, dom %s\n", server, domain)); - dump_data(100, nt_cli_chal, *nt_cli_chal_len); -} - -void ntv2_owf_gen(const uchar owf[16], - const char *user_n, - const char *domain_n, - uchar kr_buf[16]) -{ - pstring user_u; - pstring dom_u; - HMACMD5Context ctx; - - int user_l = strlen(user_n ); - int domain_l = strlen(domain_n); - - _my_mbstowcsupper((int16*)user_u, user_n , user_l*2 ); - _my_mbstowcsupper((int16*)dom_u , domain_n, domain_l*2); - - hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update(user_u, user_l*2, &ctx); - hmac_md5_update(dom_u, domain_l*2, &ctx); - hmac_md5_final(kr_buf, &ctx); -#ifdef DEBUG_PASSWORD - DEBUG(100,("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, user_u, user_l*2); - dump_data(100, dom_u, domain_l*2); - dump_data(100, owf, 16); - dump_data(100, kr_buf, 16); -#endif -} - -/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ -void NTLMSSPOWFencrypt(uchar pwrd[8], uchar *ntlmchalresp, uchar p24[24]) +/* Does the NT MD4 hash then des encryption. */ + +void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) { uchar p21[21]; memset(p21,'\0',21); - memcpy(p21, pwrd, 8); - memset(p21 + 8, 0xbd, 8); + + E_md4hash(passwd, p21); + SMBOWFencrypt(p21, c8, p24); - E_P24(p21, ntlmchalresp, p24); #ifdef DEBUG_PASSWORD - DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); - dump_data(100, p21, 21); - dump_data(100, ntlmchalresp, 8); - dump_data(100, p24, 24); + DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); + dump_data(100, (char *)p21, 16); + dump_data(100, (char *)c8, 8); + dump_data(100, (char *)p24, 24); #endif } -BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16], BOOL unicode) +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) { - int new_pw_len = strlen(pwrd) * (unicode ? 2 : 1); + int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); if (new_pw_len > 512) { - DEBUG(0,("make_oem_pwrd_hash: new password is too long.\n")); + DEBUG(0,("make_oem_passwd_hash: new password is too long.\n")); return False; } @@ -425,16 +209,18 @@ BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16 generate_random_buffer((unsigned char *)data, 516, False); if (unicode) { - ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len); + /* Note that passwd should be in DOS oem character set. */ + dos_struni2( &data[512 - new_pw_len], passwd, 512); } else { - fstrcpy( &data[512 - new_pw_len], pwrd); + /* Note that passwd should be in DOS oem character set. */ + fstrcpy( &data[512 - new_pw_len], passwd); } SIVAL(data, 512, new_pw_len); #ifdef DEBUG_PASSWORD - DEBUG(100,("make_oem_pwrd_hash\n")); + DEBUG(100,("make_oem_passwd_hash\n")); dump_data(100, data, 516); #endif SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); @@ -442,138 +228,3 @@ BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16 return True; } -BOOL nt_decrypt_string2(STRING2 *out, const STRING2 *in, const uchar *key) -{ - uchar bufhdr[8]; - int datalen; - - const uchar *keyptr = key; - const uchar *keyend = key + 16; - - uchar *outbuf = (uchar *)out->buffer; - const uchar *inbuf = (const uchar *)in->buffer; - const uchar *inbufend; - - smbhash(bufhdr, inbuf, keyptr, 0); - datalen = IVAL(bufhdr, 0); - - if ((datalen > in->str_str_len) || (datalen > MAX_STRINGLEN)) - { - DEBUG(0, ("nt_decrypt_string2: failed\n")); - return False; - } - - out->str_max_len = out->str_str_len = datalen; - inbuf += 8; - inbufend = inbuf + datalen; - - while (inbuf < inbufend) - { - keyptr += 7; - if (keyptr + 7 > keyend) - { - keyptr = (keyend - keyptr) + key; - } - - smbhash(outbuf, inbuf, keyptr, 0); - - inbuf += 8; - outbuf += 8; - } - - return True; -} - -/******************************************************************* - creates a DCE/RPC bind authentication response - - - initialises the parse structure. - - dynamically allocates the header data structure - - caller is expected to free the header data structure once used. - - ********************************************************************/ -void create_ntlmssp_resp(struct pwd_info *pwd, - char *domain, char *user_name, char *my_name, - uint32 ntlmssp_cli_flgs, - prs_struct *auth_resp) -{ - RPC_AUTH_NTLMSSP_RESP ntlmssp_resp; - unsigned char lm_owf[24]; - unsigned char nt_owf[128]; - size_t nt_owf_len; - - pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len, NULL); - - make_rpc_auth_ntlmssp_resp(&ntlmssp_resp, - lm_owf, nt_owf, nt_owf_len, - domain, user_name, my_name, - ntlmssp_cli_flgs); - - smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0); - mem_realloc_data(auth_resp->data, auth_resp->offset); -} - -/*********************************************************** - decode a password buffer -************************************************************/ -BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len) -{ - /* - * The length of the new password is in the last 4 bytes of - * the data buffer. - */ - - (*new_pw_len) = IVAL(buffer, 512); - -#ifdef DEBUG_PASSWORD - dump_data(100, buffer, 516); -#endif - - if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) - { - DEBUG(0,("check_oem_password: incorrect password length (%d).\n", (*new_pw_len))); - return False; - } - - memcpy(new_pwrd, &buffer[512-(*new_pw_len)], (*new_pw_len)); - new_pwrd[(*new_pw_len)] = '\0'; - - return True; -} - -/*********************************************************** - encode a password buffer -************************************************************/ -BOOL encode_pw_buffer(char buffer[516], const char *new_pass, - int new_pw_len, BOOL nt_pass_set) -{ - generate_random_buffer(buffer, 516, True); - - if (nt_pass_set) - { - /* - * nt passwords are in unicode. last char overwrites NULL - * in ascii_to_unibuf, so use SIVAL *afterwards*. - */ - new_pw_len *= 2; - ascii_to_unibuf(&buffer[512-new_pw_len], new_pass, new_pw_len); - } - else - { - memcpy(&buffer[512-new_pw_len], new_pass, new_pw_len); - } - - /* - * The length of the new password is in the last 4 bytes of - * the data buffer. - */ - - SIVAL(buffer, 512, new_pw_len); - -#ifdef DEBUG_PASSWORD - dump_data(100, buffer, 516); -#endif - - return True; -} diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 228eee5892..c2d8884d73 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -143,70 +143,39 @@ struct {0xFF,"ERRCMD",NULL}, {-1,NULL,NULL}}; -char *smb_err_msg(uint8 class, uint32 num) -{ - static pstring ret; - smb_safe_err_msg(class, num, ret, sizeof(ret)); - return ret; -} - /**************************************************************************** return a SMB error string from a SMB buffer ****************************************************************************/ -BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len) +char *smb_errstr(char *inbuf) { - int i,j; - - for (i=0;err_classes[i].class;i++) - { - if (err_classes[i].code == class) + static pstring ret; + int class = CVAL(inbuf,smb_rcls); + int num = SVAL(inbuf,smb_err); + int i,j; + + for (i=0;err_classes[i].class;i++) + if (err_classes[i].code == class) + { + if (err_classes[i].err_msgs) + { + err_code_struct *err = err_classes[i].err_msgs; + for (j=0;err[j].name;j++) + if (num == err[j].code) { - err_code_struct *err = err_classes[i].err_msgs; - if (err != NULL) - { - for (j=0;err[j].name;j++) - { - if (num == err[j].code) - { - if (DEBUGLEVEL > 0) - { - slprintf(ret, len - 1, "%s - %s (%s)",err_classes[i].class, - err[j].name,err[j].message); - } - else - { - slprintf(ret, len - 1, "%s - %s",err_classes[i].class,err[j].name); - } - return True; - } - } - } - slprintf(ret, len - 1, "%s - %d",err_classes[i].class, num); - return True; + if (DEBUGLEVEL > 0) + slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class, + err[j].name,err[j].message); + else + slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name); + return ret; } + } - } - - slprintf(ret, len - 1, "Error: Unknown error (%d,%d)",class,num); - return False; -} - -/**************************************************************************** -return a SMB error string from a SMB buffer -****************************************************************************/ -BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len) -{ - return smb_safe_err_msg(CVAL(inbuf,smb_rcls), SVAL(inbuf,smb_err), - msg, len); -} - -/**************************************************************************** -return a SMB error string from a SMB buffer -****************************************************************************/ -char *smb_errstr(char *inbuf) -{ - static fstring errmsg; - (void)smb_safe_errstr(inbuf, errmsg, sizeof(errmsg)); - return errmsg; + slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num); + return ret; + } + + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); + return(ret); } -- cgit From 32a965e09ce4befe971855e11e1fb5ceb51a9ed1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:35:20 +0000 Subject: 2nd phase of head branch sync with SAMBA_2_0 - this delets all the files that were in the head branch but weren't in SAMBA_2_0 (This used to be commit d7b208786590b5a28618590172b8d523627dda09) --- source3/libsmb/clienttrust.c | 127 ------------------------------------------- 1 file changed, 127 deletions(-) delete mode 100644 source3/libsmb/clienttrust.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clienttrust.c b/source3/libsmb/clienttrust.c deleted file mode 100644 index b223750529..0000000000 --- a/source3/libsmb/clienttrust.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * Version 1.9. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1997, - * Copyright (C) Luke Kenneth Casson Leighton 1996-1997, - * Copyright (C) Paul Ashton 1997. - * Copyright (C) Jeremy Allison 1998. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - - -#ifdef SYSLOG -#undef SYSLOG -#endif - -#include "includes.h" - -extern int DEBUGLEVEL; -extern pstring scope; -extern pstring global_myname; - -/********************************************************* - Change the domain password on the PDC. -**********************************************************/ - -static BOOL modify_trust_password( char *domain, char *remote_machine, - unsigned char orig_trust_passwd_hash[16], - unsigned char new_trust_passwd_hash[16], - uint16 sec_chan) -{ - struct nmb_name calling, called; - fstring trust_acct; - fstring srv_name; - - fstrcpy(srv_name, "\\\\"); - fstrcat(srv_name, remote_machine); - strupper(srv_name); - - fstrcpy(trust_acct, global_myname); - fstrcat(trust_acct, "$"); - - make_nmb_name(&calling, global_myname , 0x0 , scope); - make_nmb_name(&called , remote_machine, 0x20, scope); - - if (cli_nt_setup_creds(srv_name, global_myname, trust_acct, - orig_trust_passwd_hash, sec_chan) != 0x0) - { - return False; - } - - if (!cli_nt_srv_pwset( srv_name, global_myname, trust_acct, - new_trust_passwd_hash, - sec_chan ) ) - { - return False; - } - - return True; -} - -/************************************************************************ - Change the trust account password for a domain. - The user of this function must have locked the trust password file for - update. -************************************************************************/ - -BOOL change_trust_account_password(char *domain, char *remote_machine_list, - uint16 sec_chan) -{ - fstring remote_machine; - unsigned char old_trust_passwd_hash[16]; - unsigned char new_trust_passwd_hash[16]; - time_t lct; - BOOL res; - - if(!get_trust_account_password( old_trust_passwd_hash, &lct)) { - DEBUG(0,("change_trust_account_password: unable to read the machine \ -account password for domain %s.\n", domain)); - return False; - } - - /* - * Create the new (random) password. - */ - generate_random_buffer( new_trust_passwd_hash, 16, True); - - while(remote_machine_list && - next_token(&remote_machine_list, remote_machine, - LIST_SEP, sizeof(remote_machine))) { - strupper(remote_machine); - if(modify_trust_password( domain, remote_machine, - old_trust_passwd_hash, new_trust_passwd_hash, sec_chan)) { - DEBUG(0,("%s : change_trust_account_password: Changed password for \ -domain %s.\n", timestring(), domain)); - /* - * Return the result of trying to write the new password - * back into the trust account file. - */ - res = set_trust_account_password(new_trust_passwd_hash); - memset(new_trust_passwd_hash, 0, 16); - memset(old_trust_passwd_hash, 0, 16); - return res; - } - } - - memset(new_trust_passwd_hash, 0, 16); - memset(old_trust_passwd_hash, 0, 16); - - DEBUG(0,("%s : change_trust_account_password: Failed to change password for \ -domain %s.\n", timestring(), domain)); - return False; -} - -- cgit From 574788039f53fada4769731ea3fafe9710417b71 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2000 03:17:16 +0000 Subject: added the unexpected packet database (unexpected.tdb) this means "nmblookup -S" now always works, even with broken servers the database stores all unexpected replies and these can be accessed by any client. while doing this I cleaned up a couple of functions, and put in place a better trn_id generator. in most places the code got quite a bit simpler due to the addition of simple helper functions. I haven't yet put the code in to take advantage of this for pdc replies - that will be next. Jeremys pdc finding code will then work :) (This used to be commit 280e6359d36c9bc8dcded302f15c3a1db8e3feeb) --- source3/libsmb/namequery.c | 257 ++++++++++++++++++++------------------------- source3/libsmb/nmblib.c | 174 +++++++++++++++++++----------- 2 files changed, 223 insertions(+), 208 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index abb9b7d42f..0cf89149a8 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -28,6 +28,23 @@ extern int DEBUGLEVEL; /* nmbd.c sets this to True. */ BOOL global_in_nmbd = False; +/**************************************************************************** +generate a random trn_id +****************************************************************************/ +static int generate_trn_id(void) +{ + static int trn_id; + + if (trn_id == 0) { + srandom(getpid()); + } + + trn_id = random(); + + return trn_id % (unsigned)0x7FFF; +} + + /**************************************************************************** Interpret a node status response. ****************************************************************************/ @@ -85,11 +102,10 @@ static void _interpret_node_status(char *p, char *master,char *rname) /**************************************************************************** Internal function handling a netbios name status query on a host. **************************************************************************/ - static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname, BOOL verbose, - void (*fn_interpret_node_status)(char *, char *,char *), - void (*fn)(struct packet_struct *)) + struct in_addr to_ip,char *master, + char *rname, BOOL verbose, + void (*fn_interpret_node_status)(char *, char *,char *)) { BOOL found=False; int retries = 2; @@ -98,15 +114,10 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; - static int name_trn_id = 0; memset((char *)&p,'\0',sizeof(p)); - if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + - ((unsigned)getpid()%(unsigned)100); - name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; - - nmb->header.name_trn_id = name_trn_id; + nmb->header.name_trn_id = generate_trn_id(); nmb->header.opcode = 0; nmb->header.response = False; nmb->header.nm_flags.bcast = False; @@ -139,51 +150,42 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, retries--; while (1) { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!found && !send_packet(&p)) - return False; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_packet(fd,NMB_PACKET,90))) { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); - - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) { - /* its not for us - maybe deal with it later */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount || - nmb2->answers->rr_type != 0x21) { - /* XXXX what do we do with this? could be a redirect, but - we'll discard it for the moment */ - free_packet(p2); - continue; + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!found && !send_packet(&p)) + return False; + GetTimeOfDay(&tval); + retries--; } - if(fn_interpret_node_status) - (*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname); - free_packet(p2); - return(True); - } + if ((p2=receive_reply_packet(fd,90,nmb->header.name_trn_id))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount || + nmb2->answers->rr_type != 0x21) { + /* XXXX what do we do with this? could be a + redirect, but we'll discard it for the + moment */ + free_packet(p2); + continue; + } + + if(fn_interpret_node_status) + (*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname); + free_packet(p2); + return(True); + } } if(verbose) - DEBUG(0,("No status response (this is not unusual)\n")); + DEBUG(0,("No status response (this is not unusual)\n")); return(False); } @@ -192,14 +194,12 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, Do a netbios name status query on a host. The "master" parameter is a hack used for finding workgroups. **************************************************************************/ - BOOL name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master,char *rname, - void (*fn)(struct packet_struct *)) + struct in_addr to_ip,char *master,char *rname) { - return internal_name_status(fd,name,name_type,recurse, - to_ip,master,rname,True, - _interpret_node_status, fn); + return internal_name_status(fd,name,name_type,recurse, + to_ip,master,rname,True, + _interpret_node_status); } /**************************************************************************** @@ -208,8 +208,9 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse, *count will be set to the number of addresses returned. ****************************************************************************/ -struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *)) +struct in_addr *name_query(int fd,const char *name,int name_type, + BOOL bcast,BOOL recurse, + struct in_addr to_ip, int *count) { BOOL found=False; int i, retries = 3; @@ -218,17 +219,12 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; - static int name_trn_id = 0; struct in_addr *ip_list = NULL; memset((char *)&p,'\0',sizeof(p)); (*count) = 0; - if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + - ((unsigned)getpid()%(unsigned)100); - name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; - - nmb->header.name_trn_id = name_trn_id; + nmb->header.name_trn_id = generate_trn_id(); nmb->header.opcode = 0; nmb->header.response = False; nmb->header.nm_flags.bcast = bcast; @@ -262,79 +258,57 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO while (1) { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) - { - if (!retries) - break; - if (!found && !send_packet(&p)) - return NULL; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_packet(fd,NMB_PACKET,90))) - { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); - - if (nmb->header.name_trn_id != nmb2->header.name_trn_id || - !nmb2->header.response) - { - /* - * Its not for us - maybe deal with it later - * (put it on the queue?). - */ - if (fn) - fn(p2); - else - free_packet(p2); - continue; - } + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!found && !send_packet(&p)) + return NULL; + GetTimeOfDay(&tval); + retries--; + } - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount) - { - /* - * XXXX what do we do with this? Could be a redirect, but - * we'll discard it for the moment. - */ - free_packet(p2); - continue; - } - - ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) * - ((*count)+nmb2->answers->rdlength/6)); - if (ip_list) - { - DEBUG(fn?3:2,("Got a positive name query response from %s ( ", - inet_ntoa(p2->ip))); - for (i=0;ianswers->rdlength/6;i++) - { - putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUG(fn?3:2,("%s ",inet_ntoa(ip_list[(*count)]))); - (*count)++; - } - DEBUG(fn?3:2,(")\n")); - } + if ((p2=receive_reply_packet(fd,90,nmb->header.name_trn_id))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount) { + /* + * XXXX what do we do with this? Could be a + * redirect, but we'll discard it for the + * moment. */ + free_packet(p2); + continue; + } - found=True; - retries=0; - free_packet(p2); - if (fn) - break; + ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) * + ((*count)+nmb2->answers->rdlength/6)); + if (ip_list) { + DEBUG(2,("Got a positive name query response from %s ( ", + inet_ntoa(p2->ip))); + for (i=0;ianswers->rdlength/6;i++) { + putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); + DEBUG(2,("%s ",inet_ntoa(ip_list[(*count)]))); + (*count)++; + } + DEBUG(2,(")\n")); + } - /* - * If we're doing a unicast lookup we only - * expect one reply. Don't wait the full 2 - * seconds if we got one. JRA. - */ - if(!bcast && found) - break; - } + found=True; + retries=0; + free_packet(p2); + /* + * If we're doing a unicast lookup we only + * expect one reply. Don't wait the full 2 + * seconds if we got one. JRA. + */ + if(!bcast && found) + break; + } } return ip_list; @@ -483,7 +457,7 @@ static BOOL resolve_bcast(const char *name, int name_type, /* Done this way to fix compiler error on IRIX 5.x */ sendto_ip = *iface_bcast(*iface_n_ip(i)); *return_ip_list = name_query(sock, name, name_type, True, - True, sendto_ip, return_count, NULL); + True, sendto_ip, return_count); if(*return_ip_list != NULL) { close(sock); return True; @@ -532,7 +506,7 @@ static BOOL resolve_wins(const char *name, int name_type, if (sock != -1) { *return_iplist = name_query(sock, name, name_type, False, - True, wins_ip, return_count, NULL); + True, wins_ip, return_count); if(*return_iplist != NULL) { close(sock); return True; @@ -784,8 +758,8 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd *pdc_name = '\0'; ret = internal_name_status(sock,"*SMBSERVER",0x20,True, - *pdc_ip,NULL,pdc_name,False, - _lookup_pdc_name,NULL); + *pdc_ip,NULL,pdc_name,False, + _lookup_pdc_name); close(sock); @@ -815,7 +789,6 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd struct sockaddr_in sock_name; int sock_len = sizeof(sock_name); const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON"; - static int name_trn_id = 0; char buffer[1024]; char *bufp; int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); @@ -852,10 +825,6 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd bufp += 8; len = PTR_DIFF(bufp,buffer); - if (!name_trn_id) - name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100); - name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF; - memset((char *)&p,'\0',sizeof(p)); /* DIRECT GROUP or UNIQUE datagram. */ @@ -863,7 +832,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd dgram->header.flags.node_type = M_NODE; dgram->header.flags.first = True; dgram->header.flags.more = False; - dgram->header.dgm_id = name_trn_id; + dgram->header.dgm_id = generate_trn_id(); dgram->header.source_ip = sock_name.sin_addr; dgram->header.source_port = ntohs(sock_name.sin_port); dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 3b14fd2c6b..13f7e11123 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -678,55 +678,69 @@ void free_packet(struct packet_struct *packet) } /******************************************************************* - read a packet from a socket and parse it, returning a packet ready - to be used or put on the queue. This assumes a UDP socket +parse a packet buffer into a packet structure ******************************************************************/ -struct packet_struct *read_packet(int fd,enum packet_type packet_type) +struct packet_struct *parse_packet(char *buf,int length, + enum packet_type packet_type) { - extern struct in_addr lastip; - extern int lastport; - struct packet_struct *packet; - char buf[MAX_DGRAM_SIZE]; - int length; - BOOL ok=False; - - length = read_udp_socket(fd,buf,sizeof(buf)); - if (length < MIN_DGRAM_SIZE) return(NULL); - - packet = (struct packet_struct *)malloc(sizeof(*packet)); - if (!packet) return(NULL); - - packet->next = NULL; - packet->prev = NULL; - packet->ip = lastip; - packet->port = lastport; - packet->fd = fd; - packet->locked = False; - packet->timestamp = time(NULL); - packet->packet_type = packet_type; - switch (packet_type) - { - case NMB_PACKET: - ok = parse_nmb(buf,length,&packet->packet.nmb); - break; + extern struct in_addr lastip; + extern int lastport; + struct packet_struct *p; + BOOL ok=False; + + p = (struct packet_struct *)malloc(sizeof(*p)); + if (!p) return(NULL); + + p->next = NULL; + p->prev = NULL; + p->ip = lastip; + p->port = lastport; + p->locked = False; + p->timestamp = time(NULL); + p->packet_type = packet_type; + + switch (packet_type) { + case NMB_PACKET: + ok = parse_nmb(buf,length,&p->packet.nmb); + break; + + case DGRAM_PACKET: + ok = parse_dgram(buf,length,&p->packet.dgram); + break; + } - case DGRAM_PACKET: - ok = parse_dgram(buf,length,&packet->packet.dgram); - break; - } - if (!ok) { - DEBUG(10,("read_packet: discarding packet id = %d\n", - packet->packet.nmb.header.name_trn_id)); - free_packet(packet); - return(NULL); - } + if (!ok) { + free_packet(p); + return NULL; + } - num_good_receives++; + return p; +} - DEBUG(5,("Received a packet of len %d from (%s) port %d\n", - length, inet_ntoa(packet->ip), packet->port ) ); +/******************************************************************* + read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket + ******************************************************************/ +struct packet_struct *read_packet(int fd,enum packet_type packet_type) +{ + struct packet_struct *packet; + char buf[MAX_DGRAM_SIZE]; + int length; + + length = read_udp_socket(fd,buf,sizeof(buf)); + if (length < MIN_DGRAM_SIZE) return(NULL); + + packet = parse_packet(buf, length, packet_type); + if (!packet) return NULL; - return(packet); + packet->fd = fd; + + num_good_receives++; + + DEBUG(5,("Received a packet of len %d from (%s) port %d\n", + length, inet_ntoa(packet->ip), packet->port ) ); + + return(packet); } @@ -900,6 +914,26 @@ static int build_nmb(char *buf,struct packet_struct *p) } +/******************************************************************* +linearise a packet + ******************************************************************/ +int build_packet(char *buf, struct packet_struct *p) +{ + int len = 0; + + switch (p->packet_type) { + case NMB_PACKET: + len = build_nmb(buf,p); + break; + + case DGRAM_PACKET: + len = build_dgram(buf,p); + break; + } + + return len; +} + /******************************************************************* send a packet_struct ******************************************************************/ @@ -910,17 +944,7 @@ BOOL send_packet(struct packet_struct *p) memset(buf,'\0',sizeof(buf)); - switch (p->packet_type) - { - case NMB_PACKET: - len = build_nmb(buf,p); - debug_nmb_packet(p); - break; - - case DGRAM_PACKET: - len = build_dgram(buf,p); - break; - } + len = build_packet(buf, p); if (!len) return(False); @@ -933,20 +957,42 @@ BOOL send_packet(struct packet_struct *p) ***************************************************************************/ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) { - fd_set fds; - struct timeval timeout; + fd_set fds; + struct timeval timeout; - FD_ZERO(&fds); - FD_SET(fd,&fds); - timeout.tv_sec = t/1000; - timeout.tv_usec = 1000*(t%1000); + FD_ZERO(&fds); + FD_SET(fd,&fds); + timeout.tv_sec = t/1000; + timeout.tv_usec = 1000*(t%1000); - sys_select(fd+1,&fds,&timeout); + sys_select(fd+1,&fds,&timeout); - if (FD_ISSET(fd,&fds)) - return(read_packet(fd,type)); + if (FD_ISSET(fd,&fds)) + return(read_packet(fd,type)); + + return(NULL); +} + + +/**************************************************************************** + receive a UDP/137 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified trn_id + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_reply_packet(int fd, int t, int trn_id) +{ + struct packet_struct *p; + + p = receive_packet(fd, NMB_PACKET, t); + + if (p && p->packet.nmb.header.response && + p->packet.nmb.header.name_trn_id == trn_id) { + return p; + } + if (p) free_packet(p); - return(NULL); + /* try the unexpected packet queue */ + return receive_unexpected_137(trn_id); } -- cgit From 8ae3366268e38f3f61f121d77c6083484408e442 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2000 03:24:23 +0000 Subject: the bulk of the unexpected packet handling code is in here (This used to be commit 771f610f0d0223fea815771c9efe40d00e4817f4) --- source3/libsmb/unexpected.c | 160 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 source3/libsmb/unexpected.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c new file mode 100644 index 0000000000..57fad7c696 --- /dev/null +++ b/source3/libsmb/unexpected.c @@ -0,0 +1,160 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + handle unexpected packets + Copyright (C) Andrew Tridgell 2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; + +static TDB_CONTEXT *tdb; + +/* the key type used in the unexpeceted packet database */ +struct unexpected_key { + enum packet_type packet_type; + time_t timestamp; + int count; +}; + + + +/**************************************************************************** + all unexpected packets are passed in here, to be stored in a unexpected + packet database. This allows nmblookup and other tools to receive packets + erroneoously sent to the wrong port by broken MS systems + **************************************************************************/ +void unexpected_packet(struct packet_struct *p) +{ + static int count; + TDB_DATA kbuf, dbuf; + struct unexpected_key key; + char buf[1024]; + int len=0; + + if (!tdb) { + tdb = tdb_open(lock_path("unexpected.tdb"), 0, + TDB_CLEAR_IF_FIRST, + O_RDWR | O_CREAT, 0644); + if (!tdb) { + DEBUG(0,("Failed to open unexpected.tdb\n")); + return; + } + } + + memset(buf,'\0',sizeof(buf)); + + len = build_packet(buf, p); + + key.packet_type = p->packet_type; + key.timestamp = p->timestamp; + key.count = count++; + + kbuf.dptr = (char *)&key; + kbuf.dsize = sizeof(key); + dbuf.dptr = buf; + dbuf.dsize = len; + + tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); +} + + +static time_t lastt; + +/**************************************************************************** +delete the record if it is too old + **************************************************************************/ +static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf) +{ + struct unexpected_key key; + + memcpy(&key, kbuf.dptr, sizeof(key)); + + if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) { + tdb_delete(ttdb, kbuf); + } + + return 0; +} + + +/**************************************************************************** +delete all old unexpected packets + **************************************************************************/ +void clear_unexpected(time_t t) +{ + if (!tdb) return; + + if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT)) + return; + + lastt = t; + + tdb_traverse(tdb, traverse_fn); +} + + +static struct packet_struct *matched_packet; +static int match_trn_id; + +/**************************************************************************** +tdb traversal fn to find a matching 137 packet + **************************************************************************/ +static int traverse_match_137(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf) +{ + struct unexpected_key key; + struct packet_struct *p; + + memcpy(&key, kbuf.dptr, sizeof(key)); + + if (key.packet_type != NMB_PACKET) return 0; + + p = parse_packet(dbuf.dptr, dbuf.dsize, NMB_PACKET); + + if (p->packet_type == NMB_PACKET && + p->packet.nmb.header.name_trn_id == match_trn_id) { + matched_packet = p; + return -1; + } + + free_packet(p); + + return 0; +} + + +/**************************************************************************** +check for a particular packet in the unexpected packet queue + **************************************************************************/ +struct packet_struct *receive_unexpected_137(int trn_id) +{ + TDB_CONTEXT *tdb2; + + tdb2 = tdb_open(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0); + if (!tdb2) return NULL; + + matched_packet = NULL; + match_trn_id = trn_id; + + tdb_traverse(tdb2, traverse_match_137); + + tdb_close(tdb2); + + return matched_packet; +} -- cgit From 632b4f806eae15e319b8f62caef5d25634cf720c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2000 06:30:50 +0000 Subject: added suppport for unexpected udp/138 packets I also fixed up the lookup_pdc_name() code so that it now works, even with a NT server that insists on replying to udp/138. The method I used to match packets was to use the mailslot string as a datagram ID. The true dgm_id doesn't work as NT doesn't set it correctly. uggh. PS: Jeremy, I had to change your code quite a bit, are you sure this worked with a Samba PDC?? The code looked broken, it got the offsets wrong in the SMB portion of the packet and filled in the IP incorrectly. (This used to be commit 32f66f4ea63038cb4b3785bdf1762abdde076f5d) --- source3/libsmb/namequery.c | 402 ++++++++++++++++++-------------------------- source3/libsmb/nmblib.c | 45 ++++- source3/libsmb/unexpected.c | 25 ++- 3 files changed, 225 insertions(+), 247 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0cf89149a8..3898a721c6 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -161,7 +161,7 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, retries--; } - if ((p2=receive_reply_packet(fd,90,nmb->header.name_trn_id))) { + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); @@ -269,7 +269,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, retries--; } - if ((p2=receive_reply_packet(fd,90,nmb->header.name_trn_id))) { + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); @@ -712,259 +712,189 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip) return False; } -/******************************************************** - Internal function to extract the MACHINE<0x20> name. -*********************************************************/ - -static void _lookup_pdc_name(char *p, char *master,char *rname) -{ - int numnames = CVAL(p,0); - - *rname = '\0'; - - p += 1; - while (numnames--) { - int type = CVAL(p,15); - if(type == 0x20) { - StrnCpy(rname,p,15); - trim_string(rname,NULL," "); - return; - } - p += 18; - } -} /******************************************************** Lookup a PDC name given a Domain name and IP address. *********************************************************/ - BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name) { -#if !defined(I_HATE_WINDOWS_REPLY_CODE) - - fstring pdc_name; - BOOL ret; - - /* - * Due to the fact win WinNT *sucks* we must do a node status - * query here... JRA. - */ - - int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); - - if(sock == -1) - return False; - - *pdc_name = '\0'; - - ret = internal_name_status(sock,"*SMBSERVER",0x20,True, - *pdc_ip,NULL,pdc_name,False, - _lookup_pdc_name); - - close(sock); - - if(ret && *pdc_name) { - fstrcpy(ret_name, pdc_name); - return True; - } - - return False; - -#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */ - /* - * Sigh. I *love* this code, it took me ages to get right and it's - * completely *USELESS* because NT 4.x refuses to send the mailslot - * reply back to the correct port (it always uses 138). - * I hate NT when it does these things... JRA. - */ - - int retries = 3; - int retry_time = 2000; - struct timeval tval; - struct packet_struct p; - struct dgram_packet *dgram = &p.packet.dgram; - char *ptr,*p2; - char tmp[4]; - int len; - struct sockaddr_in sock_name; - int sock_len = sizeof(sock_name); - const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON"; - char buffer[1024]; - char *bufp; - int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); - - if(sock == -1) - return False; - - /* Find out the transient UDP port we have been allocated. */ - if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) { - DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n", - strerror(errno))); - close(sock); - return False; - } - - /* - * Create the request data. - */ - - memset(buffer,'\0',sizeof(buffer)); - bufp = buffer; - SSVAL(bufp,0,QUERYFORPDC); - bufp += 2; - fstrcpy(bufp,srcname); - bufp += (strlen(bufp) + 1); - fstrcpy(bufp,"\\MAILSLOT\\NET\\GETDC411"); - bufp += (strlen(bufp) + 1); - bufp = align2(bufp, buffer); - dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1); - bufp = skip_unicode_string(bufp, 1); - SIVAL(bufp,0,1); - SSVAL(bufp,4,0xFFFF); - SSVAL(bufp,6,0xFFFF); - bufp += 8; - len = PTR_DIFF(bufp,buffer); - - memset((char *)&p,'\0',sizeof(p)); - - /* DIRECT GROUP or UNIQUE datagram. */ - dgram->header.msg_type = 0x10; - dgram->header.flags.node_type = M_NODE; - dgram->header.flags.first = True; - dgram->header.flags.more = False; - dgram->header.dgm_id = generate_trn_id(); - dgram->header.source_ip = sock_name.sin_addr; - dgram->header.source_port = ntohs(sock_name.sin_port); - dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ - dgram->header.packet_offset = 0; - - make_nmb_name(&dgram->source_name,srcname,0,scope); - make_nmb_name(&dgram->dest_name,domain,0x1B,scope); - - ptr = &dgram->data[0]; - - /* Setup the smb part. */ - ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ - memcpy(tmp,ptr,4); - set_message(ptr,17,17 + len,True); - memcpy(ptr,tmp,4); - - CVAL(ptr,smb_com) = SMBtrans; - SSVAL(ptr,smb_vwv1,len); - SSVAL(ptr,smb_vwv11,len); - SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); - SSVAL(ptr,smb_vwv13,3); - SSVAL(ptr,smb_vwv14,1); - SSVAL(ptr,smb_vwv15,1); - SSVAL(ptr,smb_vwv16,2); - p2 = smb_buf(ptr); - pstrcpy(p2,mailslot); - p2 = skip_string(p2,1); - - memcpy(p2,buffer,len); - p2 += len; - - dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ - - p.ip = *pdc_ip; - p.port = DGRAM_PORT; - p.fd = sock; - p.timestamp = time(NULL); - p.packet_type = DGRAM_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) { - DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); - close(sock); - return False; - } - - retries--; - - while (1) { - struct timeval tval2; - struct packet_struct *p_ret; - - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!send_packet(&p)) { - DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); - close(sock); - return False; - } - GetTimeOfDay(&tval); - retries--; - } - - if ((p_ret = receive_packet(sock,NMB_PACKET,90))) { - struct nmb_packet *nmb2 = &p_ret->packet.nmb; - struct dgram_packet *dgram2 = &p_ret->packet.dgram; - char *buf; - char *buf2; - - debug_nmb_packet(p_ret); - - if (memcmp(&p.ip, &p_ret->ip, sizeof(p.ip))) { - /* - * Not for us. - */ - DEBUG(0,("lookup_pdc_name: datagram return IP %s doesn't match\n", inet_ntoa(p_ret->ip) )); - free_packet(p_ret); - continue; - } + int retries = 3; + int retry_time = 2000; + struct timeval tval; + struct packet_struct p; + struct dgram_packet *dgram = &p.packet.dgram; + char *ptr,*p2; + char tmp[4]; + int len; + struct sockaddr_in sock_name; + int sock_len = sizeof(sock_name); + const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON"; + char *mailslot_name; + char buffer[1024]; + char *bufp; + int dgm_id = generate_trn_id(); + int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); + + if(sock == -1) + return False; + + /* Find out the transient UDP port we have been allocated. */ + if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) { + DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n", + strerror(errno))); + close(sock); + return False; + } - buf = &dgram2->data[0]; - buf -= 4; + /* + * Create the request data. + */ - if (CVAL(buf,smb_com) != SMBtrans) { - DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)CVAL(buf,smb_com), - (unsigned int)SMBtrans )); - free_packet(p_ret); - continue; - } + memset(buffer,'\0',sizeof(buffer)); + bufp = buffer; + SSVAL(bufp,0,QUERYFORPDC); + bufp += 2; + fstrcpy(bufp,srcname); + bufp += (strlen(bufp) + 1); + slprintf(bufp, sizeof(fstring), "\\MAILSLOT\\NET\\GETDC%d", dgm_id); + mailslot_name = bufp; + bufp += (strlen(bufp) + 1); + bufp = align2(bufp, buffer); + dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1); + bufp = skip_unicode_string(bufp, 1); + SIVAL(bufp,0,1); + SSVAL(bufp,4,0xFFFF); + SSVAL(bufp,6,0xFFFF); + bufp += 8; + len = PTR_DIFF(bufp,buffer); + + memset((char *)&p,'\0',sizeof(p)); + + /* DIRECT GROUP or UNIQUE datagram. */ + dgram->header.msg_type = 0x10; + dgram->header.flags.node_type = M_NODE; + dgram->header.flags.first = True; + dgram->header.flags.more = False; + dgram->header.dgm_id = dgm_id; + dgram->header.source_ip = *iface_ip(*pdc_ip); + dgram->header.source_port = ntohs(sock_name.sin_port); + dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ + dgram->header.packet_offset = 0; + + make_nmb_name(&dgram->source_name,srcname,0,scope); + make_nmb_name(&dgram->dest_name,domain,0x1B,scope); + + ptr = &dgram->data[0]; + + /* Setup the smb part. */ + ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ + memcpy(tmp,ptr,4); + set_message(ptr,17,17 + len,True); + memcpy(ptr,tmp,4); + + CVAL(ptr,smb_com) = SMBtrans; + SSVAL(ptr,smb_vwv1,len); + SSVAL(ptr,smb_vwv11,len); + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); + SSVAL(ptr,smb_vwv13,3); + SSVAL(ptr,smb_vwv14,1); + SSVAL(ptr,smb_vwv15,1); + SSVAL(ptr,smb_vwv16,2); + p2 = smb_buf(ptr); + pstrcpy(p2,mailslot); + p2 = skip_string(p2,1); + + memcpy(p2,buffer,len); + p2 += len; + + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ + + p.ip = *pdc_ip; + p.port = DGRAM_PORT; + p.fd = sock; + p.timestamp = time(NULL); + p.packet_type = DGRAM_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) { + DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); + close(sock); + return False; + } + + retries--; + + while (1) { + struct timeval tval2; + struct packet_struct *p_ret; + + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!send_packet(&p)) { + DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); + close(sock); + return False; + } + GetTimeOfDay(&tval); + retries--; + } - len = SVAL(buf,smb_vwv11); - buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); + if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) { + struct dgram_packet *dgram2 = &p_ret->packet.dgram; + char *buf; + char *buf2; - if (len <= 0) { - DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len )); - free_packet(p_ret); - continue; - } + buf = &dgram2->data[0]; + buf -= 4; - DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n", - nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name), - inet_ntoa(p_ret->ip), smb_buf(buf),CVAL(buf2,0),len)); + if (CVAL(buf,smb_com) != SMBtrans) { + DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int) + CVAL(buf,smb_com), (unsigned int)SMBtrans )); + free_packet(p_ret); + continue; + } + + len = SVAL(buf,smb_vwv11); + buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); + + if (len <= 0) { + DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len )); + free_packet(p_ret); + continue; + } - if(SVAL(buf,0) != QUERYFORPDC_R) { - DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", - (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R )); - free_packet(p_ret); - continue; - } + DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n", + nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name), + inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len)); - buf += 2; - /* Note this is safe as it is a bounded strcpy. */ - fstrcpy(ret_name, buf); - ret_name[sizeof(fstring)-1] = '\0'; - close(sock); - free_packet(p_ret); - return True; - } - } + if(SVAL(buf2,0) != QUERYFORPDC_R) { + DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", + (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R )); + free_packet(p_ret); + continue; + } - close(sock); - return False; -#endif /* I_HATE_WINDOWS_REPLY_CODE */ + buf2 += 2; + /* Note this is safe as it is a bounded strcpy. */ + fstrcpy(ret_name, buf2); + ret_name[sizeof(fstring)-1] = '\0'; + close(sock); + free_packet(p_ret); + return True; + } + } + + close(sock); + return False; } + /******************************************************** Get the IP address list of the PDC/BDC's of a Domain. *********************************************************/ - BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count) { return internal_resolve_name(group, 0x1C, ip_list, count); diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 13f7e11123..9ddfd3a6c6 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -979,7 +979,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) queue. The packet must be a reply packet and have the specified trn_id The timeout is in milliseconds ***************************************************************************/ -struct packet_struct *receive_reply_packet(int fd, int t, int trn_id) +struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) { struct packet_struct *p; @@ -992,7 +992,48 @@ struct packet_struct *receive_reply_packet(int fd, int t, int trn_id) if (p) free_packet(p); /* try the unexpected packet queue */ - return receive_unexpected_137(trn_id); + return receive_unexpected(NMB_PACKET, trn_id, NULL); +} + +/**************************************************************************** + receive a UDP/138 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified dgm_id + The timeout is in milliseconds + ***************************************************************************/ +struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) +{ + struct packet_struct *p; + + p = receive_packet(fd, DGRAM_PACKET, t); + + if (p && match_mailslot_name(p, mailslot_name)) { + return p; + } + if (p) free_packet(p); + + /* try the unexpected packet queue */ + return receive_unexpected(DGRAM_PACKET, 0, mailslot_name); +} + + +/**************************************************************************** + see if a datagram has the right mailslot name +***************************************************************************/ +BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name) +{ + struct dgram_packet *dgram = &p->packet.dgram; + char *buf; + + buf = &dgram->data[0]; + buf -= 4; + + buf = smb_buf(buf); + + if (memcmp(buf, mailslot_name, strlen(mailslot_name)+1) == 0) { + return True; + } + + return False; } diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 57fad7c696..5106ef60f7 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -111,24 +111,28 @@ void clear_unexpected(time_t t) static struct packet_struct *matched_packet; -static int match_trn_id; +static int match_id; +static enum packet_type match_type; +static char *match_name; /**************************************************************************** tdb traversal fn to find a matching 137 packet **************************************************************************/ -static int traverse_match_137(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf) +static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf) { struct unexpected_key key; struct packet_struct *p; memcpy(&key, kbuf.dptr, sizeof(key)); - if (key.packet_type != NMB_PACKET) return 0; + if (key.packet_type != match_type) return 0; - p = parse_packet(dbuf.dptr, dbuf.dsize, NMB_PACKET); + p = parse_packet(dbuf.dptr, dbuf.dsize, match_type); - if (p->packet_type == NMB_PACKET && - p->packet.nmb.header.name_trn_id == match_trn_id) { + if ((match_type == NMB_PACKET && + p->packet.nmb.header.name_trn_id == match_id) || + (match_type == DGRAM_PACKET && + match_mailslot_name(p, match_name))) { matched_packet = p; return -1; } @@ -142,7 +146,8 @@ static int traverse_match_137(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf) /**************************************************************************** check for a particular packet in the unexpected packet queue **************************************************************************/ -struct packet_struct *receive_unexpected_137(int trn_id) +struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, + char *mailslot_name) { TDB_CONTEXT *tdb2; @@ -150,9 +155,11 @@ struct packet_struct *receive_unexpected_137(int trn_id) if (!tdb2) return NULL; matched_packet = NULL; - match_trn_id = trn_id; + match_id = id; + match_type = packet_type; + match_name = mailslot_name; - tdb_traverse(tdb2, traverse_match_137); + tdb_traverse(tdb2, traverse_match); tdb_close(tdb2); -- cgit From fbd17c8dafeefac788f4bc1c41045726825f513f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 3 Jan 2000 19:19:48 +0000 Subject: simple mods to add msrpc pipe redirection. default behaviour: fall back to using internal msrpc code in smbd. (This used to be commit 8976e26d46cb991710bc77463f7f928ac00dd4d8) --- source3/libsmb/pwd_cache.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 94b60d3ff0..4f02c42efb 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -61,6 +61,60 @@ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) { } +/**************************************************************************** +compares two passwords. hmm, not as trivial as expected. hmm. +****************************************************************************/ +BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) +{ + pwd_deobfuscate(pwd1); + pwd_deobfuscate(pwd2); + if (pwd1->cleartext && pwd2->cleartext) + { + if (strequal(pwd1->password, pwd2->password)) + { + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return True; + } + } + if (pwd1->null_pwd && pwd2->null_pwd) + { + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return True; + } + + if (!pwd1->null_pwd && !pwd2->null_pwd && + !pwd1->cleartext && !pwd2->cleartext) + { +#ifdef DEBUG_PASSWORD + DEBUG(100,("pwd compare: nt#\n")); + dump_data(100, pwd1->smb_nt_pwd, 16); + dump_data(100, pwd2->smb_nt_pwd, 16); +#endif + if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) + { + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return True; + } +#ifdef DEBUG_PASSWORD + DEBUG(100,("pwd compare: lm#\n")); + dump_data(100, pwd1->smb_lm_pwd, 16); + dump_data(100, pwd2->smb_lm_pwd, 16); +#endif + if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) + { + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return True; + } + } + pwd_obfuscate(pwd1); + pwd_obfuscate(pwd2); + return False; +} + /**************************************************************************** reads a password ****************************************************************************/ -- cgit From 437c68b5fe4905f7420c9d1d1173f025b6a9c154 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Jan 2000 01:48:30 +0000 Subject: use a minimal hash size in the unexpected packet database. A large hash is only useful when we fetch by key, not when we use tdb_traverse() (This used to be commit e154f041e8ec8b1097d4a0c727c68d217effba34) --- source3/libsmb/unexpected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 5106ef60f7..b210fb2504 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -49,7 +49,7 @@ void unexpected_packet(struct packet_struct *p) int len=0; if (!tdb) { - tdb = tdb_open(lock_path("unexpected.tdb"), 0, + tdb = tdb_open(lock_path("unexpected.tdb"), 1, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644); if (!tdb) { -- cgit From eb87c3fbdc83839ff7a0e4d3911d46b1d994d545 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Jan 2000 00:06:46 +0000 Subject: Fix for renaming directories on OS/2 server. Fix from John Janosik . Jeremy. (This used to be commit b3c0dd72339b2004684b1650c8f7832577bc44b0) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4f620bc5f4..1e230e2ff5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1059,7 +1059,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); p = smb_buf(cli->outbuf); *p++ = 4; -- cgit From 171da4d78736730557a94b44af9f2d62081b80ba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2000 06:55:36 +0000 Subject: this looks like a big commit, but it isn't really :) This fixes our netbios scope handling. We now have a 'netbios scope' option in smb.conf and the scope option is removed from make_nmb_name() this was prompted by a bug in our PDC finding code where it didn't append the scope to the query of the '*' name. (This used to be commit b563be824b8c3141c49558eced7829b48d4ab26f) --- source3/libsmb/clientgen.c | 9 ++++----- source3/libsmb/namequery.c | 9 ++++----- source3/libsmb/nmblib.c | 5 +++-- source3/libsmb/passchange.c | 5 ++--- 4 files changed, 13 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1e230e2ff5..0436fb9df5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -27,7 +27,6 @@ extern int DEBUGLEVEL; extern pstring user_socket_options; -extern pstring scope; static void cli_process_oplock(struct cli_state *cli); @@ -3223,7 +3222,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char { struct nmb_name calling, called; - make_nmb_name(&calling, srchost, 0x0, scope); + make_nmb_name(&calling, srchost, 0x0); /* * If the called name is an IP address @@ -3231,9 +3230,9 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char */ if(is_ipaddress(desthost)) - make_nmb_name(&called, "*SMBSERVER", 0x20, scope); + make_nmb_name(&called, "*SMBSERVER", 0x20); else - make_nmb_name(&called, desthost, 0x20, scope); + make_nmb_name(&called, desthost, 0x20); if (!cli_session_request(cli, &calling, &called)) { struct nmb_name smbservername; @@ -3245,7 +3244,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char cli_shutdown(cli); - make_nmb_name(&smbservername , "*SMBSERVER", 0x20, scope); + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); if (!nmb_name_equal(&called, &smbservername) || !cli_initialise(cli) || diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 3898a721c6..08f26f10d5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -22,7 +22,6 @@ #include "includes.h" -extern pstring scope; extern int DEBUGLEVEL; /* nmbd.c sets this to True. */ @@ -131,7 +130,7 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, nmb->header.nscount = 0; nmb->header.arcount = 0; - make_nmb_name(&nmb->question.question_name,name,name_type,scope); + make_nmb_name(&nmb->question.question_name,name,name_type); nmb->question.question_type = 0x21; nmb->question.question_class = 0x1; @@ -238,7 +237,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, nmb->header.nscount = 0; nmb->header.arcount = 0; - make_nmb_name(&nmb->question.question_name,name,name_type,scope); + make_nmb_name(&nmb->question.question_name,name,name_type); nmb->question.question_type = 0x20; nmb->question.question_class = 0x1; @@ -781,8 +780,8 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ dgram->header.packet_offset = 0; - make_nmb_name(&dgram->source_name,srcname,0,scope); - make_nmb_name(&dgram->dest_name,domain,0x1B,scope); + make_nmb_name(&dgram->source_name,srcname,0); + make_nmb_name(&dgram->dest_name,domain,0x1B); ptr = &dgram->data[0]; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9ddfd3a6c6..e2ba79b006 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -819,13 +819,14 @@ static int build_dgram(char *buf,struct packet_struct *p) /******************************************************************* build a nmb name *******************************************************************/ -void make_nmb_name( struct nmb_name *n, const char *name, int type, const char *this_scope ) +void make_nmb_name( struct nmb_name *n, const char *name, int type) { + extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); StrnCpy( n->name, name, 15 ); strupper( n->name ); n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, this_scope, 63 ); + StrnCpy( n->scope, global_scope, 63 ); strupper( n->scope ); } diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index b0b1188f32..335d9a7d1a 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -23,7 +23,6 @@ extern pstring global_myname; -extern pstring scope; /************************************************************* change a password on a remote machine using IPC calls @@ -52,8 +51,8 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - make_nmb_name(&calling, global_myname , 0x0 , scope); - make_nmb_name(&called , remote_machine, 0x20, scope); + make_nmb_name(&calling, global_myname , 0x0); + make_nmb_name(&called , remote_machine, 0x20); if (!cli_session_request(&cli, &calling, &called)) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", -- cgit From 6e8548acb381499142e8d3b0a2eac2061e160b02 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2000 12:40:34 +0000 Subject: fixed a comment (This used to be commit 32f29c490e6265c8a383ce771943f937c49bfabc) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index e2ba79b006..b83081d7f0 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -998,7 +998,7 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) /**************************************************************************** receive a UDP/138 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified dgm_id + queue. The packet must be a reply packet and have the specified mailslot name The timeout is in milliseconds ***************************************************************************/ struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) -- cgit From e8b5cb45155536107a71e1106ad4a624eb559496 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Jan 2000 10:15:53 +0000 Subject: cli_open() wasn't handling DENY_FCB or O_WRONLY correctly. After fixing that I needed to use O_RDWR instead of O_WRONLY in several places to avoid the silly bug in MS servers that doesn't allow getattrE on a file opened with O_WRONLY (This used to be commit e21aa4cb088f348139309d29c85c48c8b777cff5) --- source3/libsmb/clientgen.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0436fb9df5..e37974b570 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1231,6 +1231,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) /**************************************************************************** open a file +WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) { @@ -1238,12 +1239,6 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) unsigned openfn=0; unsigned accessmode=0; - /* you must open for RW not just write - otherwise getattrE doesn't - work! */ - if ((flags & O_ACCMODE) == O_WRONLY && strncmp(cli->dev, "LPT", 3)) { - flags = (flags & ~O_ACCMODE) | O_RDWR; - } - if (flags & O_CREAT) openfn |= (1<<4); if (!(flags & O_EXCL)) { @@ -1267,6 +1262,10 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) } #endif /* O_SYNC */ + if (share_mode == DENY_FCB) { + accessmode = 0xFF; + } + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); -- cgit From 735ee07018f4514771d26e01b41b0f02295b8b48 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jan 2000 13:40:27 +0000 Subject: don't treat a packet as a oplock break unless it is a request, not a reply! (This used to be commit 45b8f1c92cf7ecae35240e72741e5ac952587c58) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e37974b570..3b6403fe73 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -52,7 +52,8 @@ static BOOL cli_receive_smb(struct cli_state *cli) if (ret) { /* it might be an oplock break request */ - if (CVAL(cli->inbuf,smb_com) == SMBlockingX && + if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && + CVAL(cli->inbuf,smb_com) == SMBlockingX && SVAL(cli->inbuf,smb_vwv6) == 0 && SVAL(cli->inbuf,smb_vwv7) == 0) { if (cli->use_oplocks) cli_process_oplock(cli); -- cgit From 0af00edf672eda7556f12745c80873376b85676f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jan 2000 14:41:20 +0000 Subject: I'm currently designing a new locking system (using a tdb database!) that will make us match NT semantics exactly and do away with the horrible fd multiplexing in smbd. this is some diag stuff to get me started. - added the ability to do read or write locks in clientgen.c - added a LOCK4 test to smbtorture. This produces a report on the server and its locking capabilities. For example, NT4 gives this: the same process cannot set overlapping write locks the same process can set overlapping read locks a different connection cannot set overlapping write locks a different connection can set overlapping read locks a different pid cannot set overlapping write locks a different pid can set overlapping read locks the same process can set the same read lock twice the same process cannot set the same write lock twice the same process cannot override a read lock with a write lock the same process can override a write lock with a read lock a different pid cannot override a write lock with a read lock the same process cannot coalesce read locks this server does strict write locking this server does strict read locking whereas Samba currently gives this: the same process can set overlapping write locks the same process can set overlapping read locks a different connection cannot set overlapping write locks a different connection can set overlapping read locks a different pid can set overlapping write locks a different pid can set overlapping read locks the same process can set the same read lock twice the same process can set the same write lock twice the same process can override a read lock with a write lock the same process can override a write lock with a read lock a different pid can override a write lock with a read lock the same process can coalesce read locks this server does strict write locking this server does strict read locking win95 gives this - I don't understand why! the same process cannot set overlapping write locks the same process cannot set overlapping read locks a different connection cannot set overlapping write locks a different connection cannot set overlapping read locks a different pid cannot set overlapping write locks a different pid cannot set overlapping read locks the same process cannot set the same read lock twice the same process cannot set the same write lock twice the same process cannot override a read lock with a write lock the same process cannot override a write lock with a read lock a different pid cannot override a write lock with a read lock the same process cannot coalesce read locks this server does strict write locking this server does strict read locking (This used to be commit 49637936b6e9478df248c4ef73d818870c73b597) --- source3/libsmb/clientgen.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3b6403fe73..bf610a7ff7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1344,7 +1344,8 @@ BOOL cli_close(struct cli_state *cli, int fnum) /**************************************************************************** lock a file ****************************************************************************/ -BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, int locktype) { char *p; int saved_timeout = cli->timeout; @@ -1360,7 +1361,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; + CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,0); SSVAL(cli->outbuf,smb_vwv7,1); @@ -1390,7 +1391,8 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti /**************************************************************************** unlock a file ****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +BOOL cli_unlock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, int locktype) { char *p; @@ -1405,7 +1407,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; + CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); -- cgit From 6bad53f758437938ee9b1cbdd34d1b74a1c522dd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Jan 2000 12:08:53 +0000 Subject: the lock routines now take a enumerated type for read/write locks, and we now don't pass the lock type at all for unlocks. I was surprised to discover that NT totally ignores the lock type in unlocks. It unlocks a matching write lock if there is one, otherwise it removes the first matching read lock. (This used to be commit 1bbc1ce18b8ccb92b5a78ee648539a591a452118) --- source3/libsmb/clientgen.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bf610a7ff7..06a5e5427f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1345,7 +1345,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) lock a file ****************************************************************************/ BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, int locktype) + uint32 offset, uint32 len, int timeout, enum lock_type lock_type) { char *p; int saved_timeout = cli->timeout; @@ -1361,7 +1361,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); + CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,0); SSVAL(cli->outbuf,smb_vwv7,1); @@ -1392,7 +1392,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, unlock a file ****************************************************************************/ BOOL cli_unlock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, int locktype) + uint32 offset, uint32 len, int timeout) { char *p; @@ -1407,7 +1407,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); + CVAL(cli->outbuf,smb_vwv3) = 0; SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); -- cgit From 82af221e4a7e456f580f16bc5d2fd904fc018c96 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Jan 2000 04:32:57 +0000 Subject: we now pass all byte range locking tests the last piece was to use a smb timeout slightly larger than the locking timeout in bloking locks to prevent a race (This used to be commit 1b54cb4a33a65e62c2e3189b78ef073869a60c75) --- source3/libsmb/clientgen.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 06a5e5427f..1c9a2123cc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1372,7 +1372,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, SIVAL(p, 6, len); cli_send_smb(cli); - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout; + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); if (!cli_receive_smb(cli)) { cli->timeout = saved_timeout; @@ -1391,8 +1391,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, /**************************************************************************** unlock a file ****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout) +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) { char *p; @@ -1408,7 +1407,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); CVAL(cli->outbuf,smb_vwv3) = 0; - SIVALS(cli->outbuf, smb_vwv4, timeout); + SIVALS(cli->outbuf, smb_vwv4, 0); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); -- cgit From 7bc1cc7e07991641d436b2c8a35b52663d4c5c05 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 14 Jan 2000 08:01:44 +0000 Subject: damn, Solaris already has a "enum lock_type" changed it to "enum brl_type" (This used to be commit 6b9ee7662c7afa70f6b20889e6b0ae1dcd677f9f) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1c9a2123cc..3497fb0f14 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1345,7 +1345,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) lock a file ****************************************************************************/ BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum lock_type lock_type) + uint32 offset, uint32 len, int timeout, enum brl_type lock_type) { char *p; int saved_timeout = cli->timeout; -- cgit From 33157e9bfc154f9151993e66bc26b3b282aac11a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Jan 2000 11:09:32 +0000 Subject: fixed a formatting error (This used to be commit 10d9d81e8b7eba588526a5d479be74ce8f86fc55) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3497fb0f14..c510302301 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1293,7 +1293,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) p = smb_buf(cli->outbuf); pstrcpy(p,fname); - unix_to_dos(p,True); + unix_to_dos(p,True); p = skip_string(p,1); cli_send_smb(cli); -- cgit From bbe275e95b86bc7af5a641455cbb379974823f84 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 4 Feb 2000 04:59:31 +0000 Subject: 1) added void* state argument to tdb_traverse. guess what! there were two places i found where it was appropriate to _use_ that third argument, in locking.c and brlock.c! there was a static traverse_function and i removed the static variable, typecast it to a void*, passed it to tdb_traverse and re-cast it back to the traverse_function inside the tdb_traverse function. this makes the use of tdb_traverse() reentrant, which is never going to happen, i know, i just don't like to see statics lying about when there's no need for them. as i had to do in samba-tng, all uses of tdb_traverse modified to take the new void* state argument. 2) disabled rpcclient: referring people to use SAMBA_TNG rpcclient. i don't know how the other samba team members would react if i deleted rpcclient from cvs main. damn, that code's so old, it's unreal. 20 rpcclient commands, instead of about 70 in SAMBA_TNG. (This used to be commit 49d7f0afbc1c5425d53019e234d54ddf205c8e9a) --- source3/libsmb/unexpected.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index b210fb2504..6c5dd611a9 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -24,7 +24,7 @@ extern int DEBUGLEVEL; -static TDB_CONTEXT *tdb; +static TDB_CONTEXT *tdbd = NULL; /* the key type used in the unexpeceted packet database */ struct unexpected_key { @@ -48,11 +48,11 @@ void unexpected_packet(struct packet_struct *p) char buf[1024]; int len=0; - if (!tdb) { - tdb = tdb_open(lock_path("unexpected.tdb"), 1, + if (!tdbd) { + tdbd = tdb_open(lock_path("unexpected.tdb"), 1, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644); - if (!tdb) { + if (!tdbd) { DEBUG(0,("Failed to open unexpected.tdb\n")); return; } @@ -71,7 +71,7 @@ void unexpected_packet(struct packet_struct *p) dbuf.dptr = buf; dbuf.dsize = len; - tdb_store(tdb, kbuf, dbuf, TDB_REPLACE); + tdb_store(tdbd, kbuf, dbuf, TDB_REPLACE); } @@ -80,7 +80,7 @@ static time_t lastt; /**************************************************************************** delete the record if it is too old **************************************************************************/ -static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf) +static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct unexpected_key key; @@ -99,14 +99,14 @@ delete all old unexpected packets **************************************************************************/ void clear_unexpected(time_t t) { - if (!tdb) return; + if (!tdbd) return; if ((lastt != 0) && (t < lastt + NMBD_UNEXPECTED_TIMEOUT)) return; lastt = t; - tdb_traverse(tdb, traverse_fn); + tdb_traverse(tdbd, traverse_fn, NULL); } @@ -118,7 +118,7 @@ static char *match_name; /**************************************************************************** tdb traversal fn to find a matching 137 packet **************************************************************************/ -static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf) +static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct unexpected_key key; struct packet_struct *p; @@ -159,7 +159,7 @@ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, match_type = packet_type; match_name = mailslot_name; - tdb_traverse(tdb2, traverse_match); + tdb_traverse(tdb2, traverse_match, NULL); tdb_close(tdb2); -- cgit From 2768aecae653929d89d7cd402d953571fe51486e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Feb 2000 14:45:22 +0000 Subject: Defensive programming for cli_error(). Jeremy. (This used to be commit 94ed74d5b09d6f28b47b2855c4e4a1dc5c2108d3) --- source3/libsmb/clientgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c510302301..b1d8f8aa73 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2685,12 +2685,18 @@ void cli_shutdown(struct cli_state *cli) ****************************************************************************/ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) { - int flgs2 = SVAL(cli->inbuf,smb_flg2); + int flgs2; char rcls; int code; if (eclass) *eclass = 0; if (num ) *num = 0; + if (nt_rpc_error) *nt_rpc_error = 0; + + if(!cli || !cli->initialised || !cli->inbuf) + return EINVAL; + + flgs2 = SVAL(cli->inbuf,smb_flg2); if (nt_rpc_error) *nt_rpc_error = cli->nt_error; if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { -- cgit From f452de7ed622669ce203b58e5a528a0933da58ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Feb 2000 15:43:09 +0000 Subject: Correct for for core dump in smbpasswd with cli_errstr(). Jeremy.plit the test for NetBIOS name being *SMBSERVER. (This used to be commit 34b0e2acb050e384c132ddfb50ec84157fb430c6) --- source3/libsmb/clientgen.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b1d8f8aa73..0b669715b9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2693,9 +2693,12 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ if (num ) *num = 0; if (nt_rpc_error) *nt_rpc_error = 0; - if(!cli || !cli->initialised || !cli->inbuf) + if(cli->initialised) return EINVAL; + if(!cli->inbuf) + return ENOMEM; + flgs2 = SVAL(cli->inbuf,smb_flg2); if (nt_rpc_error) *nt_rpc_error = cli->nt_error; @@ -3225,7 +3228,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) ****************************************************************************/ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip) + struct in_addr *pdest_ip) { struct nmb_name calling, called; @@ -3244,21 +3247,32 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char if (!cli_session_request(cli, &calling, &called)) { struct nmb_name smbservername; + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + /* * If the name wasn't *SMBSERVER then * try with *SMBSERVER if the first name fails. */ - cli_shutdown(cli); + if (nmb_name_equal(&called, &smbservername)) { - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + /* + * The name used was *SMBSERVER, don't bother with another name. + */ + + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ +with error %s.\n", desthost, cli_errstr(cli) )); + cli_shutdown(cli); + return False; + } + + cli_shutdown(cli); - if (!nmb_name_equal(&called, &smbservername) || - !cli_initialise(cli) || + if (!cli_initialise(cli) || !cli_connect(cli, desthost, pdest_ip) || !cli_session_request(cli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER.\n", - desthost)); + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ +name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); cli_shutdown(cli); return False; } -- cgit From 9d59503d554fe66a674265c2036f01c236165963 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 14 Feb 2000 21:52:35 +0000 Subject: Ooops. Fixed stupid typo with missing ! in cli error code. Jeremy. (This used to be commit 0babc4baea62aa40e8698ab88b3a95d514c001b6) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0b669715b9..d40bfc379a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2693,7 +2693,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ if (num ) *num = 0; if (nt_rpc_error) *nt_rpc_error = 0; - if(cli->initialised) + if(!cli->initialised) return EINVAL; if(!cli->inbuf) -- cgit From 74ca35e4eef8e758f37488a1128d462c21ce004c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 15 Feb 2000 05:06:53 +0000 Subject: Not enough args to DEBUG statement. (This used to be commit 156f438bce607236b2d91c28f3dbe8559e048738) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d40bfc379a..32148a4e12 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -3261,7 +3261,7 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char */ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ -with error %s.\n", desthost, cli_errstr(cli) )); +with error %s.\n", desthost, "*SMBSERVER", cli_errstr(cli) )); cli_shutdown(cli); return False; } -- cgit From 9db96b7646aa36aa5b4ff309419235fe20bef78a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Feb 2000 02:02:33 +0000 Subject: lib/system.c: Fixed gcc warnings. nmbd/nmbd_processlogon.c: Use "True" and "False" instead of 1 and 0. Others - preparing for multiple pdu write code. Jeremy. (This used to be commit 9f879ec396230deba34fbe5e82d8a65f92137c54) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 32148a4e12..df3df0b4ba 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -3260,8 +3260,8 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char * The name used was *SMBSERVER, don't bother with another name. */ - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name %s \ -with error %s.\n", desthost, "*SMBSERVER", cli_errstr(cli) )); + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ +with error %s.\n", desthost, cli_errstr(cli) )); cli_shutdown(cli); return False; } -- cgit From 1f28a345526908214240f36942c3a58e1f7bd138 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Feb 2000 22:29:27 +0000 Subject: Multiple-dot scope handling fix from Greg Bowering gb@pobox.com Jeremy. (This used to be commit 693a582c23599bbdd45adb30401b1162e44fd274) --- source3/libsmb/nmblib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b83081d7f0..7b62ca4546 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -301,8 +301,8 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) p = &buf[offset+1]; while ((p = strchr(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset]); - offset += buf[offset]; + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); p = &buf[offset+1]; } buf[offset] = strlen(&buf[offset+1]); -- cgit From 0f1eee5c7ac4031cd2a97524b1f65a24d0d618c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Feb 2000 22:25:25 +0000 Subject: client/client.c: libsmb/clientgen.c: Fixes for Win2k smbclient browsing. Other fixes implement smbpasswd -x user to delete users. Also allows swat to do the same. Jeremy. (This used to be commit 9f6ad046761adecafba59040baa3abc9f0959e65) --- source3/libsmb/clientgen.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index df3df0b4ba..8d7dbec859 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -600,7 +600,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) { char *rparam = NULL; char *rdata = NULL; @@ -618,12 +618,16 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c pstrcpy(p,"B13BWz"); p = skip_string(p,1); SSVAL(p,0,1); - SSVAL(p,2,0xFFFF); + /* + * Win2k needs a *smaller* buffer than 0xFFFF here - + * it returns "out of server memory" with 0xFFFF !!! JRA. + */ + SSVAL(p,2,0xFFE0); p += 4; if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 0xFFFF, /* data, length, maxlen */ + NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { -- cgit From 0958f44f17d05f78ddf6c25e97c317bf1b24da16 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Mar 2000 21:42:15 +0000 Subject: Fix from christoph.pfisterer@rwg.de for large directory listing to OS/2 server. Jeremy. (This used to be commit ce1c36541255b51ae429e530c0ebf016009ab84e) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d7dbec859..29c228ecfa 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2193,7 +2193,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,8+4+2); /* resume required + close on end + continue */ + SSVAL(param,4,4+2); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); pstrcpy(param+12,mask); @@ -2203,7 +2203,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ - SSVAL(param,10,8+4+2); /* resume required + close on end + continue */ + SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ pstrcpy(param+12,mask); DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", -- cgit From 4acd40ee0015dd417a7a008f7fd2a183f8e30225 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 27 Mar 2000 01:33:43 +0000 Subject: moved nmblib-specific code from util.c to nmblib.c. (This used to be commit 1b9077a1d5295bc8522b83ebed2d41d5dbd28a27) --- source3/libsmb/nmblib.c | 212 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 203 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7b62ca4546..dae7cf087a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -80,7 +80,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) for (j = 0; j < 16; j++) { - unsigned char x = res->rdata[i+j]; + uchar x = res->rdata[i+j]; if (x < 32 || x > 127) x = '.'; if (i+j >= res->rdlength) break; @@ -92,7 +92,7 @@ static void debug_nmb_res_rec(struct res_rec *res, char *hdr) for (j = 0; j < 16; j++) { if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); + DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j])); } DEBUGADD(4, ("\n")); @@ -153,7 +153,7 @@ void debug_nmb_packet(struct packet_struct *p) /******************************************************************* handle "compressed" name pointers ******************************************************************/ -static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, +static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { int loop_count=0; @@ -176,7 +176,7 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name) { int m,n=0; - unsigned char *ubuf = (unsigned char *)inbuf; + uchar *ubuf = (uchar *)inbuf; int ret = 0; BOOL got_pointer=False; int loop_count=0; @@ -202,7 +202,7 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na ret += m + 2; offset++; while (m > 0) { - unsigned char c1,c2; + uchar c1,c2; c1 = ubuf[offset++]-'A'; c2 = ubuf[offset++]-'A'; if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) @@ -215,7 +215,7 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na if (n==16) { /* parse out the name type, its always in the 16th byte of the name */ - name->name_type = ((unsigned char)name->name[15]) & 0xff; + name->name_type = ((uchar)name->name[15]) & 0xff; /* remove trailing spaces */ name->name[15] = 0; @@ -393,7 +393,7 @@ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) /******************************************************************* put a compressed name pointer record into a packet ******************************************************************/ -static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset) +static int put_compressed_name_ptr(uchar *buf,int offset,struct res_rec *rec,int ptr_offset) { int ret=0; buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); @@ -784,7 +784,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) static int build_dgram(char *buf,struct packet_struct *p) { struct dgram_packet *dgram = &p->packet.dgram; - unsigned char *ubuf = (unsigned char *)buf; + uchar *ubuf = (uchar *)buf; int offset=0; /* put in the header */ @@ -852,7 +852,7 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) static int build_nmb(char *buf,struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; - unsigned char *ubuf = (unsigned char *)buf; + uchar *ubuf = (uchar *)buf; int offset=0; /* put in the header */ @@ -1082,3 +1082,197 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } + + +#define TRUNCATE_NETBIOS_NAME 1 + +/******************************************************************* + convert, possibly using a stupid microsoft-ism which has destroyed + the transport independence of netbios (for CIFS vendors that usually + use the Win95-type methods, not for NT to NT communication, which uses + DCE/RPC and therefore full-length unicode strings...) a dns name into + a netbios name. + + the netbios name (NOT necessarily null-terminated) is truncated to 15 + characters. + + ******************************************************************/ +char *dns_to_netbios_name(char *dns_name) +{ + static char netbios_name[16]; + int i; + StrnCpy(netbios_name, dns_name, 15); + netbios_name[15] = 0; + +#ifdef TRUNCATE_NETBIOS_NAME + /* ok. this is because of a stupid microsoft-ism. if the called host + name contains a '.', microsoft clients expect you to truncate the + netbios name up to and including the '.' this even applies, by + mistake, to workgroup (domain) names, which is _really_ daft. + */ + for (i = 15; i >= 0; i--) + { + if (netbios_name[i] == '.') + { + netbios_name[i] = 0; + break; + } + } +#endif /* TRUNCATE_NETBIOS_NAME */ + + return netbios_name; +} + + +/**************************************************************************** +interpret the weird netbios "name". Return the name type +****************************************************************************/ +static int name_interpret(char *in,char *out) +{ + int ret; + int len = (*in++) / 2; + + *out=0; + + if (len > 30 || len<1) return(0); + + while (len--) + { + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(0); + } + *out = ((in[0]-'A')<<4) + (in[1]-'A'); + in += 2; + out++; + } + *out = 0; + ret = out[-1]; + +#ifdef NETBIOS_SCOPE + /* Handle any scope names */ + while(*in) + { + *out++ = '.'; /* Scope names are separated by periods */ + len = *(uchar *)in++; + StrnCpy(out, in, len); + out += len; + *out=0; + in += len; + } +#endif + return(ret); +} + +/**************************************************************************** +mangle a name into netbios format + + Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. +****************************************************************************/ +int name_mangle( char *In, char *Out, char name_type ) + { + int i; + int c; + int len; + char buf[20]; + char *p = Out; + extern pstring global_scope; + + /* Safely copy the input string, In, into buf[]. */ + (void)memset( buf, 0, 20 ); + if (strcmp(In,"*") == 0) + buf[0] = '*'; + else + (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + + /* Place the length of the first field into the output buffer. */ + p[0] = 32; + p++; + + /* Now convert the name to the rfc1001/1002 format. */ + for( i = 0; i < 16; i++ ) + { + c = toupper( buf[i] ); + p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; + p[(i*2)+1] = (c & 0x000F) + 'A'; + } + p += 32; + p[0] = '\0'; + + /* Add the scope string. */ + for( i = 0, len = 0; NULL != global_scope; i++, len++ ) + { + switch( global_scope[i] ) + { + case '\0': + p[0] = len; + if( len > 0 ) + p[len+1] = 0; + return( name_len(Out) ); + case '.': + p[0] = len; + p += (len + 1); + len = -1; + break; + default: + p[len+1] = global_scope[i]; + break; + } + } + + return( name_len(Out) ); + } /* name_mangle */ + + +/**************************************************************************** +find a pointer to a netbios name +****************************************************************************/ +static char *name_ptr(char *buf,int ofs) +{ + uchar c = *(uchar *)(buf+ofs); + + if ((c & 0xC0) == 0xC0) + { + uint16 l = RSVAL(buf, ofs) & 0x3FFF; + DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); + return(buf + l); + } + else + return(buf+ofs); +} + +/**************************************************************************** +extract a netbios name from a buf +****************************************************************************/ +int name_extract(char *buf,int ofs,char *name) +{ + char *p = name_ptr(buf,ofs); + int d = PTR_DIFF(p,buf+ofs); + pstrcpy(name,""); + if (d < -50 || d > 50) return(0); + return(name_interpret(p,name)); +} + +/**************************************************************************** +return the total storage length of a mangled name +****************************************************************************/ +int name_len(char *s1) +{ + /* NOTE: this argument _must_ be unsigned */ + uchar *s = (uchar *)s1; + int len; + + /* If the two high bits of the byte are set, return 2. */ + if (0xC0 == (*s & 0xC0)) + return(2); + + /* Add up the length bytes. */ + for (len = 1; (*s); s += (*s) + 1) { + len += *s + 1; + SMB_ASSERT(len < 80); + } + + return(len); +} /* name_len */ + + -- cgit From 18bc76a0c6830358a137b4198e17b1b7ce92b9bf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Mar 2000 12:38:45 +0000 Subject: changed the definition of dos_PutUniCode the previous definition could result is us overflowing a buffer. The null termination was always added yet the size returned did not include the null termination. the new function takes a BOOL null_terminate, and always returns the total number of bytes consumed by the string. (This used to be commit 426c90433396a95033eefcc4af97603abc934221) --- source3/libsmb/namequery.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 08f26f10d5..290a91f7b5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -759,8 +759,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd mailslot_name = bufp; bufp += (strlen(bufp) + 1); bufp = align2(bufp, buffer); - dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1); - bufp = skip_unicode_string(bufp, 1); + bufp += dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1, True); SIVAL(bufp,0,1); SSVAL(bufp,4,0xFFFF); SSVAL(bufp,6,0xFFFF); -- cgit From 2fa922611bf7160e2c1ce80c11b50006448bf98d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Apr 2000 13:55:53 +0000 Subject: finally got sick of the "extern int Client" code and the stupid assumption that we have one socket everywhere while doing so I discovered a few bugs! 1) the clientgen session retarget code if used from smbd or nmbd would cause a crash as it called close_sockets() which closed our main socket! fixed by removing close_sockets() completely - it is unnecessary 2) the caching in client_addr() and client_name() was bogus - it could easily get fooled and give the wrong result. fixed. 3) the retarget could could recurse, allowing an easy denial of service attack on nmbd. fixed. (This used to be commit 5937ab14d222696e40a3fc6f0e6a536f2d7305d3) --- source3/libsmb/clientgen.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 29c228ecfa..6472cf0380 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -88,10 +88,9 @@ static BOOL cli_send_smb(struct cli_state *cli) } } if (ret <= 0) { - DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n", + DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); - close_sockets(); - exit(1); + return False; } nwritten += ret; } @@ -1516,11 +1515,11 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t if (size2 > block) { DEBUG(0,("server returned more than we wanted!\n")); - exit(1); + return -1; } if (mid >= issued) { DEBUG(0,("invalid mid from server!\n")); - exit(1); + return -1; } p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); @@ -2551,7 +2550,6 @@ retry: /* SESSION RETARGET */ putip((char *)&cli->dest_ip,cli->inbuf+4); - close_sockets(); cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); if (cli->fd == -1) return False; @@ -2561,7 +2559,18 @@ retry: set_socket_options(cli->fd,user_socket_options); /* Try again */ - return cli_session_request(cli, calling, called); + { + static int depth; + BOOL ret; + if (depth > 4) { + DEBUG(0,("Retarget recursion - failing\n")); + return False; + } + depth++; + ret = cli_session_request(cli, calling, called); + depth--; + return ret; + } } /* C. Hoch 9/14/95 End */ #ifdef WITH_SSL -- cgit From f6be38cae223f1ad3f4ecc5b81d14c44d92f58ba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Apr 2000 19:44:54 +0000 Subject: include/byteorder.h: ALIGN4/ALIGN2 macros. include/includes.h: Added SMB_BIG_UINT_BITS. lib/util.c: Removed align2/align4 - use macros. libsmb/namequery.c: Use ALIGN2. locking/locking.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. Needed to move to hiding POSIX locks at a lower layer. nmbd/nmbd_processlogon.c: Use ALIGN2/ALIGN4 macros. smbd/blocking.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. smbd/reply.c: Replace do_lock, do_unlock, args with SMB_BIG_UINT, not SMB_OFF_T. Jeremy. (This used to be commit 491eea8a20bf80d426625479326211dc975857a6) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 290a91f7b5..500a2ff94f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -758,7 +758,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd slprintf(bufp, sizeof(fstring), "\\MAILSLOT\\NET\\GETDC%d", dgm_id); mailslot_name = bufp; bufp += (strlen(bufp) + 1); - bufp = align2(bufp, buffer); + bufp = ALIGN2(bufp, buffer); bufp += dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1, True); SIVAL(bufp,0,1); SSVAL(bufp,4,0xFFFF); -- cgit From 858e63cab3b6a23692678d6eb03f9e48c3c08603 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Apr 2000 14:04:06 +0000 Subject: split clientgen.c into several parts the next step is splitting out the auth code, to make adding lukes NTLMSSP support easier (This used to be commit 10c5470835b43116ed48b3137c3b9cc867a20989) --- source3/libsmb/cliconnect.c | 790 +++++++++++ source3/libsmb/clientgen.c | 3160 +---------------------------------------- source3/libsmb/clierror.c | 213 +++ source3/libsmb/clifile.c | 609 ++++++++ source3/libsmb/clilist.c | 303 ++++ source3/libsmb/climessage.c | 122 ++ source3/libsmb/cliprint.c | 158 +++ source3/libsmb/clirap.c | 591 ++++++++ source3/libsmb/clireadwrite.c | 273 ++++ source3/libsmb/clitrans.c | 233 +++ 10 files changed, 3343 insertions(+), 3109 deletions(-) create mode 100644 source3/libsmb/cliconnect.c create mode 100644 source3/libsmb/clierror.c create mode 100644 source3/libsmb/clifile.c create mode 100644 source3/libsmb/clilist.c create mode 100644 source3/libsmb/climessage.c create mode 100644 source3/libsmb/cliprint.c create mode 100644 source3/libsmb/clirap.c create mode 100644 source3/libsmb/clireadwrite.c create mode 100644 source3/libsmb/clitrans.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c new file mode 100644 index 0000000000..b546e1e4ec --- /dev/null +++ b/source3/libsmb/cliconnect.c @@ -0,0 +1,790 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client connect/disconnect routines + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + + +static struct { + int prot; + char *name; + } +prots[] = + { + {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1,"LANMAN1.0"}, + {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {PROTOCOL_NT1,"NT LM 0.12"}, + {-1,NULL} + }; + + +/**************************************************************************** + Send a session setup. The username is in UNIX character format and must be + converted to DOS codepage format before sending. If the password is in + plaintext, the same should be done. +****************************************************************************/ + +BOOL cli_session_setup(struct cli_state *cli, + char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup) +{ + char *p; + fstring pword, ntpword; + + if (cli->protocol < PROTOCOL_LANMAN1) + return True; + + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + return False; + } + + if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { + /* Null session connect. */ + pword[0] = '\0'; + ntpword[0] = '\0'; + } else { + if ((cli->sec_mode & 2) && passlen != 24) { + /* + * Encrypted mode needed, and non encrypted password supplied. + */ + passlen = 24; + ntpasslen = 24; + fstrcpy(pword, pass); + unix_to_dos(pword,True); + fstrcpy(ntpword, ntpass);; + unix_to_dos(ntpword,True); + SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword); + SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword); + } else if ((cli->sec_mode & 2) && passlen == 24) { + /* + * Encrypted mode needed, and encrypted password supplied. + */ + memcpy(pword, pass, passlen); + if(ntpasslen == 24) { + memcpy(ntpword, ntpass, ntpasslen); + } else { + fstrcpy(ntpword, ""); + ntpasslen = 0; + } + } else { + /* + * Plaintext mode needed, assume plaintext supplied. + */ + fstrcpy(pword, pass); + unix_to_dos(pword,True); + fstrcpy(ntpword, ""); + ntpasslen = 0; + } + } + + /* if in share level security then don't send a password now */ + if (!(cli->sec_mode & 1)) { + fstrcpy(pword, ""); + passlen=1; + fstrcpy(ntpword, ""); + ntpasslen=1; + } + + /* send a session setup command */ + memset(cli->outbuf,'\0',smb_size); + + if (cli->protocol < PROTOCOL_NT1) + { + set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,1); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += passlen; + pstrcpy(p,user); + unix_to_dos(p,True); + strupper(p); + } + else + { + set_message(cli->outbuf,13,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + SSVAL(cli->outbuf,smb_vwv8,ntpasslen); + SSVAL(cli->outbuf,smb_vwv11,0); + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += SVAL(cli->outbuf,smb_vwv7); + memcpy(p,ntpword,ntpasslen); + p += SVAL(cli->outbuf,smb_vwv8); + pstrcpy(p,user); + unix_to_dos(p,True); + strupper(p); + p = skip_string(p,1); + pstrcpy(p,workgroup); + strupper(p); + p = skip_string(p,1); + pstrcpy(p,"Unix");p = skip_string(p,1); + pstrcpy(p,"Samba");p = skip_string(p,1); + set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + } + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); + + if (cli->protocol >= PROTOCOL_NT1) { + /* + * Save off some of the connected server + * info. + */ + char *server_domain,*server_os,*server_type; + server_os = smb_buf(cli->inbuf); + server_type = skip_string(server_os,1); + server_domain = skip_string(server_type,1); + fstrcpy(cli->server_os, server_os); + dos_to_unix(cli->server_os, True); + fstrcpy(cli->server_type, server_type); + dos_to_unix(cli->server_type, True); + fstrcpy(cli->server_domain, server_domain); + dos_to_unix(cli->server_domain, True); + } + + fstrcpy(cli->user_name, user); + dos_to_unix(cli->user_name, True); + + return True; +} + +/**************************************************************************** + Send a uloggoff. +*****************************************************************************/ + +BOOL cli_ulogoff(struct cli_state *cli) +{ + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,2,0,True); + CVAL(cli->outbuf,smb_com) = SMBulogoffX; + cli_setup_packet(cli); + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + return CVAL(cli->inbuf,smb_rcls) == 0; +} + +/**************************************************************************** +send a tconX +****************************************************************************/ +BOOL cli_send_tconX(struct cli_state *cli, + char *share, char *dev, char *pass, int passlen) +{ + fstring fullshare, pword, dos_pword; + char *p; + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + fstrcpy(cli->share, share); + + /* in user level security don't send a password now */ + if (cli->sec_mode & 1) { + passlen = 1; + pass = ""; + } + + if ((cli->sec_mode & 2) && *pass && passlen != 24) { + /* + * Non-encrypted passwords - convert to DOS codepage before encryption. + */ + passlen = 24; + fstrcpy(dos_pword,pass); + unix_to_dos(dos_pword,True); + SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); + } else { + if(!(cli->sec_mode & 2)) { + /* + * Non-encrypted passwords - convert to DOS codepage before using. + */ + fstrcpy(pword,pass); + unix_to_dos(pword,True); + } else { + memcpy(pword, pass, passlen); + } + } + + slprintf(fullshare, sizeof(fullshare)-1, + "\\\\%s\\%s", cli->desthost, share); + unix_to_dos(fullshare, True); + strupper(fullshare); + + set_message(cli->outbuf,4, + 2 + strlen(fullshare) + passlen + strlen(dev),True); + CVAL(cli->outbuf,smb_com) = SMBtconX; + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv3,passlen); + + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += passlen; + fstrcpy(p,fullshare); + p = skip_string(p,1); + pstrcpy(p,dev); + unix_to_dos(p,True); + + SCVAL(cli->inbuf,smb_rcls, 1); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + fstrcpy(cli->dev, "A:"); + + if (cli->protocol >= PROTOCOL_NT1) { + fstrcpy(cli->dev, smb_buf(cli->inbuf)); + } + + if (strcasecmp(share,"IPC$")==0) { + fstrcpy(cli->dev, "IPC"); + } + + /* only grab the device if we have a recent protocol level */ + if (cli->protocol >= PROTOCOL_NT1 && + smb_buflen(cli->inbuf) == 3) { + /* almost certainly win95 - enable bug fixes */ + cli->win95 = True; + } + + cli->cnum = SVAL(cli->inbuf,smb_tid); + return True; +} + + +/**************************************************************************** +send a tree disconnect +****************************************************************************/ +BOOL cli_tdis(struct cli_state *cli) +{ + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBtdis; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + return CVAL(cli->inbuf,smb_rcls) == 0; +} + + +/**************************************************************************** +send a negprot command +****************************************************************************/ +BOOL cli_negprot(struct cli_state *cli) +{ + char *p; + int numprots; + int plength; + + memset(cli->outbuf,'\0',smb_size); + + /* setup the protocol strings */ + for (plength=0,numprots=0; + prots[numprots].name && prots[numprots].prot<=cli->protocol; + numprots++) + plength += strlen(prots[numprots].name)+2; + + set_message(cli->outbuf,0,plength,True); + + p = smb_buf(cli->outbuf); + for (numprots=0; + prots[numprots].name && prots[numprots].prot<=cli->protocol; + numprots++) { + *p++ = 2; + pstrcpy(p,prots[numprots].name); + unix_to_dos(p,True); + p += strlen(p) + 1; + } + + CVAL(cli->outbuf,smb_com) = SMBnegprot; + cli_setup_packet(cli); + + CVAL(smb_buf(cli->outbuf),0) = 2; + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + if (CVAL(cli->inbuf,smb_rcls) != 0 || + ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { + return(False); + } + + cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + + + if (cli->protocol >= PROTOCOL_NT1) { + /* NT protocol */ + cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); + cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); + cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); + cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); + cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1); + cli->serverzone *= 60; + /* this time arrives in real GMT */ + cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); + if (cli->capabilities & 1) { + cli->readbraw_supported = True; + cli->writebraw_supported = True; + } + } else if (cli->protocol >= PROTOCOL_LANMAN1) { + cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); + cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); + cli->sesskey = IVAL(cli->inbuf,smb_vwv6); + cli->serverzone = SVALS(cli->inbuf,smb_vwv10); + cli->serverzone *= 60; + /* this time is converted to GMT by make_unix_date */ + cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); + cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); + cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + } else { + /* the old core protocol */ + cli->sec_mode = 0; + cli->serverzone = TimeDiff(time(NULL)); + } + + cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); + + return True; +} + + +/**************************************************************************** + send a session request. see rfc1002.txt 4.3 and 4.3.2 +****************************************************************************/ +BOOL cli_session_request(struct cli_state *cli, + struct nmb_name *calling, struct nmb_name *called) +{ + char *p; + int len = 4; + extern pstring user_socket_options; + + /* send a session request (RFC 1002) */ + + memcpy(&(cli->calling), calling, sizeof(*calling)); + memcpy(&(cli->called ), called , sizeof(*called )); + + /* put in the destination name */ + p = cli->outbuf+len; + name_mangle(cli->called .name, p, cli->called .name_type); + len += name_len(p); + + /* and my name */ + p = cli->outbuf+len; + name_mangle(cli->calling.name, p, cli->calling.name_type); + len += name_len(p); + + /* setup the packet length */ + _smb_setlen(cli->outbuf,len); + CVAL(cli->outbuf,0) = 0x81; + +#ifdef WITH_SSL +retry: +#endif /* WITH_SSL */ + + cli_send_smb(cli); + DEBUG(5,("Sent session request\n")); + + if (!cli_receive_smb(cli)) + return False; + + if (CVAL(cli->inbuf,0) == 0x84) { + /* C. Hoch 9/14/95 Start */ + /* For information, here is the response structure. + * We do the byte-twiddling to for portability. + struct RetargetResponse{ + unsigned char type; + unsigned char flags; + int16 length; + int32 ip_addr; + int16 port; + }; + */ + int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); + /* SESSION RETARGET */ + putip((char *)&cli->dest_ip,cli->inbuf+4); + + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); + if (cli->fd == -1) + return False; + + DEBUG(3,("Retargeted\n")); + + set_socket_options(cli->fd,user_socket_options); + + /* Try again */ + { + static int depth; + BOOL ret; + if (depth > 4) { + DEBUG(0,("Retarget recursion - failing\n")); + return False; + } + depth++; + ret = cli_session_request(cli, calling, called); + depth--; + return ret; + } + } /* C. Hoch 9/14/95 End */ + +#ifdef WITH_SSL + if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ + if (!sslutil_fd_is_ssl(cli->fd)){ + if (sslutil_connect(cli->fd) == 0) + goto retry; + } + } +#endif /* WITH_SSL */ + + if (CVAL(cli->inbuf,0) != 0x82) { + /* This is the wrong place to put the error... JRA. */ + cli->rap_error = CVAL(cli->inbuf,4); + return False; + } + return(True); +} + + +/**************************************************************************** +open the client sockets +****************************************************************************/ +BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) +{ + extern struct in_addr ipzero; + extern pstring user_socket_options; + + fstrcpy(cli->desthost, host); + + if (!ip || ip_equal(*ip, ipzero)) { + if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) { + return False; + } + if (ip) *ip = cli->dest_ip; + } else { + cli->dest_ip = *ip; + } + + if (cli->port == 0) cli->port = 139; /* Set to default */ + + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + cli->port, cli->timeout); + if (cli->fd == -1) + return False; + + set_socket_options(cli->fd,user_socket_options); + + return True; +} + +/**************************************************************************** +re-establishes a connection +****************************************************************************/ +BOOL cli_reestablish_connection(struct cli_state *cli) +{ + struct nmb_name calling; + struct nmb_name called; + fstring dest_host; + fstring share; + fstring dev; + BOOL do_tcon = False; + int oldfd = cli->fd; + + if (!cli->initialised || cli->fd == -1) + { + DEBUG(3,("cli_reestablish_connection: not connected\n")); + return False; + } + + /* copy the parameters necessary to re-establish the connection */ + + if (cli->cnum != 0) + { + fstrcpy(share, cli->share); + fstrcpy(dev , cli->dev); + do_tcon = True; + } + + memcpy(&called , &(cli->called ), sizeof(called )); + memcpy(&calling, &(cli->calling), sizeof(calling)); + fstrcpy(dest_host, cli->full_dest_host_name); + + DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", + nmb_namestr(&calling), nmb_namestr(&called), + inet_ntoa(cli->dest_ip), + cli->user_name, cli->domain)); + + cli->fd = -1; + + if (cli_establish_connection(cli, + dest_host, &cli->dest_ip, + &calling, &called, + share, dev, False, do_tcon)) { + if (cli->fd != oldfd) { + if (dup2(cli->fd, oldfd) == oldfd) { + close(cli->fd); + } + } + return True; + } + return False; +} + +/**************************************************************************** +establishes a connection right up to doing tconX, reading in a password. +****************************************************************************/ +BOOL cli_establish_connection(struct cli_state *cli, + char *dest_host, struct in_addr *dest_ip, + struct nmb_name *calling, struct nmb_name *called, + char *service, char *service_type, + BOOL do_shutdown, BOOL do_tcon) +{ + DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", + nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), + cli->user_name, cli->domain)); + + /* establish connection */ + + if ((!cli->initialised)) + { + return False; + } + + if (cli->fd == -1) + { + if (!cli_connect(cli, dest_host, dest_ip)) + { + DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", + nmb_namestr(calling), inet_ntoa(*dest_ip))); + return False; + } + } + + if (!cli_session_request(cli, calling, called)) + { + DEBUG(1,("failed session request\n")); + if (do_shutdown) + cli_shutdown(cli); + return False; + } + + if (!cli_negprot(cli)) + { + DEBUG(1,("failed negprot\n")); + if (do_shutdown) + cli_shutdown(cli); + return False; + } + + if (cli->pwd.cleartext || cli->pwd.null_pwd) + { + fstring passwd; + int pass_len; + + if (cli->pwd.null_pwd) + { + /* attempt null session */ + passwd[0] = 0; + pass_len = 1; + } + else + { + /* attempt clear-text session */ + pwd_get_cleartext(&(cli->pwd), passwd); + pass_len = strlen(passwd); + } + + /* attempt clear-text session */ + if (!cli_session_setup(cli, cli->user_name, + passwd, pass_len, + NULL, 0, + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) + { + cli_shutdown(cli); + } + return False; + } + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)passwd, strlen(passwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) + { + cli_shutdown(cli); + } + return False; + } + } + } + else + { + /* attempt encrypted session */ + unsigned char nt_sess_pwd[24]; + unsigned char lm_sess_pwd[24]; + + /* creates (storing a copy of) and then obtains a 24 byte password OWF */ + pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); + + /* attempt encrypted session */ + if (!cli_session_setup(cli, cli->user_name, + (char*)lm_sess_pwd, sizeof(lm_sess_pwd), + (char*)nt_sess_pwd, sizeof(nt_sess_pwd), + cli->domain)) + { + DEBUG(1,("failed session setup\n")); + if (do_shutdown) + cli_shutdown(cli); + return False; + } + + if (do_tcon) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) + { + DEBUG(1,("failed tcon_X\n")); + if (do_shutdown) + cli_shutdown(cli); + return False; + } + } + } + + if (do_shutdown) + cli_shutdown(cli); + + return True; +} + + +/**************************************************************************** + Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. +****************************************************************************/ + +BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, + struct in_addr *pdest_ip) +{ + struct nmb_name calling, called; + + make_nmb_name(&calling, srchost, 0x0); + + /* + * If the called name is an IP address + * then use *SMBSERVER immediately. + */ + + if(is_ipaddress(desthost)) + make_nmb_name(&called, "*SMBSERVER", 0x20); + else + make_nmb_name(&called, desthost, 0x20); + + if (!cli_session_request(cli, &calling, &called)) { + struct nmb_name smbservername; + + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + + /* + * If the name wasn't *SMBSERVER then + * try with *SMBSERVER if the first name fails. + */ + + if (nmb_name_equal(&called, &smbservername)) { + + /* + * The name used was *SMBSERVER, don't bother with another name. + */ + + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ +with error %s.\n", desthost, cli_errstr(cli) )); + cli_shutdown(cli); + return False; + } + + cli_shutdown(cli); + + if (!cli_initialise(cli) || + !cli_connect(cli, desthost, pdest_ip) || + !cli_session_request(cli, &calling, &smbservername)) { + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ +name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); + cli_shutdown(cli); + return False; + } + } + + return True; +} diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6472cf0380..a3a2483bd5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,12 +22,9 @@ #define NO_SYSLOG #include "includes.h" -#include "trans2.h" extern int DEBUGLEVEL; -extern pstring user_socket_options; - static void cli_process_oplock(struct cli_state *cli); /* @@ -44,7 +41,7 @@ int cli_set_port(struct cli_state *cli, int port) /**************************************************************************** recv an smb ****************************************************************************/ -static BOOL cli_receive_smb(struct cli_state *cli) +BOOL cli_receive_smb(struct cli_state *cli) { BOOL ret; again: @@ -69,7 +66,7 @@ static BOOL cli_receive_smb(struct cli_state *cli) /**************************************************************************** send an smb to a fd and re-establish if necessary ****************************************************************************/ -static BOOL cli_send_smb(struct cli_state *cli) +BOOL cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; @@ -101,7 +98,7 @@ static BOOL cli_send_smb(struct cli_state *cli) /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ -static void cli_setup_packet(struct cli_state *cli) +void cli_setup_packet(struct cli_state *cli) { cli->rap_error = 0; cli->nt_error = 0; @@ -154,3142 +151,87 @@ static void cli_process_oplock(struct cli_state *cli) } -/***************************************************** - RAP error codes - a small start but will be extended. -*******************************************************/ - -struct -{ - int err; - char *message; -} rap_errmap[] = -{ - {5, "User has insufficient privilege" }, - {86, "The specified password is invalid" }, - {2226, "Operation only permitted on a Primary Domain Controller" }, - {2242, "The password of this user has expired." }, - {2243, "The password of this user cannot change." }, - {2244, "This password cannot be used now (password history conflict)." }, - {2245, "The password is shorter than required." }, - {2246, "The password of this user is too recent to change."}, - - /* these really shouldn't be here ... */ - {0x80, "Not listening on called name"}, - {0x81, "Not listening for calling name"}, - {0x82, "Called name not present"}, - {0x83, "Called name present, but insufficient resources"}, - - {0, NULL} -}; - /**************************************************************************** - return a description of an SMB error +initialise a client structure ****************************************************************************/ -static char *cli_smb_errstr(struct cli_state *cli) +struct cli_state *cli_initialise(struct cli_state *cli) { - return smb_errstr(cli->inbuf); -} - -/****************************************************** - Return an error message - either an SMB error or a RAP - error. -*******************************************************/ - -char *cli_errstr(struct cli_state *cli) -{ - static fstring error_message; - uint8 errclass; - uint32 errnum; - uint32 nt_rpc_error; - int i; - - /* - * Errors are of three kinds - smb errors, - * dealt with by cli_smb_errstr, NT errors, - * whose code is in cli.nt_error, and rap - * errors, whose error code is in cli.rap_error. - */ - - cli_error(cli, &errclass, &errnum, &nt_rpc_error); - - if (errclass != 0) - { - return cli_smb_errstr(cli); + if (!cli) { + cli = (struct cli_state *)malloc(sizeof(*cli)); + if (!cli) + return NULL; + ZERO_STRUCTP(cli); } - /* - * Was it an NT error ? - */ - - if (nt_rpc_error) - { - char *nt_msg = get_nt_error_msg(nt_rpc_error); - - if (nt_msg == NULL) - { - slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error); - } - else - { - fstrcpy(error_message, nt_msg); - } - - return error_message; + if (cli->initialised) { + cli_shutdown(cli); } - /* - * Must have been a rap error. - */ - - slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); + ZERO_STRUCTP(cli); - for (i = 0; rap_errmap[i].message != NULL; i++) + cli->port = 0; + cli->fd = -1; + cli->cnum = -1; + cli->pid = (uint16)getpid(); + cli->mid = 1; + cli->vuid = UID_FIELD_INVALID; + cli->protocol = PROTOCOL_NT1; + cli->timeout = 20000; /* Timeout is in milliseconds. */ + cli->bufsize = CLI_BUFFER_SIZE+4; + cli->max_xmit = cli->bufsize; + cli->outbuf = (char *)malloc(cli->bufsize); + cli->inbuf = (char *)malloc(cli->bufsize); + if (!cli->outbuf || !cli->inbuf) { - if (rap_errmap[i].err == cli->rap_error) - { - fstrcpy( error_message, rap_errmap[i].message); - break; - } - } - - return error_message; -} - -/***************************************************************************** - Convert a character pointer in a cli_call_api() response to a form we can use. - This function contains code to prevent core dumps if the server returns - invalid data. -*****************************************************************************/ -static char *fix_char_ptr(unsigned int datap, unsigned int converter, - char *rdata, int rdrcnt) -{ - if (datap == 0) { /* turn NULL pointers into zero length strings */ - return ""; - } else { - unsigned int offset = datap - converter; - - if (offset >= rdrcnt) { - DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", - datap, converter, rdrcnt)); - return ""; - } else { - return &rdata[offset]; - } - } -} - -/**************************************************************************** - send a SMB trans or trans2 request - ****************************************************************************/ -static BOOL cli_send_trans(struct cli_state *cli, int trans, - char *name, int pipe_name_len, - int fid, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) -{ - int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; - char *outdata,*outparam; - char *p; - - this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ - this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,14+lsetup,0,True); - CVAL(cli->outbuf,smb_com) = trans; - SSVAL(cli->outbuf,smb_tid, cli->cnum); - cli_setup_packet(cli); - - outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len+1 : 3); - outdata = outparam+this_lparam; - - /* primary request */ - SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ - SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ - SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ - SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ - SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ - SSVAL(cli->outbuf,smb_flags,flags); /* flags */ - SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ - SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ - SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ - SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ - SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ - SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ - for (i=0;ioutbuf,smb_setup+i*2,setup[i]); - p = smb_buf(cli->outbuf); - if (trans==SMBtrans) { - memcpy(p,name, pipe_name_len + 1); /* name[] */ - } else { - *p++ = 0; /* put in a null smb_name */ - *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ - } - if (this_lparam) /* param[] */ - memcpy(outparam,param,this_lparam); - if (this_ldata) /* data[] */ - memcpy(outdata,data,this_ldata); - set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - - show_msg(cli->outbuf); - cli_send_smb(cli); - - if (this_ldata < ldata || this_lparam < lparam) { - /* receive interim response */ - if (!cli_receive_smb(cli) || - CVAL(cli->inbuf,smb_rcls) != 0) { - return(False); - } - - tot_data = this_ldata; - tot_param = this_lparam; - - while (tot_data < ldata || tot_param < lparam) { - this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ - this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - - set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); - CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2; - - outparam = smb_buf(cli->outbuf); - outdata = outparam+this_lparam; - - /* secondary request */ - SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ - SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ - SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ - SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ - SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ - SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ - SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ - SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ - if (trans==SMBtrans2) - SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ - if (this_lparam) /* param[] */ - memcpy(outparam,param+tot_param,this_lparam); - if (this_ldata) /* data[] */ - memcpy(outdata,data+tot_data,this_ldata); - set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); - - show_msg(cli->outbuf); - cli_send_smb(cli); - - tot_data += this_ldata; - tot_param += this_lparam; - } - } - - return(True); -} - - -/**************************************************************************** - receive a SMB trans or trans2 response allocating the necessary memory - ****************************************************************************/ -static BOOL cli_receive_trans(struct cli_state *cli,int trans, - char **param, int *param_len, - char **data, int *data_len) -{ - int total_data=0; - int total_param=0; - int this_data,this_param; - uint8 eclass; - uint32 ecode; - - *data_len = *param_len = 0; - - if (!cli_receive_smb(cli)) return False; - - show_msg(cli->inbuf); - - /* sanity check */ - if (CVAL(cli->inbuf,smb_com) != trans) { - DEBUG(0,("Expected %s response, got command 0x%02x\n", - trans==SMBtrans?"SMBtrans":"SMBtrans2", - CVAL(cli->inbuf,smb_com))); - return(False); - } - - /* - * An NT RPC pipe call can return ERRDOS, ERRmoredata - * to a trans call. This is not an error and should not - * be treated as such. - */ - - if (cli_error(cli, &eclass, &ecode, NULL)) - { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) - return(False); - } - - /* parse out the lengths */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - - /* allocate it */ - *data = Realloc(*data,total_data); - *param = Realloc(*param,total_param); - - while (1) { - this_data = SVAL(cli->inbuf,smb_drcnt); - this_param = SVAL(cli->inbuf,smb_prcnt); - - if (this_data + *data_len > total_data || - this_param + *param_len > total_param) { - DEBUG(1,("Data overflow in cli_receive_trans\n")); - return False; - } - - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_drdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_prdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), - this_param); - *data_len += this_data; - *param_len += this_param; - - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - - if (total_data <= *data_len && total_param <= *param_len) - break; - - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - /* sanity check */ - if (CVAL(cli->inbuf,smb_com) != trans) { - DEBUG(0,("Expected %s response, got command 0x%02x\n", - trans==SMBtrans?"SMBtrans":"SMBtrans2", - CVAL(cli->inbuf,smb_com))); - return(False); - } - if (cli_error(cli, &eclass, &ecode, NULL)) - { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) - return(False); - } - } - - return(True); -} - -/**************************************************************************** -Call a remote api on an arbitrary pipe. takes param, data and setup buffers. -****************************************************************************/ -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, - uint16 *setup, uint32 setup_count, uint32 max_setup_count, - char *params, uint32 param_count, uint32 max_param_count, - char *data, uint32 data_count, uint32 max_data_count, - char **rparam, uint32 *rparam_count, - char **rdata, uint32 *rdata_count) -{ - if (pipe_name_len == 0) - pipe_name_len = strlen(pipe_name); - - cli_send_trans(cli, SMBtrans, - pipe_name, pipe_name_len, - 0,0, /* fid, flags */ - setup, setup_count, max_setup_count, - params, param_count, max_param_count, - data, data_count, max_data_count); - - return (cli_receive_trans(cli, SMBtrans, - rparam, (int *)rparam_count, - rdata, (int *)rdata_count)); -} - -/**************************************************************************** -call a remote api -****************************************************************************/ -BOOL cli_api(struct cli_state *cli, - char *param, int prcnt, int mprcnt, - char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) -{ - cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ - 0,0, /* fid, flags */ - NULL,0,0, /* Setup, length, max */ - param, prcnt, mprcnt, /* Params, length, max */ - data, drcnt, mdrcnt /* Data, length, max */ - ); - - return (cli_receive_trans(cli,SMBtrans, - rparam, rprcnt, - rdata, rdrcnt)); -} - - -/**************************************************************************** -perform a NetWkstaUserLogon -****************************************************************************/ -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt; - pstring param; - - memset(param, 0, sizeof(param)); - - /* send a SMBtrans command with api NetWkstaUserLogon */ - p = param; - SSVAL(p,0,132); /* api number */ - p += 2; - pstrcpy(p,"OOWb54WrLh"); - p = skip_string(p,1); - pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); - p = skip_string(p,1); - SSVAL(p,0,1); - p += 2; - pstrcpy(p,user); - strupper(p); - p += 21; - p++; - p += 15; - p++; - pstrcpy(p, workstation); - strupper(p); - p += 16; - SSVAL(p, 0, CLI_BUFFER_SIZE); - p += 2; - SSVAL(p, 0, CLI_BUFFER_SIZE); - p += 2; - - if (cli_api(cli, - param, PTR_DIFF(p,param),1024, /* param, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt /* return data, return size */ - )) { - cli->rap_error = SVAL(rparam,0); - p = rdata; - - if (cli->rap_error == 0) { - DEBUG(4,("NetWkstaUserLogon success\n")); - cli->privileges = SVAL(p, 24); - fstrcpy(cli->eff_name,p+2); - } else { - DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); - } } - - if (rparam) - free(rparam); - if (rdata) - free(rdata); - return (cli->rap_error == 0); -} - -/**************************************************************************** -call a NetShareEnum - try and browse available connections on a host -****************************************************************************/ -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt; - pstring param; - int count = -1; - - /* now send a SMBtrans command with api RNetShareEnum */ - p = param; - SSVAL(p,0,0); /* api number */ - p += 2; - pstrcpy(p,"WrLeh"); - p = skip_string(p,1); - pstrcpy(p,"B13BWz"); - p = skip_string(p,1); - SSVAL(p,0,1); - /* - * Win2k needs a *smaller* buffer than 0xFFFF here - - * it returns "out of server memory" with 0xFFFF !!! JRA. - */ - SSVAL(p,2,0xFFE0); - p += 4; - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) /* return data, length */ - { - int res = SVAL(rparam,0); - int converter=SVAL(rparam,2); - int i; - - if (res == 0 || res == ERRmoredata) { - count=SVAL(rparam,4); - p = rdata; - - for (i=0;i rdrcnt) continue; + memset(cli->outbuf, '\0', cli->bufsize); + memset(cli->inbuf, '\0', cli->bufsize); - stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + cli->initialised = 1; - dos_to_unix(sname, True); - dos_to_unix(cmnt, True); - fn(sname, stype, cmnt); - } - } - } - - if (rparam) - free(rparam); - if (rdata) - free(rdata); - - return(count > 0); + return cli; } - - - -static struct { - int prot; - char *name; - } -prots[] = - { - {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, - {PROTOCOL_LANMAN1,"LANMAN1.0"}, - {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, - {PROTOCOL_NT1,"NT LM 0.12"}, - {-1,NULL} - }; - - /**************************************************************************** - Send a session setup. The username is in UNIX character format and must be - converted to DOS codepage format before sending. If the password is in - plaintext, the same should be done. +shutdown a client structure ****************************************************************************/ - -BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) +void cli_shutdown(struct cli_state *cli) { - char *p; - fstring pword, ntpword; - - if (cli->protocol < PROTOCOL_LANMAN1) - return True; - - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { - return False; - } - - if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { - /* Null session connect. */ - pword[0] = '\0'; - ntpword[0] = '\0'; - } else { - if ((cli->sec_mode & 2) && passlen != 24) { - /* - * Encrypted mode needed, and non encrypted password supplied. - */ - passlen = 24; - ntpasslen = 24; - fstrcpy(pword, pass); - unix_to_dos(pword,True); - fstrcpy(ntpword, ntpass);; - unix_to_dos(ntpword,True); - SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword); - SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword); - } else if ((cli->sec_mode & 2) && passlen == 24) { - /* - * Encrypted mode needed, and encrypted password supplied. - */ - memcpy(pword, pass, passlen); - if(ntpasslen == 24) { - memcpy(ntpword, ntpass, ntpasslen); - } else { - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - } else { - /* - * Plaintext mode needed, assume plaintext supplied. - */ - fstrcpy(pword, pass); - unix_to_dos(pword,True); - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - } - - /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { - fstrcpy(pword, ""); - passlen=1; - fstrcpy(ntpword, ""); - ntpasslen=1; - } - - /* send a session setup command */ - memset(cli->outbuf,'\0',smb_size); - - if (cli->protocol < PROTOCOL_NT1) + if (cli->outbuf) { - set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,1); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += passlen; - pstrcpy(p,user); - unix_to_dos(p,True); - strupper(p); + free(cli->outbuf); } - else + if (cli->inbuf) { - set_message(cli->outbuf,13,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,0); - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpword,ntpasslen); - p += SVAL(cli->outbuf,smb_vwv8); - pstrcpy(p,user); - unix_to_dos(p,True); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,workgroup); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,"Unix");p = skip_string(p,1); - pstrcpy(p,"Samba");p = skip_string(p,1); - set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - } - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); - - if (cli->protocol >= PROTOCOL_NT1) { - /* - * Save off some of the connected server - * info. - */ - char *server_domain,*server_os,*server_type; - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); - fstrcpy(cli->server_os, server_os); - dos_to_unix(cli->server_os, True); - fstrcpy(cli->server_type, server_type); - dos_to_unix(cli->server_type, True); - fstrcpy(cli->server_domain, server_domain); - dos_to_unix(cli->server_domain, True); - } - - fstrcpy(cli->user_name, user); - dos_to_unix(cli->user_name, True); - - return True; -} - -/**************************************************************************** - Send a uloggoff. -*****************************************************************************/ - -BOOL cli_ulogoff(struct cli_state *cli) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBulogoffX; - cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - return CVAL(cli->inbuf,smb_rcls) == 0; -} - -/**************************************************************************** -send a tconX -****************************************************************************/ -BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pass, int passlen) -{ - fstring fullshare, pword, dos_pword; - char *p; - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - fstrcpy(cli->share, share); - - /* in user level security don't send a password now */ - if (cli->sec_mode & 1) { - passlen = 1; - pass = ""; - } - - if ((cli->sec_mode & 2) && *pass && passlen != 24) { - /* - * Non-encrypted passwords - convert to DOS codepage before encryption. - */ - passlen = 24; - fstrcpy(dos_pword,pass); - unix_to_dos(dos_pword,True); - SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); - } else { - if(!(cli->sec_mode & 2)) { - /* - * Non-encrypted passwords - convert to DOS codepage before using. - */ - fstrcpy(pword,pass); - unix_to_dos(pword,True); - } else { - memcpy(pword, pass, passlen); - } - } - - slprintf(fullshare, sizeof(fullshare)-1, - "\\\\%s\\%s", cli->desthost, share); - unix_to_dos(fullshare, True); - strupper(fullshare); - - set_message(cli->outbuf,4, - 2 + strlen(fullshare) + passlen + strlen(dev),True); - CVAL(cli->outbuf,smb_com) = SMBtconX; - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv3,passlen); - - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += passlen; - fstrcpy(p,fullshare); - p = skip_string(p,1); - pstrcpy(p,dev); - unix_to_dos(p,True); - - SCVAL(cli->inbuf,smb_rcls, 1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - fstrcpy(cli->dev, "A:"); - - if (cli->protocol >= PROTOCOL_NT1) { - fstrcpy(cli->dev, smb_buf(cli->inbuf)); - } - - if (strcasecmp(share,"IPC$")==0) { - fstrcpy(cli->dev, "IPC"); - } - - /* only grab the device if we have a recent protocol level */ - if (cli->protocol >= PROTOCOL_NT1 && - smb_buflen(cli->inbuf) == 3) { - /* almost certainly win95 - enable bug fixes */ - cli->win95 = True; + free(cli->inbuf); } - - cli->cnum = SVAL(cli->inbuf,smb_tid); - return True; +#ifdef WITH_SSL + if (cli->fd != -1) + sslutil_disconnect(cli->fd); +#endif /* WITH_SSL */ + if (cli->fd != -1) + close(cli->fd); + memset(cli, 0, sizeof(*cli)); } /**************************************************************************** -send a tree disconnect +set socket options on a open connection ****************************************************************************/ -BOOL cli_tdis(struct cli_state *cli) +void cli_sockopt(struct cli_state *cli, char *options) { - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBtdis; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - return CVAL(cli->inbuf,smb_rcls) == 0; + set_socket_options(cli->fd, options); } /**************************************************************************** -rename a file +set the PID to use for smb messages. Return the old pid. ****************************************************************************/ -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) +uint16 cli_setpid(struct cli_state *cli, uint16 pid) { - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); - - CVAL(cli->outbuf,smb_com) = SMBmv; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,fname_src); - unix_to_dos(p,True); - p = skip_string(p,1); - *p++ = 4; - pstrcpy(p,fname_dst); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; + uint16 ret = cli->pid; + cli->pid = pid; + return ret; } -/**************************************************************************** -delete a file -****************************************************************************/ -BOOL cli_unlink(struct cli_state *cli, char *fname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,1, 2 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBunlink; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,fname); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -create a directory -****************************************************************************/ -BOOL cli_mkdir(struct cli_state *cli, char *dname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0, 2 + strlen(dname),True); - - CVAL(cli->outbuf,smb_com) = SMBmkdir; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,dname); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -remove a directory -****************************************************************************/ -BOOL cli_rmdir(struct cli_state *cli, char *dname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0, 2 + strlen(dname),True); - - CVAL(cli->outbuf,smb_com) = SMBrmdir; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,dname); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - - - -/**************************************************************************** -open a file -****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,24,1 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBntcreateX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SIVAL(cli->outbuf,smb_ntcreate_Flags, 0x06); - SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f); - SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); - SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); - SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); - SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); - - p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - unix_to_dos(p,True); - p = skip_string(p,1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv2 + 1); -} - - -/**************************************************************************** -open a file -WARNING: if you open with O_WRONLY then getattrE won't work! -****************************************************************************/ -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) -{ - char *p; - unsigned openfn=0; - unsigned accessmode=0; - - if (flags & O_CREAT) - openfn |= (1<<4); - if (!(flags & O_EXCL)) { - if (flags & O_TRUNC) - openfn |= (1<<1); - else - openfn |= (1<<0); - } - - accessmode = (share_mode<<4); - - if ((flags & O_ACCMODE) == O_RDWR) { - accessmode |= 2; - } else if ((flags & O_ACCMODE) == O_WRONLY) { - accessmode |= 1; - } - -#if defined(O_SYNC) - if ((flags & O_SYNC) == O_SYNC) { - accessmode |= (1<<14); - } -#endif /* O_SYNC */ - - if (share_mode == DENY_FCB) { - accessmode = 0xFF; - } - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,15,1 + strlen(fname),True); - - CVAL(cli->outbuf,smb_com) = SMBopenX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - SSVAL(cli->outbuf,smb_vwv3,accessmode); - SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); - SSVAL(cli->outbuf,smb_vwv5,0); - SSVAL(cli->outbuf,smb_vwv8,openfn); - - if (cli->use_oplocks) { - /* if using oplocks then ask for a batch oplock via - core and extended methods */ - CVAL(cli->outbuf,smb_flg) |= - FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; - SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); - } - - p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - unix_to_dos(p,True); - p = skip_string(p,1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv2); -} - - - - -/**************************************************************************** - close a file -****************************************************************************/ -BOOL cli_close(struct cli_state *cli, int fnum) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,3,0,True); - - CVAL(cli->outbuf,smb_com) = SMBclose; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SIVALS(cli->outbuf,smb_vwv1,-1); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - - -/**************************************************************************** - lock a file -****************************************************************************/ -BOOL cli_lock(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, enum brl_type lock_type) -{ - char *p; - int saved_timeout = cli->timeout; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0', smb_size); - - set_message(cli->outbuf,8,10,True); - - CVAL(cli->outbuf,smb_com) = SMBlockingX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0); - SIVALS(cli->outbuf, smb_vwv4, timeout); - SSVAL(cli->outbuf,smb_vwv6,0); - SSVAL(cli->outbuf,smb_vwv7,1); - - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - cli_send_smb(cli); - - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); - - if (!cli_receive_smb(cli)) { - cli->timeout = saved_timeout; - return False; - } - - cli->timeout = saved_timeout; - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** - unlock a file -****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,8,10,True); - - CVAL(cli->outbuf,smb_com) = SMBlockingX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; - SIVALS(cli->outbuf, smb_vwv4, 0); - SSVAL(cli->outbuf,smb_vwv6,1); - SSVAL(cli->outbuf,smb_vwv7,0); - - p = smb_buf(cli->outbuf); - SSVAL(p, 0, cli->pid); - SIVAL(p, 2, offset); - SIVAL(p, 6, len); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - - - -/**************************************************************************** -issue a single SMBread and don't wait for a reply -****************************************************************************/ -static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, - size_t size, int i) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,10,0,True); - - CVAL(cli->outbuf,smb_com) = SMBreadX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - SSVAL(cli->outbuf,smb_vwv5,size); - SSVAL(cli->outbuf,smb_vwv6,size); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - cli_send_smb(cli); -} - -/**************************************************************************** - read from a file -****************************************************************************/ -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) -{ - char *p; - int total = -1; - int issued=0; - int received=0; -/* - * There is a problem in this code when mpx is more than one. - * for some reason files can get corrupted when being read. - * Until we understand this fully I am serializing reads (one - * read/one reply) for now. JRA. - */ -#if 0 - int mpx = MAX(cli->max_mux-1, 1); -#else - int mpx = 1; -#endif - int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int mid; - int blocks = (size + (block-1)) / block; - - if (size == 0) return 0; - - while (received < blocks) { - int size2; - - while (issued - received < mpx && issued < blocks) { - int size1 = MIN(block, size-issued*block); - cli_issue_read(cli, fnum, offset+issued*block, size1, issued); - issued++; - } - - if (!cli_receive_smb(cli)) { - return total; - } - - received++; - mid = SVAL(cli->inbuf, smb_mid) - cli->mid; - size2 = SVAL(cli->inbuf, smb_vwv5); - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - blocks = MIN(blocks, mid-1); - continue; - } - - if (size2 <= 0) { - blocks = MIN(blocks, mid-1); - /* this distinguishes EOF from an error */ - total = MAX(total, 0); - continue; - } - - if (size2 > block) { - DEBUG(0,("server returned more than we wanted!\n")); - return -1; - } - if (mid >= issued) { - DEBUG(0,("invalid mid from server!\n")); - return -1; - } - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - - memcpy(buf+mid*block, p, size2); - - total = MAX(total, mid*block + size2); - } - - while (received < issued) { - cli_receive_smb(cli); - received++; - } - - return total; -} - - -/**************************************************************************** -issue a single SMBwrite and don't wait for a reply -****************************************************************************/ -static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, - size_t size, int i) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,12,size,True); - - CVAL(cli->outbuf,smb_com) = SMBwriteX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,fnum); - - SIVAL(cli->outbuf,smb_vwv3,offset); - SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); - SSVAL(cli->outbuf,smb_vwv7,mode); - - SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_ALL(mode, 0x0008) ? size : 0); - SSVAL(cli->outbuf,smb_vwv10,size); - SSVAL(cli->outbuf,smb_vwv11, - smb_buf(cli->outbuf) - smb_base(cli->outbuf)); - - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); - memcpy(p, buf, size); - - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - show_msg(cli->outbuf); - cli_send_smb(cli); -} - -/**************************************************************************** - write to a file - write_mode: 0x0001 disallow write cacheing - 0x0002 return bytes remaining - 0x0004 use raw named pipe protocol - 0x0008 start of message mode named pipe protocol -****************************************************************************/ -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size) -{ - int bwritten = 0; - int issued = 0; - int received = 0; - int mpx = MAX(cli->max_mux-1, 1); - int block = (cli->max_xmit - (smb_size+32)) & ~1023; - int blocks = (size + (block-1)) / block; - - while (received < blocks) { - - while ((issued - received < mpx) && (issued < blocks)) - { - int bsent = issued * block; - int size1 = MIN(block, size - bsent); - - cli_issue_write(cli, fnum, offset + bsent, - write_mode, - buf + bsent, - size1, issued); - issued++; - } - - if (!cli_receive_smb(cli)) - { - return bwritten; - } - - received++; - - if (CVAL(cli->inbuf,smb_rcls) != 0) - { - break; - } - - bwritten += SVAL(cli->inbuf, smb_vwv2); - } - - while (received < issued && cli_receive_smb(cli)) - { - received++; - } - - return bwritten; -} - - -/**************************************************************************** - write to a file using a SMBwrite and not bypassing 0 byte writes -****************************************************************************/ -ssize_t cli_smbwrite(struct cli_state *cli, - int fnum, char *buf, off_t offset, size_t size1) -{ - char *p; - ssize_t total = 0; - - do { - size_t size = MIN(size1, cli->max_xmit - 48); - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,5, 3 + size,True); - - CVAL(cli->outbuf,smb_com) = SMBwrite; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SSVAL(cli->outbuf,smb_vwv1,size); - SIVAL(cli->outbuf,smb_vwv2,offset); - SSVAL(cli->outbuf,smb_vwv4,0); - - p = smb_buf(cli->outbuf); - *p++ = 1; - SSVAL(p, 0, size); - memcpy(p+2, buf, size); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - size = SVAL(cli->inbuf,smb_vwv0); - if (size == 0) break; - - size1 -= size; - total += size; - } while (size1); - - return total; -} - - -/**************************************************************************** -do a SMBgetattrE call -****************************************************************************/ -BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,1,0,True); - - CVAL(cli->outbuf,smb_com) = SMBgetattrE; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fd); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - if (size) { - *size = IVAL(cli->inbuf, smb_vwv6); - } - - if (attr) { - *attr = SVAL(cli->inbuf,smb_vwv10); - } - - if (c_time) { - *c_time = make_unix_date3(cli->inbuf+smb_vwv0); - } - - if (a_time) { - *a_time = make_unix_date3(cli->inbuf+smb_vwv2); - } - - if (m_time) { - *m_time = make_unix_date3(cli->inbuf+smb_vwv4); - } - - return True; -} - - -/**************************************************************************** -do a SMBgetatr call -****************************************************************************/ -BOOL cli_getatr(struct cli_state *cli, char *fname, - uint16 *attr, size_t *size, time_t *t) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,0,strlen(fname)+2,True); - - CVAL(cli->outbuf,smb_com) = SMBgetatr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - unix_to_dos(p+1,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - if (size) { - *size = IVAL(cli->inbuf, smb_vwv3); - } - - if (t) { - *t = make_unix_date3(cli->inbuf+smb_vwv1); - } - - if (attr) { - *attr = SVAL(cli->inbuf,smb_vwv0); - } - - - return True; -} - - -/**************************************************************************** -do a SMBsetatr call -****************************************************************************/ -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,8,strlen(fname)+4,True); - - CVAL(cli->outbuf,smb_com) = SMBsetatr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0, attr); - put_dos_date3(cli->outbuf,smb_vwv1, t); - - p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - unix_to_dos(p+1,True); - p = skip_string(p,1); - *p = 4; - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; -} - -/**************************************************************************** -send a qpathinfo call -****************************************************************************/ -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QPATHINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - int count=8; - BOOL ret; - time_t (*date_fn)(void *); - - param_len = strlen(fname) + 7; - - memset(param, 0, param_len); - SSVAL(param, 0, SMB_INFO_STANDARD); - pstrcpy(¶m[6], fname); - unix_to_dos(¶m[6],True); - - do { - ret = (cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - ) && - cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)); - if (!ret) { - /* we need to work around a Win95 bug - sometimes - it gives ERRSRV/ERRerror temprarily */ - uint8 eclass; - uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); - if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); - } - } while (count-- && ret==False); - - if (!ret || !rdata || data_len < 22) { - return False; - } - - if (cli->win95) { - date_fn = make_unix_date; - } else { - date_fn = make_unix_date2; - } - - if (c_time) { - *c_time = date_fn(rdata+0); - } - if (a_time) { - *a_time = date_fn(rdata+4); - } - if (m_time) { - *m_time = date_fn(rdata+8); - } - if (size) { - *size = IVAL(rdata, 12); - } - if (mode) { - *mode = SVAL(rdata,l1_attrFile); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - -/**************************************************************************** -send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level -****************************************************************************/ -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, - SMB_INO_T *ino) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QPATHINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - - param_len = strlen(fname) + 7; - - memset(param, 0, param_len); - SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); - pstrcpy(¶m[6], fname); - unix_to_dos(¶m[6],True); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; - } - - if (!rdata || data_len < 22) { - return False; - } - - if (c_time) { - *c_time = interpret_long_date(rdata+0) - cli->serverzone; - } - if (a_time) { - *a_time = interpret_long_date(rdata+8) - cli->serverzone; - } - if (m_time) { - *m_time = interpret_long_date(rdata+16) - cli->serverzone; - } - if (w_time) { - *w_time = interpret_long_date(rdata+24) - cli->serverzone; - } - if (mode) { - *mode = SVAL(rdata, 32); - } - if (size) { - *size = IVAL(rdata, 48); - } - if (ino) { - *ino = IVAL(rdata, 64); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - - -/**************************************************************************** -send a qfileinfo call -****************************************************************************/ -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino) -{ - int data_len = 0; - int param_len = 0; - uint16 setup = TRANSACT2_QFILEINFO; - pstring param; - char *rparam=NULL, *rdata=NULL; - - /* if its a win95 server then fail this - win95 totally screws it - up */ - if (cli->win95) return False; - - param_len = 4; - - memset(param, 0, param_len); - SSVAL(param, 0, fnum); - SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; - } - - if (!rdata || data_len < 68) { - return False; - } - - if (c_time) { - *c_time = interpret_long_date(rdata+0) - cli->serverzone; - } - if (a_time) { - *a_time = interpret_long_date(rdata+8) - cli->serverzone; - } - if (m_time) { - *m_time = interpret_long_date(rdata+16) - cli->serverzone; - } - if (w_time) { - *w_time = interpret_long_date(rdata+24) - cli->serverzone; - } - if (mode) { - *mode = SVAL(rdata, 32); - } - if (size) { - *size = IVAL(rdata, 48); - } - if (ino) { - *ino = IVAL(rdata, 64); - } - - if (rdata) free(rdata); - if (rparam) free(rparam); - return True; -} - - -/**************************************************************************** -interpret a long filename structure - this is mostly guesses at the moment -The length of the structure is returned -The structure of a long filename depends on the info level. 260 is used -by NT and 2 is used by OS/2 -****************************************************************************/ -static int interpret_long_filename(int level,char *p,file_info *finfo) -{ - extern file_info def_finfo; - - if (finfo) - memcpy(finfo,&def_finfo,sizeof(*finfo)); - - switch (level) - { - case 1: /* OS/2 understands this */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+27); - dos_to_unix(finfo->name,True); - } - return(28 + CVAL(p,26)); - - case 2: /* this is what OS/2 uses mostly */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+31); - dos_to_unix(finfo->name,True); - } - return(32 + CVAL(p,30)); - - /* levels 3 and 4 are untested */ - case 3: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+33); - dos_to_unix(finfo->name,True); - } - return(SVAL(p,4)+4); - - case 4: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+37); - dos_to_unix(finfo->name,True); - } - return(SVAL(p,4)+4); - - case 260: /* NT uses this, but also accepts 2 */ - if (finfo) { - int ret = SVAL(p,0); - int namelen; - p += 4; /* next entry offset */ - p += 4; /* fileindex */ - - /* these dates appear to arrive in a - weird way. It seems to be localtime - plus the serverzone given in the - initial connect. This is GMT when - DST is not in effect and one hour - from GMT otherwise. Can this really - be right?? - - I suppose this could be called - kludge-GMT. Is is the GMT you get - by using the current DST setting on - a different localtime. It will be - cheap to calculate, I suppose, as - no DST tables will be needed */ - - finfo->ctime = interpret_long_date(p); p += 8; - finfo->atime = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL(p,0); p += 8; - p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); p += 4; - namelen = IVAL(p,0); p += 4; - p += 4; /* EA size */ - p += 2; /* short name len? */ - p += 24; /* short name? */ - StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); - dos_to_unix(finfo->name,True); - return(ret); - } - return(SVAL(p,0)); - } - - DEBUG(1,("Unknown long filename format %d\n",level)); - return(SVAL(p,0)); -} - - -/**************************************************************************** - do a directory listing, calling fn on each file found - ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)) -{ - int max_matches = 512; - /* NT uses 260, OS/2 uses 2. Both accept 1. */ - int info_level = cli->protocol 200) { - DEBUG(0,("Error: Looping in FIND_NEXT??\n")); - break; - } - - param_len = 12+strlen(mask)+1; - - if (First) { - setup = TRANSACT2_FINDFIRST; - SSVAL(param,0,attribute); /* attribute */ - SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,4+2); /* resume required + close on end */ - SSVAL(param,6,info_level); - SIVAL(param,8,0); - pstrcpy(param+12,mask); - } else { - setup = TRANSACT2_FINDNEXT; - SSVAL(param,0,ff_dir_handle); - SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,info_level); - SIVAL(param,6,0); /* ff_resume_key */ - SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ - pstrcpy(param+12,mask); - - DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_lastname,mask)); - } - - if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 10, /* param, length, max */ - NULL, 0, - cli->max_xmit /* data, length, max */ - )) { - break; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - /* we need to work around a Win95 bug - sometimes - it gives ERRSRV/ERRerror temprarily */ - uint8 eclass; - uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); - if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); - continue; - } - - if (total_received == -1) total_received = 0; - - /* parse out some important return info */ - p = rparam; - if (First) { - ff_dir_handle = SVAL(p,0); - ff_searchcount = SVAL(p,2); - ff_eos = SVAL(p,4); - ff_lastname = SVAL(p,8); - } else { - ff_searchcount = SVAL(p,0); - ff_eos = SVAL(p,2); - ff_lastname = SVAL(p,6); - } - - if (ff_searchcount == 0) - break; - - /* point to the data bytes */ - p = rdata; - - /* we might need the lastname for continuations */ - if (ff_lastname > 0) { - switch(info_level) - { - case 260: - StrnCpy(mask,p+ff_lastname, - MIN(sizeof(mask)-1,data_len-ff_lastname)); - break; - case 1: - pstrcpy(mask,p + ff_lastname + 1); - break; - } - } else { - pstrcpy(mask,""); - } - - dos_to_unix(mask, True); - - /* and add them to the dirlist pool */ - dirlist = Realloc(dirlist,dirlist_len + data_len); - - if (!dirlist) { - DEBUG(0,("Failed to expand dirlist\n")); - break; - } - - /* put in a length for the last entry, to ensure we can chain entries - into the next packet */ - for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(info_level,p2,NULL); - SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); - - /* grab the data for later use */ - memcpy(dirlist+dirlist_len,p,data_len); - dirlist_len += data_len; - - total_received += ff_searchcount; - - if (rdata) free(rdata); rdata = NULL; - if (rparam) free(rparam); rparam = NULL; - - DEBUG(3,("received %d entries (eos=%d)\n", - ff_searchcount,ff_eos)); - - if (ff_searchcount > 0) loop_count = 0; - - First = False; - } - - for (p=dirlist,i=0;i= sizeof(fstring)-1) { - DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); - return False; - } - - SSVAL(p,0,214); /* SamOEMChangePassword command. */ - p += 2; - pstrcpy(p, "zsT"); - p = skip_string(p,1); - pstrcpy(p, "B516B16"); - p = skip_string(p,1); - pstrcpy(p,user); - p = skip_string(p,1); - SSVAL(p,0,532); - p += 2; - - param_len = PTR_DIFF(p,param); - - /* - * Get the Lanman hash of the old password, we - * use this as the key to make_oem_passwd_hash(). - */ - memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); - fstrcpy(upper_case_old_pw, old_password); - unix_to_dos(upper_case_old_pw,True); - strupper(upper_case_old_pw); - E_P16((uchar *)upper_case_old_pw, old_pw_hash); - - pstrcpy(dos_new_password, new_password); - unix_to_dos(dos_new_password, True); - - if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) - return False; - - /* - * Now place the old password hash in the data. - */ - memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); - fstrcpy(upper_case_new_pw, new_password); - unix_to_dos(upper_case_new_pw,True); - strupper(upper_case_new_pw); - - E_P16((uchar *)upper_case_new_pw, new_pw_hash); - - E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); - - data_len = 532; - - if (cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ - 0,0, /* fid, flags */ - NULL,0,0, /* setup, length, max */ - param,param_len,2, /* param, length, max */ - data,data_len,0 /* data, length, max */ - ) == False) { - DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", - user )); - return False; - } - - if (cli_receive_trans(cli,SMBtrans, - &rparam, &rprcnt, - &rdata, &rdrcnt)) { - if (rparam) - cli->rap_error = SVAL(rparam,0); - } - - if (rparam) - free(rparam); - if (rdata) - free(rdata); - - return (cli->rap_error == 0); -} - -/**************************************************************************** -send a negprot command -****************************************************************************/ -BOOL cli_negprot(struct cli_state *cli) -{ - char *p; - int numprots; - int plength; - - memset(cli->outbuf,'\0',smb_size); - - /* setup the protocol strings */ - for (plength=0,numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) - plength += strlen(prots[numprots].name)+2; - - set_message(cli->outbuf,0,plength,True); - - p = smb_buf(cli->outbuf); - for (numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) { - *p++ = 2; - pstrcpy(p,prots[numprots].name); - unix_to_dos(p,True); - p += strlen(p) + 1; - } - - CVAL(cli->outbuf,smb_com) = SMBnegprot; - cli_setup_packet(cli); - - CVAL(smb_buf(cli->outbuf),0) = 2; - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - if (CVAL(cli->inbuf,smb_rcls) != 0 || - ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { - return(False); - } - - cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - - - if (cli->protocol >= PROTOCOL_NT1) { - /* NT protocol */ - cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); - cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); - cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); - cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1); - cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1); - cli->serverzone *= 60; - /* this time arrives in real GMT */ - cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (cli->capabilities & 1) { - cli->readbraw_supported = True; - cli->writebraw_supported = True; - } - } else if (cli->protocol >= PROTOCOL_LANMAN1) { - cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); - cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); - cli->sesskey = IVAL(cli->inbuf,smb_vwv6); - cli->serverzone = SVALS(cli->inbuf,smb_vwv10); - cli->serverzone *= 60; - /* this time is converted to GMT by make_unix_date */ - cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); - cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); - cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - } else { - /* the old core protocol */ - cli->sec_mode = 0; - cli->serverzone = TimeDiff(time(NULL)); - } - - cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); - - return True; -} - - -/**************************************************************************** - send a session request. see rfc1002.txt 4.3 and 4.3.2 -****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, - struct nmb_name *calling, struct nmb_name *called) -{ - char *p; - int len = 4; - /* send a session request (RFC 1002) */ - - memcpy(&(cli->calling), calling, sizeof(*calling)); - memcpy(&(cli->called ), called , sizeof(*called )); - - /* put in the destination name */ - p = cli->outbuf+len; - name_mangle(cli->called .name, p, cli->called .name_type); - len += name_len(p); - - /* and my name */ - p = cli->outbuf+len; - name_mangle(cli->calling.name, p, cli->calling.name_type); - len += name_len(p); - - /* setup the packet length */ - _smb_setlen(cli->outbuf,len); - CVAL(cli->outbuf,0) = 0x81; - -#ifdef WITH_SSL -retry: -#endif /* WITH_SSL */ - - cli_send_smb(cli); - DEBUG(5,("Sent session request\n")); - - if (!cli_receive_smb(cli)) - return False; - - if (CVAL(cli->inbuf,0) == 0x84) { - /* C. Hoch 9/14/95 Start */ - /* For information, here is the response structure. - * We do the byte-twiddling to for portability. - struct RetargetResponse{ - unsigned char type; - unsigned char flags; - int16 length; - int32 ip_addr; - int16 port; - }; - */ - int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); - /* SESSION RETARGET */ - putip((char *)&cli->dest_ip,cli->inbuf+4); - - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); - if (cli->fd == -1) - return False; - - DEBUG(3,("Retargeted\n")); - - set_socket_options(cli->fd,user_socket_options); - - /* Try again */ - { - static int depth; - BOOL ret; - if (depth > 4) { - DEBUG(0,("Retarget recursion - failing\n")); - return False; - } - depth++; - ret = cli_session_request(cli, calling, called); - depth--; - return ret; - } - } /* C. Hoch 9/14/95 End */ - -#ifdef WITH_SSL - if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ - if (!sslutil_fd_is_ssl(cli->fd)){ - if (sslutil_connect(cli->fd) == 0) - goto retry; - } - } -#endif /* WITH_SSL */ - - if (CVAL(cli->inbuf,0) != 0x82) { - /* This is the wrong place to put the error... JRA. */ - cli->rap_error = CVAL(cli->inbuf,4); - return False; - } - return(True); -} - - -/**************************************************************************** -open the client sockets -****************************************************************************/ -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) -{ - extern struct in_addr ipzero; - - fstrcpy(cli->desthost, host); - - if (!ip || ip_equal(*ip, ipzero)) { - if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) { - return False; - } - if (ip) *ip = cli->dest_ip; - } else { - cli->dest_ip = *ip; - } - - if (cli->port == 0) cli->port = 139; /* Set to default */ - - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - cli->port, cli->timeout); - if (cli->fd == -1) - return False; - - set_socket_options(cli->fd,user_socket_options); - - return True; -} - - -/**************************************************************************** -initialise a client structure -****************************************************************************/ -struct cli_state *cli_initialise(struct cli_state *cli) -{ - if (!cli) { - cli = (struct cli_state *)malloc(sizeof(*cli)); - if (!cli) - return NULL; - ZERO_STRUCTP(cli); - } - - if (cli->initialised) { - cli_shutdown(cli); - } - - ZERO_STRUCTP(cli); - - cli->port = 0; - cli->fd = -1; - cli->cnum = -1; - cli->pid = (uint16)getpid(); - cli->mid = 1; - cli->vuid = UID_FIELD_INVALID; - cli->protocol = PROTOCOL_NT1; - cli->timeout = 20000; /* Timeout is in milliseconds. */ - cli->bufsize = CLI_BUFFER_SIZE+4; - cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize); - cli->inbuf = (char *)malloc(cli->bufsize); - if (!cli->outbuf || !cli->inbuf) - { - return False; - } - - memset(cli->outbuf, '\0', cli->bufsize); - memset(cli->inbuf, '\0', cli->bufsize); - - cli->initialised = 1; - - return cli; -} - -/**************************************************************************** -shutdown a client structure -****************************************************************************/ -void cli_shutdown(struct cli_state *cli) -{ - if (cli->outbuf) - { - free(cli->outbuf); - } - if (cli->inbuf) - { - free(cli->inbuf); - } -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ - if (cli->fd != -1) - close(cli->fd); - memset(cli, 0, sizeof(*cli)); -} - - -/**************************************************************************** - return error codes for the last packet - returns 0 if there was no error and the best approx of a unix errno - otherwise - - for 32 bit "warnings", a return code of 0 is expected. - -****************************************************************************/ -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) -{ - int flgs2; - char rcls; - int code; - - if (eclass) *eclass = 0; - if (num ) *num = 0; - if (nt_rpc_error) *nt_rpc_error = 0; - - if(!cli->initialised) - return EINVAL; - - if(!cli->inbuf) - return ENOMEM; - - flgs2 = SVAL(cli->inbuf,smb_flg2); - if (nt_rpc_error) *nt_rpc_error = cli->nt_error; - - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* 32 bit error codes detected */ - uint32 nt_err = IVAL(cli->inbuf,smb_rcls); - if (num) *num = nt_err; - DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); - if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; - - switch (nt_err & 0xFFFFFF) { - case NT_STATUS_ACCESS_VIOLATION: return EACCES; - case NT_STATUS_NO_SUCH_FILE: return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; - case NT_STATUS_INVALID_HANDLE: return EBADF; - case NT_STATUS_NO_MEMORY: return ENOMEM; - case NT_STATUS_ACCESS_DENIED: return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION: return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; - } - - /* for all other cases - a default code */ - return EINVAL; - } - - rcls = CVAL(cli->inbuf,smb_rcls); - code = SVAL(cli->inbuf,smb_err); - if (rcls == 0) return 0; - - if (eclass) *eclass = rcls; - if (num ) *num = code; - - if (rcls == ERRDOS) { - switch (code) { - case ERRbadfile: return ENOENT; - case ERRbadpath: return ENOTDIR; - case ERRnoaccess: return EACCES; - case ERRfilexists: return EEXIST; - case ERRrename: return EEXIST; - case ERRbadshare: return EBUSY; - case ERRlock: return EBUSY; - } - } - if (rcls == ERRSRV) { - switch (code) { - case ERRbadpw: return EPERM; - case ERRaccess: return EACCES; - case ERRnoresource: return ENOMEM; - case ERRinvdevice: return ENODEV; - case ERRinvnetname: return ENODEV; - } - } - /* for other cases */ - return EINVAL; -} - -/**************************************************************************** -set socket options on a open connection -****************************************************************************/ -void cli_sockopt(struct cli_state *cli, char *options) -{ - set_socket_options(cli->fd, options); -} - -/**************************************************************************** -set the PID to use for smb messages. Return the old pid. -****************************************************************************/ -uint16 cli_setpid(struct cli_state *cli, uint16 pid) -{ - uint16 ret = cli->pid; - cli->pid = pid; - return ret; -} - -/**************************************************************************** -re-establishes a connection -****************************************************************************/ -BOOL cli_reestablish_connection(struct cli_state *cli) -{ - struct nmb_name calling; - struct nmb_name called; - fstring dest_host; - fstring share; - fstring dev; - BOOL do_tcon = False; - int oldfd = cli->fd; - - if (!cli->initialised || cli->fd == -1) - { - DEBUG(3,("cli_reestablish_connection: not connected\n")); - return False; - } - - /* copy the parameters necessary to re-establish the connection */ - - if (cli->cnum != 0) - { - fstrcpy(share, cli->share); - fstrcpy(dev , cli->dev); - do_tcon = True; - } - - memcpy(&called , &(cli->called ), sizeof(called )); - memcpy(&calling, &(cli->calling), sizeof(calling)); - fstrcpy(dest_host, cli->full_dest_host_name); - - DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", - nmb_namestr(&calling), nmb_namestr(&called), - inet_ntoa(cli->dest_ip), - cli->user_name, cli->domain)); - - cli->fd = -1; - - if (cli_establish_connection(cli, - dest_host, &cli->dest_ip, - &calling, &called, - share, dev, False, do_tcon)) { - if (cli->fd != oldfd) { - if (dup2(cli->fd, oldfd) == oldfd) { - close(cli->fd); - } - } - return True; - } - return False; -} - -/**************************************************************************** -establishes a connection right up to doing tconX, reading in a password. -****************************************************************************/ -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon) -{ - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), - cli->user_name, cli->domain)); - - /* establish connection */ - - if ((!cli->initialised)) - { - return False; - } - - if (cli->fd == -1) - { - if (!cli_connect(cli, dest_host, dest_ip)) - { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(calling), inet_ntoa(*dest_ip))); - return False; - } - } - - if (!cli_session_request(cli, calling, called)) - { - DEBUG(1,("failed session request\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (!cli_negprot(cli)) - { - DEBUG(1,("failed negprot\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (cli->pwd.cleartext || cli->pwd.null_pwd) - { - fstring passwd; - int pass_len; - - if (cli->pwd.null_pwd) - { - /* attempt null session */ - passwd[0] = 0; - pass_len = 1; - } - else - { - /* attempt clear-text session */ - pwd_get_cleartext(&(cli->pwd), passwd); - pass_len = strlen(passwd); - } - - /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->user_name, - passwd, pass_len, - NULL, 0, - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)passwd, strlen(passwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - } - } - else - { - /* attempt encrypted session */ - unsigned char nt_sess_pwd[24]; - unsigned char lm_sess_pwd[24]; - - /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); - - /* attempt encrypted session */ - if (!cli_session_setup(cli, cli->user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, sizeof(nt_sess_pwd), - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - } - } - - if (do_shutdown) - cli_shutdown(cli); - - return True; -} - - -/**************************************************************************** - cancel a print job - ****************************************************************************/ -int cli_printjob_del(struct cli_state *cli, int job) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt, ret = -1; - pstring param; - - memset(param,'\0',sizeof(param)); - - p = param; - SSVAL(p,0,81); /* DosPrintJobDel() */ - p += 2; - pstrcpy(p,"W"); - p = skip_string(p,1); - pstrcpy(p,""); - p = skip_string(p,1); - SSVAL(p,0,job); - p += 2; - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) { /* return data, length */ - ret = SVAL(rparam,0); - } - - if (rparam) free(rparam); - if (rdata) free(rdata); - - return ret; -} - - -/**************************************************************************** -call fn() on each entry in a print queue -****************************************************************************/ -int cli_print_queue(struct cli_state *cli, - void (*fn)(struct print_job_info *)) -{ - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt, rprcnt; - pstring param; - int result_code=0; - int i = -1; - - memset(param,'\0',sizeof(param)); - - p = param; - SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ - p += 2; - pstrcpy(p,"zWrLeh"); /* parameter description? */ - p = skip_string(p,1); - pstrcpy(p,"WWzWWDDzz"); /* returned data format */ - p = skip_string(p,1); - pstrcpy(p,cli->share); /* name of queue */ - p = skip_string(p,1); - SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ - SSVAL(p,2,1000); /* size of bytes of returned data buffer */ - p += 4; - pstrcpy(p,""); /* subformat */ - p = skip_string(p,1); - - DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) { /* return data, length */ - int converter; - result_code = SVAL(rparam,0); - converter = SVAL(rparam,2); /* conversion factor */ - - if (result_code == 0) { - struct print_job_info job; - - p = rdata; - - for (i = 0; i < SVAL(rparam,4); ++i) { - job.id = SVAL(p,0); - job.priority = SVAL(p,2); - fstrcpy(job.user, - fix_char_ptr(SVAL(p,4), converter, - rdata, rdrcnt)); - job.t = make_unix_date3(p + 12); - job.size = IVAL(p,16); - fstrcpy(job.name,fix_char_ptr(SVAL(p,24), - converter, - rdata, rdrcnt)); - fn(&job); - p += 28; - } - } - } - - /* If any parameters or data were returned, free the storage. */ - if(rparam) free(rparam); - if(rdata) free(rdata); - - return i; -} - -/**************************************************************************** -check for existance of a dir -****************************************************************************/ -BOOL cli_chkpath(struct cli_state *cli, char *path) -{ - pstring path2; - char *p; - - safe_strcpy(path2,path,sizeof(pstring)); - trim_string(path2,NULL,"\\"); - if (!*path2) *path2 = '\\'; - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,4 + strlen(path2),True); - SCVAL(cli->outbuf,smb_com,SMBchkpth); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - p = smb_buf(cli->outbuf); - *p++ = 4; - safe_strcpy(p,path2,strlen(path2)); - unix_to_dos(p,True); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} - - -/**************************************************************************** -start a message sequence -****************************************************************************/ -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp) -{ - char *p; - - /* send a SMBsendstrt command */ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendstrt; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - p = smb_buf(cli->outbuf); - *p++ = 4; - pstrcpy(p,username); - unix_to_dos(p,True); - p = skip_string(p,1); - *p++ = 4; - pstrcpy(p,host); - unix_to_dos(p,True); - p = skip_string(p,1); - - set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); - - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - *grp = SVAL(cli->inbuf,smb_vwv0); - - return True; -} - - -/**************************************************************************** -send a message -****************************************************************************/ -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) -{ - char *p; - - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,len+3,True); - CVAL(cli->outbuf,smb_com) = SMBsendtxt; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,grp); - - p = smb_buf(cli->outbuf); - *p = 1; - SSVAL(p,1,len); - memcpy(p+3,msg,len); - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} - -/**************************************************************************** -end a message -****************************************************************************/ -BOOL cli_message_end(struct cli_state *cli, int grp) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendend; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - - SSVAL(cli->outbuf,smb_vwv0,grp); - - cli_setup_packet(cli); - - cli_send_smb(cli); - - if (!cli_receive_smb(cli)) { - return False; - } - - if (cli_error(cli, NULL, NULL, NULL)) return False; - - return True; -} - - -/**************************************************************************** -query disk space -****************************************************************************/ -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) -{ - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBdskattr; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - - *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2); - *total = SVAL(cli->inbuf,smb_vwv0); - *avail = SVAL(cli->inbuf,smb_vwv3); - - return True; -} - -/**************************************************************************** - Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. -****************************************************************************/ - -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, - struct in_addr *pdest_ip) -{ - struct nmb_name calling, called; - - make_nmb_name(&calling, srchost, 0x0); - - /* - * If the called name is an IP address - * then use *SMBSERVER immediately. - */ - - if(is_ipaddress(desthost)) - make_nmb_name(&called, "*SMBSERVER", 0x20); - else - make_nmb_name(&called, desthost, 0x20); - - if (!cli_session_request(cli, &calling, &called)) { - struct nmb_name smbservername; - - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); - - /* - * If the name wasn't *SMBSERVER then - * try with *SMBSERVER if the first name fails. - */ - - if (nmb_name_equal(&called, &smbservername)) { - - /* - * The name used was *SMBSERVER, don't bother with another name. - */ - - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ -with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } - - cli_shutdown(cli); - - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, pdest_ip) || - !cli_session_request(cli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ -name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } - } - - return True; -} diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c new file mode 100644 index 0000000000..e09064bf0f --- /dev/null +++ b/source3/libsmb/clierror.c @@ -0,0 +1,213 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client error handling routines + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + + +extern int DEBUGLEVEL; + + +/***************************************************** + RAP error codes - a small start but will be extended. +*******************************************************/ + +static struct +{ + int err; + char *message; +} rap_errmap[] = +{ + {5, "User has insufficient privilege" }, + {86, "The specified password is invalid" }, + {2226, "Operation only permitted on a Primary Domain Controller" }, + {2242, "The password of this user has expired." }, + {2243, "The password of this user cannot change." }, + {2244, "This password cannot be used now (password history conflict)." }, + {2245, "The password is shorter than required." }, + {2246, "The password of this user is too recent to change."}, + + /* these really shouldn't be here ... */ + {0x80, "Not listening on called name"}, + {0x81, "Not listening for calling name"}, + {0x82, "Called name not present"}, + {0x83, "Called name present, but insufficient resources"}, + + {0, NULL} +}; + +/**************************************************************************** + return a description of an SMB error +****************************************************************************/ +static char *cli_smb_errstr(struct cli_state *cli) +{ + return smb_errstr(cli->inbuf); +} + +/****************************************************** + Return an error message - either an SMB error or a RAP + error. +*******************************************************/ + +char *cli_errstr(struct cli_state *cli) +{ + static fstring error_message; + uint8 errclass; + uint32 errnum; + uint32 nt_rpc_error; + int i; + + /* + * Errors are of three kinds - smb errors, + * dealt with by cli_smb_errstr, NT errors, + * whose code is in cli.nt_error, and rap + * errors, whose error code is in cli.rap_error. + */ + + cli_error(cli, &errclass, &errnum, &nt_rpc_error); + + if (errclass != 0) + { + return cli_smb_errstr(cli); + } + + /* + * Was it an NT error ? + */ + + if (nt_rpc_error) + { + char *nt_msg = get_nt_error_msg(nt_rpc_error); + + if (nt_msg == NULL) + { + slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error); + } + else + { + fstrcpy(error_message, nt_msg); + } + + return error_message; + } + + /* + * Must have been a rap error. + */ + + slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); + + for (i = 0; rap_errmap[i].message != NULL; i++) + { + if (rap_errmap[i].err == cli->rap_error) + { + fstrcpy( error_message, rap_errmap[i].message); + break; + } + } + + return error_message; +} + + +/**************************************************************************** + return error codes for the last packet + returns 0 if there was no error and the best approx of a unix errno + otherwise + + for 32 bit "warnings", a return code of 0 is expected. + +****************************************************************************/ +int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) +{ + int flgs2; + char rcls; + int code; + + if (eclass) *eclass = 0; + if (num ) *num = 0; + if (nt_rpc_error) *nt_rpc_error = 0; + + if(!cli->initialised) + return EINVAL; + + if(!cli->inbuf) + return ENOMEM; + + flgs2 = SVAL(cli->inbuf,smb_flg2); + if (nt_rpc_error) *nt_rpc_error = cli->nt_error; + + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { + /* 32 bit error codes detected */ + uint32 nt_err = IVAL(cli->inbuf,smb_rcls); + if (num) *num = nt_err; + DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); + if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; + + switch (nt_err & 0xFFFFFF) { + case NT_STATUS_ACCESS_VIOLATION: return EACCES; + case NT_STATUS_NO_SUCH_FILE: return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; + case NT_STATUS_INVALID_HANDLE: return EBADF; + case NT_STATUS_NO_MEMORY: return ENOMEM; + case NT_STATUS_ACCESS_DENIED: return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; + case NT_STATUS_SHARING_VIOLATION: return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; + } + + /* for all other cases - a default code */ + return EINVAL; + } + + rcls = CVAL(cli->inbuf,smb_rcls); + code = SVAL(cli->inbuf,smb_err); + if (rcls == 0) return 0; + + if (eclass) *eclass = rcls; + if (num ) *num = code; + + if (rcls == ERRDOS) { + switch (code) { + case ERRbadfile: return ENOENT; + case ERRbadpath: return ENOTDIR; + case ERRnoaccess: return EACCES; + case ERRfilexists: return EEXIST; + case ERRrename: return EEXIST; + case ERRbadshare: return EBUSY; + case ERRlock: return EBUSY; + } + } + if (rcls == ERRSRV) { + switch (code) { + case ERRbadpw: return EPERM; + case ERRaccess: return EACCES; + case ERRnoresource: return ENOMEM; + case ERRinvdevice: return ENODEV; + case ERRinvnetname: return ENODEV; + } + } + /* for other cases */ + return EINVAL; +} + diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c new file mode 100644 index 0000000000..214c30d930 --- /dev/null +++ b/source3/libsmb/clifile.c @@ -0,0 +1,609 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client file operations + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +/**************************************************************************** +rename a file +****************************************************************************/ +BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); + + CVAL(cli->outbuf,smb_com) = SMBmv; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); + + p = smb_buf(cli->outbuf); + *p++ = 4; + pstrcpy(p,fname_src); + unix_to_dos(p,True); + p = skip_string(p,1); + *p++ = 4; + pstrcpy(p,fname_dst); + unix_to_dos(p,True); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** +delete a file +****************************************************************************/ +BOOL cli_unlink(struct cli_state *cli, char *fname) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,1, 2 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBunlink; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + + p = smb_buf(cli->outbuf); + *p++ = 4; + pstrcpy(p,fname); + unix_to_dos(p,True); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** +create a directory +****************************************************************************/ +BOOL cli_mkdir(struct cli_state *cli, char *dname) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,0, 2 + strlen(dname),True); + + CVAL(cli->outbuf,smb_com) = SMBmkdir; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + pstrcpy(p,dname); + unix_to_dos(p,True); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** +remove a directory +****************************************************************************/ +BOOL cli_rmdir(struct cli_state *cli, char *dname) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,0, 2 + strlen(dname),True); + + CVAL(cli->outbuf,smb_com) = SMBrmdir; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + pstrcpy(p,dname); + unix_to_dos(p,True); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + + +/**************************************************************************** +open a file +****************************************************************************/ +int cli_nt_create(struct cli_state *cli, char *fname) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,24,1 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBntcreateX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SIVAL(cli->outbuf,smb_ntcreate_Flags, 0x06); + SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f); + SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); + SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); + SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); + SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); + + p = smb_buf(cli->outbuf); + pstrcpy(p,fname); + unix_to_dos(p,True); + p = skip_string(p,1); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2 + 1); +} + + +/**************************************************************************** +open a file +WARNING: if you open with O_WRONLY then getattrE won't work! +****************************************************************************/ +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) +{ + char *p; + unsigned openfn=0; + unsigned accessmode=0; + + if (flags & O_CREAT) + openfn |= (1<<4); + if (!(flags & O_EXCL)) { + if (flags & O_TRUNC) + openfn |= (1<<1); + else + openfn |= (1<<0); + } + + accessmode = (share_mode<<4); + + if ((flags & O_ACCMODE) == O_RDWR) { + accessmode |= 2; + } else if ((flags & O_ACCMODE) == O_WRONLY) { + accessmode |= 1; + } + +#if defined(O_SYNC) + if ((flags & O_SYNC) == O_SYNC) { + accessmode |= (1<<14); + } +#endif /* O_SYNC */ + + if (share_mode == DENY_FCB) { + accessmode = 0xFF; + } + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,15,1 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBopenX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + SSVAL(cli->outbuf,smb_vwv3,accessmode); + SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv5,0); + SSVAL(cli->outbuf,smb_vwv8,openfn); + + if (cli->use_oplocks) { + /* if using oplocks then ask for a batch oplock via + core and extended methods */ + CVAL(cli->outbuf,smb_flg) |= + FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; + SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); + } + + p = smb_buf(cli->outbuf); + pstrcpy(p,fname); + unix_to_dos(p,True); + p = skip_string(p,1); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2); +} + + + + +/**************************************************************************** + close a file +****************************************************************************/ +BOOL cli_close(struct cli_state *cli, int fnum) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,3,0,True); + + CVAL(cli->outbuf,smb_com) = SMBclose; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SIVALS(cli->outbuf,smb_vwv1,-1); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + +/**************************************************************************** + lock a file +****************************************************************************/ +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, enum brl_type lock_type) +{ + char *p; + int saved_timeout = cli->timeout; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0', smb_size); + + set_message(cli->outbuf,8,10,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0); + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,0); + SSVAL(cli->outbuf,smb_vwv7,1); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + cli_send_smb(cli); + + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + + if (!cli_receive_smb(cli)) { + cli->timeout = saved_timeout; + return False; + } + + cli->timeout = saved_timeout; + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** + unlock a file +****************************************************************************/ +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,8,10,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = 0; + SIVALS(cli->outbuf, smb_vwv4, 0); + SSVAL(cli->outbuf,smb_vwv6,1); + SSVAL(cli->outbuf,smb_vwv7,0); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + + + + +/**************************************************************************** +do a SMBgetattrE call +****************************************************************************/ +BOOL cli_getattrE(struct cli_state *cli, int fd, + uint16 *attr, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,1,0,True); + + CVAL(cli->outbuf,smb_com) = SMBgetattrE; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fd); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + if (size) { + *size = IVAL(cli->inbuf, smb_vwv6); + } + + if (attr) { + *attr = SVAL(cli->inbuf,smb_vwv10); + } + + if (c_time) { + *c_time = make_unix_date3(cli->inbuf+smb_vwv0); + } + + if (a_time) { + *a_time = make_unix_date3(cli->inbuf+smb_vwv2); + } + + if (m_time) { + *m_time = make_unix_date3(cli->inbuf+smb_vwv4); + } + + return True; +} + + +/**************************************************************************** +do a SMBgetatr call +****************************************************************************/ +BOOL cli_getatr(struct cli_state *cli, char *fname, + uint16 *attr, size_t *size, time_t *t) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,0,strlen(fname)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBgetatr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p = 4; + pstrcpy(p+1, fname); + unix_to_dos(p+1,True); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + if (size) { + *size = IVAL(cli->inbuf, smb_vwv3); + } + + if (t) { + *t = make_unix_date3(cli->inbuf+smb_vwv1); + } + + if (attr) { + *attr = SVAL(cli->inbuf,smb_vwv0); + } + + + return True; +} + + +/**************************************************************************** +do a SMBsetatr call +****************************************************************************/ +BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,8,strlen(fname)+4,True); + + CVAL(cli->outbuf,smb_com) = SMBsetatr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0, attr); + put_dos_date3(cli->outbuf,smb_vwv1, t); + + p = smb_buf(cli->outbuf); + *p = 4; + pstrcpy(p+1, fname); + unix_to_dos(p+1,True); + p = skip_string(p,1); + *p = 4; + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + +/**************************************************************************** +check for existance of a dir +****************************************************************************/ +BOOL cli_chkpath(struct cli_state *cli, char *path) +{ + pstring path2; + char *p; + + safe_strcpy(path2,path,sizeof(pstring)); + trim_string(path2,NULL,"\\"); + if (!*path2) *path2 = '\\'; + + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,0,4 + strlen(path2),True); + SCVAL(cli->outbuf,smb_com,SMBchkpth); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + p = smb_buf(cli->outbuf); + *p++ = 4; + safe_strcpy(p,path2,strlen(path2)); + unix_to_dos(p,True); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL, NULL)) return False; + + return True; +} + + + +/**************************************************************************** +query disk space +****************************************************************************/ +BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) +{ + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBdskattr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2); + *total = SVAL(cli->inbuf,smb_vwv0); + *avail = SVAL(cli->inbuf,smb_vwv3); + + return True; +} + diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c new file mode 100644 index 0000000000..4cb477961b --- /dev/null +++ b/source3/libsmb/clilist.c @@ -0,0 +1,303 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client directory list routines + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + + +/**************************************************************************** +interpret a long filename structure - this is mostly guesses at the moment +The length of the structure is returned +The structure of a long filename depends on the info level. 260 is used +by NT and 2 is used by OS/2 +****************************************************************************/ +static int interpret_long_filename(int level,char *p,file_info *finfo) +{ + extern file_info def_finfo; + + if (finfo) + memcpy(finfo,&def_finfo,sizeof(*finfo)); + + switch (level) + { + case 1: /* OS/2 understands this */ + if (finfo) { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + pstrcpy(finfo->name,p+27); + dos_to_unix(finfo->name,True); + } + return(28 + CVAL(p,26)); + + case 2: /* this is what OS/2 uses mostly */ + if (finfo) { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + pstrcpy(finfo->name,p+31); + dos_to_unix(finfo->name,True); + } + return(32 + CVAL(p,30)); + + /* levels 3 and 4 are untested */ + case 3: + if (finfo) { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2(p+8); + finfo->atime = make_unix_date2(p+12); + finfo->mtime = make_unix_date2(p+16); + finfo->size = IVAL(p,20); + finfo->mode = CVAL(p,28); + pstrcpy(finfo->name,p+33); + dos_to_unix(finfo->name,True); + } + return(SVAL(p,4)+4); + + case 4: + if (finfo) { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2(p+8); + finfo->atime = make_unix_date2(p+12); + finfo->mtime = make_unix_date2(p+16); + finfo->size = IVAL(p,20); + finfo->mode = CVAL(p,28); + pstrcpy(finfo->name,p+37); + dos_to_unix(finfo->name,True); + } + return(SVAL(p,4)+4); + + case 260: /* NT uses this, but also accepts 2 */ + if (finfo) { + int ret = SVAL(p,0); + int namelen; + p += 4; /* next entry offset */ + p += 4; /* fileindex */ + + /* these dates appear to arrive in a + weird way. It seems to be localtime + plus the serverzone given in the + initial connect. This is GMT when + DST is not in effect and one hour + from GMT otherwise. Can this really + be right?? + + I suppose this could be called + kludge-GMT. Is is the GMT you get + by using the current DST setting on + a different localtime. It will be + cheap to calculate, I suppose, as + no DST tables will be needed */ + + finfo->ctime = interpret_long_date(p); p += 8; + finfo->atime = interpret_long_date(p); p += 8; + finfo->mtime = interpret_long_date(p); p += 8; p += 8; + finfo->size = IVAL(p,0); p += 8; + p += 8; /* alloc size */ + finfo->mode = CVAL(p,0); p += 4; + namelen = IVAL(p,0); p += 4; + p += 4; /* EA size */ + p += 2; /* short name len? */ + p += 24; /* short name? */ + StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); + dos_to_unix(finfo->name,True); + return(ret); + } + return(SVAL(p,0)); + } + + DEBUG(1,("Unknown long filename format %d\n",level)); + return(SVAL(p,0)); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found + ****************************************************************************/ +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)) +{ + int max_matches = 512; + /* NT uses 260, OS/2 uses 2. Both accept 1. */ + int info_level = cli->protocol 200) { + DEBUG(0,("Error: Looping in FIND_NEXT??\n")); + break; + } + + param_len = 12+strlen(mask)+1; + + if (First) { + setup = TRANSACT2_FINDFIRST; + SSVAL(param,0,attribute); /* attribute */ + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,4+2); /* resume required + close on end */ + SSVAL(param,6,info_level); + SIVAL(param,8,0); + pstrcpy(param+12,mask); + } else { + setup = TRANSACT2_FINDNEXT; + SSVAL(param,0,ff_dir_handle); + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,info_level); + SIVAL(param,6,0); /* ff_resume_key */ + SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ + pstrcpy(param+12,mask); + + DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", + ff_dir_handle,ff_lastname,mask)); + } + + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, 0, + cli->max_xmit /* data, length, max */ + )) { + break; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error(cli, &eclass, &ecode, NULL); + if (eclass != ERRSRV || ecode != ERRerror) break; + msleep(100); + continue; + } + + if (total_received == -1) total_received = 0; + + /* parse out some important return info */ + p = rparam; + if (First) { + ff_dir_handle = SVAL(p,0); + ff_searchcount = SVAL(p,2); + ff_eos = SVAL(p,4); + ff_lastname = SVAL(p,8); + } else { + ff_searchcount = SVAL(p,0); + ff_eos = SVAL(p,2); + ff_lastname = SVAL(p,6); + } + + if (ff_searchcount == 0) + break; + + /* point to the data bytes */ + p = rdata; + + /* we might need the lastname for continuations */ + if (ff_lastname > 0) { + switch(info_level) + { + case 260: + StrnCpy(mask,p+ff_lastname, + MIN(sizeof(mask)-1,data_len-ff_lastname)); + break; + case 1: + pstrcpy(mask,p + ff_lastname + 1); + break; + } + } else { + pstrcpy(mask,""); + } + + dos_to_unix(mask, True); + + /* and add them to the dirlist pool */ + dirlist = Realloc(dirlist,dirlist_len + data_len); + + if (!dirlist) { + DEBUG(0,("Failed to expand dirlist\n")); + break; + } + + /* put in a length for the last entry, to ensure we can chain entries + into the next packet */ + for (p2=p,i=0;i<(ff_searchcount-1);i++) + p2 += interpret_long_filename(info_level,p2,NULL); + SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); + + /* grab the data for later use */ + memcpy(dirlist+dirlist_len,p,data_len); + dirlist_len += data_len; + + total_received += ff_searchcount; + + if (rdata) free(rdata); rdata = NULL; + if (rparam) free(rparam); rparam = NULL; + + DEBUG(3,("received %d entries (eos=%d)\n", + ff_searchcount,ff_eos)); + + if (ff_searchcount > 0) loop_count = 0; + + First = False; + } + + for (p=dirlist,i=0;ioutbuf,'\0',smb_size); + set_message(cli->outbuf,0,0,True); + CVAL(cli->outbuf,smb_com) = SMBsendstrt; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + pstrcpy(p,username); + unix_to_dos(p,True); + p = skip_string(p,1); + *p++ = 4; + pstrcpy(p,host); + unix_to_dos(p,True); + p = skip_string(p,1); + + set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL, NULL)) return False; + + *grp = SVAL(cli->inbuf,smb_vwv0); + + return True; +} + + +/**************************************************************************** +send a message +****************************************************************************/ +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,1,len+3,True); + CVAL(cli->outbuf,smb_com) = SMBsendtxt; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,grp); + + p = smb_buf(cli->outbuf); + *p = 1; + SSVAL(p,1,len); + memcpy(p+3,msg,len); + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL, NULL)) return False; + + return True; +} + +/**************************************************************************** +end a message +****************************************************************************/ +BOOL cli_message_end(struct cli_state *cli, int grp) +{ + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,1,0,True); + CVAL(cli->outbuf,smb_com) = SMBsendend; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + + SSVAL(cli->outbuf,smb_vwv0,grp); + + cli_setup_packet(cli); + + cli_send_smb(cli); + + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_error(cli, NULL, NULL, NULL)) return False; + + return True; +} + diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c new file mode 100644 index 0000000000..eb9c859806 --- /dev/null +++ b/source3/libsmb/cliprint.c @@ -0,0 +1,158 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client print routines + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +/***************************************************************************** + Convert a character pointer in a cli_call_api() response to a form we can use. + This function contains code to prevent core dumps if the server returns + invalid data. +*****************************************************************************/ +static char *fix_char_ptr(unsigned int datap, unsigned int converter, + char *rdata, int rdrcnt) +{ + if (datap == 0) { /* turn NULL pointers into zero length strings */ + return ""; + } else { + unsigned int offset = datap - converter; + + if (offset >= rdrcnt) { + DEBUG(1,("bad char ptr: datap=%u, converter=%u rdrcnt=%d>", + datap, converter, rdrcnt)); + return ""; + } else { + return &rdata[offset]; + } + } +} + + +/**************************************************************************** +call fn() on each entry in a print queue +****************************************************************************/ +int cli_print_queue(struct cli_state *cli, + void (*fn)(struct print_job_info *)) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt, rprcnt; + pstring param; + int result_code=0; + int i = -1; + + memset(param,'\0',sizeof(param)); + + p = param; + SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ + p += 2; + pstrcpy(p,"zWrLeh"); /* parameter description? */ + p = skip_string(p,1); + pstrcpy(p,"WWzWWDDzz"); /* returned data format */ + p = skip_string(p,1); + pstrcpy(p,cli->share); /* name of queue */ + p = skip_string(p,1); + SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ + SSVAL(p,2,1000); /* size of bytes of returned data buffer */ + p += 4; + pstrcpy(p,""); /* subformat */ + p = skip_string(p,1); + + DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) { /* return data, length */ + int converter; + result_code = SVAL(rparam,0); + converter = SVAL(rparam,2); /* conversion factor */ + + if (result_code == 0) { + struct print_job_info job; + + p = rdata; + + for (i = 0; i < SVAL(rparam,4); ++i) { + job.id = SVAL(p,0); + job.priority = SVAL(p,2); + fstrcpy(job.user, + fix_char_ptr(SVAL(p,4), converter, + rdata, rdrcnt)); + job.t = make_unix_date3(p + 12); + job.size = IVAL(p,16); + fstrcpy(job.name,fix_char_ptr(SVAL(p,24), + converter, + rdata, rdrcnt)); + fn(&job); + p += 28; + } + } + } + + /* If any parameters or data were returned, free the storage. */ + if(rparam) free(rparam); + if(rdata) free(rdata); + + return i; +} + +/**************************************************************************** + cancel a print job + ****************************************************************************/ +int cli_printjob_del(struct cli_state *cli, int job) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt, ret = -1; + pstring param; + + memset(param,'\0',sizeof(param)); + + p = param; + SSVAL(p,0,81); /* DosPrintJobDel() */ + p += 2; + pstrcpy(p,"W"); + p = skip_string(p,1); + pstrcpy(p,""); + p = skip_string(p,1); + SSVAL(p,0,job); + p += 2; + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) { /* return data, length */ + ret = SVAL(rparam,0); + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + + return ret; +} + + diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c new file mode 100644 index 0000000000..d918dcff55 --- /dev/null +++ b/source3/libsmb/clirap.c @@ -0,0 +1,591 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client RAP calls + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + + +/**************************************************************************** +Call a remote api on an arbitrary pipe. takes param, data and setup buffers. +****************************************************************************/ +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, + uint16 *setup, uint32 setup_count, uint32 max_setup_count, + char *params, uint32 param_count, uint32 max_param_count, + char *data, uint32 data_count, uint32 max_data_count, + char **rparam, uint32 *rparam_count, + char **rdata, uint32 *rdata_count) +{ + if (pipe_name_len == 0) + pipe_name_len = strlen(pipe_name); + + cli_send_trans(cli, SMBtrans, + pipe_name, pipe_name_len, + 0,0, /* fid, flags */ + setup, setup_count, max_setup_count, + params, param_count, max_param_count, + data, data_count, max_data_count); + + return (cli_receive_trans(cli, SMBtrans, + rparam, (int *)rparam_count, + rdata, (int *)rdata_count)); +} + +/**************************************************************************** +call a remote api +****************************************************************************/ +BOOL cli_api(struct cli_state *cli, + char *param, int prcnt, int mprcnt, + char *data, int drcnt, int mdrcnt, + char **rparam, int *rprcnt, + char **rdata, int *rdrcnt) +{ + cli_send_trans(cli,SMBtrans, + PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ + 0,0, /* fid, flags */ + NULL,0,0, /* Setup, length, max */ + param, prcnt, mprcnt, /* Params, length, max */ + data, drcnt, mdrcnt /* Data, length, max */ + ); + + return (cli_receive_trans(cli,SMBtrans, + rparam, rprcnt, + rdata, rdrcnt)); +} + + +/**************************************************************************** +perform a NetWkstaUserLogon +****************************************************************************/ +BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt; + pstring param; + + memset(param, 0, sizeof(param)); + + /* send a SMBtrans command with api NetWkstaUserLogon */ + p = param; + SSVAL(p,0,132); /* api number */ + p += 2; + pstrcpy(p,"OOWb54WrLh"); + p = skip_string(p,1); + pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); + p = skip_string(p,1); + SSVAL(p,0,1); + p += 2; + pstrcpy(p,user); + strupper(p); + p += 21; + p++; + p += 15; + p++; + pstrcpy(p, workstation); + strupper(p); + p += 16; + SSVAL(p, 0, CLI_BUFFER_SIZE); + p += 2; + SSVAL(p, 0, CLI_BUFFER_SIZE); + p += 2; + + if (cli_api(cli, + param, PTR_DIFF(p,param),1024, /* param, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + cli->rap_error = SVAL(rparam,0); + p = rdata; + + if (cli->rap_error == 0) { + DEBUG(4,("NetWkstaUserLogon success\n")); + cli->privileges = SVAL(p, 24); + fstrcpy(cli->eff_name,p+2); + } else { + DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); + } + } + + if (rparam) + free(rparam); + if (rdata) + free(rdata); + return (cli->rap_error == 0); +} + +/**************************************************************************** +call a NetShareEnum - try and browse available connections on a host +****************************************************************************/ +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt; + pstring param; + int count = -1; + + /* now send a SMBtrans command with api RNetShareEnum */ + p = param; + SSVAL(p,0,0); /* api number */ + p += 2; + pstrcpy(p,"WrLeh"); + p = skip_string(p,1); + pstrcpy(p,"B13BWz"); + p = skip_string(p,1); + SSVAL(p,0,1); + /* + * Win2k needs a *smaller* buffer than 0xFFFF here - + * it returns "out of server memory" with 0xFFFF !!! JRA. + */ + SSVAL(p,2,0xFFE0); + p += 4; + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + int res = SVAL(rparam,0); + int converter=SVAL(rparam,2); + int i; + + if (res == 0 || res == ERRmoredata) { + count=SVAL(rparam,4); + p = rdata; + + for (i=0;i rdrcnt) continue; + + stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + + dos_to_unix(sname, True); + dos_to_unix(cmnt, True); + fn(sname, stype, cmnt); + } + } + } + + if (rparam) + free(rparam); + if (rdata) + free(rdata); + + return(count > 0); +} + + + +/**************************************************************************** +Send a SamOEMChangePassword command +****************************************************************************/ +BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, + const char *old_password) +{ + char param[16+sizeof(fstring)]; + char data[532]; + char *p = param; + fstring upper_case_old_pw; + fstring upper_case_new_pw; + unsigned char old_pw_hash[16]; + unsigned char new_pw_hash[16]; + int data_len; + int param_len = 0; + char *rparam = NULL; + char *rdata = NULL; + int rprcnt, rdrcnt; + pstring dos_new_password; + + if (strlen(user) >= sizeof(fstring)-1) { + DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); + return False; + } + + SSVAL(p,0,214); /* SamOEMChangePassword command. */ + p += 2; + pstrcpy(p, "zsT"); + p = skip_string(p,1); + pstrcpy(p, "B516B16"); + p = skip_string(p,1); + pstrcpy(p,user); + p = skip_string(p,1); + SSVAL(p,0,532); + p += 2; + + param_len = PTR_DIFF(p,param); + + /* + * Get the Lanman hash of the old password, we + * use this as the key to make_oem_passwd_hash(). + */ + memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); + fstrcpy(upper_case_old_pw, old_password); + unix_to_dos(upper_case_old_pw,True); + strupper(upper_case_old_pw); + E_P16((uchar *)upper_case_old_pw, old_pw_hash); + + pstrcpy(dos_new_password, new_password); + unix_to_dos(dos_new_password, True); + + if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) + return False; + + /* + * Now place the old password hash in the data. + */ + memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); + fstrcpy(upper_case_new_pw, new_password); + unix_to_dos(upper_case_new_pw,True); + strupper(upper_case_new_pw); + + E_P16((uchar *)upper_case_new_pw, new_pw_hash); + + E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); + + data_len = 532; + + if (cli_send_trans(cli,SMBtrans, + PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ + 0,0, /* fid, flags */ + NULL,0,0, /* setup, length, max */ + param,param_len,2, /* param, length, max */ + data,data_len,0 /* data, length, max */ + ) == False) { + DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", + user )); + return False; + } + + if (cli_receive_trans(cli,SMBtrans, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { + if (rparam) + cli->rap_error = SVAL(rparam,0); + } + + if (rparam) + free(rparam); + if (rdata) + free(rdata); + + return (cli->rap_error == 0); +} + + +/**************************************************************************** +send a qpathinfo call +****************************************************************************/ +BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + size_t *size, uint16 *mode) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + int count=8; + BOOL ret; + time_t (*date_fn)(void *); + + param_len = strlen(fname) + 7; + + memset(param, 0, param_len); + SSVAL(param, 0, SMB_INFO_STANDARD); + pstrcpy(¶m[6], fname); + unix_to_dos(¶m[6],True); + + do { + ret = (cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + ) && + cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)); + if (!ret) { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error(cli, &eclass, &ecode, NULL); + if (eclass != ERRSRV || ecode != ERRerror) break; + msleep(100); + } + } while (count-- && ret==False); + + if (!ret || !rdata || data_len < 22) { + return False; + } + + if (cli->win95) { + date_fn = make_unix_date; + } else { + date_fn = make_unix_date2; + } + + if (c_time) { + *c_time = date_fn(rdata+0); + } + if (a_time) { + *a_time = date_fn(rdata+4); + } + if (m_time) { + *m_time = date_fn(rdata+8); + } + if (size) { + *size = IVAL(rdata, 12); + } + if (mode) { + *mode = SVAL(rdata,l1_attrFile); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + +/**************************************************************************** +send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level +****************************************************************************/ +BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, size_t *size, uint16 *mode, + SMB_INO_T *ino) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + param_len = strlen(fname) + 7; + + memset(param, 0, param_len); + SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); + pstrcpy(¶m[6], fname); + unix_to_dos(¶m[6],True); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + if (!rdata || data_len < 22) { + return False; + } + + if (c_time) { + *c_time = interpret_long_date(rdata+0) - cli->serverzone; + } + if (a_time) { + *a_time = interpret_long_date(rdata+8) - cli->serverzone; + } + if (m_time) { + *m_time = interpret_long_date(rdata+16) - cli->serverzone; + } + if (w_time) { + *w_time = interpret_long_date(rdata+24) - cli->serverzone; + } + if (mode) { + *mode = SVAL(rdata, 32); + } + if (size) { + *size = IVAL(rdata, 48); + } + if (ino) { + *ino = IVAL(rdata, 64); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + + +/**************************************************************************** +send a qfileinfo call +****************************************************************************/ +BOOL cli_qfileinfo(struct cli_state *cli, int fnum, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + time_t *w_time, SMB_INO_T *ino) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QFILEINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + /* if its a win95 server then fail this - win95 totally screws it + up */ + if (cli->win95) return False; + + param_len = 4; + + memset(param, 0, param_len); + SSVAL(param, 0, fnum); + SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + if (!rdata || data_len < 68) { + return False; + } + + if (c_time) { + *c_time = interpret_long_date(rdata+0) - cli->serverzone; + } + if (a_time) { + *a_time = interpret_long_date(rdata+8) - cli->serverzone; + } + if (m_time) { + *m_time = interpret_long_date(rdata+16) - cli->serverzone; + } + if (w_time) { + *w_time = interpret_long_date(rdata+24) - cli->serverzone; + } + if (mode) { + *mode = SVAL(rdata, 32); + } + if (size) { + *size = IVAL(rdata, 48); + } + if (ino) { + *ino = IVAL(rdata, 64); + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} + diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c new file mode 100644 index 0000000000..8012c02a8f --- /dev/null +++ b/source3/libsmb/clireadwrite.c @@ -0,0 +1,273 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client file read/write routines + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +/**************************************************************************** +issue a single SMBread and don't wait for a reply +****************************************************************************/ +static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, + size_t size, int i) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + SSVAL(cli->outbuf,smb_vwv5,size); + SSVAL(cli->outbuf,smb_vwv6,size); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + cli_send_smb(cli); +} + +/**************************************************************************** + read from a file +****************************************************************************/ +size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +{ + char *p; + int total = -1; + int issued=0; + int received=0; +/* + * There is a problem in this code when mpx is more than one. + * for some reason files can get corrupted when being read. + * Until we understand this fully I am serializing reads (one + * read/one reply) for now. JRA. + */ +#if 0 + int mpx = MAX(cli->max_mux-1, 1); +#else + int mpx = 1; +#endif + int block = (cli->max_xmit - (smb_size+32)) & ~1023; + int mid; + int blocks = (size + (block-1)) / block; + + if (size == 0) return 0; + + while (received < blocks) { + int size2; + + while (issued - received < mpx && issued < blocks) { + int size1 = MIN(block, size-issued*block); + cli_issue_read(cli, fnum, offset+issued*block, size1, issued); + issued++; + } + + if (!cli_receive_smb(cli)) { + return total; + } + + received++; + mid = SVAL(cli->inbuf, smb_mid) - cli->mid; + size2 = SVAL(cli->inbuf, smb_vwv5); + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + blocks = MIN(blocks, mid-1); + continue; + } + + if (size2 <= 0) { + blocks = MIN(blocks, mid-1); + /* this distinguishes EOF from an error */ + total = MAX(total, 0); + continue; + } + + if (size2 > block) { + DEBUG(0,("server returned more than we wanted!\n")); + return -1; + } + if (mid >= issued) { + DEBUG(0,("invalid mid from server!\n")); + return -1; + } + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + + memcpy(buf+mid*block, p, size2); + + total = MAX(total, mid*block + size2); + } + + while (received < issued) { + cli_receive_smb(cli); + received++; + } + + return total; +} + + +/**************************************************************************** +issue a single SMBwrite and don't wait for a reply +****************************************************************************/ +static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, + size_t size, int i) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,12,size,True); + + CVAL(cli->outbuf,smb_com) = SMBwriteX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + + SIVAL(cli->outbuf,smb_vwv3,offset); + SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); + SSVAL(cli->outbuf,smb_vwv7,mode); + + SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_ALL(mode, 0x0008) ? size : 0); + SSVAL(cli->outbuf,smb_vwv10,size); + SSVAL(cli->outbuf,smb_vwv11, + smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + memcpy(p, buf, size); + + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + show_msg(cli->outbuf); + cli_send_smb(cli); +} + +/**************************************************************************** + write to a file + write_mode: 0x0001 disallow write cacheing + 0x0002 return bytes remaining + 0x0004 use raw named pipe protocol + 0x0008 start of message mode named pipe protocol +****************************************************************************/ +ssize_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + char *buf, off_t offset, size_t size) +{ + int bwritten = 0; + int issued = 0; + int received = 0; + int mpx = MAX(cli->max_mux-1, 1); + int block = (cli->max_xmit - (smb_size+32)) & ~1023; + int blocks = (size + (block-1)) / block; + + while (received < blocks) { + + while ((issued - received < mpx) && (issued < blocks)) + { + int bsent = issued * block; + int size1 = MIN(block, size - bsent); + + cli_issue_write(cli, fnum, offset + bsent, + write_mode, + buf + bsent, + size1, issued); + issued++; + } + + if (!cli_receive_smb(cli)) + { + return bwritten; + } + + received++; + + if (CVAL(cli->inbuf,smb_rcls) != 0) + { + break; + } + + bwritten += SVAL(cli->inbuf, smb_vwv2); + } + + while (received < issued && cli_receive_smb(cli)) + { + received++; + } + + return bwritten; +} + + +/**************************************************************************** + write to a file using a SMBwrite and not bypassing 0 byte writes +****************************************************************************/ +ssize_t cli_smbwrite(struct cli_state *cli, + int fnum, char *buf, off_t offset, size_t size1) +{ + char *p; + ssize_t total = 0; + + do { + size_t size = MIN(size1, cli->max_xmit - 48); + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,5, 3 + size,True); + + CVAL(cli->outbuf,smb_com) = SMBwrite; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SSVAL(cli->outbuf,smb_vwv1,size); + SIVAL(cli->outbuf,smb_vwv2,offset); + SSVAL(cli->outbuf,smb_vwv4,0); + + p = smb_buf(cli->outbuf); + *p++ = 1; + SSVAL(p, 0, size); + memcpy(p+2, buf, size); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + size = SVAL(cli->inbuf,smb_vwv0); + if (size == 0) break; + + size1 -= size; + total += size; + } while (size1); + + return total; +} + diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c new file mode 100644 index 0000000000..76758a0dd6 --- /dev/null +++ b/source3/libsmb/clitrans.c @@ -0,0 +1,233 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client transaction calls + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + + +/**************************************************************************** + send a SMB trans or trans2 request + ****************************************************************************/ +BOOL cli_send_trans(struct cli_state *cli, int trans, + char *name, int pipe_name_len, + int fid, int flags, + uint16 *setup, int lsetup, int msetup, + char *param, int lparam, int mparam, + char *data, int ldata, int mdata) +{ + int i; + int this_ldata,this_lparam; + int tot_data=0,tot_param=0; + char *outdata,*outparam; + char *p; + + this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ + this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); + + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,14+lsetup,0,True); + CVAL(cli->outbuf,smb_com) = trans; + SSVAL(cli->outbuf,smb_tid, cli->cnum); + cli_setup_packet(cli); + + outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len+1 : 3); + outdata = outparam+this_lparam; + + /* primary request */ + SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ + SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ + SSVAL(cli->outbuf,smb_mprcnt,mparam); /* mprcnt */ + SSVAL(cli->outbuf,smb_mdrcnt,mdata); /* mdrcnt */ + SCVAL(cli->outbuf,smb_msrcnt,msetup); /* msrcnt */ + SSVAL(cli->outbuf,smb_flags,flags); /* flags */ + SIVAL(cli->outbuf,smb_timeout,0); /* timeout */ + SSVAL(cli->outbuf,smb_pscnt,this_lparam); /* pscnt */ + SSVAL(cli->outbuf,smb_psoff,smb_offset(outparam,cli->outbuf)); /* psoff */ + SSVAL(cli->outbuf,smb_dscnt,this_ldata); /* dscnt */ + SSVAL(cli->outbuf,smb_dsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ + SCVAL(cli->outbuf,smb_suwcnt,lsetup); /* suwcnt */ + for (i=0;ioutbuf,smb_setup+i*2,setup[i]); + p = smb_buf(cli->outbuf); + if (trans==SMBtrans) { + memcpy(p,name, pipe_name_len + 1); /* name[] */ + } else { + *p++ = 0; /* put in a null smb_name */ + *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ + } + if (this_lparam) /* param[] */ + memcpy(outparam,param,this_lparam); + if (this_ldata) /* data[] */ + memcpy(outdata,data,this_ldata); + set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ + PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + + show_msg(cli->outbuf); + cli_send_smb(cli); + + if (this_ldata < ldata || this_lparam < lparam) { + /* receive interim response */ + if (!cli_receive_smb(cli) || + CVAL(cli->inbuf,smb_rcls) != 0) { + return(False); + } + + tot_data = this_ldata; + tot_param = this_lparam; + + while (tot_data < ldata || tot_param < lparam) { + this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ + this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); + + set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); + CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2; + + outparam = smb_buf(cli->outbuf); + outdata = outparam+this_lparam; + + /* secondary request */ + SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ + SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ + SSVAL(cli->outbuf,smb_spscnt,this_lparam); /* pscnt */ + SSVAL(cli->outbuf,smb_spsoff,smb_offset(outparam,cli->outbuf)); /* psoff */ + SSVAL(cli->outbuf,smb_spsdisp,tot_param); /* psdisp */ + SSVAL(cli->outbuf,smb_sdscnt,this_ldata); /* dscnt */ + SSVAL(cli->outbuf,smb_sdsoff,smb_offset(outdata,cli->outbuf)); /* dsoff */ + SSVAL(cli->outbuf,smb_sdsdisp,tot_data); /* dsdisp */ + if (trans==SMBtrans2) + SSVALS(cli->outbuf,smb_sfid,fid); /* fid */ + if (this_lparam) /* param[] */ + memcpy(outparam,param+tot_param,this_lparam); + if (this_ldata) /* data[] */ + memcpy(outdata,data+tot_data,this_ldata); + set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ + PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + + show_msg(cli->outbuf); + cli_send_smb(cli); + + tot_data += this_ldata; + tot_param += this_lparam; + } + } + + return(True); +} + + +/**************************************************************************** + receive a SMB trans or trans2 response allocating the necessary memory + ****************************************************************************/ +BOOL cli_receive_trans(struct cli_state *cli,int trans, + char **param, int *param_len, + char **data, int *data_len) +{ + int total_data=0; + int total_param=0; + int this_data,this_param; + uint8 eclass; + uint32 ecode; + + *data_len = *param_len = 0; + + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + /* sanity check */ + if (CVAL(cli->inbuf,smb_com) != trans) { + DEBUG(0,("Expected %s response, got command 0x%02x\n", + trans==SMBtrans?"SMBtrans":"SMBtrans2", + CVAL(cli->inbuf,smb_com))); + return(False); + } + + /* + * An NT RPC pipe call can return ERRDOS, ERRmoredata + * to a trans call. This is not an error and should not + * be treated as such. + */ + + if (cli_error(cli, &eclass, &ecode, NULL)) + { + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return(False); + } + + /* parse out the lengths */ + total_data = SVAL(cli->inbuf,smb_tdrcnt); + total_param = SVAL(cli->inbuf,smb_tprcnt); + + /* allocate it */ + *data = Realloc(*data,total_data); + *param = Realloc(*param,total_param); + + while (1) { + this_data = SVAL(cli->inbuf,smb_drcnt); + this_param = SVAL(cli->inbuf,smb_prcnt); + + if (this_data + *data_len > total_data || + this_param + *param_len > total_param) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) + memcpy(*data + SVAL(cli->inbuf,smb_drdisp), + smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), + this_data); + if (this_param) + memcpy(*param + SVAL(cli->inbuf,smb_prdisp), + smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), + this_param); + *data_len += this_data; + *param_len += this_param; + + /* parse out the total lengths again - they can shrink! */ + total_data = SVAL(cli->inbuf,smb_tdrcnt); + total_param = SVAL(cli->inbuf,smb_tprcnt); + + if (total_data <= *data_len && total_param <= *param_len) + break; + + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + /* sanity check */ + if (CVAL(cli->inbuf,smb_com) != trans) { + DEBUG(0,("Expected %s response, got command 0x%02x\n", + trans==SMBtrans?"SMBtrans":"SMBtrans2", + CVAL(cli->inbuf,smb_com))); + return(False); + } + if (cli_error(cli, &eclass, &ecode, NULL)) + { + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return(False); + } + } + + return(True); +} -- cgit From 00e3fe132476fcaed0f4b9bbe74b0a6559c39df0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Apr 2000 14:06:57 +0000 Subject: moved trans2.h and nterr.h into includes.h with all our other includes (This used to be commit d7cd7c88fdabb01d9e40ae8a657737907a21ac37) --- source3/libsmb/nterr.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index d2f9335000..ef3fb4b8ba 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -1,7 +1,6 @@ /* NT error codes. please read nterr.h */ #include "includes.h" -#include "nterr.h" typedef struct { -- cgit From 71e7974f3f847759ba6f844ea7f482786cc5db02 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Apr 2000 04:45:16 +0000 Subject: YIPEE!!!!! We finally have a perfect emulation of Microsoft wildcard matching. The routine ms_fnmatch() does wildcard matching with all MS wildcards (including the unicode wildcards), and masktest against a NT4 workstation with hundreds of thousands of random exmaples has not found a single error. amazingly it is only about 60 lines of code, but it has taken us years to get it right. I didn't sleep much last night :) (This used to be commit cc9e007cdfdd300189f89e2a55e4234e47fa842d) --- source3/libsmb/clilist.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4cb477961b..f2e42be523 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -123,6 +123,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) namelen = IVAL(p,0); p += 4; p += 4; /* EA size */ p += 2; /* short name len? */ + unistr_to_ascii(finfo->short_name, p, 12); p += 24; /* short name? */ StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); dos_to_unix(finfo->name,True); -- cgit From 23c0cb01ca5b8bafb3ed9f31c3aa672957c2af86 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Apr 2000 12:34:26 +0000 Subject: added cli_list_old() to allow for old style directory listing from masktest (This used to be commit 8a5c8cfa0ede1d119bf9013e321a497beefd4dda) --- source3/libsmb/clilist.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f2e42be523..74b908ae58 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -160,8 +160,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - int param_len, data_len; - + int param_len, data_len; uint16 setup; pstring param; @@ -302,3 +301,146 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, return(total_received); } + + +/**************************************************************************** +interpret a short filename structure +The length of the structure is returned +****************************************************************************/ +static int interpret_short_filename(char *p,file_info *finfo) +{ + extern file_info def_finfo; + + *finfo = def_finfo; + + finfo->mode = CVAL(p,21); + + /* this date is converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date(p+22); + finfo->mtime = finfo->atime = finfo->ctime; + finfo->size = IVAL(p,26); + pstrcpy(finfo->name,p+30); + if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) + fstrcpy(finfo->short_name,finfo->name); + + return(DIR_STRUCT_SIZE); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found + this uses the old SMBsearch interface. It is needed for testing Samba, + but should otherwise not be used + ****************************************************************************/ +int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)) +{ + char *p; + int received = 0; + BOOL first = True; + char status[21]; + int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; + int num_received = 0; + int i; + char *dirlist = NULL; + pstring mask; + + ZERO_ARRAY(status); + + pstrcpy(mask,Mask); + + while (1) { + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + if (first) + set_message(cli->outbuf,2,5 + strlen(mask),True); + else + set_message(cli->outbuf,2,5 + 21,True); + + CVAL(cli->outbuf,smb_com) = SMBffirst; + + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,num_asked); + SSVAL(cli->outbuf,smb_vwv1,attribute); + + p = smb_buf(cli->outbuf); + *p++ = 4; + + if (first) + pstrcpy(p,mask); + else + pstrcpy(p,""); + p += strlen(p) + 1; + + *p++ = 5; + if (first) { + SSVAL(p,0,0); + } else { + SSVAL(p,0,21); + p += 2; + memcpy(p,status,21); + } + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) break; + + received = SVAL(cli->inbuf,smb_vwv0); + if (received <= 0) break; + + first = False; + + dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + + if (!dirlist) + return 0; + + p = smb_buf(cli->inbuf) + 3; + + memcpy(dirlist+num_received*DIR_STRUCT_SIZE, + p,received*DIR_STRUCT_SIZE); + + memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); + + num_received += received; + + if (CVAL(cli->inbuf,smb_rcls) != 0) break; + } + + if (!first) { + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,0,6,True); + CVAL(cli->outbuf,smb_com) = SMBfclose; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + + pstrcpy(p,""); + p += strlen(p) + 1; + + *p++ = 5; + SSVAL(p,0,21); + p += 2; + memcpy(p,status,21); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); + } + } + + for (p=dirlist,i=0;i Date: Sun, 30 Apr 2000 14:26:59 +0000 Subject: - get the findclose code right - handle broken NT response to trans2 findfirst (This used to be commit 64f91a7a98fe9aaf176e665677e751e4e03d4c3d) --- source3/libsmb/clilist.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 74b908ae58..4374973fa9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -95,7 +95,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) case 260: /* NT uses this, but also accepts 2 */ if (finfo) { int ret = SVAL(p,0); - int namelen; + int namelen, slen; p += 4; /* next entry offset */ p += 4; /* fileindex */ @@ -122,8 +122,15 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; p += 4; /* EA size */ - p += 2; /* short name len? */ - unistr_to_ascii(finfo->short_name, p, 12); + slen = SVAL(p, 0); + p += 2; + if (p[1] == 0 && slen > 1) { + /* NT has stuffed up again */ + unistr_to_ascii(finfo->short_name, p, 24); + } else { + strncpy(finfo->short_name, p, 12); + finfo->short_name[12] = 0; + } p += 24; /* short name? */ StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); dos_to_unix(finfo->name,True); @@ -413,25 +420,26 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0,6,True); + set_message(cli->outbuf,2,5 + 21,True); CVAL(cli->outbuf,smb_com) = SMBfclose; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); + SSVAL(cli->outbuf, smb_vwv0, 0); /* find count? */ + SSVAL(cli->outbuf, smb_vwv1, attribute); + p = smb_buf(cli->outbuf); *p++ = 4; - - pstrcpy(p,""); + fstrcpy(p, ""); p += strlen(p) + 1; - *p++ = 5; - SSVAL(p,0,21); + SSVAL(p, 0, 21); p += 2; memcpy(p,status,21); cli_send_smb(cli); if (!cli_receive_smb(cli)) { - DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); + DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); } } -- cgit From 2fb2ae187d34adb7621608c82ea793e2d0bb41eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Apr 2000 14:58:13 +0000 Subject: fixed parsing of broken NT short name (This used to be commit 9e4b3529455840f11940136dd55c641d89b46961) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4374973fa9..f3e4033539 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -126,7 +126,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) p += 2; if (p[1] == 0 && slen > 1) { /* NT has stuffed up again */ - unistr_to_ascii(finfo->short_name, p, 24); + unistr_to_ascii(finfo->short_name, p, slen/2); } else { strncpy(finfo->short_name, p, 12); finfo->short_name[12] = 0; -- cgit From 05cb3464f972d336dcb82ca332bf9b2617646070 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Apr 2000 15:13:15 +0000 Subject: - added some error checking - removed the VTP hook in smbd (This used to be commit 09355fcd50e6c9c0c81e5f70ab9b7ff88aa897bf) --- source3/libsmb/clirap.c | 130 ++++++++++++++++++++++++------------------------ 1 file changed, 66 insertions(+), 64 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index d918dcff55..5e7e9427f6 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -115,7 +115,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { - cli->rap_error = SVAL(rparam,0); + cli->rap_error = rparam? SVAL(rparam,0) : -1; p = rdata; if (cli->rap_error == 0) { @@ -139,65 +139,66 @@ call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) { - char *rparam = NULL; - char *rdata = NULL; - char *p; - int rdrcnt,rprcnt; - pstring param; - int count = -1; - - /* now send a SMBtrans command with api RNetShareEnum */ - p = param; - SSVAL(p,0,0); /* api number */ - p += 2; - pstrcpy(p,"WrLeh"); - p = skip_string(p,1); - pstrcpy(p,"B13BWz"); - p = skip_string(p,1); - SSVAL(p,0,1); - /* - * Win2k needs a *smaller* buffer than 0xFFFF here - - * it returns "out of server memory" with 0xFFFF !!! JRA. - */ - SSVAL(p,2,0xFFE0); - p += 4; - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) /* return data, length */ - { - int res = SVAL(rparam,0); - int converter=SVAL(rparam,2); - int i; - - if (res == 0 || res == ERRmoredata) { - count=SVAL(rparam,4); - p = rdata; - - for (i=0;i 0); } -- cgit From 693ffb8466ada58ecc59fde754ba79fc6f51528d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 May 2000 02:23:41 +0000 Subject: Added sys_fork() and sys_getpid() functions to stop the overhead of doing a system call every time we want to just get our pid. Jeremy. (This used to be commit 148628b616b5c29ba6340d65fc3ddbcabba6e67a) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/namequery.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a3a2483bd5..32564aaf82 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -172,7 +172,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->port = 0; cli->fd = -1; cli->cnum = -1; - cli->pid = (uint16)getpid(); + cli->pid = (uint16)sys_getpid(); cli->mid = 1; cli->vuid = UID_FIELD_INVALID; cli->protocol = PROTOCOL_NT1; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 500a2ff94f..0db1e367dc 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -35,7 +35,7 @@ static int generate_trn_id(void) static int trn_id; if (trn_id == 0) { - srandom(getpid()); + srandom(sys_getpid()); } trn_id = random(); -- cgit From ddc9b8b40642c90fe7c34b088eae4f8075f4033a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 09:49:55 +0000 Subject: more merging it is now at the stage that winbindd can compile in the head branch, but not link (This used to be commit d178c00aae77710ae6ff20a7f54a30e3bd8232bb) --- source3/libsmb/clierror.c | 2 +- source3/libsmb/nterr.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index e09064bf0f..78a7c9d451 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -163,7 +163,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; - switch (nt_err & 0xFFFFFF) { + switch (nt_err) { case NT_STATUS_ACCESS_VIOLATION: return EACCES; case NT_STATUS_NO_SUCH_FILE: return ENOENT; case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index ef3fb4b8ba..3f19a66941 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -526,11 +526,9 @@ char *get_nt_error_msg(uint32 nt_code) pstrcpy(msg, "Unknown NT error"); - nt_code &= 0xFFFF; - while (nt_errs[idx].nt_errstr != NULL) { - if (nt_errs[idx].nt_errcode == nt_code) + if ((nt_errs[idx].nt_errcode & 0xFFFFFF) == (nt_code & 0xFFFFFF)) { pstrcpy(msg, nt_errs[idx].nt_errstr); return msg; -- cgit From 5dfa33bf715d850bfd0530c6ff3d0496195126a1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 May 2000 18:27:58 +0000 Subject: Fix from David Collier-Brown - sys_select return was not being checked. Jeremy. (This used to be commit a9c4371a2dc27e499ad6d35af1b598a4af0026c8) --- source3/libsmb/nmblib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index dae7cf087a..f8f38fe44d 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -966,7 +966,11 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - sys_select(fd+1,&fds,&timeout); + if (sys_select(fd+1,&fds,&timeout) == -1) { + /* errno should be EBADF or EINVAL. */ + DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); + return NULL; + } if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); -- cgit From 2c978311dcb869b91a7787feba7f537056f4b90d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 May 2000 18:53:03 +0000 Subject: Ho hum - forgot timeout case. Jeremy. (This used to be commit 597ecd724e0d4ac7c19eb9fb85b3c9910bbfb114) --- source3/libsmb/nmblib.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index f8f38fe44d..d4955fa6a6 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -960,18 +960,22 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) { fd_set fds; struct timeval timeout; + int ret; FD_ZERO(&fds); FD_SET(fd,&fds); timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - if (sys_select(fd+1,&fds,&timeout) == -1) { + if ((ret = sys_select(fd+1,&fds,&timeout)) == -1) { /* errno should be EBADF or EINVAL. */ DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); return NULL; } + if (ret == 0) /* timeout */ + return NULL; + if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); -- cgit From 612738a9e14b6fb6a2687993d6416bbe6c3ea94d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 May 2000 22:47:09 +0000 Subject: lib/util_unistr.c: libsmb/clilist.c: rpc_server/srv_spoolss_nt.c: smbd/trans2.c: Changed unistr_to_ascii to unistr_to_dos - do codepage conversion. msdfs/msdfs.c: Removed stub unistr_to_dos. libsmb/pwd_cache.c: Removed obfuscation functions as they don't do anything and don't add any security. Jeremy. (This used to be commit 1ed146467e764e6a81d8f78cd58fb5765ebf5d21) --- source3/libsmb/clilist.c | 2 +- source3/libsmb/pwd_cache.c | 48 ---------------------------------------------- 2 files changed, 1 insertion(+), 49 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f3e4033539..2e904e06b7 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -126,7 +126,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) p += 2; if (p[1] == 0 && slen > 1) { /* NT has stuffed up again */ - unistr_to_ascii(finfo->short_name, p, slen/2); + unistr_to_dos(finfo->short_name, p, slen/2); } else { strncpy(finfo->short_name, p, 12); finfo->short_name[12] = 0; diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 4f02c42efb..1c5f8b5176 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -40,47 +40,20 @@ void pwd_init(struct pwd_info *pwd) pwd->crypted = False; } -/**************************************************************************** -de-obfuscates a password -****************************************************************************/ -static void pwd_deobfuscate(struct pwd_info *pwd) -{ -} - -/**************************************************************************** -obfuscates a password -****************************************************************************/ -static void pwd_obfuscate(struct pwd_info *pwd) -{ -} - -/**************************************************************************** -sets the obfuscation key info -****************************************************************************/ -void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key) -{ -} - /**************************************************************************** compares two passwords. hmm, not as trivial as expected. hmm. ****************************************************************************/ BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) { - pwd_deobfuscate(pwd1); - pwd_deobfuscate(pwd2); if (pwd1->cleartext && pwd2->cleartext) { if (strequal(pwd1->password, pwd2->password)) { - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); return True; } } if (pwd1->null_pwd && pwd2->null_pwd) { - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); return True; } @@ -94,8 +67,6 @@ BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) #endif if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) { - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); return True; } #ifdef DEBUG_PASSWORD @@ -105,13 +76,9 @@ BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) #endif if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) { - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); return True; } } - pwd_obfuscate(pwd1); - pwd_obfuscate(pwd2); return False; } @@ -164,8 +131,6 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) pwd->cleartext = True; pwd->null_pwd = False; pwd->crypted = False; - - pwd_obfuscate(pwd); } /**************************************************************************** @@ -173,7 +138,6 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) ****************************************************************************/ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) { - pwd_deobfuscate(pwd); if (pwd->cleartext) { fstrcpy(clr, pwd->password); @@ -183,7 +147,6 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) { clr[0] = 0; } - pwd_obfuscate(pwd); } /**************************************************************************** @@ -214,8 +177,6 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) pwd->null_pwd = False; pwd->cleartext = False; pwd->crypted = False; - - pwd_obfuscate(pwd); } /**************************************************************************** @@ -223,7 +184,6 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) ****************************************************************************/ void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { - pwd_deobfuscate(pwd); if (lm_pwd != NULL) { memcpy(lm_pwd, pwd->smb_lm_pwd, 16); @@ -232,7 +192,6 @@ void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { memcpy(nt_pwd, pwd->smb_nt_pwd, 16); } - pwd_obfuscate(pwd); } /**************************************************************************** @@ -251,8 +210,6 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) pwd->null_pwd = False; pwd->cleartext = False; pwd->crypted = False; - - pwd_obfuscate(pwd); } /**************************************************************************** @@ -260,7 +217,6 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) ****************************************************************************/ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) { - pwd_deobfuscate(pwd); #ifdef DEBUG_PASSWORD DEBUG(100,("client cryptkey: ")); @@ -286,8 +242,6 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) #endif pwd->crypted = True; - - pwd_obfuscate(pwd); } /**************************************************************************** @@ -295,7 +249,6 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) ****************************************************************************/ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) { - pwd_deobfuscate(pwd); if (lm_owf != NULL) { memcpy(lm_owf, pwd->smb_lm_owf, 24); @@ -304,5 +257,4 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) { memcpy(nt_owf, pwd->smb_nt_owf, 24); } - pwd_obfuscate(pwd); } -- cgit From f0080e5a3979fac94d6668cf6ee9d9f61302839c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Jun 2000 17:01:34 +0000 Subject: Getting back to a compilable state (not there yet but close). Added patches for random -> sys_random. Added set_effective_xxx patches for AFS code. Memory allocation changes in spoolss code. Jeremy. (This used to be commit c2099cfb033c2cdb6035f4f7f50ce21b98e1584d) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0db1e367dc..5dadd4d474 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -35,10 +35,10 @@ static int generate_trn_id(void) static int trn_id; if (trn_id == 0) { - srandom(sys_getpid()); + sys_srandom(sys_getpid()); } - trn_id = random(); + trn_id = sys_random(); return trn_id % (unsigned)0x7FFF; } -- cgit From 8843a6379d7c1cf59f0f3673cbc567b09994b7d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 11 Jun 2000 05:57:58 +0000 Subject: Linux kernel oplocks now seem to work, but need a _lot_ of testing I had to modify sys_select() to not loop on EINTR. I added a wrapper called sys_select_intr() which gives the old behaviour. (This used to be commit b28cc4163bc2faaa80c5782fc02c8f03c410cdeb) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d4955fa6a6..e290ee5d4f 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -967,7 +967,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - if ((ret = sys_select(fd+1,&fds,&timeout)) == -1) { + if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) { /* errno should be EBADF or EINVAL. */ DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); return NULL; -- cgit From 098b7b378c72632d8c3df0b795ac1e4c5dbfb04a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 3 Jul 2000 04:24:31 +0000 Subject: first pass at merging rpcclient from TNG to HEAD. You can get a semi-connection and a rpcclient prompt, but no functionality there yet. Will be a few more days on that. These files changed only with the addition of some support functions from TNG --jerry (This used to be commit a04ea15f723e559db3c60bed03318cc7be851f69) --- source3/libsmb/clientgen.c | 17 +++++++++++++ source3/libsmb/namequery.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/nterr.c | 22 +++++++++++----- source3/libsmb/pwd_cache.c | 9 +++++++ 4 files changed, 105 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 32564aaf82..c6f24c5e80 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -150,6 +150,23 @@ static void cli_process_oplock(struct cli_state *cli) cli->outbuf = oldbuf; } +/**************************************************************************** +initialise a client structure +****************************************************************************/ +void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) +{ + /* copy_nt_creds(&cli->usr, usr); */ + safe_strcpy(cli->domain , usr->domain , sizeof(usr->domain )-1); + safe_strcpy(cli->user_name, usr->user_name, sizeof(usr->user_name)-1); + memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); + cli->ntlmssp_flags = usr->ntlmssp_flags; + cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; + + DEBUG(10,("cli_init_creds: user %s domain %s flgs: %x\nntlmssp_cli_flgs:%x\n", + cli->user_name, cli->domain, + cli->ntlmssp_flags,cli->ntlmssp_cli_flgs)); +} + /**************************************************************************** initialise a client structure diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 5dadd4d474..8fb607bd8f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -593,6 +593,23 @@ static BOOL resolve_hosts(const char *name, return False; } +/******************************************************** + Resolve a name into an IP address. Use this function if + the string is either an IP address, DNS or host name + or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. +*********************************************************/ +BOOL is_ip_address(const char *name) +{ + int i; + for (i=0; name[i]; i++) + if (!(isdigit((int)name[i]) || name[i] == '.')) + return False; + + return True; +} + + /******************************************************** Internal interface to resolve a name into an IP address. Use this function if the string is either an IP address, DNS @@ -686,6 +703,52 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) return False; } + +/******************************************************** + resolve a name of format \\server_name or \\ipaddress + into a name. also, cut the \\ from the front for us. +*********************************************************/ + +BOOL resolve_srv_name(const char* srv_name, fstring dest_host, + struct in_addr *ip) +{ + BOOL ret; + const char *sv_name = srv_name; + + DEBUG(10,("resolve_srv_name: %s\n", srv_name)); + + if (srv_name == NULL || strequal("\\\\.", srv_name)) + { + extern pstring global_myname; + fstrcpy(dest_host, global_myname); + ip = interpret_addr2("127.0.0.1"); + return True; + } + + if (strnequal("\\\\", srv_name, 2)) + { + sv_name = &srv_name[2]; + } + + fstrcpy(dest_host, sv_name); + /* treat the '*' name specially - it is a magic name for the PDC */ + if (strcmp(dest_host,"*") == 0) { + extern pstring global_myname; + ret = resolve_name(lp_workgroup(), ip, 0x1B); + lookup_pdc_name(global_myname, lp_workgroup(), ip, dest_host); + } else { + ret = resolve_name(dest_host, ip, 0x20); + } + + if (is_ip_address(dest_host)) + { + fstrcpy(dest_host, "*SMBSERVER"); + } + + return ret; +} + + /******************************************************** Find the IP address of the master browser or DMB for a workgroup. *********************************************************/ diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 3f19a66941..f9d717477a 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -519,22 +519,32 @@ nt_err_code_struct nt_errs[] = /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -char *get_nt_error_msg(uint32 nt_code) +BOOL get_safe_nt_error_msg(uint32 nt_code,char *msg, size_t len) { - static pstring msg; int idx = 0; - pstrcpy(msg, "Unknown NT error"); + slprintf(msg, len-1, "NT code %08x", nt_code); while (nt_errs[idx].nt_errstr != NULL) { if ((nt_errs[idx].nt_errcode & 0xFFFFFF) == (nt_code & 0xFFFFFF)) { - pstrcpy(msg, nt_errs[idx].nt_errstr); - return msg; + safe_strcpy(msg, nt_errs[idx].nt_errstr, len); + return True; } idx++; } - return msg; + return False; } +/***************************************************************************** + returns an NT error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +const char *get_nt_error_msg(uint32 nt_code) +{ + static pstring msg; + get_safe_nt_error_msg(nt_code, msg, sizeof(msg)); + return msg; +} + + diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 1c5f8b5176..26b1d192f0 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -40,6 +40,15 @@ void pwd_init(struct pwd_info *pwd) pwd->crypted = False; } +/**************************************************************************** +returns NULL password flag +****************************************************************************/ +BOOL pwd_is_nullpwd(const struct pwd_info *pwd) +{ + return pwd->null_pwd; +} + + /**************************************************************************** compares two passwords. hmm, not as trivial as expected. hmm. ****************************************************************************/ -- cgit From d2b40a7de259377d937492acedd39988ddd108a4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 Jul 2000 06:20:46 +0000 Subject: More rpcclient merge issues: * fixes some readline bugs from the merge * first attempt at commands (spoolenum almost works) * no changes to existing functions in HEAD; only additions of new functions. I'll weed out what I can as I go. --jerry (This used to be commit 61d2aad5dc2b212b11c981f1eca47efa627e9fc8) --- source3/libsmb/cliconnect.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b546e1e4ec..b18b1276c0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -640,7 +640,7 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed negprot\n")); if (do_shutdown) - cli_shutdown(cli); + cli_shutdown(cli); return False; } @@ -707,10 +707,20 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session setup\n")); if (do_shutdown) - cli_shutdown(cli); + cli_shutdown(cli); return False; } + DEBUG(1,("session setup ok\n")); + + if (*cli->server_domain || *cli->server_os || *cli->server_type) + { + DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + cli->server_domain, + cli->server_os, + cli->server_type)); + } + if (do_tcon) { if (!cli_send_tconX(cli, service, service_type, -- cgit From 119f965f494d881c69704a346443aeb4bfcbe3ef Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Sun, 9 Jul 2000 02:10:24 +0000 Subject: Quick change to short-circuit WINS queries if the WINS server returns a Negative Name Query Response. We should't wait through the timeouts and retry twice if we've been told "No Such Entry". (This used to be commit 2bbd16903db02aacb729d1ad140056b180e2a776) --- source3/libsmb/namequery.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8fb607bd8f..82c8c8f93d 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -271,7 +271,18 @@ struct in_addr *name_query(int fd,const char *name,int name_type, if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); - + + if( 0 == nmb2->header.opcode /* A query response */ + && !(bcast) /* from a WINS server */ + && 0x03 == nmb2->header.rcode /* Name doesn't exist */ + ) { + /* If we get a Negative Name Query Response from a WINS + * server, we should give up. + */ + free_packet(p2); + return( NULL ); + } + if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || nmb2->header.rcode || @@ -499,13 +510,16 @@ static BOOL resolve_wins(const char *name, int name_type, wins_ip = *interpret_addr2(lp_wins_server()); wins_ismyip = ismyip(wins_ip); + DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()), True ); - + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr(lp_socket_address()), + True ); if (sock != -1) { - *return_iplist = name_query(sock, name, name_type, False, - True, wins_ip, return_count); + *return_iplist = name_query( sock, name, + name_type, False, + True, wins_ip, + return_count); if(*return_iplist != NULL) { close(sock); return True; -- cgit From 8edb4966aeb8a8df6e5e348085450b6686bdc879 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Wed, 12 Jul 2000 04:25:12 +0000 Subject: An improved version of the Negative Query Response fix. The earlier fix only did a short-cut on an rcode of 3, which is 'name not found'. This does a short-cut on any non-zero rcode. It also puts out a DEBUG message (if DEBUGLEVEL is >= 3) detailing the error. Chris -)----- (This used to be commit d8656304d51844335e72babe852673f2dececfdc) --- source3/libsmb/namequery.c | 47 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 82c8c8f93d..193731768f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -272,16 +272,42 @@ struct in_addr *name_query(int fd,const char *name,int name_type, struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); + /* If we get a Negative Name Query Response from a WINS + * server, we should report it and give up. + */ if( 0 == nmb2->header.opcode /* A query response */ && !(bcast) /* from a WINS server */ - && 0x03 == nmb2->header.rcode /* Name doesn't exist */ + && nmb2->header.rcode /* Error returned */ ) { - /* If we get a Negative Name Query Response from a WINS - * server, we should give up. - */ - free_packet(p2); - return( NULL ); + + if( DEBUGLVL( 3 ) ) { + /* Only executed if DEBUGLEVEL >= 3 */ + dbgtext( "Negative name query response, rcode 0x%02x: ", + nmb2->header.rcode ); + switch( nmb2->header.rcode ) { + case 0x01: + dbgtext( "Request was invalidly formatted.\n" ); + break; + case 0x02: + dbgtext( "Problem with NBNS, cannot process name.\n"); + break; + case 0x03: + dbgtext( "The name requested does not exist.\n" ); + break; + case 0x04: + dbgtext( "Unsupported request error.\n" ); + break; + case 0x05: + dbgtext( "Refused error.\n" ); + break; + default: + dbgtext( "Unrecognized error code.\n" ); + break; + } } + free_packet(p2); + return( NULL ); + } if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || @@ -295,17 +321,18 @@ struct in_addr *name_query(int fd,const char *name,int name_type, continue; } - ip_list = (struct in_addr *)Realloc(ip_list, sizeof(ip_list[0]) * - ((*count)+nmb2->answers->rdlength/6)); + ip_list = (struct in_addr *)Realloc( ip_list, + sizeof( ip_list[0] ) + * ( (*count) + nmb2->answers->rdlength/6 ) ); if (ip_list) { DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); for (i=0;ianswers->rdlength/6;i++) { putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUG(2,("%s ",inet_ntoa(ip_list[(*count)]))); + DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); (*count)++; } - DEBUG(2,(")\n")); + DEBUGADD(2,(")\n")); } found=True; -- cgit From b35f21fb3a19417e2aab82a573ff121a086b224c Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Wed, 19 Jul 2000 01:21:30 +0000 Subject: First cut toward adding WINS server failover. *Note: failover doesn't actually work yet!* It's just that the code I'm adding provides all of the pieces necessary. I do have one big question. Something that I'll have to ask Jeremy, I'm thinkin'. In nmbd/nmbd_subnetdb.c the IP of the WINS server is used to set up the Unicast subnet. ...so what happens if the WINS server changes? My guess is either: a) nothing. b) I'd have to change the unicast subnet entry whenever the WINS server changes. Urq. BTW, the lp_wins_server() function no longer returns the WINS server name or IP. It returns the list of WINS servers entered in smb.conf. To get the currently 'live' WINS server, use the wins_srv() function. Fun, eh? Chris -)----- (This used to be commit cc08bdc74f4cd111fdc582ee7babef47ed8a950d) --- source3/libsmb/namequery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 193731768f..0237a9752f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -529,12 +529,12 @@ static BOOL resolve_wins(const char *name, int name_type, DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); - if(!*lp_wins_server()) { - DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS server present.\n")); + if( wins_srv_count() < 1 ) { + DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); return False; } - wins_ip = *interpret_addr2(lp_wins_server()); + wins_ip = *interpret_addr2( wins_srv() ); wins_ismyip = ismyip(wins_ip); DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); -- cgit From 3c9e410c340d53897a3f97243d8286812704f6c0 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Wed, 19 Jul 2000 05:32:43 +0000 Subject: Instead of handing back a string (which might be a DNS name or an IP string), the wins_srv module now hands back a struct in_addr when it's called. It caches the IP address once it has been looked up. The IP is cleared (and must be looked up again) if the 'wins server' parameter is reread, or if the node is marked 'dead'. A dead node will not be re-tried for 10 minutes (per a #define in wins_srv.c). As it was, the code was reading the WINS server name or IP directly from lp_wins_server. That's okay, except that if the value was expressed as a name, then a DNS lookup would be done every time the client wanted to talk to the server. I still need to work out the implications of failover regarding the 'unicast subnet' list. Chris -)----- (This used to be commit 73aa188320fd3bf10b5dfc057323f40aff2c13bd) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0237a9752f..6550d55206 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -534,7 +534,7 @@ static BOOL resolve_wins(const char *name, int name_type, return False; } - wins_ip = *interpret_addr2( wins_srv() ); + wins_ip = wins_srv_ip(); wins_ismyip = ismyip(wins_ip); DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); -- cgit From 5ec1642809d9de83da8c88c65d6595c6eb0270f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Jul 2000 00:47:19 +0000 Subject: Ok - this is a *BIG* change - but it fixes the problems with static strings in the RPC code. This change was prompted by trying to save a long (>256) character comment in the printer properties page. The new system associates a TALLOC_CTX with the pipe struct, and frees the pool on return of a complete PDU. A global TALLOC_CTX is used for the odd buffer allocated in the BUFFERxx code, and is freed in the main loop. This code works with insure, and seems to be free of memory leaks and crashes (so far) but there are probably the occasional problem with code that uses UNISTRxx structs on the stack and expects them to contain storage without doing a init_unistrXX(). This means that rpcclient will probably be horribly broken. A TALLOC_CTX also needed associating with the struct cli_state also, to make the prs_xx code there work. The main interface change is the addition of a TALLOC_CTX to the prs_init calls - used for dynamic allocation in the prs_XXX calls. Now this is in place it should make dynamic allocation of all RPC memory on unmarshall *much* easier to fix. Jeremy. (This used to be commit 0ff2ce543ee54f7364e6d839db6d06e7ef1edcf4) --- source3/libsmb/clientgen.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c6f24c5e80..8d9fcb61d6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -203,6 +203,12 @@ struct cli_state *cli_initialise(struct cli_state *cli) return False; } + if ((cli->mem_ctx = talloc_init()) == NULL) { + free(cli->outbuf); + free(cli->inbuf); + return False; + } + memset(cli->outbuf, '\0', cli->bufsize); memset(cli->inbuf, '\0', cli->bufsize); @@ -224,6 +230,10 @@ void cli_shutdown(struct cli_state *cli) { free(cli->inbuf); } + + if (cli->mem_ctx) + talloc_destroy(cli->mem_ctx); + #ifdef WITH_SSL if (cli->fd != -1) sslutil_disconnect(cli->fd); -- cgit From 7f36df301e28dc8ca0e5bfadc109d6e907d9ba2b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Aug 2000 18:32:34 +0000 Subject: Tidyup removing many of the 0xC0000000 | NT_STATUS_XXX stuff (only need NT_STATUS_XXX). Removed IS_BITS_xxx macros as they were just reproducing "C" syntax in a more obscure way. Jeremy. (This used to be commit c55bcec817f47d6162466b193d533c877194124a) --- source3/libsmb/clierror.c | 3 ++- source3/libsmb/clireadwrite.c | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 78a7c9d451..314b343f25 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -161,7 +161,8 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ uint32 nt_err = IVAL(cli->inbuf,smb_rcls); if (num) *num = nt_err; DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); - if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0; + if (!(nt_err & 0xc0000000)) + return 0; switch (nt_err) { case NT_STATUS_ACCESS_VIOLATION: return EACCES; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 8012c02a8f..86a51da835 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -148,10 +148,10 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_vwv2,fnum); SIVAL(cli->outbuf,smb_vwv3,offset); - SIVAL(cli->outbuf,smb_vwv5,IS_BITS_SET_ALL(mode, 0x0008) ? 0xFFFFFFFF : 0); + SIVAL(cli->outbuf,smb_vwv5,(mode & 0x0008) ? 0xFFFFFFFF : 0); SSVAL(cli->outbuf,smb_vwv7,mode); - SSVAL(cli->outbuf,smb_vwv8,IS_BITS_SET_ALL(mode, 0x0008) ? size : 0); + SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); -- cgit From 553579bf6fd7c9dfecddddc1f6272b523bce69d9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 4 Aug 2000 06:13:05 +0000 Subject: In cli_error() return ENOENT when an ERROR_INVALID_NAME is received instead of the generic EINVAL. (This used to be commit a290107aee01a85ca1ef5565f23c8f00e18e98c2) --- source3/libsmb/clierror.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 314b343f25..66bf83cfc5 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -197,6 +197,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ case ERRrename: return EEXIST; case ERRbadshare: return EBUSY; case ERRlock: return EBUSY; + case ERROR_INVALID_NAME: return ENOENT; } } if (rcls == ERRSRV) { -- cgit From 726e7e256e9c6d9767dea6cc600b75522ee84f07 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 11 Aug 2000 22:29:44 +0000 Subject: First shot at actually *doing* WINS failover. If libsmb/namequery.c:name_query() times out while doing a non-broadcast query, I mark that WINS server 'dead'. Note that I don't try the new WINS server. I think I can get that working too. This is only for queries, not registrations. The biggest problem is that I may have to fiddle with the UNICAST SUBNET, but I need to check talk that over with someone (Jeremy?) before I hack at it. I can't actually test the above change, I'm 'fraid. I'm getting: 4 errors detected in the compilation of "rpc_server/srv_spoolss_nt.c". in head branch. Chris -)----- (This used to be commit 40ae638866e3d826ccd5d827672634959c31b039) --- source3/libsmb/namequery.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6550d55206..6e0bf3375e 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -298,7 +298,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, dbgtext( "Unsupported request error.\n" ); break; case 0x05: - dbgtext( "Refused error.\n" ); + dbgtext( "Query refused error.\n" ); break; default: dbgtext( "Unrecognized error code.\n" ); @@ -348,6 +348,13 @@ struct in_addr *name_query(int fd,const char *name,int name_type, } } + /* Reach here if we've timed out waiting for replies.. */ + if( !bcast && !found ) + { + /* Timed out wating for WINS server to respond. Mark it dead. */ + wins_srv_died( to_ip ); + } + return ip_list; } -- cgit From c79b92bbd8d455e98486b68a2a9e1f9cb5f7905f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 25 Aug 2000 04:18:50 +0000 Subject: Replaced "\\MAILSLOT\\NET\\NETLOGON" with NET_LOGON_MAILSLOT constant. (This used to be commit 5764e84c0e01fa4d6ecba410542f6f5c63b9eae6) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6e0bf3375e..41924d4631 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -838,7 +838,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd int len; struct sockaddr_in sock_name; int sock_len = sizeof(sock_name); - const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON"; + const char *mailslot = NET_LOGON_MAILSLOT; char *mailslot_name; char buffer[1024]; char *bufp; -- cgit From dda54bcd7d6f6d674f197abd323e102fdf7e8dc3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 26 Sep 2000 05:44:42 +0000 Subject: added NEGNOWAIT. sent to secure@microsoft.com (This used to be commit b21179331802aace566671dcff6db22cdf4b3e81) --- source3/libsmb/cliconnect.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b18b1276c0..c4b491b056 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -331,6 +331,44 @@ BOOL cli_tdis(struct cli_state *cli) } +/**************************************************************************** +send a negprot command +****************************************************************************/ +void cli_negprot_send(struct cli_state *cli) +{ + char *p; + int numprots; + int plength; + + memset(cli->outbuf,'\0',smb_size); + + /* setup the protocol strings */ + for (plength=0,numprots=0; + prots[numprots].name && prots[numprots].prot<=cli->protocol; + numprots++) + plength += strlen(prots[numprots].name)+2; + + set_message(cli->outbuf,0,plength,True); + + p = smb_buf(cli->outbuf); + for (numprots=0; + prots[numprots].name && prots[numprots].prot<=cli->protocol; + numprots++) { + *p++ = 2; + pstrcpy(p,prots[numprots].name); + unix_to_dos(p,True); + p += strlen(p) + 1; + } + + CVAL(cli->outbuf,smb_com) = SMBnegprot; + cli_setup_packet(cli); + + CVAL(smb_buf(cli->outbuf),0) = 2; + + cli_send_smb(cli); +} + + /**************************************************************************** send a negprot command ****************************************************************************/ -- cgit From 3f35a785b1afc97caae2ea24ff406e5f967b27e8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 29 Sep 2000 04:41:52 +0000 Subject: added cli_lock64() and cli_unlock64() (This used to be commit 91f0a3cc2f59a49f6ce8550e7d07b9b01e0b285f) --- source3/libsmb/clifile.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 214c30d930..63f6f8cc6c 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -409,6 +409,102 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) } +/**************************************************************************** + lock a file with 64 bit offsets +****************************************************************************/ +BOOL cli_lock64(struct cli_state *cli, int fnum, + SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type) +{ + char *p; + int saved_timeout = cli->timeout; + int ltype; + + ltype = (lock_type == READ_LOCK? 1 : 0); + ltype |= LOCKING_ANDX_LARGE_FILES; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0', smb_size); + + set_message(cli->outbuf,8,20,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = ltype; + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,0); + SSVAL(cli->outbuf,smb_vwv7,1); + + p = smb_buf(cli->outbuf); + SIVAL(p, 0, cli->pid); + SIVAL(p, 4, (offset>>32)); + SIVAL(p, 8, (offset&0xffffffff)); + SIVAL(p, 12, (len>>32)); + SIVAL(p, 16, (len&0xffffffff)); + cli_send_smb(cli); + + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + + if (!cli_receive_smb(cli)) { + cli->timeout = saved_timeout; + return False; + } + + cli->timeout = saved_timeout; + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + +/**************************************************************************** + unlock a file with 64 bit offsets +****************************************************************************/ +BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,8,20,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = LOCKING_ANDX_LARGE_FILES; + SIVALS(cli->outbuf, smb_vwv4, 0); + SSVAL(cli->outbuf,smb_vwv6,1); + SSVAL(cli->outbuf,smb_vwv7,0); + + p = smb_buf(cli->outbuf); + SIVAL(p, 0, cli->pid); + SIVAL(p, 4, (offset>>32)); + SIVAL(p, 8, (offset&0xffffffff)); + SIVAL(p, 12, (len>>32)); + SIVAL(p, 16, (len&0xffffffff)); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + return True; +} + + -- cgit From 9c6acf4595d14cb0fc0c9bf17ce02de73af127cd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Oct 2000 22:37:42 +0000 Subject: Fix from RFritz@lbl.gov for Linux ECONREFUSED async errors on Linux. Jeremy. (This used to be commit dd804fdb96ff49645647787c197a61a6515a474d) --- source3/libsmb/nmblib.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index e290ee5d4f..01c4001f4c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -750,6 +750,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) { BOOL ret; + int i; struct sockaddr_in sock_out; /* set the address and port */ @@ -760,9 +761,16 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", len, inet_ntoa(ip), port ) ); + + /* + * Patch to fix asynch error notifications from Linux kernel. + */ - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, - sizeof(sock_out)) >= 0); + for (i = 0; i < 5; i++) { + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); + if (ret || errno != ECONNREFUSED) + break; + } if (!ret) DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", -- cgit From 8582d426467e715a912ef06c13bdbbdeb9000739 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 7 Oct 2000 01:15:07 +0000 Subject: Ensure browse.dat is written and read in UNIX character set format. Jeremy. (This used to be commit 279d0ec656b03f9266e38b013f16b69e7571c0d5) --- source3/libsmb/clirap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 5e7e9427f6..085b1c35bb 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -237,6 +237,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p += 4; pstrcpy(p, workgroup); + unix_to_dos(p, True); p = skip_string(p,1); if (cli_api(cli, -- cgit From 75c346e70c83f7386ecd2f10fe155c4a4dfd47de Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sat, 7 Oct 2000 15:56:36 +0000 Subject: added samr_set_user_info and info_2. cleanup of create_user cleanup of rid/sid mix in samr. now we only have sid. some prs_align() missing in parse_samr.c a small debug change in srv_pipe.c You still can't change a user's password in this commit. Will be availble in the next one. J.F. (This used to be commit b655bc281fa183b1827a946ada1fcf500fb93aea) --- source3/libsmb/smbencrypt.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b927e193dd..16f2493947 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -228,3 +228,47 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } +/*********************************************************** + decode a password buffer +************************************************************/ +BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, + int new_pwrd_size, uint32 *new_pw_len) +{ + int uni_pw_len=0; + char *pw; + /* + Warning !!! : This function is called from some rpc call. + The password IN the buffer is a UNICODE string. + The password IN new_pwrd is an ASCII string + If you reuse that code somewhere else check first. + */ + + + /* + * The length of the new password is in the last 4 bytes of + * the data buffer. + */ + + *new_pw_len = IVAL(buffer, 512); + +#ifdef DEBUG_PASSWORD + dump_data(100, buffer, 516); +#endif + + if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) { + DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", (*new_pw_len))); + return False; + } + + uni_pw_len = *new_pw_len; + *new_pw_len /= 2; + pw = dos_unistrn2((uint16 *)(&buffer[512 - uni_pw_len]), uni_pw_len); + memcpy(new_pwrd, pw, *new_pw_len + 1); + +#ifdef DEBUG_PASSWORD + dump_data(100, new_pwrd, (*new_pw_len)); +#endif + + return True; +} + -- cgit From 8719c27726d3412edd0781beb956f48f76a62fb6 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 11 Oct 2000 05:31:39 +0000 Subject: changes to sync with 2.2. tree .cvsignore remove config.h - not in this directory include/profile.h profile changes lib/messages.c added message to return debug level libsmb/clierror.c cast to get rid of compiler warning libsmb/smbencrypt.c cast to get rid of compiler warning profile/profile.c add flush profile stats changes for profile struct rpc_parse/parse_samr.c fix for compiler warning rpc_server/srv_samr.c cast to get rid of compiler warning smbd/ipc.c profile stats message.c profile stats smbd/negprot.c profile stats smbd/nttrans.c profile stats smbd/trans2.c profile stats utils/smbcontrol.c new flush stats command (This used to be commit bbb24daa25dca4e4b6b1f8942cd84ee3aa1bed8e) --- source3/libsmb/clierror.c | 2 +- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 66bf83cfc5..4c6d9a49f2 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -96,7 +96,7 @@ char *cli_errstr(struct cli_state *cli) if (nt_rpc_error) { - char *nt_msg = get_nt_error_msg(nt_rpc_error); + char *nt_msg = (char *)get_nt_error_msg(nt_rpc_error); if (nt_msg == NULL) { diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 16f2493947..371e279ffd 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -255,7 +255,7 @@ BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, dump_data(100, buffer, 516); #endif - if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) { + if (((int)*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) { DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", (*new_pw_len))); return False; } -- cgit From 330d678fbad70fabd9712c56ad15bd215f950255 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Oct 2000 01:59:14 +0000 Subject: Fix to allow smbd to call winbindd if it is running for all group enumeration, falling back to the UNIX calls on error. This should fix all problems with smbd enumerating all users in all groups in all trusted domains via winbindd. Also changed GETDC to query 1C name rather than 1b name as only the PDC registers 1b. Jeremy. (This used to be commit 5b0038a2afd8abbd6fd4a58f5477a40d1926d498) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 41924d4631..52ff6287c4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -891,7 +891,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd dgram->header.packet_offset = 0; make_nmb_name(&dgram->source_name,srcname,0); - make_nmb_name(&dgram->dest_name,domain,0x1B); + make_nmb_name(&dgram->dest_name,domain,0x1C); ptr = &dgram->data[0]; -- cgit From 85643cd72cbc51d163dba98eecd98c7bb029bfc3 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 13 Oct 2000 14:02:01 +0000 Subject: last part of W2K support. the trust domain list reply on netlogon pipe was wrong, interim hack until we have full trust relationships. changed some unistr2 to parse the ending NULL char. added a prs_align_needed() function. much like a prs_align but with a condition. needed for the unistr2 parsing. J.F. (This used to be commit d8bf81553c17d9ee3419d8150b96119ebb0b8fa9) --- source3/libsmb/smbencrypt.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 371e279ffd..858045dc02 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -108,9 +108,9 @@ void E_md4hash(uchar *passwd, uchar *p16) /* Does both the NT and LM owfs of a user's password */ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) { - char passwd[130]; + char passwd[514]; - memset(passwd,'\0',130); + memset(passwd,'\0',514); safe_strcpy( passwd, pwd, sizeof(passwd)-1); /* Calculate the MD4 hash (NT compatible) of the password */ @@ -231,7 +231,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ /*********************************************************** decode a password buffer ************************************************************/ -BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, +BOOL decode_pw_buffer(char buffer[516], char *new_pwrd, int new_pwrd_size, uint32 *new_pw_len) { int uni_pw_len=0; @@ -243,6 +243,7 @@ BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, If you reuse that code somewhere else check first. */ + ZERO_STRUCTP(new_pwrd); /* * The length of the new password is in the last 4 bytes of @@ -263,7 +264,7 @@ BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd, uni_pw_len = *new_pw_len; *new_pw_len /= 2; pw = dos_unistrn2((uint16 *)(&buffer[512 - uni_pw_len]), uni_pw_len); - memcpy(new_pwrd, pw, *new_pw_len + 1); + memcpy(new_pwrd, pw, *new_pw_len); #ifdef DEBUG_PASSWORD dump_data(100, new_pwrd, (*new_pw_len)); -- cgit From 2e62e34fe4db2603b409c48c10d5a1d0fb173618 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Oct 2000 03:02:22 +0000 Subject: Rolled back find NetBIOS name of PDC/BDC code as a temp fix. This code works :-). Jeremy. (This used to be commit 4f66eda11e0dc15ff04893da7b7d6e578a30c4dc) --- source3/libsmb/namequery.c | 61 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 52ff6287c4..81dadebd3b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -108,7 +108,7 @@ static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, { BOOL found=False; int retries = 2; - int retry_time = 5000; + int retry_time = 2000; struct timeval tval; struct packet_struct p; struct packet_struct *p2; @@ -822,12 +822,70 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip) return False; } +#if !defined(I_HATE_WINDOWS_REPLY_CODE) +/******************************************************** + Internal function to extract the MACHINE<0x20> name. +*********************************************************/ + +static void _lookup_pdc_name(char *p, char *master,char *rname) +{ + int numnames = CVAL(p,0); + + *rname = '\0'; + + p += 1; + while (numnames--) { + int type = CVAL(p,15); + if(type == 0x20) { + StrnCpy(rname,p,15); + trim_string(rname,NULL," "); + return; + } + p += 18; + } +} +#endif /* I_HATE_WINDOWS_REPLY_CODE */ /******************************************************** Lookup a PDC name given a Domain name and IP address. *********************************************************/ + BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name) { +#if !defined(I_HATE_WINDOWS_REPLY_CODE) + + fstring pdc_name; + BOOL ret; + + /* + * Due to the fact win WinNT *sucks* we must do a node status + * query here... JRA. + */ + + int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); + + if(sock == -1) + return False; + + *pdc_name = '\0'; + + ret = internal_name_status(sock,"*SMBSERVER",0x20,True, + *pdc_ip,NULL,pdc_name,False,_lookup_pdc_name); + + close(sock); + + if(ret && *pdc_name) { + fstrcpy(ret_name, pdc_name); + return True; + } + + return False; + +#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */ + +JRA - This code is broken with BDC rollover - we need to do a full +NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... + int retries = 3; int retry_time = 2000; struct timeval tval; @@ -998,6 +1056,7 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd close(sock); return False; +#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ } -- cgit From e2d1dd47d8f873a10d8f84253182059c50a229c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 28 Oct 2000 20:54:45 +0000 Subject: Another patch to fix cli_reestablish_connection from Kenichi Okuyama@Tokyo Research Lab. IBM-Japan. Co. Jp. Jeremy. (This used to be commit 06f5da5d4bf044969364afe0298347811fb4ae91) --- source3/libsmb/cliconnect.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c4b491b056..3292b9e1d6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -626,10 +626,8 @@ BOOL cli_reestablish_connection(struct cli_state *cli) dest_host, &cli->dest_ip, &calling, &called, share, dev, False, do_tcon)) { - if (cli->fd != oldfd) { - if (dup2(cli->fd, oldfd) == oldfd) { - close(cli->fd); - } + if ((cli->fd != oldfd) && (oldfd != -1)) { + close( oldfd ); } return True; } -- cgit From 6f58dd587124c8b85fc62177b26129aaea5819b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 16 Nov 2000 00:59:18 +0000 Subject: Ok - fixed a bug in our levelII oplock code. We need to break a level II on a byte range lock (write lock only, but Win2k breaks on read lock also so I do the same) - if you think about why, this is obvious. Also fixed our client code to do level II oplocks, if requested, and fixed the code where we would assume the client wanted level II if it advertised itself as being level II capable - it may not want that. Jeremy. (This used to be commit 213cd0b5192307cd4b0026cae94b2f52fb1b0c02) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 11 ++++++++++- source3/libsmb/clifile.c | 5 ++++- 3 files changed, 15 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3292b9e1d6..ff81d886b0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -146,7 +146,7 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,0); + SSVAL(cli->outbuf,smb_vwv11,CAP_NT_SMBS|(cli->use_level_II_oplocks ? CAP_LEVEL_II_OPLOCKS : 0)); p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d9fcb61d6..8d9e2f034f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -121,14 +121,20 @@ static void cli_process_oplock(struct cli_state *cli) char *oldbuf = cli->outbuf; pstring buf; int fnum; + unsigned char level; fnum = SVAL(cli->inbuf,smb_vwv2); + level = CVAL(cli->inbuf,smb_vwv3+1); /* damn, we really need to keep a record of open files so we can detect a oplock break and a close crossing on the wire. for now this swallows the errors */ if (fnum == 0) return; + /* Ignore level II break to none's. */ + if (level == OPLOCKLEVEL_NONE) + return; + cli->outbuf = buf; memset(buf,'\0',smb_size); @@ -140,7 +146,10 @@ static void cli_process_oplock(struct cli_state *cli) SSVAL(buf,smb_vwv0,0xFF); SSVAL(buf,smb_vwv1,0); SSVAL(buf,smb_vwv2,fnum); - SSVAL(buf,smb_vwv3,2); /* oplock break ack */ + if (cli->use_level_II_oplocks) + SSVAL(buf,smb_vwv3,0x102); /* levelII oplock break ack */ + else + SSVAL(buf,smb_vwv3,2); /* exclusive oplock break ack */ SIVAL(buf,smb_vwv4,0); /* timoeut */ SSVAL(buf,smb_vwv6,0); /* unlockcount */ SSVAL(buf,smb_vwv7,0); /* lockcount */ diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 63f6f8cc6c..2f183ea135 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -182,7 +182,10 @@ int cli_nt_create(struct cli_state *cli, char *fname) cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); - SIVAL(cli->outbuf,smb_ntcreate_Flags, 0x06); + if (cli->use_oplocks) + SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); + else + SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f); SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); -- cgit From 0f1713068f597fddb88faf616eeb9382029c3d58 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Dec 2000 02:18:14 +0000 Subject: - added client support for nttrans calls - added a cli_ function for querying a security descriptor on a remote file (This used to be commit e21994ff9d512d1c9d6d360e930809b135df4cf7) --- source3/libsmb/clisecdesc.c | 82 ++++++++++++++++++ source3/libsmb/clitrans.c | 200 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+) create mode 100644 source3/libsmb/clisecdesc.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c new file mode 100644 index 0000000000..7667938f02 --- /dev/null +++ b/source3/libsmb/clisecdesc.c @@ -0,0 +1,82 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client security descriptor functions + Copyright (C) Andrew Tridgell 2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + + + +/**************************************************************************** + query the security descriptor for a open file + ****************************************************************************/ +SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) +{ + char param[8]; + char *rparam=NULL, *rdata=NULL; + int rparam_count=0, rdata_count=0; + TALLOC_CTX *mem_ctx; + prs_struct pd; + SEC_DESC *psd = NULL; + SEC_DESC *ret; + + SIVAL(param, 0, fd); + SSVAL(param, 4, 7); + + if (!cli_send_nt_trans(cli, + NT_TRANSACT_QUERY_SECURITY_DESC, + 0, + NULL, 0, 0, + param, 8, 4, + NULL, 0, 0x10000)) { + DEBUG(1,("Failed to send NT_TRANSACT_QUERY_SECURITY_DESC\n")); + return NULL; + } + + + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("Failed to recv NT_TRANSACT_QUERY_SECURITY_DESC\n")); + return NULL; + } + + if ((mem_ctx = talloc_init()) == NULL) { + DEBUG(0,("talloc_init failed.\n")); + return NULL; + } + + prs_init(&pd, rdata_count, 4, mem_ctx, UNMARSHALL); + prs_append_data(&pd, rdata, rdata_count); + pd.data_offset = 0; + + if (!sec_io_desc("sd data", &psd, &pd, 1)) { + DEBUG(1,("Failed to parse secdesc\n")); + return NULL; + } + + ret = dup_sec_desc(psd); + talloc_destroy(mem_ctx); + return ret; +} + + + diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 76758a0dd6..50ed68ee16 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -231,3 +231,203 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, return(True); } + + + + +/**************************************************************************** + send a SMB nttrans request + ****************************************************************************/ +BOOL cli_send_nt_trans(struct cli_state *cli, + int function, + int flags, + uint16 *setup, int lsetup, int msetup, + char *param, int lparam, int mparam, + char *data, int ldata, int mdata) +{ + int i; + int this_ldata,this_lparam; + int tot_data=0,tot_param=0; + char *outdata,*outparam; + + this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ + this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); + + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,19+lsetup,0,True); + CVAL(cli->outbuf,smb_com) = SMBnttrans; + SSVAL(cli->outbuf,smb_tid, cli->cnum); + cli_setup_packet(cli); + + outparam = smb_buf(cli->outbuf)+3; + outdata = outparam+this_lparam; + + /* primary request */ + SCVAL(cli->outbuf,smb_nt_MaxSetupCount,msetup); + SCVAL(cli->outbuf,smb_nt_Flags,flags); + SIVAL(cli->outbuf,smb_nt_TotalParameterCount, lparam); + SIVAL(cli->outbuf,smb_nt_TotalDataCount, ldata); + SIVAL(cli->outbuf,smb_nt_MaxParameterCount, mparam); + SIVAL(cli->outbuf,smb_nt_MaxDataCount, mdata); + SIVAL(cli->outbuf,smb_nt_ParameterCount, this_lparam); + SIVAL(cli->outbuf,smb_nt_ParameterOffset, smb_offset(outparam,cli->outbuf)); + SIVAL(cli->outbuf,smb_nt_DataCount, this_ldata); + SIVAL(cli->outbuf,smb_nt_DataOffset, smb_offset(outdata,cli->outbuf)); + SIVAL(cli->outbuf,smb_nt_SetupCount, lsetup); + SIVAL(cli->outbuf,smb_nt_Function, function); + for (i=0;ioutbuf,smb_nt_SetupStart+i*2,setup[i]); + + if (this_lparam) /* param[] */ + memcpy(outparam,param,this_lparam); + if (this_ldata) /* data[] */ + memcpy(outdata,data,this_ldata); + + set_message(cli->outbuf,19+lsetup, /* wcnt, bcc */ + PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + + show_msg(cli->outbuf); + cli_send_smb(cli); + + if (this_ldata < ldata || this_lparam < lparam) { + /* receive interim response */ + if (!cli_receive_smb(cli) || + CVAL(cli->inbuf,smb_rcls) != 0) { + return(False); + } + + tot_data = this_ldata; + tot_param = this_lparam; + + while (tot_data < ldata || tot_param < lparam) { + this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ + this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); + + set_message(cli->outbuf,18,0,True); + CVAL(cli->outbuf,smb_com) = SMBnttranss; + + /* XXX - these should probably be aligned */ + outparam = smb_buf(cli->outbuf); + outdata = outparam+this_lparam; + + /* secondary request */ + SIVAL(cli->outbuf,smb_nts_TotalParameterCount,lparam); + SIVAL(cli->outbuf,smb_nts_TotalDataCount,ldata); + SIVAL(cli->outbuf,smb_nts_ParameterCount,this_lparam); + SIVAL(cli->outbuf,smb_nts_ParameterOffset,smb_offset(outparam,cli->outbuf)); + SIVAL(cli->outbuf,smb_nts_ParameterDisplacement,tot_param); + SIVAL(cli->outbuf,smb_nts_DataCount,this_ldata); + SIVAL(cli->outbuf,smb_nts_DataOffset,smb_offset(outdata,cli->outbuf)); + SIVAL(cli->outbuf,smb_nts_DataDisplacement,tot_data); + if (this_lparam) /* param[] */ + memcpy(outparam,param+tot_param,this_lparam); + if (this_ldata) /* data[] */ + memcpy(outdata,data+tot_data,this_ldata); + set_message(cli->outbuf,18, + PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + + show_msg(cli->outbuf); + cli_send_smb(cli); + + tot_data += this_ldata; + tot_param += this_lparam; + } + } + + return(True); +} + + + +/**************************************************************************** + receive a SMB nttrans response allocating the necessary memory + ****************************************************************************/ +BOOL cli_receive_nt_trans(struct cli_state *cli, + char **param, int *param_len, + char **data, int *data_len) +{ + int total_data=0; + int total_param=0; + int this_data,this_param; + uint8 eclass; + uint32 ecode; + + *data_len = *param_len = 0; + + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + /* sanity check */ + if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { + DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", + CVAL(cli->inbuf,smb_com))); + return(False); + } + + /* + * An NT RPC pipe call can return ERRDOS, ERRmoredata + * to a trans call. This is not an error and should not + * be treated as such. + */ + if (cli_error(cli, &eclass, &ecode, NULL)) { + if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return(False); + } + + /* parse out the lengths */ + total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); + total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); + + /* allocate it */ + *data = Realloc(*data,total_data); + *param = Realloc(*param,total_param); + + while (1) { + this_data = SVAL(cli->inbuf,smb_ntr_DataCount); + this_param = SVAL(cli->inbuf,smb_ntr_ParameterCount); + + if (this_data + *data_len > total_data || + this_param + *param_len > total_param) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) + memcpy(*data + SVAL(cli->inbuf,smb_ntr_DataDisplacement), + smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_DataOffset), + this_data); + if (this_param) + memcpy(*param + SVAL(cli->inbuf,smb_ntr_ParameterDisplacement), + smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_ParameterOffset), + this_param); + *data_len += this_data; + *param_len += this_param; + + /* parse out the total lengths again - they can shrink! */ + total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); + total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); + + if (total_data <= *data_len && total_param <= *param_len) + break; + + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + /* sanity check */ + if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { + DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", + CVAL(cli->inbuf,smb_com))); + return(False); + } + if (cli_error(cli, &eclass, &ecode, NULL)) { + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + return(False); + } + } + + return(True); +} -- cgit From 4fee254d678033dffa6d0ed82e55ec59d65fcd03 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Dec 2000 07:36:15 +0000 Subject: getting/setting acls now works. The SIDs are still numeric, the next step is to support usernames etc (This used to be commit 6cea1647fcbc6f5a903c691273dcec44fcda1fc4) --- source3/libsmb/clisecdesc.c | 57 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 7667938f02..e6b57f6ad4 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -39,7 +39,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) SEC_DESC *ret; SIVAL(param, 0, fd); - SSVAL(param, 4, 7); + SSVAL(param, 4, 0xf); if (!cli_send_nt_trans(cli, NT_TRANSACT_QUERY_SECURITY_DESC, @@ -70,6 +70,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) if (!sec_io_desc("sd data", &psd, &pd, 1)) { DEBUG(1,("Failed to parse secdesc\n")); + talloc_destroy(mem_ctx); return NULL; } @@ -80,3 +81,57 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) + +/**************************************************************************** + set the security descriptor for a open file + ****************************************************************************/ +BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) +{ + char param[8]; + char *rparam=NULL, *rdata=NULL; + int rparam_count=0, rdata_count=0; + TALLOC_CTX *mem_ctx; + prs_struct pd; + + if ((mem_ctx = talloc_init()) == NULL) { + DEBUG(0,("talloc_init failed.\n")); + return False; + } + + prs_init(&pd, 0, 4, mem_ctx, MARSHALL); + prs_give_memory(&pd, NULL, 0, True); + + if (!sec_io_desc("sd data", &sd, &pd, 1)) { + DEBUG(1,("Failed to marshall secdesc\n")); + return False; + } + + SIVAL(param, 0, fd); + SSVAL(param, 4, 0xf); + + if (!cli_send_nt_trans(cli, + NT_TRANSACT_SET_SECURITY_DESC, + 0, + NULL, 0, 0, + param, 8, 0, + pd.data_p, pd.data_offset, 0)) { + DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); + return False; + } + + + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("Failed to recv NT_TRANSACT_SET_SECURITY_DESC\n")); + return False; + } + + if (rparam) free(rparam); + if (rdata) free(rdata); + + talloc_destroy(mem_ctx); + + return True; +} + -- cgit From 1fac52f9f01bcdad52029563ddb35e0a5a6cc613 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 3 Dec 2000 11:04:45 +0000 Subject: changed an error message (This used to be commit f9f14a4293cecb738f733c6c845275619f7bec40) --- source3/libsmb/clisecdesc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index e6b57f6ad4..d572af3db4 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -123,7 +123,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) if (!cli_receive_nt_trans(cli, &rparam, &rparam_count, &rdata, &rdata_count)) { - DEBUG(1,("Failed to recv NT_TRANSACT_SET_SECURITY_DESC\n")); + DEBUG(1,("NT_TRANSACT_SET_SECURITY_DESC failed\n")); return False; } -- cgit From ca784bb0280205cdbacca704f0b4c94d8e79e621 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Dec 2000 04:26:22 +0000 Subject: in cli_session_setup() accept usernames of the form DOMAIN/USER or DOMAIN\USER this means all our tools can now put the domain name in the -U option (This used to be commit bac1c76f03b6b848fa2e942b12c646aed58bee12) --- source3/libsmb/cliconnect.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ff81d886b0..8a7c6da1af 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -56,6 +56,15 @@ BOOL cli_session_setup(struct cli_state *cli, { char *p; fstring pword, ntpword; + fstring user2; + + /* allow for workgroups as part of the username */ + fstrcpy(user2, user); + if ((p=strchr(user2,'\\')) || (p=strchr(user2,'/'))) { + *p = 0; + user = p+1; + workgroup = user2; + } if (cli->protocol < PROTOCOL_LANMAN1) return True; -- cgit From 5092ad82bac2d8aa07122dfdb26a425a35e1084a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Dec 2000 04:58:40 +0000 Subject: removed SACL support (as it doesn't work with w2k if you ask for SACLs) (This used to be commit 52b27d75e12eeeb52b3a93952900809c2ee0b992) --- source3/libsmb/clisecdesc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index d572af3db4..b56e1ea688 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -39,7 +39,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) SEC_DESC *ret; SIVAL(param, 0, fd); - SSVAL(param, 4, 0xf); + SSVAL(param, 4, 0x7); if (!cli_send_nt_trans(cli, NT_TRANSACT_QUERY_SECURITY_DESC, @@ -107,7 +107,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) } SIVAL(param, 0, fd); - SSVAL(param, 4, 0xf); + SSVAL(param, 4, 0x7); if (!cli_send_nt_trans(cli, NT_TRANSACT_SET_SECURITY_DESC, -- cgit From 3a01ece497557c3c18f27aa144460f700ba17457 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Dec 2000 06:39:14 +0000 Subject: fixed indentation (This used to be commit b7a1c00bed5f0650783c8d7397c11aa2ac59aa04) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 2f183ea135..c23a43f95f 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -197,7 +197,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); pstrcpy(p,fname); - unix_to_dos(p,True); + unix_to_dos(p,True); p = skip_string(p,1); cli_send_smb(cli); -- cgit From d93101300820514c038ae52ffaf8150594701d07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Dec 2000 07:26:56 +0000 Subject: pass the desired access into cli_nt_create() (This used to be commit a2d07994e0376a8d530d262573c96710bdff2236) --- source3/libsmb/clifile.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index c23a43f95f..cb492f1539 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -149,7 +149,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; pstrcpy(p,dname); - unix_to_dos(p,True); + unix_to_dos(p,True); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -168,7 +168,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) /**************************************************************************** open a file ****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname) +int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) { char *p; @@ -187,7 +187,7 @@ int cli_nt_create(struct cli_state *cli, char *fname) else SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, 0x2019f); + SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); -- cgit From 2e79da814da91f9682b73aa1e3285f1be4aa05b0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 8 Dec 2000 02:45:51 +0000 Subject: Removed compiler warning. (This used to be commit 6d3bd1d80635d91e9590bcf093662259090ea6da) --- source3/libsmb/nterr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index f9d717477a..17bb825219 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -540,9 +540,10 @@ BOOL get_safe_nt_error_msg(uint32 nt_code,char *msg, size_t len) /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -const char *get_nt_error_msg(uint32 nt_code) +char *get_nt_error_msg(uint32 nt_code) { static pstring msg; + get_safe_nt_error_msg(nt_code, msg, sizeof(msg)); return msg; } -- cgit From 2364d59cdcbed229884784684447c5690d6deb37 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 Dec 2000 00:08:17 +0000 Subject: exposed the broadcast name resolution routine outside namequery.c (This used to be commit 7d1d867acdc0f316d8de787e1f7fa27667ec4a6a) --- source3/libsmb/namequery.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 81dadebd3b..a8cc2fcf3a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -471,8 +471,8 @@ void endlmhosts(FILE *fp) Resolve via "bcast" method. *********************************************************/ -static BOOL resolve_bcast(const char *name, int name_type, - struct in_addr **return_ip_list, int *return_count) +BOOL name_resolve_bcast(const char *name, int name_type, + struct in_addr **return_ip_list, int *return_count) { int sock, i; int num_interfaces = iface_count(); @@ -484,7 +484,7 @@ static BOOL resolve_bcast(const char *name, int name_type, * "bcast" means do a broadcast lookup on all the local interfaces. */ - DEBUG(3,("resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type)); + DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type)); sock = open_socket_in( SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); @@ -714,7 +714,7 @@ static BOOL internal_resolve_name(const char *name, int name_type, return True; } } else if(strequal( tok, "bcast")) { - if (resolve_bcast(name, name_type, return_iplist, return_count)) { + if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { return True; } } else { -- cgit From 16e05346e56edac2fc85243a36e7b9047c2d8b58 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 13 Dec 2000 12:52:21 +0000 Subject: Lightweight rpc client library. Uses only routines in libsmb and rpc_client/cli_pipe.c Only cli_lsa_open_policy(), cli_lsa_close(), cli_lsa_lookup_names() and cli_lsa_lookup_sids() implemented so far. (This used to be commit 129d5a155a73d926868d74f8447c1e93b429388d) --- source3/libsmb/cli_lsarpc.c | 370 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 370 insertions(+) create mode 100644 source3/libsmb/cli_lsarpc.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c new file mode 100644 index 0000000000..4199ab2648 --- /dev/null +++ b/source3/libsmb/cli_lsarpc.c @@ -0,0 +1,370 @@ +/* + Unix SMB/Netbios implementation. + Version 2.2 + RPC pipe client + Copyright (C) Tim Potter 2000, + Copyright (C) Andrew Tridgell 1992-1997,2000, + Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, + Copyright (C) Paul Ashton 1997,2000, + Copyright (C) Elrond 2000. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* Opens a SMB connection to the lsa pipe */ + +struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, + struct ntuser_creds *creds) +{ + struct in_addr dest_ip; + struct nmb_name calling, called; + fstring dest_host; + extern pstring global_myname; + + /* Initialise cli_state information */ + + ZERO_STRUCTP(cli); + + if (!cli_initialise(cli)) { + return NULL; + } + + cli_init_creds(cli, creds); + + /* Establish a SMB connection */ + + if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { + return NULL; + } + + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); + + if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, + &called, "IPC$", "IPC", False, True)) { + return NULL; + } + + /* Open a NT session thingy */ + + if (!cli_nt_session_open(cli, PIPE_LSARPC)) { + cli_shutdown(cli); + return NULL; + } + + return cli; +} + +/* Shut down a SMB connection to the LSA pipe */ + +void cli_lsa_shutdown(struct cli_state *cli) +{ + if (cli->fd != -1) cli_ulogoff(cli); + cli_shutdown(cli); +} + +/* Open a LSA policy handle */ + +uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, + uint32 des_access, POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + LSA_Q_OPEN_POL q; + LSA_R_OPEN_POL r; + LSA_SEC_QOS qos; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Initialise input parameters */ + + if (sec_qos) { + init_lsa_sec_qos(&qos, 2, 1, 0, des_access); + init_q_open_pol(&q, '\\', 0, des_access, &qos); + } else { + init_q_open_pol(&q, '\\', 0, des_access, NULL); + } + + /* Marshall data and send request */ + + if (!lsa_io_q_open_pol("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) { + return NT_STATUS_UNSUCCESSFUL; + } + + /* Unmarshall response */ + + if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) { + return NT_STATUS_UNSUCCESSFUL; + } + + result = r.status; + + /* Return output parameters */ + + if (result == NT_STATUS_NOPROBLEMO) { + *hnd = r.pol; + } + + return result; +} + +/* Close a LSA policy handle */ + +uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + LSA_Q_CLOSE q; + LSA_R_CLOSE r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_lsa_q_close(&q, hnd); + + if (!lsa_io_q_close("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) { + return NT_STATUS_UNSUCCESSFUL; + } + + /* Unmarshall response */ + + if (!lsa_io_r_close("", &r, &rbuf, 0)) { + return NT_STATUS_UNSUCCESSFUL; + } + + result = r.status; + + /* Return output parameters */ + + if (result == NT_STATUS_NOPROBLEMO) { + *hnd = r.pol; + } + + return result; +} + +/* Lookup a list of sids */ + +uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, + int num_sids, DOM_SID *sids, char ***names, + uint32 **types, int *num_names) +{ + prs_struct qbuf, rbuf; + LSA_Q_LOOKUP_SIDS q; + LSA_R_LOOKUP_SIDS r; + DOM_R_REF ref; + LSA_TRANS_NAME_ENUM t_names; + uint32 result; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_q_lookup_sids(cli->mem_ctx, &q, hnd, num_sids, sids, 1); + + if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { + return NT_STATUS_UNSUCCESSFUL; + } + + /* Unmarshall response */ + + ZERO_STRUCT(ref); + ZERO_STRUCT(t_names); + + r.dom_ref = &ref; + r.names = &t_names; + + if (!lsa_io_r_lookup_sids("", &r, &rbuf, 0)) { + return NT_STATUS_UNSUCCESSFUL; + } + + result = r.status; + + if (result != 0 && r.status != 0x107 && + r.status != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { + + /* An actual error occured */ + + goto done; + } + + result = NT_STATUS_NOPROBLEMO; + + /* Return output parameters */ + + (*num_names) = r.names->num_entries; + + if (!((*names) = (char **)malloc(sizeof(char *) * + r.names->num_entries))) { + DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!((*types) = (uint32 *)malloc(sizeof(uint32) * + r.names->num_entries))) { + DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + for (i = 0; i < r.names->num_entries; i++) { + fstring name, dom_name, full_name; + uint32 dom_idx = t_names.name[i].domain_idx; + + /* Translate optimised name through domain index array */ + + if (dom_idx != 0xffffffff) { + unistr2_to_ascii(dom_name, + &ref.ref_dom[dom_idx].uni_dom_name, + sizeof(dom_name)- 1); + unistr2_to_ascii(name, &t_names.uni_name[i], + sizeof(name) - 1); + + slprintf(full_name, sizeof(full_name) - 1, + "%s%s%s", dom_name, dom_name[0] ? + "\\" : "", name); + + (*names)[i] = strdup(full_name); + (*types)[i] = t_names.name[i].sid_name_use; + } else { + (*names)[i] = NULL; + (*types)[i] = SID_NAME_UNKNOWN; + } + } + + done: + return result; +} + +/* Lookup a list of names */ + +uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, + int num_names, char **names, DOM_SID **sids, + uint32 **types, int *num_sids) +{ + prs_struct qbuf, rbuf; + LSA_Q_LOOKUP_NAMES q; + LSA_R_LOOKUP_NAMES r; + DOM_R_REF ref; + uint32 result; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_q_lookup_names(cli->mem_ctx, &q, hnd, num_names, names); + + if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { + return NT_STATUS_UNSUCCESSFUL; + } + + /* Unmarshall response */ + + ZERO_STRUCT(ref); + r.dom_ref = &ref; + + if (!lsa_io_r_lookup_names(cli->mem_ctx, "", &r, &rbuf, 0)) { + return NT_STATUS_UNSUCCESSFUL; + } + + result = r.status; + + if (result != 0 && result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { + + /* An actual error occured */ + + goto done; + } + + result = NT_STATUS_NOPROBLEMO; + + /* Return output parameters */ + + (*num_sids) = r.num_entries; + + if (!((*sids = (DOM_SID *)malloc(sizeof(DOM_SID) * + r.num_entries)))) { + DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!((*types = (uint32 *)malloc(sizeof(uint32) * + r.num_entries)))) { + DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + for (i = 0; i < r.num_entries; i++) { + DOM_RID2 *t_rids = r.dom_rid; + uint32 dom_idx = t_rids[i].rid_idx; + uint32 dom_rid = t_rids[i].rid; + DOM_SID *sid = &(*sids)[i]; + + /* Translate optimised sid through domain index array */ + + if (dom_idx != 0xffffffff) { + + sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid); + + if (dom_rid != 0xffffffff) { + sid_append_rid(sid, dom_rid); + } + + (*types)[i] = t_rids[i].type; + } else { + ZERO_STRUCTP(sid); + (*types)[i] = SID_NAME_UNKNOWN; + } + } + + done: + return result; +} -- cgit From 369f5fd1d7a6e6298bc3cbe01e3aaed0106f6cf4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 15 Dec 2000 01:02:11 +0000 Subject: Fixed memory leaks in lsa_XX calls. Fixed memory leaks in smbcacls. Merged in fixes from appliance-head and 2.2. Fixed multiple connection.tdb open problem. Jeremy. (This used to be commit 0a40bc83e14c69a09948ec09bb6fc5026c4f4c14) --- source3/libsmb/cli_lsarpc.c | 28 +++++++++++++++++++++++++++- source3/libsmb/clientgen.c | 4 ++-- source3/libsmb/clisecdesc.c | 39 ++++++++++++++++++++++++--------------- source3/libsmb/clitrans.c | 7 ++++++- 4 files changed, 59 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 4199ab2648..60fab75cca 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -109,12 +109,16 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, if (!lsa_io_q_open_pol("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) { + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return NT_STATUS_UNSUCCESSFUL; } /* Unmarshall response */ if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) { + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return NT_STATUS_UNSUCCESSFUL; } @@ -126,6 +130,8 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, *hnd = r.pol; } + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return result; } @@ -152,12 +158,16 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) if (!lsa_io_q_close("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) { + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return NT_STATUS_UNSUCCESSFUL; } /* Unmarshall response */ if (!lsa_io_r_close("", &r, &rbuf, 0)) { + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return NT_STATUS_UNSUCCESSFUL; } @@ -169,6 +179,8 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) *hnd = r.pol; } + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return result; } @@ -200,6 +212,8 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return NT_STATUS_UNSUCCESSFUL; } @@ -212,6 +226,8 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, r.names = &t_names; if (!lsa_io_r_lookup_sids("", &r, &rbuf, 0)) { + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return NT_STATUS_UNSUCCESSFUL; } @@ -271,6 +287,9 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, } done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } @@ -301,6 +320,8 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return NT_STATUS_UNSUCCESSFUL; } @@ -309,7 +330,9 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, ZERO_STRUCT(ref); r.dom_ref = &ref; - if (!lsa_io_r_lookup_names(cli->mem_ctx, "", &r, &rbuf, 0)) { + if (!lsa_io_r_lookup_names("", &r, &rbuf, 0)) { + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return NT_STATUS_UNSUCCESSFUL; } @@ -366,5 +389,8 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, } done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d9e2f034f..1938049806 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -209,13 +209,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->inbuf = (char *)malloc(cli->bufsize); if (!cli->outbuf || !cli->inbuf) { - return False; + return NULL; } if ((cli->mem_ctx = talloc_init()) == NULL) { free(cli->outbuf); free(cli->inbuf); - return False; + return NULL; } memset(cli->outbuf, '\0', cli->bufsize); diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index b56e1ea688..d53b3073b2 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -36,7 +36,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) TALLOC_CTX *mem_ctx; prs_struct pd; SEC_DESC *psd = NULL; - SEC_DESC *ret; SIVAL(param, 0, fd); SSVAL(param, 4, 0x7); @@ -48,7 +47,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) param, 8, 4, NULL, 0, 0x10000)) { DEBUG(1,("Failed to send NT_TRANSACT_QUERY_SECURITY_DESC\n")); - return NULL; + goto cleanup; } @@ -56,12 +55,12 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) &rparam, &rparam_count, &rdata, &rdata_count)) { DEBUG(1,("Failed to recv NT_TRANSACT_QUERY_SECURITY_DESC\n")); - return NULL; + goto cleanup; } if ((mem_ctx = talloc_init()) == NULL) { DEBUG(0,("talloc_init failed.\n")); - return NULL; + goto cleanup; } prs_init(&pd, rdata_count, 4, mem_ctx, UNMARSHALL); @@ -70,13 +69,17 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) if (!sec_io_desc("sd data", &psd, &pd, 1)) { DEBUG(1,("Failed to parse secdesc\n")); - talloc_destroy(mem_ctx); - return NULL; + goto cleanup; } - ret = dup_sec_desc(psd); + cleanup: + talloc_destroy(mem_ctx); - return ret; + safe_free(rparam); + safe_free(rdata); + + prs_mem_free(&pd); + return psd; } @@ -92,10 +95,11 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) int rparam_count=0, rdata_count=0; TALLOC_CTX *mem_ctx; prs_struct pd; + BOOL ret = False; if ((mem_ctx = talloc_init()) == NULL) { DEBUG(0,("talloc_init failed.\n")); - return False; + goto cleanup; } prs_init(&pd, 0, 4, mem_ctx, MARSHALL); @@ -103,7 +107,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) if (!sec_io_desc("sd data", &sd, &pd, 1)) { DEBUG(1,("Failed to marshall secdesc\n")); - return False; + goto cleanup; } SIVAL(param, 0, fd); @@ -116,7 +120,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) param, 8, 0, pd.data_p, pd.data_offset, 0)) { DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); - return False; + goto cleanup; } @@ -124,14 +128,19 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) &rparam, &rparam_count, &rdata, &rdata_count)) { DEBUG(1,("NT_TRANSACT_SET_SECURITY_DESC failed\n")); - return False; + goto cleanup; } - if (rparam) free(rparam); - if (rdata) free(rdata); + ret = True; + + cleanup: + + safe_free(rparam); + safe_free(rdata); talloc_destroy(mem_ctx); - return True; + prs_mem_free(&pd); + return ret; } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 50ed68ee16..5cd6ae30ce 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -170,8 +170,13 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (cli_error(cli, &eclass, &ecode, NULL)) { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + if(cli->nt_pipe_fnum == 0) return(False); + + if(!(eclass == ERRDOS && ecode == ERRmoredata)) { + if (eclass != 0 && (ecode != (0x80000000 | STATUS_BUFFER_OVERFLOW))) + return(False); + } } /* parse out the lengths */ -- cgit From 862b835040694353c3ecc7bdd964332e60779723 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 18 Dec 2000 05:27:44 +0000 Subject: Streamlined exit path. Allow NULL to be passed to cli_lsa_initialise() which creates an anonymous connection to the server. (This used to be commit 8ccd06ee9635e81bdefa8ae58a88c39f132b371c) --- source3/libsmb/cli_lsarpc.c | 51 ++++++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 24 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 60fab75cca..b3b6f204d3 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -34,6 +34,7 @@ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, struct nmb_name calling, called; fstring dest_host; extern pstring global_myname; + struct ntuser_creds anon; /* Initialise cli_state information */ @@ -43,6 +44,12 @@ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, return NULL; } + if (!creds) { + ZERO_STRUCT(anon); + anon.pwd.null_pwd = 1; + creds = &anon; + } + cli_init_creds(cli, creds); /* Establish a SMB connection */ @@ -109,17 +116,15 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, if (!lsa_io_q_open_pol("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) { - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } /* Unmarshall response */ if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) { - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } result = r.status; @@ -130,8 +135,10 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, *hnd = r.pol; } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); + return result; } @@ -158,17 +165,15 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) if (!lsa_io_q_close("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) { - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } /* Unmarshall response */ if (!lsa_io_r_close("", &r, &rbuf, 0)) { - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } result = r.status; @@ -179,8 +184,10 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) *hnd = r.pol; } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); + return result; } @@ -212,9 +219,8 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } /* Unmarshall response */ @@ -226,9 +232,8 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, r.names = &t_names; if (!lsa_io_r_lookup_sids("", &r, &rbuf, 0)) { - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } result = r.status; @@ -320,9 +325,8 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } /* Unmarshall response */ @@ -331,9 +335,8 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, r.dom_ref = &ref; if (!lsa_io_r_lookup_names("", &r, &rbuf, 0)) { - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_UNSUCCESSFUL; + goto done; } result = r.status; -- cgit From cc4870aa0ecdf0784a989383e385c3bd532847f2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 18 Dec 2000 06:09:40 +0000 Subject: Added query info policy call. (This used to be commit dcea2a4bc0503822667b73d19c4f0a59b15715a5) --- source3/libsmb/cli_lsarpc.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index b3b6f204d3..3651d786ef 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -397,3 +397,89 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, return result; } + +/* Query info policy */ + +uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *hnd, + uint16 info_class, fstring domain_name, + DOM_SID * domain_sid) +{ + prs_struct qbuf, rbuf; + LSA_Q_QUERY_INFO q; + LSA_R_QUERY_INFO r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_q_query(&q, hnd, info_class); + + if (!lsa_io_q_query("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_query("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + result = r.status; + + if (result != NT_STATUS_NOPROBLEMO) { + goto done; + } + + /* Return output parameters */ + + switch (info_class) { + + case 3: + if (r.dom.id3.buffer_dom_name != 0) { + unistr2_to_ascii(domain_name, + &r.dom.id3. + uni_domain_name, + sizeof (fstring) - 1); + } + + if (r.dom.id3.buffer_dom_sid != 0) { + *domain_sid = r.dom.id3.dom_sid.sid; + } + + break; + + case 5: + + if (r.dom.id5.buffer_dom_name != 0) { + unistr2_to_ascii(domain_name, &r.dom.id5. + uni_domain_name, + sizeof (fstring) - 1); + } + + if (r.dom.id5.buffer_dom_sid != 0) { + *domain_sid = r.dom.id5.dom_sid.sid; + } + + break; + + default: + DEBUG(3, ("unknown info class %d\n", info_class)); + break; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 7bf9d8ce4bb7e96a4c72f674e21d015b1ef1481e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Dec 2000 23:57:48 +0000 Subject: Fixed bug found by Gerald. If a Samba server joins a domain and is set to search for a DC to authenticate to using the "*" syntax than ensure that for the first hour after the password change is searches for the PDC using the 1B name not the 1C name as domain replication may not have occured. Jeremy. (This used to be commit c25533de9918ed9b0c79fd039e11d1b79f513db0) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a8cc2fcf3a..fa90691a95 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1063,7 +1063,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... /******************************************************** Get the IP address list of the PDC/BDC's of a Domain. *********************************************************/ -BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count) +BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *count) { - return internal_resolve_name(group, 0x1C, ip_list, count); + return internal_resolve_name(group, pdc_only ? 0x1B : 0x1C, ip_list, count); } -- cgit From abb9a2de72073a8a6f332b60d74af9eb6c3d6f25 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 20 Dec 2000 03:22:51 +0000 Subject: implemented a much nicer name_status() interface. It now returns a list of structures rather than the dodgy parsing code we had before this also gets smbw working correctly with no initial workgroup (using name_status_find on __MSBROWSE__ returns) (This used to be commit f2be88a8738a39ca5c98936edb7537cd701348a1) --- source3/libsmb/namequery.c | 289 +++++++++++++++++++-------------------------- 1 file changed, 122 insertions(+), 167 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index fa90691a95..59a3856cfb 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -45,168 +45,155 @@ static int generate_trn_id(void) /**************************************************************************** - Interpret a node status response. + parse a node status response into an array of structures ****************************************************************************/ - -static void _interpret_node_status(char *p, char *master,char *rname) +static struct node_status *parse_node_status(char *p, int *num_names) { - int numnames = CVAL(p,0); - DEBUG(1,("received %d names\n",numnames)); - - if (rname) *rname = 0; - if (master) *master = 0; - - p += 1; - while (numnames--) { - char qname[17]; - int type; - fstring flags; - int i; - *flags = 0; - StrnCpy(qname,p,15); - type = CVAL(p,15); - p += 16; - - fstrcat(flags, (p[0] & 0x80) ? " " : " "); - if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B "); - if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P "); - if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M "); - if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H "); - if (p[0] & 0x10) fstrcat(flags," "); - if (p[0] & 0x08) fstrcat(flags," "); - if (p[0] & 0x04) fstrcat(flags," "); - if (p[0] & 0x02) fstrcat(flags," "); - - if (master && !*master && type == 0x1d) { - StrnCpy(master,qname,15); - trim_string(master,NULL," "); - } + struct node_status *ret; + int i; - if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) { - StrnCpy(rname,qname,15); - trim_string(rname,NULL," "); - } - - for (i = strlen( qname) ; --i >= 0 ; ) { - if (!isprint((int)qname[i])) qname[i] = '.'; - } - DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags)); - p+=2; - } + *num_names = CVAL(p,0); + + if (*num_names == 0) return NULL; + + ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names)); + if (!ret) return NULL; - DEBUG(1,("num_good_sends=%d num_good_receives=%d\n", - IVAL(p,20),IVAL(p,24))); + p++; + for (i=0;i< *num_names;i++) { + StrnCpy(ret[i].name,p,15); + trim_string(ret[i].name,NULL," "); + ret[i].type = CVAL(p,15); + ret[i].flags = p[16]; + p += 18; + } + return ret; } + /**************************************************************************** - Internal function handling a netbios name status query on a host. +do a NBT node status query on an open socket and return an array of +structures holding the returned names or NULL if the query failed **************************************************************************/ -static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse, - struct in_addr to_ip,char *master, - char *rname, BOOL verbose, - void (*fn_interpret_node_status)(char *, char *,char *)) +struct node_status *name_status_query(int fd,struct nmb_name *name, + struct in_addr to_ip, int *num_names) { - BOOL found=False; - int retries = 2; - int retry_time = 2000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - - memset((char *)&p,'\0',sizeof(p)); - - nmb->header.name_trn_id = generate_trn_id(); - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = False; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type); + BOOL found=False; + int retries = 2; + int retry_time = 2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + struct node_status *ret; + + ZERO_STRUCT(p); + + nmb->header.name_trn_id = generate_trn_id(); + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = False; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = False; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + nmb->question.question_name = *name; + nmb->question.question_type = 0x21; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return NULL; - nmb->question.question_type = 0x21; - nmb->question.question_class = 0x1; + retries--; - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; + while (1) { + struct timeval tval2; + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!found && !send_packet(&p)) + return NULL; + GetTimeOfDay(&tval); + retries--; + } - GetTimeOfDay(&tval); + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount || + nmb2->answers->rr_type != 0x21) { + /* XXXX what do we do with this? could be a + redirect, but we'll discard it for the + moment */ + free_packet(p2); + continue; + } - if (!send_packet(&p)) - return(False); + ret = parse_node_status(&nmb2->answers->rdata[0], num_names); + free_packet(p2); + return ret; + } + } + + return NULL; +} - retries--; - while (1) { - struct timeval tval2; - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!found && !send_packet(&p)) - return False; - GetTimeOfDay(&tval); - retries--; - } +/**************************************************************************** +find the first type XX name in a node status reply - used for finding +a servers name given its IP +return the matched name in *name +**************************************************************************/ +BOOL name_status_find(int type, struct in_addr to_ip, char *name) +{ + struct node_status *status; + struct nmb_name nname; + int count, i; + int sock; - if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); + sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); + if (sock == -1) return False; - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount || - nmb2->answers->rr_type != 0x21) { - /* XXXX what do we do with this? could be a - redirect, but we'll discard it for the - moment */ - free_packet(p2); - continue; - } + make_nmb_name(&nname, "*", 0); + status = name_status_query(sock, &nname, to_ip, &count); + close(sock); + if (!status) return False; - if(fn_interpret_node_status) - (*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname); - free_packet(p2); - return(True); - } - } + for (i=0;i name. -*********************************************************/ - -static void _lookup_pdc_name(char *p, char *master,char *rname) -{ - int numnames = CVAL(p,0); - - *rname = '\0'; - - p += 1; - while (numnames--) { - int type = CVAL(p,15); - if(type == 0x20) { - StrnCpy(rname,p,15); - trim_string(rname,NULL," "); - return; - } - p += 18; - } -} -#endif /* I_HATE_WINDOWS_REPLY_CODE */ - /******************************************************** Lookup a PDC name given a Domain name and IP address. *********************************************************/ @@ -862,17 +825,9 @@ BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pd * query here... JRA. */ - int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); - - if(sock == -1) - return False; - *pdc_name = '\0'; - ret = internal_name_status(sock,"*SMBSERVER",0x20,True, - *pdc_ip,NULL,pdc_name,False,_lookup_pdc_name); - - close(sock); + ret = name_status_find(0x20,*pdc_ip,pdc_name); if(ret && *pdc_name) { fstrcpy(ret_name, pdc_name); -- cgit From b37ac378cff2b2cbc3266ca85ebd738694727526 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 21 Dec 2000 00:30:32 +0000 Subject: Replace magic number with constant. (This used to be commit 1a228868cf14418894b798f19955df3276bd1089) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8a7c6da1af..3e41ec8296 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -438,7 +438,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); - if (cli->capabilities & 1) { + if (cli->capabilities & CAP_RAW_MODE) { cli->readbraw_supported = True; cli->writebraw_supported = True; } -- cgit From 8fd4d9fab4195dcfcd13c455c3c2da665cbe8533 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 21 Dec 2000 05:22:15 +0000 Subject: Added a cli_nt_create_uni() to do a ntcreate&x with a unicode filename, regardless of the settings negotiated in the flags2 smb field. (This used to be commit c4476c6315a6e99dd4a1d0e3185a0d17c073205d) --- source3/libsmb/clifile.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index cb492f1539..ce9a79ede3 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -163,8 +163,6 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) return True; } - - /**************************************************************************** open a file ****************************************************************************/ @@ -212,6 +210,55 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) return SVAL(cli->inbuf,smb_vwv2 + 1); } +/**************************************************************************** +open a file +****************************************************************************/ +int cli_nt_create_uni(struct cli_state *cli, char *fname, uint32 DesiredAccess) +{ + pstring uni; + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,24,(strlen(fname) + 1) * 2 + 1,True); + + CVAL(cli->outbuf,smb_com) = SMBntcreateX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + if (cli->use_oplocks) + SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); + else + SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); + SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); + SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); + SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); + SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); + SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname) * 2); + + p = smb_buf(cli->outbuf); + p++; /* Alignment */ + pstrcpy(uni, fname); + unix_to_dos(uni, True); + dos_struni2(p, uni, (strlen(fname) + 1) * 2); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2 + 1); +} + /**************************************************************************** open a file -- cgit From b87c484051e8fcb4fc920d7355eb92ff68a41350 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 26 Dec 2000 05:57:10 +0000 Subject: First pass at the libsmbclient code ... This code handles the basic stuff and compiles and links under Linux, but I do not know about any other operating systems. Now onto directory listing routines, including those that list workgroups, servers, etc. Nothing is built automatically yet, you have to make client/testsmbc to build the library and test program. Also, no make install targets are defined for libsmbclient.so as yet, either. Would be good if people test on operating systems other than Linux. (This used to be commit 51c0436a50e9f9274cee9de043bbefc93aff8011) --- source3/libsmb/libsmbclient.c | 1140 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1140 insertions(+) create mode 100644 source3/libsmb/libsmbclient.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c new file mode 100644 index 0000000000..b299e59f7c --- /dev/null +++ b/source3/libsmb/libsmbclient.c @@ -0,0 +1,1140 @@ +/* + Unix SMB/Netbios implementation. + Version 2.0 + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000 + Copyright (C) John Terpstra 2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "libsmbclient.h" + +/* Structure for servers ... Held here so we don't need an include ... + * May be better to put in an include file + */ + +struct smbc_server { + struct smbc_server *next, *prev; + struct cli_state cli; + dev_t dev; + char *server_name; + char *share_name; + char *workgroup; + char *username; + BOOL no_pathinfo2; +}; + +struct smbc_file { + int cli_fd; + int smbc_fd; + char *fname; + off_t offset; + struct smbc_server *srv; + BOOL file; +}; + +static int smbc_initialized = 0; +static smbc_get_auth_data_fn smbc_auth_fn = NULL; +static int smbc_debug; +static int smbc_start_fd; +static int smbc_max_fd = 10000; +static struct smbc_file **smbc_file_table; + +/* + * Clean up a filename by removing redundent stuff + */ + +static void +clean_fname(char *name) +{ + char *p, *p2; + int l; + int modified = 1; + + if (!name) return; + + while (modified) { + modified = 0; + + DEBUG(5,("cleaning %s\n", name)); + + if ((p=strstr(name,"/./"))) { + modified = 1; + while (*p) { + p[0] = p[2]; + p++; + } + } + + if ((p=strstr(name,"//"))) { + modified = 1; + while (*p) { + p[0] = p[1]; + p++; + } + } + + if (strcmp(name,"/../")==0) { + modified = 1; + name[1] = 0; + } + + if ((p=strstr(name,"/../"))) { + modified = 1; + for (p2=(p>name?p-1:p);p2>name;p2--) { + if (p2[0] == '/') break; + } + while (*p2) { + p2[0] = p2[3]; + p2++; + } + } + + if (strcmp(name,"/..")==0) { + modified = 1; + name[1] = 0; + } + + l = strlen(name); + p = l>=3?(name+l-3):name; + if (strcmp(p,"/..")==0) { + modified = 1; + for (p2=p-1;p2>name;p2--) { + if (p2[0] == '/') break; + } + if (p2==name) { + p[0] = '/'; + p[1] = 0; + } else { + p2[0] = 0; + } + } + + l = strlen(name); + p = l>=2?(name+l-2):name; + if (strcmp(p,"/.")==0) { + if (p == name) { + p[1] = 0; + } else { + p[0] = 0; + } + } + + if (strncmp(p=name,"./",2) == 0) { + modified = 1; + do { + p[0] = p[2]; + } while (*p++); + } + + l = strlen(p=name); + if (l > 1 && p[l-1] == '/') { + modified = 1; + p[l-1] = 0; + } + } +} + +/* + * Function to parse a path and turn it into components + * + * We accept smb://server/share/path... + * We also accept //server/share/path ... + */ + +static const char *smbc_prefix = "smb:"; + +static int +smbc_parse_path(const char *fname, char *server, char *share, char *path) +{ + static pstring s; + char *p; + int len; + fstring workgroup; + + pstrcpy(s, fname); + + /* clean_fname(s); causing problems ... */ + + /* see if it has the right prefix */ + len = strlen(smbc_prefix); + if (strncmp(s,smbc_prefix,len) || + (s[len] != '/' && s[len] != 0)) return -1; /* What about no smb: ? */ + + p = s + len; + + /* Watch the test below, we are testing to see if we should exit */ + + if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { + + return -1; + + } + + p += 2; /* Skip the // or \\ */ + + /* ok, its for us. Now parse out the server, share etc. */ + + if (!next_token(&p, server, "/", sizeof(fstring))) { + + return -1; + + } + + if (!next_token(&p, share, "/", sizeof(fstring))) { + + return -1; + + } + + pstrcpy(path, p); + + all_string_sub(path, "/", "\\", 0); + + return 0; +} + +/* + * Convert an SMB error into a UNIX error ... + */ + +int smbc_errno(struct cli_state *c) +{ + uint8 eclass; + uint32 ecode; + int ret; + + ret = cli_error(c, &eclass, &ecode, NULL); + + if (ret) { + DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", + (int)eclass, (int)ecode, (int)ecode, ret)); + } + return ret; +} + +/* + * Connect to a server, possibly on an existing connection + */ + +static struct smbc_server *smbc_srvs; +static pstring my_netbios_name; + +struct smbc_server *smbc_server(char *server, char *share) +{ + struct smbc_server *srv=NULL; + struct cli_state c; + char *username = NULL; + char *password = NULL; + char *workgroup = NULL; + struct nmb_name called, calling; + char *p, *server_n = server; + fstring group; + pstring ipenv; + struct in_addr ip; + extern struct in_addr ipzero; + + ip = ipzero; + ZERO_STRUCT(c); + + smbc_auth_fn(server, share, &workgroup, &username, &password); + + /* try to use an existing connection */ + for (srv=smbc_srvs;srv;srv=srv->next) { + if (strcmp(server,srv->server_name)==0 && + strcmp(share,srv->share_name)==0 && + strcmp(workgroup,srv->workgroup)==0 && + strcmp(username, srv->username) == 0) + return srv; + } + + if (server[0] == 0) { + errno = EPERM; + return NULL; + } + + make_nmb_name(&calling, my_netbios_name, 0x0); + make_nmb_name(&called , server, 0x20); + + DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server)); + + if ((p=strchr(server_n,'#')) && + (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { + struct in_addr sip; + pstring s; + + fstrcpy(group, server_n); + p = strchr(group,'#'); + *p = 0; + + } + + DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); + + again: + slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); + + ip = ipzero; + + /* have to open a new connection */ + if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { + errno = ENOENT; + return NULL; + } + + if (!cli_session_request(&c, &calling, &called)) { + cli_shutdown(&c); + if (strcmp(called.name, "*SMBSERVER")) { + make_nmb_name(&called , "*SMBSERVER", 0x20); + goto again; + } + errno = ENOENT; + return NULL; + } + + DEBUG(4,(" session request ok\n")); + + if (!cli_negprot(&c)) { + cli_shutdown(&c); + errno = ENOENT; + return NULL; + } + + if (!cli_session_setup(&c, username, + password, strlen(password), + password, strlen(password), + workgroup) && + /* try an anonymous login if it failed */ + !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) { + cli_shutdown(&c); + errno = EPERM; + return NULL; + } + + DEBUG(4,(" session setup ok\n")); + + if (!cli_send_tconX(&c, share, "?????", + password, strlen(password)+1)) { + errno = smbc_errno(&c); + cli_shutdown(&c); + return NULL; + } + + DEBUG(4,(" tconx ok\n")); + + srv = (struct smbc_server *)malloc(sizeof(*srv)); + if (!srv) { + errno = ENOMEM; + goto failed; + } + + ZERO_STRUCTP(srv); + + srv->cli = c; + + srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); + + srv->server_name = strdup(server); + if (!srv->server_name) { + errno = ENOMEM; + goto failed; + } + + srv->share_name = strdup(share); + if (!srv->share_name) { + errno = ENOMEM; + goto failed; + } + + srv->workgroup = strdup(workgroup); + if (!srv->workgroup) { + errno = ENOMEM; + goto failed; + } + + srv->username = strdup(username); + if (!srv->username) { + errno = ENOMEM; + goto failed; + } + + DLIST_ADD(smbc_srvs, srv); + + return srv; + + failed: + cli_shutdown(&c); + if (!srv) return NULL; + + if (srv->server_name) free(srv->server_name); + if (srv->share_name) free(srv->share_name); + free(srv); + return NULL; +} + +/* + *Initialise the library etc + */ + +int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) +{ + static pstring workgroup; + int p, pid; + char *user = NULL, *host = NULL; + + smbc_initialized = 1; + smbc_auth_fn = fn; + smbc_debug = debug; + + /* + * We try to construct our netbios name from our hostname etc + */ + + user = getenv("USER"); + if (!user) user = ""; + + pid = getpid(); + + /* + * Hmmm, I want to get hostname as well, but I am too lazy for the moment + */ + + slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); + pstrcpy(workgroup, wgroup); + + charset_initialise(); + + /* Here we would open the smb.conf file if needed ... */ + + /* To do soon ... try $HOME/.smb/smb.conf first ... */ + + /* + * Now initialize the file descriptor array and figure out what the + * max open files is, so we can return FD's that are above the max + * open file, and separated by a guard band + */ + +#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) + do { + struct rlimit rlp; + + if (getrlimit(RLIMIT_NOFILE, &rlp)) { + + DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno))); + + smbc_start_fd = 1000000; + smbc_max_fd = 10000; /* FIXME, should be a define ... */ + + } + else { + + smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */ + smbc_max_fd = 10000; + + } + } while ( 0 ); +#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */ + + smbc_start_fd = 1000000; + smbc_max_fd = 10000; /* FIXME, should be a define ... */ + +#endif + + smbc_file_table = malloc(smbc_max_fd * sizeof(struct smbc_file *)); + + for (p = 0; p < smbc_max_fd; p++) + smbc_file_table[p] = NULL; + + if (!smbc_file_table) + return ENOMEM; + + smbc_start_fd = 100000; /* FIXME: Figure it out */ + + return 0; /* Success */ + +} + +/* + * Routine to open() a file ... + */ + +int smbc_open(const char *fname, int flags, mode_t mode) +{ + fstring server, share; + pstring path; + struct smbc_server *srv = NULL; + struct smbc_file *file = NULL; + int fd; + + if (!smbc_initialized) { + + errno = EUCLEAN; /* Best I can think of ... */ + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + smbc_parse_path(fname, server, share, path); /* FIXME, check errors */ + + srv = smbc_server(server, share); + + if (!srv) { + + return -1; /* smbc_server sets errno */ + + } + + if (path[strlen(path) - 1] == '\\') { + + fd = -1; + + } + else { + + int slot = 0; + + /* Find a free slot first */ + + while (smbc_file_table[slot]) + slot++; + + if (slot > smbc_max_fd) return ENOMEM; /* FIXME, is this best? */ + + smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); + + if (!smbc_file_table[slot]) + return ENOMEM; + + fd = cli_open(&srv->cli, path, flags, DENY_NONE); + + /* Fill in file struct */ + + smbc_file_table[slot]->cli_fd = fd; + smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; + smbc_file_table[slot]->fname = strdup(fname); + smbc_file_table[slot]->srv = srv; + smbc_file_table[slot]->offset = 0; + smbc_file_table[slot]->file = True; + + return smbc_file_table[slot]->smbc_fd; + + } + + /* Check if opendir needed ... */ + + if (fd == -1) { + int eno = 0; + + eno = smbc_errno(&srv->cli); + fd = smbc_dir_open(fname); + if (fd < 0) errno = eno; + return fd; + + } + + return 1; /* Success, with fd ... */ + + failed: + + /*FIXME, clean up things ... */ + return -1; + +} + +/* + * Routine to create a file + */ + +static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ + +int smbc_creat(const char *path, mode_t mode) +{ + return smbc_open(path, creat_bits, mode); +} + +/* + * Routine to read() a file ... + */ + +ssize_t smbc_read(int fd, void *buf, size_t count) +{ + struct smbc_file *fe; + int ret; + + DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count)); + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + if (!fe->file) { + + errno = EBADF; + return -1; + + } + + ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count); + + if (ret < 0) { + + errno = smbc_errno(&fe->srv->cli); + return -1; + + } + + fe->offset += ret; + + DEBUG(4, (" --> %d\n", ret)); + + return ret; /* Success, ret bytes of data ... */ + +} + +/* + * Routine to write() a file ... + */ + +ssize_t smbc_write(int fd, void *buf, size_t count) +{ + int ret; + struct smbc_file *fe; + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count); + + if (ret < 0) { + + errno = smbc_errno(&fe->srv->cli); + return -1; + + } + + fe->offset += ret; + + return ret; /* Success, 0 bytes of data ... */ +} + +/* + * Routine to close() a file ... + */ + +int smbc_close(int fd) +{ + struct smbc_file *fe; + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + if (!fe->file) { + + return smbc_closedir(fd); + + } + + if (!cli_close(&fe->srv->cli, fe->cli_fd)) { + + errno = smbc_errno(&fe->srv->cli); /* FIXME, should we deallocate slot? */ + return -1; + + } + + free(fe); + smbc_file_table[fd - smbc_start_fd] = NULL; + + return 0; +} + +/* + * Routine to unlink() a file + */ + +int smbc_unlink(const char *fname) +{ + fstring server, share; + pstring path; + struct smbc_server *srv = NULL; + + if (!smbc_initialized) { + + errno = EUCLEAN; /* Best I can think of ... */ + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + smbc_parse_path(fname, server, share, path); /* FIXME, check errors */ + + srv = smbc_server(server, share); + + if (!srv) { + + return -1; /* smbc_server sets errno */ + + } + + /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) { + + int job = smbc_stat_printjob(srv, path, NULL, NULL); + if (job == -1) { + + return -1; + + } + if (cli_printjob_del(&srv->cli, job) != 0) { + + return -1; + + } + } else */ + + if (!cli_unlink(&srv->cli, path)) { + + errno = smbc_errno(&srv->cli); + return -1; + + } + + return 0; /* Success ... */ + +} + +/* + * Routine to rename() a file + */ + +int smbc_rename(const char *oname, const char *nname) +{ + fstring server1, share1, server2, share2; + pstring path1, path2; + struct smbc_server *srv = NULL; + + if (!smbc_initialized) { + + errno = EUCLEAN; /* Best I can think of ... */ + return -1; + + } + + if (!oname || !nname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); + + smbc_parse_path(oname, server1, share1, path1); + smbc_parse_path(nname, server2, share2, path2); + + if (strcmp(server1, server2) || strcmp(share1, share2)) { + + /* Can't rename across file systems */ + + errno = EXDEV; + return -1; + + } + + srv = smbc_server(server1, share1); + if (!srv) { + + return -1; + + } + + if (!cli_rename(&srv->cli, path1, path2)) { + int eno = smbc_errno(&srv->cli); + + if (eno != EEXIST || + !cli_unlink(&srv->cli, path2) || + !cli_rename(&srv->cli, path1, path2)) { + + errno = eno; + return -1; + + } + } + + return 0; /* Success */ + +} + +/* + * A routine to lseek() a file + */ + +off_t smbc_lseek(int fd, off_t offset, int whence) +{ + struct smbc_file *fe; + size_t size; + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + if (!fe->file) { + + return smbc_lseekdir(fd, offset, whence); + + } + + switch (whence) { + case SEEK_SET: + fe->offset = offset; + break; + + case SEEK_CUR: + fe->offset += offset; + break; + + case SEEK_END: + if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + NULL, NULL, NULL) && + !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + NULL)) { + + errno = EINVAL; + return -1; + } + fe->offset = size + offset; + break; + + default: + errno = EINVAL; + break; + + } + + return fe->offset; + +} + +/* + * Generate an inode number from file name for those things that need it + */ + +static +ino_t smbc_inode(const char *name) +{ + + if (!*name) return 2; /* FIXME, why 2 ??? */ + return (ino_t)str_checksum(name); + +} + +/* + * Routine to put basic stat info into a stat structure ... Used by stat and + * fstat below. + */ + +static +int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) +{ + + st->st_mode = 0; + + if (IS_DOS_DIR(mode)) { + st->st_mode = SMBC_DIR_MODE; + } else { + st->st_mode = SMBC_FILE_MODE; + } + + if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; + if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; + if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; + if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; + + st->st_size = size; + st->st_blksize = 512; + st->st_blocks = (size+511)/512; + st->st_uid = getuid(); + st->st_gid = getgid(); + + if (IS_DOS_DIR(mode)) { + st->st_nlink = 2; + } else { + st->st_nlink = 1; + } + + if (st->st_ino == 0) { + st->st_ino = smbc_inode(fname); + } +} + +/* + * Get info from an SMB server on a file. Use a qpathinfo call first + * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo + */ + +BOOL smbc_getatr(struct smbc_server *srv, char *path, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + SMB_INO_T *ino) +{ + DEBUG(4,("sending qpathinfo\n")); + + if (!srv->no_pathinfo2 && + cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, + size, mode, ino)) return True; + + /* if this is NT then don't bother with the getatr */ + if (srv->cli.capabilities & CAP_NT_SMBS) return False; + + if (cli_getatr(&srv->cli, path, mode, size, m_time)) { + a_time = c_time = m_time; + srv->no_pathinfo2 = True; + return True; + } + return False; +} + +/* + * Routine to stat a file given a name + */ + +int smbc_stat(const char *fname, struct stat *st) +{ + struct smbc_server *srv; + fstring server, share; + pstring path; + time_t m_time = 0, a_time = 0, c_time = 0; + size_t size = 0; + uint16 mode = 0; + SMB_INO_T ino = 0; + + if (!smbc_initialized) { + + errno = EUCLEAN; /* Best I can think of ... */ + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("stat(%s)\n", fname)); + + smbc_parse_path(fname, server, share, path); + + srv = smbc_server(server, share); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { + + mode = aDIR | aRONLY; + + } + else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { + + if (strcmp(path, "\\") == 0) { + + mode = aDIR | aRONLY; + + } + else { + + mode = aRONLY; + smbc_stat_printjob(srv, path, &size, &m_time); + c_time = a_time = m_time; + + } + else { */ + + if (!smbc_getatr(srv, path, &mode, &size, + &c_time, &a_time, &m_time, &ino)) { + + errno = smbc_errno(&srv->cli); + return -1; + + } + + /* } */ + + st->st_ino = ino; + + smbc_setup_stat(st, path, size, mode); + + st->st_atime = a_time; + st->st_ctime = c_time; + st->st_mtime = m_time; + st->st_dev = srv->dev; + + return 0; + +} + +/* + * Routine to stat a file given an fd + */ + +int smbc_fstat(int fd, struct stat *st) +{ + struct smbc_file *fe; + time_t c_time, a_time, m_time; + size_t size; + uint16 mode; + SMB_INO_T ino = 0; + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + if (!fe->file) { + + return smbc_fstatdir(fd, st); + + } + + if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, + &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) && + !cli_getattrE(&fe->srv->cli, fe->cli_fd, + &mode, &size, &c_time, &a_time, &m_time)) { + + errno = EINVAL; + return -1; + + } + + st->st_ino = ino; + + smbc_setup_stat(st, fe->fname, size, mode); + + st->st_atime = a_time; + st->st_ctime = c_time; + st->st_mtime = m_time; + st->st_dev = fe->srv->dev; + + return 0; + +} + +/* + * Routine to open a directory + */ + +int smbc_dir_open(const char *fname) +{ + + return 0; + +} + +/* + * Routine to close a directory + */ + +int smbc_closedir(int fd) +{ + + return 0; + +} + +/* + * Routine to get a directory entry + */ + +int smbc_getdents(unsigned int fd, struct dirent *dirp, int count) +{ + + return 0; + +} + +/* + * Routine to create a directory ... + */ + +int smbc_mkdir(const char *fname, mode_t mode) +{ + +} + +/* + * Routine to seek on a directory + */ + +int smbc_lseekdir(int fd, off_t offset, int whence) +{ + + return 0; + +} + +/* + * Routine to fstat a dir + */ + +int smbc_fstatdir(int fd, struct stat *st) +{ + + return 0; + +} -- cgit From e86cbff0a9f463eef7c3b92081908be4f83f595b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Jan 2001 23:41:15 +0000 Subject: Return EACCES for bad password. (This used to be commit 143006d32f0a0d339b870741b811ec49795b7099) --- source3/libsmb/clierror.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 4c6d9a49f2..eb2ca624e8 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -202,7 +202,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ } if (rcls == ERRSRV) { switch (code) { - case ERRbadpw: return EPERM; + case ERRbadpw: return EACCES; case ERRaccess: return EACCES; case ERRnoresource: return ENOMEM; case ERRinvdevice: return ENODEV; -- cgit From b6cb83d0d11cdea2fed06f63dffa48f4ed22d290 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 3 Jan 2001 05:19:21 +0000 Subject: Add a new file clidgram with routines that are used by the libsmbclient code. These routines handle the sending of dgrams in ways that don't bind us to the nmbd code, but we may merge the two routines at some stage. Also fix Makefile.in so the new code is compiled ... Let's see whether or not it compiles on other architectures ... Seems OK under Linux. (This used to be commit f7466ba67cb6f863ee495e6de884e9b7a2e49430) --- source3/libsmb/clidgram.c | 239 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 source3/libsmb/clidgram.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c new file mode 100644 index 0000000000..b76d46e1bf --- /dev/null +++ b/source3/libsmb/clidgram.c @@ -0,0 +1,239 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client dgram calls + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Richard Sharpe 2001 + Copyright (C) John Terpstra 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +/* + * cli_send_mailslot, send a mailslot for client code ... + */ + +static int dgram_sock = -1; + +int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len, + const char *srcname, int src_type, + const char *dstname, int dest_type, + struct in_addr dest_ip, struct in_addr src_ip, + int dest_port) +{ + struct packet_struct p; + struct dgram_packet *dgram = &p.packet.dgram; + struct sockaddr_in sock_out; + char *ptr, *p2; + char tmp[4]; + + bzero((char *)&p, sizeof(p)); + + /* + * First, check if we have an open socket to the dest IP + */ + + if (dgram_sock < 1) { + + int name_size; + + if ((dgram_sock = open_socket_out(SOCK_DGRAM, &dest_ip, 138, LONG_CONNECT_TIMEOUT)) < 0) { + + DEBUG(4, ("open_sock_out failed ...")); + return False; + + } + + /* Make it a broadcast socket ... */ + + set_socket_options(dgram_sock, "SO_BROADCAST"); + + /* Now, bind my addr to it ... */ + + bzero((char *)&sock_out, sizeof(sock_out)); + putip((char *)&sock_out.sin_addr, (char *)&src_ip); + sock_out.sin_port = INADDR_ANY; + sock_out.sin_family = AF_INET; + + bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)); + + /* Now, figure out what socket name we were bound to. We want the port */ + + name_size = sizeof(sock_out); + + getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size); + + fprintf(stderr, "Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port)); + + } + + /* + * Next, build the DGRAM ... + */ + + /* DIRECT GROUP or UNIQUE datagram. */ + dgram->header.msg_type = unique ? 0x10 : 0x11; + dgram->header.flags.node_type = M_NODE; + dgram->header.flags.first = True; + dgram->header.flags.more = False; + dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100); + dgram->header.source_ip = src_ip; + dgram->header.source_port = ntohs(sock_out.sin_port); + dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ + dgram->header.packet_offset = 0; + + make_nmb_name(&dgram->source_name,srcname,src_type); + make_nmb_name(&dgram->dest_name,dstname,dest_type); + + ptr = &dgram->data[0]; + + /* Setup the smb part. */ + ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ + memcpy(tmp,ptr,4); + set_message(ptr,17,17 + len,True); + memcpy(ptr,tmp,4); + + CVAL(ptr,smb_com) = SMBtrans; + SSVAL(ptr,smb_vwv1,len); + SSVAL(ptr,smb_vwv11,len); + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); + SSVAL(ptr,smb_vwv13,3); + SSVAL(ptr,smb_vwv14,1); + SSVAL(ptr,smb_vwv15,1); + SSVAL(ptr,smb_vwv16,2); + p2 = smb_buf(ptr); + pstrcpy(p2,mailslot); + p2 = skip_string(p2,1); + + memcpy(p2,buf,len); + p2 += len; + + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ + + p.ip = dest_ip; + p.port = dest_port; + p.fd = dgram_sock; + p.timestamp = time(NULL); + p.packet_type = DGRAM_PACKET; + + DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot, + nmb_namestr(&dgram->source_name), inet_ntoa(src_ip))); + DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip))); + + return send_packet(&p); + +} + +/* + * cli_get_response: Get a response ... + */ +int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz) +{ + struct packet_struct *packet; + + packet = read_packet(dgram_sock, DGRAM_PACKET); + + if (packet) { /* We got one, pull what we want out of the SMB data ... */ + + struct dgram_packet *dgram = &packet->packet.dgram; + + /* + * We should probably parse the SMB, but for now, we will pull what + * from fixed, known locations ... + */ + + fprintf(stderr, "Packet: Data is: %s\n", &dgram->data[92]); + + /* Copy the data to buffer, respecting sizes ... */ + + bcopy(&dgram->data[92], buf, MIN(bufsiz, (dgram->datasize - 92))); + + } + else + return -1; + +} + +/* + * cli_get_backup_list: Send a get backup list request ... + */ + +static char cli_backup_list[1024]; + +int cli_get_backup_list(const char *myname, const char *send_to_name) +{ + char outbuf[15]; + char *p; + struct in_addr sendto_ip, my_ip; + + if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) { + + fprintf(stderr, "Could not resolve name: %s<1D>\n", send_to_name); + + } + + inet_aton("10.0.0.6", &my_ip); + + if (!resolve_name(myname, &my_ip, 0x00)) { + + fprintf(stderr, "Could not resolve name: %s<00>\n", myname); + + } + + bzero(cli_backup_list, sizeof(cli_backup_list)); + bzero(outbuf, sizeof(outbuf)); + + p = outbuf; + + SCVAL(p, 0, ANN_GetBackupListReq); + p++; + + SCVAL(p, 0, 1); /* Count pointer ... */ + p++; + + SIVAL(p, 0, 1); /* The sender's token ... */ + p += 4; + + cli_send_mailslot(True, "\\MAILSLOT\\BROWSE", outbuf, PTR_DIFF(p, outbuf), + myname, 0, send_to_name, 0x1d, sendto_ip, my_ip, 138); + + /* We should check the error and return if we got one */ + + /* Now, get the response ... */ + + cli_get_response(True, "\\MAILSLOT\\BROWSE", cli_backup_list, sizeof(cli_backup_list)); + + /* Should check the response here ... FIXME */ + +} + +/* + * cli_get_backup_server: Get the backup list and retrieve a server from it + */ + +int cli_get_backup_server(char *my_name, char *target, char *servername, int namesize) +{ + + /* Get the backup list first. We could pull this from the cache later */ + + cli_get_backup_list(my_name, target); /* FIXME: Check the response */ + + strncpy(servername, cli_backup_list, MIN(16, namesize)); + +} -- cgit From 92ebc81734a8a4165f88eeba9c05a05ea2917584 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 4 Jan 2001 11:35:55 +0000 Subject: I need a callback arg for cli_NetServerEnum and cli_RNetShareEnum, so I had to modifiy any routine that calls it to pass NULL and so forth. Should have no impact. It compiles OK. (This used to be commit 7f862e387f935a2125481338eee850afcb8d82ba) --- source3/libsmb/clirap.c | 52 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 44 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 085b1c35bb..cd261eac59 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -137,7 +137,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) /**************************************************************************** call a NetShareEnum - try and browse available connections on a host ****************************************************************************/ -int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *)) +int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state) { char *rparam = NULL; char *rdata = NULL; @@ -184,7 +184,7 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co char *cmnt = comment_offset?(rdata+comment_offset-converter):""; dos_to_unix(sname,True); dos_to_unix(cmnt,True); - fn(sname, type, cmnt); + fn(sname, type, cmnt, state); } } else { DEBUG(4,("NetShareEnum res=%d\n", res)); @@ -210,7 +210,8 @@ The callback function takes 3 arguments: the machine name, the server type and the comment. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *)) + void (*fn)(const char *, uint32, const char *, void *), + void *state) { char *rparam = NULL; char *rdata = NULL; @@ -219,16 +220,38 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, pstring param; int uLevel = 1; int count = -1; + + /* + * First, check that the stype is reasonable ... + */ + + if (stype&0x80000000 && stype&0x7FFFFFFF) { + + /* Set an error here ... */ + + return False; + + } /* send a SMBtrans command with api NetServerEnum */ p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - pstrcpy(p,"WrLehDz"); + if (!(stype&0x80000000)) + pstrcpy(p,"WrLehDz"); + else + pstrcpy(p,"WrLehDO"); p = skip_string(p,1); - pstrcpy(p,"B16BBDz"); - + if (!(stype&0x80000000)) { + pstrcpy(p,"B16BBDz"); + uLevel = 1; + } + else { + pstrcpy(p,"B16"); + uLevel = 0; + } + p = skip_string(p,1); SSVAL(p,0,uLevel); SSVAL(p,2,CLI_BUFFER_SIZE); @@ -255,7 +278,9 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, count=SVAL(rparam,4); p = rdata; - for (i = 0;i < count;i++, p += 26) { + + if (!(stype&0x80000000)) { + for (i = 0;i < count;i++, p += 26) { char *sname = p; int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; char *cmnt = comment_offset?(rdata+comment_offset):""; @@ -265,7 +290,18 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, dos_to_unix(sname, True); dos_to_unix(cmnt, True); - fn(sname, stype, cmnt); + fn(sname, stype, cmnt, state); + } + } + else { + for (i = 0; i < count; i++, p+= 16) { + char *sname = p; + + dos_to_unix(sname, True); + + fn(sname, stype, NULL, state); + + } } } } -- cgit From dca808cbc4b52e38701f814f7aac043ddd1ca1c1 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 5 Jan 2001 13:11:29 +0000 Subject: Needed a callback arg on cli_list ... (This used to be commit d45e667a74fc2fcbf69c4819d480269c03dbfae4) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2e904e06b7..ae1607c1c4 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -148,7 +148,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) do a directory listing, calling fn on each file found ****************************************************************************/ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)) + void (*fn)(file_info *, const char *, void *), void *state) { int max_matches = 512; /* NT uses 260, OS/2 uses 2. Both accept 1. */ @@ -300,7 +300,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, for (p=dirlist,i=0;i Date: Fri, 5 Jan 2001 13:43:19 +0000 Subject: The latest changes to libsmbclient ... It can now do a directory listing for workgroups, servers, and shares, and, with a bit more effort, it will be able to list directories and files. I also does not request a username and password for the IPC$ share, but it should if the first attempt to connect fails. (This used to be commit 38ff91c5059a32c7ad2fd6074697c7c7f68a878c) --- source3/libsmb/libsmbclient.c | 476 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 455 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b299e59f7c..d0461f2257 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -39,6 +39,12 @@ struct smbc_server { BOOL no_pathinfo2; }; +/* Keep directory entries in a list */ +struct smbc_dir_list { + struct smbc_dir_list *next; + struct smbc_dirent *dirent; +}; + struct smbc_file { int cli_fd; int smbc_fd; @@ -46,21 +52,26 @@ struct smbc_file { off_t offset; struct smbc_server *srv; BOOL file; + struct smbc_dir_list *dir_list, *dir_end, *dir_next; + int dir_type, dir_error; }; +extern BOOL in_client; static int smbc_initialized = 0; static smbc_get_auth_data_fn smbc_auth_fn = NULL; static int smbc_debug; static int smbc_start_fd; static int smbc_max_fd = 10000; static struct smbc_file **smbc_file_table; +static struct smbc_server *smbc_srvs; +static pstring my_netbios_name; /* * Clean up a filename by removing redundent stuff */ static void -clean_fname(char *name) +smbc_clean_fname(char *name) { char *p, *p2; int l; @@ -153,8 +164,11 @@ clean_fname(char *name) /* * Function to parse a path and turn it into components * - * We accept smb://server/share/path... - * We also accept //server/share/path ... + * We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]] + * + * smb:// means show all the workgroups + * smb://name/ means, if name<1D> exists, list servers in workgroup, + * else, if name<20> exists, list all shares for server ... */ static const char *smbc_prefix = "smb:"; @@ -167,6 +181,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path) int len; fstring workgroup; + server[0] = share[0] = path[0] = (char)0; pstrcpy(s, fname); /* clean_fname(s); causing problems ... */ @@ -186,7 +201,10 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path) } - p += 2; /* Skip the // or \\ */ + p += 2; /* Skip the // or \\ */ + + if (*p == (char)0) + return 0; /* ok, its for us. Now parse out the server, share etc. */ @@ -195,13 +213,15 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path) return -1; } + + if (*p == (char)0) return 0; /* That's it ... */ if (!next_token(&p, share, "/", sizeof(fstring))) { return -1; } - + pstrcpy(path, p); all_string_sub(path, "/", "\\", 0); @@ -232,9 +252,6 @@ int smbc_errno(struct cli_state *c) * Connect to a server, possibly on an existing connection */ -static struct smbc_server *smbc_srvs; -static pstring my_netbios_name; - struct smbc_server *smbc_server(char *server, char *share) { struct smbc_server *srv=NULL; @@ -252,7 +269,15 @@ struct smbc_server *smbc_server(char *server, char *share) ip = ipzero; ZERO_STRUCT(c); - smbc_auth_fn(server, share, &workgroup, &username, &password); + if (strncmp(share, "IPC$", 4)) /* IPC$ should not need a pwd ... */ + smbc_auth_fn(server, share, &workgroup, &username, &password); + else { + + workgroup = lp_workgroup(); /* Is this relevant here? */ + username = ""; + password = ""; + + } /* try to use an existing connection */ for (srv=smbc_srvs;srv;srv=srv->next) { @@ -394,8 +419,9 @@ struct smbc_server *smbc_server(char *server, char *share) int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) { static pstring workgroup; + pstring conf; int p, pid; - char *user = NULL, *host = NULL; + char *user = NULL, *host = NULL, *home = NULL; smbc_initialized = 1; smbc_auth_fn = fn; @@ -421,7 +447,28 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) /* Here we would open the smb.conf file if needed ... */ - /* To do soon ... try $HOME/.smb/smb.conf first ... */ + home = getenv("HOME"); + + slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); + + load_interfaces(); /* Load the list of interfaces ... */ + + in_client = True; /* FIXME, make a param */ + + + + if (!lp_load(conf, True, False, False)) { + + /* + * Hmmm, what the hell do we do here ... we could not parse the + * config file ... We must return an error ... and keep info around + * about why we failed + */ + /* + errno = ENOENT; /* Hmmm, what error resp does lp_load return ? */ + return -1; + + } /* * Now initialize the file descriptor array and figure out what the @@ -463,8 +510,6 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) if (!smbc_file_table) return ENOMEM; - smbc_start_fd = 100000; /* FIXME: Figure it out */ - return 0; /* Success */ } @@ -519,12 +564,21 @@ int smbc_open(const char *fname, int flags, mode_t mode) while (smbc_file_table[slot]) slot++; - if (slot > smbc_max_fd) return ENOMEM; /* FIXME, is this best? */ + if (slot > smbc_max_fd) { + + errno = ENOMEM; /* FIXME, is this best? */ + return -1; + + } smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); - if (!smbc_file_table[slot]) - return ENOMEM; + if (!smbc_file_table[slot]) { + + errno = ENOMEM; + return -1; + + } fd = cli_open(&srv->cli, path, flags, DENY_NONE); @@ -547,7 +601,7 @@ int smbc_open(const char *fname, int flags, mode_t mode) int eno = 0; eno = smbc_errno(&srv->cli); - fd = smbc_dir_open(fname); + fd = smbc_opendir(fname); if (fd < 0) errno = eno; return fd; @@ -648,7 +702,7 @@ ssize_t smbc_write(int fd, void *buf, size_t count) return ret; /* Success, 0 bytes of data ... */ } - + /* * Routine to close() a file ... */ @@ -1077,15 +1131,324 @@ int smbc_fstat(int fd, struct stat *st) /* * Routine to open a directory + * + * We want to allow: + * + * smb: which should list all the workgroups available + * smb:workgroup + * smb:workgroup//server + * smb://server + * smb://server/share */ -int smbc_dir_open(const char *fname) +static void smbc_remove_dir(struct smbc_file *dir) +{ + for (dir->dir_next = dir->dir_list; + dir->dir_next != NULL; + dir->dir_next = dir->dir_next->next) { + + if (dir->dir_next->dirent) free(dir->dir_next->dirent); + free(dir->dir_next); + + } + + dir->dir_list = dir->dir_end = dir->dir_next = NULL; + +} + +static int add_dirent(struct smbc_file *dir, const char *name, const char *comment, uint32 type) { + struct smbc_dirent *dirent; + + /* + * Allocate space for the dirent, which must be increased by the + * size of the name and the comment and 1 for the null on the comment. + * The null on the name is already accounted for. + */ + + dirent = malloc(sizeof(struct smbc_dirent) + (name?strlen(name):0) + + (comment?strlen(comment):0) + 1); + + if (!dirent) { + + dir->dir_error = ENOMEM; + return -1; + + } + + if (dir->dir_list == NULL) { + + dir->dir_list = malloc(sizeof(struct smbc_dir_list)); + if (!dir->dir_list) { + + free(dirent); + dir->dir_error = ENOMEM; + return -1; + + } + + dir->dir_end = dir->dir_next = dir->dir_list; + + } + else { + + dir->dir_end->next = malloc(sizeof(struct smbc_dir_list)); + + if (!dir->dir_end) { + + free(dirent); + dir->dir_error = ENOMEM; + return -1; + + } + + dir->dir_end = dir->dir_end->next; + dir->dir_end->next = NULL; + + } + + dir->dir_end->dirent = dirent; + + dirent->smbc_type = dir->dir_type; + dirent->namelen = (name?strlen(name):0); + dirent->commentlen = (comment?strlen(comment):0); + + strncpy(dirent->name, (name?name:""), dirent->namelen + 1); + + dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); + strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); return 0; } +static void +list_fn(const char *name, uint32 type, const char *comment, void *state) +{ + + if (add_dirent((struct smbc_file *)state, name, comment, type) < 0) { + + /* An error occurred, what do we do? */ + + } + +} + +int smbc_opendir(const char *fname) +{ + struct in_addr addr; + fstring server, share; + pstring path; + struct smbc_server *srv = NULL; + struct in_addr rem_ip; + int slot = 0; + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + if (smbc_parse_path(fname, server, share, path)) { + + errno = EINVAL; + return -1; + + } + + /* Get a file entry ... */ + + slot = 0; + + while (smbc_file_table[slot]) + slot++; + + if (slot > smbc_max_fd) { + + errno = ENOMEM; + return -1; /* FIXME, ... move into a func */ + + } + + smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); + + if (!smbc_file_table[slot]) { + + errno = ENOMEM; + return -1; + + } + + smbc_file_table[slot]->cli_fd = 0; + smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; + smbc_file_table[slot]->fname = strdup(fname); + smbc_file_table[slot]->srv = NULL; + smbc_file_table[slot]->offset = 0; + smbc_file_table[slot]->file = False; + smbc_file_table[slot]->dir_list = NULL; + + if (server[0] == (char)0) { + + if (share[0] != (char)0 || path[0] != (char)0) { + + errno = EINVAL; + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + + /* We have server and share and path empty ... so list the workgroups */ + + /* fprintf(stderr, "Workgroup is: %s\n", lp_workgroup()); */ + cli_get_backup_server(my_netbios_name, lp_workgroup(), server, sizeof(server)); + + smbc_file_table[slot]->dir_type = SMBC_WORKGROUP; + + /* + * Get a connection to IPC$ on the server if we do not already have one + */ + + srv = smbc_server(server, "IPC$"); + + if (!srv) { + + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + + smbc_file_table[slot]->srv = srv; + + /* Now, list the stuff ... */ + + if (!cli_NetServerEnum(&srv->cli, lp_workgroup(), 0x80000000, list_fn, + (void *)smbc_file_table[slot])) { + + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + } + else { /* Server not an empty string ... Check the rest and see what gives */ + + if (share[0] == (char)0) { + + if (path[0] != (char)0) { /* Should not have empty share with path */ + + errno = EINVAL; + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + + /* Check to see if <1D> translates, or <20> translates */ + + if (resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ + + smbc_file_table[slot]->dir_type = SMBC_SERVER; + + /* + * Get the backup list ... + */ + + cli_get_backup_server(my_netbios_name, server, server, sizeof(server)); + + /* + * Get a connection to IPC$ on the server if we do not already have one + */ + + srv = smbc_server(server, "IPC$"); + + if (!srv) { + + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; /* FIXME: Memory leaks ... */ + return -1; + + } + + smbc_file_table[slot]->srv = srv; + + /* Now, list the servers ... */ + + if (!cli_NetServerEnum(&srv->cli, lp_workgroup(), 0x0000FFFE, list_fn, + (void *)smbc_file_table[slot])) { + + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + + } + else { + + if (resolve_name(server, &rem_ip, 0x20)) { + + /* Now, list the shares ... */ + + smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + + srv = smbc_server(server, "IPC$"); + + if (!srv) { + + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + + smbc_file_table[slot]->srv = srv; + + /* Now, list the servers ... */ + + if (!cli_RNetShareEnum(&srv->cli, list_fn, + (void *)smbc_file_table[slot])) { + + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + + } + else { + + errno = EINVAL; + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + + } + + } + else { /* The server and share are specified ... work from there ... */ + + + + } + + } + + return smbc_file_table[slot]->smbc_fd; + +} + /* * Routine to close a directory */ @@ -1101,10 +1464,81 @@ int smbc_closedir(int fd) * Routine to get a directory entry */ -int smbc_getdents(unsigned int fd, struct dirent *dirp, int count) +int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) { + struct smbc_file *fe; + struct smbc_dir_list *dir; + int rem = count, reqd; - return 0; + /* Check that all is ok first ... */ + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + if (fe->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + return -1; + + } + + /* + * Now, retrieve the number of entries that will fit in what was passed + * We have to figure out if the info is in the list, or we need to + * send a request to the server to get the info. + */ + + while ((dir = fe->dir_next)) { + struct smbc_dirent *dirent; + + if (!dir->dirent) { + + errno = ENOENT; /* Bad error */ + return -1; + + } + + if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen + + dir->dirent->commentlen + 1))) { + + if (rem < count) { /* We managed to copy something */ + + errno = 0; + return count - rem; + + } + else { /* Nothing copied ... */ + + errno = EINVAL; /* Not enough space ... */ + return -1; + + } + + } + + dirent = dir->dirent; + + bcopy(dirent, dirp, reqd); /* Copy the data in ... */ + + dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); + + (char *)dirp += reqd; + + rem -= reqd; + + fe->dir_next = dir = dir -> next; + } + + if (rem == count) + return 0; + else + return count - rem; } -- cgit From a0feaf62b7a25f05978b90f3b11b7e7f882e07dd Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 6 Jan 2001 12:15:46 +0000 Subject: Fix a minor problem with listing servers in a workgroup and add a gtk+ test application that tests out some of this stuff ... (This used to be commit 606c4aeceac0bd1823ec6376df3ca5016007ab38) --- source3/libsmb/libsmbclient.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index d0461f2257..50d330e363 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -206,6 +206,13 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path) if (*p == (char)0) return 0; + if (*p == '/') { + + strncpy(server, lp_workgroup(), 16); /* FIXME: Danger here */ + return 0; + + } + /* ok, its for us. Now parse out the server, share etc. */ if (!next_token(&p, server, "/", sizeof(fstring))) { @@ -1356,6 +1363,7 @@ int smbc_opendir(const char *fname) /* Check to see if <1D> translates, or <20> translates */ if (resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ + pstring buserver; smbc_file_table[slot]->dir_type = SMBC_SERVER; @@ -1363,13 +1371,13 @@ int smbc_opendir(const char *fname) * Get the backup list ... */ - cli_get_backup_server(my_netbios_name, server, server, sizeof(server)); + cli_get_backup_server(my_netbios_name, server, buserver, sizeof(buserver)); /* * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(server, "IPC$"); + srv = smbc_server(buserver, "IPC$"); if (!srv) { @@ -1383,7 +1391,7 @@ int smbc_opendir(const char *fname) /* Now, list the servers ... */ - if (!cli_NetServerEnum(&srv->cli, lp_workgroup(), 0x0000FFFE, list_fn, + if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn, (void *)smbc_file_table[slot])) { if (smbc_file_table[slot]) free(smbc_file_table[slot]); -- cgit From 34fea75f35b61841886234e5f167ecf32d95c9c2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 6 Jan 2001 14:48:55 +0000 Subject: Fix some more bugs in libsmbclient.c and add functionality to tree.c (This used to be commit d6cef8877a7ed80329b3ba67231a94601fcfd060) --- source3/libsmb/libsmbclient.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 50d330e363..960fa1d3da 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1241,6 +1241,19 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) } +static void +dir_list_fn(file_info *finfo, const char *mask, void *state) +{ + + fprintf(stderr, "Finfo->name=%s, mask=%s\n", finfo->name, mask); + if (add_dirent((struct smbc_file *)state, finfo->name, "", SMBC_FILE) < 0) { + + /* Handle an error ... */ + + } + +} + int smbc_opendir(const char *fname) { struct in_addr addr; @@ -1447,8 +1460,35 @@ int smbc_opendir(const char *fname) } else { /* The server and share are specified ... work from there ... */ + /* Well, we connect to the server and list the directory */ + + smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + + srv = smbc_server(server, share); + if (!srv) { + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + return -1; + + } + + smbc_file_table[slot]->srv = srv; + + /* Now, list the files ... */ + + pstrcat(path, "\\*"); + + if (!cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, + (void *)smbc_file_table[slot])) { + + if (smbc_file_table[slot]) free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + errno = smbc_errno(&srv->cli); + return -1; + + } } } -- cgit From c6d5280a546752a7eb93deba90dd49ee9cf327d5 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 7 Jan 2001 07:10:50 +0000 Subject: More fixes and implementation bits and pieces for libsmbclient (This used to be commit 991f6907ac200d53b95a206d65844a0c0830caae) --- source3/libsmb/libsmbclient.c | 172 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 161 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 960fa1d3da..5c6360354e 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -631,6 +631,14 @@ static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this int smbc_creat(const char *path, mode_t mode) { + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + return smbc_open(path, creat_bits, mode); } @@ -643,6 +651,13 @@ ssize_t smbc_read(int fd, void *buf, size_t count) struct smbc_file *fe; int ret; + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count)); if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { @@ -687,6 +702,13 @@ ssize_t smbc_write(int fd, void *buf, size_t count) int ret; struct smbc_file *fe; + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { errno = EBADF; @@ -718,6 +740,13 @@ int smbc_close(int fd) { struct smbc_file *fe; + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { errno = EBADF; @@ -877,6 +906,13 @@ off_t smbc_lseek(int fd, off_t offset, int whence) struct smbc_file *fe; size_t size; + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { errno = EBADF; @@ -985,6 +1021,14 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino) { + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + DEBUG(4,("sending qpathinfo\n")); if (!srv->no_pathinfo2 && @@ -1098,6 +1142,13 @@ int smbc_fstat(int fd, struct stat *st) uint16 mode; SMB_INO_T ino = 0; + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { errno = EBADF; @@ -1150,12 +1201,15 @@ int smbc_fstat(int fd, struct stat *st) static void smbc_remove_dir(struct smbc_file *dir) { - for (dir->dir_next = dir->dir_list; - dir->dir_next != NULL; - dir->dir_next = dir->dir_next->next) { + struct smbc_dir_list *d,*f; + + d = dir->dir_list; + while (d) { - if (dir->dir_next->dirent) free(dir->dir_next->dirent); - free(dir->dir_next); + f = d; d = d->next; + + if (f->dirent) free(f->dirent); + free(f); } @@ -1166,6 +1220,7 @@ static void smbc_remove_dir(struct smbc_file *dir) static int add_dirent(struct smbc_file *dir, const char *name, const char *comment, uint32 type) { struct smbc_dirent *dirent; + int size; /* * Allocate space for the dirent, which must be increased by the @@ -1173,9 +1228,11 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme * The null on the name is already accounted for. */ - dirent = malloc(sizeof(struct smbc_dirent) + (name?strlen(name):0) + - (comment?strlen(comment):0) + 1); + size = sizeof(struct smbc_dirent) + (name?strlen(name):0) + + (comment?strlen(comment):0) + 1; + dirent = malloc(size); + if (!dirent) { dir->dir_error = ENOMEM; @@ -1216,10 +1273,11 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme dir->dir_end->dirent = dirent; - dirent->smbc_type = dir->dir_type; + dirent->smbc_type = type; dirent->namelen = (name?strlen(name):0); dirent->commentlen = (comment?strlen(comment):0); - + dirent->dirlen = size; + strncpy(dirent->name, (name?name:""), dirent->namelen + 1); dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); @@ -1232,8 +1290,39 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme static void list_fn(const char *name, uint32 type, const char *comment, void *state) { + struct smbc_file *dir = (struct smbc_file *)state; + int dirent_type; + + /* We need to process the type a little ... */ + + if (dir->dir_type == SMBC_FILE_SHARE) { + + switch (type) { + case 0: /* Directory tree */ + dirent_type = SMBC_FILE_SHARE; + break; + + case 1: + dirent_type = SMBC_PRINTER_SHARE; + break; + + case 2: + dirent_type = SMBC_COMMS_SHARE; + break; - if (add_dirent((struct smbc_file *)state, name, comment, type) < 0) { + case 3: + dirent_type = SMBC_IPC_SHARE; + break; + + default: + dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ + break; + } + + } + else dirent_type = dir->dir_type; + + if (add_dirent(dir, name, comment, dirent_type) < 0) { /* An error occurred, what do we do? */ @@ -1246,7 +1335,8 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) { fprintf(stderr, "Finfo->name=%s, mask=%s\n", finfo->name, mask); - if (add_dirent((struct smbc_file *)state, finfo->name, "", SMBC_FILE) < 0) { + if (add_dirent((struct smbc_file *)state, finfo->name, "", + (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { /* Handle an error ... */ @@ -1503,6 +1593,36 @@ int smbc_opendir(const char *fname) int smbc_closedir(int fd) { + struct smbc_file *fe; + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + if (!fe) { + + errno = ENOENT; /* FIXME: Is this correct */ + return -1; + + } + + smbc_remove_dir(fe); /* Clean it up */ + + if (fe) free(fe); /* Free the space too */ + + smbc_file_table[fd - smbc_start_fd] = NULL; return 0; @@ -1520,6 +1640,13 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) /* Check that all is ok first ... */ + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { errno = EBADF; @@ -1597,6 +1724,15 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) int smbc_mkdir(const char *fname, mode_t mode) { + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + return 0; + } /* @@ -1606,6 +1742,13 @@ int smbc_mkdir(const char *fname, mode_t mode) int smbc_lseekdir(int fd, off_t offset, int whence) { + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + return 0; } @@ -1617,6 +1760,13 @@ int smbc_lseekdir(int fd, off_t offset, int whence) int smbc_fstatdir(int fd, struct stat *st) { + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + return 0; } -- cgit From bdb2c12d2ecd47d07acc8ef3f72fcb0215ecc988 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 7 Jan 2001 13:07:26 +0000 Subject: More bug fixen ... (This used to be commit a13b5ef7bba86d42df98b4f493aa2ea9e1caa6c3) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 5c6360354e..2cbc66986e 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1252,7 +1252,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme } dir->dir_end = dir->dir_next = dir->dir_list; - + } else { @@ -1267,10 +1267,10 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme } dir->dir_end = dir->dir_end->next; - dir->dir_end->next = NULL; } + dir->dir_end->next = NULL; dir->dir_end->dirent = dirent; dirent->smbc_type = type; -- cgit From 24bf82f30631565578a40b0532341f6aa6bbcd41 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 7 Jan 2001 13:38:24 +0000 Subject: Get rid of 10.0.0.6 and replace it with 0.0.0.0 as my_ip address prior to sending datagrams in clidgram.c (This used to be commit 4c540393b33a5c49adafcc9320f591490b97192a) --- source3/libsmb/clidgram.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index b76d46e1bf..a45cc009ac 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -158,8 +158,6 @@ int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz) * from fixed, known locations ... */ - fprintf(stderr, "Packet: Data is: %s\n", &dgram->data[92]); - /* Copy the data to buffer, respecting sizes ... */ bcopy(&dgram->data[92], buf, MIN(bufsiz, (dgram->datasize - 92))); @@ -188,9 +186,9 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) } - inet_aton("10.0.0.6", &my_ip); + inet_aton("0.0.0.0", &my_ip); - if (!resolve_name(myname, &my_ip, 0x00)) { + if (!resolve_name(myname, &my_ip, 0x00)) { /* FIXME: Call others here */ fprintf(stderr, "Could not resolve name: %s<00>\n", myname); -- cgit From 8788aea643453a8d18563629220e7edd53babf41 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 8 Jan 2001 02:47:30 +0000 Subject: Add support for logging to wherever smb.conf specifies. (This used to be commit cc5a2db8a0c195b328b93fff566bc1120aeef54a) --- source3/libsmb/libsmbclient.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2cbc66986e..3c1c343ec2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -428,12 +428,16 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) static pstring workgroup; pstring conf; int p, pid; - char *user = NULL, *host = NULL, *home = NULL; + char *user = NULL, *host = NULL, *home = NULL, *pname="libsmbclient"; smbc_initialized = 1; smbc_auth_fn = fn; smbc_debug = debug; + DEBUGLEVEL = -1; + + setup_logging(pname, False); + /* * We try to construct our netbios name from our hostname etc */ @@ -458,7 +462,7 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - load_interfaces(); /* Load the list of interfaces ... */ + load_interfaces(); /* Load the list of interfaces ... */ in_client = True; /* FIXME, make a param */ @@ -477,6 +481,8 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) } + reopen_logs(); /* Get logging working ... */ + /* * Now initialize the file descriptor array and figure out what the * max open files is, so we can return FD's that are above the max -- cgit From 51a37d1960ec1233ddf549e1586da6a19db44413 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 10 Jan 2001 18:44:39 +0000 Subject: Fixed authenticated pipe access. Added cli_lsa_enum_trust_dom(). Misc other cosmetic changes. (This used to be commit 751483a155723581f987d46605b59cdeba34ad72) --- source3/libsmb/cli_lsarpc.c | 127 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 102 insertions(+), 25 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 3651d786ef..e4da7a7cc7 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -38,8 +38,6 @@ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, /* Initialise cli_state information */ - ZERO_STRUCTP(cli); - if (!cli_initialise(cli)) { return NULL; } @@ -87,7 +85,7 @@ void cli_lsa_shutdown(struct cli_state *cli) /* Open a LSA policy handle */ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, - uint32 des_access, POLICY_HND *hnd) + uint32 des_access, POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_OPEN_POL q; @@ -127,12 +125,10 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, goto done; } - result = r.status; - /* Return output parameters */ - if (result == NT_STATUS_NOPROBLEMO) { - *hnd = r.pol; + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *pol = r.pol; } done: @@ -144,7 +140,7 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, /* Close a LSA policy handle */ -uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) +uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_CLOSE q; @@ -161,7 +157,7 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) /* Marshall data and send request */ - init_lsa_q_close(&q, hnd); + init_lsa_q_close(&q, pol); if (!lsa_io_q_close("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) { @@ -176,12 +172,10 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) goto done; } - result = r.status; - /* Return output parameters */ - if (result == NT_STATUS_NOPROBLEMO) { - *hnd = r.pol; + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *pol = r.pol; } done: @@ -193,7 +187,7 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *hnd) /* Lookup a list of sids */ -uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, +uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, int num_sids, DOM_SID *sids, char ***names, uint32 **types, int *num_names) { @@ -215,7 +209,7 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, /* Marshall data and send request */ - init_q_lookup_sids(cli->mem_ctx, &q, hnd, num_sids, sids, 1); + init_q_lookup_sids(cli->mem_ctx, &q, pol, num_sids, sids, 1); if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { @@ -238,8 +232,8 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, result = r.status; - if (result != 0 && r.status != 0x107 && - r.status != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { + if (result != NT_STATUS_NOPROBLEMO && result != 0x00000107 && + result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { /* An actual error occured */ @@ -300,7 +294,7 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *hnd, /* Lookup a list of names */ -uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, +uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, int num_names, char **names, DOM_SID **sids, uint32 **types, int *num_sids) { @@ -321,7 +315,7 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, /* Marshall data and send request */ - init_q_lookup_names(cli->mem_ctx, &q, hnd, num_names, names); + init_q_lookup_names(cli->mem_ctx, &q, pol, num_names, names); if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { @@ -341,7 +335,8 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, result = r.status; - if (result != 0 && result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { + if (result != NT_STATUS_NOPROBLEMO && + result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { /* An actual error occured */ @@ -400,7 +395,7 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *hnd, /* Query info policy */ -uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *hnd, +uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, uint16 info_class, fstring domain_name, DOM_SID * domain_sid) { @@ -419,7 +414,7 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *hnd, /* Marshall data and send request */ - init_q_query(&q, hnd, info_class); + init_q_query(&q, pol, info_class); if (!lsa_io_q_query("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) { @@ -434,9 +429,7 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *hnd, goto done; } - result = r.status; - - if (result != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { goto done; } @@ -483,3 +476,87 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *hnd, return result; } + +/* Enumerate list of trusted domains */ + +uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, + uint32 *enum_ctx, uint32 *num_domains, + char ***domain_names, DOM_SID **domain_sids) +{ + prs_struct qbuf, rbuf; + LSA_Q_ENUM_TRUST_DOM q; + LSA_R_ENUM_TRUST_DOM r; + uint32 result; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_q_enum_trust_dom(&q, pol, *enum_ctx, 0xffffffff); + + if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_enum_trust_dom("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + result = r.status; + + if (result != NT_STATUS_NOPROBLEMO && result != 0x8000001a) { + + /* An actual error ocured */ + + goto done; + } + + result = NT_STATUS_NOPROBLEMO; + + /* Return output parameters */ + + if (!((*domain_names) = (char **)malloc(sizeof(char *) * + r.num_domains))) { + DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!((*domain_sids) = (DOM_SID *)malloc(sizeof(DOM_SID) * + r.num_domains))) { + DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + for (i = 0; i < r.num_domains; i++) { + fstring tmp; + + unistr2_to_ascii(tmp, &r.uni_domain_name[i], sizeof(tmp) - 1); + (*domain_names)[i] = strdup(tmp); + sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); + } + + *num_domains = r.num_domains; + *enum_ctx = r.enum_context; + + lsa_free_r_enum_trust_dom(&r); + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 5688f5292a78de0cc80d7c74eeddc33d27d96380 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 10 Jan 2001 18:46:24 +0000 Subject: Added init functions, cli_samr_connect(), cli_samr_close(), cli_samr_open_{domain,user}() and cli_samr_query_userinfo() (This used to be commit 385860107346de26b4bcbd33d5f131a0670f6f93) --- source3/libsmb/cli_samr.c | 325 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 source3/libsmb/cli_samr.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c new file mode 100644 index 0000000000..09b39265b2 --- /dev/null +++ b/source3/libsmb/cli_samr.c @@ -0,0 +1,325 @@ +/* + Unix SMB/Netbios implementation. + Version 2.2 + RPC pipe client + Copyright (C) Tim Potter 2000, + Copyright (C) Andrew Tridgell 1992-1997,2000, + Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, + Copyright (C) Paul Ashton 1997,2000, + Copyright (C) Elrond 2000. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* Opens a SMB connection to the SAMR pipe */ + +struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name, + struct ntuser_creds *creds) +{ + struct in_addr dest_ip; + struct nmb_name calling, called; + fstring dest_host; + extern pstring global_myname; + struct ntuser_creds anon; + + /* Initialise cli_state information */ + + if (!cli_initialise(cli)) { + return NULL; + } + + if (!creds) { + ZERO_STRUCT(anon); + anon.pwd.null_pwd = 1; + creds = &anon; + } + + cli_init_creds(cli, creds); + + /* Establish a SMB connection */ + + if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { + return NULL; + } + + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); + + if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, + &called, "IPC$", "IPC", False, True)) { + return NULL; + } + + /* Open a NT session thingy */ + + if (!cli_nt_session_open(cli, PIPE_SAMR)) { + cli_shutdown(cli); + return NULL; + } + + return cli; +} + +/* Shut down a SMB connection to the SAMR pipe */ + +void cli_samr_shutdown(struct cli_state *cli) +{ + if (cli->fd != -1) cli_ulogoff(cli); + cli_shutdown(cli); +} + +/* Connect to SAMR database */ + +uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, + uint32 access_mask, POLICY_HND *connect_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_CONNECT q; + SAMR_R_CONNECT r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_connect(&q, srv_name, access_mask); + + if (!samr_io_q_connect("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_connect("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *connect_pol = r.connect_pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Close SAMR handle */ + +uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_CLOSE_HND q; + SAMR_R_CLOSE_HND r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_close_hnd(&q, connect_pol); + + if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *connect_pol = r.pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Open handle on a domain */ + +uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, + uint32 access_mask, DOM_SID *domain_sid, + POLICY_HND *domain_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_OPEN_DOMAIN q; + SAMR_R_OPEN_DOMAIN r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid); + + if (!samr_io_q_open_domain("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_open_domain("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *domain_pol = r.domain_pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Open handle on a user */ + +uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, + uint32 access_mask, uint32 user_rid, + POLICY_HND *user_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_OPEN_USER q; + SAMR_R_OPEN_USER r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_open_user(&q, domain_pol, access_mask, user_rid); + + if (!samr_io_q_open_user("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_open_user("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *user_pol = r.user_pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Query user info */ + +uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, + uint16 switch_value, SAM_USERINFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_USERINFO q; + SAMR_R_QUERY_USERINFO r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_query_userinfo(&q, user_pol, switch_value); + + if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + r.ctr = ctr; + + if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 3ab2ea54068d7441fb8d9aed9596657758ac5000 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 10 Jan 2001 18:48:02 +0000 Subject: Added init functions, cli_spoolss_open_printer_ex(), cli_spoolss_closeprinter(), cli_spoolss_enum_printers(), cli_spoolss_enum_ports() and cli_spoolss_getprinter() (This used to be commit 84247ba7d7048cc828edad282313bfd21bbc6b5d) --- source3/libsmb/cli_spoolss.c | 538 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 538 insertions(+) create mode 100644 source3/libsmb/cli_spoolss.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c new file mode 100644 index 0000000000..2dbc1a0ab0 --- /dev/null +++ b/source3/libsmb/cli_spoolss.c @@ -0,0 +1,538 @@ +/* + Unix SMB/Netbios implementation. + Version 2.2 + RPC pipe client + Copyright (C) Tim Potter 2000, + Copyright (C) Andrew Tridgell 1994-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Jean-Francois Micouleau 1999-2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* Opens a SMB connection to the SPOOLSS pipe */ + +struct cli_state *cli_spoolss_initialise(struct cli_state *cli, + char *system_name, + struct ntuser_creds *creds) +{ + struct in_addr dest_ip; + struct nmb_name calling, called; + fstring dest_host; + extern pstring global_myname; + struct ntuser_creds anon; + + /* Initialise cli_state information */ + + if (!cli_initialise(cli)) { + return NULL; + } + + if (!creds) { + ZERO_STRUCT(anon); + anon.pwd.null_pwd = 1; + creds = &anon; + } + + cli_init_creds(cli, creds); + + /* Establish a SMB connection */ + + if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { + return NULL; + } + + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); + + if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, + &called, "IPC$", "IPC", False, True)) { + return NULL; + } + + /* Open a NT session thingy */ + + if (!cli_nt_session_open(cli, PIPE_SPOOLSS)) { + cli_shutdown(cli); + return NULL; + } + + return cli; +} + +/* Shut down a SMB connection to the SPOOLSS pipe */ + +void cli_spoolss_shutdown(struct cli_state *cli) +{ + if (cli->fd != -1) cli_ulogoff(cli); + cli_shutdown(cli); +} + +/* Open printer ex */ + +uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, + char *datatype, uint32 access_required, + char *station, char *username, + POLICY_HND *pol) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_OPEN_PRINTER_EX q; + SPOOL_R_OPEN_PRINTER_EX r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Initialise input parameters */ + + make_spoolss_q_open_printer_ex(&q, printername, datatype, + access_required, station, username); + + /* Marshall data and send request */ + + if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *pol = r.handle; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Close a printer handle */ + +uint32 cli_spoolss_closeprinter(struct cli_state *cli, POLICY_HND *pol) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_CLOSEPRINTER q; + SPOOL_R_CLOSEPRINTER r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Initialise input parameters */ + + make_spoolss_q_closeprinter(&q, pol); + + /* Marshall data and send request */ + + if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *pol = r.handle; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Initialize a spoolss NEW_BUFFER */ + +static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) +{ + buffer->ptr = (size != 0); + buffer->size = size; + buffer->string_at_end = size; + prs_init(&buffer->prs, size, 4, ctx, MARSHALL); + buffer->struct_start = prs_offset(&buffer->prs); +} + +/* Decode various printer info levels - perhaps this should live in + parse_spoolss.c? */ + +static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, + PRINTER_INFO_0 **info) +{ + uint32 i; + PRINTER_INFO_0 *inf; + + inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0)); + + buffer->prs.data_offset=0; + + for (i=0; iprs.data_offset=0; + + for (i=0; iprs.data_offset=0; + + for (i=0; iprs.data_offset=0; + + for (i=0; iprs, 0); + + for (i=0; iprs, 0); + + for (i=0; imem_ctx); + + prs_init(&qbuf , MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, 4, cli->mem_ctx, UNMARSHALL); + + make_spoolss_q_enumprinters(&q, flags, "", level, &buffer, + needed); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, + &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + prs_switch_type(&buffer.prs, UNMARSHALL); + prs_set_offset(&buffer.prs, 0); + r.buffer = &buffer; + + if (new_spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { + needed = r.needed; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO && + r.returned > 0) { + + *returned = r.returned; + + switch (level) { + case 1: + decode_printer_info_1(&buffer, r.returned, + &ctr->printers_1); + break; + case 2: + decode_printer_info_2(&buffer, r.returned, + &ctr->printers_2); + break; + case 3: + decode_printer_info_3(&buffer, r.returned, + &ctr->printers_3); + break; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + } while (result == ERROR_INSUFFICIENT_BUFFER); + + return result; +} + +/* Enumerate printer ports */ + +uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, + int *returned, PORT_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMPORTS q; + SPOOL_R_ENUMPORTS r; + NEW_BUFFER buffer; + uint32 needed = 100; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + do { + /* Initialise input parameters */ + + init_buffer(&buffer, needed, cli->mem_ctx); + + prs_init(&qbuf , MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, 4, cli->mem_ctx, UNMARSHALL); + + make_spoolss_q_enumports(&q, "", level, &buffer, needed); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumports("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, + &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + prs_switch_type(&buffer.prs, UNMARSHALL); + prs_set_offset(&buffer.prs, 0); + r.buffer = &buffer; + + if (new_spoolss_io_r_enumports("", &r, &rbuf, 0)) { + needed = r.needed; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO && + r.returned > 0) { + + *returned = r.returned; + + switch (level) { + case 1: + decode_port_info_1(&buffer, r.returned, + &ctr->port.info_1); + break; + case 2: + decode_port_info_2(&buffer, r.returned, + &ctr->port.info_2); + break; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + } while (result == ERROR_INSUFFICIENT_BUFFER); + + return result; +} + +/* Get printer info */ + +uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, + uint32 level, PRINTER_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTER q; + SPOOL_R_GETPRINTER r; + NEW_BUFFER buffer; + uint32 needed = 100; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + do { + /* Initialise input parameters */ + + init_buffer(&buffer, needed, cli->mem_ctx); + + prs_init(&qbuf , MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, 4, cli->mem_ctx, UNMARSHALL); + + make_spoolss_q_getprinter(&q, pol, level, &buffer, + needed); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, + &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + prs_switch_type(&buffer.prs, UNMARSHALL); + prs_set_offset(&buffer.prs, 0); + r.buffer = &buffer; + + if (spoolss_io_r_getprinter("", &r, &rbuf, 0)) { + needed = r.needed; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + + switch (level) { + case 0: + decode_printer_info_0(&buffer, 1, + &ctr->printers_0); + break; + case 1: + decode_printer_info_1(&buffer, 1, + &ctr->printers_1); + break; + case 2: + decode_printer_info_2(&buffer, 1, + &ctr->printers_2); + break; + case 3: + decode_printer_info_3(&buffer, 1, + &ctr->printers_3); + break; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + } while (result == ERROR_INSUFFICIENT_BUFFER); + + return result; +} -- cgit From adb91565b5ec81ebb9e0d57b7d91fbd9da410aa3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Jan 2001 18:38:55 +0000 Subject: rpc_server/srv_samr.c: smbd/reply.c: Added fix needed for appliances. When using winbindd - a new user may exist (from winbind) but have no home directory. Extend add user script so it is called with a %H substitution when a user exists but their home directory does not. Thanks to Alex Win at VA Linux for finding this one and testing the fix. libsmb/clidgram.c: Fixed missing return statements. smbd/uid.c: Fixed typo in debug. Jeremy. (This used to be commit 7ba0a2192b89954604dd793c537b4a17c2d1ac07) --- source3/libsmb/clidgram.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index a45cc009ac..70e97c6bb6 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -162,6 +162,7 @@ int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz) bcopy(&dgram->data[92], buf, MIN(bufsiz, (dgram->datasize - 92))); + return 0; } else return -1; @@ -218,7 +219,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) cli_get_response(True, "\\MAILSLOT\\BROWSE", cli_backup_list, sizeof(cli_backup_list)); /* Should check the response here ... FIXME */ - + return 0; } /* @@ -234,4 +235,5 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam strncpy(servername, cli_backup_list, MIN(16, namesize)); + return 0; } -- cgit From fb4013444677629af4b663a61da3b575bba49195 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 12 Jan 2001 05:10:45 +0000 Subject: Many bug fixes to the libsmbclient.c code plus - an implementation of smbc_readdir - extensions to tree.c to show files in a second window - changes to auth_fn to provide buffers for username, password, etc from caller rather than callee (This used to be commit 7f559c1a7307b91218d5984f48f65e7dc0ab66b9) --- source3/libsmb/libsmbclient.c | 175 +++++++++++++++++++++++++++++++++--------- 1 file changed, 137 insertions(+), 38 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3c1c343ec2..807dfb987c 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -65,6 +65,7 @@ static int smbc_max_fd = 10000; static struct smbc_file **smbc_file_table; static struct smbc_server *smbc_srvs; static pstring my_netbios_name; +static pstring smbc_user; /* * Clean up a filename by removing redundent stuff @@ -174,14 +175,15 @@ smbc_clean_fname(char *name) static const char *smbc_prefix = "smb:"; static int -smbc_parse_path(const char *fname, char *server, char *share, char *path) +smbc_parse_path(const char *fname, char *server, char *share, char *path, + char *user, char *password) /* FIXME, lengths of strings */ { static pstring s; char *p; int len; fstring workgroup; - server[0] = share[0] = path[0] = (char)0; + server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; pstrcpy(s, fname); /* clean_fname(s); causing problems ... */ @@ -257,15 +259,21 @@ int smbc_errno(struct cli_state *c) /* * Connect to a server, possibly on an existing connection + * + * Here, what we want to do is: If the server and username + * match an existing connection, reuse that, otherwise, establish a + * new connection. + * + * If we have to create a new connection, call the auth_fn to get the + * info we need, unless the username and password were passed in. */ -struct smbc_server *smbc_server(char *server, char *share) +struct smbc_server *smbc_server(char *server, char *share, + char *workgroup, char *username, + char *password) { struct smbc_server *srv=NULL; struct cli_state c; - char *username = NULL; - char *password = NULL; - char *workgroup = NULL; struct nmb_name called, calling; char *p, *server_n = server; fstring group; @@ -276,16 +284,6 @@ struct smbc_server *smbc_server(char *server, char *share) ip = ipzero; ZERO_STRUCT(c); - if (strncmp(share, "IPC$", 4)) /* IPC$ should not need a pwd ... */ - smbc_auth_fn(server, share, &workgroup, &username, &password); - else { - - workgroup = lp_workgroup(); /* Is this relevant here? */ - username = ""; - password = ""; - - } - /* try to use an existing connection */ for (srv=smbc_srvs;srv;srv=srv->next) { if (strcmp(server,srv->server_name)==0 && @@ -300,6 +298,24 @@ struct smbc_server *smbc_server(char *server, char *share) return NULL; } + /* Pick up the auth info here, once we know we need to connect */ + + smbc_auth_fn(server, share, workgroup, sizeof(fstring), + username, sizeof(fstring), password, sizeof(fstring)); + + /* + * However, smbc_auth_fn may have picked up info relating to an + * existing connection, so try for and existing connection again ... + */ + + for (srv=smbc_srvs;srv;srv=srv->next) { + if (strcmp(server,srv->server_name)==0 && + strcmp(share,srv->share_name)==0 && + strcmp(workgroup,srv->workgroup)==0 && + strcmp(username, srv->username) == 0) + return srv; + } + make_nmb_name(&calling, my_netbios_name, 0x0); make_nmb_name(&called , server, 0x20); @@ -443,7 +459,12 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) */ user = getenv("USER"); - if (!user) user = ""; + if (!user) user = ""; /* FIXME: What to do about this? */ + + /* + * FIXME: Is this the best way to get the user info? */ + + pstrcpy(smbc_user, user); /* Save for use elsewhere */ pid = getpid(); @@ -533,7 +554,7 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) int smbc_open(const char *fname, int flags, mode_t mode) { - fstring server, share; + fstring server, share, user, password; pstring path; struct smbc_server *srv = NULL; struct smbc_file *file = NULL; @@ -553,9 +574,11 @@ int smbc_open(const char *fname, int flags, mode_t mode) } - smbc_parse_path(fname, server, share, path); /* FIXME, check errors */ + smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ - srv = smbc_server(server, share); + if (user[0] == (char)0) pstrcpy(user, smbc_user); + + srv = smbc_server(server, share, lp_workgroup(), user, password); if (!srv) { @@ -787,7 +810,7 @@ int smbc_close(int fd) int smbc_unlink(const char *fname) { - fstring server, share; + fstring server, share, user, password; pstring path; struct smbc_server *srv = NULL; @@ -805,9 +828,11 @@ int smbc_unlink(const char *fname) } - smbc_parse_path(fname, server, share, path); /* FIXME, check errors */ + smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + + if (user[0] == (char)0) pstrcpy(user, smbc_user); - srv = smbc_server(server, share); + srv = smbc_server(server, share, lp_workgroup(), user, password); if (!srv) { @@ -847,7 +872,7 @@ int smbc_unlink(const char *fname) int smbc_rename(const char *oname, const char *nname) { - fstring server1, share1, server2, share2; + fstring server1, share1, server2, share2, user1, user2, password1, password2; pstring path1, path2; struct smbc_server *srv = NULL; @@ -867,19 +892,25 @@ int smbc_rename(const char *oname, const char *nname) DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - smbc_parse_path(oname, server1, share1, path1); - smbc_parse_path(nname, server2, share2, path2); + smbc_parse_path(oname, server1, share1, path1, user1, password1); - if (strcmp(server1, server2) || strcmp(share1, share2)) { + if (user1[0] == (char)0) pstrcpy(user1, smbc_user); - /* Can't rename across file systems */ + smbc_parse_path(nname, server2, share2, path2, user2, password2); + + if (user2[0] == (char)0) pstrcpy(user2, smbc_user); + + if (strcmp(server1, server2) || strcmp(share1, share2) || + strcmp(user1, user2)) { + + /* Can't rename across file systems, or users?? */ errno = EXDEV; return -1; } - srv = smbc_server(server1, share1); + srv = smbc_server(server1, share1, lp_workgroup(), user1, password1); if (!srv) { return -1; @@ -1059,7 +1090,7 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, int smbc_stat(const char *fname, struct stat *st) { struct smbc_server *srv; - fstring server, share; + fstring server, share, user, password; pstring path; time_t m_time = 0, a_time = 0, c_time = 0; size_t size = 0; @@ -1082,9 +1113,11 @@ int smbc_stat(const char *fname, struct stat *st) DEBUG(4, ("stat(%s)\n", fname)); - smbc_parse_path(fname, server, share, path); + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - srv = smbc_server(server, share); + if (user[0] == (char)0) pstrcpy(user, smbc_user); + + srv = smbc_server(server, share, lp_workgroup(), user, password); if (!srv) { @@ -1353,7 +1386,7 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) int smbc_opendir(const char *fname) { struct in_addr addr; - fstring server, share; + fstring server, share, user, password; pstring path; struct smbc_server *srv = NULL; struct in_addr rem_ip; @@ -1373,13 +1406,15 @@ int smbc_opendir(const char *fname) } - if (smbc_parse_path(fname, server, share, path)) { + if (smbc_parse_path(fname, server, share, path, user, password)) { errno = EINVAL; return -1; } + if (user[0] == (char)0) pstrcpy(user, smbc_user); + /* Get a file entry ... */ slot = 0; @@ -1433,7 +1468,7 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(server, "IPC$"); + srv = smbc_server(server, "IPC$", lp_workgroup(), user, password); if (!srv) { @@ -1486,7 +1521,7 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(buserver, "IPC$"); + srv = smbc_server(buserver, "IPC$", lp_workgroup(), user, password); if (!srv) { @@ -1518,7 +1553,7 @@ int smbc_opendir(const char *fname) smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, "IPC$"); + srv = smbc_server(server, "IPC$", lp_workgroup(), user, password); if (!srv) { @@ -1560,7 +1595,7 @@ int smbc_opendir(const char *fname) smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, share); + srv = smbc_server(server, share, lp_workgroup(), user, password); if (!srv) { @@ -1638,6 +1673,70 @@ int smbc_closedir(int fd) * Routine to get a directory entry */ +static char smbc_local_dirent[512]; /* Make big enough */ + +struct smbc_dirent *smbc_readdir(unsigned int fd) +{ + struct smbc_file *fe; + struct smbc_dirent *dirp, *dirent; + + /* Check that all is ok first ... */ + + if (!smbc_initialized) { + + errno = EUCLEAN; + return NULL; + + } + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return NULL; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + if (fe->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + return NULL; + + } + + if (!fe->dir_next) + return NULL; + else { + + dirent = fe->dir_next->dirent; + + if (!dirent) { + + errno = ENOENT; + return NULL; + + } + + /* Hmmm, do I even need to copy it? */ + + bcopy(dirent, smbc_local_dirent, dirent->dirlen); /* Copy the dirent */ + + dirp = (struct smbc_dirent *)smbc_local_dirent; + + dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); + + fe->dir_next = fe->dir_next->next; + + return (struct smbc_dirent *)smbc_local_dirent; + } + +} + +/* + * Routine to get directory entries + */ + int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) { struct smbc_file *fe; -- cgit From 338fd23290cb0770b59cb77ef4733bb8da6d3164 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 12 Jan 2001 12:48:55 +0000 Subject: Some more bug fixes plus implementations of smbc_mkdir and smbc_rmdir, both tested ... More later. (This used to be commit 66bb40153a9ff38692356cadfad89cf91439032e) --- source3/libsmb/libsmbclient.c | 157 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 807dfb987c..de0653588c 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1828,6 +1828,9 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) int smbc_mkdir(const char *fname, mode_t mode) { + struct smbc_server *srv; + fstring server, share, user, password; + pstring path; if (!smbc_initialized) { @@ -1836,10 +1839,164 @@ int smbc_mkdir(const char *fname, mode_t mode) } + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("stat(%s)\n", fname)); + + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) pstrcpy(user, smbc_user); + + srv = smbc_server(server, share, lp_workgroup(), user, password); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { + + mode = aDIR | aRONLY; + + } + else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { + + if (strcmp(path, "\\") == 0) { + + mode = aDIR | aRONLY; + + } + else { + + mode = aRONLY; + smbc_stat_printjob(srv, path, &size, &m_time); + c_time = a_time = m_time; + + } + else { */ + + if (!cli_mkdir(&srv->cli, path)) { + + errno = smbc_errno(&srv->cli); + return -1; + + } + + return 0; + +} + +/* + * Routine to remove a directory + */ + +int smbc_rmdir(const char *fname) +{ + struct smbc_server *srv; + fstring server, share, user, password; + pstring path; + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("stat(%s)\n", fname)); + + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) pstrcpy(user, smbc_user); + + srv = smbc_server(server, share, lp_workgroup(), user, password); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { + + mode = aDIR | aRONLY; + + } + else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { + + if (strcmp(path, "\\") == 0) { + + mode = aDIR | aRONLY; + + } + else { + + mode = aRONLY; + smbc_stat_printjob(srv, path, &size, &m_time); + c_time = a_time = m_time; + + } + else { */ + + if (!cli_rmdir(&srv->cli, path)) { + + errno = smbc_errno(&srv->cli); + return -1; + + } + return 0; } +/* + * Routine to return the current directory position + */ + +off_t smbc_telldir(int fd) +{ + struct smbc_file *fe; + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + fe = smbc_file_table[fd - smbc_start_fd]; + + if (fe->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + return -1; + + } + + return (off_t) fe->dir_next; + +} + /* * Routine to seek on a directory */ -- cgit From 552d6bce08fdf98c50c3dbc7b873a49bd72baac5 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 14 Jan 2001 00:11:29 +0000 Subject: Fixed bugs relating to Win2K and the need for a codepage so that unicode strings can be handled correctly. (This used to be commit 5629b097d4f04ad45c66f270bd58f08d7c717353) --- source3/libsmb/libsmbclient.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index de0653588c..f51ae42280 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -502,6 +502,8 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) } + codepage_initialise(lp_client_code_page()); /* Get a codepage */ + reopen_logs(); /* Get logging working ... */ /* @@ -1391,6 +1393,8 @@ int smbc_opendir(const char *fname) struct smbc_server *srv = NULL; struct in_addr rem_ip; int slot = 0; + uint8 eclass; + uint32 ecode; if (!smbc_initialized) { @@ -1444,7 +1448,9 @@ int smbc_opendir(const char *fname) smbc_file_table[slot]->srv = NULL; smbc_file_table[slot]->offset = 0; smbc_file_table[slot]->file = False; - smbc_file_table[slot]->dir_list = NULL; + smbc_file_table[slot]->dir_list = + smbc_file_table[slot]->dir_next = + smbc_file_table[slot]->dir_end = NULL; if (server[0] == (char)0) { @@ -1487,6 +1493,7 @@ int smbc_opendir(const char *fname) if (smbc_file_table[slot]) free(smbc_file_table[slot]); smbc_file_table[slot] = NULL; + errno = cli_error(&srv->cli, &eclass, &ecode, NULL); return -1; } @@ -1540,6 +1547,7 @@ int smbc_opendir(const char *fname) if (smbc_file_table[slot]) free(smbc_file_table[slot]); smbc_file_table[slot] = NULL; + errno = cli_error(&srv->cli, &eclass, &ecode, NULL); return -1; } @@ -1567,9 +1575,10 @@ int smbc_opendir(const char *fname) /* Now, list the servers ... */ - if (!cli_RNetShareEnum(&srv->cli, list_fn, - (void *)smbc_file_table[slot])) { + if (cli_RNetShareEnum(&srv->cli, list_fn, + (void *)smbc_file_table[slot]) < 0) { + errno = cli_error(&srv->cli, &eclass, &ecode, NULL); if (smbc_file_table[slot]) free(smbc_file_table[slot]); smbc_file_table[slot] = NULL; return -1; -- cgit From 5a0e2f19575f98a6d5530e66a9e3758e9a1c0a1a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 15 Jan 2001 23:34:32 +0000 Subject: Added remaining samr functions needed by winbindd. Added #define/#undef NEW_NTDOMAIN symbols. (This used to be commit 13e4fd1d84ab1150446530b11c47c4d6617014cb) --- source3/libsmb/cli_samr.c | 198 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 198 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 09b39265b2..22ef324d63 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -1,3 +1,4 @@ +#define NEW_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 2.2 @@ -275,6 +276,55 @@ uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, return result; } +/* Open handle on a group */ + +uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, + uint32 access_mask, uint32 group_rid, + POLICY_HND *group_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_OPEN_GROUP q; + SAMR_R_OPEN_GROUP r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_open_group(&q, domain_pol, access_mask, group_rid); + + if (!samr_io_q_open_group("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_open_group("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *group_pol = r.group_pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Query user info */ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, @@ -314,7 +364,103 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, /* Return output parameters */ + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Query group info */ + +uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, + uint32 info_level, GROUP_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_GROUPINFO q; + SAMR_R_QUERY_GROUPINFO r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_query_groupinfo(&q, group_pol, info_level); + + if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + r.ctr = ctr; + + if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Query user groups */ + +uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, + uint32 *num_groups, DOM_GID **gid) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_USERGROUPS q; + SAMR_R_QUERY_USERGROUPS r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_query_usergroups(&q, user_pol); + + if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *num_groups = r.num_entries; + *gid = r.gid; } done: @@ -323,3 +469,55 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, return result; } + +/* Query user groups */ + +uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, + uint32 *num_mem, uint32 **rid, uint32 **attr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_GROUPMEM q; + SAMR_R_QUERY_GROUPMEM r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); + prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + + /* Marshall data and send request */ + + init_samr_q_query_groupmem(&q, group_pol); + + if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *num_mem = r.num_entries; + *rid = r.rid; + *attr = r.attr; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +#undef NEW_NTDOMAIN -- cgit From d53f9716bb10efe164b67f9916ab5e59880c9b7c Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 24 Jan 2001 12:32:20 +0000 Subject: Fix a problem with smbc_unlink on directories where it was returning EACCES instead of EPERM and a problem with SMBC_OPEN where it ignored an error from the underlying cli_open routine and cheerfully returned a bogus FD. (This used to be commit 68614bac5a1a4109fdfb728aeae6956b13c64d8f) --- source3/libsmb/libsmbclient.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f51ae42280..7cf5ad7dd7 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -618,7 +618,16 @@ int smbc_open(const char *fname, int flags, mode_t mode) } - fd = cli_open(&srv->cli, path, flags, DENY_NONE); + if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) { + + /* Handle the error ... */ + + free(smbc_file_table[slot]); + smbc_file_table[slot] = NULL; + errno = smbc_errno(&srv->cli); + return -1; + + } /* Fill in file struct */ @@ -860,6 +869,35 @@ int smbc_unlink(const char *fname) if (!cli_unlink(&srv->cli, path)) { errno = smbc_errno(&srv->cli); + + if (errno == EACCES) { /* Check if the file is a directory */ + + int err, saverr = errno; + struct stat st; + size_t size = 0; + uint16 mode = 0; + time_t m_time = 0, a_time = 0, c_time = 0; + SMB_INO_T ino = 0; + + if (!smbc_getatr(srv, path, &mode, &size, + &c_time, &a_time, &m_time, &ino)) { + + /* Hmmm, bad error ... What? */ + + errno = smbc_errno(&srv->cli); + return -1; + + } + else { + + if (IS_DOS_DIR(mode)) + errno = EPERM; + else + errno = saverr; /* Restore this */ + + } + } + return -1; } -- cgit From 5aef8a21c6e3cd690afb11d2d69d2e9bac25b6b4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Jan 2001 02:59:13 +0000 Subject: Fixes from appliance-head for pdc searches. Jeremy. (This used to be commit d04ed97ecab846def8467f313a71ef0e5c4005f6) --- source3/libsmb/namequery.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 59a3856cfb..173fe12bcb 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -628,23 +628,6 @@ static BOOL resolve_hosts(const char *name, return False; } -/******************************************************** - Resolve a name into an IP address. Use this function if - the string is either an IP address, DNS or host name - or NetBIOS name. This uses the name switch in the - smb.conf to determine the order of name resolution. -*********************************************************/ -BOOL is_ip_address(const char *name) -{ - int i; - for (i=0; name[i]; i++) - if (!(isdigit((int)name[i]) || name[i] == '.')) - return False; - - return True; -} - - /******************************************************** Internal interface to resolve a name into an IP address. Use this function if the string is either an IP address, DNS @@ -775,7 +758,7 @@ BOOL resolve_srv_name(const char* srv_name, fstring dest_host, ret = resolve_name(dest_host, ip, 0x20); } - if (is_ip_address(dest_host)) + if (is_ipaddress(dest_host)) { fstrcpy(dest_host, "*SMBSERVER"); } -- cgit From 4f7b2b7083e4b4e6541633a5e2ffddb7989229a0 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 25 Jan 2001 13:47:13 +0000 Subject: Remove an inet_aton so that this code will compile on Solaris ... Ahhh, the sweet smell of portability. (This used to be commit 09902d2d4a51b134190861fbb3ddaabcae5bc1bb) --- source3/libsmb/clidgram.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 70e97c6bb6..e7391734ea 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -162,7 +162,6 @@ int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz) bcopy(&dgram->data[92], buf, MIN(bufsiz, (dgram->datasize - 92))); - return 0; } else return -1; @@ -187,8 +186,8 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) } - inet_aton("0.0.0.0", &my_ip); - + bzero(&my_ip, 4); /* Cheap way to get 0.0.0.0 in there */ + if (!resolve_name(myname, &my_ip, 0x00)) { /* FIXME: Call others here */ fprintf(stderr, "Could not resolve name: %s<00>\n", myname); @@ -219,7 +218,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) cli_get_response(True, "\\MAILSLOT\\BROWSE", cli_backup_list, sizeof(cli_backup_list)); /* Should check the response here ... FIXME */ - return 0; + } /* @@ -235,5 +234,4 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam strncpy(servername, cli_backup_list, MIN(16, namesize)); - return 0; } -- cgit From 7eea846f52f223855d1abe52f39a29b690f97099 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 29 Jan 2001 04:52:12 +0000 Subject: Add an extra error code translation to clierror.c so that libsmbclient gets some more error codes correct ... (This used to be commit bca6b7dd20839a15aa97b4e6ba03c60eab9ed237) --- source3/libsmb/clierror.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index eb2ca624e8..6d49986790 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -198,11 +198,12 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ case ERRbadshare: return EBUSY; case ERRlock: return EBUSY; case ERROR_INVALID_NAME: return ENOENT; + case ERRnosuchshare: return ENODEV; } } if (rcls == ERRSRV) { switch (code) { - case ERRbadpw: return EACCES; + case ERRbadpw: return EPERM; case ERRaccess: return EACCES; case ERRnoresource: return ENOMEM; case ERRinvdevice: return ENODEV; -- cgit From b370588b9c451d6aa8a0ba0f7513013f6d9847ac Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 29 Jan 2001 09:34:24 +0000 Subject: Fix some bugs and prepare for some other bug fixes ... (This used to be commit 4ae7812353c0ed088fb1ae4cd79c99daab363d1c) --- source3/libsmb/libsmbclient.c | 73 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 7cf5ad7dd7..f093e2b4be 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -179,6 +179,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, char *user, char *password) /* FIXME, lengths of strings */ { static pstring s; + pstring userinfo; char *p; int len; fstring workgroup; @@ -215,7 +216,47 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, } - /* ok, its for us. Now parse out the server, share etc. */ + /* + * ok, its for us. Now parse out the server, share etc. + * + * However, we want to parse out [[domain;]user[:password]@] if it + * exists ... + */ + + if (strchr(p, '@')) { + pstring username, passwd, domain; + char *u = userinfo; + + next_token(&p, userinfo, "@", sizeof(fstring)); + + username[0] = passwd[0] = domain[0] = 0; + + if (strchr(u, ';')) { + + next_token(&u, domain, ";", sizeof(fstring)); + + } + + if (strchr(u, ':')) { + + next_token(&u, username, ":", sizeof(fstring)); + + pstrcpy(passwd, u); + + } + else { + + pstrcpy(username, u); + + } + + if (username[0]) + strncpy(user, username, sizeof(fstring)); /* FIXME, size and domain */ + + if (passwd[0]) + strncpy(password, passwd, sizeof(fstring)); /* FIXME, size */ + + } if (!next_token(&p, server, "/", sizeof(fstring))) { @@ -298,14 +339,18 @@ struct smbc_server *smbc_server(char *server, char *share, return NULL; } - /* Pick up the auth info here, once we know we need to connect */ + /* + * Pick up the auth info here, once we know we need to connect + * But only if we do not have a username and password ... + */ - smbc_auth_fn(server, share, workgroup, sizeof(fstring), - username, sizeof(fstring), password, sizeof(fstring)); + if (!username[0] || !password[0]) + smbc_auth_fn(server, share, workgroup, sizeof(fstring), + username, sizeof(fstring), password, sizeof(fstring)); /* * However, smbc_auth_fn may have picked up info relating to an - * existing connection, so try for and existing connection again ... + * existing connection, so try for an existing connection again ... */ for (srv=smbc_srvs;srv;srv=srv->next) { @@ -437,6 +482,9 @@ struct smbc_server *smbc_server(char *server, char *share, /* *Initialise the library etc + * + * We accept valiv values for debug from 0 to 100, + * and insist that fn must be non-null. */ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) @@ -446,6 +494,18 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) int p, pid; char *user = NULL, *host = NULL, *home = NULL, *pname="libsmbclient"; + /* + * Next lot ifdef'd out until test suite fixed ... + */ +#ifdef 0 + if (!fn || debug < 0 || debug > 100) { + + errno = EINVAL; + return -1; + + } +#endif + smbc_initialized = 1; smbc_auth_fn = fn; smbc_debug = debug; @@ -584,6 +644,7 @@ int smbc_open(const char *fname, int flags, mode_t mode) if (!srv) { + if (errno == EPERM) errno = EACCES; return -1; /* smbc_server sets errno */ } @@ -891,7 +952,7 @@ int smbc_unlink(const char *fname) else { if (IS_DOS_DIR(mode)) - errno = EPERM; + errno = EISDIR; else errno = saverr; /* Restore this */ -- cgit From f9a2be782207013445e2f228a08e44b209a9133c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 2 Feb 2001 17:42:00 +0000 Subject: Convert netbios name to dos codepage in make_nmb_name(). This allows nmblookup and smbclient to work with i18n netbios names. (This used to be commit 2eabb7c229fb8a64d47757f291b327f5b7f26b55) --- source3/libsmb/nmblib.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 01c4001f4c..22ff09faa3 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -832,6 +832,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); StrnCpy( n->name, name, 15 ); + unix_to_dos(n->name, True); strupper( n->name ); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope, 63 ); -- cgit From 2fd7e6e6a0d1b22d841d49c4fc0868c0be471475 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 4 Feb 2001 19:48:26 +0000 Subject: Fix some further small bugs in libsmbclient to make it pass the Caldera test suite and start to add the printing routines. (This used to be commit 838cfad404ef648ee7909f449264afa4db60fa3b) --- source3/libsmb/libsmbclient.c | 63 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f093e2b4be..feb0baaee3 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -364,7 +364,7 @@ struct smbc_server *smbc_server(char *server, char *share, make_nmb_name(&calling, my_netbios_name, 0x0); make_nmb_name(&called , server, 0x20); - DEBUG(4,("server_n=[%s] server=[%s]\n", server_n, server)); + DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); if ((p=strchr(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { @@ -497,14 +497,13 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) /* * Next lot ifdef'd out until test suite fixed ... */ -#ifdef 0 + if (!fn || debug < 0 || debug > 100) { errno = EINVAL; return -1; } -#endif smbc_initialized = 1; smbc_auth_fn = fn; @@ -1167,7 +1166,7 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, } - DEBUG(4,("sending qpathinfo\n")); + DEBUG(4,("smbc_getatr: sending qpathinfo\n")); if (!srv->no_pathinfo2 && cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, @@ -1212,7 +1211,7 @@ int smbc_stat(const char *fname, struct stat *st) } - DEBUG(4, ("stat(%s)\n", fname)); + DEBUG(4, ("smbc_stat(%s)\n", fname)); smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ @@ -1954,7 +1953,7 @@ int smbc_mkdir(const char *fname, mode_t mode) } - DEBUG(4, ("stat(%s)\n", fname)); + DEBUG(4, ("smbc_mkdir(%s)\n", fname)); smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ @@ -2024,7 +2023,7 @@ int smbc_rmdir(const char *fname) } - DEBUG(4, ("stat(%s)\n", fname)); + DEBUG(4, ("smbc_rmdir(%s)\n", fname)); smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ @@ -2140,3 +2139,53 @@ int smbc_fstatdir(int fd, struct stat *st) return 0; } + +/* + * Routine to list print jobs on a printer share ... + */ + +int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) +{ + struct smbc_server *srv; + fstring server, share, user, password; + pstring path; + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) pstrcpy(user, smbc_user); + + srv = smbc_server(server, share, lp_workgroup(), user, password); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + if (cli_print_queue(&srv->cli, fn) < 0) { + + errno = smbc_errno(&srv->cli); + return -1; + + } + + return 0; + +} + -- cgit From ca03ad79cfaad48fb20426dfb98a30740fe80a0d Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 5 Feb 2001 13:02:20 +0000 Subject: Implement two printing related functions and start the remaining two. (This used to be commit c19559a286c3ec6dedefbd2423aa5738edd9ba41) --- source3/libsmb/libsmbclient.c | 63 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index feb0baaee3..68dbe666f7 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2138,6 +2138,20 @@ int smbc_fstatdir(int fd, struct stat *st) return 0; +} + +/* + * Routine to print a file on a remote server ... + * + * We open the file, which we assume to be on a remote server, and then + * copy it to a print file on the share specified by printq. + */ + +int smbc_print_file(const char *fname, const char *printq) +{ + + + } /* @@ -2189,3 +2203,52 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } +/* + * Delete a print job from a remote printer share + */ + +int smbc_unlink_print_job(const char *fname, int id) +{ + struct smbc_server *srv; + fstring server, share, user, password; + pstring path; + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); + + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) pstrcpy(user, smbc_user); + + srv = smbc_server(server, share, lp_workgroup(), user, password); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + if (cli_printjob_del(&srv->cli, id) < 0) { + + errno = smbc_errno(&srv->cli); + return -1; + + } + + return 0; + +} + -- cgit From 5455f2896f65a650a32f18dfb4bc4ae81a79848e Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 6 Feb 2001 19:25:12 +0000 Subject: Fix problems in libsmbclient with pring job struct plus add implementation of last two print routines ... (This used to be commit 7c50af3b71eeedfef8ed0d5771c2dc578fa95741) --- source3/libsmb/libsmbclient.c | 96 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 68dbe666f7..3afa98b28e 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2149,8 +2149,104 @@ int smbc_fstatdir(int fd, struct stat *st) int smbc_print_file(const char *fname, const char *printq) { + int fid1, fid2, bytes, saverr, tot_bytes = 0; + char buf[4096]; + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + if (!fname && !printq) { + + errno = EINVAL; + return -1; + + } + + /* Try to open the file for reading ... */ + + if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { + + return -1; /* smbc_open sets errno */ + + } + + /* Now, try to open the printer file for writing */ + + if ((fid2 = smbc_open_print_job(printq)) < 0) { + + saverr = errno; /* Save errno */ + smbc_close(fid1); + errno = saverr; + return -1; + + } + + while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) { + + tot_bytes += bytes; + + if ((smbc_write(fid2, buf, bytes)) < 0) { + + saverr = errno; + smbc_close(fid1); + smbc_close(fid2); + errno = saverr; + + } + + } + + saverr = errno; + + smbc_close(fid1); /* We have to close these anyway */ + smbc_close(fid2); + + if (bytes < 0) { + + errno = saverr; + return -1; + + } + + return tot_bytes; + +} + +/* + * Open a print file to be written to by other calls + */ + +int smbc_open_print_job(const char *fname) +{ + struct smbc_server *srv; + fstring server, share, user, password; + pstring path; + + if (!smbc_initialized) { + + errno = EUCLEAN; + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_open_print_job(%s)\n", fname)); + + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + + /* What if the path is empty, or the file exists? */ + return smbc_open(fname, O_WRONLY, 666); } -- cgit From 167a7d76d96a2e4884b85ac3eb775050b34346de Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 12 Feb 2001 12:17:54 +0000 Subject: Added commented/documented version of libsmbclient.h and fixed up a small problem in libsmbclient.c where we no longer pass the workgroup. (This used to be commit 3c6611434601a45ba448f0313397104c7cea616c) --- source3/libsmb/libsmbclient.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3afa98b28e..3541028fb8 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -487,9 +487,8 @@ struct smbc_server *smbc_server(char *server, char *share, * and insist that fn must be non-null. */ -int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) +int smbc_init(smbc_get_auth_data_fn fn, int debug) { - static pstring workgroup; pstring conf; int p, pid; char *user = NULL, *host = NULL, *home = NULL, *pname="libsmbclient"; @@ -532,7 +531,6 @@ int smbc_init(smbc_get_auth_data_fn fn, const char *wgroup, int debug) */ slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); - pstrcpy(workgroup, wgroup); charset_initialise(); -- cgit From 64172d82fcf1762a8bc938282919f9e3bd39675d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 14 Feb 2001 05:34:50 +0000 Subject: Merge of i18n fixes from appliance branch. Samba can now talk to a network with a PDC that has international netbios name and domain name. There's still quite a bit of i18n stuff to fix though... (This used to be commit 79045bd72ace9144e7dd73785b1d10a71b0d15aa) --- source3/libsmb/cliconnect.c | 7 ++++--- source3/libsmb/namequery.c | 2 ++ 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3e41ec8296..96bf06d0ac 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -43,9 +43,9 @@ prots[] = /**************************************************************************** - Send a session setup. The username is in UNIX character format and must be - converted to DOS codepage format before sending. If the password is in - plaintext, the same should be done. + Send a session setup. The username and workgroup is in UNIX character + format and must be converted to DOS codepage format before sending. If the + password is in plaintext, the same should be done. ****************************************************************************/ BOOL cli_session_setup(struct cli_state *cli, @@ -166,6 +166,7 @@ BOOL cli_session_setup(struct cli_state *cli, strupper(p); p = skip_string(p,1); pstrcpy(p,workgroup); + unix_to_dos(p,True); strupper(p); p = skip_string(p,1); pstrcpy(p,"Unix");p = skip_string(p,1); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 173fe12bcb..3e4855b037 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -184,6 +184,8 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name) StrnCpy(name, status[i].name, 15); + dos_to_unix(name, True); + free(status); return True; } -- cgit From 7f9fbcd0eff68e7a27847dd56a0f17f9433af93f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 15 Feb 2001 05:42:04 +0000 Subject: Merge of i18n password fix for smbclient. (This used to be commit ec217eb8fc2a9cf329a51c51ba08a04fa5b008c2) --- source3/libsmb/cliconnect.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 96bf06d0ac..8a56a08b1d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -87,7 +87,6 @@ BOOL cli_session_setup(struct cli_state *cli, fstrcpy(pword, pass); unix_to_dos(pword,True); fstrcpy(ntpword, ntpass);; - unix_to_dos(ntpword,True); SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword); SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword); } else if ((cli->sec_mode & 2) && passlen == 24) { -- cgit From fd46817f0b20c633c80dee70a29cf7478e2dfd68 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Feb 2001 19:21:18 +0000 Subject: Excise snprintf -> slprintf. srv_samr.c: duplicate gid fix. srv_spoolss_nt.c: Merge of JF's work. uid.c: Fix for returning names when a PDC. Jeremy. (This used to be commit d938ad6963a2dd4eda930d508600ec1902dc2b16) --- source3/libsmb/clidgram.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index e7391734ea..c58e3fc796 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -166,6 +166,7 @@ int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz) else return -1; + return 0; } /* @@ -219,6 +220,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) /* Should check the response here ... FIXME */ + return 0; } /* @@ -234,4 +236,7 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam strncpy(servername, cli_backup_list, MIN(16, namesize)); + /* Should check the response here ... FIXME */ + + return 0; } -- cgit From 0293869b1f6012d1f106e4ab1bd392cea1c66ff0 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 18 Feb 2001 10:36:03 +0000 Subject: Fixes to libsmbclient so it will work when browsing real Windows systems which only respond to port 138 when dealing with NetBIOS datagrams. We use the unexpected packed database. (This used to be commit 620cc34015ab16d25f7ef7e13cbc3d0f669da11e) --- source3/libsmb/clidgram.c | 43 +++++++----- source3/libsmb/libsmbclient.c | 4 +- source3/libsmb/namequery.c | 153 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index c58e3fc796..68ac3b5c45 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -42,6 +42,7 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len, struct sockaddr_in sock_out; char *ptr, *p2; char tmp[4]; + int name_size; bzero((char *)&p, sizeof(p)); @@ -51,8 +52,6 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len, if (dgram_sock < 1) { - int name_size; - if ((dgram_sock = open_socket_out(SOCK_DGRAM, &dest_ip, 138, LONG_CONNECT_TIMEOUT)) < 0) { DEBUG(4, ("open_sock_out failed ...")); @@ -67,22 +66,35 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len, /* Now, bind my addr to it ... */ bzero((char *)&sock_out, sizeof(sock_out)); - putip((char *)&sock_out.sin_addr, (char *)&src_ip); - sock_out.sin_port = INADDR_ANY; + sock_out.sin_addr.s_addr = INADDR_ANY; + sock_out.sin_port = htons(138); sock_out.sin_family = AF_INET; - bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)); + if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) { + + /* Try again on any port ... */ - /* Now, figure out what socket name we were bound to. We want the port */ + sock_out.sin_port = INADDR_ANY; - name_size = sizeof(sock_out); + if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) { - getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size); + DEBUG(4, ("failed to bind socket to address ...\n")); + return False; - fprintf(stderr, "Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port)); + } + + } } + /* Now, figure out what socket name we were bound to. We want the port */ + + name_size = sizeof(sock_out); + + getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size); + + fprintf(stderr, "Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port)); + /* * Next, build the DGRAM ... */ @@ -93,8 +105,10 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len, dgram->header.flags.first = True; dgram->header.flags.more = False; dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100); - dgram->header.source_ip = src_ip; + dgram->header.source_ip.s_addr = sock_out.sin_addr.s_addr; + fprintf(stderr, "Source IP = %0X\n", dgram->header.source_ip); dgram->header.source_port = ntohs(sock_out.sin_port); + fprintf(stderr, "Source Port = %0X\n", dgram->header.source_port); dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ dgram->header.packet_offset = 0; @@ -147,7 +161,7 @@ int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz) { struct packet_struct *packet; - packet = read_packet(dgram_sock, DGRAM_PACKET); + packet = receive_dgram_packet(dgram_sock, 2, mailslot); if (packet) { /* We got one, pull what we want out of the SMB data ... */ @@ -166,7 +180,6 @@ int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz) else return -1; - return 0; } /* @@ -187,7 +200,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) } - bzero(&my_ip, 4); /* Cheap way to get 0.0.0.0 in there */ + my_ip.s_addr = inet_addr("0.0.0.0"); if (!resolve_name(myname, &my_ip, 0x00)) { /* FIXME: Call others here */ @@ -220,7 +233,6 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) /* Should check the response here ... FIXME */ - return 0; } /* @@ -236,7 +248,4 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam strncpy(servername, cli_backup_list, MIN(16, namesize)); - /* Should check the response here ... FIXME */ - - return 0; } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3541028fb8..67d5b92100 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -544,8 +544,6 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) in_client = True; /* FIXME, make a param */ - - if (!lp_load(conf, True, False, False)) { /* @@ -563,6 +561,8 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) reopen_logs(); /* Get logging working ... */ + name_register_wins(my_netbios_name, 0); + /* * Now initialize the file descriptor array and figure out what the * max open files is, so we can return FD's that are above the max diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 3e4855b037..f6ada87840 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -190,6 +190,100 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name) return True; } +/**************************************************************************** + Do a NetBIOS name registation to try to claim a name ... +***************************************************************************/ +BOOL name_register(int fd, const char *name, int name_type, + struct in_addr name_ip, int opcode, + BOOL bcast, + struct in_addr to_ip, int *count) +{ + int i, retries = 3, retry = bcast?250:2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + struct in_addr register_ip; + + DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip))); + + register_ip.s_addr = name_ip.s_addr; /* Fix this ... */ + + bzero((char *)&p, sizeof(p)); + + *count = 0; + + nmb->header.name_trn_id = generate_trn_id(); + nmb->header.opcode = opcode; + nmb->header.response = False; + nmb->header.nm_flags.bcast = False; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = True; /* ? */ + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = True; + + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 1; + + make_nmb_name(&nmb->question.question_name, name, name_type); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + /* Now, create the additional stuff for a registration request */ + + if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) { + + DEBUG(0, ("name_register: malloc fail for additional record.\n")); + return False; + + } + + bzero((char *)nmb->additional, sizeof(struct res_rec)); + + nmb->additional->rr_name = nmb->question.question_name; + nmb->additional->rr_type = RR_TYPE_NB; + nmb->additional->rr_class = RR_CLASS_IN; + + /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */ + if (nmb->header.nm_flags.bcast) + nmb->additional->ttl = PERMANENT_TTL; + else + nmb->additional->ttl = lp_max_ttl(); + + nmb->additional->rdlength = 6; + + nmb->additional->rdata[0] = NB_MFLAG & 0xFF; + + /* Set the address for the name we are registering. */ + putip(&nmb->additional->rdata[2], ®ister_ip); + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return False; + + retries--; + + if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + + + free(p2); /* No memory leaks ... */ + + } + + return True; +} /**************************************************************************** Do a netbios name query to find someones IP. @@ -456,6 +550,65 @@ void endlmhosts(FILE *fp) fclose(fp); } +BOOL name_register_wins(const char *name, int name_type) +{ + int sock, i, return_count; + int num_interfaces = iface_count(); + struct in_addr sendto_ip; + + /* + * Do a broadcast register ... + */ + + if (!lp_wins_server()) + return False; + + DEBUG(4, ("name_register_wins:Registering my name %s on %s\n", name, lp_wins_server())); + + sock = open_socket_in(SOCK_DGRAM, 0, 3, + interpret_addr("0.0.0.0"), True); + + if (sock == -1) return False; + + set_socket_options(sock, "SO_BROADCAST"); + + sendto_ip.s_addr = inet_addr(lp_wins_server()); + + if (num_interfaces > 1) { + + for (i = 0; i < num_interfaces; i++) { + + if (!name_register(sock, name, name_type, *iface_n_ip(i), + NMB_NAME_MULTIHOMED_REG_OPCODE, + True, sendto_ip, &return_count)) { + + close(sock); + return False; + + } + + } + + } + else { + + if (!name_register(sock, name, name_type, *iface_n_ip(0), + NMB_NAME_REG_OPCODE, + True, sendto_ip, &return_count)) { + + close(sock); + return False; + + } + + } + + close(sock); + + return True; + +} + /******************************************************** Resolve via "bcast" method. *********************************************************/ -- cgit From 8a3d6ee07e6f1abb54ac94e105f4c29ec8a49995 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 19 Feb 2001 02:17:27 +0000 Subject: Change code around and add retry to deal with the occassional loss of NetBIOS datagrams responses, either via TDB or direct receive ... (This used to be commit 54b0fbe98b1cbb1d9d62606c16921dbffc3a3c6d) --- source3/libsmb/clidgram.c | 135 +++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 62 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 68ac3b5c45..28041e1b76 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -29,72 +29,20 @@ * cli_send_mailslot, send a mailslot for client code ... */ -static int dgram_sock = -1; - -int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len, +int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, + char *buf, int len, const char *srcname, int src_type, const char *dstname, int dest_type, struct in_addr dest_ip, struct in_addr src_ip, - int dest_port) + int dest_port, int src_port) { struct packet_struct p; struct dgram_packet *dgram = &p.packet.dgram; - struct sockaddr_in sock_out; char *ptr, *p2; char tmp[4]; - int name_size; bzero((char *)&p, sizeof(p)); - /* - * First, check if we have an open socket to the dest IP - */ - - if (dgram_sock < 1) { - - if ((dgram_sock = open_socket_out(SOCK_DGRAM, &dest_ip, 138, LONG_CONNECT_TIMEOUT)) < 0) { - - DEBUG(4, ("open_sock_out failed ...")); - return False; - - } - - /* Make it a broadcast socket ... */ - - set_socket_options(dgram_sock, "SO_BROADCAST"); - - /* Now, bind my addr to it ... */ - - bzero((char *)&sock_out, sizeof(sock_out)); - sock_out.sin_addr.s_addr = INADDR_ANY; - sock_out.sin_port = htons(138); - sock_out.sin_family = AF_INET; - - if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) { - - /* Try again on any port ... */ - - sock_out.sin_port = INADDR_ANY; - - if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) { - - DEBUG(4, ("failed to bind socket to address ...\n")); - return False; - - } - - } - - } - - /* Now, figure out what socket name we were bound to. We want the port */ - - name_size = sizeof(sock_out); - - getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size); - - fprintf(stderr, "Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port)); - /* * Next, build the DGRAM ... */ @@ -105,9 +53,9 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len, dgram->header.flags.first = True; dgram->header.flags.more = False; dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100); - dgram->header.source_ip.s_addr = sock_out.sin_addr.s_addr; + dgram->header.source_ip.s_addr = src_ip.s_addr; fprintf(stderr, "Source IP = %0X\n", dgram->header.source_ip); - dgram->header.source_port = ntohs(sock_out.sin_port); + dgram->header.source_port = ntohs(src_port); fprintf(stderr, "Source Port = %0X\n", dgram->header.source_port); dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ dgram->header.packet_offset = 0; @@ -157,11 +105,11 @@ int cli_send_mailslot(BOOL unique, char *mailslot, char *buf, int len, /* * cli_get_response: Get a response ... */ -int cli_get_response(BOOL unique, char *mailslot, char *buf, int bufsiz) +int cli_get_response(int dgram_sock, BOOL unique, char *mailslot, char *buf, int bufsiz) { struct packet_struct *packet; - packet = receive_dgram_packet(dgram_sock, 2, mailslot); + packet = receive_dgram_packet(dgram_sock, 5, mailslot); if (packet) { /* We got one, pull what we want out of the SMB data ... */ @@ -193,6 +141,9 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) char outbuf[15]; char *p; struct in_addr sendto_ip, my_ip; + int dgram_sock; + struct sockaddr_in sock_out; + int name_size; if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) { @@ -208,6 +159,57 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) } + if ((dgram_sock = open_socket_out(SOCK_DGRAM, &sendto_ip, 138, LONG_CONNECT_TIMEOUT)) < 0) { + + DEBUG(4, ("open_sock_out failed ...")); + return False; + + } + + /* Make it a broadcast socket ... */ + + set_socket_options(dgram_sock, "SO_BROADCAST"); + + /* Make it non-blocking??? */ + + if (fcntl(dgram_sock, F_SETFL, O_NONBLOCK) < 0) { + + fprintf(stderr, "Unable to set non blocking on dgram sock\n"); + + } + + /* Now, bind a local addr to it ... Try port 138 first ... */ + + bzero((char *)&sock_out, sizeof(sock_out)); + sock_out.sin_addr.s_addr = INADDR_ANY; + sock_out.sin_port = htons(138); + sock_out.sin_family = AF_INET; + + if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) { + + /* Try again on any port ... */ + + sock_out.sin_port = INADDR_ANY; + + if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) { + + DEBUG(4, ("failed to bind socket to address ...\n")); + return False; + + } + + } + + /* Now, figure out what socket name we were bound to. We want the port */ + + name_size = sizeof(sock_out); + + getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size); + + fprintf(stderr, "Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port)); + + /* Now, build the request */ + bzero(cli_backup_list, sizeof(cli_backup_list)); bzero(outbuf, sizeof(outbuf)); @@ -222,17 +224,20 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) SIVAL(p, 0, 1); /* The sender's token ... */ p += 4; - cli_send_mailslot(True, "\\MAILSLOT\\BROWSE", outbuf, PTR_DIFF(p, outbuf), - myname, 0, send_to_name, 0x1d, sendto_ip, my_ip, 138); + cli_send_mailslot(dgram_sock, True, "\\MAILSLOT\\BROWSE", outbuf, + PTR_DIFF(p, outbuf), myname, 0, send_to_name, + 0x1d, sendto_ip, my_ip, 138, sock_out.sin_port); /* We should check the error and return if we got one */ /* Now, get the response ... */ - cli_get_response(True, "\\MAILSLOT\\BROWSE", cli_backup_list, sizeof(cli_backup_list)); + cli_get_response(dgram_sock, True, "\\MAILSLOT\\BROWSE", cli_backup_list, sizeof(cli_backup_list)); /* Should check the response here ... FIXME */ + close(dgram_sock); + } /* @@ -246,6 +251,12 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam cli_get_backup_list(my_name, target); /* FIXME: Check the response */ + if (!cli_backup_list[0]) { /* Empty list ... try again */ + + cli_get_backup_list(my_name, target); + + } + strncpy(servername, cli_backup_list, MIN(16, namesize)); } -- cgit From 2e99f0f8d31eb1e9ff518df17be30205752b17cd Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 19 Feb 2001 05:50:09 +0000 Subject: Opps, last one did not commit the correct changes ... Here they are. This now uses a lookup on <1D> and then does a name status query to the IP address returned to find the name of the server. Seems to work well against Samba, Win9X, WinNT and Win2K. (This used to be commit debb723194f903c7b3af61f93949df062985e218) --- source3/libsmb/libsmbclient.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 67d5b92100..1444e5883a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1471,7 +1471,7 @@ static void dir_list_fn(file_info *finfo, const char *mask, void *state) { - fprintf(stderr, "Finfo->name=%s, mask=%s\n", finfo->name, mask); + /* fprintf(stderr, "Finfo->name=%s, mask=%s, mode=%0X\n", finfo->name, mask, finfo->mode);*/ if (add_dirent((struct smbc_file *)state, finfo->name, "", (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { @@ -1561,14 +1561,30 @@ int smbc_opendir(const char *fname) /* We have server and share and path empty ... so list the workgroups */ - /* fprintf(stderr, "Workgroup is: %s\n", lp_workgroup()); */ - cli_get_backup_server(my_netbios_name, lp_workgroup(), server, sizeof(server)); + /*cli_get_backup_server(my_netbios_name, lp_workgroup(), server, sizeof(server));*/ + + if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) { + + errno = EINVAL; /* Something wrong with smb.conf? */ + return -1; + + } smbc_file_table[slot]->dir_type = SMBC_WORKGROUP; - /* - * Get a connection to IPC$ on the server if we do not already have one - */ + /* find the name of the server ... */ + + if (!name_status_find(0, rem_ip, server)) { + + fprintf(stderr, "Could not get the name of local master browser ...\n"); + errno = EINVAL; + return -1; + + } + + /* + * Get a connection to IPC$ on the server if we do not already have one + */ srv = smbc_server(server, "IPC$", lp_workgroup(), user, password); @@ -1618,7 +1634,15 @@ int smbc_opendir(const char *fname) * Get the backup list ... */ - cli_get_backup_server(my_netbios_name, server, buserver, sizeof(buserver)); + /*cli_get_backup_server(my_netbios_name, server, buserver, sizeof(buserver)); */ + + if (!name_status_find(0, rem_ip, buserver)) { + + fprintf(stderr, "Could not get name of local master browser ...\n"); + errno = EPERM; /* FIXME, is this correct */ + return -1; + + } /* * Get a connection to IPC$ on the server if we do not already have one -- cgit From 6492d6b2f6a2743f5e794447911cbbba7e031d5d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 08:09:06 +0000 Subject: initial client side unicode support (needed for netapp filer) I've currently got this code disabled by default as it is incomplete. You enable it by setting a USE_UNICODE environment variable. Once the support is complete this check will be removed and the CAP_UNICODE capability bit will be the sole determination of whether the client library code uses unicode right now I have converted session_setup and tconx. I will do more fns over the next few days. see clistr.c for the new client side string interface. Luckily it tends to make the code smaller and neater while adding unicode support. (This used to be commit e1a04e621f1c28d8e6e543d43741ca0272e2237f) --- source3/libsmb/cliconnect.c | 75 ++++++++++----------- source3/libsmb/clientgen.c | 18 ++++- source3/libsmb/clistr.c | 161 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 41 deletions(-) create mode 100644 source3/libsmb/clistr.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8a56a08b1d..74a10ddf8b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -104,8 +104,7 @@ BOOL cli_session_setup(struct cli_state *cli, /* * Plaintext mode needed, assume plaintext supplied. */ - fstrcpy(pword, pass); - unix_to_dos(pword,True); + passlen = clistr_push(cli, pword, pass, -1, CLISTR_CONVERT|CLISTR_TERMINATE); fstrcpy(ntpword, ""); ntpasslen = 0; } @@ -124,7 +123,10 @@ BOOL cli_session_setup(struct cli_state *cli, if (cli->protocol < PROTOCOL_NT1) { - set_message(cli->outbuf,10,1 + strlen(user) + passlen,True); + set_message(cli->outbuf,10, + clistr_align(cli, 1) + + clistr_push_size(cli, user, -1, CLISTR_TERMINATE|CLISTR_CONVERT) + + passlen,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -135,11 +137,10 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); p = smb_buf(cli->outbuf); + p += clistr_align(cli, PTR_DIFF(p,cli->outbuf)); memcpy(p,pword,passlen); p += passlen; - pstrcpy(p,user); - unix_to_dos(p,True); - strupper(p); + clistr_push(cli, p, user, -1, CLISTR_CONVERT|CLISTR_UPPER|CLISTR_TERMINATE); } else { @@ -156,20 +157,15 @@ BOOL cli_session_setup(struct cli_state *cli, SSVAL(cli->outbuf,smb_vwv8,ntpasslen); SSVAL(cli->outbuf,smb_vwv11,CAP_NT_SMBS|(cli->use_level_II_oplocks ? CAP_LEVEL_II_OPLOCKS : 0)); p = smb_buf(cli->outbuf); + p += clistr_align(cli, PTR_DIFF(p,cli->outbuf)); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpword,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - pstrcpy(p,user); - unix_to_dos(p,True); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,workgroup); - unix_to_dos(p,True); - strupper(p); - p = skip_string(p,1); - pstrcpy(p,"Unix");p = skip_string(p,1); - pstrcpy(p,"Samba");p = skip_string(p,1); + p += clistr_push(cli, p, user, -1, CLISTR_CONVERT|CLISTR_TERMINATE|CLISTR_UPPER); + p += clistr_push(cli, p, workgroup, -1, CLISTR_CONVERT|CLISTR_TERMINATE|CLISTR_UPPER); + p += clistr_push(cli, p, "Unix", -1, CLISTR_CONVERT|CLISTR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, CLISTR_CONVERT|CLISTR_TERMINATE); set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } @@ -187,24 +183,18 @@ BOOL cli_session_setup(struct cli_state *cli, cli->vuid = SVAL(cli->inbuf,smb_uid); if (cli->protocol >= PROTOCOL_NT1) { - /* - * Save off some of the connected server - * info. - */ - char *server_domain,*server_os,*server_type; - server_os = smb_buf(cli->inbuf); - server_type = skip_string(server_os,1); - server_domain = skip_string(server_type,1); - fstrcpy(cli->server_os, server_os); - dos_to_unix(cli->server_os, True); - fstrcpy(cli->server_type, server_type); - dos_to_unix(cli->server_type, True); - fstrcpy(cli->server_domain, server_domain); - dos_to_unix(cli->server_domain, True); + /* + * Save off some of the connected server + * info. + */ + char *p = smb_buf(cli->inbuf); + p += clistr_align(cli, PTR_DIFF(p,cli->outbuf)); + p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); + p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); + p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); } fstrcpy(cli->user_name, user); - dos_to_unix(cli->user_name, True); return True; } @@ -257,12 +247,11 @@ BOOL cli_send_tconX(struct cli_state *cli, unix_to_dos(dos_pword,True); SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); } else { - if(!(cli->sec_mode & 2)) { + if((cli->sec_mode & 3) == 0) { /* * Non-encrypted passwords - convert to DOS codepage before using. */ - fstrcpy(pword,pass); - unix_to_dos(pword,True); + passlen = clistr_push(cli, pword, pass, -1, CLISTR_CONVERT|CLISTR_TERMINATE); } else { memcpy(pword, pass, passlen); } @@ -274,7 +263,10 @@ BOOL cli_send_tconX(struct cli_state *cli, strupper(fullshare); set_message(cli->outbuf,4, - 2 + strlen(fullshare) + passlen + strlen(dev),True); + clistr_push_size(cli, fullshare, -1, CLISTR_TERMINATE | CLISTR_CONVERT) + + passlen + + 1+strlen(dev), + True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -284,10 +276,10 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - fstrcpy(p,fullshare); - p = skip_string(p,1); - pstrcpy(p,dev); - unix_to_dos(p,True); + p += clistr_push(cli, p, fullshare, -1, CLISTR_CONVERT | CLISTR_TERMINATE); + fstrcpy(p, dev); p += strlen(dev)+1; + + set_message(cli->outbuf,4,PTR_DIFF(p,smb_buf(cli->outbuf)),False); SCVAL(cli->inbuf,smb_rcls, 1); @@ -302,7 +294,7 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->dev, "A:"); if (cli->protocol >= PROTOCOL_NT1) { - fstrcpy(cli->dev, smb_buf(cli->inbuf)); + clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, CLISTR_TERMINATE | CLISTR_CONVERT); } if (strcasecmp(share,"IPC$")==0) { @@ -461,6 +453,9 @@ BOOL cli_negprot(struct cli_state *cli) cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); + /* this ensures cli_use_unicode is setup - delete this call later (tridge) */ + cli_setup_packet(cli); + return True; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1938049806..d7649074db 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -95,19 +95,35 @@ BOOL cli_send_smb(struct cli_state *cli) return True; } +int cli_use_unicode = 0; + /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ void cli_setup_packet(struct cli_state *cli) { + static int initialised; + + /* the USE_UNICODE check will be deleted once our client side unicode + support is complete (tridge) */ + if (!initialised) { + initialised = 1; + if (getenv("USE_UNICODE")) cli_use_unicode = 1; + } + cli->rap_error = 0; cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); if (cli->protocol > PROTOCOL_CORE) { + uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); - SSVAL(cli->outbuf,smb_flg2,0x1); + flags2 = FLAGS2_LONG_PATH_COMPONENTS; + if (cli_use_unicode && cli->capabilities & CAP_UNICODE) { + flags2 |= FLAGS2_UNICODE_STRINGS; + } + SSVAL(cli->outbuf,smb_flg2, flags2); } } diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c new file mode 100644 index 0000000000..839dec7592 --- /dev/null +++ b/source3/libsmb/clistr.c @@ -0,0 +1,161 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client string routines + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +/* we will delete this variable once our client side unicode support is complete */ +extern int cli_use_unicode; + +/**************************************************************************** +copy a string from a char* src to a unicode or ascii +dos code page destination choosing unicode or ascii based on the +cli->capabilities flag +return the number of bytes occupied by the string in the destination +flags can have: + CLISTR_TERMINATE means include the null termination + CLISTR_CONVERT means convert from unix to dos codepage + CLISTR_UPPER means uppercase in the destination +dest_len is the maximum length allowed in the destination. If dest_len +is -1 then no maxiumum is used +****************************************************************************/ +int clistr_push(struct cli_state *cli, void *dest, char *src, int dest_len, int flags) +{ + int len; + + /* treat a pstring as "unlimited" length */ + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { + /* the server doesn't want unicode */ + safe_strcpy(dest, src, dest_len); + len = strlen(dest); + if (flags & CLISTR_TERMINATE) len++; + if (flags & CLISTR_CONVERT) unix_to_dos(dest,True); + if (flags & CLISTR_UPPER) strupper(dest); + return len; + } + + /* the server likes unicode. give it the works */ + if (flags & CLISTR_CONVERT) { + dos_PutUniCode(dest, src, dest_len, flags & CLISTR_TERMINATE); + } else { + ascii_to_unistr(dest, src, dest_len); + } + if (flags & CLISTR_UPPER) { + strupper_w(dest); + } + len = strlen(src)*2; + if (flags & CLISTR_TERMINATE) len += 2; + return len; +} + + +/**************************************************************************** +return the length that a string would occupy when copied with clistr_push() + CLISTR_TERMINATE means include the null termination + CLISTR_CONVERT means convert from unix to dos codepage + CLISTR_UPPER means uppercase in the destination +****************************************************************************/ +int clistr_push_size(struct cli_state *cli, char *src, int dest_len, int flags) +{ + int len = strlen(src); + if (flags & CLISTR_TERMINATE) len++; + if (cli_use_unicode && (cli->capabilities & CAP_UNICODE)) len *= 2; + return len; +} + +/**************************************************************************** +copy a string from a unicode or ascii source (depending on +cli->capabilities) to a char* destination +flags can have: + CLISTR_CONVERT means convert from dos to unix codepage + CLISTR_TERMINATE means the string in src is null terminated +if CLISTR_TERMINATE is set then src_len is ignored +src_len is the length of the source area in bytes +return the number of bytes occupied by the string in src +****************************************************************************/ +int clistr_pull(struct cli_state *cli, char *dest, void *src, int dest_len, int src_len, int flags) +{ + int len; + + if (dest_len == -1) { + dest_len = sizeof(pstring); + } + + if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { + /* the server doesn't want unicode */ + if (flags & CLISTR_TERMINATE) { + safe_strcpy(dest, src, dest_len); + len = strlen(src)+1; + } else { + if (src_len > dest_len) src_len = dest_len; + len = src_len; + memcpy(dest, src, len); + dest[len] = 0; + } + if (flags & CLISTR_CONVERT) dos_to_unix(dest,True); + return len; + } + + if (flags & CLISTR_TERMINATE) { + unistr_to_ascii(dest, src, dest_len); + len = strlen(dest)*2 + 2; + } else { + int i, c; + if (dest_len < src_len) src_len = dest_len; + for (i=0; i < src_len; i += 2) { + c = SVAL(src, i); + *dest++ = c; + } + *dest++ = 0; + len = src_len; + } + if (flags & CLISTR_CONVERT) dos_to_unix(dest,True); + return len; +} + +/**************************************************************************** +return the length that a string would occupy (not including the null) +when copied with clistr_pull() +if src_len is -1 then assume the source is null terminated +****************************************************************************/ +int clistr_pull_size(struct cli_state *cli, void *src, int src_len) +{ + if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { + return strlen(src); + } + return strlen_w(src); +} + +/**************************************************************************** +return an alignment of either 0 or 1 +if unicode is not negotiated then return 0 +otherwise return 1 if offset is off +****************************************************************************/ +int clistr_align(struct cli_state *cli, int offset) +{ + if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) return 0; + return offset & 1; +} -- cgit From c565c98723f1fab04d47ae6076d742c8ee2dcb49 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 10:11:40 +0000 Subject: pipe opening now works with unicode (This used to be commit ba3ce3404e1cd2e9da3ba1708f6fc8a12c085ef2) --- source3/libsmb/cliconnect.c | 17 ++++------------- source3/libsmb/clilist.c | 2 +- source3/libsmb/clirap.c | 19 ++++++++----------- source3/libsmb/clistr.c | 23 ++++++++++++++++++++++- source3/libsmb/clitrans.c | 13 ++++++++++--- 5 files changed, 45 insertions(+), 29 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 74a10ddf8b..4f9c5ad615 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -123,10 +123,7 @@ BOOL cli_session_setup(struct cli_state *cli, if (cli->protocol < PROTOCOL_NT1) { - set_message(cli->outbuf,10, - clistr_align(cli, 1) + - clistr_push_size(cli, user, -1, CLISTR_TERMINATE|CLISTR_CONVERT) + - passlen,True); + set_message(cli->outbuf,10, 0, True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -137,10 +134,10 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); p = smb_buf(cli->outbuf); - p += clistr_align(cli, PTR_DIFF(p,cli->outbuf)); memcpy(p,pword,passlen); p += passlen; - clistr_push(cli, p, user, -1, CLISTR_CONVERT|CLISTR_UPPER|CLISTR_TERMINATE); + p += clistr_push(cli, p, user, -1, CLISTR_CONVERT|CLISTR_UPPER|CLISTR_TERMINATE); + set_message(cli->outbuf,10,PTR_DIFF(p,smb_buf(cli->outbuf)),False); } else { @@ -157,7 +154,6 @@ BOOL cli_session_setup(struct cli_state *cli, SSVAL(cli->outbuf,smb_vwv8,ntpasslen); SSVAL(cli->outbuf,smb_vwv11,CAP_NT_SMBS|(cli->use_level_II_oplocks ? CAP_LEVEL_II_OPLOCKS : 0)); p = smb_buf(cli->outbuf); - p += clistr_align(cli, PTR_DIFF(p,cli->outbuf)); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpword,ntpasslen); @@ -188,7 +184,6 @@ BOOL cli_session_setup(struct cli_state *cli, * info. */ char *p = smb_buf(cli->inbuf); - p += clistr_align(cli, PTR_DIFF(p,cli->outbuf)); p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); @@ -262,11 +257,7 @@ BOOL cli_send_tconX(struct cli_state *cli, unix_to_dos(fullshare, True); strupper(fullshare); - set_message(cli->outbuf,4, - clistr_push_size(cli, fullshare, -1, CLISTR_TERMINATE | CLISTR_CONVERT) + - passlen + - 1+strlen(dev), - True); + set_message(cli->outbuf,4, 0, True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index ae1607c1c4..d4c67fd9e4 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -205,7 +205,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, } if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ + NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index cd261eac59..cd0e5ab73f 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -27,18 +27,15 @@ /**************************************************************************** Call a remote api on an arbitrary pipe. takes param, data and setup buffers. ****************************************************************************/ -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, int pipe_name_len, +BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, char *data, uint32 data_count, uint32 max_data_count, char **rparam, uint32 *rparam_count, char **rdata, uint32 *rdata_count) { - if (pipe_name_len == 0) - pipe_name_len = strlen(pipe_name); - cli_send_trans(cli, SMBtrans, - pipe_name, pipe_name_len, + pipe_name, 0,0, /* fid, flags */ setup, setup_count, max_setup_count, params, param_count, max_param_count, @@ -59,8 +56,8 @@ BOOL cli_api(struct cli_state *cli, char **rdata, int *rdrcnt) { cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* Name, length */ - 0,0, /* fid, flags */ + PIPE_LANMAN, /* Name */ + 0,0, /* fid, flags */ NULL,0,0, /* Setup, length, max */ param, prcnt, mprcnt, /* Params, length, max */ data, drcnt, mdrcnt /* Data, length, max */ @@ -385,7 +382,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char data_len = 532; if (cli_send_trans(cli,SMBtrans, - PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */ + PIPE_LANMAN, /* name */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ @@ -437,7 +434,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, do { ret = (cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ + NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ @@ -510,7 +507,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, unix_to_dos(¶m[6],True); if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ + NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ @@ -582,7 +579,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ + NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 839dec7592..eb66d08c30 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -47,6 +47,11 @@ int clistr_push(struct cli_state *cli, void *dest, char *src, int dest_len, int dest_len = sizeof(pstring); } + if (clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { + dest++; + dest_len--; + } + if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { /* the server doesn't want unicode */ safe_strcpy(dest, src, dest_len); @@ -77,12 +82,18 @@ return the length that a string would occupy when copied with clistr_push() CLISTR_TERMINATE means include the null termination CLISTR_CONVERT means convert from unix to dos codepage CLISTR_UPPER means uppercase in the destination +note that dest is only used for alignment purposes. No data is written. ****************************************************************************/ -int clistr_push_size(struct cli_state *cli, char *src, int dest_len, int flags) +int clistr_push_size(struct cli_state *cli, void *dest, char *src, int dest_len, int flags) { int len = strlen(src); if (flags & CLISTR_TERMINATE) len++; if (cli_use_unicode && (cli->capabilities & CAP_UNICODE)) len *= 2; + + if (clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { + len++; + } + return len; } @@ -104,6 +115,11 @@ int clistr_pull(struct cli_state *cli, char *dest, void *src, int dest_len, int dest_len = sizeof(pstring); } + if (clistr_align(cli, PTR_DIFF(cli->inbuf, src))) { + src++; + if (src_len > 0) src_len--; + } + if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { /* the server doesn't want unicode */ if (flags & CLISTR_TERMINATE) { @@ -143,6 +159,11 @@ if src_len is -1 then assume the source is null terminated ****************************************************************************/ int clistr_pull_size(struct cli_state *cli, void *src, int src_len) { + if (clistr_align(cli, PTR_DIFF(cli->inbuf, src))) { + src++; + if (src_len > 0) src_len--; + } + if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { return strlen(src); } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 5cd6ae30ce..3afca997cc 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -28,7 +28,7 @@ send a SMB trans or trans2 request ****************************************************************************/ BOOL cli_send_trans(struct cli_state *cli, int trans, - char *name, int pipe_name_len, + char *pipe_name, int fid, int flags, uint16 *setup, int lsetup, int msetup, char *param, int lparam, int mparam, @@ -39,6 +39,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, int tot_data=0,tot_param=0; char *outdata,*outparam; char *p; + int pipe_name_len=0; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); @@ -49,7 +50,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); - outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len+1 : 3); + if (pipe_name) { + pipe_name_len = clistr_push_size(cli, smb_buf(cli->outbuf), + pipe_name, -1, + CLISTR_TERMINATE); + } + + outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3); outdata = outparam+this_lparam; /* primary request */ @@ -69,7 +76,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); p = smb_buf(cli->outbuf); if (trans==SMBtrans) { - memcpy(p,name, pipe_name_len + 1); /* name[] */ + clistr_push(cli, p, pipe_name, -1, CLISTR_TERMINATE); } else { *p++ = 0; /* put in a null smb_name */ *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ -- cgit From 23ded01d93ae83bbfab4c7b373f40e92ab1386db Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 10:19:02 +0000 Subject: converted cli_mkdir() (This used to be commit bce3ed01a9c3c7c89cdc21b60f1122dc6b6db264) --- source3/libsmb/clifile.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ce9a79ede3..ab16b21564 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -107,7 +107,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 2 + strlen(dname),True); + set_message(cli->outbuf,0, 0,True); CVAL(cli->outbuf,smb_com) = SMBmkdir; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -115,8 +115,9 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,dname); - unix_to_dos(p,True); + p += clistr_push(cli, p, dname, -1, CLISTR_CONVERT|CLISTR_TERMINATE); + + set_message(cli->outbuf,0, PTR_DIFF(p, smb_buf(cli->outbuf)), False); cli_send_smb(cli); if (!cli_receive_smb(cli)) { -- cgit From c7c3db2f16e572e14c5d881b641271b2ab9aa4be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 12:22:30 +0000 Subject: converted cli_list() (This used to be commit bdce09b77807c80281c1e169b7c4813c9238fbe3) --- source3/libsmb/cliconnect.c | 11 ++++++- source3/libsmb/clilist.c | 77 ++++++++++++++++++++++++++------------------- source3/libsmb/clistr.c | 3 +- 3 files changed, 57 insertions(+), 34 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4f9c5ad615..31bdfdca46 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -141,6 +141,15 @@ BOOL cli_session_setup(struct cli_state *cli, } else { + uint32 capabilities; + + capabilities = CAP_NT_SMBS; + if (cli->use_level_II_oplocks) + capabilities |= CAP_LEVEL_II_OPLOCKS; + if (getenv("USE_UNICODE") && + (cli->capabilities & CAP_UNICODE)) { + capabilities |= CAP_UNICODE; + } set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; cli_setup_packet(cli); @@ -152,7 +161,7 @@ BOOL cli_session_setup(struct cli_state *cli, SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SSVAL(cli->outbuf,smb_vwv11,CAP_NT_SMBS|(cli->use_level_II_oplocks ? CAP_LEVEL_II_OPLOCKS : 0)); + SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += SVAL(cli->outbuf,smb_vwv7); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d4c67fd9e4..f7044b27e8 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -30,7 +30,8 @@ The length of the structure is returned The structure of a long filename depends on the info level. 260 is used by NT and 2 is used by OS/2 ****************************************************************************/ -static int interpret_long_filename(int level,char *p,file_info *finfo) +static int interpret_long_filename(struct cli_state *cli, + int level,char *p,file_info *finfo) { extern file_info def_finfo; @@ -47,8 +48,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+27); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+27, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } return(28 + CVAL(p,26)); @@ -60,8 +63,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+31); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+31, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } return(32 + CVAL(p,30)); @@ -74,8 +79,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+16); finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+33); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+33, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } return(SVAL(p,4)+4); @@ -87,8 +94,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+16); finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+37); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+37, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } return(SVAL(p,4)+4); @@ -124,16 +133,15 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) p += 4; /* EA size */ slen = SVAL(p, 0); p += 2; - if (p[1] == 0 && slen > 1) { - /* NT has stuffed up again */ - unistr_to_dos(finfo->short_name, p, slen/2); - } else { - strncpy(finfo->short_name, p, 12); - finfo->short_name[12] = 0; - } + clistr_pull(cli, finfo->short_name, p, + sizeof(finfo->short_name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); p += 24; /* short name? */ - StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); return(ret); } return(SVAL(p,0)); @@ -172,7 +180,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, pstring param; pstrcpy(mask,Mask); - unix_to_dos(mask,True); while (ff_eos == 0) { loop_count++; @@ -181,7 +188,9 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - param_len = 12+strlen(mask)+1; + param_len = 12+clistr_push_size(cli, NULL, mask, -1, + CLISTR_TERMINATE | + CLISTR_CONVERT); if (First) { setup = TRANSACT2_FINDFIRST; @@ -190,7 +199,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,4+2); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); - pstrcpy(param+12,mask); + clistr_push(cli, param+12, mask, -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -198,10 +208,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ - pstrcpy(param+12,mask); - - DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_lastname,mask)); + clistr_push(cli, param+12, mask, -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } if (!cli_send_trans(cli, SMBtrans2, @@ -254,19 +262,24 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, switch(info_level) { case 260: - StrnCpy(mask,p+ff_lastname, - MIN(sizeof(mask)-1,data_len-ff_lastname)); + clistr_pull(cli, mask, p+ff_lastname, + sizeof(mask), + data_len-ff_lastname, + CLISTR_TERMINATE | + CLISTR_CONVERT); break; case 1: - pstrcpy(mask,p + ff_lastname + 1); + clistr_pull(cli, mask, p+ff_lastname+1, + sizeof(mask), + -1, + CLISTR_TERMINATE | + CLISTR_CONVERT); break; } } else { pstrcpy(mask,""); } - dos_to_unix(mask, True); - /* and add them to the dirlist pool */ dirlist = Realloc(dirlist,dirlist_len + data_len); @@ -278,7 +291,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, /* put in a length for the last entry, to ensure we can chain entries into the next packet */ for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(info_level,p2,NULL); + p2 += interpret_long_filename(cli,info_level,p2,NULL); SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); /* grab the data for later use */ @@ -299,7 +312,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, } for (p=dirlist,i=0;ioutbuf, dest))) { + *(char *)dest = 0; dest++; dest_len--; } @@ -90,7 +91,7 @@ int clistr_push_size(struct cli_state *cli, void *dest, char *src, int dest_len, if (flags & CLISTR_TERMINATE) len++; if (cli_use_unicode && (cli->capabilities & CAP_UNICODE)) len *= 2; - if (clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { + if (dest && clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { len++; } -- cgit From d4b2639c00c17ad98d038e7974b1b1eddd541e0e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 12:25:42 +0000 Subject: converted cli_chkpath() (This used to be commit 95268f52556e5983004e594002b7e18a8656d1f0) --- source3/libsmb/clifile.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ab16b21564..0cfe168f43 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -710,14 +710,15 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) if (!*path2) *path2 = '\\'; memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,4 + strlen(path2),True); + set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBchkpth); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; - safe_strcpy(p,path2,strlen(path2)); - unix_to_dos(p,True); + p += clistr_push(cli, p, path2, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + + set_message(cli->outbuf,0,PTR_DIFF(p, smb_buf(cli->outbuf)), False); cli_send_smb(cli); if (!cli_receive_smb(cli)) { -- cgit From 20b037b84951368cdac7fb65cd77aee0aeae9b37 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 12:30:01 +0000 Subject: converted cli_open() (This used to be commit db60c0c26242be0370e6459fe6f1634c97b61176) --- source3/libsmb/clifile.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 0cfe168f43..8dc16c3f66 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -141,7 +141,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 2 + strlen(dname),True); + set_message(cli->outbuf,0, 0, True); CVAL(cli->outbuf,smb_com) = SMBrmdir; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -149,8 +149,9 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,dname); - unix_to_dos(p,True); + p += clistr_push(cli, p, dname, -1, CLISTR_TERMINATE|CLISTR_CONVERT); + + set_message(cli->outbuf,0, PTR_DIFF(p, smb_buf(cli->outbuf)), False); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -301,7 +302,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,15,1 + strlen(fname),True); + set_message(cli->outbuf,15,0,True); CVAL(cli->outbuf,smb_com) = SMBopenX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -323,9 +324,9 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) } p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + + set_message(cli->outbuf,15, PTR_DIFF(p, smb_buf(cli->outbuf)), False); cli_send_smb(cli); if (!cli_receive_smb(cli)) { -- cgit From 8acf5e04482cb43734fbb786f8d363ee3bfff652 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 12:45:50 +0000 Subject: - neater setting of bcc - converted cli_rename and cli_unlink (This used to be commit 0a8992e224b7a3d90d45b13d73fa8a6f155efa79) --- source3/libsmb/cliconnect.c | 6 +++--- source3/libsmb/clientgen.c | 7 +++++++ source3/libsmb/clifile.c | 27 ++++++++++++++------------- source3/libsmb/climessage.c | 2 +- source3/libsmb/clitrans.c | 12 ++++-------- 5 files changed, 29 insertions(+), 25 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 31bdfdca46..4a957a9ccd 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -137,7 +137,7 @@ BOOL cli_session_setup(struct cli_state *cli, memcpy(p,pword,passlen); p += passlen; p += clistr_push(cli, p, user, -1, CLISTR_CONVERT|CLISTR_UPPER|CLISTR_TERMINATE); - set_message(cli->outbuf,10,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, p); } else { @@ -171,7 +171,7 @@ BOOL cli_session_setup(struct cli_state *cli, p += clistr_push(cli, p, workgroup, -1, CLISTR_CONVERT|CLISTR_TERMINATE|CLISTR_UPPER); p += clistr_push(cli, p, "Unix", -1, CLISTR_CONVERT|CLISTR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, CLISTR_CONVERT|CLISTR_TERMINATE); - set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, p); } cli_send_smb(cli); @@ -279,7 +279,7 @@ BOOL cli_send_tconX(struct cli_state *cli, p += clistr_push(cli, p, fullshare, -1, CLISTR_CONVERT | CLISTR_TERMINATE); fstrcpy(p, dev); p += strlen(dev)+1; - set_message(cli->outbuf,4,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, p); SCVAL(cli->inbuf,smb_rcls, 1); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d7649074db..c25e71ff3d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -127,6 +127,13 @@ void cli_setup_packet(struct cli_state *cli) } } +/**************************************************************************** +setup the bcc length of the packet from a pointer to the end of the data +****************************************************************************/ +void cli_setup_bcc(struct cli_state *cli, void *p) +{ + set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); +} /**************************************************************************** diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 8dc16c3f66..10b6a9e543 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -33,7 +33,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True); + set_message(cli->outbuf,1, 0, True); CVAL(cli->outbuf,smb_com) = SMBmv; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -43,12 +43,13 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,fname_src); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, fname_src, -1, + CLISTR_TERMINATE | CLISTR_CONVERT); *p++ = 4; - pstrcpy(p,fname_dst); - unix_to_dos(p,True); + p += clistr_push(cli, p, fname_dst, -1, + CLISTR_TERMINATE | CLISTR_CONVERT); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -72,7 +73,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 2 + strlen(fname),True); + set_message(cli->outbuf,1, 0,True); CVAL(cli->outbuf,smb_com) = SMBunlink; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -82,9 +83,9 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,fname); - unix_to_dos(p,True); + p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; @@ -117,7 +118,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) *p++ = 4; p += clistr_push(cli, p, dname, -1, CLISTR_CONVERT|CLISTR_TERMINATE); - set_message(cli->outbuf,0, PTR_DIFF(p, smb_buf(cli->outbuf)), False); + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -151,7 +152,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) *p++ = 4; p += clistr_push(cli, p, dname, -1, CLISTR_TERMINATE|CLISTR_CONVERT); - set_message(cli->outbuf,0, PTR_DIFF(p, smb_buf(cli->outbuf)), False); + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -326,7 +327,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) p = smb_buf(cli->outbuf); p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); - set_message(cli->outbuf,15, PTR_DIFF(p, smb_buf(cli->outbuf)), False); + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -719,7 +720,7 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) *p++ = 4; p += clistr_push(cli, p, path2, -1, CLISTR_TERMINATE | CLISTR_CONVERT); - set_message(cli->outbuf,0,PTR_DIFF(p, smb_buf(cli->outbuf)), False); + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index c15fdbce8c..058358e2f1 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -49,7 +49,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, unix_to_dos(p,True); p = skip_string(p,1); - set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, p); cli_send_smb(cli); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3afca997cc..630e9f93c0 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -85,8 +85,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memcpy(outparam,param,this_lparam); if (this_ldata) /* data[] */ memcpy(outdata,data,this_ldata); - set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); cli_send_smb(cli); @@ -126,8 +125,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memcpy(outparam,param+tot_param,this_lparam); if (this_ldata) /* data[] */ memcpy(outdata,data+tot_data,this_ldata); - set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); cli_send_smb(cli); @@ -295,8 +293,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, if (this_ldata) /* data[] */ memcpy(outdata,data,this_ldata); - set_message(cli->outbuf,19+lsetup, /* wcnt, bcc */ - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); cli_send_smb(cli); @@ -335,8 +332,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, memcpy(outparam,param+tot_param,this_lparam); if (this_ldata) /* data[] */ memcpy(outdata,data+tot_data,this_ldata); - set_message(cli->outbuf,18, - PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False); + cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); cli_send_smb(cli); -- cgit From c28d3f635887c22713221d2df3c7aee5b53dc613 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 12:49:55 +0000 Subject: converted nt_create and setatr (This used to be commit c40a1e4ebdb379482bf6e7d4efcc9b5321a4e7c6) --- source3/libsmb/clifile.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 10b6a9e543..199fd831c0 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -176,7 +176,7 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,24,1 + strlen(fname),True); + set_message(cli->outbuf,24,0,True); CVAL(cli->outbuf,smb_com) = SMBntcreateX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -197,9 +197,9 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); p = smb_buf(cli->outbuf); - pstrcpy(p,fname); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -623,16 +623,17 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0,strlen(fname)+2,True); + set_message(cli->outbuf,0,0,True); CVAL(cli->outbuf,smb_com) = SMBgetatr; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - unix_to_dos(p+1,True); + *p++ = 4; + p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -682,7 +683,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) p = smb_buf(cli->outbuf); *p = 4; pstrcpy(p+1, fname); - unix_to_dos(p+1,True); + unix_to_dos(p+1,True); p = skip_string(p,1); *p = 4; -- cgit From 064898cf8ad604c3d0a7399964b122d4c53fe7df Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 13:16:01 +0000 Subject: converted a bunch more fns (This used to be commit f6b8d6730452522f77852af0917cb48424d4c8a9) --- source3/libsmb/clifile.c | 40 ++++++++++++++++++++++++--------------- source3/libsmb/climessage.c | 10 ++++------ source3/libsmb/clirap.c | 46 ++++++++++++++++++++++++++------------------- 3 files changed, 56 insertions(+), 40 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 199fd831c0..60e9251995 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -224,7 +224,7 @@ int cli_nt_create_uni(struct cli_state *cli, char *fname, uint32 DesiredAccess) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,24,(strlen(fname) + 1) * 2 + 1,True); + set_message(cli->outbuf,24,0,True); CVAL(cli->outbuf,smb_com) = SMBntcreateX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -248,8 +248,8 @@ int cli_nt_create_uni(struct cli_state *cli, char *fname, uint32 DesiredAccess) p++; /* Alignment */ pstrcpy(uni, fname); unix_to_dos(uni, True); - dos_struni2(p, uni, (strlen(fname) + 1) * 2); - + p += dos_struni2(p, uni, (strlen(fname) + 1) * 2); + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return -1; @@ -386,7 +386,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,10,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBlockingX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -403,6 +403,11 @@ BOOL cli_lock(struct cli_state *cli, int fnum, SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); + + p += 10; + + cli_setup_bcc(cli, p); + cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); @@ -431,7 +436,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,10,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBlockingX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -448,7 +453,8 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) SSVAL(p, 0, cli->pid); SIVAL(p, 2, offset); SIVAL(p, 6, len); - + p += 10; + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; @@ -478,7 +484,7 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,20,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBlockingX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -497,6 +503,9 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, SIVAL(p, 8, (offset&0xffffffff)); SIVAL(p, 12, (len>>32)); SIVAL(p, 16, (len&0xffffffff)); + p += 20; + + cli_setup_bcc(cli, p); cli_send_smb(cli); cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); @@ -525,7 +534,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,20,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBlockingX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -544,7 +553,8 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ SIVAL(p, 8, (offset&0xffffffff)); SIVAL(p, 12, (len>>32)); SIVAL(p, 16, (len&0xffffffff)); - + p += 20; + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { return False; @@ -671,7 +681,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,strlen(fname)+4,True); + set_message(cli->outbuf,8,0,True); CVAL(cli->outbuf,smb_com) = SMBsetatr; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -681,11 +691,11 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) put_dos_date3(cli->outbuf,smb_vwv1, t); p = smb_buf(cli->outbuf); - *p = 4; - pstrcpy(p+1, fname); - unix_to_dos(p+1,True); - p = skip_string(p,1); - *p = 4; + *p++ = 4; + p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + *p++ = 4; + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 058358e2f1..47139dcfd6 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -41,13 +41,11 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, p = smb_buf(cli->outbuf); *p++ = 4; - pstrcpy(p,username); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, username, -1, + CLISTR_TERMINATE|CLISTR_CONVERT); *p++ = 4; - pstrcpy(p,host); - unix_to_dos(p,True); - p = skip_string(p,1); + p += clistr_push(cli, p, host, -1, + CLISTR_TERMINATE|CLISTR_CONVERT); cli_setup_bcc(cli, p); diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index cd0e5ab73f..d1ce4d712e 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -255,10 +255,9 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p += 4; SIVAL(p,0,stype); p += 4; - - pstrcpy(p, workgroup); - unix_to_dos(p, True); - p = skip_string(p,1); + + p += clistr_push(cli, p, workgroup, -1, + CLISTR_TERMINATE | CLISTR_CONVERT); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ @@ -275,29 +274,38 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, count=SVAL(rparam,4); p = rdata; - if (!(stype&0x80000000)) { for (i = 0;i < count;i++, p += 26) { - char *sname = p; - int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; - char *cmnt = comment_offset?(rdata+comment_offset):""; - if (comment_offset < 0 || comment_offset > rdrcnt) continue; - - stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - - dos_to_unix(sname, True); - dos_to_unix(cmnt, True); - fn(sname, stype, cmnt, state); + fstring sname, cmnt; + int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; + char *cptr = comment_offset?(rdata+comment_offset):NULL; + if (comment_offset < 0 || comment_offset > rdrcnt) continue; + + stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + clistr_pull(cli, sname, p, + sizeof(fstring), -1, + CLISTR_TERMINATE | + CLISTR_CONVERT); + fstrcpy(cmnt, ""); + if (cptr) { + clistr_pull(cli, cmnt, cptr, + sizeof(fstring), -1, + CLISTR_TERMINATE | + CLISTR_CONVERT); + } + fn(sname, stype, cmnt, state); } } else { for (i = 0; i < count; i++, p+= 16) { - char *sname = p; - - dos_to_unix(sname, True); + fstring sname; - fn(sname, stype, NULL, state); + clistr_pull(cli, sname, p, + sizeof(fstring), -1, + CLISTR_TERMINATE | + CLISTR_CONVERT); + fn(sname, stype, NULL, state); } } } -- cgit From f76015333a80521aa3f2a06524e4cebd5c4bda1a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 23:52:27 +0000 Subject: yipee! client unicode now works well with nt (This used to be commit 5b2ef8a1b914265c6072c968d2dad7d26c2aeffc) --- source3/libsmb/clifile.c | 12 +++++++++--- source3/libsmb/clilist.c | 4 ++-- source3/libsmb/clistr.c | 7 ++++--- 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 60e9251995..c5da049cf4 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -172,6 +172,7 @@ open a file int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) { char *p; + int len; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -194,10 +195,15 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); - SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname)); p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + /* this alignment and termination is critical for netapp filers. Don't change */ + p += clistr_align(cli, PTR_DIFF(p, cli->outbuf)); + len = clistr_push(cli, p, fname, -1, CLISTR_CONVERT); + p += len; + SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); + SSVAL(p, 0, 0); + p += 2; cli_setup_bcc(cli, p); @@ -248,7 +254,7 @@ int cli_nt_create_uni(struct cli_state *cli, char *fname, uint32 DesiredAccess) p++; /* Alignment */ pstrcpy(uni, fname); unix_to_dos(uni, True); - p += dos_struni2(p, uni, (strlen(fname) + 1) * 2); + p += dos_struni2(p, uni, (strlen(fname) + 1) * 2) * 2; cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f7044b27e8..9348b65bad 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -140,8 +140,8 @@ static int interpret_long_filename(struct cli_state *cli, p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), - -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + namelen, + CLISTR_CONVERT); return(ret); } return(SVAL(p,0)); diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 32168cae16..4c7c8e3077 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -40,17 +40,18 @@ is -1 then no maxiumum is used ****************************************************************************/ int clistr_push(struct cli_state *cli, void *dest, char *src, int dest_len, int flags) { - int len; + int len=0; /* treat a pstring as "unlimited" length */ if (dest_len == -1) { dest_len = sizeof(pstring); } - if (clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { + if (clistr_align(cli, PTR_DIFF(dest, cli->outbuf))) { *(char *)dest = 0; dest++; dest_len--; + len++; } if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { @@ -72,7 +73,7 @@ int clistr_push(struct cli_state *cli, void *dest, char *src, int dest_len, int if (flags & CLISTR_UPPER) { strupper_w(dest); } - len = strlen(src)*2; + len += strlen(src)*2; if (flags & CLISTR_TERMINATE) len += 2; return len; } -- cgit From 3910d7baca440b21e66c1dc15556748c6f028085 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Feb 2001 02:51:22 +0000 Subject: added support for a CLISTR_ASCII flag so we can use a uniform interface for ascii-only fields (This used to be commit cdf0316610803e6743936b29f232b32f9ec81422) --- source3/libsmb/clistr.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 4c7c8e3077..da40fba9e6 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -35,6 +35,7 @@ flags can have: CLISTR_TERMINATE means include the null termination CLISTR_CONVERT means convert from unix to dos codepage CLISTR_UPPER means uppercase in the destination + CLISTR_ASCII use ascii even with unicode servers dest_len is the maximum length allowed in the destination. If dest_len is -1 then no maxiumum is used ****************************************************************************/ @@ -47,14 +48,14 @@ int clistr_push(struct cli_state *cli, void *dest, char *src, int dest_len, int dest_len = sizeof(pstring); } - if (clistr_align(cli, PTR_DIFF(dest, cli->outbuf))) { + if (!(flags & CLISTR_ASCII) && clistr_align(cli, PTR_DIFF(dest, cli->outbuf))) { *(char *)dest = 0; dest++; dest_len--; len++; } - if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { + if ((flags & CLISTR_ASCII) || !cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { /* the server doesn't want unicode */ safe_strcpy(dest, src, dest_len); len = strlen(dest); @@ -90,9 +91,9 @@ int clistr_push_size(struct cli_state *cli, void *dest, char *src, int dest_len, { int len = strlen(src); if (flags & CLISTR_TERMINATE) len++; - if (cli_use_unicode && (cli->capabilities & CAP_UNICODE)) len *= 2; + if (!(flags & CLISTR_ASCII) && cli_use_unicode && (cli->capabilities & CAP_UNICODE)) len *= 2; - if (dest && clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { + if (!(flags & CLISTR_ASCII) && dest && clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { len++; } -- cgit From 518f2fc391266c2f9b9cfc8b485a8e57ce359be8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Feb 2001 02:52:41 +0000 Subject: reverted richards cli_NetServerEnum changes - they broke lots of things (This used to be commit 86adbb0caf26a8c2fc4d3748b965c0ce79360c1a) --- source3/libsmb/clirap.c | 68 +++++++++---------------------------------------- 1 file changed, 12 insertions(+), 56 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index d1ce4d712e..bf0940d1d6 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -218,36 +218,14 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, int uLevel = 1; int count = -1; - /* - * First, check that the stype is reasonable ... - */ - - if (stype&0x80000000 && stype&0x7FFFFFFF) { - - /* Set an error here ... */ - - return False; - - } - /* send a SMBtrans command with api NetServerEnum */ p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - if (!(stype&0x80000000)) - pstrcpy(p,"WrLehDz"); - else - pstrcpy(p,"WrLehDO"); + pstrcpy(p,"WrLehDz"); p = skip_string(p,1); - if (!(stype&0x80000000)) { - pstrcpy(p,"B16BBDz"); - uLevel = 1; - } - else { - pstrcpy(p,"B16"); - uLevel = 0; - } + pstrcpy(p,"B16BBDz"); p = skip_string(p,1); SSVAL(p,0,uLevel); @@ -257,7 +235,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p += 4; p += clistr_push(cli, p, workgroup, -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + CLISTR_TERMINATE | CLISTR_CONVERT | CLISTR_ASCII); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ @@ -274,39 +252,17 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, count=SVAL(rparam,4); p = rdata; - if (!(stype&0x80000000)) { - for (i = 0;i < count;i++, p += 26) { - fstring sname, cmnt; - int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; - char *cptr = comment_offset?(rdata+comment_offset):NULL; - if (comment_offset < 0 || comment_offset > rdrcnt) continue; - - stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - clistr_pull(cli, sname, p, - sizeof(fstring), -1, - CLISTR_TERMINATE | - CLISTR_CONVERT); - fstrcpy(cmnt, ""); - if (cptr) { - clistr_pull(cli, cmnt, cptr, - sizeof(fstring), -1, - CLISTR_TERMINATE | - CLISTR_CONVERT); - } - fn(sname, stype, cmnt, state); - } - } - else { - for (i = 0; i < count; i++, p+= 16) { - fstring sname; + for (i = 0;i < count;i++, p += 26) { + char *sname = p; + int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; + char *cmnt = comment_offset?(rdata+comment_offset):""; + if (comment_offset < 0 || comment_offset > rdrcnt) continue; - clistr_pull(cli, sname, p, - sizeof(fstring), -1, - CLISTR_TERMINATE | - CLISTR_CONVERT); + stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - fn(sname, stype, NULL, state); - } + dos_to_unix(sname, True); + dos_to_unix(cmnt, True); + fn(sname, stype, cmnt, state); } } } -- cgit From a8ab9840786b8376283743de8eef861d382b3171 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Feb 2001 03:40:20 +0000 Subject: the unicode conversion of our client code is complete enough to be enabled by default you can disable it by setting the environment variable CLI_FORCE_ASCII (This used to be commit 4d59c08c5e6f54c0d6ced7650750cb987e77b6c9) --- source3/libsmb/cliconnect.c | 12 ++++++----- source3/libsmb/clientgen.c | 13 +---------- source3/libsmb/clifile.c | 50 ------------------------------------------- source3/libsmb/clilist.c | 25 ++++++++++------------ source3/libsmb/clistr.c | 13 +++++------ source3/libsmb/libsmbclient.c | 6 ------ 6 files changed, 24 insertions(+), 95 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4a957a9ccd..d572c0f7d7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -144,10 +144,10 @@ BOOL cli_session_setup(struct cli_state *cli, uint32 capabilities; capabilities = CAP_NT_SMBS; - if (cli->use_level_II_oplocks) + if (cli->use_level_II_oplocks) { capabilities |= CAP_LEVEL_II_OPLOCKS; - if (getenv("USE_UNICODE") && - (cli->capabilities & CAP_UNICODE)) { + } + if (cli->capabilities & CAP_UNICODE) { capabilities |= CAP_UNICODE; } set_message(cli->outbuf,13,0,True); @@ -453,8 +453,10 @@ BOOL cli_negprot(struct cli_state *cli) cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); - /* this ensures cli_use_unicode is setup - delete this call later (tridge) */ - cli_setup_packet(cli); + /* a way to force ascii SMB */ + if (getenv("CLI_FORCE_ASCII")) { + cli->capabilities &= ~CAP_UNICODE; + } return True; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c25e71ff3d..8d4a025fcc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -95,22 +95,11 @@ BOOL cli_send_smb(struct cli_state *cli) return True; } -int cli_use_unicode = 0; - /**************************************************************************** setup basics in a outgoing packet ****************************************************************************/ void cli_setup_packet(struct cli_state *cli) { - static int initialised; - - /* the USE_UNICODE check will be deleted once our client side unicode - support is complete (tridge) */ - if (!initialised) { - initialised = 1; - if (getenv("USE_UNICODE")) cli_use_unicode = 1; - } - cli->rap_error = 0; cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); @@ -120,7 +109,7 @@ void cli_setup_packet(struct cli_state *cli) uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli_use_unicode && cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) { flags2 |= FLAGS2_UNICODE_STRINGS; } SSVAL(cli->outbuf,smb_flg2, flags2); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index c5da049cf4..6264baf00e 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -219,56 +219,6 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) return SVAL(cli->inbuf,smb_vwv2 + 1); } -/**************************************************************************** -open a file -****************************************************************************/ -int cli_nt_create_uni(struct cli_state *cli, char *fname, uint32 DesiredAccess) -{ - pstring uni; - char *p; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,24,0,True); - - CVAL(cli->outbuf,smb_com) = SMBntcreateX; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - if (cli->use_oplocks) - SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); - else - SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); - SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); - SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); - SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); - SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); - SSVAL(cli->outbuf,smb_ntcreate_NameLength, strlen(fname) * 2); - - p = smb_buf(cli->outbuf); - p++; /* Alignment */ - pstrcpy(uni, fname); - unix_to_dos(uni, True); - p += dos_struni2(p, uni, (strlen(fname) + 1) * 2) * 2; - cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; - } - - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return -1; - } - - return SVAL(cli->inbuf,smb_vwv2 + 1); -} - - /**************************************************************************** open a file WARNING: if you open with O_WRONLY then getattrE won't work! diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 9348b65bad..d4cc00d9f3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -353,7 +353,7 @@ static int interpret_short_filename(char *p,file_info *finfo) but should otherwise not be used ****************************************************************************/ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)) + void (*fn)(file_info *, const char *, void *), void *state) { char *p; int received = 0; @@ -373,12 +373,9 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - if (first) - set_message(cli->outbuf,2,5 + strlen(mask),True); - else - set_message(cli->outbuf,2,5 + 21,True); + set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBffirst; + CVAL(cli->outbuf,smb_com) = SMBsearch; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -389,21 +386,19 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - if (first) - pstrcpy(p,mask); - else - pstrcpy(p,""); - p += strlen(p) + 1; - + p += clistr_push(cli, p, first?mask:"", -1, CLISTR_TERMINATE|CLISTR_CONVERT); *p++ = 5; if (first) { SSVAL(p,0,0); + p += 2; } else { SSVAL(p,0,21); p += 2; memcpy(p,status,21); + p += 21; } + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) break; @@ -433,7 +428,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,5 + 21,True); + set_message(cli->outbuf,2,0,True); CVAL(cli->outbuf,smb_com) = SMBfclose; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -449,7 +444,9 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(p, 0, 21); p += 2; memcpy(p,status,21); + p += 21; + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); @@ -459,7 +456,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, for (p=dirlist,i=0;icapabilities & CAP_UNICODE)) { + if ((flags & CLISTR_ASCII) || !(cli->capabilities & CAP_UNICODE)) { /* the server doesn't want unicode */ safe_strcpy(dest, src, dest_len); len = strlen(dest); @@ -91,7 +88,7 @@ int clistr_push_size(struct cli_state *cli, void *dest, char *src, int dest_len, { int len = strlen(src); if (flags & CLISTR_TERMINATE) len++; - if (!(flags & CLISTR_ASCII) && cli_use_unicode && (cli->capabilities & CAP_UNICODE)) len *= 2; + if (!(flags & CLISTR_ASCII) && (cli->capabilities & CAP_UNICODE)) len *= 2; if (!(flags & CLISTR_ASCII) && dest && clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { len++; @@ -123,7 +120,7 @@ int clistr_pull(struct cli_state *cli, char *dest, void *src, int dest_len, int if (src_len > 0) src_len--; } - if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { + if (!(cli->capabilities & CAP_UNICODE)) { /* the server doesn't want unicode */ if (flags & CLISTR_TERMINATE) { safe_strcpy(dest, src, dest_len); @@ -167,7 +164,7 @@ int clistr_pull_size(struct cli_state *cli, void *src, int src_len) if (src_len > 0) src_len--; } - if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) { + if (!(cli->capabilities & CAP_UNICODE)) { return strlen(src); } return strlen_w(src); @@ -180,6 +177,6 @@ otherwise return 1 if offset is off ****************************************************************************/ int clistr_align(struct cli_state *cli, int offset) { - if (!cli_use_unicode || !(cli->capabilities & CAP_UNICODE)) return 0; + if (!(cli->capabilities & CAP_UNICODE)) return 0; return offset & 1; } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 1444e5883a..bc400d5b8d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1575,11 +1575,8 @@ int smbc_opendir(const char *fname) /* find the name of the server ... */ if (!name_status_find(0, rem_ip, server)) { - - fprintf(stderr, "Could not get the name of local master browser ...\n"); errno = EINVAL; return -1; - } /* @@ -1637,11 +1634,8 @@ int smbc_opendir(const char *fname) /*cli_get_backup_server(my_netbios_name, server, buserver, sizeof(buserver)); */ if (!name_status_find(0, rem_ip, buserver)) { - - fprintf(stderr, "Could not get name of local master browser ...\n"); errno = EPERM; /* FIXME, is this correct */ return -1; - } /* -- cgit From d689f00026541dd2cb87c6949fdc2f8eb3ad919f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Feb 2001 04:14:28 +0000 Subject: converted the last couple of functions in libsmb to be unicode the whole of libsmb should now do unicode where appropriate (This used to be commit ac7529d2b69826f8214d5632c31778cc87216653) --- source3/libsmb/clirap.c | 24 ++++++++++++++---------- source3/libsmb/clistr.c | 8 ++++---- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index bf0940d1d6..3c87464495 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -388,13 +388,15 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, int count=8; BOOL ret; time_t (*date_fn)(void *); + char *p; - param_len = strlen(fname) + 7; + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_INFO_STANDARD); + p += 6; + p += clistr_push(cli, p, fname, sizeof(pstring)-6, CLISTR_TERMINATE | CLISTR_CONVERT); - memset(param, 0, param_len); - SSVAL(param, 0, SMB_INFO_STANDARD); - pstrcpy(¶m[6], fname); - unix_to_dos(¶m[6],True); + param_len = PTR_DIFF(p, param); do { ret = (cli_send_trans(cli, SMBtrans2, @@ -462,13 +464,15 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; + char *p; - param_len = strlen(fname) + 7; + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO); + p += 6; + p += clistr_push(cli, p, fname, sizeof(pstring)-6, CLISTR_TERMINATE | CLISTR_CONVERT); - memset(param, 0, param_len); - SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO); - pstrcpy(¶m[6], fname); - unix_to_dos(¶m[6],True); + param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 9f46099ba9..e07b4d5a63 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -36,7 +36,7 @@ flags can have: dest_len is the maximum length allowed in the destination. If dest_len is -1 then no maxiumum is used ****************************************************************************/ -int clistr_push(struct cli_state *cli, void *dest, char *src, int dest_len, int flags) +int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags) { int len=0; @@ -84,7 +84,7 @@ return the length that a string would occupy when copied with clistr_push() CLISTR_UPPER means uppercase in the destination note that dest is only used for alignment purposes. No data is written. ****************************************************************************/ -int clistr_push_size(struct cli_state *cli, void *dest, char *src, int dest_len, int flags) +int clistr_push_size(struct cli_state *cli, const void *dest, const char *src, int dest_len, int flags) { int len = strlen(src); if (flags & CLISTR_TERMINATE) len++; @@ -107,7 +107,7 @@ if CLISTR_TERMINATE is set then src_len is ignored src_len is the length of the source area in bytes return the number of bytes occupied by the string in src ****************************************************************************/ -int clistr_pull(struct cli_state *cli, char *dest, void *src, int dest_len, int src_len, int flags) +int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags) { int len; @@ -157,7 +157,7 @@ return the length that a string would occupy (not including the null) when copied with clistr_pull() if src_len is -1 then assume the source is null terminated ****************************************************************************/ -int clistr_pull_size(struct cli_state *cli, void *src, int src_len) +int clistr_pull_size(struct cli_state *cli, const void *src, int src_len) { if (clistr_align(cli, PTR_DIFF(cli->inbuf, src))) { src++; -- cgit From 21b1ab0a76d051dda3400e99324573f6bffe4d03 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 Feb 2001 03:38:21 +0000 Subject: cope better with broken filer expectations (This used to be commit 847de3b4adfb00a98032e478b2663d09e240380e) --- source3/libsmb/clifile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 6264baf00e..3471ecdc67 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -202,8 +202,8 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) len = clistr_push(cli, p, fname, -1, CLISTR_CONVERT); p += len; SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); - SSVAL(p, 0, 0); - p += 2; + /* sigh. this copes with broken netapp filer behaviour */ + p += clistr_push(cli, p, "", -1, CLISTR_TERMINATE); cli_setup_bcc(cli, p); -- cgit From 1239b92c73a803c5cb517925523a2936df51a232 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 Feb 2001 03:38:48 +0000 Subject: make sure we don't free non-allocated data (This used to be commit 4a620f7037378dc042b6388ede6356c6db5d58fb) --- source3/libsmb/clisecdesc.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index d53b3073b2..59d8bdcc71 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -33,7 +33,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx; + TALLOC_CTX *mem_ctx = NULL; prs_struct pd; SEC_DESC *psd = NULL; @@ -74,11 +74,13 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) cleanup: - talloc_destroy(mem_ctx); + if (mem_ctx) { + talloc_destroy(mem_ctx); + prs_mem_free(&pd); + } safe_free(rparam); safe_free(rdata); - prs_mem_free(&pd); return psd; } @@ -93,7 +95,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx; + TALLOC_CTX *mem_ctx=NULL; prs_struct pd; BOOL ret = False; @@ -138,9 +140,10 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) safe_free(rparam); safe_free(rdata); - talloc_destroy(mem_ctx); - - prs_mem_free(&pd); + if (mem_ctx) { + talloc_destroy(mem_ctx); + prs_mem_free(&pd); + } return ret; } -- cgit From 1c8eb37534f885c7835f3971e5d28c9e89dd85d1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 25 Feb 2001 02:14:49 +0000 Subject: Separated reg code into interface & implementation. libsmb/namequery.c: Removed ununsed variables. Jeremy. (This used to be commit b857113f400551c57ac400a9cdc3c752085d107d) --- source3/libsmb/namequery.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f6ada87840..01ec5e9b29 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -198,7 +198,7 @@ BOOL name_register(int fd, const char *name, int name_type, BOOL bcast, struct in_addr to_ip, int *count) { - int i, retries = 3, retry = bcast?250:2000; + int retries = 3; struct timeval tval; struct packet_struct p; struct packet_struct *p2; @@ -274,12 +274,8 @@ BOOL name_register(int fd, const char *name, int name_type, retries--; if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) { - struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); - - free(p2); /* No memory leaks ... */ - } return True; -- cgit From 57467a9f6002eafdb7d1395a50089c53c37335d9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 25 Feb 2001 23:46:02 +0000 Subject: neater negprot code using the new cli_setup_bcc() call (This used to be commit 5b1728426531785d37b4fac0684114f8a84dacb2) --- source3/libsmb/cliconnect.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d572c0f7d7..fd0218b908 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -339,17 +339,11 @@ void cli_negprot_send(struct cli_state *cli) { char *p; int numprots; - int plength; memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ - for (plength=0,numprots=0; - prots[numprots].name && prots[numprots].prot<=cli->protocol; - numprots++) - plength += strlen(prots[numprots].name)+2; - - set_message(cli->outbuf,0,plength,True); + set_message(cli->outbuf,0,0,True); p = smb_buf(cli->outbuf); for (numprots=0; @@ -362,6 +356,7 @@ void cli_negprot_send(struct cli_state *cli) } CVAL(cli->outbuf,smb_com) = SMBnegprot; + cli_setup_bcc(cli, p); cli_setup_packet(cli); CVAL(smb_buf(cli->outbuf),0) = 2; -- cgit From 96e791eb11e0da4f283d7a6f526d5bd1bfd08d2c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 25 Feb 2001 23:46:28 +0000 Subject: use cli_list_old() when negotiating the older protocols (This used to be commit 735f29319b8d81df203c8ddbcea5349b11f2195d) --- source3/libsmb/clilist.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d4cc00d9f3..c30f69a36c 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -178,6 +178,10 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, int param_len, data_len; uint16 setup; pstring param; + + if (cli->protocol <= PROTOCOL_LANMAN1) { + return cli_list_old(cli, Mask, attribute, fn, state); + } pstrcpy(mask,Mask); -- cgit From f9405ab8f921753f1de9490f37b18ccfcd3ab370 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Feb 2001 05:10:44 +0000 Subject: add cli_list_new() for forced new protocol listing (This used to be commit a5407366b77f2bec2c21e1f36dd007813d33f75e) --- source3/libsmb/clilist.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index c30f69a36c..eccf3c553a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -135,8 +135,8 @@ static int interpret_long_filename(struct cli_state *cli, p += 2; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), - -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + 24, + CLISTR_CONVERT); p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), @@ -155,8 +155,8 @@ static int interpret_long_filename(struct cli_state *cli, /**************************************************************************** do a directory listing, calling fn on each file found ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *, void *), void *state) +int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *state) { int max_matches = 512; /* NT uses 260, OS/2 uses 2. Both accept 1. */ @@ -179,10 +179,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, uint16 setup; pstring param; - if (cli->protocol <= PROTOCOL_LANMAN1) { - return cli_list_old(cli, Mask, attribute, fn, state); - } - pstrcpy(mask,Mask); while (ff_eos == 0) { @@ -466,3 +462,17 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, if (dirlist) free(dirlist); return(num_received); } + + +/**************************************************************************** + do a directory listing, calling fn on each file found + this auto-switches between old and new style + ****************************************************************************/ +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *state) +{ + if (cli->protocol <= PROTOCOL_LANMAN1) { + return cli_list_old(cli, Mask, attribute, fn, state); + } + return cli_list_new(cli, Mask, attribute, fn, state); +} -- cgit From d33b294b9aa6059bd0831a264b427108bd2d5db2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Feb 2001 05:11:06 +0000 Subject: fixed a bug in non-terminated unicode strings with clistr_pull() (This used to be commit 339bcfd05d3260a123ccf3c06429da6bfe621f74) --- source3/libsmb/clistr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index e07b4d5a63..52137d9f78 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -140,7 +140,7 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len len = strlen(dest)*2 + 2; } else { int i, c; - if (dest_len < src_len) src_len = dest_len; + if (dest_len*2 < src_len) src_len = 2*dest_len; for (i=0; i < src_len; i += 2) { c = SVAL(src, i); *dest++ = c; -- cgit From 0d54de536c03f941739359a121a337aa33a2dc84 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Feb 2001 06:53:42 +0000 Subject: made some LANMAN1 wildcard progress it now handles -M LANMAN1 -f '.x' -m '?x' nicely (This used to be commit e7ccb9be6da9b1426eb136b4a0a1171232471768) --- source3/libsmb/clilist.c | 18 ++++++++++++------ source3/libsmb/clistr.c | 7 ++++--- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index eccf3c553a..175673d4fe 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -133,10 +133,14 @@ static int interpret_long_filename(struct cli_state *cli, p += 4; /* EA size */ slen = SVAL(p, 0); p += 2; - clistr_pull(cli, finfo->short_name, p, - sizeof(finfo->short_name), - 24, - CLISTR_CONVERT); + { + /* stupid NT bugs. grr */ + int flags = CLISTR_CONVERT; + if (p[1] == 0 && namelen > 1) flags |= CLISTR_UNICODE; + clistr_pull(cli, finfo->short_name, p, + sizeof(finfo->short_name), + 24, flags); + } p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), @@ -159,8 +163,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { int max_matches = 512; - /* NT uses 260, OS/2 uses 2. Both accept 1. */ - int info_level = cli->protocolcapabilities&CAP_NT_SMBS)?260:1; + pstrcpy(mask,Mask); while (ff_eos == 0) { diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 52137d9f78..1835e15971 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -103,6 +103,7 @@ cli->capabilities) to a char* destination flags can have: CLISTR_CONVERT means convert from dos to unix codepage CLISTR_TERMINATE means the string in src is null terminated + CLISTR_UNICODE means to force as unicode if CLISTR_TERMINATE is set then src_len is ignored src_len is the length of the source area in bytes return the number of bytes occupied by the string in src @@ -115,12 +116,12 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len dest_len = sizeof(pstring); } - if (clistr_align(cli, PTR_DIFF(cli->inbuf, src))) { + if (clistr_align(cli, PTR_DIFF(src, cli->inbuf))) { src++; if (src_len > 0) src_len--; } - if (!(cli->capabilities & CAP_UNICODE)) { + if (!(flags & CLISTR_UNICODE) && !(cli->capabilities & CAP_UNICODE)) { /* the server doesn't want unicode */ if (flags & CLISTR_TERMINATE) { safe_strcpy(dest, src, dest_len); @@ -159,7 +160,7 @@ if src_len is -1 then assume the source is null terminated ****************************************************************************/ int clistr_pull_size(struct cli_state *cli, const void *src, int src_len) { - if (clistr_align(cli, PTR_DIFF(cli->inbuf, src))) { + if (clistr_align(cli, PTR_DIFF(src, cli->inbuf))) { src++; if (src_len > 0) src_len--; } -- cgit From 00e4feec00c41ef4078c85f67b805940c4609a42 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 26 Feb 2001 11:53:22 +0000 Subject: Fix some errors uncovered in libsmbclient by the test suite Fix some problems with unused variables and reaching the end of a nonvoid function (This used to be commit 44986f397ae647aa790422737a839443efb99920) --- source3/libsmb/clidgram.c | 20 ++++-- source3/libsmb/libsmbclient.c | 157 +++++++++++------------------------------- 2 files changed, 57 insertions(+), 120 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 28041e1b76..3eaf2bf48a 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -54,7 +54,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, dgram->header.flags.more = False; dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100); dgram->header.source_ip.s_addr = src_ip.s_addr; - fprintf(stderr, "Source IP = %0X\n", dgram->header.source_ip); + /*fprintf(stderr, "Source IP = %0X\n", dgram->header.source_ip); */ dgram->header.source_port = ntohs(src_port); fprintf(stderr, "Source Port = %0X\n", dgram->header.source_port); dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ @@ -128,6 +128,8 @@ int cli_get_response(int dgram_sock, BOOL unique, char *mailslot, char *buf, int else return -1; + return 0; + } /* @@ -147,7 +149,8 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) { - fprintf(stderr, "Could not resolve name: %s<1D>\n", send_to_name); + DEBUG(0, ("Could not resolve name: %s<1D>\n", send_to_name)); + return False; } @@ -155,7 +158,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) if (!resolve_name(myname, &my_ip, 0x00)) { /* FIXME: Call others here */ - fprintf(stderr, "Could not resolve name: %s<00>\n", myname); + DEBUG(0, ("Could not resolve name: %s<00>\n", myname)); } @@ -174,7 +177,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) if (fcntl(dgram_sock, F_SETFL, O_NONBLOCK) < 0) { - fprintf(stderr, "Unable to set non blocking on dgram sock\n"); + DEBUG(0, ("Unable to set non blocking on dgram sock\n")); } @@ -206,7 +209,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size); - fprintf(stderr, "Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port)); + DEBUG(5, ("Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port))); /* Now, build the request */ @@ -238,6 +241,8 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) close(dgram_sock); + return True; + } /* @@ -259,4 +264,9 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam strncpy(servername, cli_backup_list, MIN(16, namesize)); + return True; + } + + + diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index bc400d5b8d..ce0b32a5ca 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -56,6 +56,12 @@ struct smbc_file { int dir_type, dir_error; }; +int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ +BOOL smbc_getatr(struct smbc_server *srv, char *path, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + SMB_INO_T *ino); + extern BOOL in_client; static int smbc_initialized = 0; static smbc_get_auth_data_fn smbc_auth_fn = NULL; @@ -67,101 +73,6 @@ static struct smbc_server *smbc_srvs; static pstring my_netbios_name; static pstring smbc_user; -/* - * Clean up a filename by removing redundent stuff - */ - -static void -smbc_clean_fname(char *name) -{ - char *p, *p2; - int l; - int modified = 1; - - if (!name) return; - - while (modified) { - modified = 0; - - DEBUG(5,("cleaning %s\n", name)); - - if ((p=strstr(name,"/./"))) { - modified = 1; - while (*p) { - p[0] = p[2]; - p++; - } - } - - if ((p=strstr(name,"//"))) { - modified = 1; - while (*p) { - p[0] = p[1]; - p++; - } - } - - if (strcmp(name,"/../")==0) { - modified = 1; - name[1] = 0; - } - - if ((p=strstr(name,"/../"))) { - modified = 1; - for (p2=(p>name?p-1:p);p2>name;p2--) { - if (p2[0] == '/') break; - } - while (*p2) { - p2[0] = p2[3]; - p2++; - } - } - - if (strcmp(name,"/..")==0) { - modified = 1; - name[1] = 0; - } - - l = strlen(name); - p = l>=3?(name+l-3):name; - if (strcmp(p,"/..")==0) { - modified = 1; - for (p2=p-1;p2>name;p2--) { - if (p2[0] == '/') break; - } - if (p2==name) { - p[0] = '/'; - p[1] = 0; - } else { - p2[0] = 0; - } - } - - l = strlen(name); - p = l>=2?(name+l-2):name; - if (strcmp(p,"/.")==0) { - if (p == name) { - p[1] = 0; - } else { - p[0] = 0; - } - } - - if (strncmp(p=name,"./",2) == 0) { - modified = 1; - do { - p[0] = p[2]; - } while (*p++); - } - - l = strlen(p=name); - if (l > 1 && p[l-1] == '/') { - modified = 1; - p[l-1] = 0; - } - } -} - /* * Function to parse a path and turn it into components * @@ -182,7 +93,6 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, pstring userinfo; char *p; int len; - fstring workgroup; server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; pstrcpy(s, fname); @@ -368,8 +278,6 @@ struct smbc_server *smbc_server(char *server, char *share, if ((p=strchr(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { - struct in_addr sip; - pstring s; fstrcpy(group, server_n); p = strchr(group,'#'); @@ -491,7 +399,7 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) { pstring conf; int p, pid; - char *user = NULL, *host = NULL, *home = NULL, *pname="libsmbclient"; + char *user = NULL, *home = NULL, *pname="libsmbclient"; /* * Next lot ifdef'd out until test suite fixed ... @@ -551,8 +459,8 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) * config file ... We must return an error ... and keep info around * about why we failed */ - /* - errno = ENOENT; /* Hmmm, what error resp does lp_load return ? */ + + errno = ENOENT; /* FIXME: Figure out the correct error response */ return -1; } @@ -616,7 +524,6 @@ int smbc_open(const char *fname, int flags, mode_t mode) fstring server, share, user, password; pstring path; struct smbc_server *srv = NULL; - struct smbc_file *file = NULL; int fd; if (!smbc_initialized) { @@ -714,11 +621,6 @@ int smbc_open(const char *fname, int flags, mode_t mode) return 1; /* Success, with fd ... */ - failed: - - /*FIXME, clean up things ... */ - return -1; - } /* @@ -814,11 +716,20 @@ ssize_t smbc_write(int fd, void *buf, size_t count) } + /* Check that the buffer exists ... */ + + if (buf == NULL) { + + errno = EINVAL; + return -1; + + } + fe = smbc_file_table[fd - smbc_start_fd]; ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count); - if (ret < 0) { + if (ret <= 0) { errno = smbc_errno(&fe->srv->cli); return -1; @@ -930,8 +841,7 @@ int smbc_unlink(const char *fname) if (errno == EACCES) { /* Check if the file is a directory */ - int err, saverr = errno; - struct stat st; + int saverr = errno; size_t size = 0; uint16 mode = 0; time_t m_time = 0, a_time = 0, c_time = 0; @@ -1144,6 +1054,9 @@ int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) if (st->st_ino == 0) { st->st_ino = smbc_inode(fname); } + + return True; /* FIXME: Is this needed ? */ + } /* @@ -1483,7 +1396,6 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) int smbc_opendir(const char *fname) { - struct in_addr addr; fstring server, share, user, password; pstring path; struct smbc_server *srv = NULL; @@ -1575,8 +1487,11 @@ int smbc_opendir(const char *fname) /* find the name of the server ... */ if (!name_status_find(0, rem_ip, server)) { + + fprintf(stderr, "Could not get the name of local master browser ...\n"); errno = EINVAL; return -1; + } /* @@ -1634,8 +1549,11 @@ int smbc_opendir(const char *fname) /*cli_get_backup_server(my_netbios_name, server, buserver, sizeof(buserver)); */ if (!name_status_find(0, rem_ip, buserver)) { + + fprintf(stderr, "Could not get name of local master browser ...\n"); errno = EPERM; /* FIXME, is this correct */ return -1; + } /* @@ -1734,8 +1652,8 @@ int smbc_opendir(const char *fname) pstrcat(path, "\\*"); - if (!cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, - (void *)smbc_file_table[slot])) { + if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, + (void *)smbc_file_table[slot]) < 0) { if (smbc_file_table[slot]) free(smbc_file_table[slot]); smbc_file_table[slot] = NULL; @@ -2134,7 +2052,14 @@ int smbc_lseekdir(int fd, off_t offset, int whence) } - return 0; + if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + + errno = EBADF; + return -1; + + } + + return ENOSYS; /* Not implemented so far ... */ } @@ -2152,6 +2077,8 @@ int smbc_fstatdir(int fd, struct stat *st) } + /* No code yet ... */ + return 0; } @@ -2186,6 +2113,7 @@ int smbc_print_file(const char *fname, const char *printq) if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { + fprintf(stderr, "Error, fname=%s, errno=%i\n", fname, errno); return -1; /* smbc_open sets errno */ } @@ -2238,7 +2166,6 @@ int smbc_print_file(const char *fname, const char *printq) int smbc_open_print_job(const char *fname) { - struct smbc_server *srv; fstring server, share, user, password; pstring path; -- cgit From ff2616aaf90ceb744379a2c4a9f69edea6d720e2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 1 Mar 2001 06:36:57 +0000 Subject: Fixed compiler warning. (This used to be commit 33e5c56ab049fe5e156579dbf2f9cd54897f1dd3) --- source3/libsmb/cliconnect.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index fd0218b908..f2f9b89ea4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -192,10 +192,10 @@ BOOL cli_session_setup(struct cli_state *cli, * Save off some of the connected server * info. */ - char *p = smb_buf(cli->inbuf); - p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); - p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); - p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); + char *q = smb_buf(cli->inbuf); + q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); + q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); + q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); } fstrcpy(cli->user_name, user); -- cgit From 1b476b12d914e57a1b46864d0e12c0ba054af949 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 1 Mar 2001 19:21:57 +0000 Subject: Fix two problems identified by the test suite, one a major one where I was indexing through a NULL pointer :-( (This used to be commit 5f1ea70e110bd3b97a4c75b2fe0edef22847550b) --- source3/libsmb/libsmbclient.c | 64 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ce0b32a5ca..29f2d807ba 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -667,9 +667,18 @@ ssize_t smbc_read(int fd, void *buf, size_t count) } + /* Check that the buffer exists ... */ + + if (buf == NULL) { + + errno = EINVAL; + return -1; + + } + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe->file) { + if (!fe || !fe->file) { errno = EBADF; return -1; @@ -727,6 +736,13 @@ ssize_t smbc_write(int fd, void *buf, size_t count) fe = smbc_file_table[fd - smbc_start_fd]; + if (!fe || !fe->file) { + + errno = EBADF; + return -1; + + } + ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count); if (ret <= 0) { @@ -765,6 +781,13 @@ int smbc_close(int fd) fe = smbc_file_table[fd - smbc_start_fd]; + if (!fe) { + + errno = EBADF; + return -1; + + } + if (!fe->file) { return smbc_closedir(fd); @@ -967,6 +990,13 @@ off_t smbc_lseek(int fd, off_t offset, int whence) fe = smbc_file_table[fd - smbc_start_fd]; + if (!fe) { + + errno = EBADF; + return -1; + + } + if (!fe->file) { return smbc_lseekdir(fd, offset, whence); @@ -1208,6 +1238,13 @@ int smbc_fstat(int fd, struct stat *st) fe = smbc_file_table[fd - smbc_start_fd]; + if (!fe) { + + errno = EBADF; + return -1; + + } + if (!fe->file) { return smbc_fstatdir(fd, st); @@ -1620,7 +1657,7 @@ int smbc_opendir(const char *fname) } else { - errno = EINVAL; + errno = ENODEV; /* Neither the workgroup nor server exists */ if (smbc_file_table[slot]) free(smbc_file_table[slot]); smbc_file_table[slot] = NULL; return -1; @@ -1695,7 +1732,7 @@ int smbc_closedir(int fd) if (!fe) { - errno = ENOENT; /* FIXME: Is this correct */ + errno = EBADF; return -1; } @@ -1739,6 +1776,13 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) fe = smbc_file_table[fd - smbc_start_fd]; + if (!fe) { + + errno = EBADF; + return NULL; + + } + if (fe->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; @@ -1802,6 +1846,13 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) fe = smbc_file_table[fd - smbc_start_fd]; + if (!fe) { + + errno = EBADF; + return -1; + + } + if (fe->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; @@ -2027,6 +2078,13 @@ off_t smbc_telldir(int fd) fe = smbc_file_table[fd - smbc_start_fd]; + if (!fe) { + + errno = EBADF; + return -1; + + } + if (fe->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; -- cgit From 134c0d27cce4a6912212770f645a46a22e204ad6 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 5 Mar 2001 13:34:48 +0000 Subject: smb.h: add one error code for no such printer job libsmbclient.c: fix problems with return codes on smbc_unlink_print_job (This used to be commit 7557f9145ccdced3fcebdd20e1eb6fc5a27abda2) --- source3/libsmb/libsmbclient.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 29f2d807ba..410e2ebdd6 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -851,8 +851,9 @@ int smbc_unlink(const char *fname) return -1; } - if (cli_printjob_del(&srv->cli, job) != 0) { + if ((err = cli_printjob_del(&srv->cli, job)) != 0) { + return -1; } @@ -2102,6 +2103,7 @@ off_t smbc_telldir(int fd) int smbc_lseekdir(int fd, off_t offset, int whence) { + struct smbc_file *fe; if (!smbc_initialized) { @@ -2117,6 +2119,24 @@ int smbc_lseekdir(int fd, off_t offset, int whence) } + fe = smbc_file_table[fd - smbc_start_fd]; + + if (!fe) { + + errno = EBADF; + return -1; + + } + + if (fe->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + return -1; + + } + + /* Now, check what we were passed and see if it is OK ... */ + return ENOSYS; /* Not implemented so far ... */ } @@ -2309,6 +2329,7 @@ int smbc_unlink_print_job(const char *fname, int id) struct smbc_server *srv; fstring server, share, user, password; pstring path; + int err; if (!smbc_initialized) { @@ -2338,11 +2359,15 @@ int smbc_unlink_print_job(const char *fname, int id) } - if (cli_printjob_del(&srv->cli, id) < 0) { + if ((err = cli_printjob_del(&srv->cli, id)) != 0) { - errno = smbc_errno(&srv->cli); + if (err < 0) + errno = smbc_errno(&srv->cli); + else if (err == ERRnosuchprintjob) + errno = EINVAL; return -1; + } return 0; -- cgit From 5bf5952fd68f7801e66ece29ccf4b0d5baa26c79 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 6 Mar 2001 14:00:48 +0000 Subject: Implement smbc_lseekdir, but it will have to change ... because it has the wrong interface defn. (This used to be commit 317e369c3e20206c9f8b36a91dc666ebeede68ec) --- source3/libsmb/libsmbclient.c | 53 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 410e2ebdd6..770be06fda 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2097,6 +2097,36 @@ off_t smbc_telldir(int fd) } +/* + * A routine to run down the list and see if the entry is OK + */ + +struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, + struct smbc_dirent *dirent) +{ + + /* Run down the list looking for what we want */ + + if (dirent) { + + struct smbc_dir_list *tmp = list; + + while (tmp) { + + if (tmp->dirent == dirent) + return tmp; + + tmp = tmp->next; + + } + + } + + return NULL; /* Not found, or an error */ + +} + + /* * Routine to seek on a directory */ @@ -2104,6 +2134,8 @@ off_t smbc_telldir(int fd) int smbc_lseekdir(int fd, off_t offset, int whence) { struct smbc_file *fe; + struct smbc_dirent *dirent = (struct smbc_dirent *)whence; + struct smbc_dir_list *list_ent = NULL; if (!smbc_initialized) { @@ -2137,7 +2169,26 @@ int smbc_lseekdir(int fd, off_t offset, int whence) /* Now, check what we were passed and see if it is OK ... */ - return ENOSYS; /* Not implemented so far ... */ + if (!whence) { + + errno = EINVAL; + return -1; + + } + + /* Now, run down the list and make sure that the entry is OK */ + /* This may need to be changed if we change the format of the list */ + + if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) { + + errno = EINVAL; /* Bad entry */ + return -1; + + } + + fe->dir_next = list_ent; + + return 0; } -- cgit From 2b22019e426c4bb7a5745a326c302a4e19aa5ff2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 7 Mar 2001 04:39:31 +0000 Subject: Fix the definition and implementation of smbc_lseekdir ... (This used to be commit e628d80d1e0f6ec87b61baeaf64019b43bf7dac8) --- source3/libsmb/libsmbclient.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 770be06fda..c181780d3a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1000,7 +1000,8 @@ off_t smbc_lseek(int fd, off_t offset, int whence) if (!fe->file) { - return smbc_lseekdir(fd, offset, whence); + errno = EINVAL; + return -1; /* Can't lseek a dir ... */ } @@ -2131,10 +2132,10 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, * Routine to seek on a directory */ -int smbc_lseekdir(int fd, off_t offset, int whence) +int smbc_lseekdir(int fd, off_t offset) { struct smbc_file *fe; - struct smbc_dirent *dirent = (struct smbc_dirent *)whence; + struct smbc_dirent *dirent = (struct smbc_dirent *)offset; struct smbc_dir_list *list_ent = NULL; if (!smbc_initialized) { @@ -2169,10 +2170,10 @@ int smbc_lseekdir(int fd, off_t offset, int whence) /* Now, check what we were passed and see if it is OK ... */ - if (!whence) { + if (dirent == NULL) { /* Seek to the begining of the list */ - errno = EINVAL; - return -1; + fe->dir_next = fe->dir_list; + return 0; } -- cgit From e8fcbc5df1d51b2b3683254288f204f42b75e7e9 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 9 Mar 2001 05:47:48 +0000 Subject: More SGI type fixes ... (This used to be commit 26d7d8af2903b1f24da51c78e12f54a1d42ed798) --- source3/libsmb/libsmbclient.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c181780d3a..43ccd6486a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -65,7 +65,7 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, extern BOOL in_client; static int smbc_initialized = 0; static smbc_get_auth_data_fn smbc_auth_fn = NULL; -static int smbc_debug; +/*static int smbc_debug;*/ static int smbc_start_fd; static int smbc_max_fd = 10000; static struct smbc_file **smbc_file_table; @@ -414,7 +414,7 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) smbc_initialized = 1; smbc_auth_fn = fn; - smbc_debug = debug; + /* smbc_debug = debug; */ DEBUGLEVEL = -1; @@ -1829,6 +1829,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) struct smbc_file *fe; struct smbc_dir_list *dir; int rem = count, reqd; + char *ndir = (char *)dirp; /* Check that all is ok first ... */ @@ -1898,11 +1899,12 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) dirent = dir->dirent; - bcopy(dirent, dirp, reqd); /* Copy the data in ... */ + bcopy(dirent, ndir, reqd); /* Copy the data in ... */ - dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); + ((struct smbc_dirent *)ndir)->comment = + (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1); - (char *)dirp += reqd; + ndir += reqd; rem -= reqd; -- cgit From 00ab9021b0cc5fe2667d383eb9cc2973072cdaaa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Mar 2001 23:48:58 +0000 Subject: Serious (and I *mean* serious) attempt to fix little/bigendian RPC issues. We were reading the endainness in the RPC header and then never propagating it to the internal parse_structs used to parse the data. Also removed the "align" argument to prs_init as it was *always* set to 4, and if needed can be set differently on a case by case basis. Now ready for AS/U testing when Herb gets it set up :-). Jeremy. (This used to be commit 0cd37c831d79a12a10e479bf4fa89ffe64c1292a) --- source3/libsmb/cli_lsarpc.c | 24 ++++++++++++------------ source3/libsmb/clisecdesc.c | 4 ++-- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index e4da7a7cc7..7f5431e4b3 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -98,8 +98,8 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -152,8 +152,8 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol) /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -204,8 +204,8 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -310,8 +310,8 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -409,8 +409,8 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -494,8 +494,8 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 59d8bdcc71..d34a23537a 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -63,7 +63,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) goto cleanup; } - prs_init(&pd, rdata_count, 4, mem_ctx, UNMARSHALL); + prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL); prs_append_data(&pd, rdata, rdata_count); pd.data_offset = 0; @@ -104,7 +104,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) goto cleanup; } - prs_init(&pd, 0, 4, mem_ctx, MARSHALL); + prs_init(&pd, 0, mem_ctx, MARSHALL); prs_give_memory(&pd, NULL, 0, True); if (!sec_io_desc("sd data", &sd, &pd, 1)) { -- cgit From 2a490ed2a07a3e60c9855f09bea455da705601c5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Mar 2001 23:58:26 +0000 Subject: Missed some prs_inits. Jeremy. (This used to be commit 7a8a7a24d4c328d26d34c3b3ac28af39e6acd32c) --- source3/libsmb/cli_samr.c | 36 ++++++++++++++++++------------------ source3/libsmb/cli_spoolss.c | 22 +++++++++++----------- 2 files changed, 29 insertions(+), 29 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 22ef324d63..d4540b15c5 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -98,8 +98,8 @@ uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -145,8 +145,8 @@ uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol) /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -194,8 +194,8 @@ uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -243,8 +243,8 @@ uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -292,8 +292,8 @@ uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -340,8 +340,8 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -388,8 +388,8 @@ uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -436,8 +436,8 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -485,8 +485,8 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Marshall data and send request */ diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 2dbc1a0ab0..d8e7b0cce6 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -99,8 +99,8 @@ uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -149,8 +149,8 @@ uint32 cli_spoolss_closeprinter(struct cli_state *cli, POLICY_HND *pol) /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, False); - prs_init(&rbuf, 0, 4, cli->mem_ctx, True); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -191,7 +191,7 @@ static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) buffer->ptr = (size != 0); buffer->size = size; buffer->string_at_end = size; - prs_init(&buffer->prs, size, 4, ctx, MARSHALL); + prs_init(&buffer->prs, size, ctx, MARSHALL); buffer->struct_start = prs_offset(&buffer->prs); } @@ -330,8 +330,8 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, init_buffer(&buffer, needed, cli->mem_ctx); - prs_init(&qbuf , MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, 4, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); make_spoolss_q_enumprinters(&q, flags, "", level, &buffer, needed); @@ -407,8 +407,8 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, init_buffer(&buffer, needed, cli->mem_ctx); - prs_init(&qbuf , MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, 4, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); make_spoolss_q_enumports(&q, "", level, &buffer, needed); @@ -479,8 +479,8 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, init_buffer(&buffer, needed, cli->mem_ctx); - prs_init(&qbuf , MAX_PDU_FRAG_LEN, 4, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, 4, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); make_spoolss_q_getprinter(&q, pol, level, &buffer, needed); -- cgit From 45c2ee3ff2d01fdd0a2db9fa90457cff4663c43d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 10 Mar 2001 11:35:25 +0000 Subject: to use the same macros in the client and server rename the CLISTR_ macros to STR_ (This used to be commit 95c9e4e0ba8f37f565aaf136f41eb76489441ff7) --- source3/libsmb/cliconnect.c | 24 +++++++++---------- source3/libsmb/clifile.c | 22 +++++++++--------- source3/libsmb/clilist.c | 32 +++++++++++++------------- source3/libsmb/climessage.c | 4 ++-- source3/libsmb/clirap.c | 6 ++--- source3/libsmb/clistr.c | 56 ++++++++++++++++++++++----------------------- source3/libsmb/clitrans.c | 4 ++-- 7 files changed, 74 insertions(+), 74 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f2f9b89ea4..46a63dc5f1 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -104,7 +104,7 @@ BOOL cli_session_setup(struct cli_state *cli, /* * Plaintext mode needed, assume plaintext supplied. */ - passlen = clistr_push(cli, pword, pass, -1, CLISTR_CONVERT|CLISTR_TERMINATE); + passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE); fstrcpy(ntpword, ""); ntpasslen = 0; } @@ -136,7 +136,7 @@ BOOL cli_session_setup(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p += clistr_push(cli, p, user, -1, CLISTR_CONVERT|CLISTR_UPPER|CLISTR_TERMINATE); + p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_UPPER|STR_TERMINATE); cli_setup_bcc(cli, p); } else @@ -167,10 +167,10 @@ BOOL cli_session_setup(struct cli_state *cli, p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpword,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - p += clistr_push(cli, p, user, -1, CLISTR_CONVERT|CLISTR_TERMINATE|CLISTR_UPPER); - p += clistr_push(cli, p, workgroup, -1, CLISTR_CONVERT|CLISTR_TERMINATE|CLISTR_UPPER); - p += clistr_push(cli, p, "Unix", -1, CLISTR_CONVERT|CLISTR_TERMINATE); - p += clistr_push(cli, p, "Samba", -1, CLISTR_CONVERT|CLISTR_TERMINATE); + p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, workgroup, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, "Unix", -1, STR_CONVERT|STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_CONVERT|STR_TERMINATE); cli_setup_bcc(cli, p); } @@ -193,9 +193,9 @@ BOOL cli_session_setup(struct cli_state *cli, * info. */ char *q = smb_buf(cli->inbuf); - q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); - q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); - q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, CLISTR_TERMINATE|CLISTR_CONVERT); + q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); + q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); + q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); } fstrcpy(cli->user_name, user); @@ -255,7 +255,7 @@ BOOL cli_send_tconX(struct cli_state *cli, /* * Non-encrypted passwords - convert to DOS codepage before using. */ - passlen = clistr_push(cli, pword, pass, -1, CLISTR_CONVERT|CLISTR_TERMINATE); + passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE); } else { memcpy(pword, pass, passlen); } @@ -276,7 +276,7 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p += clistr_push(cli, p, fullshare, -1, CLISTR_CONVERT | CLISTR_TERMINATE); + p += clistr_push(cli, p, fullshare, -1, STR_CONVERT | STR_TERMINATE); fstrcpy(p, dev); p += strlen(dev)+1; cli_setup_bcc(cli, p); @@ -294,7 +294,7 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->dev, "A:"); if (cli->protocol >= PROTOCOL_NT1) { - clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, CLISTR_TERMINATE | CLISTR_CONVERT); + clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE | STR_CONVERT); } if (strcasecmp(share,"IPC$")==0) { diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 3471ecdc67..8742a576cf 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -44,10 +44,10 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) p = smb_buf(cli->outbuf); *p++ = 4; p += clistr_push(cli, p, fname_src, -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); *p++ = 4; p += clistr_push(cli, p, fname_dst, -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); cli_setup_bcc(cli, p); @@ -83,7 +83,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); cli_setup_bcc(cli, p); cli_send_smb(cli); @@ -116,7 +116,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, dname, -1, CLISTR_CONVERT|CLISTR_TERMINATE); + p += clistr_push(cli, p, dname, -1, STR_CONVERT|STR_TERMINATE); cli_setup_bcc(cli, p); @@ -150,7 +150,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, dname, -1, CLISTR_TERMINATE|CLISTR_CONVERT); + p += clistr_push(cli, p, dname, -1, STR_TERMINATE|STR_CONVERT); cli_setup_bcc(cli, p); @@ -199,11 +199,11 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ p += clistr_align(cli, PTR_DIFF(p, cli->outbuf)); - len = clistr_push(cli, p, fname, -1, CLISTR_CONVERT); + len = clistr_push(cli, p, fname, -1, STR_CONVERT); p += len; SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); /* sigh. this copes with broken netapp filer behaviour */ - p += clistr_push(cli, p, "", -1, CLISTR_TERMINATE); + p += clistr_push(cli, p, "", -1, STR_TERMINATE); cli_setup_bcc(cli, p); @@ -281,7 +281,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) } p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); cli_setup_bcc(cli, p); @@ -597,7 +597,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); cli_setup_bcc(cli, p); @@ -648,7 +648,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); *p++ = 4; cli_setup_bcc(cli, p); @@ -685,7 +685,7 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, path2, -1, CLISTR_TERMINATE | CLISTR_CONVERT); + p += clistr_push(cli, p, path2, -1, STR_TERMINATE | STR_CONVERT); cli_setup_bcc(cli, p); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 175673d4fe..f0ca0d5f54 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -51,7 +51,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+27, sizeof(finfo->name), -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } return(28 + CVAL(p,26)); @@ -66,7 +66,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+31, sizeof(finfo->name), -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } return(32 + CVAL(p,30)); @@ -82,7 +82,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+33, sizeof(finfo->name), -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } return(SVAL(p,4)+4); @@ -97,7 +97,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+37, sizeof(finfo->name), -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } return(SVAL(p,4)+4); @@ -135,8 +135,8 @@ static int interpret_long_filename(struct cli_state *cli, p += 2; { /* stupid NT bugs. grr */ - int flags = CLISTR_CONVERT; - if (p[1] == 0 && namelen > 1) flags |= CLISTR_UNICODE; + int flags = STR_CONVERT; + if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), 24, flags); @@ -145,7 +145,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, - CLISTR_CONVERT); + STR_CONVERT); return(ret); } return(SVAL(p,0)); @@ -195,8 +195,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } param_len = 12+clistr_push_size(cli, NULL, mask, -1, - CLISTR_TERMINATE | - CLISTR_CONVERT); + STR_TERMINATE | + STR_CONVERT); if (First) { setup = TRANSACT2_FINDFIRST; @@ -206,7 +206,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,6,info_level); SIVAL(param,8,0); clistr_push(cli, param+12, mask, -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -215,7 +215,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ clistr_push(cli, param+12, mask, -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } if (!cli_send_trans(cli, SMBtrans2, @@ -271,15 +271,15 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, clistr_pull(cli, mask, p+ff_lastname, sizeof(mask), data_len-ff_lastname, - CLISTR_TERMINATE | - CLISTR_CONVERT); + STR_TERMINATE | + STR_CONVERT); break; case 1: clistr_pull(cli, mask, p+ff_lastname+1, sizeof(mask), -1, - CLISTR_TERMINATE | - CLISTR_CONVERT); + STR_TERMINATE | + STR_CONVERT); break; } } else { @@ -392,7 +392,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, first?mask:"", -1, CLISTR_TERMINATE|CLISTR_CONVERT); + p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE|STR_CONVERT); *p++ = 5; if (first) { SSVAL(p,0,0); diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 47139dcfd6..87f8175459 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -42,10 +42,10 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, p = smb_buf(cli->outbuf); *p++ = 4; p += clistr_push(cli, p, username, -1, - CLISTR_TERMINATE|CLISTR_CONVERT); + STR_TERMINATE|STR_CONVERT); *p++ = 4; p += clistr_push(cli, p, host, -1, - CLISTR_TERMINATE|CLISTR_CONVERT); + STR_TERMINATE|STR_CONVERT); cli_setup_bcc(cli, p); diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 3c87464495..561d717e73 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -235,7 +235,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p += 4; p += clistr_push(cli, p, workgroup, -1, - CLISTR_TERMINATE | CLISTR_CONVERT | CLISTR_ASCII); + STR_TERMINATE | STR_CONVERT | STR_ASCII); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ @@ -394,7 +394,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, memset(p, 0, 6); SSVAL(p, 0, SMB_INFO_STANDARD); p += 6; - p += clistr_push(cli, p, fname, sizeof(pstring)-6, CLISTR_TERMINATE | CLISTR_CONVERT); + p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE | STR_CONVERT); param_len = PTR_DIFF(p, param); @@ -470,7 +470,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO); p += 6; - p += clistr_push(cli, p, fname, sizeof(pstring)-6, CLISTR_TERMINATE | CLISTR_CONVERT); + p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE | STR_CONVERT); param_len = PTR_DIFF(p, param); diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 1835e15971..c0e7231d7a 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -29,10 +29,10 @@ dos code page destination choosing unicode or ascii based on the cli->capabilities flag return the number of bytes occupied by the string in the destination flags can have: - CLISTR_TERMINATE means include the null termination - CLISTR_CONVERT means convert from unix to dos codepage - CLISTR_UPPER means uppercase in the destination - CLISTR_ASCII use ascii even with unicode servers + STR_TERMINATE means include the null termination + STR_CONVERT means convert from unix to dos codepage + STR_UPPER means uppercase in the destination + STR_ASCII use ascii even with unicode servers dest_len is the maximum length allowed in the destination. If dest_len is -1 then no maxiumum is used ****************************************************************************/ @@ -45,52 +45,52 @@ int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len dest_len = sizeof(pstring); } - if (!(flags & CLISTR_ASCII) && clistr_align(cli, PTR_DIFF(dest, cli->outbuf))) { + if (!(flags & STR_ASCII) && clistr_align(cli, PTR_DIFF(dest, cli->outbuf))) { *(char *)dest = 0; dest++; dest_len--; len++; } - if ((flags & CLISTR_ASCII) || !(cli->capabilities & CAP_UNICODE)) { + if ((flags & STR_ASCII) || !(cli->capabilities & CAP_UNICODE)) { /* the server doesn't want unicode */ safe_strcpy(dest, src, dest_len); len = strlen(dest); - if (flags & CLISTR_TERMINATE) len++; - if (flags & CLISTR_CONVERT) unix_to_dos(dest,True); - if (flags & CLISTR_UPPER) strupper(dest); + if (flags & STR_TERMINATE) len++; + if (flags & STR_CONVERT) unix_to_dos(dest,True); + if (flags & STR_UPPER) strupper(dest); return len; } /* the server likes unicode. give it the works */ - if (flags & CLISTR_CONVERT) { - dos_PutUniCode(dest, src, dest_len, flags & CLISTR_TERMINATE); + if (flags & STR_CONVERT) { + dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE); } else { ascii_to_unistr(dest, src, dest_len); } - if (flags & CLISTR_UPPER) { + if (flags & STR_UPPER) { strupper_w(dest); } len += strlen(src)*2; - if (flags & CLISTR_TERMINATE) len += 2; + if (flags & STR_TERMINATE) len += 2; return len; } /**************************************************************************** return the length that a string would occupy when copied with clistr_push() - CLISTR_TERMINATE means include the null termination - CLISTR_CONVERT means convert from unix to dos codepage - CLISTR_UPPER means uppercase in the destination + STR_TERMINATE means include the null termination + STR_CONVERT means convert from unix to dos codepage + STR_UPPER means uppercase in the destination note that dest is only used for alignment purposes. No data is written. ****************************************************************************/ int clistr_push_size(struct cli_state *cli, const void *dest, const char *src, int dest_len, int flags) { int len = strlen(src); - if (flags & CLISTR_TERMINATE) len++; - if (!(flags & CLISTR_ASCII) && (cli->capabilities & CAP_UNICODE)) len *= 2; + if (flags & STR_TERMINATE) len++; + if (!(flags & STR_ASCII) && (cli->capabilities & CAP_UNICODE)) len *= 2; - if (!(flags & CLISTR_ASCII) && dest && clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { + if (!(flags & STR_ASCII) && dest && clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { len++; } @@ -101,10 +101,10 @@ int clistr_push_size(struct cli_state *cli, const void *dest, const char *src, i copy a string from a unicode or ascii source (depending on cli->capabilities) to a char* destination flags can have: - CLISTR_CONVERT means convert from dos to unix codepage - CLISTR_TERMINATE means the string in src is null terminated - CLISTR_UNICODE means to force as unicode -if CLISTR_TERMINATE is set then src_len is ignored + STR_CONVERT means convert from dos to unix codepage + STR_TERMINATE means the string in src is null terminated + STR_UNICODE means to force as unicode +if STR_TERMINATE is set then src_len is ignored src_len is the length of the source area in bytes return the number of bytes occupied by the string in src ****************************************************************************/ @@ -121,9 +121,9 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len if (src_len > 0) src_len--; } - if (!(flags & CLISTR_UNICODE) && !(cli->capabilities & CAP_UNICODE)) { + if (!(flags & STR_UNICODE) && !(cli->capabilities & CAP_UNICODE)) { /* the server doesn't want unicode */ - if (flags & CLISTR_TERMINATE) { + if (flags & STR_TERMINATE) { safe_strcpy(dest, src, dest_len); len = strlen(src)+1; } else { @@ -132,11 +132,11 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len memcpy(dest, src, len); dest[len] = 0; } - if (flags & CLISTR_CONVERT) dos_to_unix(dest,True); + if (flags & STR_CONVERT) dos_to_unix(dest,True); return len; } - if (flags & CLISTR_TERMINATE) { + if (flags & STR_TERMINATE) { unistr_to_ascii(dest, src, dest_len); len = strlen(dest)*2 + 2; } else { @@ -149,7 +149,7 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len *dest++ = 0; len = src_len; } - if (flags & CLISTR_CONVERT) dos_to_unix(dest,True); + if (flags & STR_CONVERT) dos_to_unix(dest,True); return len; } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 630e9f93c0..0bbe7c6dae 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -53,7 +53,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, if (pipe_name) { pipe_name_len = clistr_push_size(cli, smb_buf(cli->outbuf), pipe_name, -1, - CLISTR_TERMINATE); + STR_TERMINATE); } outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3); @@ -76,7 +76,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, SSVAL(cli->outbuf,smb_setup+i*2,setup[i]); p = smb_buf(cli->outbuf); if (trans==SMBtrans) { - clistr_push(cli, p, pipe_name, -1, CLISTR_TERMINATE); + clistr_push(cli, p, pipe_name, -1, STR_TERMINATE); } else { *p++ = 0; /* put in a null smb_name */ *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/libsmb/cli_samr.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index d4540b15c5..cf11110bd3 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -1,4 +1,3 @@ -#define NEW_NTDOMAIN 1 /* Unix SMB/Netbios implementation. Version 2.2 @@ -519,5 +518,3 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, return result; } - -#undef NEW_NTDOMAIN -- cgit From ce069f413215185bd7d248ad7c5b49a17c5b247e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:44:30 +0000 Subject: Ok - everything now compiles in HEAD (at least the default stuff). We should now be ready for the trivial winbindd port..... (Tim ? :-). Jeremy. (This used to be commit 85021b16388e8efc15ac57bf1a7c01bba552bf41) --- source3/libsmb/cli_samr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index cf11110bd3..4c53bd0584 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -314,7 +314,7 @@ uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, /* Return output parameters */ if ((result = r.status) == NT_STATUS_NOPROBLEMO) { - *group_pol = r.group_pol; + *group_pol = r.pol; } done: -- cgit From 9ea70bd00349bc391809bec374700c6d9ce2952b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 14 Mar 2001 12:42:43 +0000 Subject: simpler clistr interface which handles individual packets having unicode bit set differently to capabilities (This used to be commit 34a0821e087810381996f5ff6cf3b4d7b9bb53a0) --- source3/libsmb/clifile.c | 2 +- source3/libsmb/clilist.c | 16 +++++++-------- source3/libsmb/clistr.c | 52 +++++++---------------------------------------- source3/libsmb/clitrans.c | 8 ++------ 4 files changed, 18 insertions(+), 60 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 8742a576cf..79a168121b 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -198,7 +198,7 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ - p += clistr_align(cli, PTR_DIFF(p, cli->outbuf)); + p += clistr_align(cli->outbuf, p); len = clistr_push(cli, p, fname, -1, STR_CONVERT); p += len; SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f0ca0d5f54..0033f05942 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -194,10 +194,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - param_len = 12+clistr_push_size(cli, NULL, mask, -1, - STR_TERMINATE | - STR_CONVERT); - if (First) { setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ @@ -205,8 +201,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,4+2); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); - clistr_push(cli, param+12, mask, -1, - STR_TERMINATE | STR_CONVERT); + p = param+12; + p += clistr_push(cli, param+12, mask, -1, + STR_TERMINATE | STR_CONVERT); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -214,10 +211,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ - clistr_push(cli, param+12, mask, -1, - STR_TERMINATE | STR_CONVERT); + p = param+12; + p += clistr_push(cli, param+12, mask, -1, + STR_TERMINATE | STR_CONVERT); } + param_len = PTR_DIFF(p, param); + if (!cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index c0e7231d7a..feed10fa4e 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -45,14 +45,14 @@ int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len dest_len = sizeof(pstring); } - if (!(flags & STR_ASCII) && clistr_align(cli, PTR_DIFF(dest, cli->outbuf))) { + if (!(flags & STR_ASCII) && clistr_align(cli->outbuf, dest)) { *(char *)dest = 0; dest++; dest_len--; len++; } - if ((flags & STR_ASCII) || !(cli->capabilities & CAP_UNICODE)) { + if ((flags & STR_ASCII) || !(SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) { /* the server doesn't want unicode */ safe_strcpy(dest, src, dest_len); len = strlen(dest); @@ -76,27 +76,6 @@ int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len return len; } - -/**************************************************************************** -return the length that a string would occupy when copied with clistr_push() - STR_TERMINATE means include the null termination - STR_CONVERT means convert from unix to dos codepage - STR_UPPER means uppercase in the destination -note that dest is only used for alignment purposes. No data is written. -****************************************************************************/ -int clistr_push_size(struct cli_state *cli, const void *dest, const char *src, int dest_len, int flags) -{ - int len = strlen(src); - if (flags & STR_TERMINATE) len++; - if (!(flags & STR_ASCII) && (cli->capabilities & CAP_UNICODE)) len *= 2; - - if (!(flags & STR_ASCII) && dest && clistr_align(cli, PTR_DIFF(cli->outbuf, dest))) { - len++; - } - - return len; -} - /**************************************************************************** copy a string from a unicode or ascii source (depending on cli->capabilities) to a char* destination @@ -116,12 +95,12 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len dest_len = sizeof(pstring); } - if (clistr_align(cli, PTR_DIFF(src, cli->inbuf))) { + if (clistr_align(cli->inbuf, src)) { src++; if (src_len > 0) src_len--; } - if (!(flags & STR_UNICODE) && !(cli->capabilities & CAP_UNICODE)) { + if (!(flags & STR_UNICODE) && !(SVAL(cli->inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) { /* the server doesn't want unicode */ if (flags & STR_TERMINATE) { safe_strcpy(dest, src, dest_len); @@ -153,31 +132,14 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len return len; } -/**************************************************************************** -return the length that a string would occupy (not including the null) -when copied with clistr_pull() -if src_len is -1 then assume the source is null terminated -****************************************************************************/ -int clistr_pull_size(struct cli_state *cli, const void *src, int src_len) -{ - if (clistr_align(cli, PTR_DIFF(src, cli->inbuf))) { - src++; - if (src_len > 0) src_len--; - } - - if (!(cli->capabilities & CAP_UNICODE)) { - return strlen(src); - } - return strlen_w(src); -} /**************************************************************************** return an alignment of either 0 or 1 if unicode is not negotiated then return 0 otherwise return 1 if offset is off ****************************************************************************/ -int clistr_align(struct cli_state *cli, int offset) +int clistr_align(const void *buf, const void *p) { - if (!(cli->capabilities & CAP_UNICODE)) return 0; - return offset & 1; + if (!(SVAL(buf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) return 0; + return PTR_DIFF(p, buf) & 1; } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 0bbe7c6dae..d21d179126 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -51,9 +51,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_packet(cli); if (pipe_name) { - pipe_name_len = clistr_push_size(cli, smb_buf(cli->outbuf), - pipe_name, -1, - STR_TERMINATE); + pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE); } outparam = smb_buf(cli->outbuf)+(trans==SMBtrans ? pipe_name_len : 3); @@ -75,9 +73,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, for (i=0;ioutbuf,smb_setup+i*2,setup[i]); p = smb_buf(cli->outbuf); - if (trans==SMBtrans) { - clistr_push(cli, p, pipe_name, -1, STR_TERMINATE); - } else { + if (trans != SMBtrans) { *p++ = 0; /* put in a null smb_name */ *p++ = 'D'; *p++ = ' '; /* observed in OS/2 */ } -- cgit From fb3d8452e5250973eae682dd4a13bf530ccfc56a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 14 Mar 2001 20:22:57 +0000 Subject: set of changes in the beginning of bringing rpcclient changes back to working order. The main change is that the cli_*() RPC functions from libsmb/*.c now should accept a struct cli_state*. The reason for this is that rpcclient should establish the connection to the server at startup so that it is not necessary to keep the clear test or password hash in memory for each command. enumports and enumprinters now works as well. lsa* functions have been tested. SAMR calls may or may not work (one of the core dumps I know), but it compiles :-) jerry (This used to be commit d98ac8852ae6b39b6fcff92c346ba56d9e63c518) --- source3/libsmb/cli_spoolss.c | 56 +++++++++++++++++++------------------------- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/pwd_cache.c | 10 ++++++++ 3 files changed, 35 insertions(+), 33 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index d8e7b0cce6..af12f102d7 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -25,7 +25,6 @@ #include "includes.h" /* Opens a SMB connection to the SPOOLSS pipe */ - struct cli_state *cli_spoolss_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) @@ -321,10 +320,14 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, NEW_BUFFER buffer; uint32 needed = 100; uint32 result; + fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); + fstrcpy (server, cli->desthost); + strupper (server); + do { /* Initialise input parameters */ @@ -333,46 +336,39 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - make_spoolss_q_enumprinters(&q, flags, "", level, &buffer, + make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, needed); /* Marshall data and send request */ if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, - &rbuf)) { + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf)) { result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ - - prs_switch_type(&buffer.prs, UNMARSHALL); - prs_set_offset(&buffer.prs, 0); - r.buffer = &buffer; - if (new_spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { needed = r.needed; } /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO && - r.returned > 0) { + if ((result = r.status) == NT_STATUS_NOPROBLEMO && r.returned > 0) { *returned = r.returned; switch (level) { case 1: - decode_printer_info_1(&buffer, r.returned, + decode_printer_info_1(r.buffer, r.returned, &ctr->printers_1); break; case 2: - decode_printer_info_2(&buffer, r.returned, + decode_printer_info_2(r.buffer, r.returned, &ctr->printers_2); break; case 3: - decode_printer_info_3(&buffer, r.returned, + decode_printer_info_3(r.buffer, r.returned, &ctr->printers_3); break; } @@ -398,10 +394,14 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, NEW_BUFFER buffer; uint32 needed = 100; uint32 result; + fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); + fstrcpy (server, cli->desthost); + strupper (server); + do { /* Initialise input parameters */ @@ -410,23 +410,20 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + /* NT4 will return NT_STATUS_CTL_FILE_NOT_SUPPORTED is we + set the servername here in the query. Not sure why \ + --jerry */ make_spoolss_q_enumports(&q, "", level, &buffer, needed); /* Marshall data and send request */ if (!spoolss_io_q_enumports("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, - &rbuf)) { + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf)) { result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ - - prs_switch_type(&buffer.prs, UNMARSHALL); - prs_set_offset(&buffer.prs, 0); - r.buffer = &buffer; - if (new_spoolss_io_r_enumports("", &r, &rbuf, 0)) { needed = r.needed; } @@ -440,11 +437,11 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, switch (level) { case 1: - decode_port_info_1(&buffer, r.returned, + decode_port_info_1(r.buffer, r.returned, &ctr->port.info_1); break; case 2: - decode_port_info_2(&buffer, r.returned, + decode_port_info_2(r.buffer, r.returned, &ctr->port.info_2); break; } @@ -495,11 +492,6 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, } /* Unmarshall response */ - - prs_switch_type(&buffer.prs, UNMARSHALL); - prs_set_offset(&buffer.prs, 0); - r.buffer = &buffer; - if (spoolss_io_r_getprinter("", &r, &rbuf, 0)) { needed = r.needed; } @@ -510,19 +502,19 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, switch (level) { case 0: - decode_printer_info_0(&buffer, 1, + decode_printer_info_0(r.buffer, 1, &ctr->printers_0); break; case 1: - decode_printer_info_1(&buffer, 1, + decode_printer_info_1(r.buffer, 1, &ctr->printers_1); break; case 2: - decode_printer_info_2(&buffer, 1, + decode_printer_info_2(r.buffer, 1, &ctr->printers_2); break; case 3: - decode_printer_info_3(&buffer, 1, + decode_printer_info_3(r.buffer, 1, &ctr->printers_3); break; } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 46a63dc5f1..06f283c321 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -669,7 +669,7 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed session request\n")); if (do_shutdown) - cli_shutdown(cli); + cli_shutdown(cli); return False; } diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 26b1d192f0..420b49ed2e 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -103,11 +103,21 @@ void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) user_pass = (char*)getpass(passwd_report); + /* + * Do not assume that an empty string is a NULL password. + * If you do this will break the session key generation for + * and account with an emtpy password. If you wish to use + * a NULL password, use the -N option to smbclient and rpcclient + * --jerry + */ +#if 0 if (user_pass == NULL || user_pass[0] == 0) { pwd_set_nullpwd(pwd); } else if (do_encrypt) +#endif + if (do_encrypt) { pwd_make_lm_nt_16(pwd, user_pass); } -- cgit From 79dc43767eb59f0482ac1d8a62d71959e5611ecb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Mar 2001 02:15:05 +0000 Subject: more updates. several spoolss commands added as placeholders to be filled in one at a time. (This used to be commit 6aaac3766324302b995b5a55876bf2ab74af1ff8) --- source3/libsmb/cli_spoolss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index af12f102d7..26ab99419a 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -136,7 +136,7 @@ uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, /* Close a printer handle */ -uint32 cli_spoolss_closeprinter(struct cli_state *cli, POLICY_HND *pol) +uint32 cli_spoolss_close_printer(struct cli_state *cli, POLICY_HND *pol) { prs_struct qbuf, rbuf; SPOOL_Q_CLOSEPRINTER q; -- cgit From f4ae39d53a62a8496cc20bc554fb7b791676bfdc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Mar 2001 07:13:27 +0000 Subject: added getdriver and enumdrivers commands. Also fixed enumprinters so that it works as well. Couple of other misc fixes while we're working on rpcclient. (This used to be commit 83d6bc4454f0cda581d26de32a4fcaad42431b34) --- source3/libsmb/cli_spoolss.c | 225 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 217 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 26ab99419a..c0ec4d0d9c 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -308,6 +308,59 @@ static void decode_port_info_2(NEW_BUFFER *buffer, uint32 returned, *info=inf; } +static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned, + DRIVER_INFO_1 **info) +{ + uint32 i; + DRIVER_INFO_1 *inf; + + inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1)); + + buffer->prs.data_offset=0; + + for (i=0; iprs.data_offset=0; + + for (i=0; iprs.data_offset=0; + + for (i=0; idesthost); - strupper (server); + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); do { /* Initialise input parameters */ @@ -410,10 +462,7 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - /* NT4 will return NT_STATUS_CTL_FILE_NOT_SUPPORTED is we - set the servername here in the query. Not sure why \ - --jerry */ - make_spoolss_q_enumports(&q, "", level, &buffer, needed); + make_spoolss_q_enumports(&q, server, level, &buffer, needed); /* Marshall data and send request */ @@ -457,7 +506,6 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, } /* Get printer info */ - uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr) { @@ -528,3 +576,164 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, return result; } + +/********************************************************************** + * Get installed printer drivers for a given printer + */ +uint32 cli_spoolss_getprinterdriver ( + struct cli_state *cli, + POLICY_HND *pol, + uint32 level, + char* env, + PRINTER_DRIVER_CTR *ctr +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTERDRIVER2 q; + SPOOL_R_GETPRINTERDRIVER2 r; + NEW_BUFFER buffer; + uint32 needed = 1024; + uint32 result; + fstring server; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + fstrcpy (server, cli->desthost); + strupper (server); + + do + { + /* Initialise input parameters */ + + init_buffer(&buffer, needed, cli->mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + + /* write the request */ + make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2, &buffer, needed); + + /* Marshall data and send request */ + if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf)) + { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) + { + needed = r.needed; + } + + /* Return output parameters */ + if ((result = r.status) == NT_STATUS_NOPROBLEMO) + { + + switch (level) + { + case 1: + decode_printer_driver_1(r.buffer, 1, &ctr->info1); + break; + case 2: + decode_printer_driver_2(r.buffer, 1, &ctr->info2); + break; + case 3: + decode_printer_driver_3(r.buffer, 1, &ctr->info3); + break; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + } while (result == ERROR_INSUFFICIENT_BUFFER); + + return result; +} + +/********************************************************************** + * Get installed printer drivers for a given printer + */ +uint32 cli_spoolss_enumprinterdrivers ( + struct cli_state *cli, + uint32 level, + char* env, + uint32 *returned, + PRINTER_DRIVER_CTR *ctr +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMPRINTERDRIVERS q; + SPOOL_R_ENUMPRINTERDRIVERS r; + NEW_BUFFER buffer; + uint32 needed = 0; + uint32 result; + fstring server; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + + do + { + /* Initialise input parameters */ + init_buffer(&buffer, needed, cli->mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + + /* write the request */ + make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, needed); + + /* Marshall data and send request */ + if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf)) + { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + if (spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) + { + needed = r.needed; + } + + /* Return output parameters */ + if (((result=r.status) == NT_STATUS_NOPROBLEMO) && + (r.returned != 0)) + { + *returned = r.returned; + + switch (level) + { + case 1: + decode_printer_driver_1(r.buffer, r.returned, &ctr->info1); + break; + case 2: + decode_printer_driver_2(r.buffer, r.returned, &ctr->info2); + break; + case 3: + decode_printer_driver_3(r.buffer, r.returned, &ctr->info3); + break; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + } while (result == ERROR_INSUFFICIENT_BUFFER); + + return result; +} + + -- cgit From 729b7cf214a8eeb36cef9ff86cfbc1a03fcf0d51 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Mar 2001 16:43:19 +0000 Subject: added getdriverdir and cleaned up the PRINTER_DRIVER_CTR struct (This used to be commit 5d321673850e1e28e1bee4093705d7e319421687) --- source3/libsmb/cli_spoolss.c | 96 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index c0ec4d0d9c..55eb4dc4b2 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -2,6 +2,8 @@ Unix SMB/Netbios implementation. Version 2.2 RPC pipe client + + Copyright (C) Gerald Carter 2001, Copyright (C) Tim Potter 2000, Copyright (C) Andrew Tridgell 1994-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 @@ -342,8 +344,11 @@ static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_driver_3(NEW_BUFFER *buffer, uint32 returned, - DRIVER_INFO_3 **info) +static void decode_printer_driver_3( + NEW_BUFFER *buffer, + uint32 returned, + DRIVER_INFO_3 **info +) { uint32 i; DRIVER_INFO_3 *inf; @@ -359,6 +364,22 @@ static void decode_printer_driver_3(NEW_BUFFER *buffer, uint32 returned, *info=inf; } +static void decode_printerdriverdir_1 ( + NEW_BUFFER *buffer, + uint32 returned, + DRIVER_DIRECTORY_1 **info +) +{ + DRIVER_DIRECTORY_1 *inf; + + inf=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1)); + + prs_set_offset(&buffer->prs, 0); + + new_smb_io_driverdir_1("", buffer, inf, 0); + + *info=inf; +} /* Enumerate printers */ @@ -737,3 +758,74 @@ uint32 cli_spoolss_enumprinterdrivers ( } +/********************************************************************** + * Get installed printer drivers for a given printer + */ +uint32 cli_spoolss_getprinterdriverdir ( + struct cli_state *cli, + uint32 level, + char* env, + DRIVER_DIRECTORY_CTR *ctr +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTERDRIVERDIR q; + SPOOL_R_GETPRINTERDRIVERDIR r; + NEW_BUFFER buffer; + uint32 needed = 100; + uint32 result; + fstring server; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + + do + { + /* Initialise input parameters */ + init_buffer(&buffer, needed, cli->mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + + /* write the request */ + make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, needed); + + /* Marshall data and send request */ + if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, &qbuf, &rbuf)) + { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) + { + needed = r.needed; + } + + /* Return output parameters */ + if ((result=r.status) == NT_STATUS_NOPROBLEMO) + { + switch (level) + { + case 1: + decode_printerdriverdir_1(r.buffer, 1, &ctr->info1); + break; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + } while (result == ERROR_INSUFFICIENT_BUFFER); + + return result; +} + + -- cgit From 207e715059d2fde9df24e16b87f2510fb33f3859 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Mar 2001 22:06:53 +0000 Subject: addprinter and adddriver are working now :-) (This used to be commit 0cb7639cef4a1ba0d56d7e58bd7e03343cbf229d) --- source3/libsmb/cli_spoolss.c | 106 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 55eb4dc4b2..356ee8f03d 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -26,6 +26,8 @@ #include "includes.h" +extern pstring global_myname; + /* Opens a SMB connection to the SPOOLSS pipe */ struct cli_state *cli_spoolss_initialise(struct cli_state *cli, char *system_name, @@ -828,4 +830,108 @@ uint32 cli_spoolss_getprinterdriverdir ( return result; } +/********************************************************************** + * Install a printer driver + */ +uint32 cli_spoolss_addprinterdriver ( + struct cli_state *cli, + uint32 level, + PRINTER_DRIVER_CTR *ctr +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ADDPRINTERDRIVER q; + SPOOL_R_ADDPRINTERDRIVER r; + uint32 result; + fstring server; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + + /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + + /* write the request */ + make_spoolss_q_addprinterdriver (&q, server, level, ctr); + + /* Marshall data and send request */ + if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) + { + return NT_STATUS_UNSUCCESSFUL; + } + + + /* Unmarshall response */ + if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0)) + { + return NT_STATUS_UNSUCCESSFUL; + } + + /* Return output parameters */ + result = r.status; + + return result; +} + +/********************************************************************** + * Install a printer + */ +uint32 cli_spoolss_addprinterex ( + struct cli_state *cli, + uint32 level, + PRINTER_INFO_CTR *ctr +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ADDPRINTEREX q; + SPOOL_R_ADDPRINTEREX r; + uint32 result; + fstring server, + client, + user; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + slprintf (client, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (client); + slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + strupper (server); + fstrcpy (user, cli->user_name); + + + /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + + /* write the request */ + make_spoolss_q_addprinterex (&q, server, client, user, level, ctr); + + /* Marshall data and send request */ + if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf)) + { + return NT_STATUS_UNSUCCESSFUL; + } + + + /* Unmarshall response */ + if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0)) + { + return NT_STATUS_UNSUCCESSFUL; + } + + /* Return output parameters */ + result = r.status; + + return result; +} + -- cgit From 871a4294043e2e74d906f63ad97a31e35abd0374 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 Mar 2001 03:25:13 +0000 Subject: added STR_ASCII support to clistr_pull() (This used to be commit 797293811ef0a79eecc460c471135c89090f8c06) --- source3/libsmb/clilist.c | 6 +++--- source3/libsmb/clistr.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 0033f05942..9080a9c221 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -333,7 +333,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, interpret a short filename structure The length of the structure is returned ****************************************************************************/ -static int interpret_short_filename(char *p,file_info *finfo) +static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { extern file_info def_finfo; @@ -345,7 +345,7 @@ static int interpret_short_filename(char *p,file_info *finfo) finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); - pstrcpy(finfo->name,p+30); + clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_CONVERT|STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); @@ -461,7 +461,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, for (p=dirlist,i=0;iinbuf, src)) { + if (!(flags & STR_ASCII) && clistr_align(cli->inbuf, src)) { src++; if (src_len > 0) src_len--; } - if (!(flags & STR_UNICODE) && !(SVAL(cli->inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) { + if ((flags & STR_ASCII) || + (!(flags & STR_UNICODE) && !(SVAL(cli->inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS))) { /* the server doesn't want unicode */ if (flags & STR_TERMINATE) { safe_strcpy(dest, src, dest_len); -- cgit From cf313f6232e02577b0d79cc90e74cf8f20a81896 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 18 Mar 2001 22:47:17 +0000 Subject: fixed some compilation errors with IRIX cc (This used to be commit e430ded56e9c15a462a171e6350f1eddefa8dd11) --- source3/libsmb/clistr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 93361053e0..13bf1f05b7 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -47,7 +47,7 @@ int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len if (!(flags & STR_ASCII) && clistr_align(cli->outbuf, dest)) { *(char *)dest = 0; - dest++; + dest = (void *)((char *)dest + 1); dest_len--; len++; } @@ -96,7 +96,7 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len } if (!(flags & STR_ASCII) && clistr_align(cli->inbuf, src)) { - src++; + src = (void *)((char *)src + 1); if (src_len > 0) src_len--; } -- cgit From 344fb49fbf4df55492bfa9cc1aee2d8210c32ca6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 19 Mar 2001 18:14:09 +0000 Subject: reverted the rename of new_spoolss_io_r_enumprinterdrivers() (This used to be commit fd6bfe03f4454272bdce59c78ae7148a72caaf18) --- source3/libsmb/cli_spoolss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 356ee8f03d..12abcc1a15 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -725,7 +725,7 @@ uint32 cli_spoolss_enumprinterdrivers ( } /* Unmarshall response */ - if (spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) + if (new_spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) { needed = r.needed; } -- cgit From 5e0734417c7cff16ee69ca8f97b84c2b62af9491 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 27 Mar 2001 12:13:59 +0000 Subject: One small Insure fix for a memory leak. More fixes to come perhaps ... Also fixed an error return for smbc_rmdir so that we can distinguish between EACCES and ENOTEMPTY (This used to be commit f204901fcc11eb3299cc6c7f3793fc3c7bd6bc57) --- source3/libsmb/libsmbclient.c | 54 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 43ccd6486a..826b5fdeb5 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -553,7 +553,9 @@ int smbc_open(const char *fname, int flags, mode_t mode) } - if (path[strlen(path) - 1] == '\\') { + /* Hmmm, the test for a directory is suspect here ... FIXME */ + + if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { fd = -1; @@ -801,6 +803,7 @@ int smbc_close(int fd) } + if (fe->fname) free(fe->fname); free(fe); smbc_file_table[fd - smbc_start_fd] = NULL; @@ -1741,7 +1744,12 @@ int smbc_closedir(int fd) smbc_remove_dir(fe); /* Clean it up */ - if (fe) free(fe); /* Free the space too */ + if (fe) { + + if (fe->fname) free(fe->fname); + free(fe); /* Free the space too */ + + } smbc_file_table[fd - smbc_start_fd] = NULL; @@ -1988,6 +1996,20 @@ int smbc_mkdir(const char *fname, mode_t mode) } +/* + * Our list function simply checks to see if a directory is not empty + */ + +static int smbc_rmdir_dirempty = True; + +static void rmdir_list_fn(file_info *finfo, const char *mask, void *state) +{ + + if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0) + smbc_rmdir_dirempty = False; + +} + /* * Routine to remove a directory */ @@ -2050,6 +2072,34 @@ int smbc_rmdir(const char *fname) if (!cli_rmdir(&srv->cli, path)) { errno = smbc_errno(&srv->cli); + + if (errno == EACCES) { /* Check if the dir empty or not */ + + pstring lpath; /* Local storage to avoid buffer overflows */ + + smbc_rmdir_dirempty = True; /* Make this so ... */ + + pstrcpy(lpath, path); + pstrcat(lpath, "\\*"); + + if (cli_list(&srv->cli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn, + NULL) < 0) { + + /* Fix errno to ignore latest error ... */ + + DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n", + smbc_errno(&srv->cli))); + errno = EACCES; + + } + + if (smbc_rmdir_dirempty) + errno = EACCES; + else + errno = ENOTEMPTY; + + } + return -1; } -- cgit From 25d975e5500243dff4918fe04416695cd3e79a72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 27 Mar 2001 18:19:01 +0000 Subject: merge from 2.2. (This used to be commit 817258f1174d27d74e8b21ffb5f1384db2238007) --- source3/libsmb/cli_spoolss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 12abcc1a15..139bd31526 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -424,7 +424,7 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, } /* Unmarshall response */ - if (new_spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { + if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { needed = r.needed; } @@ -496,7 +496,7 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, } /* Unmarshall response */ - if (new_spoolss_io_r_enumports("", &r, &rbuf, 0)) { + if (spoolss_io_r_enumports("", &r, &rbuf, 0)) { needed = r.needed; } @@ -725,7 +725,7 @@ uint32 cli_spoolss_enumprinterdrivers ( } /* Unmarshall response */ - if (new_spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) + if (spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) { needed = r.needed; } -- cgit From 87f8d78fd790c3643a9c4148e35b00cbe070696f Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 28 Mar 2001 14:45:57 +0000 Subject: More memory leaks fixed courtesy of Insure ... (This used to be commit 4fc385ca6830cb2ac6198501966088fbed27330e) --- source3/libsmb/libsmbclient.c | 55 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 826b5fdeb5..0873661317 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1507,7 +1507,10 @@ int smbc_opendir(const char *fname) if (share[0] != (char)0 || path[0] != (char)0) { errno = EINVAL; - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; return -1; @@ -1544,7 +1547,10 @@ int smbc_opendir(const char *fname) if (!srv) { - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; return -1; @@ -1557,7 +1563,10 @@ int smbc_opendir(const char *fname) if (!cli_NetServerEnum(&srv->cli, lp_workgroup(), 0x80000000, list_fn, (void *)smbc_file_table[slot])) { - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; errno = cli_error(&srv->cli, &eclass, &ecode, NULL); return -1; @@ -1571,7 +1580,10 @@ int smbc_opendir(const char *fname) if (path[0] != (char)0) { /* Should not have empty share with path */ errno = EINVAL; - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; return -1; @@ -1606,7 +1618,10 @@ int smbc_opendir(const char *fname) if (!srv) { - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; /* FIXME: Memory leaks ... */ return -1; @@ -1619,7 +1634,10 @@ int smbc_opendir(const char *fname) if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn, (void *)smbc_file_table[slot])) { - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; errno = cli_error(&srv->cli, &eclass, &ecode, NULL); return -1; @@ -1639,7 +1657,10 @@ int smbc_opendir(const char *fname) if (!srv) { - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; return -1; @@ -1653,7 +1674,10 @@ int smbc_opendir(const char *fname) (void *)smbc_file_table[slot]) < 0) { errno = cli_error(&srv->cli, &eclass, &ecode, NULL); - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; return -1; @@ -1663,7 +1687,10 @@ int smbc_opendir(const char *fname) else { errno = ENODEV; /* Neither the workgroup nor server exists */ - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; return -1; @@ -1682,7 +1709,10 @@ int smbc_opendir(const char *fname) if (!srv) { - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; return -1; @@ -1697,7 +1727,10 @@ int smbc_opendir(const char *fname) if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, (void *)smbc_file_table[slot]) < 0) { - if (smbc_file_table[slot]) free(smbc_file_table[slot]); + if (smbc_file_table[slot]) { + if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); + free(smbc_file_table[slot]); + } smbc_file_table[slot] = NULL; errno = smbc_errno(&srv->cli); return -1; -- cgit From 738a83a14f1eba8fceeec41ab81c7e9da944ccda Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 28 Mar 2001 16:08:00 +0000 Subject: rename of 16 new_smb_io functions to smb_io_* for consistency sake (merge from 2.2) (This used to be commit ea963a648b889da9e47661c61c7fafe13b277e75) --- source3/libsmb/cli_spoolss.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 139bd31526..b335127b8b 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -212,7 +212,7 @@ static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, buffer->prs.data_offset=0; for (i=0; iprs.data_offset=0; for (i=0; iprs, 0); for (i=0; iprs, 0); for (i=0; iprs.data_offset=0; for (i=0; iprs.data_offset=0; for (i=0; iprs.data_offset=0; for (i=0; iprs, 0); - new_smb_io_driverdir_1("", buffer, inf, 0); + smb_io_driverdir_1("", buffer, inf, 0); *info=inf; } -- cgit From 1b95784324cd518d166cc790d9b1cf8a7905aed6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Mar 2001 00:58:52 +0000 Subject: Added cli_nt_create_full() as a way to get at all the ntcreate parameters. Used in smbtorture mods. Re-cast cli_nt_create() as a call to cli_nt_create_full(). Jeremy. (This used to be commit f602fa1205e99541e825ccae8502c35cd0e7ccfc) --- source3/libsmb/clifile.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 79a168121b..bae07d34e6 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -167,9 +167,13 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) } /**************************************************************************** -open a file + open a file - exposing the full horror of the NT API :-). + Used in smbtorture. ****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) + +int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, + uint32 FileAttributes, uint32 ShareAccess, + uint32 CreateDisposition, uint32 CreateOptions) { char *p; int len; @@ -190,10 +194,10 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); - SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, 0x0); - SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, 0x03); - SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, 0x01); - SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, 0x0); + SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, FileAttributes); + SIVAL(cli->outbuf,smb_ntcreate_ShareAccess, ShareAccess); + SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition); + SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions); SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); p = smb_buf(cli->outbuf); @@ -219,6 +223,16 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) return SVAL(cli->inbuf,smb_vwv2 + 1); } +/**************************************************************************** +open a file +****************************************************************************/ + +int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) +{ + return cli_nt_create_full(cli, fname, DesiredAccess, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0); +} + /**************************************************************************** open a file WARNING: if you open with O_WRONLY then getattrE won't work! -- cgit From 34508053bfeba53ec91f5dbf18874c5078e146c9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Mar 2001 02:58:47 +0000 Subject: Added cli_nt_delete_on_close() call to allow flag to be set for torture tests. Jeremy. (This used to be commit 6f7d9e29e4d3a17254ff0ae20c0da63eacded7fe) --- source3/libsmb/clifile.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index bae07d34e6..e90bd7c41f 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -164,6 +164,47 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) } return True; + Set or clear the delete on close flag. +****************************************************************************/ + +int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) +{ + int data_len = 1; + int param_len = 6; + uint16 setup = TRANSACT2_SETFILEINFO; + pstring param; + unsigned char data; + char *rparam=NULL, *rdata=NULL; + + memset(param, 0, param_len); + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_SET_FILE_DISPOSITION_INFO); + + data = flag ? 1 : 0; + + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + &data, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + if (rdata) free(rdata); + if (rparam) free(rparam); + + return True; +} + +/**************************************************************************** } /**************************************************************************** -- cgit From 6e7f03f9b920d1b81056959cca8c0b27ada4ee2d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Mar 2001 08:57:24 +0000 Subject: This is a big, rather ugly patch. Whilst investigating the files not truncated when copying to a full disk problem, I discovered that we were not allowing the delete on close flag to be set properly, this led to other things, and after investigation of the proper delete on close semantics and their relationship to the file_share_delete flag I discovered there were some cases where we weren't doing the deny modes properly. And this after only 5 years working on them..... :-) :-). So here's the latest attempt. I realised the delete on close flag needs to be set across all smbds with a dev/ino pair open - in addition, the delete on close flag, allow share delete and delete access requested all need to be stored in the share mode tdb. The "delete_on_close" entry in the fsp struct is now redundant and should really be removed. This may also mean we can get rid of the "iterate_fsp" calls that I didn't like adding in the first place. Whilst doing this patch, I also discovered we needed to do the se_map_generic() call for file opens and POSIX ACL mapping, so I added that also. This code, although ugly, now passes the deny mode torture tests plus the delete on close tests I added. I do need to add one more multiple connection delete on close test to make sure I got the semantics exactly right, plus we should also (as Andrew suggested) move to random testing here. The good news is that NT should now correctly delete the file on disk full error when copying to a disk :-). Jeremy. (This used to be commit 51987684bd231c744da2e5f3705fd236d5616173) --- source3/libsmb/clifile.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index e90bd7c41f..d62a0a417a 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -164,6 +164,9 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) } return True; +} + +/**************************************************************************** Set or clear the delete on close flag. ****************************************************************************/ @@ -183,7 +186,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) data = flag ? 1 : 0; if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* name, length */ + NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ @@ -204,9 +207,6 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) return True; } -/**************************************************************************** -} - /**************************************************************************** open a file - exposing the full horror of the NT API :-). Used in smbtorture. -- cgit From f9a15ce1a69f905e94db7650f0a4805720cd9c88 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 8 Apr 2001 20:22:39 +0000 Subject: Got "medieval on our ass" about adding the -1 to slprintf. Jeremy. (This used to be commit 94747b4639ed9b19f7d0fb896e43aa392a84989a) --- source3/libsmb/cli_spoolss.c | 12 ++++++------ source3/libsmb/namequery.c | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index b335127b8b..475ebf66a2 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -474,7 +474,7 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, ZERO_STRUCT(q); ZERO_STRUCT(r); - slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); do { @@ -701,7 +701,7 @@ uint32 cli_spoolss_enumprinterdrivers ( ZERO_STRUCT(q); ZERO_STRUCT(r); - slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); do @@ -781,7 +781,7 @@ uint32 cli_spoolss_getprinterdriverdir ( ZERO_STRUCT(q); ZERO_STRUCT(r); - slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); do @@ -848,7 +848,7 @@ uint32 cli_spoolss_addprinterdriver ( ZERO_STRUCT(q); ZERO_STRUCT(r); - slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); /* Initialise input parameters */ @@ -899,9 +899,9 @@ uint32 cli_spoolss_addprinterex ( ZERO_STRUCT(q); ZERO_STRUCT(r); - slprintf (client, sizeof(fstring), "\\\\%s", cli->desthost); + slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (client); - slprintf (server, sizeof(fstring), "\\\\%s", cli->desthost); + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); fstrcpy (user, cli->user_name); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 01ec5e9b29..781bca7eff 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1013,7 +1013,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... bufp += 2; fstrcpy(bufp,srcname); bufp += (strlen(bufp) + 1); - slprintf(bufp, sizeof(fstring), "\\MAILSLOT\\NET\\GETDC%d", dgm_id); + slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id); mailslot_name = bufp; bufp += (strlen(bufp) + 1); bufp = ALIGN2(bufp, buffer); -- cgit From 2ef68c7e92d4661664f0410509f7cb551e74a198 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Apr 2001 19:12:06 +0000 Subject: Merge of Andrew's changes in 2.2. Jeremy. (This used to be commit fc76681812b1469208ad6c8847afdfc68bc6db49) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 22ff09faa3..0a6bbe87e2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -749,7 +749,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) ******************************************************************/ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) { - BOOL ret; + BOOL ret = False; int i; struct sockaddr_in sock_out; -- cgit From 452f60e0303d33a5f6f1d9c5648643068141b849 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 15 Apr 2001 21:22:18 +0000 Subject: Fix from "Darrin B. Jewell" to allow anything other than nmbd to talk to nmbd if it's a WINS server. Jeremy. (This used to be commit 0e8147aecaf6941c77fd05b4b705ca31c1ec5760) --- source3/libsmb/namequery.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 781bca7eff..7714de760b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -674,14 +674,22 @@ static BOOL resolve_wins(const char *name, int name_type, DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); - if( wins_srv_count() < 1 ) { + if (lp_wins_support()) { + /* + * We're providing WINS support. Call ourselves so + * long as we're not nmbd. + */ + extern struct in_addr loopback_ip; + wins_ip = loopback_ip; + wins_ismyip = True; + } else if( wins_srv_count() < 1 ) { DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); return False; + } else { + wins_ip = wins_srv_ip(); + wins_ismyip = ismyip(wins_ip); } - wins_ip = wins_srv_ip(); - wins_ismyip = ismyip(wins_ip); - DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { sock = open_socket_in( SOCK_DGRAM, 0, 3, -- cgit From ac9e221c3e6bc892e0f73a403c89434ae13a8eec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 22 Apr 2001 02:54:04 +0000 Subject: merging from 2.2 to head (This used to be commit bfcc6f88271025760732271f03933839b1cbe0de) --- source3/libsmb/cli_spoolss.c | 100 ++++++++++++++++++++++++++++++++++--------- source3/libsmb/clifile.c | 53 +++++++++++++++++++---- source3/libsmb/clisecdesc.c | 17 +++----- source3/libsmb/smbencrypt.c | 80 ++++++++++++++++++++++++++-------- 4 files changed, 195 insertions(+), 55 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 475ebf66a2..db761e57bf 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -529,8 +529,12 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, } /* Get printer info */ -uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, - uint32 level, PRINTER_INFO_CTR *ctr) +uint32 cli_spoolss_getprinter( + struct cli_state *cli, + POLICY_HND *pol, + uint32 level, + PRINTER_INFO_CTR *ctr +) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTER q; @@ -550,14 +554,12 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - make_spoolss_q_getprinter(&q, pol, level, &buffer, - needed); + make_spoolss_q_getprinter(&q, pol, level, &buffer, needed); /* Marshall data and send request */ - if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, - &rbuf)) { + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf)) + { result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -568,25 +570,20 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, } /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { switch (level) { case 0: - decode_printer_info_0(r.buffer, 1, - &ctr->printers_0); + decode_printer_info_0(r.buffer, 1, &ctr->printers_0); break; case 1: - decode_printer_info_1(r.buffer, 1, - &ctr->printers_1); + decode_printer_info_1(r.buffer, 1, &ctr->printers_1); break; case 2: - decode_printer_info_2(r.buffer, 1, - &ctr->printers_2); + decode_printer_info_2(r.buffer, 1, &ctr->printers_2); break; case 3: - decode_printer_info_3(r.buffer, 1, - &ctr->printers_3); + decode_printer_info_3(r.buffer, 1, &ctr->printers_3); break; } } @@ -600,6 +597,57 @@ uint32 cli_spoolss_getprinter(struct cli_state *cli, POLICY_HND *pol, return result; } +/********************************************************************** + * Set printer info + */ +uint32 cli_spoolss_setprinter( + struct cli_state *cli, + POLICY_HND *pol, + uint32 level, + PRINTER_INFO_CTR *ctr, + uint32 command +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETPRINTER q; + SPOOL_R_SETPRINTER r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + make_spoolss_q_setprinter(&q, pol, level, ctr, command); + + /* Marshall data and send request */ + result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) + { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) + { + goto done; + } + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + + return result; +} + /********************************************************************** * Get installed printer drivers for a given printer */ @@ -860,22 +908,28 @@ uint32 cli_spoolss_addprinterdriver ( make_spoolss_q_addprinterdriver (&q, server, level, ctr); /* Marshall data and send request */ + result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) || !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) { - return NT_STATUS_UNSUCCESSFUL; + goto done; } /* Unmarshall response */ + result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0)) { - return NT_STATUS_UNSUCCESSFUL; + goto done; } /* Return output parameters */ result = r.status; +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } @@ -915,22 +969,28 @@ uint32 cli_spoolss_addprinterex ( make_spoolss_q_addprinterex (&q, server, client, user, level, ctr); /* Marshall data and send request */ + result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) || !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf)) { - return NT_STATUS_UNSUCCESSFUL; + goto done; } /* Unmarshall response */ + result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0)) { - return NT_STATUS_UNSUCCESSFUL; + goto done; } /* Return output parameters */ result = r.status; +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d62a0a417a..c2db97cb3e 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -510,10 +510,8 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, p = smb_buf(cli->outbuf); SIVAL(p, 0, cli->pid); - SIVAL(p, 4, (offset>>32)); - SIVAL(p, 8, (offset&0xffffffff)); - SIVAL(p, 12, (len>>32)); - SIVAL(p, 16, (len&0xffffffff)); + SOFF_T_R(p, 4, offset); + SOFF_T_R(p, 12, len); p += 20; cli_setup_bcc(cli, p); @@ -560,10 +558,8 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ p = smb_buf(cli->outbuf); SIVAL(p, 0, cli->pid); - SIVAL(p, 4, (offset>>32)); - SIVAL(p, 8, (offset&0xffffffff)); - SIVAL(p, 12, (len>>32)); - SIVAL(p, 16, (len&0xffffffff)); + SOFF_T_R(p, 4, offset); + SOFF_T_R(p, 12, len); p += 20; cli_setup_bcc(cli, p); cli_send_smb(cli); @@ -779,3 +775,44 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } + +/**************************************************************************** +create and open a temporary file +****************************************************************************/ +int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,1,strlen(path)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBctemp; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0); + + p = smb_buf(cli->outbuf); + *p++ = 4; + p += clistr_push(cli, p, path, -1, STR_TERMINATE | STR_CONVERT); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + if (tmp_path) { + pstring path2; + clistr_pull(cli, path2, smb_buf(cli->inbuf)+1, + sizeof(path2), -1, STR_TERMINATE | STR_CONVERT); + *tmp_path = strdup(path2); + } + + return SVAL(cli->inbuf,smb_vwv0); +} diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index d34a23537a..0b52d62513 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -33,7 +33,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx = NULL; + TALLOC_CTX *mem_ctx; prs_struct pd; SEC_DESC *psd = NULL; @@ -74,13 +74,11 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) cleanup: - if (mem_ctx) { - talloc_destroy(mem_ctx); - prs_mem_free(&pd); - } + talloc_destroy(mem_ctx); safe_free(rparam); safe_free(rdata); + prs_mem_free(&pd); return psd; } @@ -95,7 +93,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx=NULL; + TALLOC_CTX *mem_ctx; prs_struct pd; BOOL ret = False; @@ -140,10 +138,9 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) safe_free(rparam); safe_free(rdata); - if (mem_ctx) { - talloc_destroy(mem_ctx); - prs_mem_free(&pd); - } + talloc_destroy(mem_ctx); + + prs_mem_free(&pd); return ret; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 858045dc02..caf9256787 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -231,11 +231,18 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ /*********************************************************** decode a password buffer ************************************************************/ -BOOL decode_pw_buffer(char buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len) +BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, + int new_pwrd_size, uint32 *new_pw_len, + uchar nt_p16[16], uchar p16[16]) { - int uni_pw_len=0; char *pw; + + int uni_pw_len=0; + int byte_len=0; + char unicode_passwd[514]; + char lm_ascii_passwd[514]; + char passwd[514]; + /* Warning !!! : This function is called from some rpc call. The password IN the buffer is a UNICODE string. @@ -243,33 +250,72 @@ BOOL decode_pw_buffer(char buffer[516], char *new_pwrd, If you reuse that code somewhere else check first. */ - ZERO_STRUCTP(new_pwrd); + ZERO_STRUCT(unicode_passwd); + ZERO_STRUCT(lm_ascii_passwd); + ZERO_STRUCT(passwd); - /* - * The length of the new password is in the last 4 bytes of - * the data buffer. - */ + memset(nt_p16, '\0', 16); + memset(p16, '\0', 16); - *new_pw_len = IVAL(buffer, 512); + /* The length of the new password is in the last 4 bytes of the data buffer. */ + + byte_len = IVAL(in_buffer, 512); #ifdef DEBUG_PASSWORD - dump_data(100, buffer, 516); + dump_data(100, in_buffer, 516); #endif - if (((int)*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1) { - DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", (*new_pw_len))); + /* Password cannot be longer than 128 characters */ + if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) { + DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); return False; } + + uni_pw_len = byte_len/2; + pw = dos_unistrn2((uint16 *)(&in_buffer[512 - byte_len]), byte_len); + memcpy(passwd, pw, uni_pw_len); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: passwd: ")); + dump_data(100, (char *)passwd, uni_pw_len); + DEBUG(100,("len:%d\n", uni_pw_len)); +#endif + memcpy(unicode_passwd, &in_buffer[512 - byte_len], byte_len); + + mdfour(nt_p16, (unsigned char *)unicode_passwd, byte_len); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("nt_lm_owf_gen: nt#:")); + dump_data(100, (char *)nt_p16, 16); + DEBUG(100,("\n")); +#endif + + /* Mangle the passwords into Lanman format */ + memcpy(lm_ascii_passwd, passwd, uni_pw_len); + lm_ascii_passwd[14] = '\0'; + strupper(lm_ascii_passwd); - uni_pw_len = *new_pw_len; - *new_pw_len /= 2; - pw = dos_unistrn2((uint16 *)(&buffer[512 - uni_pw_len]), uni_pw_len); - memcpy(new_pwrd, pw, *new_pw_len); + /* Calculate the SMB (lanman) hash functions of the password */ + E_P16((uchar *) lm_ascii_passwd, (uchar *)p16); #ifdef DEBUG_PASSWORD - dump_data(100, new_pwrd, (*new_pw_len)); + DEBUG(100,("nt_lm_owf_gen: lm#:")); + dump_data(100, (char *)p16, 16); + DEBUG(100,("\n")); #endif + /* copy the password and it's length to the return buffer */ + *new_pw_len=uni_pw_len; + memcpy(new_pwrd, passwd, uni_pw_len); + new_pwrd[uni_pw_len]='\0'; + + + /* clear out local copy of user's password (just being paranoid). */ + ZERO_STRUCT(unicode_passwd); + ZERO_STRUCT(lm_ascii_passwd); + ZERO_STRUCT(passwd); + return True; + } -- cgit From e40449fa720d0934abd06cd0b0b05d0ca0f4e257 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 28 Apr 2001 00:32:56 +0000 Subject: rpcclient merge from 2.2 (including Jeremy's non-void return fix) (This used to be commit 0a6ceed279cc8111008b21f75c6791efbd993f4b) --- source3/libsmb/cli_lsarpc.c | 104 ++++++++++++------- source3/libsmb/cli_samr.c | 121 +++++++++++++++------- source3/libsmb/cli_spoolss.c | 237 +++++++++++++++++++++++++++---------------- 3 files changed, 300 insertions(+), 162 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 7f5431e4b3..d2174f8d37 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -84,8 +84,13 @@ void cli_lsa_shutdown(struct cli_state *cli) /* Open a LSA policy handle */ -uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, - uint32 des_access, POLICY_HND *pol) +uint32 cli_lsa_open_policy( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + BOOL sec_qos, + uint32 des_access, + POLICY_HND *pol +) { prs_struct qbuf, rbuf; LSA_Q_OPEN_POL q; @@ -98,8 +103,8 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -140,7 +145,11 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, BOOL sec_qos, /* Close a LSA policy handle */ -uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol) +uint32 cli_lsa_close( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *pol +) { prs_struct qbuf, rbuf; LSA_Q_CLOSE q; @@ -152,8 +161,8 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol) /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -187,9 +196,16 @@ uint32 cli_lsa_close(struct cli_state *cli, POLICY_HND *pol) /* Lookup a list of sids */ -uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, - int num_sids, DOM_SID *sids, char ***names, - uint32 **types, int *num_names) +uint32 cli_lsa_lookup_sids( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *pol, + int num_sids, + DOM_SID *sids, + char ***names, + uint32 **types, + int *num_names +) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; @@ -204,12 +220,12 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ - init_q_lookup_sids(cli->mem_ctx, &q, pol, num_sids, sids, 1); + init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1); if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { @@ -246,14 +262,14 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, (*num_names) = r.names->num_entries; - if (!((*names) = (char **)malloc(sizeof(char *) * + if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.names->num_entries))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types) = (uint32 *)malloc(sizeof(uint32) * + if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.names->num_entries))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; @@ -294,9 +310,16 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, POLICY_HND *pol, /* Lookup a list of names */ -uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, - int num_names, char **names, DOM_SID **sids, - uint32 **types, int *num_sids) +uint32 cli_lsa_lookup_names( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *pol, + int num_names, + char **names, + DOM_SID **sids, + uint32 **types, + int *num_sids +) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_NAMES q; @@ -310,12 +333,12 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ - init_q_lookup_names(cli->mem_ctx, &q, pol, num_names, names); + init_q_lookup_names(mem_ctx, &q, pol, num_names, names); if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { @@ -349,14 +372,14 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, (*num_sids) = r.num_entries; - if (!((*sids = (DOM_SID *)malloc(sizeof(DOM_SID) * + if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.num_entries)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types = (uint32 *)malloc(sizeof(uint32) * + if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.num_entries)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; @@ -395,9 +418,14 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, POLICY_HND *pol, /* Query info policy */ -uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, - uint16 info_class, fstring domain_name, - DOM_SID * domain_sid) +uint32 cli_lsa_query_info_policy( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *pol, + uint16 info_class, + fstring domain_name, + DOM_SID * domain_sid +) { prs_struct qbuf, rbuf; LSA_Q_QUERY_INFO q; @@ -409,8 +437,8 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -479,9 +507,15 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, POLICY_HND *pol, /* Enumerate list of trusted domains */ -uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, - uint32 *enum_ctx, uint32 *num_domains, - char ***domain_names, DOM_SID **domain_sids) +uint32 cli_lsa_enum_trust_dom( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *pol, + uint32 *enum_ctx, + uint32 *num_domains, + char ***domain_names, + DOM_SID **domain_sids +) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; @@ -494,8 +528,8 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -527,14 +561,14 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, POLICY_HND *pol, /* Return output parameters */ - if (!((*domain_names) = (char **)malloc(sizeof(char *) * + if (!((*domain_names) = (char **)talloc(mem_ctx, sizeof(char *) * r.num_domains))) { DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*domain_sids) = (DOM_SID *)malloc(sizeof(DOM_SID) * + if (!((*domain_sids) = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.num_domains))) { DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 4c53bd0584..a822611445 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -84,8 +84,13 @@ void cli_samr_shutdown(struct cli_state *cli) /* Connect to SAMR database */ -uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, - uint32 access_mask, POLICY_HND *connect_pol) +uint32 cli_samr_connect( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *srv_name, + uint32 access_mask, + POLICY_HND *connect_pol +) { prs_struct qbuf, rbuf; SAMR_Q_CONNECT q; @@ -97,8 +102,8 @@ uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -132,7 +137,11 @@ uint32 cli_samr_connect(struct cli_state *cli, char *srv_name, /* Close SAMR handle */ -uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol) +uint32 cli_samr_close( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol +) { prs_struct qbuf, rbuf; SAMR_Q_CLOSE_HND q; @@ -144,8 +153,8 @@ uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol) /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -179,9 +188,14 @@ uint32 cli_samr_close(struct cli_state *cli, POLICY_HND *connect_pol) /* Open handle on a domain */ -uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, - uint32 access_mask, DOM_SID *domain_sid, - POLICY_HND *domain_pol) +uint32 cli_samr_open_domain( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol, + uint32 access_mask, + DOM_SID *domain_sid, + POLICY_HND *domain_pol +) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_DOMAIN q; @@ -193,8 +207,8 @@ uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -228,9 +242,14 @@ uint32 cli_samr_open_domain(struct cli_state *cli, POLICY_HND *connect_pol, /* Open handle on a user */ -uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, - uint32 access_mask, uint32 user_rid, - POLICY_HND *user_pol) +uint32 cli_samr_open_user( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, + uint32 access_mask, + uint32 user_rid, + POLICY_HND *user_pol +) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_USER q; @@ -242,8 +261,8 @@ uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -277,9 +296,14 @@ uint32 cli_samr_open_user(struct cli_state *cli, POLICY_HND *domain_pol, /* Open handle on a group */ -uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, - uint32 access_mask, uint32 group_rid, - POLICY_HND *group_pol) +uint32 cli_samr_open_group( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, + uint32 access_mask, + uint32 group_rid, + POLICY_HND *group_pol +) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_GROUP q; @@ -291,8 +315,8 @@ uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -326,8 +350,13 @@ uint32 cli_samr_open_group(struct cli_state *cli, POLICY_HND *domain_pol, /* Query user info */ -uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, - uint16 switch_value, SAM_USERINFO_CTR *ctr) +uint32 cli_samr_query_userinfo( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, + uint16 switch_value, + SAM_USERINFO_CTR *ctr +) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERINFO q; @@ -339,8 +368,8 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -374,8 +403,13 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, POLICY_HND *user_pol, /* Query group info */ -uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, - uint32 info_level, GROUP_INFO_CTR *ctr) +uint32 cli_samr_query_groupinfo( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, + uint32 info_level, + GROUP_INFO_CTR *ctr +) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPINFO q; @@ -387,8 +421,8 @@ uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -422,8 +456,13 @@ uint32 cli_samr_query_groupinfo(struct cli_state *cli, POLICY_HND *group_pol, /* Query user groups */ -uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, - uint32 *num_groups, DOM_GID **gid) +uint32 cli_samr_query_usergroups( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, + uint32 *num_groups, + DOM_GID **gid +) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERGROUPS q; @@ -435,8 +474,8 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ @@ -471,8 +510,14 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, POLICY_HND *user_pol, /* Query user groups */ -uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, - uint32 *num_mem, uint32 **rid, uint32 **attr) +uint32 cli_samr_query_groupmem( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, + uint32 *num_mem, + uint32 **rid, + uint32 **attr +) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPMEM q; @@ -484,8 +529,8 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, POLICY_HND *group_pol, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Marshall data and send request */ diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index db761e57bf..f68483dabe 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -87,10 +87,16 @@ void cli_spoolss_shutdown(struct cli_state *cli) /* Open printer ex */ -uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, - char *datatype, uint32 access_required, - char *station, char *username, - POLICY_HND *pol) +uint32 cli_spoolss_open_printer_ex( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *printername, + char *datatype, + uint32 access_required, + char *station, + char *username, + POLICY_HND *pol +) { prs_struct qbuf, rbuf; SPOOL_Q_OPEN_PRINTER_EX q; @@ -102,8 +108,8 @@ uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -140,7 +146,11 @@ uint32 cli_spoolss_open_printer_ex(struct cli_state *cli, char *printername, /* Close a printer handle */ -uint32 cli_spoolss_close_printer(struct cli_state *cli, POLICY_HND *pol) +uint32 cli_spoolss_close_printer( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + POLICY_HND *pol +) { prs_struct qbuf, rbuf; SPOOL_Q_CLOSEPRINTER q; @@ -152,8 +162,8 @@ uint32 cli_spoolss_close_printer(struct cli_state *cli, POLICY_HND *pol) /* Initialise parse structures */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Initialise input parameters */ @@ -201,8 +211,12 @@ static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) /* Decode various printer info levels - perhaps this should live in parse_spoolss.c? */ -static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, - PRINTER_INFO_0 **info) +static void decode_printer_info_0( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PRINTER_INFO_0 **info +) { uint32 i; PRINTER_INFO_0 *inf; @@ -218,13 +232,17 @@ static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned, - PRINTER_INFO_1 **info) +static void decode_printer_info_1( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PRINTER_INFO_1 **info +) { uint32 i; PRINTER_INFO_1 *inf; - inf=(PRINTER_INFO_1 *)malloc(returned*sizeof(PRINTER_INFO_1)); + inf=(PRINTER_INFO_1 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_1)); buffer->prs.data_offset=0; @@ -235,13 +253,17 @@ static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned, - PRINTER_INFO_2 **info) +static void decode_printer_info_2( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PRINTER_INFO_2 **info +) { uint32 i; PRINTER_INFO_2 *inf; - inf=(PRINTER_INFO_2 *)malloc(returned*sizeof(PRINTER_INFO_2)); + inf=(PRINTER_INFO_2 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_2)); buffer->prs.data_offset=0; @@ -254,13 +276,17 @@ static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned, - PRINTER_INFO_3 **info) +static void decode_printer_info_3( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PRINTER_INFO_3 **info +) { uint32 i; PRINTER_INFO_3 *inf; - inf=(PRINTER_INFO_3 *)malloc(returned*sizeof(PRINTER_INFO_3)); + inf=(PRINTER_INFO_3 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_3)); buffer->prs.data_offset=0; @@ -275,13 +301,17 @@ static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned, /********************************************************************** Decode a PORT_INFO_1 struct from a NEW_BUFFER **********************************************************************/ -static void decode_port_info_1(NEW_BUFFER *buffer, uint32 returned, - PORT_INFO_1 **info) +static void decode_port_info_1( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PORT_INFO_1 **info +) { uint32 i; PORT_INFO_1 *inf; - inf=(PORT_INFO_1*)malloc(returned*sizeof(PORT_INFO_1)); + inf=(PORT_INFO_1*)talloc(mem_ctx, returned*sizeof(PORT_INFO_1)); prs_set_offset(&buffer->prs, 0); @@ -295,13 +325,16 @@ static void decode_port_info_1(NEW_BUFFER *buffer, uint32 returned, /********************************************************************** Decode a PORT_INFO_2 struct from a NEW_BUFFER **********************************************************************/ -static void decode_port_info_2(NEW_BUFFER *buffer, uint32 returned, - PORT_INFO_2 **info) +static void decode_port_info_2( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + PORT_INFO_2 **info) { uint32 i; PORT_INFO_2 *inf; - inf=(PORT_INFO_2*)malloc(returned*sizeof(PORT_INFO_2)); + inf=(PORT_INFO_2*)talloc(mem_ctx, returned*sizeof(PORT_INFO_2)); prs_set_offset(&buffer->prs, 0); @@ -312,13 +345,17 @@ static void decode_port_info_2(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned, - DRIVER_INFO_1 **info) +static void decode_printer_driver_1( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + DRIVER_INFO_1 **info +) { uint32 i; DRIVER_INFO_1 *inf; - inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1)); + inf=(DRIVER_INFO_1 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_1)); buffer->prs.data_offset=0; @@ -329,13 +366,17 @@ static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned, *info=inf; } -static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned, - DRIVER_INFO_2 **info) +static void decode_printer_driver_2( + TALLOC_CTX *mem_ctx, + NEW_BUFFER *buffer, + uint32 returned, + DRIVER_INFO_2 **info +) { uint32 i; DRIVER_INFO_2 *inf; - inf=(DRIVER_INFO_2 *)malloc(returned*sizeof(DRIVER_INFO_2)); + inf=(DRIVER_INFO_2 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_2)); buffer->prs.data_offset=0; @@ -347,6 +388,7 @@ static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned, } static void decode_printer_driver_3( + TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, uint32 returned, DRIVER_INFO_3 **info @@ -355,7 +397,7 @@ static void decode_printer_driver_3( uint32 i; DRIVER_INFO_3 *inf; - inf=(DRIVER_INFO_3 *)malloc(returned*sizeof(DRIVER_INFO_3)); + inf=(DRIVER_INFO_3 *)talloc(mem_ctx, returned*sizeof(DRIVER_INFO_3)); buffer->prs.data_offset=0; @@ -367,6 +409,7 @@ static void decode_printer_driver_3( } static void decode_printerdriverdir_1 ( + TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, uint32 returned, DRIVER_DIRECTORY_1 **info @@ -374,7 +417,7 @@ static void decode_printerdriverdir_1 ( { DRIVER_DIRECTORY_1 *inf; - inf=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1)); + inf=(DRIVER_DIRECTORY_1 *)talloc(mem_ctx, sizeof(DRIVER_DIRECTORY_1)); prs_set_offset(&buffer->prs, 0); @@ -386,9 +429,14 @@ static void decode_printerdriverdir_1 ( /* Enumerate printers */ -uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, - uint32 level, int *returned, - PRINTER_INFO_CTR *ctr) +uint32 cli_spoolss_enum_printers( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 flags, + uint32 level, + int *returned, + PRINTER_INFO_CTR *ctr +) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMPRINTERS q; @@ -407,10 +455,10 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, needed); @@ -430,21 +478,20 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO && r.returned > 0) { - - *returned = r.returned; + if (((result=r.status) == NT_STATUS_NOPROBLEMO) && (*returned = r.returned)) + { switch (level) { case 1: - decode_printer_info_1(r.buffer, r.returned, + decode_printer_info_1(mem_ctx, r.buffer, r.returned, &ctr->printers_1); break; case 2: - decode_printer_info_2(r.buffer, r.returned, + decode_printer_info_2(mem_ctx, r.buffer, r.returned, &ctr->printers_2); break; case 3: - decode_printer_info_3(r.buffer, r.returned, + decode_printer_info_3(mem_ctx, r.buffer, r.returned, &ctr->printers_3); break; } @@ -460,8 +507,13 @@ uint32 cli_spoolss_enum_printers(struct cli_state *cli, uint32 flags, } /* Enumerate printer ports */ -uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, - int *returned, PORT_INFO_CTR *ctr) +uint32 cli_spoolss_enum_ports( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 level, + int *returned, + PORT_INFO_CTR *ctr +) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMPORTS q; @@ -480,10 +532,10 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); make_spoolss_q_enumports(&q, server, level, &buffer, needed); @@ -509,11 +561,11 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, switch (level) { case 1: - decode_port_info_1(r.buffer, r.returned, + decode_port_info_1(mem_ctx, r.buffer, r.returned, &ctr->port.info_1); break; case 2: - decode_port_info_2(r.buffer, r.returned, + decode_port_info_2(mem_ctx, r.buffer, r.returned, &ctr->port.info_2); break; } @@ -531,6 +583,7 @@ uint32 cli_spoolss_enum_ports(struct cli_state *cli, uint32 level, /* Get printer info */ uint32 cli_spoolss_getprinter( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr @@ -549,12 +602,12 @@ uint32 cli_spoolss_getprinter( do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_getprinter(&q, pol, level, &buffer, needed); + make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, needed); /* Marshall data and send request */ if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || @@ -574,16 +627,16 @@ uint32 cli_spoolss_getprinter( switch (level) { case 0: - decode_printer_info_0(r.buffer, 1, &ctr->printers_0); + decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); break; case 1: - decode_printer_info_1(r.buffer, 1, &ctr->printers_1); + decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1); break; case 2: - decode_printer_info_2(r.buffer, 1, &ctr->printers_2); + decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2); break; case 3: - decode_printer_info_3(r.buffer, 1, &ctr->printers_3); + decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3); break; } } @@ -602,6 +655,7 @@ uint32 cli_spoolss_getprinter( */ uint32 cli_spoolss_setprinter( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, PRINTER_INFO_CTR *ctr, @@ -617,10 +671,10 @@ uint32 cli_spoolss_setprinter( ZERO_STRUCT(r); /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_setprinter(&q, pol, level, ctr, command); + make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); /* Marshall data and send request */ result = NT_STATUS_UNSUCCESSFUL; @@ -653,6 +707,7 @@ done: */ uint32 cli_spoolss_getprinterdriver ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 level, char* env, @@ -677,10 +732,10 @@ uint32 cli_spoolss_getprinterdriver ( { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ @@ -707,13 +762,13 @@ uint32 cli_spoolss_getprinterdriver ( switch (level) { case 1: - decode_printer_driver_1(r.buffer, 1, &ctr->info1); + decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1); break; case 2: - decode_printer_driver_2(r.buffer, 1, &ctr->info2); + decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2); break; case 3: - decode_printer_driver_3(r.buffer, 1, &ctr->info3); + decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); break; } } @@ -732,6 +787,7 @@ uint32 cli_spoolss_getprinterdriver ( */ uint32 cli_spoolss_enumprinterdrivers ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, char* env, uint32 *returned, @@ -755,10 +811,10 @@ uint32 cli_spoolss_enumprinterdrivers ( do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ @@ -787,13 +843,13 @@ uint32 cli_spoolss_enumprinterdrivers ( switch (level) { case 1: - decode_printer_driver_1(r.buffer, r.returned, &ctr->info1); + decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1); break; case 2: - decode_printer_driver_2(r.buffer, r.returned, &ctr->info2); + decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2); break; case 3: - decode_printer_driver_3(r.buffer, r.returned, &ctr->info3); + decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); break; } } @@ -813,6 +869,7 @@ uint32 cli_spoolss_enumprinterdrivers ( */ uint32 cli_spoolss_getprinterdriverdir ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, char* env, DRIVER_DIRECTORY_CTR *ctr @@ -835,10 +892,10 @@ uint32 cli_spoolss_getprinterdriverdir ( do { /* Initialise input parameters */ - init_buffer(&buffer, needed, cli->mem_ctx); + init_buffer(&buffer, needed, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ @@ -864,7 +921,7 @@ uint32 cli_spoolss_getprinterdriverdir ( switch (level) { case 1: - decode_printerdriverdir_1(r.buffer, 1, &ctr->info1); + decode_printerdriverdir_1(mem_ctx, r.buffer, 1, &ctr->info1); break; } } @@ -883,6 +940,7 @@ uint32 cli_spoolss_getprinterdriverdir ( */ uint32 cli_spoolss_addprinterdriver ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, PRINTER_DRIVER_CTR *ctr ) @@ -890,22 +948,22 @@ uint32 cli_spoolss_addprinterdriver ( prs_struct qbuf, rbuf; SPOOL_Q_ADDPRINTERDRIVER q; SPOOL_R_ADDPRINTERDRIVER r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); - + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ - make_spoolss_q_addprinterdriver (&q, server, level, ctr); + make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr); /* Marshall data and send request */ result = NT_STATUS_UNSUCCESSFUL; @@ -929,7 +987,7 @@ uint32 cli_spoolss_addprinterdriver ( done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - + return result; } @@ -938,6 +996,7 @@ done: */ uint32 cli_spoolss_addprinterex ( struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, PRINTER_INFO_CTR *ctr ) @@ -961,12 +1020,12 @@ uint32 cli_spoolss_addprinterex ( /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* write the request */ - make_spoolss_q_addprinterex (&q, server, client, user, level, ctr); + make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, level, ctr); /* Marshall data and send request */ result = NT_STATUS_UNSUCCESSFUL; -- cgit From 63602d15afe96206e1fdcea4d2b9014582aa41aa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 28 Apr 2001 14:01:02 +0000 Subject: - fixed some compiler warnings - fixed slprintf and vsprintf macros (This used to be commit c986a3c51e8cdbc1230edbe0f4a91138c4ada29d) --- source3/libsmb/clisecdesc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 0b52d62513..6824a0edf4 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -33,7 +33,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx; + TALLOC_CTX *mem_ctx=NULL; prs_struct pd; SEC_DESC *psd = NULL; -- cgit From f5eab4421c0fcda6907259cb91ba091e9cca5eae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 May 2001 23:07:30 +0000 Subject: Fixup smbcacls. Don't return memory already freed, don't free memory allocated with talloc. Jeremy. (This used to be commit 0ae0d024f5898f7e47e4b1d4487b15447096780c) --- source3/libsmb/clisecdesc.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 6824a0edf4..69c7d5f73f 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -28,12 +28,11 @@ /**************************************************************************** query the security descriptor for a open file ****************************************************************************/ -SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) +SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx) { char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; - TALLOC_CTX *mem_ctx=NULL; prs_struct pd; SEC_DESC *psd = NULL; @@ -58,11 +57,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) goto cleanup; } - if ((mem_ctx = talloc_init()) == NULL) { - DEBUG(0,("talloc_init failed.\n")); - goto cleanup; - } - prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL); prs_append_data(&pd, rdata, rdata_count); pd.data_offset = 0; @@ -74,7 +68,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) cleanup: - talloc_destroy(mem_ctx); safe_free(rparam); safe_free(rdata); @@ -82,9 +75,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd) return psd; } - - - /**************************************************************************** set the security descriptor for a open file ****************************************************************************/ @@ -143,4 +133,3 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) prs_mem_free(&pd); return ret; } - -- cgit From da5faba27787112d4be64f2454af2e55c6a9eb52 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 4 May 2001 04:16:59 +0000 Subject: Added cli_samr_enum_dom_groups() function. (This used to be commit 5a3b7d8b1302fd11321c4a65161de169b41f5d9e) --- source3/libsmb/cli_samr.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index a822611445..0536780444 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -563,3 +563,80 @@ uint32 cli_samr_query_groupmem( return result; } + +/* Enumerate domain groups */ + +uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *start_idx, + uint32 size, struct acct_info **dom_groups, + uint32 *num_dom_groups) +{ + prs_struct qbuf, rbuf; + SAMR_Q_ENUM_DOM_GROUPS q; + SAMR_R_ENUM_DOM_GROUPS r; + uint32 result = NT_STATUS_UNSUCCESSFUL, name_idx, i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_enum_dom_groups(&q, pol, *start_idx, size); + + if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + result = r.status; + + if (result != NT_STATUS_NOPROBLEMO && + result != STATUS_MORE_ENTRIES) { + goto done; + } + + *num_dom_groups = r.num_entries2; + + if (!((*dom_groups) = (struct acct_info *) + talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); + + name_idx = 0; + + for (i = 0; i < *num_dom_groups; i++) { + + (*dom_groups)[i].rid = r.sam[i].rid; + + if (r.sam[i].hdr_name.buffer) { + unistr2_to_ascii((*dom_groups)[i].acct_name, + &r.uni_grp_name[name_idx], + sizeof(fstring) - 1); + name_idx++; + } + + *start_idx = r.next_idx; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 7948967c063cc5b0f6df5efe233f4f7857f918c4 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 4 May 2001 07:27:52 +0000 Subject: Added cli_samr_query_aliasmem() and cli_samr_open_alias() functions. (This used to be commit 0b3bc4375b8984fc16c8972d2b62762c1657f675) --- source3/libsmb/cli_samr.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 0536780444..985a0a1ecb 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -640,3 +640,110 @@ uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Query alias members */ + +uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *alias_pol, uint32 *num_mem, + DOM_SID **sids) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_ALIASMEM q; + SAMR_R_QUERY_ALIASMEM r; + uint32 result = NT_STATUS_UNSUCCESSFUL, i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_query_aliasmem(&q, alias_pol); + + if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + *num_mem = r.num_sids; + + if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + for (i = 0; i < *num_mem; i++) { + (*sids)[i] = r.sid[i].sid; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Open handle on an alias */ + +uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 alias_rid, POLICY_HND *alias_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_OPEN_ALIAS q; + SAMR_R_OPEN_ALIAS r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid); + + if (!samr_io_q_open_alias("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_open_alias("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *alias_pol = r.pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 5ffe6fd4cd1afd28d2c595b278bd3be9f5df70f2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 4 May 2001 07:28:41 +0000 Subject: Zero fnum when initialising a cli_state. (This used to be commit 5a387f59c441d355fe4535eae5c2c924ae9dd451) --- source3/libsmb/clientgen.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d4a025fcc..8e00bca82a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -233,6 +233,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, '\0', cli->bufsize); memset(cli->inbuf, '\0', cli->bufsize); + cli->nt_pipe_fnum = 0; + cli->initialised = 1; return cli; -- cgit From 350dc55c6e9d15dce5defb35b93d3a211865ae79 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 7 May 2001 01:48:03 +0000 Subject: Fixed a compiler warning. Still more const warnings though. )-: (This used to be commit a345b477a22f6261613d21d079b1632a9409c914) --- source3/libsmb/clistr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 13bf1f05b7..0225797538 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -96,7 +96,7 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len } if (!(flags & STR_ASCII) && clistr_align(cli->inbuf, src)) { - src = (void *)((char *)src + 1); + src = (const void *)((const char *)src + 1); if (src_len > 0) src_len--; } -- cgit From b4092fea169022228e4bc0349e51c30786b20ba8 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 7 May 2001 01:55:08 +0000 Subject: Some reformatting (sorry Gerald). Cleanup of exit paths. Added query domain info and query display info. (This used to be commit ff9e222e2ff3f50f4966d3c5859738a831c7adc9) --- source3/libsmb/cli_lsarpc.c | 68 ++++--------- source3/libsmb/cli_samr.c | 230 ++++++++++++++++++++++++++------------------ 2 files changed, 155 insertions(+), 143 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index d2174f8d37..f60a0f960c 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 2.2 RPC pipe client - Copyright (C) Tim Potter 2000, + Copyright (C) Tim Potter 2000-2001, Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, @@ -84,13 +84,8 @@ void cli_lsa_shutdown(struct cli_state *cli) /* Open a LSA policy handle */ -uint32 cli_lsa_open_policy( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - BOOL sec_qos, - uint32 des_access, - POLICY_HND *pol -) +uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, + BOOL sec_qos, uint32 des_access, POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_OPEN_POL q; @@ -145,11 +140,8 @@ uint32 cli_lsa_open_policy( /* Close a LSA policy handle */ -uint32 cli_lsa_close( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol -) +uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_CLOSE q; @@ -196,16 +188,9 @@ uint32 cli_lsa_close( /* Lookup a list of sids */ -uint32 cli_lsa_lookup_sids( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - int num_sids, - DOM_SID *sids, - char ***names, - uint32 **types, - int *num_names -) +uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, int num_sids, DOM_SID *sids, + char ***names, uint32 **types, int *num_names) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; @@ -310,16 +295,9 @@ uint32 cli_lsa_lookup_sids( /* Lookup a list of names */ -uint32 cli_lsa_lookup_names( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - int num_names, - char **names, - DOM_SID **sids, - uint32 **types, - int *num_sids -) +uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, int num_names, char **names, + DOM_SID **sids, uint32 **types, int *num_sids) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_NAMES q; @@ -418,14 +396,9 @@ uint32 cli_lsa_lookup_names( /* Query info policy */ -uint32 cli_lsa_query_info_policy( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint16 info_class, - fstring domain_name, - DOM_SID * domain_sid -) +uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint16 info_class, + fstring domain_name, DOM_SID *domain_sid) { prs_struct qbuf, rbuf; LSA_Q_QUERY_INFO q; @@ -507,15 +480,10 @@ uint32 cli_lsa_query_info_policy( /* Enumerate list of trusted domains */ -uint32 cli_lsa_enum_trust_dom( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint32 *enum_ctx, - uint32 *num_domains, - char ***domain_names, - DOM_SID **domain_sids -) +uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *enum_ctx, + uint32 *num_domains, char ***domain_names, + DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 985a0a1ecb..9fb7e078f6 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 2.2 RPC pipe client - Copyright (C) Tim Potter 2000, + Copyright (C) Tim Potter 2000-2001, Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, @@ -84,18 +84,14 @@ void cli_samr_shutdown(struct cli_state *cli) /* Connect to SAMR database */ -uint32 cli_samr_connect( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - char *srv_name, - uint32 access_mask, - POLICY_HND *connect_pol -) +uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *srv_name, uint32 access_mask, + POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CONNECT q; SAMR_R_CONNECT r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -111,14 +107,12 @@ uint32 cli_samr_connect( if (!samr_io_q_connect("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_connect("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -137,16 +131,13 @@ uint32 cli_samr_connect( /* Close SAMR handle */ -uint32 cli_samr_close( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol -) +uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CLOSE_HND q; SAMR_R_CLOSE_HND r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -162,14 +153,12 @@ uint32 cli_samr_close( if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -188,19 +177,14 @@ uint32 cli_samr_close( /* Open handle on a domain */ -uint32 cli_samr_open_domain( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol, - uint32 access_mask, - DOM_SID *domain_sid, - POLICY_HND *domain_pol -) +uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol, uint32 access_mask, + DOM_SID *domain_sid, POLICY_HND *domain_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_DOMAIN q; SAMR_R_OPEN_DOMAIN r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -216,14 +200,12 @@ uint32 cli_samr_open_domain( if (!samr_io_q_open_domain("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_domain("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -242,19 +224,14 @@ uint32 cli_samr_open_domain( /* Open handle on a user */ -uint32 cli_samr_open_user( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, - uint32 access_mask, - uint32 user_rid, - POLICY_HND *user_pol -) +uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 user_rid, POLICY_HND *user_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_USER q; SAMR_R_OPEN_USER r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -270,14 +247,12 @@ uint32 cli_samr_open_user( if (!samr_io_q_open_user("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_user("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -296,19 +271,14 @@ uint32 cli_samr_open_user( /* Open handle on a group */ -uint32 cli_samr_open_group( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, - uint32 access_mask, - uint32 group_rid, - POLICY_HND *group_pol -) +uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 group_rid, POLICY_HND *group_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_GROUP q; SAMR_R_OPEN_GROUP r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -324,14 +294,12 @@ uint32 cli_samr_open_group( if (!samr_io_q_open_group("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_open_group("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -350,18 +318,14 @@ uint32 cli_samr_open_group( /* Query user info */ -uint32 cli_samr_query_userinfo( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, - uint16 switch_value, - SAM_USERINFO_CTR *ctr -) +uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERINFO q; SAMR_R_QUERY_USERINFO r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -377,7 +341,6 @@ uint32 cli_samr_query_userinfo( if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -386,7 +349,6 @@ uint32 cli_samr_query_userinfo( r.ctr = ctr; if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -403,18 +365,14 @@ uint32 cli_samr_query_userinfo( /* Query group info */ -uint32 cli_samr_query_groupinfo( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, - uint32 info_level, - GROUP_INFO_CTR *ctr -) +uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 info_level, + GROUP_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPINFO q; SAMR_R_QUERY_GROUPINFO r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -430,7 +388,6 @@ uint32 cli_samr_query_groupinfo( if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -439,7 +396,6 @@ uint32 cli_samr_query_groupinfo( r.ctr = ctr; if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -456,18 +412,14 @@ uint32 cli_samr_query_groupinfo( /* Query user groups */ -uint32 cli_samr_query_usergroups( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, - uint32 *num_groups, - DOM_GID **gid -) +uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint32 *num_groups, + DOM_GID **gid) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERGROUPS q; SAMR_R_QUERY_USERGROUPS r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -483,14 +435,12 @@ uint32 cli_samr_query_usergroups( if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -510,19 +460,14 @@ uint32 cli_samr_query_usergroups( /* Query user groups */ -uint32 cli_samr_query_groupmem( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, - uint32 *num_mem, - uint32 **rid, - uint32 **attr -) +uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 *num_mem, + uint32 **rid, uint32 **attr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPMEM q; SAMR_R_QUERY_GROUPMEM r; - uint32 result; + uint32 result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -538,14 +483,12 @@ uint32 cli_samr_query_groupmem( if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } /* Unmarshall response */ if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -747,3 +690,104 @@ uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Query domain info */ + +uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint16 switch_value, + SAM_UNK_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_DOMAIN_INFO q; + SAMR_R_QUERY_DOMAIN_INFO r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_query_dom_info(&q, domain_pol, switch_value); + + if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + r.ctr = ctr; + + if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Query display info */ + +uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 *start_idx, + uint16 switch_value, uint32 *num_entries, + uint32 max_entries, SAM_DISPINFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_DISPINFO q; + SAMR_R_QUERY_DISPINFO r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_query_dispinfo(&q, domain_pol, switch_value, + *start_idx, max_entries); + + if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + *num_entries = r.num_entries; + *start_idx += r.num_entries; /* No next_idx in this structure! */ + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 4009e89f014fe17901fad4045ba3b3b7c8086b10 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 8 May 2001 03:49:57 +0000 Subject: Fix for query_dispinfo() Added lookup_rids() function. (This used to be commit 9ff3c82a54a18d0d9f187c119656e58316c7eb0e) --- source3/libsmb/cli_samr.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 9fb7e078f6..94c2b6ae92 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -772,6 +772,8 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Unmarshall response */ + r.ctr = ctr; + if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) { goto done; } @@ -791,3 +793,71 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Lookup rids */ + +uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 flags, + uint32 num_rids, uint32 *rids, + uint32 *num_names, char ***names, + uint32 **name_types) +{ + prs_struct qbuf, rbuf; + SAMR_Q_LOOKUP_RIDS q; + SAMR_R_LOOKUP_RIDS r; + uint32 result = NT_STATUS_UNSUCCESSFUL, i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags, + num_rids, rids); + + if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + if (r.num_names1 == 0) { + *num_names = 0; + *names = NULL; + goto done; + } + + *num_names = r.num_names1; + *names = talloc(mem_ctx, sizeof(char *) * r.num_names1); + *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1); + + for (i = 0; i < r.num_names1; i++) { + fstring tmp; + + unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1); + (*names)[i] = strdup(tmp); + (*name_types)[i] = r.type[i]; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 862fe3b7ede1ff2214e9129e10820d7fa67681bc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 11 May 2001 07:04:47 +0000 Subject: Memory leak fixes plus general cleanup. (This used to be commit 48688c4592d03d6404631a7d57701f0af38cfb2d) --- source3/libsmb/cli_lsarpc.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index f60a0f960c..00c5ac9a16 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -278,7 +278,7 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, "%s%s%s", dom_name, dom_name[0] ? "\\" : "", name); - (*names)[i] = strdup(full_name); + (*names)[i] = talloc_strdup(mem_ctx, full_name); (*types)[i] = t_names.name[i].sid_name_use; } else { (*names)[i] = NULL; @@ -436,6 +436,9 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ + ZERO_STRUCTP(domain_sid); + domain_name[0] = '\0'; + switch (info_class) { case 3: -- cgit From 324cd98913fef80016326e907c5130d71d88495d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 11 May 2001 07:13:13 +0000 Subject: Use talloc_strdup() instead of strdup(). (This used to be commit 3b4b5b3c61bb1fe1db15306219f24036bf342e2d) --- source3/libsmb/cli_samr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 94c2b6ae92..538574f437 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -851,7 +851,7 @@ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, fstring tmp; unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1); - (*names)[i] = strdup(tmp); + (*names)[i] = talloc_strdup(mem_ctx, tmp); (*name_types)[i] = r.type[i]; } -- cgit From 5bcd434e6e1e5c5ab4d567e2a4c2bdaf4806ff1f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 14 May 2001 03:58:49 +0000 Subject: Compile fixes for dynamic samr_query_userinfo() stuff. (This used to be commit a92a0d061bd322b9d3a1fe13c6ce2d2e1f070ef7) --- source3/libsmb/cli_samr.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 538574f437..a33474d1c1 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -320,7 +320,7 @@ uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *user_pol, uint16 switch_value, - SAM_USERINFO_CTR *ctr) + SAM_USERINFO_CTR **ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERINFO q; @@ -346,8 +346,6 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Unmarshall response */ - r.ctr = ctr; - if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) { goto done; } @@ -355,6 +353,7 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ result = r.status; + *ctr = r.ctr; done: prs_mem_free(&qbuf); -- cgit From eb40ad72baba90a9fdc9372340358864025c36a3 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 15 May 2001 01:45:54 +0000 Subject: Change EUCLEAN to EINVAL, as some systems do not have EUCLEAN, and EINVAL is a better return code anyway (I knew that :-) (This used to be commit 0bf2797b183b4d709a401ebdb2d5f3d5b1c907af) --- source3/libsmb/libsmbclient.c | 48 +++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 0873661317..2b93614338 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -528,7 +528,7 @@ int smbc_open(const char *fname, int flags, mode_t mode) if (!smbc_initialized) { - errno = EUCLEAN; /* Best I can think of ... */ + errno = EINVAL; /* Best I can think of ... */ return -1; } @@ -636,7 +636,7 @@ int smbc_creat(const char *path, mode_t mode) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -655,7 +655,7 @@ ssize_t smbc_read(int fd, void *buf, size_t count) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -715,7 +715,7 @@ ssize_t smbc_write(int fd, void *buf, size_t count) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -769,7 +769,7 @@ int smbc_close(int fd) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -822,7 +822,7 @@ int smbc_unlink(const char *fname) if (!smbc_initialized) { - errno = EUCLEAN; /* Best I can think of ... */ + errno = EINVAL; /* Best I can think of ... */ return -1; } @@ -913,7 +913,7 @@ int smbc_rename(const char *oname, const char *nname) if (!smbc_initialized) { - errno = EUCLEAN; /* Best I can think of ... */ + errno = EINVAL; /* Best I can think of ... */ return -1; } @@ -980,7 +980,7 @@ off_t smbc_lseek(int fd, off_t offset, int whence) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -1107,7 +1107,7 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -1145,7 +1145,7 @@ int smbc_stat(const char *fname, struct stat *st) if (!smbc_initialized) { - errno = EUCLEAN; /* Best I can think of ... */ + errno = EINVAL; /* Best I can think of ... */ return -1; } @@ -1229,7 +1229,7 @@ int smbc_fstat(int fd, struct stat *st) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -1448,7 +1448,7 @@ int smbc_opendir(const char *fname) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -1754,7 +1754,7 @@ int smbc_closedir(int fd) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -1805,7 +1805,7 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return NULL; } @@ -1876,7 +1876,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -1971,7 +1971,7 @@ int smbc_mkdir(const char *fname, mode_t mode) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -2055,7 +2055,7 @@ int smbc_rmdir(const char *fname) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -2151,7 +2151,7 @@ off_t smbc_telldir(int fd) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -2225,7 +2225,7 @@ int smbc_lseekdir(int fd, off_t offset) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -2287,7 +2287,7 @@ int smbc_fstatdir(int fd, struct stat *st) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -2312,7 +2312,7 @@ int smbc_print_file(const char *fname, const char *printq) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -2386,7 +2386,7 @@ int smbc_open_print_job(const char *fname) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -2420,7 +2420,7 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } @@ -2470,7 +2470,7 @@ int smbc_unlink_print_job(const char *fname, int id) if (!smbc_initialized) { - errno = EUCLEAN; + errno = EINVAL; return -1; } -- cgit From 2378ba1c214e8c377516fd9d5dd10afec6493be3 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 17 May 2001 02:44:10 +0000 Subject: Further recasts to sockaddr * rather than sockaddr_in * (This used to be commit b0ba25e22d101acbe4079bc81759a4e0c8a7e6d8) --- source3/libsmb/clidgram.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 3eaf2bf48a..1ac2439b08 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -188,13 +188,13 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) sock_out.sin_port = htons(138); sock_out.sin_family = AF_INET; - if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) { + if (bind(dgram_sock, (struct sockaddr *)&sock_out, sizeof(sock_out)) < 0) { /* Try again on any port ... */ sock_out.sin_port = INADDR_ANY; - if (bind(dgram_sock, (struct sockaddr_in *)&sock_out, sizeof(sock_out)) < 0) { + if (bind(dgram_sock, (struct sockaddr *)&sock_out, sizeof(sock_out)) < 0) { DEBUG(4, ("failed to bind socket to address ...\n")); return False; @@ -207,7 +207,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) name_size = sizeof(sock_out); - getsockname(dgram_sock, (struct sockaddr_in *)&sock_out, &name_size); + getsockname(dgram_sock, (struct sockaddr *)&sock_out, &name_size); DEBUG(5, ("Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port))); -- cgit From 89de0c46ad994bd15217b4eb6c8d3793e35ffb92 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 17 May 2001 04:09:08 +0000 Subject: Fix a small warning about char * vs unsigned char * that gets some compilers in a twitch. (This used to be commit 672242a52eafde35cba4657bce248fef0df9e46b) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index c2db97cb3e..4002a43c1b 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -190,7 +190,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ - &data, data_len, cli->max_xmit /* data, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ )) { return False; } -- cgit From 013b454d1a2858b6f3b48e7b73f549ec7540d189 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 17 May 2001 18:57:25 +0000 Subject: merge from 2.2 DeletePrinterDriver() server side stud coming in separate commit after I get it working in 2.2. (This used to be commit 09506ac0e64b84d73e3b8fdd4942fa52dba6060f) --- source3/libsmb/cli_spoolss.c | 57 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index f68483dabe..4f8d6c0c88 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1053,4 +1053,61 @@ done: return result; } +/********************************************************************** + * Delete a Printer Driver from the server (does not remove + * the driver files + */ +uint32 cli_spoolss_deleteprinterdriver ( + struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *arch, + char *driver +) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_DELETEPRINTERDRIVER q; + SPOOL_R_DELETEPRINTERDRIVER r; + uint32 result; + fstring server; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + + /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (server); + + /* write the request */ + make_spoolss_q_deleteprinterdriver (mem_ctx, &q, server, arch, driver); + + /* Marshall data and send request */ + result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) + { + goto done; + } + + + /* Unmarshall response */ + result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0)) + { + goto done; + } + + /* Return output parameters */ + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + -- cgit From 40ff4007c7ea1c1512592c8a0cb3833be2fe97d1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 24 May 2001 00:20:32 +0000 Subject: Added stubs for SRVSVC and NETLOGON rpcclient commands. (This used to be commit 3343c9f0d67d98687e5933e1a73c0ff487279160) --- source3/libsmb/cli_netlogon.c | 142 ++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/cli_srvsvc.c | 82 ++++++++++++++++++++++++ 2 files changed, 224 insertions(+) create mode 100644 source3/libsmb/cli_netlogon.c create mode 100644 source3/libsmb/cli_srvsvc.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c new file mode 100644 index 0000000000..ee0ed82829 --- /dev/null +++ b/source3/libsmb/cli_netlogon.c @@ -0,0 +1,142 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Tim Potter 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* Opens a SMB connection to the netlogon pipe */ + +struct cli_state *cli_netlogon_initialise(struct cli_state *cli, + char *system_name, + struct ntuser_creds *creds) +{ + struct in_addr dest_ip; + struct nmb_name calling, called; + fstring dest_host; + extern pstring global_myname; + struct ntuser_creds anon; + + /* Initialise cli_state information */ + + if (!cli_initialise(cli)) { + return NULL; + } + + if (!creds) { + ZERO_STRUCT(anon); + anon.pwd.null_pwd = 1; + creds = &anon; + } + + cli_init_creds(cli, creds); + + /* Establish a SMB connection */ + + if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { + return NULL; + } + + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); + + if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, + &called, "IPC$", "IPC", False, True)) { + return NULL; + } + + /* Open a NT session thingy */ + + if (!cli_nt_session_open(cli, PIPE_NETLOGON)) { + cli_shutdown(cli); + return NULL; + } + + return cli; +} + +/* Shut down a SMB connection to the netlogon pipe */ + +void cli_netlogon_shutdown(struct cli_state *cli) +{ + if (cli->fd != -1) cli_ulogoff(cli); + cli_shutdown(cli); +} + +/*************************************************************************** +Synchronise SAM Database (requires SEC_CHAN_BDC). +****************************************************************************/ +BOOL cli_net_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *srv_name, uint32 database_id, uint32 *num_deltas, + SAM_DELTA_HDR *hdr_deltas, SAM_DELTA_CTR *deltas) +{ + prs_struct qbuf, rbuf; + NET_Q_SAM_SYNC q; + NET_R_SAM_SYNC r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + DOM_CRED new_clnt_cred; + uint8 sess_key[16]; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_q_sam_sync(&q, srv_name, cli->clnt_name_slash, &new_clnt_cred, + database_id); + + /* Marshall data and send request */ + + if (!net_io_q_sam_sync("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) { + goto done; + } + + r.hdr_deltas = hdr_deltas; + r.deltas = deltas; + + if (!net_io_r_sam_sync("", sess_key, &r, &rbuf, 0)) { + goto done; + } + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + +#if 0 + /* Update the credentials. */ + if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds))) + { + *num_deltas = r_s.num_deltas2; + } +#endif + + done: + prs_mem_free(&rbuf); + prs_mem_free(&qbuf); + + return result; +} diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c new file mode 100644 index 0000000000..9d13e94930 --- /dev/null +++ b/source3/libsmb/cli_srvsvc.c @@ -0,0 +1,82 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Tim Potter 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* Opens a SMB connection to the svrsvc pipe */ + +struct cli_state *cli_svrsvc_initialise(struct cli_state *cli, + char *system_name, + struct ntuser_creds *creds) +{ + struct in_addr dest_ip; + struct nmb_name calling, called; + fstring dest_host; + extern pstring global_myname; + struct ntuser_creds anon; + + /* Initialise cli_state information */ + + if (!cli_initialise(cli)) { + return NULL; + } + + if (!creds) { + ZERO_STRUCT(anon); + anon.pwd.null_pwd = 1; + creds = &anon; + } + + cli_init_creds(cli, creds); + + /* Establish a SMB connection */ + + if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { + return NULL; + } + + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); + + if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, + &called, "IPC$", "IPC", False, True)) { + return NULL; + } + + /* Open a NT session thingy */ + + if (!cli_nt_session_open(cli, PIPE_SRVSVC)) { + cli_shutdown(cli); + return NULL; + } + + return cli; +} + +/* Shut down a SMB connection to the srvsvc pipe */ + +void cli_srvsvc_shutdown(struct cli_state *cli) +{ + if (cli->fd != -1) cli_ulogoff(cli); + cli_shutdown(cli); +} -- cgit From 6958bfa518ef4f0ddd88c31b071f7c23158854e4 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 24 May 2001 08:01:55 +0000 Subject: Added logon control2 client call. (This used to be commit 8d5f2027095c3fb9240db238fb6d405aeefef1ef) --- source3/libsmb/cli_netlogon.c | 44 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 29 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index ee0ed82829..47b7c2f22e 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -81,19 +81,15 @@ void cli_netlogon_shutdown(struct cli_state *cli) cli_shutdown(cli); } -/*************************************************************************** -Synchronise SAM Database (requires SEC_CHAN_BDC). -****************************************************************************/ -BOOL cli_net_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *srv_name, uint32 database_id, uint32 *num_deltas, - SAM_DELTA_HDR *hdr_deltas, SAM_DELTA_CTR *deltas) +/* Logon Control 2 */ + +uint32 cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 query_level) { prs_struct qbuf, rbuf; - NET_Q_SAM_SYNC q; - NET_R_SAM_SYNC r; + NET_Q_LOGON_CTRL2 q; + NET_R_LOGON_CTRL2 r; uint32 result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED new_clnt_cred; - uint8 sess_key[16]; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -105,38 +101,28 @@ BOOL cli_net_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - init_q_sam_sync(&q, srv_name, cli->clnt_name_slash, &new_clnt_cred, - database_id); + init_net_q_logon_ctrl2(&q, cli->srv_name_slash, query_level); /* Marshall data and send request */ - if (!net_io_q_sam_sync("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) { + if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; goto done; } - r.hdr_deltas = hdr_deltas; - r.deltas = deltas; - - if (!net_io_r_sam_sync("", sess_key, &r, &rbuf, 0)) { - goto done; - } + /* Unmarshall response */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if (!net_io_r_logon_ctrl2("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; goto done; } -#if 0 - /* Update the credentials. */ - if (ok && !cli_con_deal_with_creds(con, &(r_s.srv_creds))) - { - *num_deltas = r_s.num_deltas2; - } -#endif + result = r.status; done: - prs_mem_free(&rbuf); prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return result; } -- cgit From 69eb5affbd01f3961077e85f11663de1418f1d13 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 24 May 2001 08:02:27 +0000 Subject: Added srv_get_info client command. (This used to be commit ee599c9481c26d8407f03a9897eb5f1abd1e47f1) --- source3/libsmb/cli_srvsvc.c | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 9d13e94930..8209d9301f 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -80,3 +80,49 @@ void cli_srvsvc_shutdown(struct cli_state *cli) if (cli->fd != -1) cli_ulogoff(cli); cli_shutdown(cli); } + +uint32 cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 switch_value, SRV_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SRV_GET_INFO q; + SRV_R_NET_SRV_GET_INFO r; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value); + + /* Marshall data and send request */ + + if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + r.ctr = ctr; + + if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 7a33f253e15a0907b22eb03a3a2c79e9998aa1ec Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 31 May 2001 17:28:40 +0000 Subject: merge from 2.2 (This used to be commit 7e23ed48908cf396610d26efda9f54d5f5f0e83c) --- source3/libsmb/cli_spoolss.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 4f8d6c0c88..2c962ef27a 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -677,7 +677,6 @@ uint32 cli_spoolss_setprinter( make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); /* Marshall data and send request */ - result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) { @@ -686,7 +685,6 @@ uint32 cli_spoolss_setprinter( } /* Unmarshall response */ - result = NT_STATUS_UNSUCCESSFUL; if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) { goto done; -- cgit From f903ec893ad7aff832193bcd7035be3ee9c65c22 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 4 Jun 2001 04:34:50 +0000 Subject: Added add domain user to rpcclient. Added cli_ functions for set userinfo and userinfo2. (This used to be commit 6c9796286c489a79c96d28b081ecf151803dbf7c) --- source3/libsmb/cli_samr.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index a33474d1c1..11b8543cce 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -860,3 +860,153 @@ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Create a domain user */ + +uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, char *acct_name, + uint32 acb_info, uint32 unknown, + POLICY_HND *user_pol, uint32 *rid) +{ + prs_struct qbuf, rbuf; + SAMR_Q_CREATE_USER q; + SAMR_R_CREATE_USER r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown); + + if (!samr_io_q_create_user("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_create_user("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + if (user_pol) + *user_pol = r.user_pol; + + if (rid) + *rid = r.user_rid; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Set userinfo */ + +uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + uchar sess_key[16], SAM_USERINFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_SET_USERINFO q; + SAMR_R_SET_USERINFO r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + q.ctr = ctr; + + init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, ctr); + + if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Set userinfo2 */ + +uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + uchar sess_key[16], SAM_USERINFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SAMR_Q_SET_USERINFO2 q; + SAMR_R_SET_USERINFO2 r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr); + + if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 05fc3e578c895f632b351969d09cd00feb7599c7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 4 Jun 2001 05:13:59 +0000 Subject: use LDSHFLAGS not -shared in several places (This used to be commit 8ec9c87b5d1a7dae17d5b1a30f58effaf5e69e4b) --- source3/libsmb/unexpected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 6c5dd611a9..d757551963 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -49,7 +49,7 @@ void unexpected_packet(struct packet_struct *p) int len=0; if (!tdbd) { - tdbd = tdb_open(lock_path("unexpected.tdb"), 1, + tdbd = tdb_open_log(lock_path("unexpected.tdb"), 1, TDB_CLEAR_IF_FIRST, O_RDWR | O_CREAT, 0644); if (!tdbd) { -- cgit From 5264e9a2a737d6498be0f346bcbc3b583609abf5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 5 Jun 2001 08:17:16 +0000 Subject: Set correct reply word in large writeX (greater than 64k) replies. Also added smbtorture test for this. Jeremy. (This used to be commit 6d65556ae8bea45a203defaded8436cbb56965e1) --- source3/libsmb/clireadwrite.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 86a51da835..6c52d2b776 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -138,7 +138,10 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,12,size,True); + if (size > 0xFFFF) + set_message(cli->outbuf,14,size,True); + else + set_message(cli->outbuf,12,size,True); CVAL(cli->outbuf,smb_com) = SMBwriteX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -152,6 +155,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_vwv7,mode); SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); + SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1)); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); -- cgit From d4631e3d56ee00916cb82dc2f666791f0187cd97 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Jun 2001 07:17:31 +0000 Subject: Fixed bug in cli_samr_create_dom_user() Added cli_samr_lookup_names() Removed redundant argument to cli_samr_connect() (This used to be commit 79710a3ab394dc024b3ccfccfb45fb6a906c3499) --- source3/libsmb/cli_samr.c | 72 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 68 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 11b8543cce..f8dd8040c9 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -85,8 +85,7 @@ void cli_samr_shutdown(struct cli_state *cli) /* Connect to SAMR database */ uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *srv_name, uint32 access_mask, - POLICY_HND *connect_pol) + uint32 access_mask, POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CONNECT q; @@ -103,7 +102,7 @@ uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ - init_samr_q_connect(&q, srv_name, access_mask); + init_samr_q_connect(&q, cli->desthost, access_mask); if (!samr_io_q_connect("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) { @@ -861,6 +860,70 @@ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Lookup names */ + +uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 flags, + uint32 num_names, char **names, + uint32 *num_rids, uint32 **rids, + uint32 **rid_types) +{ + prs_struct qbuf, rbuf; + SAMR_Q_LOOKUP_NAMES q; + SAMR_R_LOOKUP_NAMES r; + uint32 result = NT_STATUS_UNSUCCESSFUL, i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags, + num_names, names); + + if (!samr_io_q_lookup_names("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + goto done; + } + + if (r.num_rids1 == 0) { + *num_rids = 0; + goto done; + } + + *num_rids = r.num_rids1; + *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1); + *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1); + + for (i = 0; i < r.num_rids1; i++) { + (*rids)[i] = r.rids[i]; + (*rid_types)[i] = r.types[i]; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Create a domain user */ uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, @@ -938,7 +1001,8 @@ uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, q.ctr = ctr; - init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, ctr); + init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, + ctr->info.id); if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) { -- cgit From 68e83b0fee5405fc2e393e69aff3a8e3f94430a5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Jun 2001 07:32:51 +0000 Subject: Added stubs for dfs rpc client routines. (This used to be commit abc294c4a82dc132b937aec374ee947992a1b93f) --- source3/libsmb/cli_dfs.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 source3/libsmb/cli_dfs.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c new file mode 100644 index 0000000000..1874fc5cf4 --- /dev/null +++ b/source3/libsmb/cli_dfs.c @@ -0,0 +1,79 @@ +/* + Unix SMB/Netbios implementation. + Version 2.2 + RPC pipe client + Copyright (C) Tim Potter 2000-2001, + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* Opens a SMB connection to the netdfs pipe */ + +struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name, + struct ntuser_creds *creds) +{ + struct in_addr dest_ip; + struct nmb_name calling, called; + fstring dest_host; + extern pstring global_myname; + struct ntuser_creds anon; + + /* Initialise cli_state information */ + + if (!cli_initialise(cli)) { + return NULL; + } + + if (!creds) { + ZERO_STRUCT(anon); + anon.pwd.null_pwd = 1; + creds = &anon; + } + + cli_init_creds(cli, creds); + + /* Establish a SMB connection */ + + if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { + return NULL; + } + + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); + + if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, + &called, "IPC$", "IPC", False, True)) { + return NULL; + } + + /* Open a NT session thingy */ + + if (!cli_nt_session_open(cli, PIPE_NETDFS)) { + cli_shutdown(cli); + return NULL; + } + + return cli; +} + +/* Shut down a SMB connection to the DFS pipe */ + +void cli_dfs_shutdown(struct cli_state *cli) +{ + if (cli->fd != -1) cli_ulogoff(cli); + cli_shutdown(cli); +} -- cgit From 87b5c377073c1ee4071aee02ef5f598ad850a92b Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 7 Jun 2001 22:17:01 +0000 Subject: Fix up the problems with calling smbc_init multiple times. (This used to be commit 832227a72b9c1d965736128ff84ffa235df6ecaf) --- source3/libsmb/libsmbclient.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2b93614338..cdf26e6b23 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -412,6 +412,12 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) } + if (smbc_initialize) { /* Don't go through this if we have already done it */ + + return 0; + + } + smbc_initialized = 1; smbc_auth_fn = fn; /* smbc_debug = debug; */ -- cgit From 5eee0f1968391ff0aa42ad09e1687ef4a9da88e3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 13 Jun 2001 06:37:02 +0000 Subject: Added some msdfs client routines. (This used to be commit 13df2304b309a2bd14d4441db0e72e75b8742262) --- source3/libsmb/cli_dfs.c | 222 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 222 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index 1874fc5cf4..830681effb 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -77,3 +77,225 @@ void cli_dfs_shutdown(struct cli_state *cli) if (cli->fd != -1) cli_ulogoff(cli); cli_shutdown(cli); } + +/* Query DFS support */ + +uint32 cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, + BOOL *dfs_exists) +{ + prs_struct qbuf, rbuf; + DFS_Q_DFS_EXIST q; + DFS_R_DFS_EXIST r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_dfs_q_dfs_exist(&q); + + if (!dfs_io_q_dfs_exist("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, DFS_EXIST, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!dfs_io_r_dfs_exist("", &r, &rbuf, 0)) { + goto done; + } + + /* Return result */ + + *dfs_exists = (r.status == 1); + + result = NT_STATUS_NOPROBLEMO; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +uint32 cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *entrypath, char *servername, char *sharename, + char *comment, uint32 flags) +{ + prs_struct qbuf, rbuf; + DFS_Q_DFS_ADD q; + DFS_R_DFS_ADD r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_dfs_q_dfs_add(&q, entrypath, servername, sharename, comment, + flags); + + if (!dfs_io_q_dfs_add("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, DFS_ADD, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!dfs_io_r_dfs_add("", &r, &rbuf, 0)) { + goto done; + } + + /* Return result */ + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +uint32 cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *entrypath, char *servername, char *sharename) +{ + prs_struct qbuf, rbuf; + DFS_Q_DFS_REMOVE q; + DFS_R_DFS_REMOVE r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_dfs_q_dfs_remove(&q, entrypath, servername, sharename); + + if (!dfs_io_q_dfs_remove("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, DFS_REMOVE, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!dfs_io_r_dfs_remove("", &r, &rbuf, 0)) { + goto done; + } + + /* Return result */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +uint32 cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *entrypath, char *servername, char *sharename, + uint32 info_level, DFS_INFO_CTR *ctr) + +{ + prs_struct qbuf, rbuf; + DFS_Q_DFS_GET_INFO q; + DFS_R_DFS_GET_INFO r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_dfs_q_dfs_get_info(&q, entrypath, servername, sharename, + info_level); + + if (!dfs_io_q_dfs_get_info("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, DFS_GET_INFO, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!dfs_io_r_dfs_get_info("", &r, &rbuf, 0)) { + goto done; + } + + /* Return result */ + + result = r.status; + *ctr = r.ctr; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Enumerate dfs shares */ + +uint32 cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 info_level, DFS_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + DFS_Q_DFS_ENUM q; + DFS_R_DFS_ENUM r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_dfs_q_dfs_enum(&q, info_level, ctr); + + if (!dfs_io_q_dfs_enum("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, DFS_ENUM, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + r.ctr = ctr; + + if (!dfs_io_r_dfs_enum("", &r, &rbuf, 0)) { + goto done; + } + + /* Return result */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 8888bf6582485433493e76139fa36e4d9f3be3a1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 15 Jun 2001 04:47:05 +0000 Subject: Merged encode_pw_buffer() and nt_owf_genW() functions from TNG branch. (This used to be commit fb80cf2aa13883c6dac461f95bc1000c4881d724) --- source3/libsmb/smbencrypt.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index caf9256787..68af1b4941 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -228,6 +228,39 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } +/*********************************************************** + encode a password buffer +************************************************************/ +BOOL encode_pw_buffer(char buffer[516], const char *new_pass, + int new_pw_len, BOOL nt_pass_set) +{ + generate_random_buffer(buffer, 516, True); + + if (nt_pass_set) + { + /* + * nt passwords are in unicode. last char overwrites NULL + * in ascii_to_unibuf, so use SIVAL *afterwards*. + */ + new_pw_len *= 2; + ascii_to_unistr((uint16 *)&buffer[512 - new_pw_len], new_pass, + new_pw_len); + } + else + { + memcpy(&buffer[512 - new_pw_len], new_pass, new_pw_len); + } + + /* + * The length of the new password is in the last 4 bytes of + * the data buffer. + */ + + SIVAL(buffer, 512, new_pw_len); + + return True; +} + /*********************************************************** decode a password buffer ************************************************************/ @@ -319,3 +352,19 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, } +/* Calculate the NT owfs of a user's password */ +void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]) +{ + char buf[512]; + int i; + + for (i = 0; i < MIN(pwd->uni_str_len, sizeof(buf) / 2); i++) + { + SIVAL(buf, i * 2, pwd->buffer[i]); + } + /* Calculate the MD4 hash (NT compatible) of the password */ + mdfour(nt_p16, buf, pwd->uni_str_len * 2); + + /* clear out local copy of user's password (just being paranoid). */ + ZERO_STRUCT(buf); +} -- cgit From f339bbbc30a7b8a2ee049c1f93d978ed0a2f1238 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 15 Jun 2001 07:13:12 +0000 Subject: Added a unix error code for NT_STATUS_PATH_NOT_COVERED. (This used to be commit 66e62245ea50fe7b996484ca919083eec2edfd14) --- source3/libsmb/clierror.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 6d49986790..77e2be805b 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -175,6 +175,7 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ case NT_STATUS_SHARING_VIOLATION: return EBUSY; case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; + case NT_STATUS_PATH_NOT_COVERED: return ENOENT; } /* for all other cases - a default code */ -- cgit From 7b01c627c62ef6be519110fcd6cb88c86c5cd0ab Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 18 Jun 2001 05:42:18 +0000 Subject: Removed silly Get_Hostbyname() wrapper as DNS names are case-insensitive and the use of this function only increased timeouts when Samba queries a broken DNS server. (This used to be commit 720fea53603b2f99153709e6717ca930ab60ca9f) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7714de760b..465198dfad 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -772,7 +772,7 @@ static BOOL resolve_hosts(const char *name, DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name)); - if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { struct in_addr return_ip; putip((char *)&return_ip,(char *)hp->h_addr); *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); -- cgit From e324e21457b232acb13a06fa5a4b8f363b3dec7c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 18 Jun 2001 08:26:15 +0000 Subject: added a oplock break handler hook to the client code, this allows for more complete testing of oplocks from smbtorture and would also be essential if a client app ever really did want to use oplocks properly (This used to be commit 3d4a3bfacd9ef225aeaab801e5a216d12814b60a) --- source3/libsmb/clientgen.c | 54 +++++----------------------------- source3/libsmb/clioplock.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+), 47 deletions(-) create mode 100644 source3/libsmb/clioplock.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8e00bca82a..e9f55850ac 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -25,7 +25,6 @@ extern int DEBUGLEVEL; -static void cli_process_oplock(struct cli_state *cli); /* * Change the port number used to call on @@ -53,7 +52,11 @@ BOOL cli_receive_smb(struct cli_state *cli) CVAL(cli->inbuf,smb_com) == SMBlockingX && SVAL(cli->inbuf,smb_vwv6) == 0 && SVAL(cli->inbuf,smb_vwv7) == 0) { - if (cli->use_oplocks) cli_process_oplock(cli); + if (cli->oplock_handler) { + int fnum = SVAL(cli->inbuf,smb_vwv2); + unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); + if (!cli->oplock_handler(cli, fnum, level)) return False; + } /* try to prevent loops */ CVAL(cli->inbuf,smb_com) = 0xFF; goto again; @@ -125,51 +128,6 @@ void cli_setup_bcc(struct cli_state *cli, void *p) } -/**************************************************************************** -process an oplock break request from the server -****************************************************************************/ -static void cli_process_oplock(struct cli_state *cli) -{ - char *oldbuf = cli->outbuf; - pstring buf; - int fnum; - unsigned char level; - - fnum = SVAL(cli->inbuf,smb_vwv2); - level = CVAL(cli->inbuf,smb_vwv3+1); - - /* damn, we really need to keep a record of open files so we - can detect a oplock break and a close crossing on the - wire. for now this swallows the errors */ - if (fnum == 0) return; - - /* Ignore level II break to none's. */ - if (level == OPLOCKLEVEL_NONE) - return; - - cli->outbuf = buf; - - memset(buf,'\0',smb_size); - set_message(buf,8,0,True); - - CVAL(buf,smb_com) = SMBlockingX; - SSVAL(buf,smb_tid, cli->cnum); - cli_setup_packet(cli); - SSVAL(buf,smb_vwv0,0xFF); - SSVAL(buf,smb_vwv1,0); - SSVAL(buf,smb_vwv2,fnum); - if (cli->use_level_II_oplocks) - SSVAL(buf,smb_vwv3,0x102); /* levelII oplock break ack */ - else - SSVAL(buf,smb_vwv3,2); /* exclusive oplock break ack */ - SIVAL(buf,smb_vwv4,0); /* timoeut */ - SSVAL(buf,smb_vwv6,0); /* unlockcount */ - SSVAL(buf,smb_vwv7,0); /* lockcount */ - - cli_send_smb(cli); - - cli->outbuf = oldbuf; -} /**************************************************************************** initialise a client structure @@ -219,6 +177,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->max_xmit = cli->bufsize; cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); + cli->oplock_handler = cli_oplock_ack; + if (!cli->outbuf || !cli->inbuf) { return NULL; diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c new file mode 100644 index 0000000000..a52dcf3a3e --- /dev/null +++ b/source3/libsmb/clioplock.c @@ -0,0 +1,72 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + SMB client oplock functions + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" +extern int DEBUGLEVEL; + + +/**************************************************************************** +send an ack for an oplock break request +****************************************************************************/ +BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) +{ + char *oldbuf = cli->outbuf; + pstring buf; + BOOL ret; + + cli->outbuf = buf; + + memset(buf,'\0',smb_size); + set_message(buf,8,0,True); + + CVAL(buf,smb_com) = SMBlockingX; + SSVAL(buf,smb_tid, cli->cnum); + cli_setup_packet(cli); + SSVAL(buf,smb_vwv0,0xFF); + SSVAL(buf,smb_vwv1,0); + SSVAL(buf,smb_vwv2,fnum); + if (level == 1) + SSVAL(buf,smb_vwv3,0x102); /* levelII oplock break ack */ + else + SSVAL(buf,smb_vwv3,2); /* exclusive oplock break ack */ + SIVAL(buf,smb_vwv4,0); /* timoeut */ + SSVAL(buf,smb_vwv6,0); /* unlockcount */ + SSVAL(buf,smb_vwv7,0); /* lockcount */ + + ret = cli_send_smb(cli); + + cli->outbuf = oldbuf; + + return ret; +} + + +/**************************************************************************** +set the oplock handler for a connection +****************************************************************************/ +void cli_oplock_handler(struct cli_state *cli, + BOOL (*handler)(struct cli_state *, int, unsigned char)) +{ + cli->oplock_handler = handler; +} + -- cgit From 0c69d176532ea4ee2fa4c7809db37b00ecfbeeb6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 18 Jun 2001 23:31:22 +0000 Subject: New info level tester. Jeremy. (This used to be commit 9297ae69a7dde878bb4c696f90fbaceb46e18720) --- source3/libsmb/clirap.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 561d717e73..5d41af13f9 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -593,3 +593,46 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return True; } +/**************************************************************************** +send a qfileinfo call +****************************************************************************/ +BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QFILEINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + /* if its a win95 server then fail this - win95 totally screws it + up */ + if (cli->win95) return False; + + param_len = 4; + + memset(param, 0, param_len); + SSVAL(param, 0, fnum); + SSVAL(param, 2, level); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + memcpy(outdata, rdata, data_len); + + if (rdata) free(rdata); + if (rparam) free(rparam); + return True; +} -- cgit From 401a0174009b82f02c0fd45ce50dfa849c67befc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 20 Jun 2001 07:08:28 +0000 Subject: Added cli_samr_delete_dom_user() function. (This used to be commit 2162454d9ea5a07892d0b5d7fc5abe7251b4fa98) --- source3/libsmb/cli_samr.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index f8dd8040c9..29f136427d 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -1074,3 +1074,47 @@ uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Delete domain user */ + +uint32 cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol) +{ + prs_struct qbuf, rbuf; + SAMR_Q_DELETE_DOM_USER q; + SAMR_R_DELETE_DOM_USER r; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_delete_dom_user(&q, user_pol); + + if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 3f1254bee1b3cc8cce1e17be6f0250090f579417 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Jun 2001 19:55:59 +0000 Subject: Fixed W2K SP2 joining a Samba PDC hosted domain. Jermey. (This used to be commit 05a2911403a0710d994a618e72743205a3b0b87a) --- source3/libsmb/smbdes.c | 2 +- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index d0e1c6e85f..7e8a9a5b89 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -381,7 +381,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) s_box[ind] = s_box[j]; s_box[j] = tc; } - for( ind = 0; ind < (val ? 516 : 16); ind++) + for( ind = 0; ind < val; ind++) { unsigned char tc; unsigned char t; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 68af1b4941..b9827333d8 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -223,7 +223,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ DEBUG(100,("make_oem_passwd_hash\n")); dump_data(100, data, 516); #endif - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True); + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); return True; } -- cgit From fda0f83d751a1ea6c731fd6a82484a724a1c6e32 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 21 Jun 2001 01:01:15 +0000 Subject: Following info from TAKAHASHI Motonobu , Samba Users Group Japan, ensure that we don't use dos_to_unix(xx,True), but always use dos_to_unix(xx,False) to prevent overwriting. Jeremy. (This used to be commit 244aec8ea623fec828add3ab09c5003bf32bd5c7) --- source3/libsmb/clirap.c | 17 +++++++++++------ source3/libsmb/clistr.c | 6 ++++-- 2 files changed, 15 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 5d41af13f9..5050caf073 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -179,9 +179,12 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co int type = SVAL(p,14); int comment_offset = IVAL(p,16) & 0xFFFF; char *cmnt = comment_offset?(rdata+comment_offset-converter):""; - dos_to_unix(sname,True); - dos_to_unix(cmnt,True); - fn(sname, type, cmnt, state); + pstring s1, s2; + + pstrcpy(s1, dos_to_unix(sname, False)); + pstrcpy(s2, dos_to_unix(cmnt, False)); + + fn(s1, type, s2, state); } } else { DEBUG(4,("NetShareEnum res=%d\n", res)); @@ -256,13 +259,15 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, char *sname = p; int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; char *cmnt = comment_offset?(rdata+comment_offset):""; + pstring s1, s2; + if (comment_offset < 0 || comment_offset > rdrcnt) continue; stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - dos_to_unix(sname, True); - dos_to_unix(cmnt, True); - fn(sname, stype, cmnt, state); + pstrcpy(s1, dos_to_unix(sname, False)); + pstrcpy(s2, dos_to_unix(cmnt, False)); + fn(s1, stype, s2, state); } } } diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 0225797538..887b5e84c1 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -112,7 +112,8 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len memcpy(dest, src, len); dest[len] = 0; } - if (flags & STR_CONVERT) dos_to_unix(dest,True); + if (flags & STR_CONVERT) + safe_strcpy(dest,dos_to_unix(dest,False),dest_len); return len; } @@ -129,7 +130,8 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len *dest++ = 0; len = src_len; } - if (flags & STR_CONVERT) dos_to_unix(dest,True); + if (flags & STR_CONVERT) + safe_strcpy(dest,dos_to_unix(dest,False),dest_len); return len; } -- cgit From 4ff011d88ef5b79b92d2cea1abe32c93bc03f724 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Jun 2001 05:38:28 +0000 Subject: Added STR_NOALIGN flags to clistr and srvstr fns. Yes, NT actually does send unaligned unicode strings sometimes! Fixed our handling of the workgroup name tacked on the end of the NT1 negprot response (a unaligned unicode) fixed a couple of places where we should be using the message_end fns instead of pre-calculated buffer lengths (This used to be commit 86613493a9b2e56523153486931d0bf8d39beb7a) --- source3/libsmb/cliconnect.c | 6 ++++++ source3/libsmb/clifile.c | 6 ++++-- source3/libsmb/climessage.c | 11 +++++++---- source3/libsmb/clistr.c | 21 +++++++++++++-------- 4 files changed, 30 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 06f283c321..529aa0fef9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -429,6 +429,12 @@ BOOL cli_negprot(struct cli_state *cli) cli->readbraw_supported = True; cli->writebraw_supported = True; } + /* work out if they sent us a workgroup */ + if (smb_buflen(cli->inbuf) > 8) { + clistr_pull(cli, cli->server_domain, + smb_buf(cli->inbuf)+8, sizeof(cli->server_domain), + smb_buflen(cli->inbuf)-8, STR_CONVERT|STR_UNICODE|STR_NOALIGN); + } } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 4002a43c1b..42454b306f 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -243,7 +243,7 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ - p += clistr_align(cli->outbuf, p); + p += clistr_align(cli, p, STR_CONVERT); len = clistr_push(cli, p, fname, -1, STR_CONVERT); p += len; SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); @@ -786,7 +786,7 @@ int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1,strlen(path)+2,True); + set_message(cli->outbuf,1,0,True); CVAL(cli->outbuf,smb_com) = SMBctemp; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -798,6 +798,8 @@ int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) *p++ = 4; p += clistr_push(cli, p, path, -1, STR_TERMINATE | STR_CONVERT); + cli_setup_bcc(cli, p); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { return -1; diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 87f8175459..d46986bfd6 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -71,7 +71,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) char *p; memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,len+3,True); + set_message(cli->outbuf,1,0,True); CVAL(cli->outbuf,smb_com) = SMBsendtxt; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -79,9 +79,12 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) SSVAL(cli->outbuf,smb_vwv0,grp); p = smb_buf(cli->outbuf); - *p = 1; - SSVAL(p,1,len); - memcpy(p+3,msg,len); + *p++ = 1; + SSVAL(p,0,len); p += 2; + memcpy(p,msg,len); + p += len; + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 887b5e84c1..762a24c22c 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -23,6 +23,10 @@ #include "includes.h" +#define UNICODE_FLAG(cli, flags) (!(flags & STR_ASCII) && \ + ((flags & STR_UNICODE || \ + (SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) + /**************************************************************************** copy a string from a char* src to a unicode or ascii dos code page destination choosing unicode or ascii based on the @@ -33,6 +37,7 @@ flags can have: STR_CONVERT means convert from unix to dos codepage STR_UPPER means uppercase in the destination STR_ASCII use ascii even with unicode servers + STR_NOALIGN means don't do alignment dest_len is the maximum length allowed in the destination. If dest_len is -1 then no maxiumum is used ****************************************************************************/ @@ -45,14 +50,14 @@ int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len dest_len = sizeof(pstring); } - if (!(flags & STR_ASCII) && clistr_align(cli->outbuf, dest)) { + if (clistr_align(cli, dest, flags)) { *(char *)dest = 0; dest = (void *)((char *)dest + 1); dest_len--; len++; } - if ((flags & STR_ASCII) || !(SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) { + if (!UNICODE_FLAG(cli, flags)) { /* the server doesn't want unicode */ safe_strcpy(dest, src, dest_len); len = strlen(dest); @@ -83,6 +88,7 @@ flags can have: STR_CONVERT means convert from dos to unix codepage STR_TERMINATE means the string in src is null terminated STR_UNICODE means to force as unicode + STR_NOALIGN means don't do alignment if STR_TERMINATE is set then src_len is ignored src_len is the length of the source area in bytes return the number of bytes occupied by the string in src @@ -95,13 +101,12 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len dest_len = sizeof(pstring); } - if (!(flags & STR_ASCII) && clistr_align(cli->inbuf, src)) { + if (clistr_align(cli, src, flags)) { src = (const void *)((const char *)src + 1); if (src_len > 0) src_len--; } - if ((flags & STR_ASCII) || - (!(flags & STR_UNICODE) && !(SVAL(cli->inbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS))) { + if (!UNICODE_FLAG(cli, flags)) { /* the server doesn't want unicode */ if (flags & STR_TERMINATE) { safe_strcpy(dest, src, dest_len); @@ -141,8 +146,8 @@ return an alignment of either 0 or 1 if unicode is not negotiated then return 0 otherwise return 1 if offset is off ****************************************************************************/ -int clistr_align(const void *buf, const void *p) +int clistr_align(struct cli_state *cli, const void *p, int flags) { - if (!(SVAL(buf, smb_flg2) & FLAGS2_UNICODE_STRINGS)) return 0; - return PTR_DIFF(p, buf) & 1; + if ((flags & STR_NOALIGN) || !UNICODE_FLAG(cli, flags)) return 0; + return PTR_DIFF(p, cli->outbuf) & 1; } -- cgit From 91b8a8d1d21b810b6aca44ce647837669efd6dcf Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Jun 2001 09:10:42 +0000 Subject: next_token() was supposed to be a reentrant replacement for strtok(), but the code suffered from bitrot and is not now reentrant. That means we can get bizarre behaviour i've fixed this by making next_token() reentrant and creating a next_token_nr() that is a small non-reentrant wrapper for those lumps of code (mostly smbclient) that have come to rely on the non-reentrant behaviour (This used to be commit 674ee2f1d12b0afc164a9e9072758fd1c5e54df7) --- source3/libsmb/clireadwrite.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 6c52d2b776..9ee63270df 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -139,9 +139,9 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 memset(cli->inbuf,'\0',smb_size); if (size > 0xFFFF) - set_message(cli->outbuf,14,size,True); + set_message(cli->outbuf,14,0,True); else - set_message(cli->outbuf,12,size,True); + set_message(cli->outbuf,12,0,True); CVAL(cli->outbuf,smb_com) = SMBwriteX; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -162,6 +162,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); memcpy(p, buf, size); + cli_setup_bcc(cli, p+size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); @@ -240,7 +241,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,5, 3 + size,True); + set_message(cli->outbuf,5, 0,True); CVAL(cli->outbuf,smb_com) = SMBwrite; SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -253,8 +254,10 @@ ssize_t cli_smbwrite(struct cli_state *cli, p = smb_buf(cli->outbuf); *p++ = 1; - SSVAL(p, 0, size); - memcpy(p+2, buf, size); + SSVAL(p, 0, size); p += 2; + memcpy(p, buf, size); p += size; + + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { -- cgit From 6fdffd9b6c6150793d86114f18c2239a53625e73 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Jun 2001 00:42:53 +0000 Subject: added some comments to make the cli read code clearer (This used to be commit bbfbe03cc6166c23c42a704b5acaa19cbdbc39ce) --- source3/libsmb/clireadwrite.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 9ee63270df..70266a2d9a 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -55,8 +55,6 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t { char *p; int total = -1; - int issued=0; - int received=0; /* * There is a problem in this code when mpx is more than one. * for some reason files can get corrupted when being read. @@ -68,12 +66,24 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t #else int mpx = 1; #endif - int block = (cli->max_xmit - (smb_size+32)) & ~1023; + int block; int mid; - int blocks = (size + (block-1)) / block; + int blocks; + /* issued is the number of readX requests we have sent so far */ + int issued=0; + /* received is the number of readX replies we have received */ + int received=0; + /* maybe its a very silly request? */ if (size == 0) return 0; + /* set block to the maximum size we can handle in one readX, + rounded down to a multiple of 1024 */ + block = (cli->max_xmit - (smb_size+32)) & ~1023; + + /* work out how many readX calls we will need in total */ + blocks = (size + (block-1)) / block; + while (received < blocks) { int size2; -- cgit From ff5a18ad3e5a9a4dac6947e3551126c8ea9077dd Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 22 Jun 2001 01:09:40 +0000 Subject: Merged cli_read_one() function for reading DCE/RPC reply fragments. (This used to be commit 9e074bc2bf2df34048b67457623bb8219fb1e4d6) --- source3/libsmb/clireadwrite.c | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 70266a2d9a..f5ddc77c8f 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -48,6 +48,52 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, cli_send_smb(cli); } +/**************************************************************************** + issue a single SMBread and wait for a reply. This function only called + in the rpc pipe code to read dce/rpc reply fragments. +****************************************************************************/ +size_t cli_read_one(struct cli_state *cli, int fnum, char *buf, off_t offset, + size_t size) +{ + uint32 ecode; + uint8 eclass; + char *p; + int size2; + + if (size == 0) + return 0; + + /* Issue a read and receive a reply */ + + cli_issue_read(cli, fnum, offset, size, 0); + + if (!cli_receive_smb(cli)) + return -1; + + size2 = SVAL(cli->inbuf, smb_vwv5); + + /* Check for error. Because the client library doesn't support + STATUS32, we need to check for and ignore the more data error + for pipe support. */ + + if (cli_error(cli, &eclass, &ecode, NULL) && + (eclass != ERRDOS && ecode != ERRmoredata)) { + return -1; + } + + if (size2 > size) { + DEBUG(5,("server returned more than we wanted!\n")); + return -1; + } + + /* Copy data into buffer */ + + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf, p, size2); + + return size2; +} + /**************************************************************************** read from a file ****************************************************************************/ -- cgit From df07df9ffce69551105dfd1334d33f69de4442b7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 22 Jun 2001 02:15:02 +0000 Subject: Cleanup of cli_lsa_enum_trust_dom(). talloc() doesn't like attempts to allocate 0 bytes. (This used to be commit 465994cfbca72649474345bc057d436961cccf97) --- source3/libsmb/cli_lsarpc.c | 54 ++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 00c5ac9a16..88f0dff225 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -521,7 +521,12 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_NOPROBLEMO && result != 0x8000001a) { + /* For some undocumented reason this function sometimes returns + 0x8000001a (NT_STATUS_UNABLE_TO_FREE_VM) so we ignore it and + pretend everything is OK. */ + + if (result != NT_STATUS_NOPROBLEMO && + result != NT_STATUS_UNABLE_TO_FREE_VM) { /* An actual error ocured */ @@ -532,33 +537,42 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if (!((*domain_names) = (char **)talloc(mem_ctx, sizeof(char *) * - r.num_domains))) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if (r.num_domains) { - if (!((*domain_sids) = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * - r.num_domains))) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + /* Allocate memory for trusted domain names and sids */ - for (i = 0; i < r.num_domains; i++) { - fstring tmp; + *domain_names = (char **)talloc(mem_ctx, sizeof(char *) * + r.num_domains); - unistr2_to_ascii(tmp, &r.uni_domain_name[i], sizeof(tmp) - 1); - (*domain_names)[i] = strdup(tmp); - sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); + if (!*domain_names) { + DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + *domain_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * + r.num_domains); + if (!domain_sids) { + DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Copy across names and sids */ + + for (i = 0; i < r.num_domains; i++) { + fstring tmp; + + unistr2_to_ascii(tmp, &r.uni_domain_name[i], + sizeof(tmp) - 1); + (*domain_names)[i] = strdup(tmp); + sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); + } } *num_domains = r.num_domains; *enum_ctx = r.enum_context; - lsa_free_r_enum_trust_dom(&r); - done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); -- cgit From 868d010aa1b614109b54928e46eb626a1d320a2d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 22 Jun 2001 15:14:45 +0000 Subject: added the ability to test smbd safely as an ordinary user. The way it works is that libsmb/ creates a local tcp socket then launches smbd as a subprocess attached to that socket. smbd thinks it is being launched from inetd. to use it do the following: - compile with -DSMB_REGRESSION_TEST - run like this (also works with smbtorture etc) export SMBD_TEST=1 export LIBSMB_PROG=bin/smbd smbclient //server/share -Uuser%pass obviously you need to setup a smb.conf etc. Using --prefix to configure is useful. The aim of all this stuff is to add a decent set of regression tests to the build farm, so we know if smbd actually runs correctly on all the platforms, not just builds. We can run smbtorture, masktest, locktest etc, plus a bunch of smbclient scripts and any new tests we write. This doesn't help much with nmbd (at least not yet) but its a good start. (This used to be commit 7e8e6ae9a88c4d2587eb4e7f0501cd71bd36ebb2) --- source3/libsmb/cliconnect.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 529aa0fef9..034208f3b2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -558,7 +558,6 @@ retry: return(True); } - /**************************************************************************** open the client sockets ****************************************************************************/ @@ -580,8 +579,15 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) if (cli->port == 0) cli->port = 139; /* Set to default */ - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - cli->port, cli->timeout); +#ifdef SMB_REGRESSION_TEST + if (getenv("LIBSMB_PROG")) { + cli->fd = sock_exec(getenv("LIBSMB_PROG")); + } else +#endif + { + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + cli->port, cli->timeout); + } if (cli->fd == -1) return False; -- cgit From 8b79a473faf2ff25acb220500158920490c71576 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Jun 2001 00:46:34 +0000 Subject: - make the regresison test mode code build in by default. This should allow us to have test targets without special configure options - fixed make proto so that it actually does something (This used to be commit 55109a752578e9389d853cb27ec17c2114ecff77) --- source3/libsmb/cliconnect.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 034208f3b2..67eef52583 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -579,12 +579,9 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) if (cli->port == 0) cli->port = 139; /* Set to default */ -#ifdef SMB_REGRESSION_TEST if (getenv("LIBSMB_PROG")) { cli->fd = sock_exec(getenv("LIBSMB_PROG")); - } else -#endif - { + } else { cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, cli->port, cli->timeout); } -- cgit From b95a294a0879e800e816281a80d0074224cd8cd4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 25 Jun 2001 02:53:13 +0000 Subject: fixed usage of socklen_t and also tidied up SIG_ATOMIC_T, using a typedef instead of a define (This used to be commit e2ecff419fdc0a0dc7551b33b377dc11061ef2a3) --- source3/libsmb/clidgram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 1ac2439b08..fc1453dce1 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -145,7 +145,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) struct in_addr sendto_ip, my_ip; int dgram_sock; struct sockaddr_in sock_out; - int name_size; + socklen_t name_size; if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) { -- cgit From 0c563186fb143e047180e3c296ea024e49f948b8 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 26 Jun 2001 06:26:05 +0000 Subject: Put an 0x in front of a hex number. (This used to be commit a48d480ce986ff1c00f2c17f30f23723ce0bb044) --- source3/libsmb/nterr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 17bb825219..36dd65cda2 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -523,7 +523,7 @@ BOOL get_safe_nt_error_msg(uint32 nt_code,char *msg, size_t len) { int idx = 0; - slprintf(msg, len-1, "NT code %08x", nt_code); + slprintf(msg, len-1, "NT code 0x%08x", nt_code); while (nt_errs[idx].nt_errstr != NULL) { -- cgit From 8831dcd59de347c9ca000ee9f3b6331399bbc425 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 27 Jun 2001 04:06:13 +0000 Subject: Fix a stupid typo ... (This used to be commit 8a873b5dfb52393541c36fea0a5082771a6c8d63) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index cdf26e6b23..bc70dc520b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -121,7 +121,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, if (*p == '/') { - strncpy(server, lp_workgroup(), 16); /* FIXME: Danger here */ + strncpy(server, (char *)lp_workgroup(), 16); /* FIXME: Danger here */ return 0; } @@ -412,7 +412,7 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) } - if (smbc_initialize) { /* Don't go through this if we have already done it */ + if (smbc_initialized) { /* Don't go through this if we have already done it */ return 0; -- cgit From 5fb9a869b7e56ca567eae43d85079c37f246daec Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Jun 2001 00:22:22 +0000 Subject: Use a logical cli_read(), removed the cli_read_one() hack. Jeremy. (This used to be commit 2999eab5abe86bf08e693800c01ad544f04e4d6c) --- source3/libsmb/clireadwrite.c | 185 ++++++++++++++---------------------------- 1 file changed, 61 insertions(+), 124 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index f5ddc77c8f..54d3fd18e3 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -26,7 +26,8 @@ /**************************************************************************** issue a single SMBread and don't wait for a reply ****************************************************************************/ -static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, + +static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { memset(cli->outbuf,'\0',smb_size); @@ -45,148 +46,89 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - cli_send_smb(cli); + return cli_send_smb(cli); } /**************************************************************************** - issue a single SMBread and wait for a reply. This function only called - in the rpc pipe code to read dce/rpc reply fragments. + Read size bytes at offset offset using SMBreadX. ****************************************************************************/ -size_t cli_read_one(struct cli_state *cli, int fnum, char *buf, off_t offset, - size_t size) + +ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { uint32 ecode; uint8 eclass; char *p; int size2; + int readsize; + ssize_t total = 0; if (size == 0) return 0; - /* Issue a read and receive a reply */ - - cli_issue_read(cli, fnum, offset, size, 0); + /* + * Set readsize to the maximum size we can handle in one readX, + * rounded down to a multiple of 1024. + */ - if (!cli_receive_smb(cli)) - return -1; + readsize = (cli->max_xmit - (smb_size+32)) & ~1023; + if (readsize > size ) + readsize = size; - size2 = SVAL(cli->inbuf, smb_vwv5); + while (total < size) { - /* Check for error. Because the client library doesn't support - STATUS32, we need to check for and ignore the more data error - for pipe support. */ + /* Issue a read and receive a reply */ - if (cli_error(cli, &eclass, &ecode, NULL) && - (eclass != ERRDOS && ecode != ERRmoredata)) { - return -1; - } - - if (size2 > size) { - DEBUG(5,("server returned more than we wanted!\n")); - return -1; - } - - /* Copy data into buffer */ - - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - memcpy(buf, p, size2); - - return size2; -} - -/**************************************************************************** - read from a file -****************************************************************************/ -size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) -{ - char *p; - int total = -1; -/* - * There is a problem in this code when mpx is more than one. - * for some reason files can get corrupted when being read. - * Until we understand this fully I am serializing reads (one - * read/one reply) for now. JRA. - */ -#if 0 - int mpx = MAX(cli->max_mux-1, 1); -#else - int mpx = 1; -#endif - int block; - int mid; - int blocks; - /* issued is the number of readX requests we have sent so far */ - int issued=0; - /* received is the number of readX replies we have received */ - int received=0; - - /* maybe its a very silly request? */ - if (size == 0) return 0; - - /* set block to the maximum size we can handle in one readX, - rounded down to a multiple of 1024 */ - block = (cli->max_xmit - (smb_size+32)) & ~1023; - - /* work out how many readX calls we will need in total */ - blocks = (size + (block-1)) / block; + if (!cli_issue_read(cli, fnum, offset, readsize, 0)) + return -1; - while (received < blocks) { - int size2; + if (!cli_receive_smb(cli)) + return -1; - while (issued - received < mpx && issued < blocks) { - int size1 = MIN(block, size-issued*block); - cli_issue_read(cli, fnum, offset+issued*block, size1, issued); - issued++; - } + /* + * Check for error. Because the client library doesn't support + * STATUS32, we need to check for and ignore the more data error + * for pipe support. + */ - if (!cli_receive_smb(cli)) { - return total; + if (cli_error(cli, &eclass, &ecode, NULL) && + (eclass != ERRDOS && ecode != ERRmoredata)) { + return -1; } - received++; - mid = SVAL(cli->inbuf, smb_mid) - cli->mid; size2 = SVAL(cli->inbuf, smb_vwv5); - if (CVAL(cli->inbuf,smb_rcls) != 0) { - blocks = MIN(blocks, mid-1); - continue; - } - - if (size2 <= 0) { - blocks = MIN(blocks, mid-1); - /* this distinguishes EOF from an error */ - total = MAX(total, 0); - continue; - } - - if (size2 > block) { - DEBUG(0,("server returned more than we wanted!\n")); + if (size2 > readsize) { + DEBUG(5,("server returned more than we wanted!\n")); return -1; - } - if (mid >= issued) { - DEBUG(0,("invalid mid from server!\n")); + } else if (size2 < 0) { + DEBUG(5,("read return < 0!\n")); return -1; } + + /* Copy data into buffer */ + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf + total, p, size2); - memcpy(buf+mid*block, p, size2); + total += size2; + offset += size2; - total = MAX(total, mid*block + size2); - } + /* + * If the server returned less than we asked for we're at EOF. + */ - while (received < issued) { - cli_receive_smb(cli); - received++; + if (size2 < readsize) + break; } - + return total; } - /**************************************************************************** issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, + +static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, size_t size, int i) { char *p; @@ -223,7 +165,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_mid,cli->mid + i); show_msg(cli->outbuf); - cli_send_smb(cli); + return cli_send_smb(cli); } /**************************************************************************** @@ -233,6 +175,7 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 0x0004 use raw named pipe protocol 0x0008 start of message mode named pipe protocol ****************************************************************************/ + ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, char *buf, off_t offset, size_t size) @@ -246,45 +189,39 @@ ssize_t cli_write(struct cli_state *cli, while (received < blocks) { - while ((issued - received < mpx) && (issued < blocks)) - { + while ((issued - received < mpx) && (issued < blocks)) { int bsent = issued * block; int size1 = MIN(block, size - bsent); - cli_issue_write(cli, fnum, offset + bsent, + if (!cli_issue_write(cli, fnum, offset + bsent, write_mode, buf + bsent, - size1, issued); + size1, issued)) + return -1; issued++; } if (!cli_receive_smb(cli)) - { return bwritten; - } received++; if (CVAL(cli->inbuf,smb_rcls) != 0) - { break; - } bwritten += SVAL(cli->inbuf, smb_vwv2); } while (received < issued && cli_receive_smb(cli)) - { received++; - } return bwritten; } - /**************************************************************************** write to a file using a SMBwrite and not bypassing 0 byte writes ****************************************************************************/ + ssize_t cli_smbwrite(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size1) { @@ -315,17 +252,18 @@ ssize_t cli_smbwrite(struct cli_state *cli, cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { + if (!cli_send_smb(cli)) + return -1; + + if (!cli_receive_smb(cli)) return -1; - } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (CVAL(cli->inbuf,smb_rcls) != 0) return -1; - } size = SVAL(cli->inbuf,smb_vwv0); - if (size == 0) break; + if (size == 0) + break; size1 -= size; total += size; @@ -333,4 +271,3 @@ ssize_t cli_smbwrite(struct cli_state *cli, return total; } - -- cgit From 4592d107fc01c8cb46f99843529d145d268b35da Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 1 Jul 2001 13:18:35 +0000 Subject: cli_read() was reading too many bytes. (This used to be commit ba79d2a030b9ae087f0cc4248baa6cf6bee112fb) --- source3/libsmb/clireadwrite.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 54d3fd18e3..458532cb2e 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -71,10 +71,9 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ */ readsize = (cli->max_xmit - (smb_size+32)) & ~1023; - if (readsize > size ) - readsize = size; while (total < size) { + readsize = MIN(readsize, size-total); /* Issue a read and receive a reply */ -- cgit From 82b76931cb62ea952fb0a4091880a8e0188530c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 2 Jul 2001 00:33:15 +0000 Subject: Insure caught the fact that PTRDIFFs were being done between two unrelated pointers. Jeremy. (This used to be commit 15c64199cb29e2fca6ee7353673dbb3f962e0e24) --- source3/libsmb/clifile.c | 2 +- source3/libsmb/clistr.c | 20 ++++++++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 42454b306f..2c4eef9bbe 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -243,7 +243,7 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ - p += clistr_align(cli, p, STR_CONVERT); + p += clistr_align_out(cli, p, STR_CONVERT); len = clistr_push(cli, p, fname, -1, STR_CONVERT); p += len; SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 762a24c22c..6dd3b751b4 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -50,7 +50,7 @@ int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len dest_len = sizeof(pstring); } - if (clistr_align(cli, dest, flags)) { + if (clistr_align_out(cli, dest, flags)) { *(char *)dest = 0; dest = (void *)((char *)dest + 1); dest_len--; @@ -101,7 +101,7 @@ int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len dest_len = sizeof(pstring); } - if (clistr_align(cli, src, flags)) { + if (clistr_align_in(cli, src, flags)) { src = (const void *)((const char *)src + 1); if (src_len > 0) src_len--; } @@ -146,8 +146,20 @@ return an alignment of either 0 or 1 if unicode is not negotiated then return 0 otherwise return 1 if offset is off ****************************************************************************/ -int clistr_align(struct cli_state *cli, const void *p, int flags) +static int clistr_align(struct cli_state *cli, char *buf, const void *p, int flags) { if ((flags & STR_NOALIGN) || !UNICODE_FLAG(cli, flags)) return 0; - return PTR_DIFF(p, cli->outbuf) & 1; + return PTR_DIFF(p, buf) & 1; } + +int clistr_align_out(struct cli_state *cli, const void *p, int flags) +{ + return clistr_align(cli, cli->outbuf, p, flags); +} + +int clistr_align_in(struct cli_state *cli, const void *p, int flags) +{ + return clistr_align(cli, cli->inbuf, p, flags); +} + + -- cgit From 75e33b78036438b2a07eed3cc5a1e591103b7c9c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 3 Jul 2001 04:09:09 +0000 Subject: Fixed incorrect comment for cli_NetServerEnum() (This used to be commit 0a505e50a5059930de6583918f25ef84af53de0e) --- source3/libsmb/clirap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 5050caf073..253d192aba 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -203,11 +203,11 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co /**************************************************************************** -call a NetServerEnum for the specified workgroup and servertype mask. -This function then calls the specified callback function for each name returned. +call a NetServerEnum for the specified workgroup and servertype mask. This +function then calls the specified callback function for each name returned. -The callback function takes 3 arguments: the machine name, the server type and -the comment. +The callback function takes 4 arguments: the machine name, the server type, +the comment and a state pointer. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, void (*fn)(const char *, uint32, const char *, void *), -- cgit From 87fbb7092b8f8b2f0db0f361c3d625e19de57cd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:15:53 +0000 Subject: The big character set handling changeover! This commit gets rid of all our old codepage handling and replaces it with iconv. All internal strings in Samba are now in "unix" charset, which may be multi-byte. See internals.doc and my posting to samba-technical for a more complete explanation. (This used to be commit debb471267960e56005a741817ebd227ecfc512a) --- source3/libsmb/cli_lsarpc.c | 7 +-- source3/libsmb/cliconnect.c | 53 ++++++++--------- source3/libsmb/clierror.c | 2 +- source3/libsmb/clifile.c | 26 ++++----- source3/libsmb/clilist.c | 27 ++++----- source3/libsmb/climessage.c | 6 +- source3/libsmb/clirap.c | 26 ++++----- source3/libsmb/clistr.c | 133 ++---------------------------------------- source3/libsmb/clitrans.c | 2 +- source3/libsmb/libsmbclient.c | 4 -- source3/libsmb/namequery.c | 7 +-- source3/libsmb/nmblib.c | 4 +- source3/libsmb/pwd_cache.c | 14 ++--- source3/libsmb/smbencrypt.c | 41 ++++--------- source3/libsmb/smberr.c | 8 ++- 15 files changed, 94 insertions(+), 266 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 88f0dff225..61afeb7f38 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -268,11 +268,8 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Translate optimised name through domain index array */ if (dom_idx != 0xffffffff) { - unistr2_to_ascii(dom_name, - &ref.ref_dom[dom_idx].uni_dom_name, - sizeof(dom_name)- 1); - unistr2_to_ascii(name, &t_names.uni_name[i], - sizeof(name) - 1); + pull_ascii_fstring(dom_name, &ref.ref_dom[dom_idx].uni_dom_name); + pull_ascii_fstring(name, &t_names.uni_name[i]); slprintf(full_name, sizeof(full_name) - 1, "%s%s%s", dom_name, dom_name[0] ? diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 67eef52583..7ec0627682 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -26,7 +26,7 @@ static struct { int prot; - char *name; + const char *name; } prots[] = { @@ -84,8 +84,7 @@ BOOL cli_session_setup(struct cli_state *cli, */ passlen = 24; ntpasslen = 24; - fstrcpy(pword, pass); - unix_to_dos(pword,True); + clistr_push(cli, pword, pass, -1, STR_TERMINATE); fstrcpy(ntpword, ntpass);; SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword); SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword); @@ -104,7 +103,7 @@ BOOL cli_session_setup(struct cli_state *cli, /* * Plaintext mode needed, assume plaintext supplied. */ - passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); fstrcpy(ntpword, ""); ntpasslen = 0; } @@ -136,7 +135,7 @@ BOOL cli_session_setup(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_UPPER|STR_TERMINATE); + p += clistr_push(cli, p, user, -1, STR_UPPER|STR_TERMINATE); cli_setup_bcc(cli, p); } else @@ -167,10 +166,10 @@ BOOL cli_session_setup(struct cli_state *cli, p += SVAL(cli->outbuf,smb_vwv7); memcpy(p,ntpword,ntpasslen); p += SVAL(cli->outbuf,smb_vwv8); - p += clistr_push(cli, p, user, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, workgroup, -1, STR_CONVERT|STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, "Unix", -1, STR_CONVERT|STR_TERMINATE); - p += clistr_push(cli, p, "Samba", -1, STR_CONVERT|STR_TERMINATE); + p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); } @@ -193,9 +192,9 @@ BOOL cli_session_setup(struct cli_state *cli, * info. */ char *q = smb_buf(cli->inbuf); - q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); - q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); - q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, STR_TERMINATE|STR_CONVERT); + q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, STR_TERMINATE); + q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, STR_TERMINATE); + q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, STR_TERMINATE); } fstrcpy(cli->user_name, user); @@ -227,7 +226,7 @@ BOOL cli_ulogoff(struct cli_state *cli) send a tconX ****************************************************************************/ BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pass, int passlen) + const char *share, const char *dev, const char *pass, int passlen) { fstring fullshare, pword, dos_pword; char *p; @@ -247,15 +246,15 @@ BOOL cli_send_tconX(struct cli_state *cli, * Non-encrypted passwords - convert to DOS codepage before encryption. */ passlen = 24; - fstrcpy(dos_pword,pass); - unix_to_dos(dos_pword,True); + clistr_push(cli, dos_pword, pass, -1, STR_TERMINATE); + SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); } else { if((cli->sec_mode & 3) == 0) { /* * Non-encrypted passwords - convert to DOS codepage before using. */ - passlen = clistr_push(cli, pword, pass, -1, STR_CONVERT|STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); } else { memcpy(pword, pass, passlen); } @@ -263,8 +262,6 @@ BOOL cli_send_tconX(struct cli_state *cli, slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); - unix_to_dos(fullshare, True); - strupper(fullshare); set_message(cli->outbuf,4, 0, True); CVAL(cli->outbuf,smb_com) = SMBtconX; @@ -276,7 +273,7 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p += clistr_push(cli, p, fullshare, -1, STR_CONVERT | STR_TERMINATE); + p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER); fstrcpy(p, dev); p += strlen(dev)+1; cli_setup_bcc(cli, p); @@ -294,7 +291,7 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->dev, "A:"); if (cli->protocol >= PROTOCOL_NT1) { - clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE | STR_CONVERT); + clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE); } if (strcasecmp(share,"IPC$")==0) { @@ -350,9 +347,7 @@ void cli_negprot_send(struct cli_state *cli) prots[numprots].name && prots[numprots].prot<=cli->protocol; numprots++) { *p++ = 2; - pstrcpy(p,prots[numprots].name); - unix_to_dos(p,True); - p += strlen(p) + 1; + p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE); } CVAL(cli->outbuf,smb_com) = SMBnegprot; @@ -389,9 +384,7 @@ BOOL cli_negprot(struct cli_state *cli) prots[numprots].name && prots[numprots].prot<=cli->protocol; numprots++) { *p++ = 2; - pstrcpy(p,prots[numprots].name); - unix_to_dos(p,True); - p += strlen(p) + 1; + p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE); } CVAL(cli->outbuf,smb_com) = SMBnegprot; @@ -433,7 +426,7 @@ BOOL cli_negprot(struct cli_state *cli) if (smb_buflen(cli->inbuf) > 8) { clistr_pull(cli, cli->server_domain, smb_buf(cli->inbuf)+8, sizeof(cli->server_domain), - smb_buflen(cli->inbuf)-8, STR_CONVERT|STR_UNICODE|STR_NOALIGN); + smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); @@ -762,9 +755,9 @@ BOOL cli_establish_connection(struct cli_state *cli, if (*cli->server_domain || *cli->server_os || *cli->server_type) { DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - cli->server_domain, - cli->server_os, - cli->server_type)); + cli->server_domain, + cli->server_os, + cli->server_type)); } if (do_tcon) diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 77e2be805b..f533eabb0b 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -120,7 +120,7 @@ char *cli_errstr(struct cli_state *cli) { if (rap_errmap[i].err == cli->rap_error) { - fstrcpy( error_message, rap_errmap[i].message); + fstrcpy(error_message, rap_errmap[i].message); break; } } diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 2c4eef9bbe..215c500c30 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -44,10 +44,10 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) p = smb_buf(cli->outbuf); *p++ = 4; p += clistr_push(cli, p, fname_src, -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); *p++ = 4; p += clistr_push(cli, p, fname_dst, -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); cli_setup_bcc(cli, p); @@ -83,7 +83,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); @@ -116,7 +116,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, dname, -1, STR_CONVERT|STR_TERMINATE); + p += clistr_push(cli, p, dname, -1, 0); cli_setup_bcc(cli, p); @@ -150,7 +150,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, dname, -1, STR_TERMINATE|STR_CONVERT); + p += clistr_push(cli, p, dname, -1, STR_TERMINATE); cli_setup_bcc(cli, p); @@ -243,8 +243,8 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ - p += clistr_align_out(cli, p, STR_CONVERT); - len = clistr_push(cli, p, fname, -1, STR_CONVERT); + p += clistr_align_out(cli, p, 0); + len = clistr_push(cli, p, fname, -1, 0); p += len; SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); /* sigh. this copes with broken netapp filer behaviour */ @@ -336,7 +336,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) } p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE); cli_setup_bcc(cli, p); @@ -648,7 +648,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE); cli_setup_bcc(cli, p); @@ -699,7 +699,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname, -1, STR_TERMINATE | STR_CONVERT); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE); *p++ = 4; cli_setup_bcc(cli, p); @@ -736,7 +736,7 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, path2, -1, STR_TERMINATE | STR_CONVERT); + p += clistr_push(cli, p, path2, -1, STR_TERMINATE); cli_setup_bcc(cli, p); @@ -796,7 +796,7 @@ int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, path, -1, STR_TERMINATE | STR_CONVERT); + p += clistr_push(cli, p, path, -1, STR_TERMINATE); cli_setup_bcc(cli, p); @@ -812,7 +812,7 @@ int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) if (tmp_path) { pstring path2; clistr_pull(cli, path2, smb_buf(cli->inbuf)+1, - sizeof(path2), -1, STR_TERMINATE | STR_CONVERT); + sizeof(path2), -1, STR_TERMINATE); *tmp_path = strdup(path2); } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 9080a9c221..b08cc08f01 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -51,7 +51,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+27, sizeof(finfo->name), -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } return(28 + CVAL(p,26)); @@ -66,7 +66,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+31, sizeof(finfo->name), -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } return(32 + CVAL(p,30)); @@ -82,7 +82,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+33, sizeof(finfo->name), -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } return(SVAL(p,4)+4); @@ -97,7 +97,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+37, sizeof(finfo->name), -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } return(SVAL(p,4)+4); @@ -135,7 +135,7 @@ static int interpret_long_filename(struct cli_state *cli, p += 2; { /* stupid NT bugs. grr */ - int flags = STR_CONVERT; + int flags = 0; if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), @@ -144,8 +144,7 @@ static int interpret_long_filename(struct cli_state *cli, p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), - namelen, - STR_CONVERT); + namelen, 0); return(ret); } return(SVAL(p,0)); @@ -203,7 +202,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,8,0); p = param+12; p += clistr_push(cli, param+12, mask, -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -213,7 +212,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ p = param+12; p += clistr_push(cli, param+12, mask, -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } param_len = PTR_DIFF(p, param); @@ -271,15 +270,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, clistr_pull(cli, mask, p+ff_lastname, sizeof(mask), data_len-ff_lastname, - STR_TERMINATE | - STR_CONVERT); + STR_TERMINATE); break; case 1: clistr_pull(cli, mask, p+ff_lastname+1, sizeof(mask), -1, - STR_TERMINATE | - STR_CONVERT); + STR_TERMINATE); break; } } else { @@ -345,7 +342,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); - clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_CONVERT|STR_ASCII); + clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); @@ -392,7 +389,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE|STR_CONVERT); + p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE); *p++ = 5; if (first) { SSVAL(p,0,0); diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index d46986bfd6..e0a308104b 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -41,11 +41,9 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, username, -1, - STR_TERMINATE|STR_CONVERT); + p += clistr_push(cli, p, username, -1, STR_TERMINATE); *p++ = 4; - p += clistr_push(cli, p, host, -1, - STR_TERMINATE|STR_CONVERT); + p += clistr_push(cli, p, host, -1, STR_TERMINATE); cli_setup_bcc(cli, p); diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 253d192aba..c16fe2d08d 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -181,8 +181,8 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co char *cmnt = comment_offset?(rdata+comment_offset-converter):""; pstring s1, s2; - pstrcpy(s1, dos_to_unix(sname, False)); - pstrcpy(s2, dos_to_unix(cmnt, False)); + pull_ascii_pstring(s1, sname); + pull_ascii_pstring(s2, cmnt); fn(s1, type, s2, state); } @@ -237,8 +237,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - p += clistr_push(cli, p, workgroup, -1, - STR_TERMINATE | STR_CONVERT | STR_ASCII); + p += push_pstring(p, workgroup); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ @@ -265,8 +264,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - pstrcpy(s1, dos_to_unix(sname, False)); - pstrcpy(s2, dos_to_unix(cmnt, False)); + pull_ascii_pstring(s1, sname); + pull_ascii_pstring(s2, cmnt); fn(s1, stype, s2, state); } } @@ -325,13 +324,10 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char * use this as the key to make_oem_passwd_hash(). */ memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); - fstrcpy(upper_case_old_pw, old_password); - unix_to_dos(upper_case_old_pw,True); - strupper(upper_case_old_pw); + clistr_push(cli, upper_case_old_pw, old_password, -1,STR_TERMINATE|STR_UPPER); E_P16((uchar *)upper_case_old_pw, old_pw_hash); - pstrcpy(dos_new_password, new_password); - unix_to_dos(dos_new_password, True); + clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE); if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) return False; @@ -340,9 +336,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char * Now place the old password hash in the data. */ memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); - fstrcpy(upper_case_new_pw, new_password); - unix_to_dos(upper_case_new_pw,True); - strupper(upper_case_new_pw); + clistr_push(cli, upper_case_new_pw, new_password, -1, STR_TERMINATE|STR_UPPER); E_P16((uchar *)upper_case_new_pw, new_pw_hash); @@ -399,7 +393,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, memset(p, 0, 6); SSVAL(p, 0, SMB_INFO_STANDARD); p += 6; - p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE | STR_CONVERT); + p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); @@ -475,7 +469,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO); p += 6; - p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE | STR_CONVERT); + p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 6dd3b751b4..baec3e5da8 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -19,147 +19,26 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" -#define UNICODE_FLAG(cli, flags) (!(flags & STR_ASCII) && \ - ((flags & STR_UNICODE || \ - (SVAL(cli->outbuf, smb_flg2) & FLAGS2_UNICODE_STRINGS)))) - -/**************************************************************************** -copy a string from a char* src to a unicode or ascii -dos code page destination choosing unicode or ascii based on the -cli->capabilities flag -return the number of bytes occupied by the string in the destination -flags can have: - STR_TERMINATE means include the null termination - STR_CONVERT means convert from unix to dos codepage - STR_UPPER means uppercase in the destination - STR_ASCII use ascii even with unicode servers - STR_NOALIGN means don't do alignment -dest_len is the maximum length allowed in the destination. If dest_len -is -1 then no maxiumum is used -****************************************************************************/ int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags) { - int len=0; - - /* treat a pstring as "unlimited" length */ - if (dest_len == -1) { - dest_len = sizeof(pstring); - } - - if (clistr_align_out(cli, dest, flags)) { - *(char *)dest = 0; - dest = (void *)((char *)dest + 1); - dest_len--; - len++; - } - - if (!UNICODE_FLAG(cli, flags)) { - /* the server doesn't want unicode */ - safe_strcpy(dest, src, dest_len); - len = strlen(dest); - if (flags & STR_TERMINATE) len++; - if (flags & STR_CONVERT) unix_to_dos(dest,True); - if (flags & STR_UPPER) strupper(dest); - return len; - } - - /* the server likes unicode. give it the works */ - if (flags & STR_CONVERT) { - dos_PutUniCode(dest, src, dest_len, flags & STR_TERMINATE); - } else { - ascii_to_unistr(dest, src, dest_len); - } - if (flags & STR_UPPER) { - strupper_w(dest); - } - len += strlen(src)*2; - if (flags & STR_TERMINATE) len += 2; - return len; + return push_string(cli->outbuf, dest, src, dest_len, flags); } -/**************************************************************************** -copy a string from a unicode or ascii source (depending on -cli->capabilities) to a char* destination -flags can have: - STR_CONVERT means convert from dos to unix codepage - STR_TERMINATE means the string in src is null terminated - STR_UNICODE means to force as unicode - STR_NOALIGN means don't do alignment -if STR_TERMINATE is set then src_len is ignored -src_len is the length of the source area in bytes -return the number of bytes occupied by the string in src -****************************************************************************/ -int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, int flags) +int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, + int flags) { - int len; - - if (dest_len == -1) { - dest_len = sizeof(pstring); - } - - if (clistr_align_in(cli, src, flags)) { - src = (const void *)((const char *)src + 1); - if (src_len > 0) src_len--; - } - - if (!UNICODE_FLAG(cli, flags)) { - /* the server doesn't want unicode */ - if (flags & STR_TERMINATE) { - safe_strcpy(dest, src, dest_len); - len = strlen(src)+1; - } else { - if (src_len > dest_len) src_len = dest_len; - len = src_len; - memcpy(dest, src, len); - dest[len] = 0; - } - if (flags & STR_CONVERT) - safe_strcpy(dest,dos_to_unix(dest,False),dest_len); - return len; - } - - if (flags & STR_TERMINATE) { - unistr_to_ascii(dest, src, dest_len); - len = strlen(dest)*2 + 2; - } else { - int i, c; - if (dest_len*2 < src_len) src_len = 2*dest_len; - for (i=0; i < src_len; i += 2) { - c = SVAL(src, i); - *dest++ = c; - } - *dest++ = 0; - len = src_len; - } - if (flags & STR_CONVERT) - safe_strcpy(dest,dos_to_unix(dest,False),dest_len); - return len; + return pull_string(cli->inbuf, dest, src, dest_len, src_len, flags); } -/**************************************************************************** -return an alignment of either 0 or 1 -if unicode is not negotiated then return 0 -otherwise return 1 if offset is off -****************************************************************************/ -static int clistr_align(struct cli_state *cli, char *buf, const void *p, int flags) -{ - if ((flags & STR_NOALIGN) || !UNICODE_FLAG(cli, flags)) return 0; - return PTR_DIFF(p, buf) & 1; -} - int clistr_align_out(struct cli_state *cli, const void *p, int flags) { - return clistr_align(cli, cli->outbuf, p, flags); + return align_string(cli->outbuf, p, flags); } int clistr_align_in(struct cli_state *cli, const void *p, int flags) { - return clistr_align(cli, cli->inbuf, p, flags); + return align_string(cli->inbuf, p, flags); } - - diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index d21d179126..68583c4199 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -28,7 +28,7 @@ send a SMB trans or trans2 request ****************************************************************************/ BOOL cli_send_trans(struct cli_state *cli, int trans, - char *pipe_name, + const char *pipe_name, int fid, int flags, uint16 *setup, int lsetup, int msetup, char *param, int lparam, int mparam, diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index bc70dc520b..10444a8ab9 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -446,8 +446,6 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); - charset_initialise(); - /* Here we would open the smb.conf file if needed ... */ home = getenv("HOME"); @@ -471,8 +469,6 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) } - codepage_initialise(lp_client_code_page()); /* Get a codepage */ - reopen_logs(); /* Get logging working ... */ name_register_wins(my_netbios_name, 0); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 465198dfad..18bf6f4804 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -182,9 +182,7 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name) } if (i == count) return False; - StrnCpy(name, status[i].name, 15); - - dos_to_unix(name, True); + pull_ascii(name, status[i].name, 15, 0, STR_TERMINATE); free(status); return True; @@ -1025,7 +1023,8 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... mailslot_name = bufp; bufp += (strlen(bufp) + 1); bufp = ALIGN2(bufp, buffer); - bufp += dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1, True); + bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE); + SIVAL(bufp,0,1); SSVAL(bufp,4,0xFFFF); SSVAL(bufp,6,0xFFFF); diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 0a6bbe87e2..d3b0e68aef 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -831,9 +831,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) { extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); - StrnCpy( n->name, name, 15 ); - unix_to_dos(n->name, True); - strupper( n->name ); + push_ascii(n->name, name, 15, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope, 63 ); strupper( n->scope ); diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 420b49ed2e..37a07a0001 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -145,8 +145,7 @@ void pwd_set_nullpwd(struct pwd_info *pwd) void pwd_set_cleartext(struct pwd_info *pwd, char *clr) { pwd_init(pwd); - fstrcpy(pwd->password, clr); - unix_to_dos(pwd->password,True); + push_ascii_fstring(pwd->password, clr); pwd->cleartext = True; pwd->null_pwd = False; pwd->crypted = False; @@ -157,13 +156,9 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) ****************************************************************************/ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) { - if (pwd->cleartext) - { + if (pwd->cleartext) { fstrcpy(clr, pwd->password); - dos_to_unix(clr, True); - } - else - { + } else { clr[0] = 0; } } @@ -222,8 +217,7 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) pwd_init(pwd); - pstrcpy(dos_passwd, clr); - unix_to_dos(dos_passwd, True); + push_ascii_pstring(dos_passwd, clr); nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); pwd->null_pwd = False; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b9827333d8..4cc8261e66 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -207,16 +207,8 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ * decrypt. JRA. */ generate_random_buffer((unsigned char *)data, 516, False); - if (unicode) - { - /* Note that passwd should be in DOS oem character set. */ - dos_struni2( &data[512 - new_pw_len], passwd, 512); - } - else - { - /* Note that passwd should be in DOS oem character set. */ - fstrcpy( &data[512 - new_pw_len], passwd); - } + push_string(NULL, &data[512 - new_pw_len], passwd, new_pw_len, + STR_NOALIGN | (unicode?STR_UNICODE:STR_ASCII)); SIVAL(data, 512, new_pw_len); #ifdef DEBUG_PASSWORD @@ -236,26 +228,19 @@ BOOL encode_pw_buffer(char buffer[516], const char *new_pass, { generate_random_buffer(buffer, 516, True); - if (nt_pass_set) - { - /* - * nt passwords are in unicode. last char overwrites NULL - * in ascii_to_unibuf, so use SIVAL *afterwards*. - */ + if (nt_pass_set) { new_pw_len *= 2; - ascii_to_unistr((uint16 *)&buffer[512 - new_pw_len], new_pass, - new_pw_len); - } - else - { - memcpy(&buffer[512 - new_pw_len], new_pass, new_pw_len); + push_ucs2(NULL, &buffer[512 - new_pw_len], new_pass, + new_pw_len, 0); + } else { + push_ascii(&buffer[512 - new_pw_len], new_pass, + new_pw_len, 0); } /* * The length of the new password is in the last 4 bytes of * the data buffer. */ - SIVAL(buffer, 512, new_pw_len); return True; @@ -268,8 +253,6 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, int new_pwrd_size, uint32 *new_pw_len, uchar nt_p16[16], uchar p16[16]) { - char *pw; - int uni_pw_len=0; int byte_len=0; char unicode_passwd[514]; @@ -304,9 +287,8 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return False; } + pull_string(NULL, passwd, &in_buffer[512 - byte_len], -1, byte_len, STR_UNICODE); uni_pw_len = byte_len/2; - pw = dos_unistrn2((uint16 *)(&in_buffer[512 - byte_len]), byte_len); - memcpy(passwd, pw, uni_pw_len); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: passwd: ")); @@ -324,7 +306,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, #endif /* Mangle the passwords into Lanman format */ - memcpy(lm_ascii_passwd, passwd, uni_pw_len); + memcpy(lm_ascii_passwd, passwd, byte_len/2); lm_ascii_passwd[14] = '\0'; strupper(lm_ascii_passwd); @@ -338,11 +320,10 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, #endif /* copy the password and it's length to the return buffer */ - *new_pw_len=uni_pw_len; + *new_pw_len = byte_len/2; memcpy(new_pwrd, passwd, uni_pw_len); new_pwrd[uni_pw_len]='\0'; - /* clear out local copy of user's password (just being paranoid). */ ZERO_STRUCT(unicode_passwd); ZERO_STRUCT(lm_ascii_passwd); diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index c2d8884d73..924fa76d71 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -164,10 +164,12 @@ char *smb_errstr(char *inbuf) if (num == err[j].code) { if (DEBUGLEVEL > 0) - slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class, - err[j].name,err[j].message); + slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)", + err_classes[i].class, + err[j].name,err[j].message); else - slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name); + slprintf(ret, sizeof(ret) - 1, "%s - %s", + err_classes[i].class,err[j].name); return ret; } } -- cgit From 527e824293ee934ca5da0ef5424efe5ab7757248 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:36:09 +0000 Subject: strchr and strrchr are macros when compiling with optimisation in gcc, so we can't redefine them. damn. (This used to be commit c41fc06376d1a2b83690612304e85010b5e5f3cf) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/libsmbclient.c | 10 +++++----- source3/libsmb/namequery.c | 4 ++-- source3/libsmb/nmblib.c | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7ec0627682..9511a56e31 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -60,7 +60,7 @@ BOOL cli_session_setup(struct cli_state *cli, /* allow for workgroups as part of the username */ fstrcpy(user2, user); - if ((p=strchr(user2,'\\')) || (p=strchr(user2,'/'))) { + if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/'))) { *p = 0; user = p+1; workgroup = user2; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 10444a8ab9..b944174665 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -133,7 +133,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, * exists ... */ - if (strchr(p, '@')) { + if (strchr_m(p, '@')) { pstring username, passwd, domain; char *u = userinfo; @@ -141,13 +141,13 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, username[0] = passwd[0] = domain[0] = 0; - if (strchr(u, ';')) { + if (strchr_m(u, ';')) { next_token(&u, domain, ";", sizeof(fstring)); } - if (strchr(u, ':')) { + if (strchr_m(u, ':')) { next_token(&u, username, ":", sizeof(fstring)); @@ -276,11 +276,11 @@ struct smbc_server *smbc_server(char *server, char *share, DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - if ((p=strchr(server_n,'#')) && + if ((p=strchr_m(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { fstrcpy(group, server_n); - p = strchr(group,'#'); + p = strchr_m(group,'#'); *p = 0; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 18bf6f4804..c5c4d92c09 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -503,7 +503,7 @@ BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipad DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); - if (strchr(flags,'G') || strchr(flags,'S')) + if (strchr_m(flags,'G') || strchr_m(flags,'S')) { DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); continue; @@ -513,7 +513,7 @@ BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipad /* Extra feature. If the name ends in '#XX', where XX is a hex number, then only add that name type. */ - if((ptr = strchr(name, '#')) != NULL) + if((ptr = strchr_m(name, '#')) != NULL) { char *endptr; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d3b0e68aef..9d7167f305 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -300,7 +300,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) pstrcpy(&buf[offset+1],name->scope); p = &buf[offset+1]; - while ((p = strchr(p,'.'))) { + while ((p = strchr_m(p,'.'))) { buf[offset] = PTR_DIFF(p,&buf[offset+1]); offset += (buf[offset] + 1); p = &buf[offset+1]; -- cgit From 005582d1b54e095cadd9fbb50c475a203d831dac Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 5 Jul 2001 08:24:03 +0000 Subject: Renamed formal parameter fd to fnum because we're talking about SMB file handles, not unix ones. (This used to be commit 974790e45e6774a0e8ca3f8bb73ea941457e0866) --- source3/libsmb/clisecdesc.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 69c7d5f73f..e0d6ae809f 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -19,16 +19,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" - - /**************************************************************************** query the security descriptor for a open file - ****************************************************************************/ -SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx) + ****************************************************************************/ +SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, + TALLOC_CTX *mem_ctx) { char param[8]; char *rparam=NULL, *rdata=NULL; @@ -36,7 +33,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx) prs_struct pd; SEC_DESC *psd = NULL; - SIVAL(param, 0, fd); + SIVAL(param, 0, fnum); SSVAL(param, 4, 0x7); if (!cli_send_nt_trans(cli, @@ -77,8 +74,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli,int fd, TALLOC_CTX *mem_ctx) /**************************************************************************** set the security descriptor for a open file - ****************************************************************************/ -BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) + ****************************************************************************/ +BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) { char param[8]; char *rparam=NULL, *rdata=NULL; @@ -100,7 +97,7 @@ BOOL cli_set_secdesc(struct cli_state *cli,int fd, SEC_DESC *sd) goto cleanup; } - SIVAL(param, 0, fd); + SIVAL(param, 0, fnum); SSVAL(param, 4, 0x7); if (!cli_send_nt_trans(cli, -- cgit From 7be19ad10fc30fab199653facd11496170219e1b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 7 Jul 2001 07:00:15 +0000 Subject: Add backend encryption support for NTLMv2. The leg-work for this was done by the folks at samba-tng.org, I'm just bringing it accross to HEAD. The MD5 implementation is seperatly derived, and does not have the copyright problems that the one in TNG has. Also add const to a few places where it makes sence. Andrew Bartlett (This used to be commit 8df8e841445dfe09fc7a06bb55d12adc3fecb345) --- source3/libsmb/smbdes.c | 8 ++-- source3/libsmb/smbencrypt.c | 97 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 7e8a9a5b89..c5dbbdf99a 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -259,7 +259,7 @@ static void dohash(char *out, char *in, char *key, int forw) permute(out, rl, perm6, 64); } -static void str_to_key(unsigned char *str,unsigned char *key) +static void str_to_key(const unsigned char *str,unsigned char *key) { int i; @@ -277,7 +277,7 @@ static void str_to_key(unsigned char *str,unsigned char *key) } -static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw) +static void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { int i; char outb[64]; @@ -305,14 +305,14 @@ static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, i } } -void E_P16(unsigned char *p14,unsigned char *p16) +void E_P16(const unsigned char *p14,unsigned char *p16) { unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; smbhash(p16, sp8, p14, 1); smbhash(p16+8, sp8, p14+7, 1); } -void E_P24(unsigned char *p21, unsigned char *c8, unsigned char *p24) +void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24) { smbhash(p24, c8, p21, 1); smbhash(p24+8, c8, p21+7, 1); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 4cc8261e66..e7ebd4c000 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -4,6 +4,8 @@ SMB parameters and setup Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. + Copyright (C) Jeremy Allison 1995-2000. + Copyright (C) Luke Kennethc Casson Leighton 1996-2000. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -83,6 +85,24 @@ static int _my_mbstowcs(int16 *dst, uchar *src, int len) return i; } +static int _my_mbstowcsupper(int16 * dst, const uchar * src, int len) +{ + int i; + int16 val; + + for (i = 0; i < len; i++) + { + val = toupper(*src); + SSVAL(dst, 0, val); + dst++; + src++; + if (val == 0) + break; + } + return i; +} + + /* * Creates the MD4 Hash of the users password in NT UNICODE. */ @@ -141,8 +161,36 @@ void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) memset(passwd, '\0', sizeof(passwd)); } +/* Does both the NTLMv2 owfs of a user's password */ +void ntv2_owf_gen(const uchar owf[16], + const char *user_n, const char *domain_n, uchar kr_buf[16]) +{ + pstring user_u; + pstring dom_u; + HMACMD5Context ctx; + + int user_l = strlen(user_n); + int domain_l = strlen(domain_n); + + _my_mbstowcsupper((int16 *) user_u, user_n, user_l * 2); + _my_mbstowcsupper((int16 *) dom_u, domain_n, domain_l * 2); + + hmac_md5_init_limK_to_64(owf, 16, &ctx); + hmac_md5_update(user_u, user_l * 2, &ctx); + hmac_md5_update(dom_u, domain_l * 2, &ctx); + hmac_md5_final(kr_buf, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); + dump_data(100, user_u, user_l * 2); + dump_data(100, dom_u, domain_l * 2); + dump_data(100, owf, 16); + dump_data(100, kr_buf, 16); +#endif +} + /* Does the des encryption from the NT or LM MD4 hash. */ -void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24]) +void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) { uchar p21[21]; @@ -220,6 +268,53 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } +/* Does the md5 encryption from the NT hash for NTLMv2. */ +void SMBOWFencrypt_ntv2(const uchar kr[16], + const uchar * srv_chal, int srv_chal_len, + const uchar * cli_chal, int cli_chal_len, + char resp_buf[16]) +{ + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(srv_chal, srv_chal_len, &ctx); + hmac_md5_update(cli_chal, cli_chal_len, &ctx); + hmac_md5_final(resp_buf, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); + dump_data(100, srv_chal, srv_chal_len); + dump_data(100, cli_chal, cli_chal_len); + dump_data(100, resp_buf, 16); +#endif +} + +void SMBsesskeygen_ntv2(const uchar kr[16], + const uchar * nt_resp, char sess_key[16]) +{ + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(kr, 16, &ctx); + hmac_md5_update(nt_resp, 16, &ctx); + hmac_md5_final(sess_key, &ctx); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_ntv2:\n")); + dump_data(100, sess_key, 16); +#endif +} + +void SMBsesskeygen_ntv1(const uchar kr[16], + const uchar * nt_resp, char sess_key[16]) +{ + mdfour(sess_key, kr, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_ntv1:\n")); + dump_data(100, sess_key, 16); +#endif +} + /*********************************************************** encode a password buffer ************************************************************/ -- cgit From 74e99216289956bef5d13f4a691b749933eadfa2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 7 Jul 2001 21:23:32 +0000 Subject: fixed some unicode and LANMAN2 bugs in trans2 find first (This used to be commit dc99b9ddf847c210c72921ba1dedcdc34fd32aab) --- source3/libsmb/clilist.c | 180 ++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 103 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index b08cc08f01..e0287bf6c4 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -34,120 +34,94 @@ static int interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { extern file_info def_finfo; + file_info finfo2; + int len; + char *base = p; - if (finfo) - memcpy(finfo,&def_finfo,sizeof(*finfo)); + if (!finfo) finfo = &finfo2; + + memcpy(finfo,&def_finfo,sizeof(*finfo)); switch (level) { case 1: /* OS/2 understands this */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - clistr_pull(cli, finfo->name, p+27, - sizeof(finfo->name), - -1, - STR_TERMINATE); - } - return(28 + CVAL(p,26)); + /* these dates are converted to GMT by + make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + len = CVAL(p, 26); + p += 27; + p += clistr_align_in(cli, p, 0); + p += clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + len, + STR_TERMINATE); + return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - clistr_pull(cli, finfo->name, p+31, - sizeof(finfo->name), - -1, - STR_TERMINATE); - } - return(32 + CVAL(p,30)); - - /* levels 3 and 4 are untested */ - case 3: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - clistr_pull(cli, finfo->name, p+33, - sizeof(finfo->name), - -1, - STR_TERMINATE); - } - return(SVAL(p,4)+4); - - case 4: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - clistr_pull(cli, finfo->name, p+37, - sizeof(finfo->name), - -1, - STR_TERMINATE); - } - return(SVAL(p,4)+4); + /* these dates are converted to GMT by + make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + len = CVAL(p, 30); + p += 31; + p += clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + len, + STR_NOALIGN); + return PTR_DIFF(p, base) + 1; case 260: /* NT uses this, but also accepts 2 */ - if (finfo) { - int ret = SVAL(p,0); - int namelen, slen; - p += 4; /* next entry offset */ - p += 4; /* fileindex */ + { + int namelen, slen; + p += 4; /* next entry offset */ + p += 4; /* fileindex */ - /* these dates appear to arrive in a - weird way. It seems to be localtime - plus the serverzone given in the - initial connect. This is GMT when - DST is not in effect and one hour - from GMT otherwise. Can this really - be right?? - - I suppose this could be called - kludge-GMT. Is is the GMT you get - by using the current DST setting on - a different localtime. It will be - cheap to calculate, I suppose, as - no DST tables will be needed */ - - finfo->ctime = interpret_long_date(p); p += 8; - finfo->atime = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL(p,0); p += 8; - p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); p += 4; - namelen = IVAL(p,0); p += 4; - p += 4; /* EA size */ - slen = SVAL(p, 0); - p += 2; - { - /* stupid NT bugs. grr */ - int flags = 0; - if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; - clistr_pull(cli, finfo->short_name, p, - sizeof(finfo->short_name), - 24, flags); - } - p += 24; /* short name? */ - clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - namelen, 0); - return(ret); + /* these dates appear to arrive in a + weird way. It seems to be localtime + plus the serverzone given in the + initial connect. This is GMT when + DST is not in effect and one hour + from GMT otherwise. Can this really + be right?? + + I suppose this could be called + kludge-GMT. Is is the GMT you get + by using the current DST setting on + a different localtime. It will be + cheap to calculate, I suppose, as + no DST tables will be needed */ + + finfo->ctime = interpret_long_date(p); p += 8; + finfo->atime = interpret_long_date(p); p += 8; + finfo->mtime = interpret_long_date(p); p += 8; p += 8; + finfo->size = IVAL(p,0); p += 8; + p += 8; /* alloc size */ + finfo->mode = CVAL(p,0); p += 4; + namelen = IVAL(p,0); p += 4; + p += 4; /* EA size */ + slen = SVAL(p, 0); + p += 2; + { + /* stupid NT bugs. grr */ + int flags = 0; + if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; + clistr_pull(cli, finfo->short_name, p, + sizeof(finfo->short_name), + 24, flags); } - return(SVAL(p,0)); + p += 24; /* short name? */ + clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + namelen, 0); + return SVAL(base, 0); + } } DEBUG(1,("Unknown long filename format %d\n",level)); -- cgit From 3ad0801dd3e8a937493ea9a7395b727e809b5824 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 8 Jul 2001 18:23:53 +0000 Subject: formatting fix (This used to be commit 3dc9fd076a2c4c352d51f7b9dfa8b570a231c9e2) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9511a56e31..9981672801 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -774,7 +774,7 @@ BOOL cli_establish_connection(struct cli_state *cli, } if (do_shutdown) - cli_shutdown(cli); + cli_shutdown(cli); return True; } -- cgit From 31fe984d2fc7a2813404a8c25816bb6bb25adfe9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 20 Jul 2001 01:35:00 +0000 Subject: Changed the cli_lsa_lookup_sids() function to unpack the domain and user or group using rpcstr_pull_unistr2_fstring rather than pull_ascii_fstring (!!) (This used to be commit 2accab2589d8c3decc489fb6af8d65d437a506e7) --- source3/libsmb/cli_lsarpc.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 61afeb7f38..4f015f20f0 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -268,15 +268,19 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Translate optimised name through domain index array */ if (dom_idx != 0xffffffff) { - pull_ascii_fstring(dom_name, &ref.ref_dom[dom_idx].uni_dom_name); - pull_ascii_fstring(name, &t_names.uni_name[i]); + + rpcstr_pull_unistr2_fstring( + dom_name, &ref.ref_dom[dom_idx].uni_dom_name); + rpcstr_pull_unistr2_fstring( + name, &t_names.uni_name[i]); slprintf(full_name, sizeof(full_name) - 1, "%s%s%s", dom_name, dom_name[0] ? - "\\" : "", name); + lp_winbind_separator() : "", name); (*names)[i] = talloc_strdup(mem_ctx, full_name); (*types)[i] = t_names.name[i].sid_name_use; + } else { (*names)[i] = NULL; (*types)[i] = SID_NAME_UNKNOWN; -- cgit From 57933a9c6f1a914b69dd38e0346ac17d47f87d45 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 20 Jul 2001 06:25:12 +0000 Subject: In cli_lsa_lookup_sids() don't append a separator character between domain and name if there is no name. (This used to be commit e0ebbc9ae3277a5a389eef021f32509a017cbd4d) --- source3/libsmb/cli_lsarpc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 4f015f20f0..dcc4a65414 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -275,7 +275,8 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, name, &t_names.uni_name[i]); slprintf(full_name, sizeof(full_name) - 1, - "%s%s%s", dom_name, dom_name[0] ? + "%s%s%s", dom_name, + (dom_name[0] && name[0]) ? lp_winbind_separator() : "", name); (*names)[i] = talloc_strdup(mem_ctx, full_name); -- cgit From 10fa3f878b9be6a78c10888ef9e9c3967f8d7e70 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 23 Jul 2001 03:05:01 +0000 Subject: Added a warning debug if cli_samr_lookup_rids is called with more than 1000 rids as this seems to crash LSASS.EXE more often than not. (This used to be commit 375636b7630d117da5a57b51e11929c3a38646df) --- source3/libsmb/cli_samr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 29f136427d..d8b300d090 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -792,7 +792,8 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Lookup rids */ +/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are + looked up in one packet. */ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *domain_pol, uint32 flags, @@ -805,6 +806,11 @@ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, SAMR_R_LOOKUP_RIDS r; uint32 result = NT_STATUS_UNSUCCESSFUL, i; + if (num_rids > 1000) { + DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if " + "more than ~1000 rids are looked up at once.\n")); + } + ZERO_STRUCT(q); ZERO_STRUCT(r); -- cgit From 516eeb0b792d313ff4f42959a2f63140f4315c80 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 23 Jul 2001 07:20:46 +0000 Subject: cli_samr_query_dispinfo() can return STATUS_MORE_ENTRIES which isn't an entry. (This used to be commit 12e44e40298b5469f6f1fea3495cfa023305411d) --- source3/libsmb/cli_samr.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index d8b300d090..5f6d0fbae5 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -778,7 +778,10 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + result = r.status; + + if (result != NT_STATUS_NOPROBLEMO && + result != STATUS_MORE_ENTRIES) { goto done; } -- cgit From d17d9bee6f3d23f31f6b408e7b80630d4602c9c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Jul 2001 20:25:35 +0000 Subject: Throw out crappy (non-ascii unaware) mbtows stuff and use proper unicode push calls. If this breaks authentication then good, it needed fixing anyway :-). Jeremy. (This used to be commit e3580b4033c551e215cb246d4e36c4870cb4a582) --- source3/libsmb/smbencrypt.c | 63 +++++---------------------------------------- 1 file changed, 6 insertions(+), 57 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index e7ebd4c000..95d21dc772 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -53,56 +53,6 @@ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) #endif } -/* Routines for Windows NT MD4 Hash functions. */ -static int _my_wcslen(int16 *str) -{ - int len = 0; - while(*str++ != 0) - len++; - return len; -} - -/* - * Convert a string into an NT UNICODE string. - * Note that regardless of processor type - * this must be in intel (little-endian) - * format. - */ - -static int _my_mbstowcs(int16 *dst, uchar *src, int len) -{ - int i; - int16 val; - - for(i = 0; i < len; i++) { - val = *src; - SSVAL(dst,0,val); - dst++; - src++; - if(val == 0) - break; - } - return i; -} - -static int _my_mbstowcsupper(int16 * dst, const uchar * src, int len) -{ - int i; - int16 val; - - for (i = 0; i < len; i++) - { - val = toupper(*src); - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } - return i; -} - - /* * Creates the MD4 Hash of the users password in NT UNICODE. */ @@ -110,17 +60,16 @@ static int _my_mbstowcsupper(int16 * dst, const uchar * src, int len) void E_md4hash(uchar *passwd, uchar *p16) { int len; - int16 wpwd[129]; + smb_ucs2_t wpwd[129]; /* Password cannot be longer than 128 characters */ len = strlen((char *)passwd); if(len > 128) len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - wpwd[len] = 0; /* Ensure string is null terminated */ + /* Password must be converted to NT unicode - null terminated. */ + push_ucs2(NULL, wpwd, passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(int16); + len = strlen_w(wpwd) * sizeof(int16); mdfour(p16, (unsigned char *)wpwd, len); } @@ -172,8 +121,8 @@ void ntv2_owf_gen(const uchar owf[16], int user_l = strlen(user_n); int domain_l = strlen(domain_n); - _my_mbstowcsupper((int16 *) user_u, user_n, user_l * 2); - _my_mbstowcsupper((int16 *) dom_u, domain_n, domain_l * 2); + push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); + push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); hmac_md5_init_limK_to_64(owf, 16, &ctx); hmac_md5_update(user_u, user_l * 2, &ctx); -- cgit From 996719cce26700c68ff0e456e6a25d20085d091f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Jul 2001 22:21:31 +0000 Subject: Added "use mmap" for HPUX. Jeremy. (This used to be commit 840802f10677cb0009cb4df4c37c7d01aa5edacd) --- source3/libsmb/unexpected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index d757551963..109e2b454a 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -50,7 +50,7 @@ void unexpected_packet(struct packet_struct *p) if (!tdbd) { tdbd = tdb_open_log(lock_path("unexpected.tdb"), 1, - TDB_CLEAR_IF_FIRST, + TDB_CLEAR_IF_FIRST|USE_TDB_MMAP_FLAG, O_RDWR | O_CREAT, 0644); if (!tdbd) { DEBUG(0,("Failed to open unexpected.tdb\n")); -- cgit From 54fc7e1abaff6403843235e1ab06edce14f5fa7b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 6 Aug 2001 02:13:23 +0000 Subject: Changed lone malloc() call to talloc(). Spotted by Claudia Moroder (This used to be commit 99ce277fc857069f86824a3c0cd8012f4cede1b6) --- source3/libsmb/cli_spoolss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 2c962ef27a..4b0c381394 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -221,7 +221,7 @@ static void decode_printer_info_0( uint32 i; PRINTER_INFO_0 *inf; - inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0)); + inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0)); buffer->prs.data_offset=0; -- cgit From 9f08cea054e7c2a3fd3b32d9c6711a269704d20b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 6 Aug 2001 02:18:40 +0000 Subject: Cleaned up error handling in cli_initialise() to fix a memleak found by Claudia Moroder (This used to be commit b5373f4b59cfe1cffe915e5d4eb29ed83fe99ba6) --- source3/libsmb/clientgen.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e9f55850ac..79fa224e8f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -180,24 +180,28 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->oplock_handler = cli_oplock_ack; if (!cli->outbuf || !cli->inbuf) - { - return NULL; - } + goto error; - if ((cli->mem_ctx = talloc_init()) == NULL) { - free(cli->outbuf); - free(cli->inbuf); - return NULL; - } + if ((cli->mem_ctx = talloc_init()) == NULL) + goto error; - memset(cli->outbuf, '\0', cli->bufsize); - memset(cli->inbuf, '\0', cli->bufsize); + memset(cli->outbuf, 0, cli->bufsize); + memset(cli->inbuf, 0, cli->bufsize); cli->nt_pipe_fnum = 0; cli->initialised = 1; return cli; + + /* Clean up after malloc() error */ + + error: + + safe_free(cli->inbuf); + safe_free(cli->outbuf); + + return NULL; } /**************************************************************************** -- cgit From a6234ad6f297611bcd00f67d388de532d1a6874f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 6 Aug 2001 23:29:25 +0000 Subject: Fixed another possible memleak in cli_initialise() (This used to be commit 4c9f010a1eef81addfea0315bef81570bc604f8a) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 79fa224e8f..ba852dea52 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -152,11 +152,14 @@ initialise a client structure ****************************************************************************/ struct cli_state *cli_initialise(struct cli_state *cli) { + BOOL alloced_cli = False; + if (!cli) { cli = (struct cli_state *)malloc(sizeof(*cli)); if (!cli) return NULL; ZERO_STRUCTP(cli); + alloced_cli = True; } if (cli->initialised) { @@ -201,6 +204,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) safe_free(cli->inbuf); safe_free(cli->outbuf); + if (alloced_cli) + safe_free(cli); + return NULL; } -- cgit From 49eea105fd99f43ee508f278865c655683b9be58 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 8 Aug 2001 03:18:49 +0000 Subject: Factored out common rpc pipe initialisation and shutdown code. (This used to be commit 04d978258ba2fea702232c815e140ab12364e8e7) --- source3/libsmb/cli_dfs.c | 51 +-------------------------- source3/libsmb/cli_lsarpc.c | 51 +-------------------------- source3/libsmb/cli_netlogon.c | 51 +-------------------------- source3/libsmb/cli_pipe_util.c | 80 ++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/cli_samr.c | 51 +-------------------------- source3/libsmb/cli_spoolss.c | 51 +-------------------------- source3/libsmb/cli_srvsvc.c | 51 +-------------------------- 7 files changed, 86 insertions(+), 300 deletions(-) create mode 100644 source3/libsmb/cli_pipe_util.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index 830681effb..a16c76658f 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -26,56 +26,7 @@ struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, PIPE_NETDFS)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the DFS pipe */ - -void cli_dfs_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); + return cli_pipe_initialise(cli, system_name, PIPE_NETDFS, creds); } /* Query DFS support */ diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index dcc4a65414..e4b6683389 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -30,56 +30,7 @@ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, PIPE_LSARPC)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the LSA pipe */ - -void cli_lsa_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); + return cli_pipe_initialise(cli, system_name, PIPE_LSASS, creds); } /* Open a LSA policy handle */ diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 47b7c2f22e..63a2f4a5b1 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -29,56 +29,7 @@ struct cli_state *cli_netlogon_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, PIPE_NETLOGON)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the netlogon pipe */ - -void cli_netlogon_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); + return cli_pipe_initialise(cli, system_name, PIPE_NETLOGON, creds); } /* Logon Control 2 */ diff --git a/source3/libsmb/cli_pipe_util.c b/source3/libsmb/cli_pipe_util.c new file mode 100644 index 0000000000..9521d817fa --- /dev/null +++ b/source3/libsmb/cli_pipe_util.c @@ -0,0 +1,80 @@ +/* + Unix SMB/Netbios implementation. + Version 2.2 + RPC pipe client utility functions + Copyright (C) Tim Potter 2001, + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* Opens a SMB connection to a named pipe */ + +struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name, + char *pipe_name, + struct ntuser_creds *creds) +{ + struct in_addr dest_ip; + struct nmb_name calling, called; + fstring dest_host; + extern pstring global_myname; + struct ntuser_creds anon; + + /* Initialise cli_state information */ + + if (!cli_initialise(cli)) { + return NULL; + } + + if (!creds) { + ZERO_STRUCT(anon); + anon.pwd.null_pwd = 1; + creds = &anon; + } + + cli_init_creds(cli, creds); + + /* Establish a SMB connection */ + + if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { + return NULL; + } + + make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); + make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); + + if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, + &called, "IPC$", "IPC", False, True)) { + return NULL; + } + + /* Open a NT session thingy */ + + if (!cli_nt_session_open(cli, pipe_name)) { + cli_shutdown(cli); + return NULL; + } + + return cli; +} + +/* Shut down a SMB connection to the SAMR pipe */ + +void cli_pipe_shutdown(struct cli_state *cli) +{ + if (cli->fd != -1) cli_ulogoff(cli); + cli_shutdown(cli); +} diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 5f6d0fbae5..dee1baff02 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -30,56 +30,7 @@ struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, PIPE_SAMR)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the SAMR pipe */ - -void cli_samr_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); + return cli_pipe_initialise(cli, system_name, PIPE_SAMR, creds); } /* Connect to SAMR database */ diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 4b0c381394..9c53912dff 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -33,56 +33,7 @@ struct cli_state *cli_spoolss_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, PIPE_SPOOLSS)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the SPOOLSS pipe */ - -void cli_spoolss_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); + return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds); } /* Open printer ex */ diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 8209d9301f..042a9c44ff 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -29,56 +29,7 @@ struct cli_state *cli_svrsvc_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, PIPE_SRVSVC)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the srvsvc pipe */ - -void cli_srvsvc_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); + return cli_pipe_initialise(cli, system_name, PIPE_SRVSVC, creds); } uint32 cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, -- cgit From c4495240f63c2bae164d4ef29ab9af2d3d87aec1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 04:59:05 +0000 Subject: Changed the order of arguments in make_oem_passwd_hash(). All the other encryption functions have outputs as the last arguments. (This used to be commit fb60798a771a7a2358d78e5cef97487addf930e7) --- source3/libsmb/clirap.c | 2 +- source3/libsmb/smbencrypt.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index c16fe2d08d..c649aedfba 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -329,7 +329,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE); - if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) + if (!make_oem_passwd_hash(dos_new_password, old_pw_hash, False, data)) return False; /* diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 95d21dc772..e13b180fcb 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -187,7 +187,8 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) #endif } -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) +BOOL make_oem_passwd_hash(const char *passwd, uchar old_pw_hash[16], + BOOL unicode, char data[516]) { int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); -- cgit From 2ccfea3de7b2b7dc0be2438c3adb3f7be82a2dfc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 06:00:33 +0000 Subject: A rewrite of the error handling in the libsmb client code. I've separated out the error handling into a bunch of separate functions rather than all being handled in one big function. Fetch error codes from the last received packet: void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *num); uint32 cli_nt_error(struct cli_state *); Convert errors to UNIX errno values: int cli_errno_from_dos(uint8 eclass, uint32 num); int cli_errno_from_nt(uint32 status); int cli_errno(struct cli_state *cli); Detect different kinds of errors: BOOL cli_is_dos_error(struct cli_state *cli); BOOL cli_is_nt_error(struct cli_state *cli); BOOL cli_is_error(struct cli_state *cli); This also means we now support CAP_STATUS32 as we can decode and understand NT errors instead of just DOS errors. Yay! Ported a whole bunch of files in libsmb to use this new API instead of the just the DOS error. (This used to be commit 6dbdb0d813f3c7ab20b38baa1223b0b479aadec9) --- source3/libsmb/cliconnect.c | 9 ++ source3/libsmb/clientgen.c | 1 - source3/libsmb/clierror.c | 249 ++++++++++++++++++++++++++---------------- source3/libsmb/clifile.c | 2 +- source3/libsmb/clilist.c | 5 +- source3/libsmb/climessage.c | 6 +- source3/libsmb/clirap.c | 6 +- source3/libsmb/clireadwrite.c | 24 ++-- source3/libsmb/clitrans.c | 24 ++-- source3/libsmb/libsmbclient.c | 33 ++++-- source3/libsmb/nterr.c | 50 +++++---- source3/libsmb/smbencrypt.c | 3 +- source3/libsmb/smberr.c | 53 ++++----- 13 files changed, 283 insertions(+), 182 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9981672801..dffff5e6ab 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -143,6 +143,15 @@ BOOL cli_session_setup(struct cli_state *cli, uint32 capabilities; capabilities = CAP_NT_SMBS; + + /* Set the CLI_FORCE_DOSERR environment variable to test + client routines using DOS errors instead of STATUS32 + ones. This intended only as a temporary hack. */ + + if (!getenv("CLI_FORCE_DOSERR")) { + capabilities |= CAP_STATUS32; + } + if (cli->use_level_II_oplocks) { capabilities |= CAP_LEVEL_II_OPLOCKS; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ba852dea52..5ddfa48ac0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -104,7 +104,6 @@ setup basics in a outgoing packet void cli_setup_packet(struct cli_state *cli) { cli->rap_error = 0; - cli->nt_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index f533eabb0b..c2234e8ead 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -23,10 +23,8 @@ #include "includes.h" - extern int DEBUGLEVEL; - /***************************************************** RAP error codes - a small start but will be extended. *******************************************************/ @@ -63,134 +61,119 @@ static char *cli_smb_errstr(struct cli_state *cli) return smb_errstr(cli->inbuf); } -/****************************************************** - Return an error message - either an SMB error or a RAP - error. -*******************************************************/ +/*************************************************************************** + Return an error message - either an NT error, SMB error or a RAP error. + Note some of the NT errors are actually warnings or "informational" errors + in which case they can be safely ignored. +****************************************************************************/ char *cli_errstr(struct cli_state *cli) { static fstring error_message; - uint8 errclass; - uint32 errnum; - uint32 nt_rpc_error; - int i; - - /* - * Errors are of three kinds - smb errors, - * dealt with by cli_smb_errstr, NT errors, - * whose code is in cli.nt_error, and rap - * errors, whose error code is in cli.rap_error. - */ - - cli_error(cli, &errclass, &errnum, &nt_rpc_error); - - if (errclass != 0) - { - return cli_smb_errstr(cli); - } + uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum; + uint8 errclass; + int i; - /* - * Was it an NT error ? - */ + /* Case #1: 32-bit NT errors */ - if (nt_rpc_error) - { - char *nt_msg = (char *)get_nt_error_msg(nt_rpc_error); + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { + uint32 status = IVAL(cli->inbuf,smb_rcls); - if (nt_msg == NULL) - { - slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error); - } - else - { - fstrcpy(error_message, nt_msg); - } + return get_nt_error_msg(status); + } - return error_message; - } + cli_dos_error(cli, &errclass, &errnum); + + /* Case #2: SMB error */ - /* - * Must have been a rap error. - */ + if (errclass != 0) + return cli_smb_errstr(cli); - slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error); + /* Case #3: RAP error */ - for (i = 0; rap_errmap[i].message != NULL; i++) - { - if (rap_errmap[i].err == cli->rap_error) - { - fstrcpy(error_message, rap_errmap[i].message); - break; + for (i = 0; rap_errmap[i].message != NULL; i++) { + if (rap_errmap[i].err == cli->rap_error) { + return rap_errmap[i].message; } } + slprintf(error_message, sizeof(error_message) - 1, "code %d", + cli->rap_error); + return error_message; } +/* Return the 32-bit NT status code from the last packet */ -/**************************************************************************** - return error codes for the last packet - returns 0 if there was no error and the best approx of a unix errno - otherwise +uint32 cli_nt_error(struct cli_state *cli) +{ + int flgs2 = SVAL(cli->inbuf,smb_flg2); - for 32 bit "warnings", a return code of 0 is expected. + if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) { -****************************************************************************/ -int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error) + /* Eek! We've requested a NT error when the packet that + came back does not contain one. What do we return + here? */ + + DEBUG(1, ("ERROR: cli_error() called to read a status code " + "from a packet that does not contain one!\n")); + + return NT_STATUS_UNSUCCESSFUL; + } + + return IVAL(cli->inbuf,smb_rcls); +} + +/* Return the DOS error from the last packet - an error class and an error + code. */ + +void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *num) { int flgs2; char rcls; int code; - if (eclass) *eclass = 0; - if (num ) *num = 0; - if (nt_rpc_error) *nt_rpc_error = 0; + if (eclass) + *eclass = 0; + + if (num) + *num = 0; if(!cli->initialised) - return EINVAL; + return; if(!cli->inbuf) - return ENOMEM; + return; flgs2 = SVAL(cli->inbuf,smb_flg2); - if (nt_rpc_error) *nt_rpc_error = cli->nt_error; if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* 32 bit error codes detected */ - uint32 nt_err = IVAL(cli->inbuf,smb_rcls); - if (num) *num = nt_err; - DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err)); - if (!(nt_err & 0xc0000000)) - return 0; - - switch (nt_err) { - case NT_STATUS_ACCESS_VIOLATION: return EACCES; - case NT_STATUS_NO_SUCH_FILE: return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; - case NT_STATUS_INVALID_HANDLE: return EBADF; - case NT_STATUS_NO_MEMORY: return ENOMEM; - case NT_STATUS_ACCESS_DENIED: return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION: return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; - case NT_STATUS_PATH_NOT_COVERED: return ENOENT; - } + /* Eek! We've requested a DOS error when the packet that + came back does not contain one. What do we return + here? */ - /* for all other cases - a default code */ - return EINVAL; - } + DEBUG(1, ("ERROR: cli_error() called to read a dos error code " + "from a packet that does not contain one!\n")); + + return; + } rcls = CVAL(cli->inbuf,smb_rcls); code = SVAL(cli->inbuf,smb_err); - if (rcls == 0) return 0; + + if (rcls == 0) + return; if (eclass) *eclass = rcls; if (num ) *num = code; +} - if (rcls == ERRDOS) { - switch (code) { +/* Return a UNIX errno from a dos error class, error number tuple */ + +int cli_errno_from_dos(uint8 eclass, uint32 num) +{ + if (eclass == ERRDOS) { + switch (num) { case ERRbadfile: return ENOENT; case ERRbadpath: return ENOTDIR; case ERRnoaccess: return EACCES; @@ -198,12 +181,13 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ case ERRrename: return EEXIST; case ERRbadshare: return EBUSY; case ERRlock: return EBUSY; - case ERROR_INVALID_NAME: return ENOENT; + case ERRinvalidname: return ENOENT; case ERRnosuchshare: return ENODEV; } } - if (rcls == ERRSRV) { - switch (code) { + + if (eclass == ERRSRV) { + switch (num) { case ERRbadpw: return EPERM; case ERRaccess: return EACCES; case ERRnoresource: return ENOMEM; @@ -211,7 +195,88 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_ case ERRinvnetname: return ENODEV; } } + /* for other cases */ return EINVAL; } +/* Return a UNIX errno from a NT status code */ + +int cli_errno_from_nt(uint32 status) +{ + DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", status)); + + /* Status codes without this bit set are not errors */ + + if (!(status & 0xc0000000)) + return 0; + + switch (status) { + case NT_STATUS_ACCESS_VIOLATION: return EACCES; + case NT_STATUS_NO_SUCH_FILE: return ENOENT; + case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; + case NT_STATUS_INVALID_HANDLE: return EBADF; + case NT_STATUS_NO_MEMORY: return ENOMEM; + case NT_STATUS_ACCESS_DENIED: return EACCES; + case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; + case NT_STATUS_SHARING_VIOLATION: return EBUSY; + case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; + case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; + case NT_STATUS_PATH_NOT_COVERED: return ENOENT; + } + + /* for all other cases - a default code */ + return EINVAL; +} + +/* Return a UNIX errno appropriate for the error received in the last + packet. */ + +int cli_errno(struct cli_state *cli) +{ + uint32 status; + + if (cli_is_dos_error) { + uint8 eclass; + uint32 ecode; + + cli_dos_error(cli, &eclass, &ecode); + return cli_errno_from_dos(eclass, ecode); + } + + status = cli_nt_error(cli); + + return cli_errno_from_nt(status); +} + +/* Return true if the last packet was in error */ + +BOOL cli_is_error(struct cli_state *cli) +{ + uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; + + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + rcls = IVAL(cli->inbuf, smb_rcls); + else + rcls = CVAL(cli->inbuf, smb_rcls); + + return (rcls == 0); +} + +/* Return true if the last error was an NT error */ + +BOOL cli_is_nt_error(struct cli_state *cli) +{ + uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); + + return cli_is_error(cli) && (flgs2 & FLAGS2_32_BIT_ERROR_CODES); +} + +/* Return true if the last error was a DOS error */ + +BOOL cli_is_dos_error(struct cli_state *cli) +{ + uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); + + return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES); +} diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 215c500c30..66be21e3c5 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -745,7 +745,7 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) return False; } - if (cli_error(cli, NULL, NULL, NULL)) return False; + if (cli_is_error(cli)) return False; return True; } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e0287bf6c4..b7624486d6 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -204,12 +204,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, - &rdata, &data_len)) { + &rdata, &data_len) && + cli_is_dos_error(cli)) { /* we need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); + cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; msleep(100); continue; diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index e0a308104b..d32c5de042 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -53,7 +53,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, return False; } - if (cli_error(cli, NULL, NULL, NULL)) return False; + if (cli_is_error(cli)) return False; *grp = SVAL(cli->inbuf,smb_vwv0); @@ -89,7 +89,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) return False; } - if (cli_error(cli, NULL, NULL, NULL)) return False; + if (cli_is_error(cli)) return False; return True; } @@ -114,7 +114,7 @@ BOOL cli_message_end(struct cli_state *cli, int grp) return False; } - if (cli_error(cli, NULL, NULL, NULL)) return False; + if (cli_is_error(cli)) return False; return True; } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index c649aedfba..bfbe478191 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -329,7 +329,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE); - if (!make_oem_passwd_hash(dos_new_password, old_pw_hash, False, data)) + if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) return False; /* @@ -408,12 +408,12 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)); - if (!ret) { + if (!ret && cli_is_dos_error(cli)) { /* we need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); + cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; msleep(100); } diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 458532cb2e..f6ee78c567 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -55,8 +55,6 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { - uint32 ecode; - uint8 eclass; char *p; int size2; int readsize; @@ -83,15 +81,21 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ if (!cli_receive_smb(cli)) return -1; - /* - * Check for error. Because the client library doesn't support - * STATUS32, we need to check for and ignore the more data error - * for pipe support. - */ + /* Check for error. Make sure to check for DOS and NT + errors. */ - if (cli_error(cli, &eclass, &ecode, NULL) && - (eclass != ERRDOS && ecode != ERRmoredata)) { - return -1; + if (cli_is_error(cli)) { + uint32 status = 0; + uint8 eclass = 0; + + if (cli_is_nt_error(cli)) + status = cli_nt_error(cli); + else + cli_dos_error(cli, &eclass, &status); + + if ((eclass == ERRDOS && status == ERRmoredata) || + status == STATUS_MORE_ENTRIES) + return -1; } size2 = SVAL(cli->inbuf, smb_vwv5); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 68583c4199..ac50c7bf6d 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -169,12 +169,14 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, * be treated as such. */ - if (cli_error(cli, &eclass, &ecode, NULL)) + if (cli_is_dos_error(cli)) { - if(cli->nt_pipe_fnum == 0) + cli_dos_error(cli, &eclass, &ecode); + + if(cli->nt_pipe_fnum == 0) return(False); - if(!(eclass == ERRDOS && ecode == ERRmoredata)) { + if(!(eclass == ERRDOS && ecode == ERRmoredata)) { if (eclass != 0 && (ecode != (0x80000000 | STATUS_BUFFER_OVERFLOW))) return(False); } @@ -228,9 +230,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_error(cli, &eclass, &ecode, NULL)) - { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + if (cli_is_dos_error(cli)) { + cli_dos_error(cli, &eclass, &ecode); + if(cli->nt_pipe_fnum == 0 || + !(eclass == ERRDOS && ecode == ERRmoredata)) return(False); } } @@ -375,7 +378,8 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, * to a trans call. This is not an error and should not * be treated as such. */ - if (cli_error(cli, &eclass, &ecode, NULL)) { + if (cli_is_dos_error(cli)) { + cli_dos_error(cli, &eclass, &ecode); if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) return(False); } @@ -427,8 +431,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_error(cli, &eclass, &ecode, NULL)) { - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + if (cli_is_dos_error(cli)) { + cli_dos_error(cli, &eclass, &ecode); + if(cli->nt_pipe_fnum == 0 || + !(eclass == ERRDOS && ecode == ERRmoredata)) return(False); } } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b944174665..a86447a094 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -195,16 +195,27 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, int smbc_errno(struct cli_state *c) { - uint8 eclass; - uint32 ecode; int ret; - ret = cli_error(c, &eclass, &ecode, NULL); + if (cli_is_dos_error(c)) { + uint8 eclass; + uint32 ecode; + + cli_dos_error(c, &eclass, &ecode); + ret = cli_errno_from_dos(eclass, ecode); + + DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", + (int)eclass, (int)ecode, (int)ecode, ret)); + } else { + uint32 status; + + cli_nt_error(c, &status); + ret = cli_errno_from_nt(status); + + DEBUG(3,("smbc errno 0x%08x -> %d\n", + status, ret)); + } - if (ret) { - DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", - (int)eclass, (int)ecode, (int)ecode, ret)); - } return ret; } @@ -1445,8 +1456,6 @@ int smbc_opendir(const char *fname) struct smbc_server *srv = NULL; struct in_addr rem_ip; int slot = 0; - uint8 eclass; - uint32 ecode; if (!smbc_initialized) { @@ -1570,7 +1579,7 @@ int smbc_opendir(const char *fname) free(smbc_file_table[slot]); } smbc_file_table[slot] = NULL; - errno = cli_error(&srv->cli, &eclass, &ecode, NULL); + errno = cli_errno(dos_error(&srv->cli); return -1; } @@ -1641,7 +1650,7 @@ int smbc_opendir(const char *fname) free(smbc_file_table[slot]); } smbc_file_table[slot] = NULL; - errno = cli_error(&srv->cli, &eclass, &ecode, NULL); + errno = cli_error(&srv->cli); return -1; } @@ -1675,7 +1684,7 @@ int smbc_opendir(const char *fname) if (cli_RNetShareEnum(&srv->cli, list_fn, (void *)smbc_file_table[slot]) < 0) { - errno = cli_error(&srv->cli, &eclass, &ecode, NULL); + errno = cli_errno(&srv->cli); if (smbc_file_table[slot]) { if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); free(smbc_file_table[slot]); diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 36dd65cda2..1b8e8737f7 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -1,3 +1,24 @@ +/* + * Unix SMB/Netbios implementation. + * Version 1.9. + * RPC Pipe client / server routines + * Copyright (C) Luke Kenneth Casson Leighton 1997-2001. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + /* NT error codes. please read nterr.h */ #include "includes.h" @@ -519,33 +540,20 @@ nt_err_code_struct nt_errs[] = /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -BOOL get_safe_nt_error_msg(uint32 nt_code,char *msg, size_t len) +char *get_nt_error_msg(uint32 nt_code) { - int idx = 0; + static pstring msg; + int idx = 0; - slprintf(msg, len-1, "NT code 0x%08x", nt_code); + slprintf(msg, sizeof(msg), "NT code 0x%08x", nt_code); - while (nt_errs[idx].nt_errstr != NULL) - { - if ((nt_errs[idx].nt_errcode & 0xFFFFFF) == (nt_code & 0xFFFFFF)) - { - safe_strcpy(msg, nt_errs[idx].nt_errstr, len); - return True; + while (nt_errs[idx].nt_errstr != NULL) { + if ((nt_errs[idx].nt_errcode & 0xFFFFFF) == + (nt_code & 0xFFFFFF)) { + return nt_errs[idx].nt_errstr; } idx++; } - return False; -} -/***************************************************************************** - returns an NT error message. not amazingly helpful, but better than a number. - *****************************************************************************/ -char *get_nt_error_msg(uint32 nt_code) -{ - static pstring msg; - - get_safe_nt_error_msg(nt_code, msg, sizeof(msg)); return msg; } - - diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index e13b180fcb..95d21dc772 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -187,8 +187,7 @@ void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) #endif } -BOOL make_oem_passwd_hash(const char *passwd, uchar old_pw_hash[16], - BOOL unicode, char data[516]) +BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) { int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 924fa76d71..9648786ea5 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -36,34 +36,35 @@ typedef struct /* Dos Error Messages */ err_code_struct dos_msgs[] = { - {"ERRbadfunc",1,"Invalid function."}, - {"ERRbadfile",2,"File not found."}, - {"ERRbadpath",3,"Directory invalid."}, - {"ERRnofids",4,"No file descriptors available"}, - {"ERRnoaccess",5,"Access denied."}, - {"ERRbadfid",6,"Invalid file handle."}, + {"ERRbadfunc",ERRbadfunc,"Invalid function."}, + {"ERRbadfile",ERRbadfile,"File not found."}, + {"ERRbadpath",ERRbadpath,"Directory invalid."}, + {"ERRnofids",ERRnofids,"No file descriptors available"}, + {"ERRnoaccess",ERRnoaccess,"Access denied."}, + {"ERRbadfid",ERRbadfid,"Invalid file handle."}, {"ERRbadmcb",7,"Memory control blocks destroyed."}, - {"ERRnomem",8,"Insufficient server memory to perform the requested function."}, - {"ERRbadmem",9,"Invalid memory block address."}, - {"ERRbadenv",10,"Invalid environment."}, + {"ERRnomem",ERRnomem,"Insufficient server memory to perform the requested function."}, + {"ERRbadmem",ERRbadmem,"Invalid memory block address."}, + {"ERRbadenv",ERRbadenv,"Invalid environment."}, {"ERRbadformat",11,"Invalid format."}, - {"ERRbadaccess",12,"Invalid open mode."}, - {"ERRbaddata",13,"Invalid data."}, - {"ERR",14,"reserved."}, - {"ERRbaddrive",15,"Invalid drive specified."}, - {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."}, - {"ERRdiffdevice",17,"Not same device."}, - {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."}, - {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, - {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, - {"ERRunsup", 50, "The operation is unsupported"}, - {"ERRnosuchshare", 67, "You specified an invalid share name"}, - {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."}, - {"ERRbadpipe",230,"Pipe invalid."}, - {"ERRpipebusy",231,"All instances of the requested pipe are busy."}, - {"ERRpipeclosing",232,"Pipe close in progress."}, - {"ERRnotconnected",233,"No process on other end of pipe."}, - {"ERRmoredata",234,"There is more data to be returned."}, + {"ERRbadaccess",ERRbadaccess,"Invalid open mode."}, + {"ERRbaddata",ERRbaddata,"Invalid data."}, + {"ERR",ERRres,"reserved."}, + {"ERRbaddrive",ERRbaddrive,"Invalid drive specified."}, + {"ERRremcd",ERRremcd,"A Delete Directory request attempted to remove the server's current directory."}, + {"ERRdiffdevice",ERRdiffdevice,"Not same device."}, + {"ERRnofiles",ERRnofiles,"A File Search command can find no more files matching the specified criteria."}, + {"ERRbadshare",ERRbadshare,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, + {"ERRlock",ERRlock,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRunsup", ERRunsup, "The operation is unsupported"}, + {"ERRnosuchshare", ERRnosuchshare, "You specified an invalid share name"}, + {"ERRfilexists",ERRfilexists,"The file named in a Create Directory, Make New File or Link request already exists."}, + {"ERRinvalidname",ERRinvalidname, "Invalid name"}, + {"ERRbadpipe",ERRbadpipe,"Pipe invalid."}, + {"ERRpipebusy",ERRpipebusy,"All instances of the requested pipe are busy."}, + {"ERRpipeclosing",ERRpipeclosing,"Pipe close in progress."}, + {"ERRnotconnected",ERRnotconnected,"No process on other end of pipe."}, + {"ERRmoredata",ERRmoredata,"There is more data to be returned."}, {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"}, {NULL,-1,NULL}}; -- cgit From afbca61a28896696259911a087e0a002903c1399 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 06:16:05 +0000 Subject: Fixes for new client error api. (This used to be commit 9c57e45d443a3cf6215318d1355cac18ff57a8b5) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index a86447a094..581af9b957 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -209,7 +209,7 @@ int smbc_errno(struct cli_state *c) } else { uint32 status; - cli_nt_error(c, &status); + status = cli_nt_error(c); ret = cli_errno_from_nt(status); DEBUG(3,("smbc errno 0x%08x -> %d\n", @@ -1579,7 +1579,7 @@ int smbc_opendir(const char *fname) free(smbc_file_table[slot]); } smbc_file_table[slot] = NULL; - errno = cli_errno(dos_error(&srv->cli); + errno = cli_errno(&srv->cli); return -1; } -- cgit From ea43baeeb01dd302f3c5bfecb5d642228b029c3c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 06:46:11 +0000 Subject: Had the test for cli_is_error() reversed. You idiot Stimpy! (This used to be commit e9ceb17d777f4bcb7a9ff6b509c178f063be4722) --- source3/libsmb/clierror.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index c2234e8ead..bb2bbd0dff 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -260,7 +260,7 @@ BOOL cli_is_error(struct cli_state *cli) else rcls = CVAL(cli->inbuf, smb_rcls); - return (rcls == 0); + return (rcls != 0); } /* Return true if the last error was an NT error */ -- cgit From 5c47841335059ace57dfbf03e35872504d86b447 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 07:41:18 +0000 Subject: Debug cleanups. (This used to be commit e98f9481235dce9a0a76450b84769b86eca57ca2) --- source3/libsmb/clierror.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index bb2bbd0dff..022e808fea 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -115,7 +115,7 @@ uint32 cli_nt_error(struct cli_state *cli) came back does not contain one. What do we return here? */ - DEBUG(1, ("ERROR: cli_error() called to read a status code " + DEBUG(1, ("ERROR: cli_nt_error() called to read a status code " "from a packet that does not contain one!\n")); return NT_STATUS_UNSUCCESSFUL; @@ -152,8 +152,8 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *num) came back does not contain one. What do we return here? */ - DEBUG(1, ("ERROR: cli_error() called to read a dos error code " - "from a packet that does not contain one!\n")); + DEBUG(1, ("ERROR: cli_dos_error() called to read a dos error " + "code from a packet that does not contain one!\n")); return; } -- cgit From acc149c427e780b35ebe3028722ed0c42c4c3854 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 10 Aug 2001 09:52:10 +0000 Subject: - avoid possible mem leaks in rpcclient/cmd_*.c (talloc_destroy not performed) - ported two rpc back from TNG (WINREG: shutdown and abort shutdown) - some optimizations and changed some DEBUG statement in loadparm.c - changed rpcclient a bit moved from non reentrant next_token_nr to next_token - in cmd_reg.c not sure if getopt will work ok on all platforms only setting optind=0 (This used to be commit fd54412ce9c3504a547e232602d6129e08dd9d4d) --- source3/libsmb/cli_reg.c | 116 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 source3/libsmb/cli_reg.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c new file mode 100644 index 0000000000..42fea91874 --- /dev/null +++ b/source3/libsmb/cli_reg.c @@ -0,0 +1,116 @@ + +/* + Unix SMB/Netbios implementation. + Version 2.2 + RPC Pipe client + + Copyright (C) Andrew Tridgell 1992-1998, + Copyright (C) Luke Kenneth Casson Leighton 1996-1998, + Copyright (C) Paul Ashton 1997-1998. + Copyright (C) Jeremy Allison 1999. + Copyright (C) Simo Sorce 2000 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* Opens a SMB connection to the WINREG pipe */ +struct cli_state *cli_winreg_initialise(struct cli_state *cli, + char *system_name, + struct ntuser_creds *creds) +{ + return cli_pipe_initialise(cli, system_name, PIPE_WINREG, creds); +} + +/* Shutdown a server */ + +uint32 cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, + const char *srv_name, const char *msg, + uint32 timeout, uint16 flags) +{ + prs_struct qbuf; + prs_struct rbuf; + REG_Q_SHUTDOWN q_s; + REG_R_SHUTDOWN r_s; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + if (msg == NULL) return False; + + ZERO_STRUCT (q_s); + ZERO_STRUCT (r_s); + + prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_reg_q_shutdown(&q_s, msg, timeout, flags); + + if (!reg_io_q_shutdown("", &q_s, &qbuf, 0) || + !rpc_api_pipe_req(cli, REG_SHUTDOWN, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if(reg_io_r_shutdown("", &r_s, &rbuf, 0)) + result = r_s.status; + +done: + prs_mem_free(&rbuf); + prs_mem_free(&qbuf); + + return result; +} + + +/* Abort a server shutdown */ + +uint32 cli_reg_abort_shutdown(struct cli_state * cli, + TALLOC_CTX *mem_ctx, + const char *srv_name) +{ + prs_struct rbuf; + prs_struct qbuf; + REG_Q_ABORT_SHUTDOWN q_s; + REG_R_ABORT_SHUTDOWN r_s; + uint32 result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT (q_s); + ZERO_STRUCT (r_s); + + prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_reg_q_abort_shutdown(&q_s); + + if (!reg_io_q_abort_shutdown("", &q_s, &qbuf, 0) || + !rpc_api_pipe_req(cli, REG_ABORT_SHUTDOWN, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0)) + result = r_s.status; + +done: + prs_mem_free(&rbuf); + prs_mem_free(&qbuf ); + + return result; +} + -- cgit From 6ad80352dd2523c310258de3211a2af0f1763d2a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 12 Aug 2001 11:19:57 +0000 Subject: This patch does a number of things, mostly smaller than they look :-) In particuar, it moves the domain_client_validate stuff out of auth_domain.c to somwhere where they (I hope) they can be shared with winbind better. (This may need some work) The main purpose of this patch was however to improve some of the internal documentation and to correctly place become_root()/unbecome_root() calls within the code. Finally this patch moves some more of auth.c into other files, auth_unix.c in this case. Andrew Bartlett (This used to be commit ea1c547ac880def29f150de2172c95213509350e) --- source3/libsmb/domain_client_validate.c | 363 ++++++++++++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100644 source3/libsmb/domain_client_validate.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c new file mode 100644 index 0000000000..de5df84e9b --- /dev/null +++ b/source3/libsmb/domain_client_validate.c @@ -0,0 +1,363 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Authenticate against a remote domain + Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Andrew Bartlett 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +extern int DEBUGLEVEL; +extern struct in_addr ipzero; + +extern pstring global_myname; + +/*********************************************************************** + Connect to a remote machine for domain security authentication + given a name or IP address. + ***********************************************************************/ + +static BOOL connect_to_domain_password_server(struct cli_state *pcli, + char *server, unsigned char *trust_passwd) +{ + struct in_addr dest_ip; + fstring remote_machine; + + if(cli_initialise(pcli) == NULL) { + DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); + return False; + } + + if (is_ipaddress(server)) { + struct in_addr to_ip; + + /* we shouldn't have 255.255.255.255 forthe IP address of + a password server anyways */ + if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) { + DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server)); + return False; + } + + if (!name_status_find(0x20, to_ip, remote_machine)) { + DEBUG(0, ("connect_to_domain_password_server: Can't " + "resolve name for IP %s\n", server)); + return False; + } + } else { + fstrcpy(remote_machine, server); + } + + standard_sub_basic(remote_machine); + strupper(remote_machine); + + if(!resolve_name( remote_machine, &dest_ip, 0x20)) { + DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (ismyip(dest_ip)) { + DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (!cli_connect(pcli, remote_machine, &dest_ip)) { + DEBUG(0,("connect_to_domain_password_server: unable to connect to SMB server on \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (!attempt_netbios_session_request(pcli, global_myname, remote_machine, &dest_ip)) { + DEBUG(0,("connect_to_password_server: machine %s rejected the NetBIOS \ +session request. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + return False; + } + + pcli->protocol = PROTOCOL_NT1; + + if (!cli_negprot(pcli)) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the negotiate protocol. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (pcli->protocol != PROTOCOL_NT1) { + DEBUG(0,("connect_to_domain_password_server: machine %s didn't negotiate NT protocol.\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + /* + * Do an anonymous session setup. + */ + + if (!cli_session_setup(pcli, "", "", 0, "", 0, "")) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (!(pcli->sec_mode & 1)) { + DEBUG(1,("connect_to_domain_password_server: machine %s isn't in user level security mode\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (!cli_send_tconX(pcli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the tconX on the IPC$ share. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + /* + * We now have an anonymous connection to IPC$ on the domain password server. + */ + + /* + * Even if the connect succeeds we need to setup the netlogon + * pipe here. We do this as we may just have changed the domain + * account password on the PDC and yet we may be talking to + * a BDC that doesn't have this replicated yet. In this case + * a successful connect to a DC needs to take the netlogon connect + * into account also. This patch from "Bjart Kvarme" . + */ + + if(cli_nt_session_open(pcli, PIPE_NETLOGON) == False) { + DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); + cli_nt_session_close(pcli); + cli_ulogoff(pcli); + cli_shutdown(pcli); + return False; + } + + if (cli_nt_setup_creds(pcli, trust_passwd) == False) { + DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ +%s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); + cli_nt_session_close(pcli); + cli_ulogoff(pcli); + cli_shutdown(pcli); + return(False); + } + + return True; +} + +/*********************************************************************** + Utility function to attempt a connection to an IP address of a DC. +************************************************************************/ + +static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, + unsigned char *trust_passwd) +{ + fstring dc_name; + + /* + * Ignore addresses we have already tried. + */ + + if (ip_equal(ipzero, *ip)) + return False; + + if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) + return False; + + return connect_to_domain_password_server(pcli, dc_name, trust_passwd); +} + +/*********************************************************************** + We have been asked to dynamcially determine the IP addresses of + the PDC and BDC's for this DOMAIN, and query them in turn. +************************************************************************/ +static BOOL find_connect_pdc(struct cli_state *pcli, + unsigned char *trust_passwd, + time_t last_change_time) +{ + struct in_addr *ip_list = NULL; + int count = 0; + int i; + BOOL connected_ok = False; + time_t time_now = time(NULL); + BOOL use_pdc_only = False; + + /* + * If the time the machine password has changed + * was less than an hour ago then we need to contact + * the PDC only, as we cannot be sure domain replication + * has yet taken place. Bug found by Gerald (way to go + * Gerald !). JRA. + */ + + if (time_now - last_change_time < 3600) + use_pdc_only = True; + + if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count)) + return False; + + /* + * Firstly try and contact a PDC/BDC who has the same + * network address as any of our interfaces. + */ + for(i = 0; i < count; i++) { + if(!is_local_net(ip_list[i])) + continue; + + if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + break; + + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Secondly try and contact a random PDC/BDC. + */ + if(!connected_ok) { + i = (sys_random() % count); + + if (!(connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Finally go through the IP list in turn, ignoring any addresses + * we have already tried. + */ + if(!connected_ok) { + /* + * Try and connect to any of the other IP addresses in the PDC/BDC list. + * Note that from a WINS server the #1 IP address is the PDC. + */ + for(i = 0; i < count; i++) { + if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + break; + } + } + + if(ip_list != NULL) + free((char *)ip_list); + + + return connected_ok; +} + +/*********************************************************************** + Do the same as security=server, but using NT Domain calls and a session + key from the machine password. If the server parameter is specified + use it, otherwise figure out a server from the 'password server' param. +************************************************************************/ + +uint32 domain_client_validate(const auth_usersupplied_info *user_info, + auth_serversupplied_info *server_info, + char *server, unsigned char *trust_passwd, + time_t last_change_time) +{ + fstring remote_machine; + NET_ID_INFO_CTR ctr; + NET_USER_INFO_3 info3; + struct cli_state cli; + uint32 smb_uid_low; + BOOL connected_ok = False; + uint32 nt_status; + + /* + * Check that the requested domain is not our own machine name. + * If it is, we should never check the PDC here, we use our own local + * password file. + */ + + if(strequal(user_info->domain.str, global_myname)) { + DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); + return NT_STATUS_LOGON_FAILURE; + } + + /* + * At this point, smb_apasswd points to the lanman response to + * the challenge in local_challenge, and smb_ntpasswd points to + * the NT response to the challenge in local_challenge. Ship + * these over the secure channel to a domain controller and + * see if they were valid. + */ + + ZERO_STRUCT(cli); + + while (!connected_ok && + next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) { + if(strequal(remote_machine, "*")) { + connected_ok = find_connect_pdc(&cli, trust_passwd, last_change_time); + } else { + connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); + } + } + + if (!connected_ok) { + DEBUG(0,("domain_client_validate: Domain password server not available.\n")); + cli_shutdown(&cli); + return NT_STATUS_LOGON_FAILURE; + } + + /* We really don't care what LUID we give the user. */ + generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); + + ZERO_STRUCT(info3); + + if (!cli_nt_login_network(&cli, user_info, smb_uid_low, &ctr, &info3)) { + nt_status = cli_nt_error(&cli); + DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ +%s to Domain controller %s. Error was %s.\n", user_info->smb_username.str, user_info->domain.str, remote_machine, cli_errstr(&cli))); + } else { + nt_status = NT_STATUS_NOPROBLEMO; + } + + /* + * Here, if we really want it, we have lots of info about the user in info3. + */ + +#if 0 + /* + * We don't actually need to do this - plus it fails currently with + * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to + * send here. JRA. + */ + + if (nt_status == NT_STATUS_NOPROBLMO) { + if(cli_nt_logoff(&cli, &ctr) == False) { + DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ +%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); + nt_status = NT_STATUS_LOGON_FAILURE; + } + } +#endif /* 0 */ + + /* Note - once the cli stream is shutdown the mem_ctx used + to allocate the other_sids and gids structures has been deleted - so + these pointers are no longer valid..... */ + + cli_nt_session_close(&cli); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return nt_status; +} + -- cgit From 2e783a47076bd0994b6ce86df7ec967bc1c2da63 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 12 Aug 2001 17:30:01 +0000 Subject: this is a big global fix for the ptr = Realloc(ptr, size) bug. many possible mem leaks, and segfaults fixed. someone should port this fix to 2.2 also. (This used to be commit fa8e55b8b465114ce209344965c1ca0333b84db9) --- source3/libsmb/clilist.c | 19 ++++++++++++------- source3/libsmb/clitrans.c | 30 ++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index b7624486d6..609f5f2331 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -141,7 +141,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, pstring mask; file_info finfo; int i; - char *dirlist = NULL; + char *tdl, *dirlist = NULL; int dirlist_len = 0; int total_received = -1; BOOL First = True; @@ -259,12 +259,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } /* and add them to the dirlist pool */ - dirlist = Realloc(dirlist,dirlist_len + data_len); + tdl = Realloc(dirlist,dirlist_len + data_len); - if (!dirlist) { - DEBUG(0,("Failed to expand dirlist\n")); + if (!tdl) { + DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); break; } + else dirlist = tdl; /* put in a length for the last entry, to ensure we can chain entries into the next packet */ @@ -340,7 +341,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; int num_received = 0; int i; - char *dirlist = NULL; + char *tdl, *dirlist = NULL; pstring mask; ZERO_ARRAY(status); @@ -385,10 +386,14 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, first = False; - dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + tdl = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); - if (!dirlist) + if (!tdl) { + DEBUG(0,("cli_list_old: failed to expand dirlist")); + if (dirlist) free(dirlist); return 0; + } + else dirlist = tdl; p = smb_buf(cli->inbuf) + 3; diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index ac50c7bf6d..c4e19b9375 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -147,6 +147,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, int this_data,this_param; uint8 eclass; uint32 ecode; + char *tdata; *data_len = *param_len = 0; @@ -187,8 +188,18 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, total_param = SVAL(cli->inbuf,smb_tprcnt); /* allocate it */ - *data = Realloc(*data,total_data); - *param = Realloc(*param,total_param); + tdata = Realloc(*data,total_data); + if (!tdata) { + DEBUG(0,("cli_receive_trans: failed to enlarge buffer")); + return False; + } + else *data = tdata; + tdata = Realloc(*param,total_param); + if (!tdata) { + DEBUG(0,("cli_receive_trans: failed to enlarge buffer")); + return False; + } + else *param = tdata; while (1) { this_data = SVAL(cli->inbuf,smb_drcnt); @@ -358,6 +369,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, int this_data,this_param; uint8 eclass; uint32 ecode; + char *tdata; *data_len = *param_len = 0; @@ -389,8 +401,18 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); /* allocate it */ - *data = Realloc(*data,total_data); - *param = Realloc(*param,total_param); + tdata = Realloc(*data,total_data); + if (!tdata) { + DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer")); + return False; + } + else *data = tdata; + tdata = Realloc(*param,total_param); + if (!tdata) { + DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer")); + return False; + } + else *param = tdata; while (1) { this_data = SVAL(cli->inbuf,smb_ntr_DataCount); -- cgit From 4da562d4dc6d197c3a7495672638e0f14838d38c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 12 Aug 2001 23:53:26 +0000 Subject: Fixed crash bug when attempting to list contents of non-existent directory. (This used to be commit a7863f0f033b31838a53960e9f616d9a82081ecf) --- source3/libsmb/clilist.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 609f5f2331..a7ba1c07ad 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -216,6 +216,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, continue; } + if (cli_is_error(cli)) + return -1; + if (total_received == -1) total_received = 0; /* parse out some important return info */ -- cgit From ccb927b17ca3194118b9dfc9a5a533b62a448ec7 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 17 Aug 2001 17:07:40 +0000 Subject: more useful debug messages and check if the size are non null. that fix the notification backend channel for spoolss. J.F. (This used to be commit 5e9a36bd9c1aa1a28f042ec9016a097215e4539e) --- source3/libsmb/clitrans.c | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index c4e19b9375..c97ddfc331 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -188,18 +188,25 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, total_param = SVAL(cli->inbuf,smb_tprcnt); /* allocate it */ - tdata = Realloc(*data,total_data); - if (!tdata) { - DEBUG(0,("cli_receive_trans: failed to enlarge buffer")); - return False; + if (total_data!=0) { + tdata = Realloc(*data,total_data); + if (!tdata) { + DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); + return False; + } + else + *data = tdata; } - else *data = tdata; - tdata = Realloc(*param,total_param); - if (!tdata) { - DEBUG(0,("cli_receive_trans: failed to enlarge buffer")); - return False; + + if (total_param!=0) { + tdata = Realloc(*param,total_param); + if (!tdata && total_param!=0) { + DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); + return False; + } + else + *param = tdata; } - else *param = tdata; while (1) { this_data = SVAL(cli->inbuf,smb_drcnt); -- cgit From 556c8f3fbfd060ff865bb6854393018cc9e86828 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Aug 2001 18:16:42 +0000 Subject: Use tparam not tdata when reallocing params to make clearer. Jeremy. (This used to be commit 31804cb7a89f280cec4c047cad643c7f593f9b03) --- source3/libsmb/clitrans.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index c97ddfc331..83912ddc6d 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -148,6 +148,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, uint8 eclass; uint32 ecode; char *tdata; + char *tparam; *data_len = *param_len = 0; @@ -170,14 +171,13 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, * be treated as such. */ - if (cli_is_dos_error(cli)) - { - cli_dos_error(cli, &eclass, &ecode); + if (cli_is_dos_error(cli)) { + cli_dos_error(cli, &eclass, &ecode); - if(cli->nt_pipe_fnum == 0) + if(cli->nt_pipe_fnum == 0) return(False); - if(!(eclass == ERRDOS && ecode == ERRmoredata)) { + if(!(eclass == ERRDOS && ecode == ERRmoredata)) { if (eclass != 0 && (ecode != (0x80000000 | STATUS_BUFFER_OVERFLOW))) return(False); } @@ -199,13 +199,13 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, } if (total_param!=0) { - tdata = Realloc(*param,total_param); - if (!tdata && total_param!=0) { + tparam = Realloc(*param,total_param); + if (!tparam) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); return False; } else - *param = tdata; + *param = tparam; } while (1) { @@ -377,6 +377,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, uint8 eclass; uint32 ecode; char *tdata; + char *tparam; *data_len = *param_len = 0; @@ -413,13 +414,15 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer")); return False; } - else *data = tdata; - tdata = Realloc(*param,total_param); - if (!tdata) { + else + *data = tdata; + tparam = Realloc(*param,total_param); + if (!tparam) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer")); return False; } - else *param = tdata; + else + *param = tparam; while (1) { this_data = SVAL(cli->inbuf,smb_ntr_DataCount); -- cgit From 9326b82ffa255196ab68a23bf3f4ff14a7fd9bda Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 19 Aug 2001 17:34:37 +0000 Subject: Realloc fix. Jeremy. (This used to be commit 9cabc3fd63d7780eb5d80eb7619fd7606d9da3b8) --- source3/libsmb/namequery.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c5c4d92c09..a0fb366f1b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -335,6 +335,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, while (1) { struct timeval tval2; + struct in_addr *tmp_ip_list; + GetTimeOfDay(&tval2); if (TvalDiff(&tval,&tval2) > retry_time) { if (!retries) @@ -398,9 +400,17 @@ struct in_addr *name_query(int fd,const char *name,int name_type, continue; } - ip_list = (struct in_addr *)Realloc( ip_list, - sizeof( ip_list[0] ) - * ( (*count) + nmb2->answers->rdlength/6 ) ); + tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] ) + * ( (*count) + nmb2->answers->rdlength/6 ) ); + + if (!tmp_ip_list) { + DEBUG(0,("name_query: Realloc failed.\n")); + if (ip_list) + free(ip_list); + } + + ip_list = tmp_ip_list; + if (ip_list) { DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); -- cgit From 11ce0f4d2d493702386c0bd49c8e2dd2aad84d56 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Aug 2001 05:15:26 +0000 Subject: a bunch of fixes from the sflight to seattle in particular: - fixed NT status code for a bunch of ops - fixed handling of protocol levels in ms_fnmatch (This used to be commit 3eba9606f71f90bfd9820af26f8676277ed22390) --- source3/libsmb/cliconnect.c | 1 - source3/libsmb/clilist.c | 2 +- source3/libsmb/clitrans.c | 17 ++++++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index dffff5e6ab..982ac544cf 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -414,7 +414,6 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a7ba1c07ad..e727217628 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -216,7 +216,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, continue; } - if (cli_is_error(cli)) + if (cli_is_error(cli) || !rdata || !rparam) return -1; if (total_received == -1) total_received = 0; diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 83912ddc6d..4822508e38 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -171,16 +171,19 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, * be treated as such. */ - if (cli_is_dos_error(cli)) { - cli_dos_error(cli, &eclass, &ecode); - - if(cli->nt_pipe_fnum == 0) - return(False); + if (cli_is_error(cli)) { + if (cli_is_dos_error(cli)) { + cli_dos_error(cli, &eclass, &ecode); - if(!(eclass == ERRDOS && ecode == ERRmoredata)) { - if (eclass != 0 && (ecode != (0x80000000 | STATUS_BUFFER_OVERFLOW))) + if(cli->nt_pipe_fnum == 0) return(False); + + if(!(eclass == ERRDOS && ecode == ERRmoredata)) { + if (eclass != 0 && (ecode != (0x80000000 | STATUS_BUFFER_OVERFLOW))) + return(False); + } } + return False; } /* parse out the lengths */ -- cgit From 4294f6f2c80cb81fdf872bee87e171640e3601fe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Aug 2001 18:05:12 +0000 Subject: allow for the NULL in make_nmb_name() (This used to be commit b6c78d4c6fde2065678dd62bbd9dd4af9c5e805b) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9d7167f305..6a24cb382c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -831,7 +831,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) { extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); - push_ascii(n->name, name, 15, STR_TERMINATE|STR_UPPER); + push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope, 63 ); strupper( n->scope ); -- cgit From 1b7fab220f7b30c7ddd73c00544902332ce8525d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 21 Aug 2001 03:04:41 +0000 Subject: Distinguish between NT informational and error codes. (This used to be commit 02fe0e18dfcb8cc83b3cf0b6c8dd4dc1ddb7e196) --- source3/libsmb/clierror.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 022e808fea..59a11dcc60 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -255,12 +255,18 @@ BOOL cli_is_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { + + /* Return error is error bits are set */ + rcls = IVAL(cli->inbuf, smb_rcls); - else - rcls = CVAL(cli->inbuf, smb_rcls); + return (rcls & 0xF0000000) == 0xC0000000; + } + + /* Return error if error class in non-zero */ - return (rcls != 0); + rcls = CVAL(cli->inbuf, smb_rcls); + return rcls != 0; } /* Return true if the last error was an NT error */ -- cgit From 4a273d209b8e588ccadb37bb316830bc251c5adf Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 21 Aug 2001 03:05:27 +0000 Subject: Added cli_lsa_open_policy2() (This used to be commit afaafc3e5a2adef4736196aa5f4e6ca25a0571d2) --- source3/libsmb/cli_lsarpc.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index e4b6683389..8cf0817420 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -89,6 +89,64 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Open a LSA policy handle */ + +uint32 cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, + BOOL sec_qos, uint32 des_access, POLICY_HND *pol) +{ + prs_struct qbuf, rbuf; + LSA_Q_OPEN_POL2 q; + LSA_R_OPEN_POL2 r; + LSA_SEC_QOS qos; + uint32 result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + if (sec_qos) { + init_lsa_sec_qos(&qos, 2, 1, 0, des_access); + init_q_open_pol2(&q, cli->clnt_name_slash, 0, des_access, + &qos); + } else { + init_q_open_pol2(&q, cli->clnt_name_slash, 0, des_access, + NULL); + } + + /* Marshall data and send request */ + + if (!lsa_io_q_open_pol2("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_OPENPOLICY2, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_open_pol2("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + *pol = r.pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Close a LSA policy handle */ uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, -- cgit From 75eae84b1c90f9874dd4e6ef34fd6fd72322689a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Aug 2001 03:50:31 +0000 Subject: string terminate in mkdir (This used to be commit fe414d5e1afdfe7bb20ff5da60394ffd9fa81b05) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 66be21e3c5..b1be4aafc5 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -116,7 +116,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, dname, -1, 0); + p += clistr_push(cli, p, dname, -1, STR_TERMINATE); cli_setup_bcc(cli, p); -- cgit From 8d9cdf0d749413c1575b6cc44bfeed3f0605a526 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Aug 2001 02:47:38 +0000 Subject: a fix for directory listing with the dave/thursby client (This used to be commit 5a3fd3317e0fedd72450660f031b5ba42a11b875) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e727217628..6368674488 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -217,7 +217,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } if (cli_is_error(cli) || !rdata || !rparam) - return -1; + break; if (total_received == -1) total_received = 0; -- cgit From c5004cf0e6014fd8b1776c7d717560b347495bed Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Aug 2001 22:39:39 +0000 Subject: added port 445 support to our client code (This used to be commit 0c3120ae475fb53662d6ab9f0d96a832c3c90625) --- source3/libsmb/cliconnect.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 982ac544cf..eb14f54b1a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -269,8 +269,13 @@ BOOL cli_send_tconX(struct cli_state *cli, } } - slprintf(fullshare, sizeof(fullshare)-1, - "\\\\%s\\%s", cli->desthost, share); + if (cli->port == 445) { + slprintf(fullshare, sizeof(fullshare)-1, + "%s", share); + } else { + slprintf(fullshare, sizeof(fullshare)-1, + "\\\\%s\\%s", "foo", share); + } set_message(cli->outbuf,4, 0, True); CVAL(cli->outbuf,smb_com) = SMBtconX; @@ -474,6 +479,9 @@ BOOL cli_session_request(struct cli_state *cli, int len = 4; extern pstring user_socket_options; + /* 445 doesn't have session request */ + if (cli->port == 445) return True; + /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); @@ -578,13 +586,19 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) cli->dest_ip = *ip; } - if (cli->port == 0) cli->port = 139; /* Set to default */ - if (getenv("LIBSMB_PROG")) { cli->fd = sock_exec(getenv("LIBSMB_PROG")); } else { + /* try 445 first, then 139 */ + int port = cli->port?cli->port:445; cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, - cli->port, cli->timeout); + port, cli->timeout); + if (cli->fd == -1 && cli->port == 0) { + port = 139; + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + port, cli->timeout); + } + if (cli->fd != -1) cli->port = port; } if (cli->fd == -1) return False; -- cgit From c45fbe69f5b7a57fea9ba18cfa47e63b42de7992 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 23 Aug 2001 16:25:57 +0000 Subject: better error reporting for servers that don't do port 445 (This used to be commit a896dc299eba12886d800e6c88309d534232cabc) --- source3/libsmb/cliconnect.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index eb14f54b1a..31b3541376 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -600,8 +600,11 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } if (cli->fd != -1) cli->port = port; } - if (cli->fd == -1) + if (cli->fd == -1) { + DEBUG(1,("Error connecting to %s (%s)\n", + inet_ntoa(*ip),strerror(errno))); return False; + } set_socket_options(cli->fd,user_socket_options); -- cgit From f3c1c25b97254c89e637e14d535ba97e1717e76c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 23 Aug 2001 23:15:18 +0000 Subject: use 32 bit locking if client doesn't do 64 bit (This used to be commit 759ca19f3223c28e3e3478b4001251d2cb0fbfd6) --- source3/libsmb/clifile.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index b1be4aafc5..c325d882c9 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -489,6 +489,10 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, int saved_timeout = cli->timeout; int ltype; + if (! (cli->capabilities & CAP_LARGE_FILES)) { + return cli_lock(cli, fnum, offset, len, timeout, lock_type); + } + ltype = (lock_type == READ_LOCK? 1 : 0); ltype |= LOCKING_ANDX_LARGE_FILES; @@ -540,6 +544,10 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ { char *p; + if (! (cli->capabilities & CAP_LARGE_FILES)) { + return cli_unlock(cli, fnum, offset, len); + } + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); -- cgit From a350db7c7cc19876045f20a84b41953fd6a346ac Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2001 04:53:39 +0000 Subject: fixed shortname length in trans2 list (This used to be commit ae669720d8f434a23397deaea3371998ab6f1f54) --- source3/libsmb/clilist.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 6368674488..562e1710d3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -71,6 +71,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; + /* check for unisys! */ p += clistr_pull(cli, finfo->name, p, sizeof(finfo->name), len, @@ -114,7 +115,7 @@ static int interpret_long_filename(struct cli_state *cli, if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), - 24, flags); + slen, flags); } p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, -- cgit From 31b6b7aecdca9086e4cbbb7ae89fd6d6ca84928d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 24 Aug 2001 19:09:37 +0000 Subject: Make domain_client_validate return a status code instead of a boolean. (This used to be commit b4e79ab34b7df4687966f4ca81b575dce8503775) --- source3/libsmb/domain_client_validate.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index de5df84e9b..5c56a815ef 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -280,7 +280,7 @@ uint32 domain_client_validate(const auth_usersupplied_info *user_info, struct cli_state cli; uint32 smb_uid_low; BOOL connected_ok = False; - uint32 nt_status; + uint32 status; /* * Check that the requested domain is not our own machine name. @@ -323,12 +323,16 @@ uint32 domain_client_validate(const auth_usersupplied_info *user_info, ZERO_STRUCT(info3); - if (!cli_nt_login_network(&cli, user_info, smb_uid_low, &ctr, &info3)) { - nt_status = cli_nt_error(&cli); - DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user_info->smb_username.str, user_info->domain.str, remote_machine, cli_errstr(&cli))); + if ((status = cli_nt_login_network(&cli, user_info, smb_uid_low, + &ctr, &info3)) + != NT_STATUS_NOPROBLEMO) { + DEBUG(0,("domain_client_validate: unable to validate password " + "for user %s in domain %s to Domain controller %s. " + "Error was %s.\n", user_info->smb_username.str, + user_info->domain.str, remote_machine, + get_nt_error_msg(status))); } else { - nt_status = NT_STATUS_NOPROBLEMO; + status = NT_STATUS_NOPROBLEMO; } /* @@ -342,11 +346,11 @@ uint32 domain_client_validate(const auth_usersupplied_info *user_info, * send here. JRA. */ - if (nt_status == NT_STATUS_NOPROBLMO) { + if (status == NT_STATUS_NOPROBLMO) { if(cli_nt_logoff(&cli, &ctr) == False) { DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ %s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); - nt_status = NT_STATUS_LOGON_FAILURE; + status = NT_STATUS_LOGON_FAILURE; } } #endif /* 0 */ @@ -358,6 +362,6 @@ uint32 domain_client_validate(const auth_usersupplied_info *user_info, cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); - return nt_status; + return status; } -- cgit From 705fb73e5083b40bee0d3428337051b689368337 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 24 Aug 2001 19:52:01 +0000 Subject: Fixed debug in cli_establish_connection() - print out the called name on connection failure rather than the calling name. (This used to be commit 946f6eb9320c9897942adee8b513d8caaa3232c0) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 31b3541376..1628139dd9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -687,7 +687,7 @@ BOOL cli_establish_connection(struct cli_state *cli, if (!cli_connect(cli, dest_host, dest_ip)) { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(calling), inet_ntoa(*dest_ip))); + nmb_namestr(called), inet_ntoa(*dest_ip))); return False; } } -- cgit From 464237cdb8d4f4c4c93d9cf24f38f2720ea99b9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2001 20:11:09 +0000 Subject: fixed handling of 139/445 in clients (This used to be commit 22b372f8a7996a19bebb8cdb411df999cffa32a4) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1628139dd9..8230edbd63 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -274,7 +274,7 @@ BOOL cli_send_tconX(struct cli_state *cli, "%s", share); } else { slprintf(fullshare, sizeof(fullshare)-1, - "\\\\%s\\%s", "foo", share); + "\\\\%s\\%s", cli->desthost, share); } set_message(cli->outbuf,4, 0, True); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5ddfa48ac0..b3933f41e0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,10 +31,8 @@ extern int DEBUGLEVEL; */ int cli_set_port(struct cli_state *cli, int port) { - if (port > 0) - cli->port = port; - - return cli->port; + cli->port = port; + return port; } /**************************************************************************** -- cgit From 364d0e56e94718ad49bca4d6dcc95dee8e4e85e5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Aug 2001 20:20:08 +0000 Subject: Re-added readbraw call to test with smbtorture. This code not yet tested... Jeremy. (This used to be commit fe85a19b4b9db5910ad8259890f94c9496e1aebf) --- source3/libsmb/clireadwrite.c | 89 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index f6ee78c567..6566acf4ef 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -24,7 +24,7 @@ #include "includes.h" /**************************************************************************** -issue a single SMBread and don't wait for a reply +Issue a single SMBread and don't wait for a reply. ****************************************************************************/ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, @@ -49,6 +49,31 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, return cli_send_smb(cli); } +/**************************************************************************** +Issue a single SMBreadraw and don't wait for a reply. +****************************************************************************/ + +static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, + size_t size, int i) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadbraw; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SIVAL(cli->outbuf,smb_vwv1,offset); + SSVAL(cli->outbuf,smb_vwv2,size); + SSVAL(cli->outbuf,smb_vwv3,size); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + return cli_send_smb(cli); +} + /**************************************************************************** Read size bytes at offset offset using SMBreadX. ****************************************************************************/ @@ -127,6 +152,68 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return total; } +/**************************************************************************** + Tester for the readraw call. +****************************************************************************/ + +ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +{ + char *p; + int size2; + size_t readsize; + ssize_t total = 0; + + if (size == 0) + return 0; + + /* + * Set readsize to the maximum size we can handle in one readraw. + */ + + readsize = 0xFFFF; + + while (total < size) { + readsize = MIN(readsize, size-total); + + /* Issue a read and receive a reply */ + + if (!cli_issue_readraw(cli, fnum, offset, readsize, 0)) + return -1; + + if (!client_receive_smb(cli->fd, cli->inbuf, cli->timeout)) + return -1; + + size2 = smb_len(cli->inbuf); + + if (size2 > readsize) { + DEBUG(5,("server returned more than we wanted!\n")); + return -1; + } else if (size2 < 0) { + DEBUG(5,("read return < 0!\n")); + return -1; + } + + /* Copy data into buffer */ + + if (size2) { + p = cli->inbuf + 4; + memcpy(buf + total, p, size2); + } + + total += size2; + offset += size2; + + /* + * If the server returned less than we asked for we're at EOF. + */ + + if (size2 < readsize) + break; + } + + return total; +} + /**************************************************************************** issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -- cgit From 717533483b41ef975953f58e0c6be04828a3d467 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 24 Aug 2001 20:32:01 +0000 Subject: get rid of compiler warnings (This used to be commit 0768991d04ea03e774ca8662c9cae5e1951b88e0) --- source3/libsmb/smbencrypt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 95d21dc772..b6273dedfc 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -67,7 +67,7 @@ void E_md4hash(uchar *passwd, uchar *p16) if(len > 128) len = 128; /* Password must be converted to NT unicode - null terminated. */ - push_ucs2(NULL, wpwd, passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); + push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); /* Calculate length in bytes */ len = strlen_w(wpwd) * sizeof(int16); @@ -125,8 +125,8 @@ void ntv2_owf_gen(const uchar owf[16], push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update(user_u, user_l * 2, &ctx); - hmac_md5_update(dom_u, domain_l * 2, &ctx); + hmac_md5_update((const unsigned char *)user_u, user_l * 2, &ctx); + hmac_md5_update((const unsigned char *)dom_u, domain_l * 2, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD @@ -228,7 +228,7 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], hmac_md5_init_limK_to_64(kr, 16, &ctx); hmac_md5_update(srv_chal, srv_chal_len, &ctx); hmac_md5_update(cli_chal, cli_chal_len, &ctx); - hmac_md5_final(resp_buf, &ctx); + hmac_md5_final((unsigned char *)resp_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); @@ -245,7 +245,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], hmac_md5_init_limK_to_64(kr, 16, &ctx); hmac_md5_update(nt_resp, 16, &ctx); - hmac_md5_final(sess_key, &ctx); + hmac_md5_final((unsigned char *)sess_key, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_ntv2:\n")); @@ -256,7 +256,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], void SMBsesskeygen_ntv1(const uchar kr[16], const uchar * nt_resp, char sess_key[16]) { - mdfour(sess_key, kr, 16); + mdfour((unsigned char *)sess_key, kr, 16); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_ntv1:\n")); @@ -270,7 +270,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], BOOL encode_pw_buffer(char buffer[516], const char *new_pass, int new_pw_len, BOOL nt_pass_set) { - generate_random_buffer(buffer, 516, True); + generate_random_buffer((unsigned char *)buffer, 516, True); if (nt_pass_set) { new_pw_len *= 2; @@ -388,7 +388,7 @@ void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]) SIVAL(buf, i * 2, pwd->buffer[i]); } /* Calculate the MD4 hash (NT compatible) of the password */ - mdfour(nt_p16, buf, pwd->uni_str_len * 2); + mdfour(nt_p16, (const unsigned char *)buf, pwd->uni_str_len * 2); /* clear out local copy of user's password (just being paranoid). */ ZERO_STRUCT(buf); -- cgit From e8e98c9ea0690e3acf1126b50882e59e1056c7b3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 08:19:43 +0000 Subject: converted smbd to use NTSTATUS by default major changes include: - added NSTATUS type - added automatic mapping between dos and nt error codes - changed all ERROR() calls to ERROR_DOS() and many to ERROR_NT() these calls auto-translate to the client error code system - got rid of the cached error code and the writebmpx code We eventually will need to also: - get rid of BOOL, so we don't lose error info - replace all ERROR_DOS() calls with ERROR_NT() calls but that is too much for one night (This used to be commit 83d9896c1ea8be796192b51a4678c2a3b87f7518) --- source3/libsmb/clientgen.c | 3 +++ source3/libsmb/clierror.c | 49 ++++++++++--------------------------------- source3/libsmb/clitrans.c | 29 ++++++++++++++----------- source3/libsmb/libsmbclient.c | 2 +- 4 files changed, 32 insertions(+), 51 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b3933f41e0..87c8348853 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,6 +112,9 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_UNICODE) { flags2 |= FLAGS2_UNICODE_STRINGS; } + if (cli->capabilities & CAP_STATUS32) { + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + } SSVAL(cli->outbuf,smb_flg2, flags2); } } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 59a11dcc60..896360ce98 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -75,7 +75,6 @@ char *cli_errstr(struct cli_state *cli) int i; /* Case #1: 32-bit NT errors */ - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { uint32 status = IVAL(cli->inbuf,smb_rcls); @@ -90,7 +89,6 @@ char *cli_errstr(struct cli_state *cli) return cli_smb_errstr(cli); /* Case #3: RAP error */ - for (i = 0; rap_errmap[i].message != NULL; i++) { if (rap_errmap[i].err == cli->rap_error) { return rap_errmap[i].message; @@ -103,69 +101,45 @@ char *cli_errstr(struct cli_state *cli) return error_message; } -/* Return the 32-bit NT status code from the last packet */ +/* Return the 32-bit NT status code from the last packet */ uint32 cli_nt_error(struct cli_state *cli) { int flgs2 = SVAL(cli->inbuf,smb_flg2); if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) { - - /* Eek! We've requested a NT error when the packet that - came back does not contain one. What do we return - here? */ - - DEBUG(1, ("ERROR: cli_nt_error() called to read a status code " - "from a packet that does not contain one!\n")); - - return NT_STATUS_UNSUCCESSFUL; + int class = CVAL(cli->inbuf,smb_rcls); + int code = SVAL(cli->inbuf,smb_err); + return dos_to_ntstatus(class, code); } return IVAL(cli->inbuf,smb_rcls); } + /* Return the DOS error from the last packet - an error class and an error code. */ - -void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *num) +void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) { int flgs2; char rcls; int code; - if (eclass) - *eclass = 0; - - if (num) - *num = 0; - - if(!cli->initialised) - return; - - if(!cli->inbuf) - return; + if(!cli->initialised) return; flgs2 = SVAL(cli->inbuf,smb_flg2); if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* Eek! We've requested a DOS error when the packet that - came back does not contain one. What do we return - here? */ - - DEBUG(1, ("ERROR: cli_dos_error() called to read a dos error " - "code from a packet that does not contain one!\n")); - + uint32 ntstatus = IVAL(cli->inbuf, smb_rcls); + ntstatus_to_dos(ntstatus, eclass, ecode); return; } rcls = CVAL(cli->inbuf,smb_rcls); code = SVAL(cli->inbuf,smb_err); - if (rcls == 0) - return; - if (eclass) *eclass = rcls; - if (num ) *num = code; + if (ecode) *ecode = code; } /* Return a UNIX errno from a dos error class, error number tuple */ @@ -256,9 +230,7 @@ BOOL cli_is_error(struct cli_state *cli) uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - /* Return error is error bits are set */ - rcls = IVAL(cli->inbuf, smb_rcls); return (rcls & 0xF0000000) == 0xC0000000; } @@ -286,3 +258,4 @@ BOOL cli_is_dos_error(struct cli_state *cli) return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES); } + diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 4822508e38..6ae1014435 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -412,20 +412,25 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); /* allocate it */ - tdata = Realloc(*data,total_data); - if (!tdata) { - DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer")); - return False; + if (total_data) { + tdata = Realloc(*data,total_data); + if (!tdata) { + DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); + return False; + } else { + *data = tdata; + } } - else - *data = tdata; - tparam = Realloc(*param,total_param); - if (!tparam) { - DEBUG(0,("cli_receive_nt_trans: failed to enlarge buffer")); - return False; + + if (total_param) { + tparam = Realloc(*param,total_param); + if (!tparam) { + DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); + return False; + } else { + *param = tparam; + } } - else - *param = tparam; while (1) { this_data = SVAL(cli->inbuf,smb_ntr_DataCount); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 581af9b957..c0c586eceb 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1650,7 +1650,7 @@ int smbc_opendir(const char *fname) free(smbc_file_table[slot]); } smbc_file_table[slot] = NULL; - errno = cli_error(&srv->cli); + errno = cli_errno(&srv->cli); return -1; } -- cgit From ee5f7237decfe446f4fdb08422beb2e6cb43af7f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 17:52:23 +0000 Subject: started converting NTSTATUS to be a structure on systems with gcc in order to make it type incompatible with BOOL so we catch errors sooner. This has already found a number of bugs (This used to be commit 1b778bc7d22efff3f90dc450eb12baa1241cf68f) --- source3/libsmb/clierror.c | 53 +-- source3/libsmb/clireadwrite.c | 9 +- source3/libsmb/clitrans.c | 26 +- source3/libsmb/errormap.c | 854 ++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/nterr.c | 13 +- 5 files changed, 902 insertions(+), 53 deletions(-) create mode 100644 source3/libsmb/errormap.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 896360ce98..f485d328e2 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -76,7 +76,7 @@ char *cli_errstr(struct cli_state *cli) /* Case #1: 32-bit NT errors */ if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - uint32 status = IVAL(cli->inbuf,smb_rcls); + NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls)); return get_nt_error_msg(status); } @@ -103,7 +103,7 @@ char *cli_errstr(struct cli_state *cli) /* Return the 32-bit NT status code from the last packet */ -uint32 cli_nt_error(struct cli_state *cli) +NTSTATUS cli_nt_error(struct cli_state *cli) { int flgs2 = SVAL(cli->inbuf,smb_flg2); @@ -113,7 +113,7 @@ uint32 cli_nt_error(struct cli_state *cli) return dos_to_ntstatus(class, code); } - return IVAL(cli->inbuf,smb_rcls); + return NT_STATUS(IVAL(cli->inbuf,smb_rcls)); } @@ -130,7 +130,7 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) flgs2 = SVAL(cli->inbuf,smb_flg2); if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - uint32 ntstatus = IVAL(cli->inbuf, smb_rcls); + NTSTATUS ntstatus = NT_STATUS(IVAL(cli->inbuf, smb_rcls)); ntstatus_to_dos(ntstatus, eclass, ecode); return; } @@ -175,29 +175,38 @@ int cli_errno_from_dos(uint8 eclass, uint32 num) } /* Return a UNIX errno from a NT status code */ - -int cli_errno_from_nt(uint32 status) +static struct { + NTSTATUS status; + int error; +} nt_errno_map[] = { + {NT_STATUS_ACCESS_VIOLATION, EACCES}, + {NT_STATUS_NO_SUCH_FILE, ENOENT}, + {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, + {NT_STATUS_INVALID_HANDLE, EBADF}, + {NT_STATUS_NO_MEMORY, ENOMEM}, + {NT_STATUS_ACCESS_DENIED, EACCES}, + {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, + {NT_STATUS_SHARING_VIOLATION, EBUSY}, + {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, + {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, + {NT_STATUS_PATH_NOT_COVERED, ENOENT}, + {NT_STATUS(0), 0} +}; + +int cli_errno_from_nt(NTSTATUS status) { - DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", status)); + int i; + DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", NT_STATUS_V(status))); /* Status codes without this bit set are not errors */ - if (!(status & 0xc0000000)) + if (!(NT_STATUS_V(status) & 0xc0000000)) return 0; - switch (status) { - case NT_STATUS_ACCESS_VIOLATION: return EACCES; - case NT_STATUS_NO_SUCH_FILE: return ENOENT; - case NT_STATUS_NO_SUCH_DEVICE: return ENODEV; - case NT_STATUS_INVALID_HANDLE: return EBADF; - case NT_STATUS_NO_MEMORY: return ENOMEM; - case NT_STATUS_ACCESS_DENIED: return EACCES; - case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT; - case NT_STATUS_SHARING_VIOLATION: return EBUSY; - case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR; - case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST; - case NT_STATUS_PATH_NOT_COVERED: return ENOENT; - } + for (i=0;nt_errno_map[i].error;i++) { + if (NT_STATUS_V(nt_errno_map[i].status) == + NT_STATUS_V(status)) return nt_errno_map[i].error; + } /* for all other cases - a default code */ return EINVAL; @@ -208,7 +217,7 @@ int cli_errno_from_nt(uint32 status) int cli_errno(struct cli_state *cli) { - uint32 status; + NTSTATUS status; if (cli_is_dos_error) { uint8 eclass; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 6566acf4ef..abbb8cd110 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -110,16 +110,17 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ errors. */ if (cli_is_error(cli)) { - uint32 status = 0; + NTSTATUS status = NT_STATUS_OK; uint8 eclass = 0; + uint32 ecode = 0; if (cli_is_nt_error(cli)) status = cli_nt_error(cli); else - cli_dos_error(cli, &eclass, &status); + cli_dos_error(cli, &eclass, &ecode); - if ((eclass == ERRDOS && status == ERRmoredata) || - status == STATUS_MORE_ENTRIES) + if ((eclass == ERRDOS && ecode == ERRmoredata) || + NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES)) return -1; } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 6ae1014435..bcf1bf5f74 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -145,8 +145,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, int total_data=0; int total_param=0; int this_data,this_param; - uint8 eclass; - uint32 ecode; + NTSTATUS status; char *tdata; char *tparam; @@ -170,19 +169,9 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, * to a trans call. This is not an error and should not * be treated as such. */ - - if (cli_is_error(cli)) { - if (cli_is_dos_error(cli)) { - cli_dos_error(cli, &eclass, &ecode); - - if(cli->nt_pipe_fnum == 0) - return(False); - - if(!(eclass == ERRDOS && ecode == ERRmoredata)) { - if (eclass != 0 && (ecode != (0x80000000 | STATUS_BUFFER_OVERFLOW))) - return(False); - } - } + status = cli_nt_error(cli); + + if (NT_STATUS_IS_ERR(status)) { return False; } @@ -251,11 +240,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); return(False); } - if (cli_is_dos_error(cli)) { - cli_dos_error(cli, &eclass, &ecode); - if(cli->nt_pipe_fnum == 0 || - !(eclass == ERRDOS && ecode == ERRmoredata)) - return(False); + if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { + return(False); } } diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c new file mode 100644 index 0000000000..92a4b19847 --- /dev/null +++ b/source3/libsmb/errormap.c @@ -0,0 +1,854 @@ +/* + * Unix SMB/Netbios implementation. + * Version 3.0 + * error mapping functions + * Copyright (C) Andrew Tridgell 2001 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +/* NT status -> dos error map */ +static struct { + uint8 dos_class; + uint32 dos_code; + NTSTATUS ntstatus; +} ntstatus_to_dos_map[] = { + {ERRDOS, 997, NT_STATUS(0x00000103)}, + {ERRDOS, 111, STATUS_MORE_ENTRIES}, + {ERRDOS, 1300, NT_STATUS(0x00000106)}, + {ERRDOS, 1301, NT_STATUS(0x00000107)}, + {ERRDOS, 1022, NT_STATUS(0x0000010c)}, + {ERRDOS, 1302, NT_STATUS(0x0000010d)}, + {ERRDOS, 8201, NT_STATUS(0x00000121)}, + {ERRDOS, 31, NT_STATUS_UNSUCCESSFUL}, + {ERRSRV, ERRsmbcmd, NT_STATUS_NOT_IMPLEMENTED}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_INFO_CLASS}, + {ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, + {ERRDOS, 998, NT_STATUS_ACCESS_VIOLATION}, + {ERRDOS, 999, NT_STATUS_IN_PAGE_ERROR}, + {ERRDOS, 1454, NT_STATUS_PAGEFILE_QUOTA}, + {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, + {ERRDOS, 1001, NT_STATUS_BAD_INITIAL_STACK}, + {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_CID}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER}, + {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, + {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, + {ERRSRV, ERRsmbcmd, NT_STATUS_INVALID_DEVICE_REQUEST}, + {ERRDOS, 38, NT_STATUS_END_OF_FILE}, + {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, + {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, + {ERRDOS, 1785, NT_STATUS_UNRECOGNIZED_MEDIA}, + {ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, + {ERRDOS, 111, NT_STATUS_MORE_PROCESSING_REQUIRED}, + {ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, + {ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, + {ERRDOS, 487, NT_STATUS_NOT_MAPPED_VIEW}, + {ERRDOS, ERRbadpipe, NT_STATUS(0xc000001a)}, + {ERRDOS, ERRbadpipe, NT_STATUS_UNABLE_TO_DELETE_SECTION}, + {ERRSRV, ERRsmbcmd, NT_STATUS_INVALID_SYSTEM_SERVICE}, + {ERRDOS, 29, NT_STATUS_ILLEGAL_INSTRUCTION}, + {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_VIEW_SIZE}, + {ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, + {ERRDOS, ERRbadaccess, NT_STATUS_ALREADY_COMMITTED}, + {ERRDOS, ERRbadaccess, NT_STATUS_ACCESS_DENIED}, + {ERRDOS, 122, NT_STATUS_BUFFER_TOO_SMALL}, + {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, + {ERRDOS, 37, NT_STATUS_NONCONTINUABLE_EXCEPTION}, + {ERRDOS, 38, NT_STATUS_INVALID_DISPOSITION}, + {ERRDOS, 158, NT_STATUS_NOT_LOCKED}, + {ERRDOS, 43, NT_STATUS_PARITY_ERROR}, + {ERRDOS, 487, NT_STATUS_UNABLE_TO_DECOMMIT_VM}, + {ERRDOS, 487, NT_STATUS_NOT_COMMITTED}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_MIX}, + {ERRDOS, 26, NT_STATUS_DISK_CORRUPT_ERROR}, + {ERRSRV, 206, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, + {ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, + {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, + {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, + {ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, + {ERRDOS, 1117, NT_STATUS_DATA_OVERRUN}, + {ERRDOS, 1117, NT_STATUS_DATA_LATE_ERROR}, + {ERRDOS, ERRbaddata, NT_STATUS_DATA_ERROR}, + {ERRDOS, ERRbaddata, NT_STATUS_CRC_ERROR}, + {ERRDOS, ERRnomem, NT_STATUS_SECTION_TOO_BIG}, + {ERRDOS, ERRbadaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, + {ERRDOS, ERRbadfid, NT_STATUS_INVALID_PORT_HANDLE}, + {ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, + {ERRDOS, 1816, NT_STATUS_QUOTA_EXCEEDED}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PAGE_PROTECTION}, + {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, + {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, + {ERRDOS, ERRbadpipe, NT_STATUS_PORT_ALREADY_SET}, + {ERRDOS, ERRbadpipe, NT_STATUS_SECTION_NOT_IMAGE}, + {ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, + {ERRDOS, ERRbadaccess, NT_STATUS_THREAD_IS_TERMINATING}, + {ERRDOS, ERRbadpipe, NT_STATUS_BAD_WORKING_SET_LIMIT}, + {ERRDOS, ERRbadpipe, NT_STATUS_INCOMPATIBLE_FILE_MAP}, + {ERRDOS, ERRbadpipe, NT_STATUS_SECTION_PROTECTION}, + {ERRDOS, 282, NT_STATUS_EAS_NOT_SUPPORTED}, + {ERRDOS, 275, NT_STATUS_EA_TOO_LARGE}, + {ERRDOS, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRDOS, 276, NT_STATUS_NO_EAS_ON_FILE}, + {ERRDOS, 276, NT_STATUS_EA_CORRUPT_ERROR}, + {ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, + {ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED}, + {ERRDOS, ERRbadaccess, NT_STATUS_DELETE_PENDING}, + {ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, + {ERRDOS, 1305, NT_STATUS_UNKNOWN_REVISION}, + {ERRDOS, 1306, NT_STATUS_REVISION_MISMATCH}, + {ERRDOS, 1307, NT_STATUS_INVALID_OWNER}, + {ERRDOS, 1308, NT_STATUS_INVALID_PRIMARY_GROUP}, + {ERRDOS, 1309, NT_STATUS_NO_IMPERSONATION_TOKEN}, + {ERRDOS, 1310, NT_STATUS_CANT_DISABLE_MANDATORY}, + {ERRDOS, 1311, NT_STATUS_NO_LOGON_SERVERS}, + {ERRDOS, 1312, NT_STATUS_NO_SUCH_LOGON_SESSION}, + {ERRDOS, 1313, NT_STATUS_NO_SUCH_PRIVILEGE}, + {ERRDOS, 1314, NT_STATUS_PRIVILEGE_NOT_HELD}, + {ERRDOS, 1315, NT_STATUS_INVALID_ACCOUNT_NAME}, + {ERRDOS, 1316, NT_STATUS_USER_EXISTS}, + {ERRDOS, 1317, NT_STATUS_NO_SUCH_USER}, + {ERRDOS, 1318, NT_STATUS_GROUP_EXISTS}, + {ERRDOS, 1319, NT_STATUS_NO_SUCH_GROUP}, + {ERRDOS, 1320, NT_STATUS_MEMBER_IN_GROUP}, + {ERRDOS, 1321, NT_STATUS_MEMBER_NOT_IN_GROUP}, + {ERRDOS, 1322, NT_STATUS_LAST_ADMIN}, + {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, + {ERRDOS, 1324, NT_STATUS_ILL_FORMED_PASSWORD}, + {ERRDOS, 1325, NT_STATUS_PASSWORD_RESTRICTION}, + {ERRDOS, 1326, NT_STATUS_LOGON_FAILURE}, + {ERRDOS, 1327, NT_STATUS_ACCOUNT_RESTRICTION}, + {ERRDOS, 1328, NT_STATUS_INVALID_LOGON_HOURS}, + {ERRDOS, 1329, NT_STATUS_INVALID_WORKSTATION}, + {ERRDOS, 1330, NT_STATUS_PASSWORD_EXPIRED}, + {ERRDOS, 1331, NT_STATUS_ACCOUNT_DISABLED}, + {ERRDOS, 1332, NT_STATUS_NONE_MAPPED}, + {ERRDOS, 1333, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, + {ERRDOS, 1334, NT_STATUS_LUIDS_EXHAUSTED}, + {ERRDOS, 1335, NT_STATUS_INVALID_SUB_AUTHORITY}, + {ERRDOS, 1336, NT_STATUS_INVALID_ACL}, + {ERRDOS, 1337, NT_STATUS_INVALID_SID}, + {ERRDOS, 1338, NT_STATUS_INVALID_SECURITY_DESCR}, + {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_FORMAT}, + {ERRDOS, 1008, NT_STATUS_NO_TOKEN}, + {ERRDOS, 1340, NT_STATUS_BAD_INHERITANCE_ACL}, + {ERRDOS, 158, NT_STATUS_RANGE_NOT_LOCKED}, + {ERRSRV, ERRnoroom, NT_STATUS_DISK_FULL}, + {ERRDOS, 1341, NT_STATUS_SERVER_DISABLED}, + {ERRDOS, 1342, NT_STATUS_SERVER_NOT_DISABLED}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, + {ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, + {ERRDOS, 1343, NT_STATUS_INVALID_ID_AUTHORITY}, + {ERRDOS, 259, NT_STATUS_AGENTS_EXHAUSTED}, + {ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, + {ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, + {ERRDOS, 487, NT_STATUS_NOT_MAPPED_DATA}, + {ERRDOS, 1812, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, + {ERRDOS, 1813, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, + {ERRDOS, 1814, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, + {ERRDOS, 140, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, + {ERRDOS, 141, NT_STATUS_FLOAT_DENORMAL_OPERAND}, + {ERRDOS, 142, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, + {ERRDOS, 143, NT_STATUS_FLOAT_INEXACT_RESULT}, + {ERRDOS, 144, NT_STATUS_FLOAT_INVALID_OPERATION}, + {ERRDOS, 145, NT_STATUS_FLOAT_OVERFLOW}, + {ERRDOS, 146, NT_STATUS_FLOAT_STACK_CHECK}, + {ERRDOS, 147, NT_STATUS_FLOAT_UNDERFLOW}, + {ERRDOS, 148, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, + {ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, + {ERRDOS, 150, NT_STATUS_PRIVILEGED_INSTRUCTION}, + {ERRDOS, ERRnomem, NT_STATUS_TOO_MANY_PAGING_FILES}, + {ERRDOS, 1006, NT_STATUS_FILE_INVALID}, + {ERRDOS, 1344, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, + {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, + {ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, + {ERRDOS, ERRbaddata, NT_STATUS_DEVICE_DATA_ERROR}, + {ERRDOS, 1167, NT_STATUS_DEVICE_NOT_CONNECTED}, + {ERRDOS, 21, NT_STATUS_DEVICE_POWER_FAILURE}, + {ERRDOS, 487, NT_STATUS_FREE_VM_NOT_AT_BASE}, + {ERRDOS, 487, NT_STATUS_MEMORY_NOT_ALLOCATED}, + {ERRDOS, 1453, NT_STATUS_WORKING_SET_QUOTA}, + {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, + {ERRDOS, 21, NT_STATUS_DEVICE_NOT_READY}, + {ERRDOS, 1345, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, + {ERRDOS, 1346, NT_STATUS_BAD_IMPERSONATION_LEVEL}, + {ERRDOS, 1347, NT_STATUS_CANT_OPEN_ANONYMOUS}, + {ERRDOS, 1348, NT_STATUS_BAD_VALIDATION_CLASS}, + {ERRDOS, 1349, NT_STATUS_BAD_TOKEN_TYPE}, + {ERRDOS, ERRbadpipe, NT_STATUS_BAD_MASTER_BOOT_RECORD}, + {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, + {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_NOT_AVAILABLE}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PIPE_STATE}, + {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_BUSY}, + {ERRSRV, ERRsmbcmd, NT_STATUS_ILLEGAL_FUNCTION}, + {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, + {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, + {ERRDOS, 535, NT_STATUS_PIPE_CONNECTED}, + {ERRDOS, 536, NT_STATUS_PIPE_LISTENING}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_READ_MODE}, + {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, + {ERRDOS, 38, NT_STATUS_FILE_FORCED_CLOSED}, + {ERRDOS, ERRbadaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, + {ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED}, + {ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, + {ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, + {ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, + {ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, + {ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, + {ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, + {ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, + {ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, + {ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, + {ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, + {ERRSRV, ERRqfull, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRSRV, ERRqtoobig, NT_STATUS_NO_SPOOL_SPACE}, + {ERRSRV, ERRinvpfid, NT_STATUS_PRINT_CANCELLED}, + {ERRSRV, ERRinvnid, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRSRV, ERRaccess, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRSRV, ERRbadtype, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRSRV, ERRinvnetname, NT_STATUS_BAD_NETWORK_NAME}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_NAMES}, + {ERRSRV, ERRtoomanyuids, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRSRV, ERRpaused, NT_STATUS_SHARING_PAUSED}, + {ERRSRV, ERRmsgoff, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, + {ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, + {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, + {ERRDOS, ERRbadaccess, NT_STATUS_FILE_RENAMED}, + {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, + {ERRDOS, 1350, NT_STATUS_NO_SECURITY_ON_OBJECT}, + {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_EMPTY}, + {ERRDOS, 1351, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, + {ERRDOS, 1352, NT_STATUS_INVALID_SERVER_STATE}, + {ERRDOS, 1353, NT_STATUS_INVALID_DOMAIN_STATE}, + {ERRDOS, 1354, NT_STATUS_INVALID_DOMAIN_ROLE}, + {ERRDOS, 1355, NT_STATUS_NO_SUCH_DOMAIN}, + {ERRDOS, 1356, NT_STATUS_DOMAIN_EXISTS}, + {ERRDOS, 1357, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, + {ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, + {ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, + {ERRDOS, 1358, NT_STATUS_INTERNAL_DB_CORRUPTION}, + {ERRDOS, 1359, NT_STATUS_INTERNAL_ERROR}, + {ERRDOS, 1360, NT_STATUS_GENERIC_NOT_MAPPED}, + {ERRDOS, 1361, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, + {ERRDOS, 1784, NT_STATUS_INVALID_USER_BUFFER}, + {ERRDOS, 1362, NT_STATUS_NOT_LOGON_PROCESS}, + {ERRDOS, 1363, NT_STATUS_LOGON_SESSION_EXISTS}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_1}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_2}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_3}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_4}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_5}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_6}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_7}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_8}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_9}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_10}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_11}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_12}, + {ERRDOS, ERRbadpath, NT_STATUS_REDIRECTOR_NOT_STARTED}, + {ERRDOS, 1001, NT_STATUS_STACK_OVERFLOW}, + {ERRDOS, 1364, NT_STATUS_NO_SUCH_PACKAGE}, + {ERRDOS, 203, NT_STATUS(0xc0000100)}, + {ERRDOS, ERRremcd, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRDOS, 276, NT_STATUS_FILE_CORRUPT_ERROR}, + {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, + {ERRDOS, 1365, NT_STATUS_BAD_LOGON_SESSION_STATE}, + {ERRDOS, 1366, NT_STATUS_LOGON_SESSION_COLLISION}, + {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, + {ERRDOS, 2401, NT_STATUS_FILES_OPEN}, + {ERRDOS, 2404, NT_STATUS_CONNECTION_IN_USE}, + {ERRDOS, ERRbadaccess, NT_STATUS_PROCESS_IS_TERMINATING}, + {ERRDOS, 1367, NT_STATUS_INVALID_LOGON_TYPE}, + {ERRDOS, 1368, NT_STATUS_CANNOT_IMPERSONATE}, + {ERRDOS, 1056, NT_STATUS_IMAGE_ALREADY_LOADED}, + {ERRDOS, 1444, NT_STATUS_NO_LDT}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NE_FORMAT}, + {ERRDOS, 1369, NT_STATUS_RXACT_INVALID_STATE}, + {ERRDOS, 1370, NT_STATUS_RXACT_COMMIT_FAILURE}, + {ERRDOS, 1006, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, + {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, + {ERRDOS, 995, NT_STATUS_CANCELLED}, + {ERRDOS, ERRbadaccess, NT_STATUS_CANNOT_DELETE}, + {ERRDOS, 1210, NT_STATUS_INVALID_COMPUTER_NAME}, + {ERRDOS, ERRbadaccess, NT_STATUS_FILE_DELETED}, + {ERRDOS, 1371, NT_STATUS_SPECIAL_ACCOUNT}, + {ERRDOS, 1372, NT_STATUS_SPECIAL_GROUP}, + {ERRDOS, 1373, NT_STATUS_SPECIAL_USER}, + {ERRDOS, 1374, NT_STATUS_MEMBERS_PRIMARY_GROUP}, + {ERRDOS, ERRbadfid, NT_STATUS_FILE_CLOSED}, + {ERRDOS, 1375, NT_STATUS_TOKEN_ALREADY_IN_USE}, + {ERRDOS, 1455, NT_STATUS_COMMITMENT_LIMIT}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_LE_FORMAT}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NOT_MZ}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_PROTECT}, + {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_WIN_16}, + {ERRDOS, 1398, NT_STATUS_TIME_DIFFERENCE_AT_DC}, + {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, + {ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, + {ERRDOS, 127, NT_STATUS_ENTRYPOINT_NOT_FOUND}, + {ERRSRV, ERRinvnid, NT_STATUS_LOCAL_DISCONNECT}, + {ERRSRV, ERRinvnid, NT_STATUS_REMOTE_DISCONNECT}, + {ERRDOS, 51, NT_STATUS_REMOTE_RESOURCES}, + {ERRDOS, 59, NT_STATUS_LINK_FAILED}, + {ERRDOS, 59, NT_STATUS_LINK_TIMEOUT}, + {ERRDOS, 59, NT_STATUS_INVALID_CONNECTION}, + {ERRDOS, 59, NT_STATUS_INVALID_ADDRESS}, + {ERRDOS, 1114, NT_STATUS_DLL_INIT_FAILED}, + {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, + {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD_CORE}, + {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, + {ERRDOS, 1009, NT_STATUS_REGISTRY_CORRUPT}, + {ERRDOS, 1016, NT_STATUS_REGISTRY_IO_FAILED}, + {ERRDOS, 1005, NT_STATUS_UNRECOGNIZED_VOLUME}, + {ERRDOS, 1118, NT_STATUS_SERIAL_NO_DEVICE_INITED}, + {ERRDOS, 1376, NT_STATUS_NO_SUCH_ALIAS}, + {ERRDOS, 1377, NT_STATUS_MEMBER_NOT_IN_ALIAS}, + {ERRDOS, 1378, NT_STATUS_MEMBER_IN_ALIAS}, + {ERRDOS, 1379, NT_STATUS_ALIAS_EXISTS}, + {ERRDOS, 1380, NT_STATUS_LOGON_NOT_GRANTED}, + {ERRDOS, 1381, NT_STATUS_TOO_MANY_SECRETS}, + {ERRDOS, 1382, NT_STATUS_SECRET_TOO_LONG}, + {ERRDOS, 1383, NT_STATUS_INTERNAL_DB_ERROR}, + {ERRDOS, 1007, NT_STATUS_FULLSCREEN_MODE}, + {ERRDOS, 1384, NT_STATUS_TOO_MANY_CONTEXT_IDS}, + {ERRDOS, 1385, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, + {ERRDOS, 1017, NT_STATUS_NOT_REGISTRY_FILE}, + {ERRDOS, 1386, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, + {ERRDOS, 1117, NT_STATUS_FT_MISSING_MEMBER}, + {ERRDOS, 1113, NT_STATUS_UNMAPPABLE_CHARACTER}, + {ERRDOS, 1122, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, + {ERRDOS, 1123, NT_STATUS_FLOPPY_WRONG_CYLINDER}, + {ERRDOS, 1124, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, + {ERRDOS, 1125, NT_STATUS_FLOPPY_BAD_REGISTERS}, + {ERRDOS, 1126, NT_STATUS_DISK_RECALIBRATE_FAILED}, + {ERRDOS, 1127, NT_STATUS_DISK_OPERATION_FAILED}, + {ERRDOS, 1128, NT_STATUS_DISK_RESET_FAILED}, + {ERRDOS, 1119, NT_STATUS_SHARED_IRQ_BUSY}, + {ERRDOS, 1117, NT_STATUS_FT_ORPHANING}, + {ERRDOS, 1105, NT_STATUS_PARTITION_FAILURE}, + {ERRDOS, 1106, NT_STATUS_INVALID_BLOCK_LENGTH}, + {ERRDOS, 1107, NT_STATUS_DEVICE_NOT_PARTITIONED}, + {ERRDOS, 1108, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, + {ERRDOS, 1109, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, + {ERRDOS, 1129, NT_STATUS_EOM_OVERFLOW}, + {ERRDOS, 1112, NT_STATUS_NO_MEDIA}, + {ERRDOS, 1387, NT_STATUS_NO_SUCH_MEMBER}, + {ERRDOS, 1388, NT_STATUS_INVALID_MEMBER}, + {ERRDOS, 1018, NT_STATUS_KEY_DELETED}, + {ERRDOS, 1019, NT_STATUS_NO_LOG_SPACE}, + {ERRDOS, 1389, NT_STATUS_TOO_MANY_SIDS}, + {ERRDOS, 1390, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, + {ERRDOS, 1020, NT_STATUS_KEY_HAS_CHILDREN}, + {ERRDOS, 1021, NT_STATUS_CHILD_MUST_BE_VOLATILE}, + {ERRDOS, ERRbadpipe, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, + {ERRDOS, 1117, NT_STATUS_DRIVER_INTERNAL_ERROR}, + {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, + {ERRDOS, 1117, NT_STATUS_IO_DEVICE_ERROR}, + {ERRDOS, 1117, NT_STATUS_DEVICE_PROTOCOL_ERROR}, + {ERRDOS, 1502, NT_STATUS_LOG_FILE_FULL}, + {ERRDOS, 19, NT_STATUS_TOO_LATE}, + {ERRDOS, 1786, NT_STATUS_NO_TRUST_LSA_SECRET}, + {ERRDOS, 1787, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, + {ERRDOS, 1788, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, + {ERRDOS, 1789, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, + {ERRDOS, 1500, NT_STATUS_EVENTLOG_FILE_CORRUPT}, + {ERRDOS, 1501, NT_STATUS_EVENTLOG_CANT_START}, + {ERRDOS, 1790, NT_STATUS_TRUST_FAILURE}, + {ERRDOS, 1792, NT_STATUS_NETLOGON_NOT_STARTED}, + {ERRDOS, 1793, NT_STATUS_ACCOUNT_EXPIRED}, + {ERRDOS, 1131, NT_STATUS_POSSIBLE_DEADLOCK}, + {ERRDOS, 1219, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, + {ERRDOS, 1220, NT_STATUS_REMOTE_SESSION_LIMIT}, + {ERRDOS, 1503, NT_STATUS_EVENTLOG_FILE_CHANGED}, + {ERRDOS, 1807, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, + {ERRDOS, 1808, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, + {ERRDOS, 1809, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, + {ERRDOS, 1810, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, + {ERRDOS, 1394, NT_STATUS_NO_USER_SESSION_KEY}, + {ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, + {ERRDOS, 1815, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, + {ERRDOS, 1130, NT_STATUS_INSUFF_SERVER_RESOURCES}, + {ERRDOS, 1784, NT_STATUS_INVALID_BUFFER_SIZE}, + {ERRDOS, 1214, NT_STATUS_INVALID_ADDRESS_COMPONENT}, + {ERRDOS, 1214, NT_STATUS_INVALID_ADDRESS_WILDCARD}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_ADDRESSES}, + {ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_EXISTS}, + {ERRSRV, ERRinvnid, NT_STATUS_ADDRESS_CLOSED}, + {ERRSRV, ERRinvnid, NT_STATUS_CONNECTION_DISCONNECTED}, + {ERRSRV, ERRinvnid, NT_STATUS_CONNECTION_RESET}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_NODES}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_ABORTED}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_TIMED_OUT}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_NO_RELEASE}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_NO_MATCH}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_RESPONDED}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_ID}, + {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_TYPE}, + {ERRDOS, ERRunsup, NT_STATUS_NOT_SERVER_SESSION}, + {ERRDOS, ERRunsup, NT_STATUS_NOT_CLIENT_SESSION}, + {ERRDOS, 6118, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, + {ERRDOS, 1132, NT_STATUS_MAPPED_ALIGNMENT}, + {ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, + {ERRDOS, 1907, NT_STATUS_PASSWORD_MUST_CHANGE}, + {ERRDOS, 1168, NT_STATUS_NOT_FOUND}, + {ERRDOS, 554, NT_STATUS_DUPLICATE_OBJECTID}, + {ERRDOS, 555, NT_STATUS_OBJECTID_EXISTS}, + {ERRDOS, 1237, NT_STATUS_RETRY}, + {ERRDOS, 1170, NT_STATUS_PROPSET_NOT_FOUND}, + {ERRDOS, 1908, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, + {ERRDOS, 1909, NT_STATUS_ACCOUNT_LOCKED_OUT}, + {ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, + {ERRDOS, 1225, NT_STATUS_CONNECTION_REFUSED}, + {ERRDOS, 1226, NT_STATUS_GRACEFUL_DISCONNECT}, + {ERRDOS, 1227, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, + {ERRDOS, 1228, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, + {ERRDOS, 1229, NT_STATUS_CONNECTION_INVALID}, + {ERRDOS, 1230, NT_STATUS_CONNECTION_ACTIVE}, + {ERRDOS, 1231, NT_STATUS_NETWORK_UNREACHABLE}, + {ERRDOS, 1232, NT_STATUS_HOST_UNREACHABLE}, + {ERRDOS, 1233, NT_STATUS_PROTOCOL_UNREACHABLE}, + {ERRDOS, 1234, NT_STATUS_PORT_UNREACHABLE}, + {ERRDOS, 1235, NT_STATUS_REQUEST_ABORTED}, + {ERRDOS, 1236, NT_STATUS_CONNECTION_ABORTED}, + {ERRDOS, 1224, NT_STATUS_USER_MAPPED_FILE}, + {ERRDOS, 1238, NT_STATUS_CONNECTION_COUNT_LIMIT}, + {ERRDOS, 1239, NT_STATUS_LOGIN_TIME_RESTRICTION}, + {ERRDOS, 1240, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, + {ERRDOS, 193, NT_STATUS_IMAGE_MP_UP_MISMATCH}, + {ERRDOS, 1359, NT_STATUS_LPC_REPLY_LOST}, + {ERRDOS, 1232, NT_STATUS_PATH_NOT_COVERED}, + {ERRDOS, 1395, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, + {ERRDOS, 1058, NT_STATUS_PLUGPLAY_NO_DEVICE}, + {ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, + {ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, + {ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, + {ERRDOS, 1142, NT_STATUS_TOO_MANY_LINKS}, + {ERRDOS, 4350, NT_STATUS_FILE_IS_OFFLINE}, + {ERRDOS, 2001, NT_STATUS(0xc000026c)}, + {ERRDOS, 1201, NT_STATUS(0xc000026d)}, + {ERRDOS, 21, NT_STATUS(0xc000026e)}, + {ERRDOS, 1169, NT_STATUS(0xc0000272)}, + {ERRDOS, 4390, NT_STATUS(0xc0000275)}, + {ERRDOS, 4393, NT_STATUS(0xc0000276)}, + {ERRDOS, 4394, NT_STATUS(0xc0000277)}, + {ERRDOS, 4392, NT_STATUS(0xc0000278)}, + {ERRDOS, 1920, NT_STATUS(0xc0000279)}, + {ERRDOS, 1921, NT_STATUS(0xc0000280)}, + {ERRDOS, 161, NT_STATUS(0xc0000281)}, + {ERRDOS, 1160, NT_STATUS(0xc0000283)}, + {ERRDOS, 1161, NT_STATUS(0xc0000284)}, + {ERRDOS, 1162, NT_STATUS(0xc0000285)}, + {ERRDOS, 1163, NT_STATUS(0xc0000286)}, + {ERRDOS, 1164, NT_STATUS(0xc0000287)}, + {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028a)}, + {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028b)}, + {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028d)}, + {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028e)}, + {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028f)}, + {ERRDOS, ERRbadaccess, NT_STATUS(0xc0000290)}, + {ERRDOS, 6007, NT_STATUS(0xc0000291)}, + {ERRDOS, 6008, NT_STATUS(0xc0000292)}, + {ERRDOS, 6002, NT_STATUS(0xc0000293)}, + {ERRDOS, 4200, NT_STATUS(0xc0000295)}, + {ERRDOS, 4201, NT_STATUS(0xc0000296)}, + {ERRDOS, 4202, NT_STATUS(0xc0000297)}, + {ERRDOS, 4203, NT_STATUS(0xc0000298)}, + {ERRDOS, 8218, NT_STATUS(0xc0000299)}, + {ERRDOS, 8219, NT_STATUS(0xc000029a)}, + {ERRDOS, 8220, NT_STATUS(0xc000029b)}, + {ERRSRV, ERRsmbcmd, NT_STATUS(0xc000029c)}, + {ERRDOS, 4351, NT_STATUS(0xc000029d)}, + {ERRDOS, 4352, NT_STATUS(0xc000029e)}, + {ERRDOS, 1172, NT_STATUS(0xc000029f)}, + {ERRDOS, 8202, NT_STATUS(0xc00002a1)}, + {ERRDOS, 8203, NT_STATUS(0xc00002a2)}, + {ERRDOS, 8204, NT_STATUS(0xc00002a3)}, + {ERRDOS, 8205, NT_STATUS(0xc00002a4)}, + {ERRDOS, 8206, NT_STATUS(0xc00002a5)}, + {ERRDOS, 8207, NT_STATUS(0xc00002a6)}, + {ERRDOS, 8208, NT_STATUS(0xc00002a7)}, + {ERRDOS, 8209, NT_STATUS(0xc00002a8)}, + {ERRDOS, 8210, NT_STATUS(0xc00002a9)}, + {ERRDOS, 8211, NT_STATUS(0xc00002aa)}, + {ERRDOS, 8212, NT_STATUS(0xc00002ab)}, + {ERRDOS, 8213, NT_STATUS(0xc00002ac)}, + {ERRDOS, 8214, NT_STATUS(0xc00002ad)}, + {ERRDOS, 8215, NT_STATUS(0xc00002ae)}, + {ERRDOS, 8216, NT_STATUS(0xc00002af)}, + {ERRDOS, 8217, NT_STATUS(0xc00002b0)}, + {ERRDOS, 8478, NT_STATUS(0xc00002b1)}, + {ERRDOS, 4391, NT_STATUS(0xc00002b2)}, + {ERRDOS, 1617, NT_STATUS(0xc00002b6)}, + {ERRDOS, 1178, NT_STATUS(0xc00002b7)}, + {ERRDOS, 1179, NT_STATUS(0xc00002b8)}, + {ERRDOS, 8228, NT_STATUS(0xc00002c1)}, + {ERRDOS, 1397, NT_STATUS(0xc00002c3)}, + {ERRDOS, 998, NT_STATUS(0xc00002c5)}, + {ERRDOS, 4213, NT_STATUS(0xc00002c6)}, + {ERRDOS, 4214, NT_STATUS(0xc00002c7)}, + {ERRDOS, 4328, NT_STATUS(0xc00002ca)}, + {ERRDOS, 8504, NT_STATUS(0xc00002cb)}, + {ERRDOS, 1251, NT_STATUS(0xc00002cc)}, + {ERRDOS, 8505, NT_STATUS(0xc00002cd)}, + {ERRDOS, 1181, NT_STATUS(0xc00002cf)}, + {ERRDOS, 8506, NT_STATUS(0xc00002d0)}, + {ERRDOS, 8513, NT_STATUS(0xc00002d4)}, + {ERRDOS, 8514, NT_STATUS(0xc00002d5)}, + {ERRDOS, 8515, NT_STATUS(0xc00002d6)}, + {ERRDOS, 8516, NT_STATUS(0xc00002d7)}, + {ERRDOS, 8517, NT_STATUS(0xc00002d8)}, + {ERRDOS, 8518, NT_STATUS(0xc00002d9)}, + {ERRDOS, 8519, NT_STATUS(0xc00002da)}, + {ERRDOS, 8520, NT_STATUS(0xc00002db)}, + {ERRDOS, 8521, NT_STATUS(0xc00002dc)}, + {ERRDOS, ERRunsup, NT_STATUS(0xc00002dd)}, + {ERRDOS, 8529, NT_STATUS(0xc00002df)}, + {ERRDOS, 8530, NT_STATUS(0xc00002e0)}, + {ERRDOS, 8531, NT_STATUS(0xc00002e1)}, + {ERRDOS, 8532, NT_STATUS(0xc00002e2)}, + {ERRDOS, 8541, NT_STATUS(0xc00002e3)}, + {ERRDOS, 8547, NT_STATUS(0xc00002e4)}, + {ERRDOS, 8548, NT_STATUS(0xc00002e5)}, + {ERRDOS, 8549, NT_STATUS(0xc00002e6)}, + {ERRDOS, 8557, NT_STATUS(0xc00002e7)}, + {ERRDOS, 1115, NT_STATUS(0xc00002fe)}, + {ERRDOS, 1255, NT_STATUS(0xc00002ff)}, + {ERRDOS, 1254, NT_STATUS(0xc0000300)}, + {ERRDOS, ERRbadfunc, NT_STATUS(0x80000001)}, + {ERRDOS, 998, NT_STATUS(0x80000002)}, + {ERRDOS, ERRbadpath, NT_STATUS(0x80000003)}, + {ERRDOS, ERRnofids, NT_STATUS(0x80000004)}, + {ERRDOS, 111, NT_STATUS(0x80000005)}, + {ERRDOS, ERRnofiles, NT_STATUS(0x80000006)}, + {ERRDOS, 1391, NT_STATUS(0x8000000b)}, + {ERRDOS, 299, NT_STATUS(0x8000000d)}, + {ERRDOS, 28, NT_STATUS(0x8000000e)}, + {ERRDOS, 21, NT_STATUS(0x8000000f)}, + {ERRDOS, 21, NT_STATUS(0x80000010)}, + {ERRDOS, 170, NT_STATUS(0x80000011)}, + {ERRDOS, 259, NT_STATUS(0x80000012)}, + {ERRDOS, 254, NT_STATUS(0x80000013)}, + {ERRDOS, 275, NT_STATUS(0x80000014)}, + {ERRDOS, 275, NT_STATUS(0x80000015)}, + {ERRDOS, 1110, NT_STATUS(0x80000016)}, + {ERRDOS, 259, NT_STATUS_UNABLE_TO_FREE_VM}, + {ERRDOS, 1101, NT_STATUS(0x8000001b)}, + {ERRDOS, 1110, NT_STATUS(0x8000001c)}, + {ERRDOS, 1111, NT_STATUS(0x8000001d)}, + {ERRDOS, 1100, NT_STATUS(0x8000001e)}, + {ERRDOS, 1102, NT_STATUS(0x8000001f)}, + {ERRDOS, 1103, NT_STATUS(0x80000021)}, + {ERRDOS, 1104, NT_STATUS(0x80000022)}, + {ERRDOS, 2402, NT_STATUS(0x80000025)}, + {ERRDOS, 1165, NT_STATUS(0x80000288)}, + {ERRDOS, 1166, NT_STATUS(0x80000289)}, +}; + + +/* dos -> nt status error map */ +static struct { + uint8 dos_class; + uint32 dos_code; + NTSTATUS ntstatus; +} dos_to_ntstatus_map[] = { + {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, + {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, + {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, + {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, + {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, + {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, + {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRDOS, ERRbaddata, NT_STATUS_DATA_ERROR}, + {ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, + {ERRDOS, ERRremcd, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, + {ERRDOS, ERRnofiles, NT_STATUS(0x80000006)}, + {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, + {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, + {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, + {ERRDOS, 23, NT_STATUS_DATA_ERROR}, + {ERRDOS, 24, NT_STATUS_DATA_ERROR}, + {ERRDOS, 26, NT_STATUS_DISK_CORRUPT_ERROR}, + {ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, + {ERRDOS, 28, NT_STATUS(0x8000000e)}, + {ERRDOS, 31, NT_STATUS_UNSUCCESSFUL}, + {ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, + {ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, + {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, + {ERRDOS, 38, NT_STATUS_END_OF_FILE}, + {ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, + {ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, + {ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, + {ERRDOS, 53, NT_STATUS_BAD_NETWORK_PATH}, + {ERRDOS, 54, NT_STATUS_NETWORK_BUSY}, + {ERRDOS, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, + {ERRDOS, 56, NT_STATUS_TOO_MANY_COMMANDS}, + {ERRDOS, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, + {ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, + {ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, + {ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, + {ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, + {ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, + {ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, + {ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, + {ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, + {ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, + {ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRDOS, 86, NT_STATUS_WRONG_PASSWORD}, + {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, + {ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, + {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, + {ERRDOS, 111, STATUS_MORE_ENTRIES}, + {ERRDOS, 112, NT_STATUS_DISK_FULL}, + {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, + {ERRDOS, 122, NT_STATUS_BUFFER_TOO_SMALL}, + {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, + {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, + {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, + {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, + {ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, + {ERRDOS, 158, NT_STATUS_NOT_LOCKED}, + {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, + {ERRDOS, 170, NT_STATUS(0x80000011)}, + {ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, + {ERRDOS, 183, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, + {ERRDOS, 203, NT_STATUS(0xc0000100)}, + {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, + {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_INFO_CLASS}, + {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, + {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, + {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, + {ERRDOS, ERRmoredata, STATUS_MORE_ENTRIES}, + {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, + {ERRDOS, 254, NT_STATUS(0x80000013)}, + {ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, + {ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, + {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, + {ERRDOS, 275, NT_STATUS_EA_TOO_LARGE}, + {ERRDOS, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRDOS, 277, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRDOS, 278, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRDOS, 282, NT_STATUS_EAS_NOT_SUPPORTED}, + {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, + {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, + {ERRDOS, 299, NT_STATUS(0x8000000d)}, + {ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, + {ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, + {ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, + {ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, + {ERRDOS, 535, NT_STATUS_PIPE_CONNECTED}, + {ERRDOS, 536, NT_STATUS_PIPE_LISTENING}, + {ERRDOS, 995, NT_STATUS_CANCELLED}, + {ERRDOS, 997, NT_STATUS(0x00000103)}, + {ERRDOS, 998, NT_STATUS_ACCESS_VIOLATION}, + {ERRDOS, 999, NT_STATUS_IN_PAGE_ERROR}, + {ERRDOS, 1001, NT_STATUS_BAD_INITIAL_STACK}, + {ERRDOS, 1005, NT_STATUS_UNRECOGNIZED_VOLUME}, + {ERRDOS, 1006, NT_STATUS_FILE_INVALID}, + {ERRDOS, 1007, NT_STATUS_FULLSCREEN_MODE}, + {ERRDOS, 1008, NT_STATUS_NO_TOKEN}, + {ERRDOS, 1009, NT_STATUS_REGISTRY_CORRUPT}, + {ERRDOS, 1016, NT_STATUS_REGISTRY_IO_FAILED}, + {ERRDOS, 1017, NT_STATUS_NOT_REGISTRY_FILE}, + {ERRDOS, 1018, NT_STATUS_KEY_DELETED}, + {ERRDOS, 1019, NT_STATUS_NO_LOG_SPACE}, + {ERRDOS, 1020, NT_STATUS_KEY_HAS_CHILDREN}, + {ERRDOS, 1021, NT_STATUS_CHILD_MUST_BE_VOLATILE}, + {ERRDOS, 1022, NT_STATUS(0x0000010c)}, + {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, + {ERRSRV, ERRbadtype, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRSRV, ERRaccess, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRSRV, ERRinvnid, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRSRV, ERRinvnetname, NT_STATUS_BAD_NETWORK_NAME}, + {ERRSRV, ERRinvdevice, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRSRV, ERRqfull, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRSRV, ERRqtoobig, NT_STATUS_NO_SPOOL_SPACE}, + {ERRSRV, ERRinvpfid, NT_STATUS_PRINT_CANCELLED}, + {ERRSRV, ERRsmbcmd, NT_STATUS_NOT_IMPLEMENTED}, + {ERRSRV, ERRbadpermits, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRSRV, ERRpaused, NT_STATUS_SHARING_PAUSED}, + {ERRSRV, ERRmsgoff, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRSRV, ERRnoroom, NT_STATUS_DISK_FULL}, + {ERRSRV, ERRnoresource, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRSRV, ERRtoomanyuids, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRSRV, 123, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRSRV, 206, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRHRD, 1, NT_STATUS_NOT_IMPLEMENTED}, + {ERRHRD, 2, NT_STATUS_NO_SUCH_DEVICE}, + {ERRHRD, 3, NT_STATUS_OBJECT_PATH_NOT_FOUND}, + {ERRHRD, 4, NT_STATUS_TOO_MANY_OPENED_FILES}, + {ERRHRD, 5, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRHRD, 6, NT_STATUS_INVALID_HANDLE}, + {ERRHRD, 8, NT_STATUS_INSUFFICIENT_RESOURCES}, + {ERRHRD, 12, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRHRD, 13, NT_STATUS_DATA_ERROR}, + {ERRHRD, 14, NT_STATUS_SECTION_NOT_EXTENDED}, + {ERRHRD, 16, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRHRD, 17, NT_STATUS_NOT_SAME_DEVICE}, + {ERRHRD, 18, NT_STATUS(0x80000006)}, + {ERRHRD, ERRnowrite, NT_STATUS_MEDIA_WRITE_PROTECTED}, + {ERRHRD, ERRnotready, NT_STATUS_NO_MEDIA_IN_DEVICE}, + {ERRHRD, ERRbadcmd, NT_STATUS_INVALID_DEVICE_STATE}, + {ERRHRD, ERRdata, NT_STATUS_DATA_ERROR}, + {ERRHRD, ERRbadreq, NT_STATUS_DATA_ERROR}, + {ERRHRD, ERRbadmedia, NT_STATUS_DISK_CORRUPT_ERROR}, + {ERRHRD, ERRbadsector, NT_STATUS_NONEXISTENT_SECTOR}, + {ERRHRD, ERRnopaper, NT_STATUS(0x8000000e)}, + {ERRHRD, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, + {ERRHRD, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, + {ERRHRD, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, + {ERRHRD, ERRwrongdisk, NT_STATUS_WRONG_VOLUME}, + {ERRHRD, 38, NT_STATUS_END_OF_FILE}, + {ERRHRD, 50, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, + {ERRHRD, 51, NT_STATUS_REMOTE_NOT_LISTENING}, + {ERRHRD, 52, NT_STATUS_DUPLICATE_NAME}, + {ERRHRD, 53, NT_STATUS_BAD_NETWORK_PATH}, + {ERRHRD, 54, NT_STATUS_NETWORK_BUSY}, + {ERRHRD, 55, NT_STATUS_DEVICE_DOES_NOT_EXIST}, + {ERRHRD, 56, NT_STATUS_TOO_MANY_COMMANDS}, + {ERRHRD, 57, NT_STATUS_ADAPTER_HARDWARE_ERROR}, + {ERRHRD, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, + {ERRHRD, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, + {ERRHRD, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, + {ERRHRD, 61, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRHRD, 62, NT_STATUS_NO_SPOOL_SPACE}, + {ERRHRD, 63, NT_STATUS_PRINT_CANCELLED}, + {ERRHRD, 64, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRHRD, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRHRD, 66, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRHRD, 67, NT_STATUS_BAD_NETWORK_NAME}, + {ERRHRD, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, + {ERRHRD, 69, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRHRD, 70, NT_STATUS_SHARING_PAUSED}, + {ERRHRD, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRHRD, 72, NT_STATUS_REDIRECTOR_PAUSED}, + {ERRHRD, 80, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRHRD, 86, NT_STATUS_WRONG_PASSWORD}, + {ERRHRD, 87, NT_STATUS_INVALID_INFO_CLASS}, + {ERRHRD, 88, NT_STATUS_NET_WRITE_FAULT}, + {ERRHRD, 109, NT_STATUS_PIPE_BROKEN}, + {ERRHRD, 111, STATUS_MORE_ENTRIES}, + {ERRHRD, 112, NT_STATUS_DISK_FULL}, + {ERRHRD, 121, NT_STATUS_IO_TIMEOUT}, + {ERRHRD, 122, NT_STATUS_BUFFER_TOO_SMALL}, + {ERRHRD, 123, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRHRD, 124, NT_STATUS_INVALID_LEVEL}, + {ERRHRD, 126, NT_STATUS_DLL_NOT_FOUND}, + {ERRHRD, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, + {ERRHRD, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRHRD, 154, NT_STATUS_INVALID_VOLUME_LABEL}, + {ERRHRD, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, + {ERRHRD, 158, NT_STATUS_NOT_LOCKED}, + {ERRHRD, 161, NT_STATUS_OBJECT_PATH_INVALID}, + {ERRHRD, 170, NT_STATUS(0x80000011)}, + {ERRHRD, 182, NT_STATUS_ORDINAL_NOT_FOUND}, + {ERRHRD, 183, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRHRD, 193, NT_STATUS_BAD_INITIAL_PC}, + {ERRHRD, 203, NT_STATUS(0xc0000100)}, + {ERRHRD, 206, NT_STATUS_NAME_TOO_LONG}, + {ERRHRD, 230, NT_STATUS_INVALID_INFO_CLASS}, + {ERRHRD, 231, NT_STATUS_INSTANCE_NOT_AVAILABLE}, + {ERRHRD, 232, NT_STATUS_PIPE_CLOSING}, + {ERRHRD, 233, NT_STATUS_PIPE_DISCONNECTED}, + {ERRHRD, 234, STATUS_MORE_ENTRIES}, + {ERRHRD, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, + {ERRHRD, 254, NT_STATUS(0x80000013)}, + {ERRHRD, 255, NT_STATUS_EA_TOO_LARGE}, + {ERRHRD, 259, NT_STATUS_GUIDS_EXHAUSTED}, + {ERRHRD, 267, NT_STATUS_NOT_A_DIRECTORY}, + {ERRHRD, 275, NT_STATUS_EA_TOO_LARGE}, + {ERRHRD, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRHRD, 277, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRHRD, 278, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRHRD, 282, NT_STATUS_EAS_NOT_SUPPORTED}, + {ERRHRD, 288, NT_STATUS_MUTANT_NOT_OWNED}, + {ERRHRD, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, + {ERRHRD, 299, NT_STATUS(0x8000000d)}, + {ERRHRD, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, + {ERRHRD, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, + {ERRHRD, 487, NT_STATUS_CONFLICTING_ADDRESSES}, + {ERRHRD, 534, NT_STATUS_INTEGER_OVERFLOW}, + {ERRHRD, 535, NT_STATUS_PIPE_CONNECTED}, + {ERRHRD, 536, NT_STATUS_PIPE_LISTENING}, + {ERRHRD, 995, NT_STATUS_CANCELLED}, + {ERRHRD, 997, NT_STATUS(0x00000103)}, + {ERRHRD, 998, NT_STATUS_ACCESS_VIOLATION}, + {ERRHRD, 999, NT_STATUS_IN_PAGE_ERROR}, + {ERRHRD, 1001, NT_STATUS_BAD_INITIAL_STACK}, + {ERRHRD, 1005, NT_STATUS_UNRECOGNIZED_VOLUME}, + {ERRHRD, 1006, NT_STATUS_FILE_INVALID}, + {ERRHRD, 1007, NT_STATUS_FULLSCREEN_MODE}, + {ERRHRD, 1008, NT_STATUS_NO_TOKEN}, + {ERRHRD, 1009, NT_STATUS_REGISTRY_CORRUPT}, + {ERRHRD, 1016, NT_STATUS_REGISTRY_IO_FAILED}, + {ERRHRD, 1017, NT_STATUS_NOT_REGISTRY_FILE}, + {ERRHRD, 1018, NT_STATUS_KEY_DELETED}, + {ERRHRD, 1019, NT_STATUS_NO_LOG_SPACE}, + {ERRHRD, 1020, NT_STATUS_KEY_HAS_CHILDREN}, + {ERRHRD, 1021, NT_STATUS_CHILD_MUST_BE_VOLATILE}, + {ERRHRD, 1022, NT_STATUS(0x0000010c)}, +}; + + +/***************************************************************************** +convert a dos eclas/ecode to a NT status32 code + *****************************************************************************/ +NTSTATUS dos_to_ntstatus(int eclass, int ecode) +{ + int i; + for (i=0; NT_STATUS_V(dos_to_ntstatus_map[i].ntstatus); i++) { + if (eclass == dos_to_ntstatus_map[i].dos_class && + ecode == dos_to_ntstatus_map[i].dos_code) { + return dos_to_ntstatus_map[i].ntstatus; + } + } + return NT_STATUS_UNSUCCESSFUL; +} + + +/***************************************************************************** +convert a NT status code to a dos class/code + *****************************************************************************/ +void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode) +{ + int i; + for (i=0; NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus); i++) { + if (NT_STATUS_V(ntstatus) == + NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus)) { + *eclass = ntstatus_to_dos_map[i].dos_class; + *ecode = ntstatus_to_dos_map[i].dos_code; + return; + } + } + *eclass = ERRSRV; + *ecode = ERRerror; +} diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 1b8e8737f7..7fdeb4e5a7 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -26,8 +26,7 @@ typedef struct { char *nt_errstr; - uint32 nt_errcode; - + NTSTATUS nt_errcode; } nt_err_code_struct; nt_err_code_struct nt_errs[] = @@ -534,22 +533,22 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, - { NULL, 0 } + { NULL, NT_STATUS(0) } }; /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -char *get_nt_error_msg(uint32 nt_code) +char *get_nt_error_msg(NTSTATUS nt_code) { static pstring msg; int idx = 0; - slprintf(msg, sizeof(msg), "NT code 0x%08x", nt_code); + slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); while (nt_errs[idx].nt_errstr != NULL) { - if ((nt_errs[idx].nt_errcode & 0xFFFFFF) == - (nt_code & 0xFFFFFF)) { + if ((NT_STATUS_V(nt_errs[idx].nt_errcode) & 0xFFFFFF) == + (NT_STATUS_V(nt_code) & 0xFFFFFF)) { return nt_errs[idx].nt_errstr; } idx++; -- cgit From b031af348c7dcc8c74bf49945211c466b8eca079 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 27 Aug 2001 19:46:22 +0000 Subject: converted another bunch of stuff to NTSTATUS (This used to be commit 1d36250e338ae0ff9fbbf86019809205dd97d05e) --- source3/libsmb/cli_dfs.c | 2 +- source3/libsmb/cli_lsarpc.c | 20 +++++++++---------- source3/libsmb/cli_samr.c | 34 ++++++++++++++++----------------- source3/libsmb/cli_spoolss.c | 16 ++++++++-------- source3/libsmb/domain_client_validate.c | 10 +++++----- source3/libsmb/errormap.c | 2 +- source3/libsmb/libsmbclient.c | 2 +- 7 files changed, 43 insertions(+), 43 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index a16c76658f..ad36438ed8 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -66,7 +66,7 @@ uint32 cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, *dfs_exists = (r.status == 1); - result = NT_STATUS_NOPROBLEMO; + result = NT_STATUS_OK; done: prs_mem_free(&qbuf); diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 8cf0817420..023f7f8dae 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -78,7 +78,7 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *pol = r.pol; } @@ -136,7 +136,7 @@ uint32 cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *pol = r.pol; } @@ -184,7 +184,7 @@ uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *pol = r.pol; } @@ -242,7 +242,7 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_NOPROBLEMO && result != 0x00000107 && + if (result != NT_STATUS_OK && result != 0x00000107 && result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { /* An actual error occured */ @@ -250,7 +250,7 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - result = NT_STATUS_NOPROBLEMO; + result = NT_STATUS_OK; /* Return output parameters */ @@ -347,7 +347,7 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_NOPROBLEMO && + if (result != NT_STATUS_OK && result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { /* An actual error occured */ @@ -355,7 +355,7 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - result = NT_STATUS_NOPROBLEMO; + result = NT_STATUS_OK; /* Return output parameters */ @@ -441,7 +441,7 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_OK) { goto done; } @@ -536,7 +536,7 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, 0x8000001a (NT_STATUS_UNABLE_TO_FREE_VM) so we ignore it and pretend everything is OK. */ - if (result != NT_STATUS_NOPROBLEMO && + if (result != NT_STATUS_OK && result != NT_STATUS_UNABLE_TO_FREE_VM) { /* An actual error ocured */ @@ -544,7 +544,7 @@ uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - result = NT_STATUS_NOPROBLEMO; + result = NT_STATUS_OK; /* Return output parameters */ diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index dee1baff02..123f5c116b 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -68,7 +68,7 @@ uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *connect_pol = r.connect_pol; } @@ -114,7 +114,7 @@ uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *connect_pol = r.pol; } @@ -161,7 +161,7 @@ uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *domain_pol = r.domain_pol; } @@ -208,7 +208,7 @@ uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *user_pol = r.user_pol; } @@ -255,7 +255,7 @@ uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *group_pol = r.pol; } @@ -395,7 +395,7 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *num_groups = r.num_entries; *gid = r.gid; } @@ -443,7 +443,7 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *num_mem = r.num_entries; *rid = r.rid; *attr = r.attr; @@ -495,7 +495,7 @@ uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_NOPROBLEMO && + if (result != NT_STATUS_OK && result != STATUS_MORE_ENTRIES) { goto done; } @@ -569,7 +569,7 @@ uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_OK) { goto done; } @@ -629,7 +629,7 @@ uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *alias_pol = r.pol; } @@ -678,7 +678,7 @@ uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_OK) { goto done; } @@ -731,7 +731,7 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_NOPROBLEMO && + if (result != NT_STATUS_OK && result != STATUS_MORE_ENTRIES) { goto done; } @@ -791,7 +791,7 @@ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_OK) { goto done; } @@ -859,7 +859,7 @@ uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_OK) { goto done; } @@ -921,7 +921,7 @@ uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_OK) { goto done; } @@ -977,7 +977,7 @@ uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_OK) { goto done; } @@ -1024,7 +1024,7 @@ uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_NOPROBLEMO) { + if ((result = r.status) != NT_STATUS_OK) { goto done; } diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 9c53912dff..b301de6448 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -84,7 +84,7 @@ uint32 cli_spoolss_open_printer_ex( /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *pol = r.handle; } @@ -137,7 +137,7 @@ uint32 cli_spoolss_close_printer( /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { *pol = r.handle; } @@ -429,7 +429,7 @@ uint32 cli_spoolss_enum_printers( /* Return output parameters */ - if (((result=r.status) == NT_STATUS_NOPROBLEMO) && (*returned = r.returned)) + if (((result=r.status) == NT_STATUS_OK) && (*returned = r.returned)) { switch (level) { @@ -505,7 +505,7 @@ uint32 cli_spoolss_enum_ports( /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO && + if ((result = r.status) == NT_STATUS_OK && r.returned > 0) { *returned = r.returned; @@ -574,7 +574,7 @@ uint32 cli_spoolss_getprinter( } /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) { + if ((result = r.status) == NT_STATUS_OK) { switch (level) { case 0: @@ -705,7 +705,7 @@ uint32 cli_spoolss_getprinterdriver ( } /* Return output parameters */ - if ((result = r.status) == NT_STATUS_NOPROBLEMO) + if ((result = r.status) == NT_STATUS_OK) { switch (level) @@ -784,7 +784,7 @@ uint32 cli_spoolss_enumprinterdrivers ( } /* Return output parameters */ - if (((result=r.status) == NT_STATUS_NOPROBLEMO) && + if (((result=r.status) == NT_STATUS_OK) && (r.returned != 0)) { *returned = r.returned; @@ -865,7 +865,7 @@ uint32 cli_spoolss_getprinterdriverdir ( } /* Return output parameters */ - if ((result=r.status) == NT_STATUS_NOPROBLEMO) + if ((result=r.status) == NT_STATUS_OK) { switch (level) { diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 5c56a815ef..69b5739b63 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -269,7 +269,7 @@ static BOOL find_connect_pdc(struct cli_state *pcli, use it, otherwise figure out a server from the 'password server' param. ************************************************************************/ -uint32 domain_client_validate(const auth_usersupplied_info *user_info, +NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, auth_serversupplied_info *server_info, char *server, unsigned char *trust_passwd, time_t last_change_time) @@ -280,7 +280,7 @@ uint32 domain_client_validate(const auth_usersupplied_info *user_info, struct cli_state cli; uint32 smb_uid_low; BOOL connected_ok = False; - uint32 status; + NTSTATUS status; /* * Check that the requested domain is not our own machine name. @@ -325,14 +325,14 @@ uint32 domain_client_validate(const auth_usersupplied_info *user_info, if ((status = cli_nt_login_network(&cli, user_info, smb_uid_low, &ctr, &info3)) - != NT_STATUS_NOPROBLEMO) { + != NT_STATUS_OK) { DEBUG(0,("domain_client_validate: unable to validate password " "for user %s in domain %s to Domain controller %s. " "Error was %s.\n", user_info->smb_username.str, user_info->domain.str, remote_machine, get_nt_error_msg(status))); } else { - status = NT_STATUS_NOPROBLEMO; + status = NT_STATUS_OK; } /* @@ -346,7 +346,7 @@ uint32 domain_client_validate(const auth_usersupplied_info *user_info, * send here. JRA. */ - if (status == NT_STATUS_NOPROBLMO) { + if (NT_STATUS_IS_OK(status)) { if(cli_nt_logoff(&cli, &ctr) == False) { DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ %s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 92a4b19847..a8baf025af 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -574,7 +574,7 @@ static struct { {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, - {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c0c586eceb..c3456bc4e7 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -207,7 +207,7 @@ int smbc_errno(struct cli_state *c) DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", (int)eclass, (int)ecode, (int)ecode, ret)); } else { - uint32 status; + NTSTATUS status; status = cli_nt_error(c); ret = cli_errno_from_nt(status); -- cgit From 316c3fb510f9b0dbff18077f3249219ba3028b3d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 27 Aug 2001 21:32:54 +0000 Subject: Convert to NTSTATUS. (This used to be commit 9e69f59d6c4ec4e0474c594ada3a05ecc2bc806b) --- source3/libsmb/cli_dfs.c | 34 ++++----- source3/libsmb/cli_lsarpc.c | 52 +++++++------- source3/libsmb/cli_reg.c | 22 +++--- source3/libsmb/cli_samr.c | 168 +++++++++++++++++++++---------------------- source3/libsmb/cli_spoolss.c | 48 ++++++------- source3/libsmb/cli_srvsvc.c | 7 +- 6 files changed, 165 insertions(+), 166 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index ad36438ed8..b1ad01e748 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -31,13 +31,13 @@ struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name, /* Query DFS support */ -uint32 cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL *dfs_exists) +NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, + BOOL *dfs_exists) { prs_struct qbuf, rbuf; DFS_Q_DFS_EXIST q; DFS_R_DFS_EXIST r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -75,14 +75,14 @@ uint32 cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -uint32 cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename, - char *comment, uint32 flags) +NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *entrypath, char *servername, char *sharename, + char *comment, uint32 flags) { prs_struct qbuf, rbuf; DFS_Q_DFS_ADD q; DFS_R_DFS_ADD r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -117,13 +117,13 @@ uint32 cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -uint32 cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename) +NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *entrypath, char *servername, char *sharename) { prs_struct qbuf, rbuf; DFS_Q_DFS_REMOVE q; DFS_R_DFS_REMOVE r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -159,15 +159,15 @@ uint32 cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -uint32 cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename, - uint32 info_level, DFS_INFO_CTR *ctr) +NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *entrypath, char *servername, char *sharename, + uint32 info_level, DFS_INFO_CTR *ctr) { prs_struct qbuf, rbuf; DFS_Q_DFS_GET_INFO q; DFS_R_DFS_GET_INFO r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -207,13 +207,13 @@ uint32 cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Enumerate dfs shares */ -uint32 cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 info_level, DFS_INFO_CTR *ctr) +NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 info_level, DFS_INFO_CTR *ctr) { prs_struct qbuf, rbuf; DFS_Q_DFS_ENUM q; DFS_R_DFS_ENUM r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 023f7f8dae..791b6eace3 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -35,14 +35,14 @@ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, /* Open a LSA policy handle */ -uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL sec_qos, uint32 des_access, POLICY_HND *pol) +NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, + BOOL sec_qos, uint32 des_access, POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_OPEN_POL q; LSA_R_OPEN_POL r; LSA_SEC_QOS qos; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -91,14 +91,14 @@ uint32 cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Open a LSA policy handle */ -uint32 cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL sec_qos, uint32 des_access, POLICY_HND *pol) +NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, + BOOL sec_qos, uint32 des_access, POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_OPEN_POL2 q; LSA_R_OPEN_POL2 r; LSA_SEC_QOS qos; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -149,13 +149,13 @@ uint32 cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Close a LSA policy handle */ -uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) +NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) { prs_struct qbuf, rbuf; LSA_Q_CLOSE q; LSA_R_CLOSE r; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -197,16 +197,16 @@ uint32 cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Lookup a list of sids */ -uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***names, uint32 **types, int *num_names) +NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, int num_sids, DOM_SID *sids, + char ***names, uint32 **types, int *num_names) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; LSA_R_LOOKUP_SIDS r; DOM_R_REF ref; LSA_TRANS_NAME_ENUM t_names; - uint32 result; + NTSTATUS result; int i; ZERO_STRUCT(q); @@ -306,15 +306,15 @@ uint32 cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Lookup a list of names */ -uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, char **names, - DOM_SID **sids, uint32 **types, int *num_sids) +NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, int num_names, char **names, + DOM_SID **sids, uint32 **types, int *num_sids) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_NAMES q; LSA_R_LOOKUP_NAMES r; DOM_R_REF ref; - uint32 result; + NTSTATUS result; int i; ZERO_STRUCT(q); @@ -407,14 +407,14 @@ uint32 cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Query info policy */ -uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint16 info_class, - fstring domain_name, DOM_SID *domain_sid) +NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint16 info_class, + fstring domain_name, DOM_SID *domain_sid) { prs_struct qbuf, rbuf; LSA_Q_QUERY_INFO q; LSA_R_QUERY_INFO r; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -494,15 +494,15 @@ uint32 cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Enumerate list of trusted domains */ -uint32 cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_ctx, - uint32 *num_domains, char ***domain_names, - DOM_SID **domain_sids) +NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *enum_ctx, + uint32 *num_domains, char ***domain_names, + DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; LSA_R_ENUM_TRUST_DOM r; - uint32 result; + NTSTATUS result; int i; ZERO_STRUCT(q); diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c index 42fea91874..88e6d3b36d 100644 --- a/source3/libsmb/cli_reg.c +++ b/source3/libsmb/cli_reg.c @@ -1,4 +1,3 @@ - /* Unix SMB/Netbios implementation. Version 2.2 @@ -28,24 +27,25 @@ #include "includes.h" /* Opens a SMB connection to the WINREG pipe */ + struct cli_state *cli_winreg_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) + char *system_name, + struct ntuser_creds *creds) { return cli_pipe_initialise(cli, system_name, PIPE_WINREG, creds); } /* Shutdown a server */ -uint32 cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, - const char *srv_name, const char *msg, - uint32 timeout, uint16 flags) +NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, + const char *srv_name, const char *msg, + uint32 timeout, uint16 flags) { prs_struct qbuf; prs_struct rbuf; REG_Q_SHUTDOWN q_s; REG_R_SHUTDOWN r_s; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; if (msg == NULL) return False; @@ -78,15 +78,14 @@ done: /* Abort a server shutdown */ -uint32 cli_reg_abort_shutdown(struct cli_state * cli, - TALLOC_CTX *mem_ctx, - const char *srv_name) +NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, + const char *srv_name) { prs_struct rbuf; prs_struct qbuf; REG_Q_ABORT_SHUTDOWN q_s; REG_R_ABORT_SHUTDOWN r_s; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT (q_s); ZERO_STRUCT (r_s); @@ -113,4 +112,3 @@ done: return result; } - diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 123f5c116b..9e40135801 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -35,13 +35,13 @@ struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name, /* Connect to SAMR database */ -uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 access_mask, POLICY_HND *connect_pol) +NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 access_mask, POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CONNECT q; SAMR_R_CONNECT r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -81,13 +81,13 @@ uint32 cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Close SAMR handle */ -uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol) +NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol) { prs_struct qbuf, rbuf; SAMR_Q_CLOSE_HND q; SAMR_R_CLOSE_HND r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -127,14 +127,14 @@ uint32 cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Open handle on a domain */ -uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol, uint32 access_mask, - DOM_SID *domain_sid, POLICY_HND *domain_pol) +NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *connect_pol, uint32 access_mask, + DOM_SID *domain_sid, POLICY_HND *domain_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_DOMAIN q; SAMR_R_OPEN_DOMAIN r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -174,14 +174,14 @@ uint32 cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Open handle on a user */ -uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 user_rid, POLICY_HND *user_pol) +NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 user_rid, POLICY_HND *user_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_USER q; SAMR_R_OPEN_USER r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -221,14 +221,14 @@ uint32 cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Open handle on a group */ -uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 group_rid, POLICY_HND *group_pol) +NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 group_rid, POLICY_HND *group_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_GROUP q; SAMR_R_OPEN_GROUP r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -268,14 +268,14 @@ uint32 cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Query user info */ -uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - SAM_USERINFO_CTR **ctr) +NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + SAM_USERINFO_CTR **ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERINFO q; SAMR_R_QUERY_USERINFO r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -314,14 +314,14 @@ uint32 cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Query group info */ -uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, uint32 info_level, - GROUP_INFO_CTR *ctr) +NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 info_level, + GROUP_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPINFO q; SAMR_R_QUERY_GROUPINFO r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -361,14 +361,14 @@ uint32 cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Query user groups */ -uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint32 *num_groups, - DOM_GID **gid) +NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint32 *num_groups, + DOM_GID **gid) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_USERGROUPS q; SAMR_R_QUERY_USERGROUPS r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -409,14 +409,14 @@ uint32 cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Query user groups */ -uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, uint32 *num_mem, - uint32 **rid, uint32 **attr) +NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *group_pol, uint32 *num_mem, + uint32 **rid, uint32 **attr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_GROUPMEM q; SAMR_R_QUERY_GROUPMEM r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -458,15 +458,15 @@ uint32 cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Enumerate domain groups */ -uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, - uint32 size, struct acct_info **dom_groups, - uint32 *num_dom_groups) +NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *start_idx, + uint32 size, struct acct_info **dom_groups, + uint32 *num_dom_groups) { prs_struct qbuf, rbuf; SAMR_Q_ENUM_DOM_GROUPS q; SAMR_R_ENUM_DOM_GROUPS r; - uint32 result = NT_STATUS_UNSUCCESSFUL, name_idx, i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL, name_idx, i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -535,14 +535,14 @@ uint32 cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Query alias members */ -uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *alias_pol, uint32 *num_mem, - DOM_SID **sids) +NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *alias_pol, uint32 *num_mem, + DOM_SID **sids) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_ALIASMEM q; SAMR_R_QUERY_ALIASMEM r; - uint32 result = NT_STATUS_UNSUCCESSFUL, i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL, i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -593,14 +593,14 @@ uint32 cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Open handle on an alias */ -uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 alias_rid, POLICY_HND *alias_pol) +NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 access_mask, + uint32 alias_rid, POLICY_HND *alias_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_ALIAS q; SAMR_R_OPEN_ALIAS r; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -642,14 +642,14 @@ uint32 cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Query domain info */ -uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint16 switch_value, - SAM_UNK_CTR *ctr) +NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint16 switch_value, + SAM_UNK_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_DOMAIN_INFO q; SAMR_R_QUERY_DOMAIN_INFO r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -691,15 +691,15 @@ uint32 cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Query display info */ -uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 *start_idx, - uint16 switch_value, uint32 *num_entries, - uint32 max_entries, SAM_DISPINFO_CTR *ctr) +NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 *start_idx, + uint16 switch_value, uint32 *num_entries, + uint32 max_entries, SAM_DISPINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_QUERY_DISPINFO q; SAMR_R_QUERY_DISPINFO r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -749,16 +749,16 @@ uint32 cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are looked up in one packet. */ -uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 flags, - uint32 num_rids, uint32 *rids, - uint32 *num_names, char ***names, - uint32 **name_types) +NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 flags, + uint32 num_rids, uint32 *rids, + uint32 *num_names, char ***names, + uint32 **name_types) { prs_struct qbuf, rbuf; SAMR_Q_LOOKUP_RIDS q; SAMR_R_LOOKUP_RIDS r; - uint32 result = NT_STATUS_UNSUCCESSFUL, i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL, i; if (num_rids > 1000) { DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if " @@ -822,16 +822,16 @@ uint32 cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Lookup names */ -uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 flags, - uint32 num_names, char **names, - uint32 *num_rids, uint32 **rids, - uint32 **rid_types) +NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, uint32 flags, + uint32 num_names, char **names, + uint32 *num_rids, uint32 **rids, + uint32 **rid_types) { prs_struct qbuf, rbuf; SAMR_Q_LOOKUP_NAMES q; SAMR_R_LOOKUP_NAMES r; - uint32 result = NT_STATUS_UNSUCCESSFUL, i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL, i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -886,15 +886,15 @@ uint32 cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Create a domain user */ -uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, char *acct_name, - uint32 acb_info, uint32 unknown, - POLICY_HND *user_pol, uint32 *rid) +NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *domain_pol, char *acct_name, + uint32 acb_info, uint32 unknown, + POLICY_HND *user_pol, uint32 *rid) { prs_struct qbuf, rbuf; SAMR_Q_CREATE_USER q; SAMR_R_CREATE_USER r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -940,14 +940,14 @@ uint32 cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Set userinfo */ -uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) +NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + uchar sess_key[16], SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_SET_USERINFO q; SAMR_R_SET_USERINFO r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -990,14 +990,14 @@ uint32 cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Set userinfo2 */ -uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) +NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + uchar sess_key[16], SAM_USERINFO_CTR *ctr) { prs_struct qbuf, rbuf; SAMR_Q_SET_USERINFO2 q; SAMR_R_SET_USERINFO2 r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -1037,13 +1037,13 @@ uint32 cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Delete domain user */ -uint32 cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol) +NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol) { prs_struct qbuf, rbuf; SAMR_Q_DELETE_DOM_USER q; SAMR_R_DELETE_DOM_USER r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index b301de6448..54769ce18d 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -38,7 +38,7 @@ struct cli_state *cli_spoolss_initialise(struct cli_state *cli, /* Open printer ex */ -uint32 cli_spoolss_open_printer_ex( +NTSTATUS cli_spoolss_open_printer_ex( struct cli_state *cli, TALLOC_CTX *mem_ctx, char *printername, @@ -52,7 +52,7 @@ uint32 cli_spoolss_open_printer_ex( prs_struct qbuf, rbuf; SPOOL_Q_OPEN_PRINTER_EX q; SPOOL_R_OPEN_PRINTER_EX r; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -97,7 +97,7 @@ uint32 cli_spoolss_open_printer_ex( /* Close a printer handle */ -uint32 cli_spoolss_close_printer( +NTSTATUS cli_spoolss_close_printer( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol @@ -106,7 +106,7 @@ uint32 cli_spoolss_close_printer( prs_struct qbuf, rbuf; SPOOL_Q_CLOSEPRINTER q; SPOOL_R_CLOSEPRINTER r; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -380,7 +380,7 @@ static void decode_printerdriverdir_1 ( /* Enumerate printers */ -uint32 cli_spoolss_enum_printers( +NTSTATUS cli_spoolss_enum_printers( struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 flags, @@ -394,7 +394,7 @@ uint32 cli_spoolss_enum_printers( SPOOL_R_ENUMPRINTERS r; NEW_BUFFER buffer; uint32 needed = 100; - uint32 result; + NTSTATUS result; fstring server; ZERO_STRUCT(q); @@ -458,7 +458,7 @@ uint32 cli_spoolss_enum_printers( } /* Enumerate printer ports */ -uint32 cli_spoolss_enum_ports( +NTSTATUS cli_spoolss_enum_ports( struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 level, @@ -471,7 +471,7 @@ uint32 cli_spoolss_enum_ports( SPOOL_R_ENUMPORTS r; NEW_BUFFER buffer; uint32 needed = 100; - uint32 result; + NTSTATUS result; fstring server; ZERO_STRUCT(q); @@ -532,7 +532,7 @@ uint32 cli_spoolss_enum_ports( } /* Get printer info */ -uint32 cli_spoolss_getprinter( +NTSTATUS cli_spoolss_getprinter( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, @@ -545,7 +545,7 @@ uint32 cli_spoolss_getprinter( SPOOL_R_GETPRINTER r; NEW_BUFFER buffer; uint32 needed = 100; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -604,7 +604,7 @@ uint32 cli_spoolss_getprinter( /********************************************************************** * Set printer info */ -uint32 cli_spoolss_setprinter( +NTSTATUS cli_spoolss_setprinter( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, @@ -616,7 +616,7 @@ uint32 cli_spoolss_setprinter( prs_struct qbuf, rbuf; SPOOL_Q_SETPRINTER q; SPOOL_R_SETPRINTER r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -654,7 +654,7 @@ done: /********************************************************************** * Get installed printer drivers for a given printer */ -uint32 cli_spoolss_getprinterdriver ( +NTSTATUS cli_spoolss_getprinterdriver ( struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, @@ -668,7 +668,7 @@ uint32 cli_spoolss_getprinterdriver ( SPOOL_R_GETPRINTERDRIVER2 r; NEW_BUFFER buffer; uint32 needed = 1024; - uint32 result; + NTSTATUS result; fstring server; ZERO_STRUCT(q); @@ -734,7 +734,7 @@ uint32 cli_spoolss_getprinterdriver ( /********************************************************************** * Get installed printer drivers for a given printer */ -uint32 cli_spoolss_enumprinterdrivers ( +NTSTATUS cli_spoolss_enumprinterdrivers ( struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 level, @@ -748,7 +748,7 @@ uint32 cli_spoolss_enumprinterdrivers ( SPOOL_R_ENUMPRINTERDRIVERS r; NEW_BUFFER buffer; uint32 needed = 0; - uint32 result; + NTSTATUS result; fstring server; ZERO_STRUCT(q); @@ -816,7 +816,7 @@ uint32 cli_spoolss_enumprinterdrivers ( /********************************************************************** * Get installed printer drivers for a given printer */ -uint32 cli_spoolss_getprinterdriverdir ( +NTSTATUS cli_spoolss_getprinterdriverdir ( struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 level, @@ -829,7 +829,7 @@ uint32 cli_spoolss_getprinterdriverdir ( SPOOL_R_GETPRINTERDRIVERDIR r; NEW_BUFFER buffer; uint32 needed = 100; - uint32 result; + NTSTATUS result; fstring server; ZERO_STRUCT(q); @@ -887,7 +887,7 @@ uint32 cli_spoolss_getprinterdriverdir ( /********************************************************************** * Install a printer driver */ -uint32 cli_spoolss_addprinterdriver ( +NTSTATUS cli_spoolss_addprinterdriver ( struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 level, @@ -897,7 +897,7 @@ uint32 cli_spoolss_addprinterdriver ( prs_struct qbuf, rbuf; SPOOL_Q_ADDPRINTERDRIVER q; SPOOL_R_ADDPRINTERDRIVER r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; fstring server; ZERO_STRUCT(q); @@ -943,7 +943,7 @@ done: /********************************************************************** * Install a printer */ -uint32 cli_spoolss_addprinterex ( +NTSTATUS cli_spoolss_addprinterex ( struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 level, @@ -953,7 +953,7 @@ uint32 cli_spoolss_addprinterex ( prs_struct qbuf, rbuf; SPOOL_Q_ADDPRINTEREX q; SPOOL_R_ADDPRINTEREX r; - uint32 result; + NTSTATUS result; fstring server, client, user; @@ -1006,7 +1006,7 @@ done: * Delete a Printer Driver from the server (does not remove * the driver files */ -uint32 cli_spoolss_deleteprinterdriver ( +NTSTATUS cli_spoolss_deleteprinterdriver ( struct cli_state *cli, TALLOC_CTX *mem_ctx, char *arch, @@ -1016,7 +1016,7 @@ uint32 cli_spoolss_deleteprinterdriver ( prs_struct qbuf, rbuf; SPOOL_Q_DELETEPRINTERDRIVER q; SPOOL_R_DELETEPRINTERDRIVER r; - uint32 result; + NTSTATUS result; fstring server; ZERO_STRUCT(q); diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 042a9c44ff..c9bd464362 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -32,13 +32,14 @@ struct cli_state *cli_svrsvc_initialise(struct cli_state *cli, return cli_pipe_initialise(cli, system_name, PIPE_SRVSVC, creds); } -uint32 cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 switch_value, SRV_INFO_CTR *ctr) +NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 switch_value, SRV_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SRV_Q_NET_SRV_GET_INFO q; SRV_R_NET_SRV_GET_INFO r; - uint32 result; + NTSTATUS result; ZERO_STRUCT(q); ZERO_STRUCT(r); -- cgit From 1f079939001fa4a48b37c319049bc273db85a79f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 28 Aug 2001 01:28:01 +0000 Subject: fixed typo (This used to be commit 2d1829dfd041336a587443435d8dccab365a2b56) --- source3/libsmb/clierror.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index f485d328e2..22c5dbaf77 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -219,7 +219,7 @@ int cli_errno(struct cli_state *cli) { NTSTATUS status; - if (cli_is_dos_error) { + if (cli_is_dos_error(cli)) { uint8 eclass; uint32 ecode; -- cgit From d5c9172adadb83283e437578be7bad4368ad9f20 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 Aug 2001 06:43:43 +0000 Subject: Merge of sam sync code from TNG. Reverse-engineered the sam replication protocol from staring at hex dumps for a while. It's pretty similar to the sam sync protocol with a couple of different delta header types. I wasn't able to figure out the format of the privilege stuff - needs more time and a whiteboard. (-: The impressive bit is that the sam sync stuff from tng basically just worked thanks mainly to Luke Leighton's efforts in this area. (This used to be commit 3a60cb44f22d5f3f8c78a56ed8f5ea4794cd7ab3) --- source3/libsmb/cli_netlogon.c | 145 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 63a2f4a5b1..b608398aa3 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -34,13 +34,13 @@ struct cli_state *cli_netlogon_initialise(struct cli_state *cli, /* Logon Control 2 */ -uint32 cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 query_level) +NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 query_level) { prs_struct qbuf, rbuf; NET_Q_LOGON_CTRL2 q; NET_R_LOGON_CTRL2 r; - uint32 result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -77,3 +77,142 @@ uint32 cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/**************************************************************************** +Generate the next creds to use. Yuck - this is a cut&paste from another +file. They should be combined at some stage. )-: +****************************************************************************/ + +static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) +{ + /* + * Create the new client credentials. + */ + + cli->clnt_cred.timestamp.time = time(NULL); + + memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred)); + + /* Calculate the new credentials. */ + cred_create(cli->sess_key, &(cli->clnt_cred.challenge), + new_clnt_cred->timestamp, &(new_clnt_cred->challenge)); + +} + +/* Sam synchronisation */ + +NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 database_id, uint32 *num_deltas, + SAM_DELTA_HDR **hdr_deltas, + SAM_DELTA_CTR **deltas) +{ + prs_struct qbuf, rbuf; + NET_Q_SAM_SYNC q; + NET_R_SAM_SYNC r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + DOM_CRED clnt_creds; + char sess_key[16]; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + gen_next_creds(cli, &clnt_creds); + + init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2, + &clnt_creds, database_id); + + /* Marshall data and send request */ + + if (!net_io_q_sam_sync("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!net_io_r_sam_sync("", sess_key, &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return results */ + + result = r.status; + *num_deltas = r.num_deltas2; + *hdr_deltas = r.hdr_deltas; + *deltas = r.deltas; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Sam synchronisation */ + +NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 database_id, UINT64_S seqnum, + uint32 *num_deltas, + SAM_DELTA_HDR **hdr_deltas, + SAM_DELTA_CTR **deltas) +{ + prs_struct qbuf, rbuf; + NET_Q_SAM_DELTAS q; + NET_R_SAM_DELTAS r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + DOM_CRED clnt_creds; + char sess_key[16]; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + gen_next_creds(cli, &clnt_creds); + + init_net_q_sam_deltas(&q, cli->srv_name_slash, + cli->clnt_name_slash + 2, &clnt_creds, + database_id, seqnum); + + /* Marshall data and send request */ + + if (!net_io_q_sam_deltas("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_SAM_DELTAS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!net_io_r_sam_deltas("", sess_key, &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return results */ + + result = r.status; + *num_deltas = r.num_deltas2; + *hdr_deltas = r.hdr_deltas; + *deltas = r.deltas; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 7f0b3ec809ce0a8804353b81d8252e11a0d01add Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Wed, 29 Aug 2001 03:30:52 +0000 Subject: Patched to ensure that it won't break HEAD. This isn't the final version, of course, I still need to get WINS failover working. This is just patched so it won't need lp_wins_server() (which I renamed to lp_wins_server_list()). I can't compile just now as something else is broken in HEAD. Let me know if this version of namequery.c causes trouble down the line. Shouldn't, as the changes are very small, but I've been known to rock the boat before. Chris -)----- (This used to be commit 29c6efc9564e51dc28e8434bdc86079c6502d73d) --- source3/libsmb/namequery.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a0fb366f1b..6cfc421c83 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -564,19 +564,23 @@ BOOL name_register_wins(const char *name, int name_type) * Do a broadcast register ... */ - if (!lp_wins_server()) + if (0 == wins_srv_count()) return False; - DEBUG(4, ("name_register_wins:Registering my name %s on %s\n", name, lp_wins_server())); + if( DEBUGLVL( 4 ) ) + { + dbg_text( "name_register_wins: Registering my name %s ", name ); + dbg_text( "with WINS server %s.\n", wins_srv_name() ); + } - sock = open_socket_in(SOCK_DGRAM, 0, 3, - interpret_addr("0.0.0.0"), True); + sock = open_socket_in( SOCK_DGRAM, 0, 3, + interpret_addr("0.0.0.0"), True ); if (sock == -1) return False; - set_socket_options(sock, "SO_BROADCAST"); + set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */ - sendto_ip.s_addr = inet_addr(lp_wins_server()); + sendto_ip = wins_srv_ip(); if (num_interfaces > 1) { -- cgit From 60519d046bea5d56f73c2a2f18c5146d233c0fad Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 29 Aug 2001 04:11:11 +0000 Subject: Should be dbgtext, not dbg_text. (This used to be commit 7a68236c42acc72e500e120906230a637305f418) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6cfc421c83..b2a7dfc788 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -569,8 +569,8 @@ BOOL name_register_wins(const char *name, int name_type) if( DEBUGLVL( 4 ) ) { - dbg_text( "name_register_wins: Registering my name %s ", name ); - dbg_text( "with WINS server %s.\n", wins_srv_name() ); + dbgtext( "name_register_wins: Registering my name %s ", name ); + dbgtext( "with WINS server %s.\n", wins_srv_name() ); } sock = open_socket_in( SOCK_DGRAM, 0, 3, -- cgit From 6c38114f57bebec95ce8252e675e8699f683ff5e Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Wed, 29 Aug 2001 04:26:27 +0000 Subject: Fuss, fuss, fuss... Function name_status_query() performs a node status query, so it really should be called "node_status_query()" just to be consistent. Yeah, minor... but it's looking as though an overhaul of namequery.c is in order and I am trying to do the tiny changes that impact other stuff first. Chris -)----- (This used to be commit 3af2de7ed26e5a26a273be2dcd9c5565c586fe47) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index b2a7dfc788..4a3cf43b35 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -75,7 +75,7 @@ static struct node_status *parse_node_status(char *p, int *num_names) do a NBT node status query on an open socket and return an array of structures holding the returned names or NULL if the query failed **************************************************************************/ -struct node_status *name_status_query(int fd,struct nmb_name *name, +struct node_status *node_status_query(int fd,struct nmb_name *name, struct in_addr to_ip, int *num_names) { BOOL found=False; @@ -173,7 +173,7 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name) if (sock == -1) return False; make_nmb_name(&nname, "*", 0); - status = name_status_query(sock, &nname, to_ip, &count); + status = node_status_query(sock, &nname, to_ip, &count); close(sock); if (!status) return False; -- cgit From 819f5ea0d5c6fe7d36b0f867e7f86ae6b54fd8b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 1 Sep 2001 23:08:08 +0000 Subject: use a name not a number for ERRinsufficientbuffer (This used to be commit 8e70666fccde1025d77e4db51b5b63e5142d98ec) --- source3/libsmb/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index a8baf025af..73bbde71eb 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -67,7 +67,7 @@ static struct { {ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, {ERRDOS, ERRbadaccess, NT_STATUS_ALREADY_COMMITTED}, {ERRDOS, ERRbadaccess, NT_STATUS_ACCESS_DENIED}, - {ERRDOS, 122, NT_STATUS_BUFFER_TOO_SMALL}, + {ERRDOS, ERRinsufficientbuffer, NT_STATUS_BUFFER_TOO_SMALL}, {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, {ERRDOS, 37, NT_STATUS_NONCONTINUABLE_EXCEPTION}, {ERRDOS, 38, NT_STATUS_INVALID_DISPOSITION}, -- cgit From fd6ea431617d91c5f5c6b07cb26910f4900c1515 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Sep 2001 08:50:59 +0000 Subject: the next step in our error code handling change - added WERROR for win32 error codes - added a configure test for immediate structures still lots to do, so its not enabled by default, but the main structure is there (This used to be commit 24f9ab683dec52587ee56717e821b49c0fa3d70f) --- source3/libsmb/smberr.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 9648786ea5..e6ecfefb34 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -182,3 +182,14 @@ char *smb_errstr(char *inbuf) slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); return(ret); } + + +/***************************************************************************** + returns an WERROR error message. + *****************************************************************************/ +char *werror_str(WERROR status) +{ + static fstring msg; + slprintf(msg, sizeof(msg), "WIN32 code 0x%08x", W_ERROR_V(status)); + return msg; +} -- cgit From fbc1f326f445a2826a10155fe0122c779bb1f80e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Sep 2001 10:38:13 +0000 Subject: more NTSTATUS/WERROR conversion (This used to be commit ad648c5cd8ebe4be8304379117f403d7673dcbc8) --- source3/libsmb/errormap.c | 584 ++++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smberr.c | 11 + 2 files changed, 595 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 73bbde71eb..65dcdf4bdf 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -818,6 +818,547 @@ static struct { {ERRHRD, 1022, NT_STATUS(0x0000010c)}, }; +/* errmap NTSTATUS->Win32 */ +static struct { + NTSTATUS ntstatus; + WERROR werror; +} ntstatus_to_werror_map[] = { + {NT_STATUS(0x103), W_ERROR(0x3e5)}, + {NT_STATUS(0x105), W_ERROR(0xea)}, + {NT_STATUS(0x106), W_ERROR(0x514)}, + {NT_STATUS(0x107), W_ERROR(0x515)}, + {NT_STATUS(0x10c), W_ERROR(0x3fe)}, + {NT_STATUS(0x10d), W_ERROR(0x516)}, + {NT_STATUS(0x121), W_ERROR(0x2009)}, + {NT_STATUS(0xc0000001), W_ERROR(0x1f)}, + {NT_STATUS(0xc0000002), W_ERROR(0x1)}, + {NT_STATUS(0xc0000003), W_ERROR(0x57)}, + {NT_STATUS(0xc0000004), W_ERROR(0x18)}, + {NT_STATUS(0xc0000005), W_ERROR(0x3e6)}, + {NT_STATUS(0xc0000006), W_ERROR(0x3e7)}, + {NT_STATUS(0xc0000007), W_ERROR(0x5ae)}, + {NT_STATUS(0xc0000008), W_ERROR(0x6)}, + {NT_STATUS(0xc0000009), W_ERROR(0x3e9)}, + {NT_STATUS(0xc000000a), W_ERROR(0xc1)}, + {NT_STATUS(0xc000000b), W_ERROR(0x57)}, + {NT_STATUS(0xc000000d), W_ERROR(0x57)}, + {NT_STATUS(0xc000000e), W_ERROR(0x2)}, + {NT_STATUS(0xc000000f), W_ERROR(0x2)}, + {NT_STATUS(0xc0000010), W_ERROR(0x1)}, + {NT_STATUS(0xc0000011), W_ERROR(0x26)}, + {NT_STATUS(0xc0000012), W_ERROR(0x22)}, + {NT_STATUS(0xc0000013), W_ERROR(0x15)}, + {NT_STATUS(0xc0000014), W_ERROR(0x6f9)}, + {NT_STATUS(0xc0000015), W_ERROR(0x1b)}, + {NT_STATUS(0xc0000016), W_ERROR(0xea)}, + {NT_STATUS(0xc0000017), W_ERROR(0x8)}, + {NT_STATUS(0xc0000018), W_ERROR(0x1e7)}, + {NT_STATUS(0xc0000019), W_ERROR(0x1e7)}, + {NT_STATUS(0xc000001a), W_ERROR(0x57)}, + {NT_STATUS(0xc000001b), W_ERROR(0x57)}, + {NT_STATUS(0xc000001c), W_ERROR(0x1)}, + {NT_STATUS(0xc000001d), W_ERROR(0xc000001d)}, + {NT_STATUS(0xc000001e), W_ERROR(0x5)}, + {NT_STATUS(0xc000001f), W_ERROR(0x5)}, + {NT_STATUS(0xc0000020), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000021), W_ERROR(0x5)}, + {NT_STATUS(0xc0000022), W_ERROR(0x5)}, + {NT_STATUS(0xc0000023), W_ERROR(0x7a)}, + {NT_STATUS(0xc0000024), W_ERROR(0x6)}, + {NT_STATUS(0xc0000025), W_ERROR(0xc0000025)}, + {NT_STATUS(0xc0000026), W_ERROR(0xc0000026)}, + {NT_STATUS(0xc000002a), W_ERROR(0x9e)}, + {NT_STATUS(0xc000002b), W_ERROR(0xc000002b)}, + {NT_STATUS(0xc000002c), W_ERROR(0x1e7)}, + {NT_STATUS(0xc000002d), W_ERROR(0x1e7)}, + {NT_STATUS(0xc0000030), W_ERROR(0x57)}, + {NT_STATUS(0xc0000032), W_ERROR(0x571)}, + {NT_STATUS(0xc0000033), W_ERROR(0x7b)}, + {NT_STATUS(0xc0000034), W_ERROR(0x2)}, + {NT_STATUS(0xc0000035), W_ERROR(0xb7)}, + {NT_STATUS(0xc0000037), W_ERROR(0x6)}, + {NT_STATUS(0xc0000039), W_ERROR(0xa1)}, + {NT_STATUS(0xc000003a), W_ERROR(0x3)}, + {NT_STATUS(0xc000003b), W_ERROR(0xa1)}, + {NT_STATUS(0xc000003c), W_ERROR(0x45d)}, + {NT_STATUS(0xc000003d), W_ERROR(0x45d)}, + {NT_STATUS(0xc000003e), W_ERROR(0x17)}, + {NT_STATUS(0xc000003f), W_ERROR(0x17)}, + {NT_STATUS(0xc0000040), W_ERROR(0x8)}, + {NT_STATUS(0xc0000041), W_ERROR(0x5)}, + {NT_STATUS(0xc0000042), W_ERROR(0x6)}, + {NT_STATUS(0xc0000043), W_ERROR(0x20)}, + {NT_STATUS(0xc0000044), W_ERROR(0x718)}, + {NT_STATUS(0xc0000045), W_ERROR(0x57)}, + {NT_STATUS(0xc0000046), W_ERROR(0x120)}, + {NT_STATUS(0xc0000047), W_ERROR(0x12a)}, + {NT_STATUS(0xc0000048), W_ERROR(0x57)}, + {NT_STATUS(0xc0000049), W_ERROR(0x57)}, + {NT_STATUS(0xc000004a), W_ERROR(0x9c)}, + {NT_STATUS(0xc000004b), W_ERROR(0x5)}, + {NT_STATUS(0xc000004c), W_ERROR(0x57)}, + {NT_STATUS(0xc000004d), W_ERROR(0x57)}, + {NT_STATUS(0xc000004e), W_ERROR(0x57)}, + {NT_STATUS(0xc000004f), W_ERROR(0x11a)}, + {NT_STATUS(0xc0000050), W_ERROR(0xff)}, + {NT_STATUS(0xc0000051), W_ERROR(0x570)}, + {NT_STATUS(0xc0000052), W_ERROR(0x570)}, + {NT_STATUS(0xc0000053), W_ERROR(0x570)}, + {NT_STATUS(0xc0000054), W_ERROR(0x21)}, + {NT_STATUS(0xc0000055), W_ERROR(0x21)}, + {NT_STATUS(0xc0000056), W_ERROR(0x5)}, + {NT_STATUS(0xc0000057), W_ERROR(0x32)}, + {NT_STATUS(0xc0000058), W_ERROR(0x519)}, + {NT_STATUS(0xc0000059), W_ERROR(0x51a)}, + {NT_STATUS(0xc000005a), W_ERROR(0x51b)}, + {NT_STATUS(0xc000005b), W_ERROR(0x51c)}, + {NT_STATUS(0xc000005c), W_ERROR(0x51d)}, + {NT_STATUS(0xc000005d), W_ERROR(0x51e)}, + {NT_STATUS(0xc000005e), W_ERROR(0x51f)}, + {NT_STATUS(0xc000005f), W_ERROR(0x520)}, + {NT_STATUS(0xc0000060), W_ERROR(0x521)}, + {NT_STATUS(0xc0000061), W_ERROR(0x522)}, + {NT_STATUS(0xc0000062), W_ERROR(0x523)}, + {NT_STATUS(0xc0000063), W_ERROR(0x524)}, + {NT_STATUS(0xc0000064), W_ERROR(0x525)}, + {NT_STATUS(0xc0000065), W_ERROR(0x526)}, + {NT_STATUS(0xc0000066), W_ERROR(0x527)}, + {NT_STATUS(0xc0000067), W_ERROR(0x528)}, + {NT_STATUS(0xc0000068), W_ERROR(0x529)}, + {NT_STATUS(0xc0000069), W_ERROR(0x52a)}, + {NT_STATUS(0xc000006a), W_ERROR(0x56)}, + {NT_STATUS(0xc000006b), W_ERROR(0x52c)}, + {NT_STATUS(0xc000006c), W_ERROR(0x52d)}, + {NT_STATUS(0xc000006d), W_ERROR(0x52e)}, + {NT_STATUS(0xc000006e), W_ERROR(0x52f)}, + {NT_STATUS(0xc000006f), W_ERROR(0x530)}, + {NT_STATUS(0xc0000070), W_ERROR(0x531)}, + {NT_STATUS(0xc0000071), W_ERROR(0x532)}, + {NT_STATUS(0xc0000072), W_ERROR(0x533)}, + {NT_STATUS(0xc0000073), W_ERROR(0x534)}, + {NT_STATUS(0xc0000074), W_ERROR(0x535)}, + {NT_STATUS(0xc0000075), W_ERROR(0x536)}, + {NT_STATUS(0xc0000076), W_ERROR(0x537)}, + {NT_STATUS(0xc0000077), W_ERROR(0x538)}, + {NT_STATUS(0xc0000078), W_ERROR(0x539)}, + {NT_STATUS(0xc0000079), W_ERROR(0x53a)}, + {NT_STATUS(0xc000007a), W_ERROR(0x7f)}, + {NT_STATUS(0xc000007b), W_ERROR(0xc1)}, + {NT_STATUS(0xc000007c), W_ERROR(0x3f0)}, + {NT_STATUS(0xc000007d), W_ERROR(0x53c)}, + {NT_STATUS(0xc000007e), W_ERROR(0x9e)}, + {NT_STATUS(0xc000007f), W_ERROR(0x70)}, + {NT_STATUS(0xc0000080), W_ERROR(0x53d)}, + {NT_STATUS(0xc0000081), W_ERROR(0x53e)}, + {NT_STATUS(0xc0000082), W_ERROR(0x44)}, + {NT_STATUS(0xc0000083), W_ERROR(0x103)}, + {NT_STATUS(0xc0000084), W_ERROR(0x53f)}, + {NT_STATUS(0xc0000085), W_ERROR(0x103)}, + {NT_STATUS(0xc0000086), W_ERROR(0x9a)}, + {NT_STATUS(0xc0000087), W_ERROR(0xe)}, + {NT_STATUS(0xc0000088), W_ERROR(0x1e7)}, + {NT_STATUS(0xc0000089), W_ERROR(0x714)}, + {NT_STATUS(0xc000008a), W_ERROR(0x715)}, + {NT_STATUS(0xc000008b), W_ERROR(0x716)}, + {NT_STATUS(0xc000008c), W_ERROR(0xc000008c)}, + {NT_STATUS(0xc000008d), W_ERROR(0xc000008d)}, + {NT_STATUS(0xc000008e), W_ERROR(0xc000008e)}, + {NT_STATUS(0xc000008f), W_ERROR(0xc000008f)}, + {NT_STATUS(0xc0000090), W_ERROR(0xc0000090)}, + {NT_STATUS(0xc0000091), W_ERROR(0xc0000091)}, + {NT_STATUS(0xc0000092), W_ERROR(0xc0000092)}, + {NT_STATUS(0xc0000093), W_ERROR(0xc0000093)}, + {NT_STATUS(0xc0000094), W_ERROR(0xc0000094)}, + {NT_STATUS(0xc0000095), W_ERROR(0x216)}, + {NT_STATUS(0xc0000096), W_ERROR(0xc0000096)}, + {NT_STATUS(0xc0000097), W_ERROR(0x8)}, + {NT_STATUS(0xc0000098), W_ERROR(0x3ee)}, + {NT_STATUS(0xc0000099), W_ERROR(0x540)}, + {NT_STATUS(0xc000009a), W_ERROR(0x5aa)}, + {NT_STATUS(0xc000009b), W_ERROR(0x3)}, + {NT_STATUS(0xc000009c), W_ERROR(0x17)}, + {NT_STATUS(0xc000009d), W_ERROR(0x48f)}, + {NT_STATUS(0xc000009e), W_ERROR(0x15)}, + {NT_STATUS(0xc000009f), W_ERROR(0x1e7)}, + {NT_STATUS(0xc00000a0), W_ERROR(0x1e7)}, + {NT_STATUS(0xc00000a1), W_ERROR(0x5ad)}, + {NT_STATUS(0xc00000a2), W_ERROR(0x13)}, + {NT_STATUS(0xc00000a3), W_ERROR(0x15)}, + {NT_STATUS(0xc00000a4), W_ERROR(0x541)}, + {NT_STATUS(0xc00000a5), W_ERROR(0x542)}, + {NT_STATUS(0xc00000a6), W_ERROR(0x543)}, + {NT_STATUS(0xc00000a7), W_ERROR(0x544)}, + {NT_STATUS(0xc00000a8), W_ERROR(0x545)}, + {NT_STATUS(0xc00000a9), W_ERROR(0x57)}, + {NT_STATUS(0xc00000ab), W_ERROR(0xe7)}, + {NT_STATUS(0xc00000ac), W_ERROR(0xe7)}, + {NT_STATUS(0xc00000ad), W_ERROR(0xe6)}, + {NT_STATUS(0xc00000ae), W_ERROR(0xe7)}, + {NT_STATUS(0xc00000af), W_ERROR(0x1)}, + {NT_STATUS(0xc00000b0), W_ERROR(0xe9)}, + {NT_STATUS(0xc00000b1), W_ERROR(0xe8)}, + {NT_STATUS(0xc00000b2), W_ERROR(0x217)}, + {NT_STATUS(0xc00000b3), W_ERROR(0x218)}, + {NT_STATUS(0xc00000b4), W_ERROR(0xe6)}, + {NT_STATUS(0xc00000b5), W_ERROR(0x79)}, + {NT_STATUS(0xc00000b6), W_ERROR(0x26)}, + {NT_STATUS(0xc00000ba), W_ERROR(0x5)}, + {NT_STATUS(0xc00000bb), W_ERROR(0x32)}, + {NT_STATUS(0xc00000bc), W_ERROR(0x33)}, + {NT_STATUS(0xc00000bd), W_ERROR(0x34)}, + {NT_STATUS(0xc00000be), W_ERROR(0x35)}, + {NT_STATUS(0xc00000bf), W_ERROR(0x36)}, + {NT_STATUS(0xc00000c0), W_ERROR(0x37)}, + {NT_STATUS(0xc00000c1), W_ERROR(0x38)}, + {NT_STATUS(0xc00000c2), W_ERROR(0x39)}, + {NT_STATUS(0xc00000c3), W_ERROR(0x3a)}, + {NT_STATUS(0xc00000c4), W_ERROR(0x3b)}, + {NT_STATUS(0xc00000c5), W_ERROR(0x3c)}, + {NT_STATUS(0xc00000c6), W_ERROR(0x3d)}, + {NT_STATUS(0xc00000c7), W_ERROR(0x3e)}, + {NT_STATUS(0xc00000c8), W_ERROR(0x3f)}, + {NT_STATUS(0xc00000c9), W_ERROR(0x40)}, + {NT_STATUS(0xc00000ca), W_ERROR(0x41)}, + {NT_STATUS(0xc00000cb), W_ERROR(0x42)}, + {NT_STATUS(0xc00000cc), W_ERROR(0x43)}, + {NT_STATUS(0xc00000cd), W_ERROR(0x44)}, + {NT_STATUS(0xc00000ce), W_ERROR(0x45)}, + {NT_STATUS(0xc00000cf), W_ERROR(0x46)}, + {NT_STATUS(0xc00000d0), W_ERROR(0x47)}, + {NT_STATUS(0xc00000d1), W_ERROR(0x48)}, + {NT_STATUS(0xc00000d2), W_ERROR(0x58)}, + {NT_STATUS(0xc00000d4), W_ERROR(0x11)}, + {NT_STATUS(0xc00000d5), W_ERROR(0x5)}, + {NT_STATUS(0xc00000d6), W_ERROR(0xf0)}, + {NT_STATUS(0xc00000d7), W_ERROR(0x546)}, + {NT_STATUS(0xc00000d9), W_ERROR(0xe8)}, + {NT_STATUS(0xc00000da), W_ERROR(0x547)}, + {NT_STATUS(0xc00000dc), W_ERROR(0x548)}, + {NT_STATUS(0xc00000dd), W_ERROR(0x549)}, + {NT_STATUS(0xc00000de), W_ERROR(0x54a)}, + {NT_STATUS(0xc00000df), W_ERROR(0x54b)}, + {NT_STATUS(0xc00000e0), W_ERROR(0x54c)}, + {NT_STATUS(0xc00000e1), W_ERROR(0x54d)}, + {NT_STATUS(0xc00000e2), W_ERROR(0x12c)}, + {NT_STATUS(0xc00000e3), W_ERROR(0x12d)}, + {NT_STATUS(0xc00000e4), W_ERROR(0x54e)}, + {NT_STATUS(0xc00000e5), W_ERROR(0x54f)}, + {NT_STATUS(0xc00000e6), W_ERROR(0x550)}, + {NT_STATUS(0xc00000e7), W_ERROR(0x551)}, + {NT_STATUS(0xc00000e8), W_ERROR(0x6f8)}, + {NT_STATUS(0xc00000ed), W_ERROR(0x552)}, + {NT_STATUS(0xc00000ee), W_ERROR(0x553)}, + {NT_STATUS(0xc00000ef), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f0), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f1), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f2), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f3), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f4), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f5), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f6), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f7), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f8), W_ERROR(0x57)}, + {NT_STATUS(0xc00000f9), W_ERROR(0x57)}, + {NT_STATUS(0xc00000fa), W_ERROR(0x57)}, + {NT_STATUS(0xc00000fb), W_ERROR(0x3)}, + {NT_STATUS(0xc00000fd), W_ERROR(0x3e9)}, + {NT_STATUS(0xc00000fe), W_ERROR(0x554)}, + {NT_STATUS(0xc0000100), W_ERROR(0xcb)}, + {NT_STATUS(0xc0000101), W_ERROR(0x91)}, + {NT_STATUS(0xc0000102), W_ERROR(0x570)}, + {NT_STATUS(0xc0000103), W_ERROR(0x10b)}, + {NT_STATUS(0xc0000104), W_ERROR(0x555)}, + {NT_STATUS(0xc0000105), W_ERROR(0x556)}, + {NT_STATUS(0xc0000106), W_ERROR(0xce)}, + {NT_STATUS(0xc0000107), W_ERROR(0x961)}, + {NT_STATUS(0xc0000108), W_ERROR(0x964)}, + {NT_STATUS(0xc000010a), W_ERROR(0x5)}, + {NT_STATUS(0xc000010b), W_ERROR(0x557)}, + {NT_STATUS(0xc000010d), W_ERROR(0x558)}, + {NT_STATUS(0xc000010e), W_ERROR(0x420)}, + {NT_STATUS(0xc0000117), W_ERROR(0x5a4)}, + {NT_STATUS(0xc000011b), W_ERROR(0xc1)}, + {NT_STATUS(0xc000011c), W_ERROR(0x559)}, + {NT_STATUS(0xc000011d), W_ERROR(0x55a)}, + {NT_STATUS(0xc000011e), W_ERROR(0x3ee)}, + {NT_STATUS(0xc000011f), W_ERROR(0x4)}, + {NT_STATUS(0xc0000120), W_ERROR(0x3e3)}, + {NT_STATUS(0xc0000121), W_ERROR(0x5)}, + {NT_STATUS(0xc0000122), W_ERROR(0x4ba)}, + {NT_STATUS(0xc0000123), W_ERROR(0x5)}, + {NT_STATUS(0xc0000124), W_ERROR(0x55b)}, + {NT_STATUS(0xc0000125), W_ERROR(0x55c)}, + {NT_STATUS(0xc0000126), W_ERROR(0x55d)}, + {NT_STATUS(0xc0000127), W_ERROR(0x55e)}, + {NT_STATUS(0xc0000128), W_ERROR(0x6)}, + {NT_STATUS(0xc000012b), W_ERROR(0x55f)}, + {NT_STATUS(0xc000012d), W_ERROR(0x5af)}, + {NT_STATUS(0xc000012e), W_ERROR(0xc1)}, + {NT_STATUS(0xc000012f), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000130), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000131), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000133), W_ERROR(0x576)}, + {NT_STATUS(0xc0000135), W_ERROR(0x7e)}, + {NT_STATUS(0xc0000138), W_ERROR(0xb6)}, + {NT_STATUS(0xc0000139), W_ERROR(0x7f)}, + {NT_STATUS(0xc000013b), W_ERROR(0x40)}, + {NT_STATUS(0xc000013c), W_ERROR(0x40)}, + {NT_STATUS(0xc000013d), W_ERROR(0x33)}, + {NT_STATUS(0xc000013e), W_ERROR(0x3b)}, + {NT_STATUS(0xc000013f), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000140), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000141), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000142), W_ERROR(0x45a)}, + {NT_STATUS(0xc0000148), W_ERROR(0x7c)}, + {NT_STATUS(0xc0000149), W_ERROR(0x56)}, + {NT_STATUS(0xc000014b), W_ERROR(0x6d)}, + {NT_STATUS(0xc000014c), W_ERROR(0x3f1)}, + {NT_STATUS(0xc000014d), W_ERROR(0x3f8)}, + {NT_STATUS(0xc000014f), W_ERROR(0x3ed)}, + {NT_STATUS(0xc0000150), W_ERROR(0x45e)}, + {NT_STATUS(0xc0000151), W_ERROR(0x560)}, + {NT_STATUS(0xc0000152), W_ERROR(0x561)}, + {NT_STATUS(0xc0000153), W_ERROR(0x562)}, + {NT_STATUS(0xc0000154), W_ERROR(0x563)}, + {NT_STATUS(0xc0000155), W_ERROR(0x564)}, + {NT_STATUS(0xc0000156), W_ERROR(0x565)}, + {NT_STATUS(0xc0000157), W_ERROR(0x566)}, + {NT_STATUS(0xc0000158), W_ERROR(0x567)}, + {NT_STATUS(0xc0000159), W_ERROR(0x3ef)}, + {NT_STATUS(0xc000015a), W_ERROR(0x568)}, + {NT_STATUS(0xc000015b), W_ERROR(0x569)}, + {NT_STATUS(0xc000015c), W_ERROR(0x3f9)}, + {NT_STATUS(0xc000015d), W_ERROR(0x56a)}, + {NT_STATUS(0xc000015f), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000162), W_ERROR(0x459)}, + {NT_STATUS(0xc0000165), W_ERROR(0x462)}, + {NT_STATUS(0xc0000166), W_ERROR(0x463)}, + {NT_STATUS(0xc0000167), W_ERROR(0x464)}, + {NT_STATUS(0xc0000168), W_ERROR(0x465)}, + {NT_STATUS(0xc0000169), W_ERROR(0x466)}, + {NT_STATUS(0xc000016a), W_ERROR(0x467)}, + {NT_STATUS(0xc000016b), W_ERROR(0x468)}, + {NT_STATUS(0xc000016c), W_ERROR(0x45f)}, + {NT_STATUS(0xc000016d), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000172), W_ERROR(0x451)}, + {NT_STATUS(0xc0000173), W_ERROR(0x452)}, + {NT_STATUS(0xc0000174), W_ERROR(0x453)}, + {NT_STATUS(0xc0000175), W_ERROR(0x454)}, + {NT_STATUS(0xc0000176), W_ERROR(0x455)}, + {NT_STATUS(0xc0000177), W_ERROR(0x469)}, + {NT_STATUS(0xc0000178), W_ERROR(0x458)}, + {NT_STATUS(0xc000017a), W_ERROR(0x56b)}, + {NT_STATUS(0xc000017b), W_ERROR(0x56c)}, + {NT_STATUS(0xc000017c), W_ERROR(0x3fa)}, + {NT_STATUS(0xc000017d), W_ERROR(0x3fb)}, + {NT_STATUS(0xc000017e), W_ERROR(0x56d)}, + {NT_STATUS(0xc000017f), W_ERROR(0x56e)}, + {NT_STATUS(0xc0000180), W_ERROR(0x3fc)}, + {NT_STATUS(0xc0000181), W_ERROR(0x3fd)}, + {NT_STATUS(0xc0000182), W_ERROR(0x57)}, + {NT_STATUS(0xc0000183), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000184), W_ERROR(0x16)}, + {NT_STATUS(0xc0000185), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000186), W_ERROR(0x45d)}, + {NT_STATUS(0xc0000188), W_ERROR(0x5de)}, + {NT_STATUS(0xc0000189), W_ERROR(0x13)}, + {NT_STATUS(0xc000018a), W_ERROR(0x6fa)}, + {NT_STATUS(0xc000018b), W_ERROR(0x6fb)}, + {NT_STATUS(0xc000018c), W_ERROR(0x6fc)}, + {NT_STATUS(0xc000018d), W_ERROR(0x6fd)}, + {NT_STATUS(0xc000018e), W_ERROR(0x5dc)}, + {NT_STATUS(0xc000018f), W_ERROR(0x5dd)}, + {NT_STATUS(0xc0000190), W_ERROR(0x6fe)}, + {NT_STATUS(0xc0000192), W_ERROR(0x700)}, + {NT_STATUS(0xc0000193), W_ERROR(0x701)}, + {NT_STATUS(0xc0000194), W_ERROR(0x46b)}, + {NT_STATUS(0xc0000195), W_ERROR(0x4c3)}, + {NT_STATUS(0xc0000196), W_ERROR(0x4c4)}, + {NT_STATUS(0xc0000197), W_ERROR(0x5df)}, + {NT_STATUS(0xc0000198), W_ERROR(0x70f)}, + {NT_STATUS(0xc0000199), W_ERROR(0x710)}, + {NT_STATUS(0xc000019a), W_ERROR(0x711)}, + {NT_STATUS(0xc000019b), W_ERROR(0x712)}, + {NT_STATUS(0xc0000202), W_ERROR(0x572)}, + {NT_STATUS(0xc0000203), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000204), W_ERROR(0x717)}, + {NT_STATUS(0xc0000205), W_ERROR(0x46a)}, + {NT_STATUS(0xc0000206), W_ERROR(0x6f8)}, + {NT_STATUS(0xc0000207), W_ERROR(0x4be)}, + {NT_STATUS(0xc0000208), W_ERROR(0x4be)}, + {NT_STATUS(0xc0000209), W_ERROR(0x44)}, + {NT_STATUS(0xc000020a), W_ERROR(0x34)}, + {NT_STATUS(0xc000020b), W_ERROR(0x40)}, + {NT_STATUS(0xc000020c), W_ERROR(0x40)}, + {NT_STATUS(0xc000020d), W_ERROR(0x40)}, + {NT_STATUS(0xc000020e), W_ERROR(0x44)}, + {NT_STATUS(0xc000020f), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000210), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000211), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000212), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000213), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000214), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000215), W_ERROR(0x3b)}, + {NT_STATUS(0xc0000216), W_ERROR(0x32)}, + {NT_STATUS(0xc0000217), W_ERROR(0x32)}, + {NT_STATUS(0xc000021c), W_ERROR(0x17e6)}, + {NT_STATUS(0xc0000220), W_ERROR(0x46c)}, + {NT_STATUS(0xc0000221), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000224), W_ERROR(0x773)}, + {NT_STATUS(0xc0000225), W_ERROR(0x490)}, + {NT_STATUS(0xc000022a), W_ERROR(0xc000022a)}, + {NT_STATUS(0xc000022b), W_ERROR(0xc000022b)}, + {NT_STATUS(0xc000022d), W_ERROR(0x4d5)}, + {NT_STATUS(0xc0000230), W_ERROR(0x492)}, + {NT_STATUS(0xc0000233), W_ERROR(0x774)}, + {NT_STATUS(0xc0000234), W_ERROR(0x775)}, + {NT_STATUS(0xc0000235), W_ERROR(0x6)}, + {NT_STATUS(0xc0000236), W_ERROR(0x4c9)}, + {NT_STATUS(0xc0000237), W_ERROR(0x4ca)}, + {NT_STATUS(0xc0000238), W_ERROR(0x4cb)}, + {NT_STATUS(0xc0000239), W_ERROR(0x4cc)}, + {NT_STATUS(0xc000023a), W_ERROR(0x4cd)}, + {NT_STATUS(0xc000023b), W_ERROR(0x4ce)}, + {NT_STATUS(0xc000023c), W_ERROR(0x4cf)}, + {NT_STATUS(0xc000023d), W_ERROR(0x4d0)}, + {NT_STATUS(0xc000023e), W_ERROR(0x4d1)}, + {NT_STATUS(0xc000023f), W_ERROR(0x4d2)}, + {NT_STATUS(0xc0000240), W_ERROR(0x4d3)}, + {NT_STATUS(0xc0000241), W_ERROR(0x4d4)}, + {NT_STATUS(0xc0000243), W_ERROR(0x4c8)}, + {NT_STATUS(0xc0000246), W_ERROR(0x4d6)}, + {NT_STATUS(0xc0000247), W_ERROR(0x4d7)}, + {NT_STATUS(0xc0000248), W_ERROR(0x4d8)}, + {NT_STATUS(0xc0000249), W_ERROR(0xc1)}, + {NT_STATUS(0xc0000253), W_ERROR(0x54f)}, + {NT_STATUS(0xc0000257), W_ERROR(0x4d0)}, + {NT_STATUS(0xc0000259), W_ERROR(0x573)}, + {NT_STATUS(0xc000025e), W_ERROR(0x422)}, + {NT_STATUS(0xc0000262), W_ERROR(0xb6)}, + {NT_STATUS(0xc0000263), W_ERROR(0x7f)}, + {NT_STATUS(0xc0000264), W_ERROR(0x120)}, + {NT_STATUS(0xc0000265), W_ERROR(0x476)}, + {NT_STATUS(0xc0000267), W_ERROR(0x10fe)}, + {NT_STATUS(0xc000026c), W_ERROR(0x7d1)}, + {NT_STATUS(0xc000026d), W_ERROR(0x4b1)}, + {NT_STATUS(0xc000026e), W_ERROR(0x15)}, + {NT_STATUS(0xc0000272), W_ERROR(0x491)}, + {NT_STATUS(0xc0000275), W_ERROR(0x1126)}, + {NT_STATUS(0xc0000276), W_ERROR(0x1129)}, + {NT_STATUS(0xc0000277), W_ERROR(0x112a)}, + {NT_STATUS(0xc0000278), W_ERROR(0x1128)}, + {NT_STATUS(0xc0000279), W_ERROR(0x780)}, + {NT_STATUS(0xc0000280), W_ERROR(0x781)}, + {NT_STATUS(0xc0000281), W_ERROR(0xa1)}, + {NT_STATUS(0xc0000283), W_ERROR(0x488)}, + {NT_STATUS(0xc0000284), W_ERROR(0x489)}, + {NT_STATUS(0xc0000285), W_ERROR(0x48a)}, + {NT_STATUS(0xc0000286), W_ERROR(0x48b)}, + {NT_STATUS(0xc0000287), W_ERROR(0x48c)}, + {NT_STATUS(0xc000028a), W_ERROR(0x5)}, + {NT_STATUS(0xc000028b), W_ERROR(0x5)}, + {NT_STATUS(0xc000028d), W_ERROR(0x5)}, + {NT_STATUS(0xc000028e), W_ERROR(0x5)}, + {NT_STATUS(0xc000028f), W_ERROR(0x5)}, + {NT_STATUS(0xc0000290), W_ERROR(0x5)}, + {NT_STATUS(0xc0000291), W_ERROR(0x1777)}, + {NT_STATUS(0xc0000292), W_ERROR(0x1778)}, + {NT_STATUS(0xc0000293), W_ERROR(0x1772)}, + {NT_STATUS(0xc0000295), W_ERROR(0x1068)}, + {NT_STATUS(0xc0000296), W_ERROR(0x1069)}, + {NT_STATUS(0xc0000297), W_ERROR(0x106a)}, + {NT_STATUS(0xc0000298), W_ERROR(0x106b)}, + {NT_STATUS(0xc0000299), W_ERROR(0x201a)}, + {NT_STATUS(0xc000029a), W_ERROR(0x201b)}, + {NT_STATUS(0xc000029b), W_ERROR(0x201c)}, + {NT_STATUS(0xc000029c), W_ERROR(0x1)}, + {NT_STATUS(0xc000029d), W_ERROR(0x10ff)}, + {NT_STATUS(0xc000029e), W_ERROR(0x1100)}, + {NT_STATUS(0xc000029f), W_ERROR(0x494)}, + {NT_STATUS(0xc00002a1), W_ERROR(0x200a)}, + {NT_STATUS(0xc00002a2), W_ERROR(0x200b)}, + {NT_STATUS(0xc00002a3), W_ERROR(0x200c)}, + {NT_STATUS(0xc00002a4), W_ERROR(0x200d)}, + {NT_STATUS(0xc00002a5), W_ERROR(0x200e)}, + {NT_STATUS(0xc00002a6), W_ERROR(0x200f)}, + {NT_STATUS(0xc00002a7), W_ERROR(0x2010)}, + {NT_STATUS(0xc00002a8), W_ERROR(0x2011)}, + {NT_STATUS(0xc00002a9), W_ERROR(0x2012)}, + {NT_STATUS(0xc00002aa), W_ERROR(0x2013)}, + {NT_STATUS(0xc00002ab), W_ERROR(0x2014)}, + {NT_STATUS(0xc00002ac), W_ERROR(0x2015)}, + {NT_STATUS(0xc00002ad), W_ERROR(0x2016)}, + {NT_STATUS(0xc00002ae), W_ERROR(0x2017)}, + {NT_STATUS(0xc00002af), W_ERROR(0x2018)}, + {NT_STATUS(0xc00002b0), W_ERROR(0x2019)}, + {NT_STATUS(0xc00002b1), W_ERROR(0x211e)}, + {NT_STATUS(0xc00002b2), W_ERROR(0x1127)}, + {NT_STATUS(0xc00002b6), W_ERROR(0x651)}, + {NT_STATUS(0xc00002b7), W_ERROR(0x49a)}, + {NT_STATUS(0xc00002b8), W_ERROR(0x49b)}, + {NT_STATUS(0xc00002c1), W_ERROR(0x2024)}, + {NT_STATUS(0xc00002c3), W_ERROR(0x575)}, + {NT_STATUS(0xc00002c5), W_ERROR(0x3e6)}, + {NT_STATUS(0xc00002c6), W_ERROR(0x1075)}, + {NT_STATUS(0xc00002c7), W_ERROR(0x1076)}, + {NT_STATUS(0xc00002ca), W_ERROR(0x10e8)}, + {NT_STATUS(0xc00002cb), W_ERROR(0x2138)}, + {NT_STATUS(0xc00002cc), W_ERROR(0x4e3)}, + {NT_STATUS(0xc00002cd), W_ERROR(0x2139)}, + {NT_STATUS(0xc00002cf), W_ERROR(0x49d)}, + {NT_STATUS(0xc00002d0), W_ERROR(0x213a)}, + {NT_STATUS(0xc00002d4), W_ERROR(0x2141)}, + {NT_STATUS(0xc00002d5), W_ERROR(0x2142)}, + {NT_STATUS(0xc00002d6), W_ERROR(0x2143)}, + {NT_STATUS(0xc00002d7), W_ERROR(0x2144)}, + {NT_STATUS(0xc00002d8), W_ERROR(0x2145)}, + {NT_STATUS(0xc00002d9), W_ERROR(0x2146)}, + {NT_STATUS(0xc00002da), W_ERROR(0x2147)}, + {NT_STATUS(0xc00002db), W_ERROR(0x2148)}, + {NT_STATUS(0xc00002dc), W_ERROR(0x2149)}, + {NT_STATUS(0xc00002dd), W_ERROR(0x32)}, + {NT_STATUS(0xc00002df), W_ERROR(0x2151)}, + {NT_STATUS(0xc00002e0), W_ERROR(0x2152)}, + {NT_STATUS(0xc00002e1), W_ERROR(0x2153)}, + {NT_STATUS(0xc00002e2), W_ERROR(0x2154)}, + {NT_STATUS(0xc00002e3), W_ERROR(0x215d)}, + {NT_STATUS(0xc00002e4), W_ERROR(0x2163)}, + {NT_STATUS(0xc00002e5), W_ERROR(0x2164)}, + {NT_STATUS(0xc00002e6), W_ERROR(0x2165)}, + {NT_STATUS(0xc00002e7), W_ERROR(0x216d)}, + {NT_STATUS(0xc00002fe), W_ERROR(0x45b)}, + {NT_STATUS(0xc00002ff), W_ERROR(0x4e7)}, + {NT_STATUS(0xc0000300), W_ERROR(0x4e6)}, + {NT_STATUS(0x80000001), W_ERROR(0x80000001)}, + {NT_STATUS(0x80000002), W_ERROR(0x3e6)}, + {NT_STATUS(0x80000003), W_ERROR(0x80000003)}, + {NT_STATUS(0x80000004), W_ERROR(0x80000004)}, + {NT_STATUS(0x80000005), W_ERROR(0xea)}, + {NT_STATUS(0x80000006), W_ERROR(0x12)}, + {NT_STATUS(0x8000000b), W_ERROR(0x56f)}, + {NT_STATUS(0x8000000d), W_ERROR(0x12b)}, + {NT_STATUS(0x8000000e), W_ERROR(0x1c)}, + {NT_STATUS(0x8000000f), W_ERROR(0x15)}, + {NT_STATUS(0x80000010), W_ERROR(0x15)}, + {NT_STATUS(0x80000011), W_ERROR(0xaa)}, + {NT_STATUS(0x80000012), W_ERROR(0x103)}, + {NT_STATUS(0x80000013), W_ERROR(0xfe)}, + {NT_STATUS(0x80000014), W_ERROR(0xff)}, + {NT_STATUS(0x80000015), W_ERROR(0xff)}, + {NT_STATUS(0x80000016), W_ERROR(0x456)}, + {NT_STATUS(0x8000001a), W_ERROR(0x103)}, + {NT_STATUS(0x8000001b), W_ERROR(0x44d)}, + {NT_STATUS(0x8000001c), W_ERROR(0x456)}, + {NT_STATUS(0x8000001d), W_ERROR(0x457)}, + {NT_STATUS(0x8000001e), W_ERROR(0x44c)}, + {NT_STATUS(0x8000001f), W_ERROR(0x44e)}, + {NT_STATUS(0x80000021), W_ERROR(0x44f)}, + {NT_STATUS(0x80000022), W_ERROR(0x450)}, + {NT_STATUS(0x80000025), W_ERROR(0x962)}, + {NT_STATUS(0x80000288), W_ERROR(0x48d)}, + {NT_STATUS(0x80000289), W_ERROR(0x48e)}, + {NT_STATUS_OK, WERR_OK}}; + /***************************************************************************** convert a dos eclas/ecode to a NT status32 code @@ -825,6 +1366,7 @@ convert a dos eclas/ecode to a NT status32 code NTSTATUS dos_to_ntstatus(int eclass, int ecode) { int i; + if (eclass == 0 && ecode == 0) return NT_STATUS_OK; for (i=0; NT_STATUS_V(dos_to_ntstatus_map[i].ntstatus); i++) { if (eclass == dos_to_ntstatus_map[i].dos_class && ecode == dos_to_ntstatus_map[i].dos_code) { @@ -841,6 +1383,11 @@ convert a NT status code to a dos class/code void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode) { int i; + if (NT_STATUS_IS_OK(ntstatus)) { + *eclass = 0; + *ecode = 0; + return; + } for (i=0; NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus); i++) { if (NT_STATUS_V(ntstatus) == NT_STATUS_V(ntstatus_to_dos_map[i].ntstatus)) { @@ -852,3 +1399,40 @@ void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode) *eclass = ERRSRV; *ecode = ERRerror; } + + +/***************************************************************************** +convert a WERROR to a NT status32 code + *****************************************************************************/ +NTSTATUS werror_to_ntstatus(WERROR error) +{ + int i; + if (W_ERROR_IS_OK(error)) return NT_STATUS_OK; + for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { + if (W_ERROR_V(error) == + W_ERROR_V(ntstatus_to_werror_map[i].werror)) { + return ntstatus_to_werror_map[i].ntstatus; + } + } + + /* just guess ... */ + return NT_STATUS(W_ERROR_V(error) | 0xc0000000); +} + +/***************************************************************************** +convert a NTSTATUS to a WERROR + *****************************************************************************/ +WERROR ntstatus_to_werror(NTSTATUS error) +{ + int i; + if (NT_STATUS_IS_OK(error)) return WERR_OK; + for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { + if (NT_STATUS_V(error) == + NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus)) { + return ntstatus_to_werror_map[i].werror; + } + } + + /* a lame guess */ + return W_ERROR(NT_STATUS_V(error) & 0xffff); +} diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index e6ecfefb34..00966aed43 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -193,3 +193,14 @@ char *werror_str(WERROR status) slprintf(msg, sizeof(msg), "WIN32 code 0x%08x", W_ERROR_V(status)); return msg; } + + +/***************************************************************************** +map a unix errno to a win32 error + *****************************************************************************/ +WERROR map_werror_from_unix(int error) +{ + NTSTATUS status = map_nt_error_from_unix(error); + return ntstatus_to_werror(status); +} + -- cgit From 19fea3242cf6234786b6cbb60631e0071f31ff9f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Sep 2001 07:13:01 +0000 Subject: the next stage in the NTSTATUS/WERROR change. smbd and nmbd now compile, but the client code still needs some work (This used to be commit dcd6e735f709a9231860ceb9682db40ff26c9a66) --- source3/libsmb/cli_lsarpc.c | 21 ++++++------ source3/libsmb/cli_reg.c | 2 +- source3/libsmb/cli_samr.c | 50 +++++++++++++++------------- source3/libsmb/cli_spoolss.c | 59 +++++++++++++++++++-------------- source3/libsmb/domain_client_validate.c | 8 ++--- 5 files changed, 77 insertions(+), 63 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 791b6eace3..f2fc167606 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -78,7 +78,7 @@ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *pol = r.pol; } @@ -136,7 +136,7 @@ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *pol = r.pol; } @@ -184,7 +184,7 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *pol = r.pol; } @@ -242,8 +242,9 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_OK && result != 0x00000107 && - result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { + if (!NT_STATUS_IS_OK(result) && + NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_FILES_OPEN) && + NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NONE_MAPPED)) { /* An actual error occured */ @@ -347,8 +348,8 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_OK && - result != (0xC0000000 | NT_STATUS_NONE_MAPPED)) { + if (!NT_STATUS_IS_OK(result) && + NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NONE_MAPPED)) { /* An actual error occured */ @@ -441,7 +442,7 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - if ((result = r.status) != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result = r.status)) { goto done; } @@ -536,8 +537,8 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, 0x8000001a (NT_STATUS_UNABLE_TO_FREE_VM) so we ignore it and pretend everything is OK. */ - if (result != NT_STATUS_OK && - result != NT_STATUS_UNABLE_TO_FREE_VM) { + if (!NT_STATUS_IS_OK(result) && + NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_UNABLE_TO_FREE_VM)) { /* An actual error ocured */ diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c index 88e6d3b36d..73eea58cb7 100644 --- a/source3/libsmb/cli_reg.c +++ b/source3/libsmb/cli_reg.c @@ -47,7 +47,7 @@ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, REG_R_SHUTDOWN r_s; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - if (msg == NULL) return False; + if (msg == NULL) return NT_STATUS_INVALID_PARAMETER; ZERO_STRUCT (q_s); ZERO_STRUCT (r_s); diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 9e40135801..4a04d67887 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -68,7 +68,7 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *connect_pol = r.connect_pol; } @@ -114,7 +114,7 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *connect_pol = r.pol; } @@ -161,7 +161,7 @@ NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *domain_pol = r.domain_pol; } @@ -208,7 +208,7 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *user_pol = r.user_pol; } @@ -255,7 +255,7 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *group_pol = r.pol; } @@ -395,7 +395,7 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *num_groups = r.num_entries; *gid = r.gid; } @@ -443,7 +443,7 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *num_mem = r.num_entries; *rid = r.rid; *attr = r.attr; @@ -466,7 +466,8 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; SAMR_Q_ENUM_DOM_GROUPS q; SAMR_R_ENUM_DOM_GROUPS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL, name_idx, i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 name_idx, i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -495,8 +496,8 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_OK && - result != STATUS_MORE_ENTRIES) { + if (!NT_STATUS_IS_OK(result) && + NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { goto done; } @@ -542,7 +543,8 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; SAMR_Q_QUERY_ALIASMEM q; SAMR_R_QUERY_ALIASMEM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL, i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -569,7 +571,7 @@ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result = r.status)) { goto done; } @@ -629,7 +631,7 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result = r.status)) { *alias_pol = r.pol; } @@ -678,7 +680,7 @@ NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result = r.status)) { goto done; } @@ -731,8 +733,8 @@ NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (result != NT_STATUS_OK && - result != STATUS_MORE_ENTRIES) { + if (!NT_STATUS_IS_OK(result) && + NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { goto done; } @@ -758,7 +760,8 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; SAMR_Q_LOOKUP_RIDS q; SAMR_R_LOOKUP_RIDS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL, i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 i; if (num_rids > 1000) { DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if " @@ -791,7 +794,7 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result = r.status)) { goto done; } @@ -831,7 +834,8 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; SAMR_Q_LOOKUP_NAMES q; SAMR_R_LOOKUP_NAMES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL, i; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -859,7 +863,7 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result = r.status)) { goto done; } @@ -921,7 +925,7 @@ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result = r.status)) { goto done; } @@ -977,7 +981,7 @@ NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result = r.status)) { goto done; } @@ -1024,7 +1028,7 @@ NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if ((result = r.status) != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result = r.status)) { goto done; } diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 54769ce18d..2663e311e0 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -84,8 +84,11 @@ NTSTATUS cli_spoolss_open_printer_ex( /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (W_ERROR_IS_OK(r.status)) { + result = NT_STATUS_OK; *pol = r.handle; + } else { + result = werror_to_ntstatus(r.status); } done: @@ -137,8 +140,11 @@ NTSTATUS cli_spoolss_close_printer( /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { + if (W_ERROR_IS_OK(r.status)) { *pol = r.handle; + result = NT_STATUS_OK; + } else { + result = werror_to_ntstatus(r.status); } done: @@ -428,10 +434,12 @@ NTSTATUS cli_spoolss_enum_printers( } /* Return output parameters */ + if (!W_ERROR_IS_OK(r.status)) { + result = werror_to_ntstatus(r.status); + goto done; + } - if (((result=r.status) == NT_STATUS_OK) && (*returned = r.returned)) - { - + if ((*returned = r.returned)) { switch (level) { case 1: decode_printer_info_1(mem_ctx, r.buffer, r.returned, @@ -452,7 +460,7 @@ NTSTATUS cli_spoolss_enum_printers( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (result == ERROR_INSUFFICIENT_BUFFER); + } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); return result; } @@ -504,8 +512,9 @@ NTSTATUS cli_spoolss_enum_ports( } /* Return output parameters */ + result = werror_to_ntstatus(r.status); - if ((result = r.status) == NT_STATUS_OK && + if (NT_STATUS_IS_OK(result) && r.returned > 0) { *returned = r.returned; @@ -526,7 +535,7 @@ NTSTATUS cli_spoolss_enum_ports( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (result == ERROR_INSUFFICIENT_BUFFER); + } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); return result; } @@ -574,8 +583,8 @@ NTSTATUS cli_spoolss_getprinter( } /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) { - + result = werror_to_ntstatus(r.status); + if (NT_STATUS_IS_OK(result)) { switch (level) { case 0: decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); @@ -596,7 +605,7 @@ NTSTATUS cli_spoolss_getprinter( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (result == ERROR_INSUFFICIENT_BUFFER); + } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); return result; } @@ -616,7 +625,7 @@ NTSTATUS cli_spoolss_setprinter( prs_struct qbuf, rbuf; SPOOL_Q_SETPRINTER q; SPOOL_R_SETPRINTER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + NTSTATUS result = NT_STATUS_ACCESS_DENIED; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -631,7 +640,7 @@ NTSTATUS cli_spoolss_setprinter( if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_ACCESS_DENIED; goto done; } @@ -641,7 +650,7 @@ NTSTATUS cli_spoolss_setprinter( goto done; } - result = r.status; + result = werror_to_ntstatus(r.status); done: prs_mem_free(&qbuf); @@ -705,9 +714,9 @@ NTSTATUS cli_spoolss_getprinterdriver ( } /* Return output parameters */ - if ((result = r.status) == NT_STATUS_OK) + result = werror_to_ntstatus(r.status); + if (NT_STATUS_IS_OK(result)) { - switch (level) { case 1: @@ -726,7 +735,7 @@ NTSTATUS cli_spoolss_getprinterdriver ( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (result == ERROR_INSUFFICIENT_BUFFER); + } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); return result; } @@ -784,7 +793,8 @@ NTSTATUS cli_spoolss_enumprinterdrivers ( } /* Return output parameters */ - if (((result=r.status) == NT_STATUS_OK) && + result = werror_to_ntstatus(r.status); + if (NT_STATUS_IS_OK(result) && (r.returned != 0)) { *returned = r.returned; @@ -807,7 +817,7 @@ NTSTATUS cli_spoolss_enumprinterdrivers ( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (result == ERROR_INSUFFICIENT_BUFFER); + } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); return result; } @@ -865,7 +875,8 @@ NTSTATUS cli_spoolss_getprinterdriverdir ( } /* Return output parameters */ - if ((result=r.status) == NT_STATUS_OK) + result = werror_to_ntstatus(r.status); + if (NT_STATUS_IS_OK(result)) { switch (level) { @@ -879,7 +890,7 @@ NTSTATUS cli_spoolss_getprinterdriverdir ( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (result == ERROR_INSUFFICIENT_BUFFER); + } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); return result; } @@ -931,7 +942,7 @@ NTSTATUS cli_spoolss_addprinterdriver ( } /* Return output parameters */ - result = r.status; + result = werror_to_ntstatus(r.status); done: prs_mem_free(&qbuf); @@ -993,7 +1004,7 @@ NTSTATUS cli_spoolss_addprinterex ( } /* Return output parameters */ - result = r.status; + result = werror_to_ntstatus(r.status); done: prs_mem_free(&qbuf); @@ -1050,7 +1061,7 @@ NTSTATUS cli_spoolss_deleteprinterdriver ( } /* Return output parameters */ - result = r.status; + result = werror_to_ntstatus(r.status); done: prs_mem_free(&qbuf); diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 69b5739b63..a6890f1027 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -323,16 +323,14 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, ZERO_STRUCT(info3); - if ((status = cli_nt_login_network(&cli, user_info, smb_uid_low, - &ctr, &info3)) - != NT_STATUS_OK) { + status = cli_nt_login_network(&cli, user_info, smb_uid_low, + &ctr, &info3); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("domain_client_validate: unable to validate password " "for user %s in domain %s to Domain controller %s. " "Error was %s.\n", user_info->smb_username.str, user_info->domain.str, remote_machine, get_nt_error_msg(status))); - } else { - status = NT_STATUS_OK; } /* -- cgit From c76dd1404041f42d3a398339cefbeb60f22d2910 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Sep 2001 10:57:29 +0000 Subject: it now all compiles - so try enabling it by default and see what explodes on the build farm (This used to be commit 5bb7e4f0f65edf1db20245f403cbe81833134240) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c3456bc4e7..f7008a2680 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -212,8 +212,8 @@ int smbc_errno(struct cli_state *c) status = cli_nt_error(c); ret = cli_errno_from_nt(status); - DEBUG(3,("smbc errno 0x%08x -> %d\n", - status, ret)); + DEBUG(3,("smbc errno %s -> %d\n", + get_nt_error_msg(status), ret)); } return ret; -- cgit From f6b531895ec3cd4883fda6d31f8b6a260a3782e3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 5 Sep 2001 04:46:21 +0000 Subject: Merged cli_net_req_chal() and cli_net_auth2() from rpc_client/cli_login.c except they are called new_cli_net_req_chal() and new_cli_net_auth2() until they are working properly. (This used to be commit 4ca085f253fc39de60115edc049e91d5c95735ef) --- source3/libsmb/cli_netlogon.c | 177 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 177 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index b608398aa3..dc43ab935d 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -32,6 +32,183 @@ struct cli_state *cli_netlogon_initialise(struct cli_state *cli, return cli_pipe_initialise(cli, system_name, PIPE_NETLOGON, creds); } +/* LSA Request Challenge. Sends our challenge to server, then gets + server response. These are used to generate the credentials. */ + +NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, + DOM_CHAL *srv_chal) +{ + prs_struct qbuf, rbuf; + NET_Q_REQ_CHAL q; + NET_R_REQ_CHAL r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + extern pstring global_myname; + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + /* create and send a MSRPC command with api NET_REQCHAL */ + + DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", + cli->desthost, global_myname, credstr(clnt_chal->data))); + + /* store the parameters */ + init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal); + + /* Marshall data and send request */ + + if (!net_io_q_req_chal("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_REQCHAL, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarhall response */ + + if (!net_io_r_req_chal("", &r, &rbuf, 0)) { + goto done; + } + + result = r.status; + + /* Return result */ + + if (result == NT_STATUS_OK) { + memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data)); + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/**************************************************************************** +LSA Authenticate 2 + +Send the client credential, receive back a server credential. +Ensure that the server credential returned matches the session key +encrypt of the server challenge originally received. JRA. +****************************************************************************/ + +NTSTATUS new_cli_net_auth2(struct cli_state *cli, uint16 sec_chan, + uint32 neg_flags, DOM_CHAL *srv_chal) +{ + prs_struct qbuf, rbuf; + NET_Q_AUTH_2 q; + NET_R_AUTH_2 r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + extern pstring global_myname; + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + /* create and send a MSRPC command with api NET_AUTH2 */ + + DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", + cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, + credstr(cli->clnt_cred.challenge.data), neg_flags)); + + /* store the parameters */ + init_q_auth_2(&q, cli->srv_name_slash, cli->mach_acct, + sec_chan, global_myname, &cli->clnt_cred.challenge, + neg_flags); + + /* turn parameters into data stream */ + + if (!net_io_q_auth_2("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_AUTH2, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!net_io_r_auth_2("", &r, &rbuf, 0)) { + goto done; + } + + result = r.status; + + if (result == NT_STATUS_OK) { + UTIME zerotime; + + /* + * Check the returned value using the initial + * server received challenge. + */ + + zerotime.time = 0; + if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, + zerotime) == 0) { + + /* + * Server replied with bad credential. Fail. + */ + DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ +password ?).\n", cli->desthost )); + result = NT_STATUS_ACCESS_DENIED; + goto done; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Initialize domain session credentials */ + +NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, + unsigned char mach_pwd[16]) +{ + DOM_CHAL clnt_chal; + DOM_CHAL srv_chal; + UTIME zerotime; + NTSTATUS result; + + /******************* Request Challenge ********************/ + + generate_random_buffer(clnt_chal.data, 8, False); + + /* send a client challenge; receive a server challenge */ + result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal); + + if (result != NT_STATUS_OK) { + DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); + return result; + } + + /**************** Long-term Session key **************/ + + /* calculate the session key */ + cred_session_key(&clnt_chal, &srv_chal, (char *)mach_pwd, + cli->sess_key); + memset((char *)cli->sess_key+8, '\0', 8); + + /******************* Authenticate 2 ********************/ + + /* calculate auth-2 credentials */ + zerotime.time = 0; + cred_create(cli->sess_key, &clnt_chal, zerotime, + &cli->clnt_cred.challenge); + + /* + * Send client auth-2 challenge. + * Receive an auth-2 challenge response and check it. + */ + + if (!new_cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, + &srv_chal)) { + DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n")); + return False; + } + + return True; +} + /* Logon Control 2 */ NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, -- cgit From 7844aa868b02f99c013f336ee03ef05adbd11a7b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Sep 2001 08:11:17 +0000 Subject: more warning fixes on solaris (This used to be commit c04c67fec85b1c81ef0b3cebacde304a1de0d854) --- source3/libsmb/cli_netlogon.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index dc43ab935d..b330299721 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -288,7 +288,7 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, NET_R_SAM_SYNC r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_CRED clnt_creds; - char sess_key[16]; + uchar sess_key[16]; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -347,7 +347,7 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, NET_R_SAM_DELTAS r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_CRED clnt_creds; - char sess_key[16]; + uchar sess_key[16]; ZERO_STRUCT(q); ZERO_STRUCT(r); -- cgit From fbe6685a79d6480ee5d6f97c30e78254dcf8b0ff Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Sep 2001 08:54:04 +0000 Subject: fixed some compilation errors in cli_netlogon.c - tim, you need to rerun configure to get the new NTSTATUS stuff right (This used to be commit 9bae57cfe30825174536d11983bb3434498e3f03) --- source3/libsmb/cli_netlogon.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index b330299721..cd68ea3503 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -72,7 +72,7 @@ NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, /* Return result */ - if (result == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result)) { memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data)); } @@ -129,7 +129,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, uint16 sec_chan, result = r.status; - if (result == NT_STATUS_OK) { + if (NT_STATUS_IS_OK(result)) { UTIME zerotime; /* @@ -175,7 +175,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, /* send a client challenge; receive a server challenge */ result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal); - if (result != NT_STATUS_OK) { + if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); return result; } @@ -199,14 +199,15 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, * Receive an auth-2 challenge response and check it. */ - if (!new_cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, - &srv_chal)) { - DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n")); - return False; + result = new_cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, + &srv_chal); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed %s\n", + get_nt_error_msg(result))); } - return True; + return result; } /* Logon Control 2 */ -- cgit From d53d5beeb29c0024556aae2f66f1d5bfe63960e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Sep 2001 11:32:59 +0000 Subject: use cli_is_error() instead of looking in smb_rcls, otherwise NT status codes don't work correctly (This used to be commit 55d5828e608671f070a9e96938be0d16d50aeb26) --- source3/libsmb/cliconnect.c | 12 ++++----- source3/libsmb/clierror.c | 2 +- source3/libsmb/clifile.c | 34 +++++++++++-------------- source3/libsmb/clilist.c | 4 +-- source3/libsmb/clireadwrite.c | 4 +-- source3/libsmb/clitrans.c | 4 +-- source3/libsmb/smberr.c | 59 ++++++++++++++++++++----------------------- 7 files changed, 55 insertions(+), 64 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8230edbd63..14faf6e8fe 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -188,7 +188,7 @@ BOOL cli_session_setup(struct cli_state *cli, show_msg(cli->inbuf); - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -228,7 +228,7 @@ BOOL cli_ulogoff(struct cli_state *cli) if (!cli_receive_smb(cli)) return False; - return CVAL(cli->inbuf,smb_rcls) == 0; + return !cli_is_error(cli); } /**************************************************************************** @@ -292,13 +292,11 @@ BOOL cli_send_tconX(struct cli_state *cli, cli_setup_bcc(cli, p); - SCVAL(cli->inbuf,smb_rcls, 1); - cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -339,7 +337,7 @@ BOOL cli_tdis(struct cli_state *cli) if (!cli_receive_smb(cli)) return False; - return CVAL(cli->inbuf,smb_rcls) == 0; + return !cli_is_error(cli); } @@ -412,7 +410,7 @@ BOOL cli_negprot(struct cli_state *cli) show_msg(cli->inbuf); - if (CVAL(cli->inbuf,smb_rcls) != 0 || + if (cli_is_error(cli) || ((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) { return(False); } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 22c5dbaf77..5bc3992944 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -58,7 +58,7 @@ static struct ****************************************************************************/ static char *cli_smb_errstr(struct cli_state *cli) { - return smb_errstr(cli->inbuf); + return smb_dos_errstr(cli->inbuf); } /*************************************************************************** diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index c325d882c9..c6cf73bcf3 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -56,7 +56,7 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -91,7 +91,7 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -125,7 +125,7 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -159,7 +159,7 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -257,7 +257,7 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return -1; } @@ -345,7 +345,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return -1; } @@ -377,11 +377,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { - return False; - } - - return True; + return !cli_is_error(cli); } @@ -430,7 +426,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, cli->timeout = saved_timeout; - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -471,7 +467,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -530,7 +526,7 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, cli->timeout = saved_timeout; - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -575,7 +571,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -609,7 +605,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -665,7 +661,7 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -717,7 +713,7 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) return False; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return False; } @@ -813,7 +809,7 @@ int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) return -1; } - if (CVAL(cli->inbuf,smb_rcls) != 0) { + if (cli_is_error(cli)) { return -1; } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 562e1710d3..a99bc91bfb 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -408,7 +408,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, num_received += received; - if (CVAL(cli->inbuf,smb_rcls) != 0) break; + if (cli_is_error(cli)) break; } if (!first) { @@ -436,7 +436,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { - DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); + DEBUG(0,("Error closing search: %s\n",cli_errstr(cli))); } } diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index abbb8cd110..f141a208bf 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -297,7 +297,7 @@ ssize_t cli_write(struct cli_state *cli, received++; - if (CVAL(cli->inbuf,smb_rcls) != 0) + if (cli_is_error(cli)) break; bwritten += SVAL(cli->inbuf, smb_vwv2); @@ -349,7 +349,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, if (!cli_receive_smb(cli)) return -1; - if (CVAL(cli->inbuf,smb_rcls) != 0) + if (cli_is_error(cli)) return -1; size = SVAL(cli->inbuf,smb_vwv0); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index bcf1bf5f74..8da1cc665f 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -89,7 +89,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || - CVAL(cli->inbuf,smb_rcls) != 0) { + cli_is_error(cli)) { return(False); } @@ -307,7 +307,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || - CVAL(cli->inbuf,smb_rcls) != 0) { + cli_is_error(cli)) { return(False); } diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 00966aed43..c881b54203 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -148,39 +148,36 @@ struct /**************************************************************************** return a SMB error string from a SMB buffer ****************************************************************************/ -char *smb_errstr(char *inbuf) +char *smb_dos_errstr(char *inbuf) { - static pstring ret; - int class = CVAL(inbuf,smb_rcls); - int num = SVAL(inbuf,smb_err); - int i,j; - - for (i=0;err_classes[i].class;i++) - if (err_classes[i].code == class) - { - if (err_classes[i].err_msgs) - { - err_code_struct *err = err_classes[i].err_msgs; - for (j=0;err[j].name;j++) - if (num == err[j].code) - { - if (DEBUGLEVEL > 0) - slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)", - err_classes[i].class, - err[j].name,err[j].message); - else - slprintf(ret, sizeof(ret) - 1, "%s - %s", - err_classes[i].class,err[j].name); - return ret; + static pstring ret; + int class = CVAL(inbuf,smb_rcls); + int num = SVAL(inbuf,smb_err); + int i,j; + + for (i=0;err_classes[i].class;i++) + if (err_classes[i].code == class) { + if (err_classes[i].err_msgs) { + err_code_struct *err = err_classes[i].err_msgs; + for (j=0;err[j].name;j++) + if (num == err[j].code) { + if (DEBUGLEVEL > 0) + slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)", + err_classes[i].class, + err[j].name,err[j].message); + else + slprintf(ret, sizeof(ret) - 1, "%s - %s", + err_classes[i].class,err[j].name); + return ret; + } + } + + slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num); + return ret; } - } - - slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num); - return ret; - } - - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); - return(ret); + + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); + return(ret); } -- cgit From 1772584c35189cba517c26bbde3205447f875952 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Sep 2001 05:45:07 +0000 Subject: actually obey the "use mmap" smb.conf option (This used to be commit b36c98036bcbaa5545c9637cb632361122033cfd) --- source3/libsmb/unexpected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 109e2b454a..41249aba56 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -151,7 +151,7 @@ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, { TDB_CONTEXT *tdb2; - tdb2 = tdb_open(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0); + tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0); if (!tdb2) return NULL; matched_packet = NULL; -- cgit From 9a9ac2739bbdc993ecdfa78298bdd9c059328378 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Sep 2001 22:08:19 +0000 Subject: got rid of USE_TDB_MMAP_FLAG as its not needed any more (This used to be commit c26e0d3f27a05ecc8bd2390f9aab7f9451524e47) --- source3/libsmb/unexpected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 41249aba56..7d221e173e 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -50,7 +50,7 @@ void unexpected_packet(struct packet_struct *p) if (!tdbd) { tdbd = tdb_open_log(lock_path("unexpected.tdb"), 1, - TDB_CLEAR_IF_FIRST|USE_TDB_MMAP_FLAG, + TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR | O_CREAT, 0644); if (!tdbd) { DEBUG(0,("Failed to open unexpected.tdb\n")); -- cgit From ba8e3e03432ee7649a3f59ba8b37edbb32c34190 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 9 Sep 2001 09:59:33 +0000 Subject: Make sure that if there are no interfaces, name_register_wins does not segfault. (This used to be commit a7842fac94a3f772da0e6ddf14044df24af798a9) --- source3/libsmb/namequery.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 4a3cf43b35..39159be41b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -560,6 +560,13 @@ BOOL name_register_wins(const char *name, int name_type) int num_interfaces = iface_count(); struct in_addr sendto_ip; + /* + * Check if we have any interfaces, prevents a segfault later + */ + + if (num_interfaces <= 0) + return False; /* Should return some indication of the problem */ + /* * Do a broadcast register ... */ -- cgit From 79139fe8d882c39620b0d52ef081f639d1294917 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Sep 2001 12:46:42 +0000 Subject: convert more code to use XFILE (This used to be commit fe6679dffba9a92bb35933ad52172c9be0e9ef90) --- source3/libsmb/namequery.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 39159be41b..9dea4b7694 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -449,26 +449,26 @@ struct in_addr *name_query(int fd,const char *name,int name_type, Start parsing the lmhosts file. *********************************************************/ -FILE *startlmhosts(char *fname) +XFILE *startlmhosts(char *fname) { - FILE *fp = sys_fopen(fname,"r"); - if (!fp) { - DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", - fname, strerror(errno))); - return NULL; - } - return fp; + XFILE *fp = x_fopen(fname,O_RDONLY, 0); + if (!fp) { + DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", + fname, strerror(errno))); + return NULL; + } + return fp; } /******************************************************** Parse the next line in the lmhosts file. *********************************************************/ -BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) +BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) { pstring line; - while(!feof(fp) && !ferror(fp)) { + while(!x_feof(fp) && !x_ferror(fp)) { pstring ip,flags,extra; char *ptr; int count = 0; @@ -549,9 +549,9 @@ BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipad Finish parsing the lmhosts file. *********************************************************/ -void endlmhosts(FILE *fp) +void endlmhosts(XFILE *fp) { - fclose(fp); + x_fclose(fp); } BOOL name_register_wins(const char *name, int name_type) @@ -741,7 +741,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, * "lmhosts" means parse the local lmhosts file. */ - FILE *fp; + XFILE *fp; pstring lmhost_name; int name_type2; struct in_addr return_ip; -- cgit From a94843061a3d2dbc7de11db9c07226670555cf9b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 11 Sep 2001 04:14:26 +0000 Subject: Added a string for NT_STATUS_OK, m'kay? (This used to be commit ff149308349fbf80399d9d541659f3c1d668306a) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 7fdeb4e5a7..1f61e648c2 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -31,6 +31,7 @@ typedef struct nt_err_code_struct nt_errs[] = { + { "NT_STATUS_OK", NT_STATUS_OK }, { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, { "NT_STATUS_NOT_IMPLEMENTED", NT_STATUS_NOT_IMPLEMENTED }, { "NT_STATUS_INVALID_INFO_CLASS", NT_STATUS_INVALID_INFO_CLASS }, -- cgit From a39d4c052c2787f97957d432c0faa337144778f8 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 12 Sep 2001 01:14:03 +0000 Subject: Converted DFS error returns to WERROR instead of uint32. (This used to be commit 97286570ef6f9151b5fe0be32aa4b294e7db9ab8) --- source3/libsmb/cli_dfs.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index b1ad01e748..d900d95bb2 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -123,7 +123,7 @@ NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; DFS_Q_DFS_REMOVE q; DFS_R_DFS_REMOVE r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + WERROR result = WERR_BADFUNC; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -156,7 +156,7 @@ NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_mem_free(&qbuf); prs_mem_free(&rbuf); - return result; + return NT_STATUS_OK; } NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, @@ -167,7 +167,7 @@ NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; DFS_Q_DFS_GET_INFO q; DFS_R_DFS_GET_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + WERROR result = WERR_BADFUNC; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -202,7 +202,7 @@ NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_mem_free(&qbuf); prs_mem_free(&rbuf); - return result; + return NT_STATUS_OK; /* Should return a WERROR */ } /* Enumerate dfs shares */ @@ -213,7 +213,7 @@ NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; DFS_Q_DFS_ENUM q; DFS_R_DFS_ENUM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + WERROR result = WERR_BADFUNC; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -248,5 +248,5 @@ NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_mem_free(&qbuf); prs_mem_free(&rbuf); - return result; + return NT_STATUS_OK; } -- cgit From b800a36b1c81fb37ca963acdc49978ff065fb0d7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 12 Sep 2001 06:39:50 +0000 Subject: Some patches to authentication: - the usersupplied_info now contains a smb_username (as it comes across on the wire) and a unix_username (after being passed through mapping functions) - when doing security={server,domain} use the smb_username, otherwise use the unix_username (This used to be commit d34fd8ec0716127c7a68eeb8e77d1ae8cc07b547) --- source3/libsmb/domain_client_validate.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index a6890f1027..b23ab01c1d 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -362,4 +362,3 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, cli_shutdown(&cli); return status; } - -- cgit From f04f28a62246dd16b3467f7aba2a492e64b8eed1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 13 Sep 2001 01:00:46 +0000 Subject: Fixed return value for cli_dfs_exist() - nt4 returns 1, w2k returns 2. Use werror_to_ntstatus() to convert error returns from dfs client functions into nt errors. (This used to be commit a83061ef3e4933c52e7206270b455a3888fa63a8) --- source3/libsmb/cli_dfs.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index d900d95bb2..83220fd1af 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -64,7 +64,7 @@ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return result */ - *dfs_exists = (r.status == 1); + *dfs_exists = (r.status != 0); result = NT_STATUS_OK; @@ -110,6 +110,8 @@ NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return result */ + result = werror_to_ntstatus(r.status); + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); @@ -123,7 +125,7 @@ NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; DFS_Q_DFS_REMOVE q; DFS_R_DFS_REMOVE r; - WERROR result = WERR_BADFUNC; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -150,13 +152,13 @@ NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return result */ - result = r.status; + result = werror_to_ntstatus(r.status); done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - return NT_STATUS_OK; + return result; } NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, @@ -167,7 +169,7 @@ NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; DFS_Q_DFS_GET_INFO q; DFS_R_DFS_GET_INFO r; - WERROR result = WERR_BADFUNC; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -195,14 +197,14 @@ NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return result */ - result = r.status; + result = werror_to_ntstatus(r.status); *ctr = r.ctr; done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - return NT_STATUS_OK; /* Should return a WERROR */ + return result; } /* Enumerate dfs shares */ @@ -213,7 +215,7 @@ NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct qbuf, rbuf; DFS_Q_DFS_ENUM q; DFS_R_DFS_ENUM r; - WERROR result = WERR_BADFUNC; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -242,11 +244,11 @@ NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return result */ - result = r.status; + result = werror_to_ntstatus(r.status); done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - return NT_STATUS_OK; + return result; } -- cgit From 0dab2c3e319d89183c2f3d75dbd1c25cbf738284 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 14 Sep 2001 04:32:52 +0000 Subject: Use session key from cli_state struct rather than the uninitialised one when calling cli_netlogon_sam_sync(). (-: (This used to be commit e4a3231a074b01cb1d6c4bf42e0a8e687e584413) --- source3/libsmb/cli_netlogon.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index cd68ea3503..98f448c6a7 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -289,7 +289,6 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, NET_R_SAM_SYNC r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_CRED clnt_creds; - uchar sess_key[16]; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -316,7 +315,7 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Unmarshall response */ - if (!net_io_r_sam_sync("", sess_key, &r, &rbuf, 0)) { + if (!net_io_r_sam_sync("", cli->sess_key, &r, &rbuf, 0)) { result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -348,7 +347,6 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, NET_R_SAM_DELTAS r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; DOM_CRED clnt_creds; - uchar sess_key[16]; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -376,7 +374,7 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Unmarshall response */ - if (!net_io_r_sam_deltas("", sess_key, &r, &rbuf, 0)) { + if (!net_io_r_sam_deltas("", cli->sess_key, &r, &rbuf, 0)) { result = NT_STATUS_UNSUCCESSFUL; goto done; } -- cgit From 82a8f8a171e4290cbae3d24069034191bf7f9f47 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 14 Sep 2001 04:34:06 +0000 Subject: Merge of sam_pwd_hash() function from tng. (This used to be commit b6cb6b837ac06d8b9cb898668e69236b64a8b698) --- source3/libsmb/smbdes.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index c5dbbdf99a..30a5746934 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -397,3 +397,20 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val) data[ind] = data[ind] ^ s_box[t]; } } + +/* Decode a sam password hash into a password. The password hash is the + same method used to store passwords in the NT registry. The DES key + used is based on the RID of the user. */ + +void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw) +{ + uchar s[14]; + + s[0] = s[4] = s[8] = s[12] = (uchar)(rid & 0xFF); + s[1] = s[5] = s[9] = s[13] = (uchar)((rid >> 8) & 0xFF); + s[2] = s[6] = s[10] = (uchar)((rid >> 16) & 0xFF); + s[3] = s[7] = s[11] = (uchar)((rid >> 24) & 0xFF); + + smbhash(out, in, s, forw); + smbhash(out+8, in+8, s+7, forw); +} -- cgit From bcbd75f7add425ebee760ddbd2e80a1d4a51e619 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 03:33:37 +0000 Subject: move to SAFE_FREE() (This used to be commit 48fc6a6cd52e01b287030fbbf0aa08a6814c5e11) --- source3/libsmb/clientgen.c | 16 +++---- source3/libsmb/clifile.c | 4 +- source3/libsmb/clilist.c | 12 ++--- source3/libsmb/cliprint.c | 8 ++-- source3/libsmb/clirap.c | 40 +++++++---------- source3/libsmb/clisecdesc.c | 8 ++-- source3/libsmb/domain_client_validate.c | 3 +- source3/libsmb/libsmbclient.c | 80 ++++++++++++++------------------- source3/libsmb/namequery.c | 21 ++++----- source3/libsmb/nmblib.c | 40 +++++------------ 10 files changed, 91 insertions(+), 141 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 87c8348853..79757947b4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -201,11 +201,11 @@ struct cli_state *cli_initialise(struct cli_state *cli) error: - safe_free(cli->inbuf); - safe_free(cli->outbuf); + SAFE_FREE(cli->inbuf); + SAFE_FREE(cli->outbuf); if (alloced_cli) - safe_free(cli); + SAFE_FREE(cli); return NULL; } @@ -215,14 +215,8 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { - if (cli->outbuf) - { - free(cli->outbuf); - } - if (cli->inbuf) - { - free(cli->inbuf); - } + SAFE_FREE(cli->outbuf); + SAFE_FREE(cli->inbuf); if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index c6cf73bcf3..4e6a89a9ae 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -201,8 +201,8 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) return False; } - if (rdata) free(rdata); - if (rparam) free(rparam); + SAFE_FREE(rdata); + SAFE_FREE(rparam); return True; } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a99bc91bfb..a9212c9dba 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -283,9 +283,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, total_received += ff_searchcount; - if (rdata) free(rdata); rdata = NULL; - if (rparam) free(rparam); rparam = NULL; - + SAFE_FREE(rdata); + SAFE_FREE(rparam); + DEBUG(3,("received %d entries (eos=%d)\n", ff_searchcount,ff_eos)); @@ -300,7 +300,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } /* free up the dirlist buffer */ - if (dirlist) free(dirlist); + SAFE_FREE(dirlist); return(total_received); } @@ -394,7 +394,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, if (!tdl) { DEBUG(0,("cli_list_old: failed to expand dirlist")); - if (dirlist) free(dirlist); + SAFE_FREE(dirlist); return 0; } else dirlist = tdl; @@ -446,7 +446,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, fn(&finfo, Mask, state); } - if (dirlist) free(dirlist); + SAFE_FREE(dirlist); return(num_received); } diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index eb9c859806..57e2c049d8 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -112,8 +112,8 @@ int cli_print_queue(struct cli_state *cli, } /* If any parameters or data were returned, free the storage. */ - if(rparam) free(rparam); - if(rdata) free(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); return i; } @@ -149,8 +149,8 @@ int cli_printjob_del(struct cli_state *cli, int job) ret = SVAL(rparam,0); } - if (rparam) free(rparam); - if (rdata) free(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); return ret; } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index bfbe478191..90f4d546d1 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -124,10 +124,8 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) } } - if (rparam) - free(rparam); - if (rdata) - free(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); return (cli->rap_error == 0); } @@ -193,10 +191,8 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co DEBUG(4,("NetShareEnum failed\n")); } - if (rparam) - free(rparam); - if (rdata) - free(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); return count; } @@ -271,10 +267,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, } } - if (rparam) - free(rparam); - if (rdata) - free(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); return(count > 0); } @@ -363,10 +357,8 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char cli->rap_error = SVAL(rparam,0); } - if (rparam) - free(rparam); - if (rdata) - free(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); return (cli->rap_error == 0); } @@ -445,8 +437,8 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, *mode = SVAL(rdata,l1_attrFile); } - if (rdata) free(rdata); - if (rparam) free(rparam); + SAFE_FREE(rdata); + SAFE_FREE(rparam); return True; } @@ -515,8 +507,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, *ino = IVAL(rdata, 64); } - if (rdata) free(rdata); - if (rparam) free(rparam); + SAFE_FREE(rdata); + SAFE_FREE(rparam); return True; } @@ -587,8 +579,8 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, *ino = IVAL(rdata, 64); } - if (rdata) free(rdata); - if (rparam) free(rparam); + SAFE_FREE(rdata); + SAFE_FREE(rparam); return True; } @@ -631,7 +623,7 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat memcpy(outdata, rdata, data_len); - if (rdata) free(rdata); - if (rparam) free(rparam); + SAFE_FREE(rdata); + SAFE_FREE(rparam); return True; } diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index e0d6ae809f..0e0884b843 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -65,8 +65,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, cleanup: - safe_free(rparam); - safe_free(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); prs_mem_free(&pd); return psd; @@ -122,8 +122,8 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) cleanup: - safe_free(rparam); - safe_free(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); talloc_destroy(mem_ctx); diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index b23ab01c1d..90c15fd1f7 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -256,8 +256,7 @@ static BOOL find_connect_pdc(struct cli_state *pcli, } } - if(ip_list != NULL) - free((char *)ip_list); + SAFE_FREE(ip_list); return connected_ok; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f7008a2680..9dca4637f4 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -393,9 +393,9 @@ struct smbc_server *smbc_server(char *server, char *share, cli_shutdown(&c); if (!srv) return NULL; - if (srv->server_name) free(srv->server_name); - if (srv->share_name) free(srv->share_name); - free(srv); + SAFE_FREE(srv->server_name); + SAFE_FREE(srv->share_name); + SAFE_FREE(srv); return NULL; } @@ -602,8 +602,7 @@ int smbc_open(const char *fname, int flags, mode_t mode) /* Handle the error ... */ - free(smbc_file_table[slot]); - smbc_file_table[slot] = NULL; + SAFE_FREE(smbc_file_table[slot]); errno = smbc_errno(&srv->cli); return -1; @@ -816,8 +815,8 @@ int smbc_close(int fd) } - if (fe->fname) free(fe->fname); - free(fe); + SAFE_FREE(fe->fname); + SAFE_FREE(fe); smbc_file_table[fd - smbc_start_fd] = NULL; return 0; @@ -1313,8 +1312,8 @@ static void smbc_remove_dir(struct smbc_file *dir) f = d; d = d->next; - if (f->dirent) free(f->dirent); - free(f); + SAFE_FREE(f->dirent); + SAFE_FREE(f); } @@ -1350,7 +1349,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme dir->dir_list = malloc(sizeof(struct smbc_dir_list)); if (!dir->dir_list) { - free(dirent); + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; @@ -1365,7 +1364,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme if (!dir->dir_end) { - free(dirent); + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; @@ -1519,10 +1518,9 @@ int smbc_opendir(const char *fname) errno = EINVAL; if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; return -1; } @@ -1559,10 +1557,9 @@ int smbc_opendir(const char *fname) if (!srv) { if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; return -1; } @@ -1575,10 +1572,9 @@ int smbc_opendir(const char *fname) (void *)smbc_file_table[slot])) { if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; errno = cli_errno(&srv->cli); return -1; @@ -1592,10 +1588,9 @@ int smbc_opendir(const char *fname) errno = EINVAL; if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; return -1; } @@ -1630,10 +1625,9 @@ int smbc_opendir(const char *fname) if (!srv) { if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; /* FIXME: Memory leaks ... */ return -1; } @@ -1646,10 +1640,9 @@ int smbc_opendir(const char *fname) (void *)smbc_file_table[slot])) { if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; errno = cli_errno(&srv->cli); return -1; @@ -1669,10 +1662,9 @@ int smbc_opendir(const char *fname) if (!srv) { if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; return -1; } @@ -1686,10 +1678,9 @@ int smbc_opendir(const char *fname) errno = cli_errno(&srv->cli); if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; return -1; } @@ -1699,10 +1690,9 @@ int smbc_opendir(const char *fname) errno = ENODEV; /* Neither the workgroup nor server exists */ if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; return -1; } @@ -1721,10 +1711,9 @@ int smbc_opendir(const char *fname) if (!srv) { if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; return -1; } @@ -1739,10 +1728,9 @@ int smbc_opendir(const char *fname) (void *)smbc_file_table[slot]) < 0) { if (smbc_file_table[slot]) { - if (smbc_file_table[slot]->fname) free(smbc_file_table[slot]->fname); - free(smbc_file_table[slot]); + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); } - smbc_file_table[slot] = NULL; errno = smbc_errno(&srv->cli); return -1; @@ -1790,8 +1778,8 @@ int smbc_closedir(int fd) if (fe) { - if (fe->fname) free(fe->fname); - free(fe); /* Free the space too */ + SAFE_FREE(fe->fname); + SAFE_FREE(fe); /* Free the space too */ } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 9dea4b7694..6fba488d66 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -184,7 +184,7 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name) pull_ascii(name, status[i].name, 15, 0, STR_TERMINATE); - free(status); + SAFE_FREE(status); return True; } @@ -273,7 +273,7 @@ BOOL name_register(int fd, const char *name, int name_type, if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) { debug_nmb_packet(p2); - free(p2); /* No memory leaks ... */ + SAFE_FREE(p2); /* No memory leaks ... */ } return True; @@ -405,8 +405,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, if (!tmp_ip_list) { DEBUG(0,("name_query: Realloc failed.\n")); - if (ip_list) - free(ip_list); + SAFE_FREE(ip_list); } ip_list = tmp_ip_list; @@ -871,7 +870,7 @@ static BOOL internal_resolve_name(const char *name, int name_type, } if((*return_iplist) != NULL) { - free((char *)(*return_iplist)); + SAFE_FREE(*return_iplist); *return_iplist = NULL; } return False; @@ -891,11 +890,10 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) if(internal_resolve_name(name, name_type, &ip_list, &count)) { *return_ip = ip_list[0]; - free((char *)ip_list); + SAFE_FREE(ip_list); return True; } - if(ip_list != NULL) - free((char *)ip_list); + SAFE_FREE(ip_list); return False; } @@ -956,17 +954,16 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip) if (internal_resolve_name(group, 0x1D, &ip_list, &count)) { *master_ip = ip_list[0]; - free((char *)ip_list); + SAFE_FREE(ip_list); return True; } if(internal_resolve_name(group, 0x1B, &ip_list, &count)) { *master_ip = ip_list[0]; - free((char *)ip_list); + SAFE_FREE((ip_list); return True; } - if(ip_list != NULL) - free((char *)ip_list); + SAFE_FREE(ip_list); return False; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6a24cb382c..4ecc887524 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -345,8 +345,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name); (*offset) += l; if (!l || (*offset)+10 > length) { - free(*recs); - *recs = NULL; + SAFE_FREE(*recs); return(False); } (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); @@ -356,8 +355,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, (*offset) += 10; if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || (*offset)+(*recs)[i].rdlength > length) { - free(*recs); - *recs = NULL; + SAFE_FREE(*recs); return(False); } memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); @@ -580,19 +578,10 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) free_and_exit: - if(copy_nmb->answers) { - free((char *)copy_nmb->answers); - copy_nmb->answers = NULL; - } - if(copy_nmb->nsrecs) { - free((char *)copy_nmb->nsrecs); - copy_nmb->nsrecs = NULL; - } - if(copy_nmb->additional) { - free((char *)copy_nmb->additional); - copy_nmb->additional = NULL; - } - free((char *)pkt_copy); + SAFE_FREE(copy_nmb->answers); + SAFE_FREE(copy_nmb->nsrecs); + SAFE_FREE(copy_nmb->additional); + SAFE_FREE(pkt_copy); DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); return NULL; @@ -640,18 +629,9 @@ struct packet_struct *copy_packet(struct packet_struct *packet) ******************************************************************/ static void free_nmb_packet(struct nmb_packet *nmb) { - if (nmb->answers) { - free(nmb->answers); - nmb->answers = NULL; - } - if (nmb->nsrecs) { - free(nmb->nsrecs); - nmb->nsrecs = NULL; - } - if (nmb->additional) { - free(nmb->additional); - nmb->additional = NULL; - } + SAFE_FREE(nmb->answers); + SAFE_FREE(nmb->nsrecs); + SAFE_FREE(nmb->additional); } /******************************************************************* @@ -674,7 +654,7 @@ void free_packet(struct packet_struct *packet) else if (packet->packet_type == DGRAM_PACKET) free_dgram_packet(&packet->packet.dgram); ZERO_STRUCTPN(packet); - free(packet); + SAFE_FREE(packet); } /******************************************************************* -- cgit From acc373297159d87849d5e4c48345723c44fc3e95 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 03:44:52 +0000 Subject: typo (This used to be commit 23dc3fc7009ce40064db57d5ec8b720c7d9350a8) --- source3/libsmb/namequery.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6fba488d66..b82e98b0fc 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -869,10 +869,7 @@ static BOOL internal_resolve_name(const char *name, int name_type, } } - if((*return_iplist) != NULL) { - SAFE_FREE(*return_iplist); - *return_iplist = NULL; - } + SAFE_FREE(*return_iplist); return False; } @@ -959,7 +956,7 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip) } if(internal_resolve_name(group, 0x1B, &ip_list, &count)) { *master_ip = ip_list[0]; - SAFE_FREE((ip_list); + SAFE_FREE(ip_list); return True; } -- cgit From 23af0743267d250a90af77c3bbce4d5fd0cdcc00 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 17 Sep 2001 04:23:48 +0000 Subject: fixed ctemp in server and client. It turns out that ctemp on NT is completely broken, and it's pointless to emulate their brokenness completely in this case, but at least this makes us use approximately the same packet format. The spec is complelet wrong in this case (This used to be commit 2d507ec669def6d49304559e53d6c14af9b290a9) --- source3/libsmb/clifile.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 4e6a89a9ae..e9981d7205 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -785,18 +785,20 @@ create and open a temporary file ****************************************************************************/ int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) { + int len; char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); + set_message(cli->outbuf,3,0,True); CVAL(cli->outbuf,smb_com) = SMBctemp; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0); + SIVALS(cli->outbuf,smb_vwv1,-1); p = smb_buf(cli->outbuf); *p++ = 4; @@ -813,10 +815,17 @@ int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) return -1; } + /* despite the spec, the result has a -1, followed by + length, followed by name */ + p = smb_buf(cli->inbuf); + p += 4; + len = smb_buflen(cli->inbuf) - 4; + if (len <= 0) return -1; + if (tmp_path) { pstring path2; - clistr_pull(cli, path2, smb_buf(cli->inbuf)+1, - sizeof(path2), -1, STR_TERMINATE); + clistr_pull(cli, path2, p, + sizeof(path2), len, STR_ASCII); *tmp_path = strdup(path2); } -- cgit From 15a6649c01195f2b385fbfd7e54279c1acc3a878 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 18 Sep 2001 02:49:35 +0000 Subject: Converted cli_net_auth2() and cli_nt_setup_creds() to return NTSTATUS. (This used to be commit e0bdcbc5994345fdc76f7590dba7bce5f0127d58) --- source3/libsmb/domain_client_validate.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 90c15fd1f7..5a8ae372ea 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -37,6 +37,7 @@ static BOOL connect_to_domain_password_server(struct cli_state *pcli, { struct in_addr dest_ip; fstring remote_machine; + NTSTATUS result; if(cli_initialise(pcli) == NULL) { DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); @@ -154,9 +155,11 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); return False; } - if (cli_nt_setup_creds(pcli, trust_passwd) == False) { + result = cli_nt_setup_creds(pcli, trust_passwd); + + if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ -%s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); +%s. Error was : %s.\n", remote_machine, get_nt_error_msg(result))); cli_nt_session_close(pcli); cli_ulogoff(pcli); cli_shutdown(pcli); -- cgit From fe1950562d6ea748da8255425e2b10c608ee1604 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Sep 2001 21:53:34 +0000 Subject: Removed extra '()' s. Jeremy. (This used to be commit b5f4a97bb028394f56c904dbb8e12827cb99e785) --- source3/libsmb/credentials.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 26d5c13bc9..d4c8792068 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -156,8 +156,8 @@ BOOL clnt_deal_with_creds(uchar sess_key[8], new_clnt_time.time = sto_clnt_cred->timestamp.time + 1; /* check that the received server credentials are valid */ - if (!cred_assert(&(rcv_srv_cred->challenge), sess_key, - &(sto_clnt_cred->challenge), new_clnt_time)) + if (!cred_assert(&rcv_srv_cred->challenge, sess_key, + &sto_clnt_cred->challenge, new_clnt_time)) { return False; } @@ -187,8 +187,8 @@ BOOL deal_with_creds(uchar sess_key[8], DEBUG(5,("deal_with_creds: %d\n", __LINE__)); /* check that the received client credentials are valid */ - if (!cred_assert(&(rcv_clnt_cred->challenge), sess_key, - &(sto_clnt_cred->challenge), rcv_clnt_cred->timestamp)) + if (!cred_assert(&rcv_clnt_cred->challenge, sess_key, + &sto_clnt_cred->challenge, rcv_clnt_cred->timestamp)) { return False; } @@ -208,8 +208,8 @@ BOOL deal_with_creds(uchar sess_key[8], DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time)); /* create return credentials for inclusion in the reply */ - cred_create(sess_key, &(sto_clnt_cred->challenge), new_clnt_time, - &(rtn_srv_cred->challenge)); + cred_create(sess_key, &sto_clnt_cred->challenge, new_clnt_time, + &rtn_srv_cred->challenge); DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data))); @@ -218,5 +218,3 @@ BOOL deal_with_creds(uchar sess_key[8], return True; } - - -- cgit From e3249d0196a3bf0c159acf69bb5fb1d0c78d1290 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Sep 2001 04:25:49 +0000 Subject: added cli_qpathinfo_alt_name() for fetching the 8.3 name of a file (This used to be commit b2eb7feb7f5bafe953fdeb92daaf9e4f08e44983) --- source3/libsmb/clirap.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 90f4d546d1..2136ba118b 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -627,3 +627,68 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat SAFE_FREE(rparam); return True; } + + + +/**************************************************************************** +send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call +****************************************************************************/ +NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + int count=8; + char *p; + BOOL ret; + int len; + + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO); + p += 6; + p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); + + param_len = PTR_DIFF(p, param); + + do { + ret = (cli_send_trans(cli, SMBtrans2, + NULL, /* Name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + ) && + cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)); + if (!ret && cli_is_dos_error(cli)) { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_dos_error(cli, &eclass, &ecode); + if (eclass != ERRSRV || ecode != ERRerror) break; + msleep(100); + } + } while (count-- && ret==False); + + if (!ret || !rdata || data_len < 4) { + return NT_STATUS_UNSUCCESSFUL; + } + + len = IVAL(rdata, 0); + + if (len > data_len - 4) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, 0); + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return NT_STATUS_OK; +} -- cgit From d74d82bddce5d6cf3f554ff014e08f2aeb2c14bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 26 Sep 2001 11:51:25 +0000 Subject: Make use of the pdb_set_plaintext_passwd() update to vastly simplify decode_pw_buffer() and the samr password changing routines. And yes, I know that we can lost some information in the Unicode->UTF->Unicode bit of this, but its worth the code cleanup. This also takes into account the possability of multibyte passwords. Andrew Bartlett (This used to be commit 42402c87d6bcff71b700e497b74d2600d7ce8b95) --- source3/libsmb/smbencrypt.c | 59 ++++++++------------------------------------- 1 file changed, 10 insertions(+), 49 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b6273dedfc..119490aa7f 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -292,16 +292,15 @@ BOOL encode_pw_buffer(char buffer[516], const char *new_pass, /*********************************************************** decode a password buffer + *new_pw_len is the length in bytes of the possibly mulitbyte + returned password including termination. ************************************************************/ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len, - uchar nt_p16[16], uchar p16[16]) + int new_pwrd_size, uint32 *new_pw_len) { - int uni_pw_len=0; int byte_len=0; char unicode_passwd[514]; char lm_ascii_passwd[514]; - char passwd[514]; /* Warning !!! : This function is called from some rpc call. @@ -310,13 +309,6 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, If you reuse that code somewhere else check first. */ - ZERO_STRUCT(unicode_passwd); - ZERO_STRUCT(lm_ascii_passwd); - ZERO_STRUCT(passwd); - - memset(nt_p16, '\0', 16); - memset(p16, '\0', 16); - /* The length of the new password is in the last 4 bytes of the data buffer. */ byte_len = IVAL(in_buffer, 512); @@ -328,50 +320,19 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, /* Password cannot be longer than 128 characters */ if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) { DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); + DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); return False; } - - pull_string(NULL, passwd, &in_buffer[512 - byte_len], -1, byte_len, STR_UNICODE); - uni_pw_len = byte_len/2; - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: passwd: ")); - dump_data(100, (char *)passwd, uni_pw_len); - DEBUG(100,("len:%d\n", uni_pw_len)); -#endif - memcpy(unicode_passwd, &in_buffer[512 - byte_len], byte_len); - - mdfour(nt_p16, (unsigned char *)unicode_passwd, byte_len); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: nt#:")); - dump_data(100, (char *)nt_p16, 16); - DEBUG(100,("\n")); -#endif - - /* Mangle the passwords into Lanman format */ - memcpy(lm_ascii_passwd, passwd, byte_len/2); - lm_ascii_passwd[14] = '\0'; - strupper(lm_ascii_passwd); - /* Calculate the SMB (lanman) hash functions of the password */ - E_P16((uchar *) lm_ascii_passwd, (uchar *)p16); + /* decode into the return buffer. Buffer must be a pstring */ + *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, STR_UNICODE); #ifdef DEBUG_PASSWORD - DEBUG(100,("nt_lm_owf_gen: lm#:")); - dump_data(100, (char *)p16, 16); - DEBUG(100,("\n")); + DEBUG(100,("decode_pw_buffer: new_pwrd: ")); + dump_data(100, (char *)new_pwrd, *new_pw_len); + DEBUG(100,("multibyte len:%d\n", *new_pw_len)); + DEBUG(100,("original char len:%d\n", byte_len/2)); #endif - - /* copy the password and it's length to the return buffer */ - *new_pw_len = byte_len/2; - memcpy(new_pwrd, passwd, uni_pw_len); - new_pwrd[uni_pw_len]='\0'; - - /* clear out local copy of user's password (just being paranoid). */ - ZERO_STRUCT(unicode_passwd); - ZERO_STRUCT(lm_ascii_passwd); - ZERO_STRUCT(passwd); return True; -- cgit From f6ce758e5b88e4a1efa7525e91ebb61c2245d23b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 27 Sep 2001 09:18:13 +0000 Subject: Kill unused variables (This used to be commit 758d923fa183b50acab9928e402f17bd25ba8f41) --- source3/libsmb/smbencrypt.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 119490aa7f..b1a5c9fbb8 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -299,8 +299,6 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, int new_pwrd_size, uint32 *new_pw_len) { int byte_len=0; - char unicode_passwd[514]; - char lm_ascii_passwd[514]; /* Warning !!! : This function is called from some rpc call. -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/libsmb/clientgen.c | 4 ---- source3/libsmb/clierror.c | 3 --- source3/libsmb/clioplock.c | 3 --- source3/libsmb/credentials.c | 4 ---- source3/libsmb/domain_client_validate.c | 1 - source3/libsmb/namequery.c | 2 -- source3/libsmb/nmblib.c | 4 ---- source3/libsmb/pwd_cache.c | 3 --- source3/libsmb/smbencrypt.c | 3 --- source3/libsmb/smberr.c | 3 --- source3/libsmb/unexpected.c | 2 -- 11 files changed, 32 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 79757947b4..62b46a7904 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -23,9 +23,6 @@ #include "includes.h" - -extern int DEBUGLEVEL; - /* * Change the port number used to call on */ @@ -248,4 +245,3 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) cli->pid = pid; return ret; } - diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 5bc3992944..bcecc92d77 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -23,8 +23,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - /***************************************************** RAP error codes - a small start but will be extended. *******************************************************/ @@ -267,4 +265,3 @@ BOOL cli_is_dos_error(struct cli_state *cli) return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES); } - diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index a52dcf3a3e..b38933181e 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -22,8 +22,6 @@ #define NO_SYSLOG #include "includes.h" -extern int DEBUGLEVEL; - /**************************************************************************** send an ack for an oplock break request @@ -69,4 +67,3 @@ void cli_oplock_handler(struct cli_state *cli, { cli->oplock_handler = handler; } - diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index d4c8792068..5f65c13edd 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -21,10 +21,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - - - /**************************************************************************** represent a credential as a string ****************************************************************************/ diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 5a8ae372ea..255b37883d 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -22,7 +22,6 @@ #include "includes.h" -extern int DEBUGLEVEL; extern struct in_addr ipzero; extern pstring global_myname; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index b82e98b0fc..0dbf4b4564 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -22,8 +22,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - /* nmbd.c sets this to True. */ BOOL global_in_nmbd = False; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4ecc887524..d7bd7b49a0 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -22,8 +22,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - int num_good_sends = 0; int num_good_receives = 0; @@ -1269,5 +1267,3 @@ int name_len(char *s1) return(len); } /* name_len */ - - diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 37a07a0001..64e23e0feb 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -21,9 +21,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - - /**************************************************************************** initialises a password structure ****************************************************************************/ diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b1a5c9fbb8..4b127051b4 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -23,9 +23,6 @@ */ #include "includes.h" - -extern int DEBUGLEVEL; - #include "byteorder.h" /* diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index c881b54203..0b59b5b1a5 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -22,8 +22,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - /* error code stuff - put together by Merik Karman merik@blackadder.dsh.oz.au */ @@ -200,4 +198,3 @@ WERROR map_werror_from_unix(int error) NTSTATUS status = map_nt_error_from_unix(error); return ntstatus_to_werror(status); } - diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 7d221e173e..b77e7490a0 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -22,8 +22,6 @@ #include "includes.h" -extern int DEBUGLEVEL; - static TDB_CONTEXT *tdbd = NULL; /* the key type used in the unexpeceted packet database */ -- cgit From 81f56139b6964ddbe2c03232475f87f474136490 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Oct 2001 07:42:52 +0000 Subject: initial kerberos/ADS/SPNEGO support in libsmb and smbclient. To activate you need to: - install krb5 libraries - run configure - build smbclient - run kinit to get a TGT - run smbclient with the -k option to choose kerberos auth (This used to be commit d33057585644e1337bac743e25ed7653bfb39eef) --- source3/libsmb/asn1.c | 139 ++++++++++++ source3/libsmb/cliconnect.c | 531 ++++++++++++++++++++++++++++++++------------ source3/libsmb/clientgen.c | 12 +- source3/libsmb/clikrb5.c | 267 ++++++++++++++++++++++ 4 files changed, 802 insertions(+), 147 deletions(-) create mode 100644 source3/libsmb/asn1.c create mode 100644 source3/libsmb/clikrb5.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c new file mode 100644 index 0000000000..5735f372ca --- /dev/null +++ b/source3/libsmb/asn1.c @@ -0,0 +1,139 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + simple SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +void asn1_free(ASN1_DATA *data) +{ + free(data->data); +} + +BOOL asn1_check_empty(ASN1_DATA *data) +{ + if (data->nesting) return False; + return True; +} + +BOOL asn1_write(ASN1_DATA *data, const void *p, int len) +{ + if (data->length < data->ofs+len) { + data->data = Realloc(data->data, data->ofs+len); + if (!data->data) return False; + data->length = data->ofs+len; + } + memcpy(data->data + data->ofs, p, len); + data->ofs += len; + return True; +} + +BOOL asn1_write_uint8(ASN1_DATA *data, uint8 v) +{ + return asn1_write(data, &v, 1); +} + +BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) +{ + struct nesting *nesting; + + asn1_write_uint8(data, tag); + nesting = (struct nesting *)malloc(sizeof(struct nesting)); + if (!nesting) return False; + + nesting->start = data->ofs; + nesting->next = data->nesting; + data->nesting = nesting; + asn1_write_uint8(data, 0xff); + return True; +} + +BOOL asn1_pop_tag(ASN1_DATA *data) +{ + struct nesting *nesting; + size_t len; + + nesting = data->nesting; + + if (!nesting) { + return False; + } + len = data->ofs - (nesting->start+1); + if (len > 127) { + data->data[nesting->start] = 0x82; + asn1_write_uint8(data, 0); + asn1_write_uint8(data, 0); + memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); + data->data[nesting->start+1] = len>>8; + data->data[nesting->start+2] = len&0xff; + } else { + data->data[nesting->start] = len; + } + + data->nesting = nesting->next; + free(nesting); + return True; +} + + +BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) +{ + unsigned v, v2; + char *p = (char *)OID; + + asn1_push_tag(data, ASN1_OID); + v = strtol(p, &p, 10); + v2 = strtol(p, &p, 10); + asn1_write_uint8(data, 40*v + v2); + + while (*p) { + v = strtol(p, &p, 10); + if (v >= (1<<28)) asn1_write_uint8(data, 0x80 | ((v>>28)&0xff)); + if (v >= (1<<21)) asn1_write_uint8(data, 0x80 | ((v>>21)&0xff)); + if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff)); + if (v >= (1<<7)) asn1_write_uint8(data, 0x80 | ((v>>7)&0xff)); + asn1_write_uint8(data, v&0x7f); + } + asn1_pop_tag(data); + return True; +} + +BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) +{ + asn1_push_tag(data, ASN1_OCTET_STRING); + asn1_write(data, p, length); + asn1_pop_tag(data); + return True; +} + +BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) +{ + asn1_push_tag(data, ASN1_GENERAL_STRING); + asn1_write(data, s, strlen(s)); + asn1_pop_tag(data); + return True; +} + +BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) +{ + asn1_write_uint8(data, ASN1_BOOLEAN); + asn1_write_uint8(data, v); + return True; +} + diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 14faf6e8fe..77a8232ed5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -31,23 +31,365 @@ static struct { prots[] = { {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, {PROTOCOL_LANMAN1,"LANMAN1.0"}, + {PROTOCOL_LANMAN1,"Windows for Workgroups 3.1a"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {PROTOCOL_NT1,"LANMAN2.1"}, {PROTOCOL_NT1,"NT LM 0.12"}, {-1,NULL} }; +/**************************************************************************** +do an old lanman2 style session setup +****************************************************************************/ +static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, + char *pass, int passlen) +{ + fstring pword; + char *p; + + if (passlen > sizeof(pword)-1) { + return False; + } + + /* if in share level security then don't send a password now */ + if (!(cli->sec_mode & 1)) { + passlen = 0; + } + + if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) { + /* Encrypted mode needed, and non encrypted password supplied. */ + passlen = 24; + clistr_push(cli, pword, pass, -1, STR_TERMINATE); + SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); + } else if ((cli->sec_mode & 2) && passlen == 24) { + /* Encrypted mode needed, and encrypted password supplied. */ + memcpy(pword, pass, passlen); + } else if (passlen > 0) { + /* Plaintext mode needed, assume plaintext supplied. */ + passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); + } + + /* send a session setup command */ + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,10, 0, True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,1); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); + p += passlen; + p += clistr_push(cli, p, user, -1, STR_UPPER|STR_TERMINATE); + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + if (cli_is_error(cli)) { + return False; + } + + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); + fstrcpy(cli->user_name, user); + + return True; +} + + +/**************************************************************************** +work out suitable capabilities to offer the server +****************************************************************************/ +static uint32 cli_session_setup_capabilities(struct cli_state *cli) +{ + uint32 capabilities = CAP_NT_SMBS; + + /* Set the CLI_FORCE_DOSERR environment variable to test + client routines using DOS errors instead of STATUS32 + ones. This intended only as a temporary hack. */ + if (!getenv("CLI_FORCE_DOSERR")) { + capabilities |= CAP_STATUS32; + } + + if (cli->use_level_II_oplocks) { + capabilities |= CAP_LEVEL_II_OPLOCKS; + } + + if (cli->capabilities & CAP_UNICODE) { + capabilities |= CAP_UNICODE; + } + + return capabilities; +} + + +/**************************************************************************** +do a NT1 guest session setup +****************************************************************************/ +static BOOL cli_session_setup_guest(struct cli_state *cli) +{ + char *p; + uint32 capabilities = cli_session_setup_capabilities(cli); + + set_message(cli->outbuf,13,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,0); + SSVAL(cli->outbuf,smb_vwv8,0); + SIVAL(cli->outbuf,smb_vwv11,capabilities); + p = smb_buf(cli->outbuf); + p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */ + p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */ + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + if (cli_is_error(cli)) { + return False; + } + + cli->vuid = SVAL(cli->inbuf,smb_uid); + + p = smb_buf(cli->inbuf); + p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); + + fstrcpy(cli->user_name, ""); + + return True; +} + + +/**************************************************************************** +do a NT1 plaintext session setup +****************************************************************************/ +static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, + char *pass, char *workgroup) +{ + uint32 capabilities = cli_session_setup_capabilities(cli); + fstring pword; + int passlen; + char *p; + + passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); + + set_message(cli->outbuf,13,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + SSVAL(cli->outbuf,smb_vwv8,0); + SIVAL(cli->outbuf,smb_vwv11,capabilities); + p = smb_buf(cli->outbuf); + memcpy(p, pword, passlen); + p += passlen; + p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + if (cli_is_error(cli)) { + return False; + } + + cli->vuid = SVAL(cli->inbuf,smb_uid); + p = smb_buf(cli->inbuf); + p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); + fstrcpy(cli->user_name, user); + + return True; +} + + +/**************************************************************************** +do a NT1 NTLM/LM encrypted session setup +****************************************************************************/ +static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, + char *pass, int passlen, + char *ntpass, int ntpasslen, + char *workgroup) +{ + uint32 capabilities = cli_session_setup_capabilities(cli); + fstring pword, ntpword; + char *p; + + if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + return False; + } + + if (passlen != 24) { + /* non encrypted password supplied. */ + passlen = 24; + ntpasslen = 24; + clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); + clistr_push(cli, ntpword, ntpass, sizeof(ntpword), STR_TERMINATE); + SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); + SMBNTencrypt((uchar *)ntpword,cli->secblob.data,(uchar *)ntpword); + } else { + memcpy(pword, pass, passlen); + memcpy(ntpword, ntpass, ntpasslen); + } + + /* send a session setup command */ + memset(cli->outbuf,'\0',smb_size); + + set_message(cli->outbuf,13,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,passlen); + SSVAL(cli->outbuf,smb_vwv8,ntpasslen); + SIVAL(cli->outbuf,smb_vwv11,capabilities); + p = smb_buf(cli->outbuf); + memcpy(p,pword,passlen); p += passlen; + memcpy(p,ntpword,ntpasslen); p += ntpasslen; + p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + if (cli_is_error(cli)) { + return False; + } + + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); + + p = smb_buf(cli->inbuf); + p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); + + fstrcpy(cli->user_name, user); + + return True; +} + +#if HAVE_KRB5 +/**************************************************************************** +do a spnego encrypted session setup +****************************************************************************/ +static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, + char *pass, char *workgroup) +{ + uint32 capabilities = cli_session_setup_capabilities(cli); + char *p; + DATA_BLOB blob2, negTokenTarg; + + negTokenTarg = spnego_gen_negTokenTarg(cli); + + capabilities |= CAP_EXTENDED_SECURITY; + + /* send a session setup command */ + memset(cli->outbuf,'\0',smb_size); + + set_message(cli->outbuf,12,0,True); + CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,0); + SIVAL(cli->outbuf,smb_vwv5,0); + SSVAL(cli->outbuf,smb_vwv7,negTokenTarg.length); + SIVAL(cli->outbuf,smb_vwv10,capabilities); + p = smb_buf(cli->outbuf); + memcpy(p, negTokenTarg.data, negTokenTarg.length); + p += negTokenTarg.length; + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + if (cli_is_error(cli)) { + return False; + } + + /* use the returned vuid from now on */ + cli->vuid = SVAL(cli->inbuf,smb_uid); + + p = smb_buf(cli->inbuf); + + blob2 = data_blob(p, SVAL(cli->inbuf, smb_vwv3)); + + p += blob2.length; + p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); + + fstrcpy(cli->user_name, user); + + data_blob_free(negTokenTarg); + + /* we don't need this blob until we do NTLMSSP */ + data_blob_free(blob2); + + return True; +} +#endif + + /**************************************************************************** Send a session setup. The username and workgroup is in UNIX character format and must be converted to DOS codepage format before sending. If the password is in plaintext, the same should be done. ****************************************************************************/ - BOOL cli_session_setup(struct cli_state *cli, char *user, char *pass, int passlen, @@ -55,7 +397,6 @@ BOOL cli_session_setup(struct cli_state *cli, char *workgroup) { char *p; - fstring pword, ntpword; fstring user2; /* allow for workgroups as part of the username */ @@ -69,146 +410,45 @@ BOOL cli_session_setup(struct cli_state *cli, if (cli->protocol < PROTOCOL_LANMAN1) return True; - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { - return False; - } + /* now work out what sort of session setup we are going to + do. I have split this into separate functions to make the + flow a bit easier to understand (tridge) */ - if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) { - /* Null session connect. */ - pword[0] = '\0'; - ntpword[0] = '\0'; - } else { - if ((cli->sec_mode & 2) && passlen != 24) { - /* - * Encrypted mode needed, and non encrypted password supplied. - */ - passlen = 24; - ntpasslen = 24; - clistr_push(cli, pword, pass, -1, STR_TERMINATE); - fstrcpy(ntpword, ntpass);; - SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword); - SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword); - } else if ((cli->sec_mode & 2) && passlen == 24) { - /* - * Encrypted mode needed, and encrypted password supplied. - */ - memcpy(pword, pass, passlen); - if(ntpasslen == 24) { - memcpy(ntpword, ntpass, ntpasslen); - } else { - fstrcpy(ntpword, ""); - ntpasslen = 0; - } - } else { - /* - * Plaintext mode needed, assume plaintext supplied. - */ - passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); - fstrcpy(ntpword, ""); - ntpasslen = 0; - } + /* if its an older server then we have to use the older request format */ + if (cli->protocol < PROTOCOL_NT1) { + return cli_session_setup_lanman2(cli, user, pass, passlen); } - /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { - fstrcpy(pword, ""); - passlen=1; - fstrcpy(ntpword, ""); - ntpasslen=1; - } - - /* send a session setup command */ - memset(cli->outbuf,'\0',smb_size); - - if (cli->protocol < PROTOCOL_NT1) - { - set_message(cli->outbuf,10, 0, True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,1); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += passlen; - p += clistr_push(cli, p, user, -1, STR_UPPER|STR_TERMINATE); - cli_setup_bcc(cli, p); + /* if no user is supplied then we have to do an anonymous connection. + passwords are ignored */ + if (!user || !*user) { + return cli_session_setup_guest(cli); } - else - { - uint32 capabilities; - - capabilities = CAP_NT_SMBS; - /* Set the CLI_FORCE_DOSERR environment variable to test - client routines using DOS errors instead of STATUS32 - ones. This intended only as a temporary hack. */ - - if (!getenv("CLI_FORCE_DOSERR")) { - capabilities |= CAP_STATUS32; - } - - if (cli->use_level_II_oplocks) { - capabilities |= CAP_LEVEL_II_OPLOCKS; - } - if (cli->capabilities & CAP_UNICODE) { - capabilities |= CAP_UNICODE; - } - set_message(cli->outbuf,13,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; - cli_setup_packet(cli); - - CVAL(cli->outbuf,smb_vwv0) = 0xFF; - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - SSVAL(cli->outbuf,smb_vwv8,ntpasslen); - SIVAL(cli->outbuf,smb_vwv11,capabilities); - p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); - p += SVAL(cli->outbuf,smb_vwv7); - memcpy(p,ntpword,ntpasslen); - p += SVAL(cli->outbuf,smb_vwv8); - p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); - p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); - cli_setup_bcc(cli, p); - } - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - if (cli_is_error(cli)) { - return False; - } - - /* use the returned vuid from now on */ - cli->vuid = SVAL(cli->inbuf,smb_uid); + /* if the server is share level then send a plaintext null + password at this point. The password is sent in the tree + connect */ + if ((cli->sec_mode & 1) == 0) { + return cli_session_setup_plaintext(cli, user, "", workgroup); + } - if (cli->protocol >= PROTOCOL_NT1) { - /* - * Save off some of the connected server - * info. - */ - char *q = smb_buf(cli->inbuf); - q += clistr_pull(cli, cli->server_os, q, sizeof(fstring), -1, STR_TERMINATE); - q += clistr_pull(cli, cli->server_type, q, sizeof(fstring), -1, STR_TERMINATE); - q += clistr_pull(cli, cli->server_domain, q, sizeof(fstring), -1, STR_TERMINATE); - } + /* if the server doesn't support encryption then we have to use plaintext. The + second password is ignored */ + if ((cli->sec_mode & 2) == 0) { + return cli_session_setup_plaintext(cli, user, pass, workgroup); + } - fstrcpy(cli->user_name, user); +#if HAVE_KRB5 + /* if the server supports extended security then use SPNEGO */ + if (cli->capabilities & CAP_EXTENDED_SECURITY) { + return cli_session_setup_spnego(cli, user, pass, workgroup); + } +#endif - return True; + /* otherwise do a NT1 style session setup */ + return cli_session_setup_nt1(cli, user, + pass, passlen, ntpass, ntpasslen, + workgroup); } /**************************************************************************** @@ -256,8 +496,7 @@ BOOL cli_send_tconX(struct cli_state *cli, */ passlen = 24; clistr_push(cli, dos_pword, pass, -1, STR_TERMINATE); - - SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword); + SMBencrypt((uchar *)dos_pword,cli->secblob.data,(uchar *)pword); } else { if((cli->sec_mode & 3) == 0) { /* @@ -404,6 +643,11 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; + if (cli->use_spnego) { + SSVAL(cli->outbuf, smb_flg2, + SVAL(cli->outbuf, smb_flg2) | FLAGS2_EXTENDED_SECURITY); + } + cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; @@ -427,7 +671,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone *= 60; /* this time arrives in real GMT */ cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); if (cli->capabilities & CAP_RAW_MODE) { cli->readbraw_supported = True; @@ -449,7 +693,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); } else { /* the old core protocol */ cli->sec_mode = 0; @@ -481,7 +725,6 @@ BOOL cli_session_request(struct cli_state *cli, if (cli->port == 445) return True; /* send a session request (RFC 1002) */ - memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); @@ -758,7 +1001,7 @@ BOOL cli_establish_connection(struct cli_state *cli, unsigned char lm_sess_pwd[24]; /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey); + pwd_make_lm_nt_owf(&(cli->pwd), cli->secblob.data); pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); /* attempt encrypted session */ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 62b46a7904..b5eddd5644 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,6 +112,10 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_STATUS32) { flags2 |= FLAGS2_32_BIT_ERROR_CODES; } + if (cli->use_spnego) { + /* once we have NTLMSSP we can enable this unconditionally */ + flags2 |= FLAGS2_EXTENDED_SECURITY; + } SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -215,15 +219,17 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); + data_blob_free(cli->secblob); + if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); #ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); + if (cli->fd != -1) + sslutil_disconnect(cli->fd); #endif /* WITH_SSL */ if (cli->fd != -1) - close(cli->fd); + close(cli->fd); memset(cli, 0, sizeof(*cli)); } diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c new file mode 100644 index 0000000000..cd64dc8444 --- /dev/null +++ b/source3/libsmb/clikrb5.c @@ -0,0 +1,267 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + simple kerberos5/SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#if HAVE_KRB5 +#include + +#define OID_SPNEGO "1 3 6 1 5 5 2" +#define OID_KERBEROS5 "1 2 840 113554 1 2 2" + +static krb5_error_code krb5_mk_req2(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + const char *service, + krb5_data *in_data, + krb5_ccache ccache, + krb5_data *outbuf) +{ + krb5_error_code retval; + krb5_principal server; + krb5_creds * credsp; + krb5_creds creds; + char *realm; + + /* we should really get the realm from the negTargInit packet, + but this will do until I've done the asn1 decoder for that */ + if ((retval = krb5_get_default_realm(context, &realm))) { + return retval; + } + + retval = krb5_build_principal(context, &server, strlen(realm), + realm, service, NULL); + if (retval) + return retval; + + /* obtain ticket & session key */ + memset((char *)&creds, 0, sizeof(creds)); + if ((retval = krb5_copy_principal(context, server, &creds.server))) + goto cleanup_princ; + + if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) + goto cleanup_creds; + + if ((retval = krb5_get_credentials(context, 0, + ccache, &creds, &credsp))) + goto cleanup_creds; + + retval = krb5_mk_req_extended(context, auth_context, ap_req_options, + in_data, credsp, outbuf); + + krb5_free_creds(context, credsp); + +cleanup_creds: + krb5_free_cred_contents(context, &creds); + +cleanup_princ: + krb5_free_principal(context, server); + + return retval; +} + +/* + get a kerberos5 ticket for the given service +*/ +static DATA_BLOB krb5_get_ticket(char *service) +{ + krb5_error_code retval; + krb5_data packet, inbuf; + krb5_ccache ccdef; + krb5_context context; + krb5_auth_context auth_context = NULL; + DATA_BLOB ret; + + retval = krb5_init_context(&context); + if (retval) { + DEBUG(1,("krb5_init_context failed\n")); + goto failed; + } + + inbuf.length = 0; + + if ((retval = krb5_cc_default(context, &ccdef))) { + DEBUG(1,("krb5_cc_default failed\n")); + goto failed; + } + + if ((retval = krb5_mk_req2(context, + &auth_context, + AP_OPTS_MUTUAL_REQUIRED, + service, + &inbuf, ccdef, &packet))) { + DEBUG(1,("krb5_mk_req2 failed\n")); + goto failed; + } + + ret = data_blob(packet.data, packet.length); + /* XXX need to free up a bunch of krb5 stuff here */ + + return ret; + +failed: + return data_blob(NULL, 0); +} + + +/* + generate a negTokenInit packet given a GUID, a list of supported + OIDs (the mechanisms) and a principle name string +*/ +ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], + const char *OIDs[], + const char *principle) +{ + int i; + ASN1_DATA data; + + memset(&data, 0, sizeof(data)); + + asn1_write(&data, guid, 16); + asn1_push_tag(&data,ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + for (i=0; OIDs[i]; i++) { + asn1_write_OID(&data,OIDs[i]); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_write_GeneralString(&data,principle); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + asn1_check_empty(&data); + return data; +} + + +/* + generate a negTokenTarg packet given a list of OIDs and a security blob +*/ +static ASN1_DATA gen_negTokenTarg(const char *OIDs[], ASN1_DATA blob) +{ + int i; + ASN1_DATA data; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; OIDs[i]; i++) { + asn1_write_OID(&data,OIDs[i]); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + asn1_check_empty(&data); + return data; +} + + +/* + generate a krb5 GSS-API wrapper packet given a ticket +*/ +static ASN1_DATA spnego_gen_krb5_wrap(DATA_BLOB ticket) +{ + ASN1_DATA data; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data, OID_KERBEROS5); + asn1_write_BOOLEAN(&data, 0); + asn1_write(&data, ticket.data, ticket.length); + asn1_pop_tag(&data); + + return data; +} + + +/* + generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY + kerberos session setup +*/ +DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli) +{ + char *p; + fstring service; + DATA_BLOB tkt, ret; + ASN1_DATA tkt_wrapped, targ; + const char *krb_mechs[] = + {"1 2 840 48018 1 2 2", "1 3 6 1 4 1 311 2 2 10", NULL}; + + /* the service name is the WINS name of the server in lowercase with + a $ on the end */ + fstrcpy(service, cli->desthost); + p = strchr_m(service, '.'); + if (p) *p = 0; + fstrcat(service, "$"); + strlower(service); + + /* get a kerberos ticket for the service */ + tkt = krb5_get_ticket(service); + + /* wrap that up in a nice GSS-API wrapping */ + tkt_wrapped = spnego_gen_krb5_wrap(tkt); + + /* and wrap that in a shiny SPNEGO wrapper */ + targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); + + ret = data_blob(targ.data, targ.length); + + asn1_free(&tkt_wrapped); + asn1_free(&targ); + data_blob_free(tkt); + + return ret; +} + +#else /* HAVE_KRB5 */ + void clikrb5_dummy(void) {} +#endif -- cgit From 8edc45ec4c467e5069875808d0abd9452e7b056c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Oct 2001 10:29:17 +0000 Subject: fixed some memory leaks, started adding asn1 decoder for server side (This used to be commit 919734c1a6fd8b3bd0e12e96d878f47b6d6ff5e0) --- source3/libsmb/asn1.c | 44 ++++++++++++++++++++++++++++++++++++-------- source3/libsmb/clikrb5.c | 10 ++++++---- 2 files changed, 42 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 5735f372ca..e4c2d3af80 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -21,17 +21,13 @@ #include "includes.h" +/* free an asn1 structure */ void asn1_free(ASN1_DATA *data) { - free(data->data); -} - -BOOL asn1_check_empty(ASN1_DATA *data) -{ - if (data->nesting) return False; - return True; + SAFE_FREE(data->data); } +/* write to the ASN1 buffer, advancing the buffer pointer */ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->length < data->ofs+len) { @@ -44,11 +40,13 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) return True; } +/* useful fn for writing a uint8 */ BOOL asn1_write_uint8(ASN1_DATA *data, uint8 v) { return asn1_write(data, &v, 1); } +/* push a tag onto the asn1 data buffer. Used for nested structures */ BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) { struct nesting *nesting; @@ -64,6 +62,7 @@ BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) return True; } +/* pop a tag */ BOOL asn1_pop_tag(ASN1_DATA *data) { struct nesting *nesting; @@ -75,6 +74,9 @@ BOOL asn1_pop_tag(ASN1_DATA *data) return False; } len = data->ofs - (nesting->start+1); + /* yes, this is ugly. We don't know in advance how many bytes the length + of a tag will take, so we assumed 1 byte. If we were wrong then we + need to correct our mistake */ if (len > 127) { data->data[nesting->start] = 0x82; asn1_write_uint8(data, 0); @@ -91,7 +93,7 @@ BOOL asn1_pop_tag(ASN1_DATA *data) return True; } - +/* write an object ID to a ASN1 buffer */ BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) { unsigned v, v2; @@ -114,6 +116,7 @@ BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) return True; } +/* write an octet string */ BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) { asn1_push_tag(data, ASN1_OCTET_STRING); @@ -122,6 +125,7 @@ BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) return True; } +/* write a general string */ BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) { asn1_push_tag(data, ASN1_GENERAL_STRING); @@ -130,6 +134,7 @@ BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) return True; } +/* write a BOOLEAN */ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) { asn1_write_uint8(data, ASN1_BOOLEAN); @@ -137,3 +142,26 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) return True; } + +/* load a ASN1_DATA structure with a lump of data, ready to be parsed */ +BOOL asn1_load(ASN1_DATA *data, void *p, size_t length) +{ + ZERO_STRUCTP(data); + data->data = memdup(p, length); + if (!data->data) return False; + data->length = length; + return True; +} + +/* read from a ASN1 buffer, advancing the buffer pointer */ +BOOL asn1_read(ASN1_DATA *data, void *p, int len) +{ + if (data->ofs + len > data->length) { + return False; + } + memcpy(p, data->data + data->ofs, len); + data->ofs += len; + return True; +} + + diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index cd64dc8444..0e049c14a1 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -27,6 +27,9 @@ #define OID_SPNEGO "1 3 6 1 5 5 2" #define OID_KERBEROS5 "1 2 840 113554 1 2 2" +/* + we can't use krb5_mk_req because w2k wants the service to be in a particular format +*/ static krb5_error_code krb5_mk_req2(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, @@ -113,11 +116,12 @@ static DATA_BLOB krb5_get_ticket(char *service) } ret = data_blob(packet.data, packet.length); - /* XXX need to free up a bunch of krb5 stuff here */ - + krb5_free_data_contents(context, &packet); + krb5_free_context(context); return ret; failed: + krb5_free_context(context); return data_blob(NULL, 0); } @@ -162,7 +166,6 @@ ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], asn1_pop_tag(&data); - asn1_check_empty(&data); return data; } @@ -199,7 +202,6 @@ static ASN1_DATA gen_negTokenTarg(const char *OIDs[], ASN1_DATA blob) asn1_pop_tag(&data); - asn1_check_empty(&data); return data; } -- cgit From 7cd9c611e2a1e0028081863a3678c47bc8af7b55 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Oct 2001 13:13:06 +0000 Subject: added a ASN.1 parser, so now I can properly parse the negTokenInit packet which means I can extract the service and realm, so we should now work with realms other than the local realm. it also means we now check the list of OIDs given by the server just in case it says that it doesn't support kerberos. In that case we should fall back to NTLMSSP but that isn't written yet. (This used to be commit 395cfeea94febb5280ea57027e8a8a3c7c3f9291) --- source3/libsmb/asn1.c | 186 +++++++++++++++++++++++++++++++++++++++----- source3/libsmb/cliconnect.c | 33 +++++++- source3/libsmb/clikrb5.c | 179 ++++++++++++++++++++++++++++-------------- 3 files changed, 320 insertions(+), 78 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index e4c2d3af80..17b1ee1089 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -30,9 +30,13 @@ void asn1_free(ASN1_DATA *data) /* write to the ASN1 buffer, advancing the buffer pointer */ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { + if (data->has_error) return False; if (data->length < data->ofs+len) { data->data = Realloc(data->data, data->ofs+len); - if (!data->data) return False; + if (!data->data) { + data->has_error = True; + return False; + } data->length = data->ofs+len; } memcpy(data->data + data->ofs, p, len); @@ -53,13 +57,15 @@ BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) asn1_write_uint8(data, tag); nesting = (struct nesting *)malloc(sizeof(struct nesting)); - if (!nesting) return False; + if (!nesting) { + data->has_error = True; + return False; + } nesting->start = data->ofs; nesting->next = data->nesting; data->nesting = nesting; - asn1_write_uint8(data, 0xff); - return True; + return asn1_write_uint8(data, 0xff); } /* pop a tag */ @@ -71,6 +77,7 @@ BOOL asn1_pop_tag(ASN1_DATA *data) nesting = data->nesting; if (!nesting) { + data->has_error = True; return False; } len = data->ofs - (nesting->start+1); @@ -79,8 +86,8 @@ BOOL asn1_pop_tag(ASN1_DATA *data) need to correct our mistake */ if (len > 127) { data->data[nesting->start] = 0x82; - asn1_write_uint8(data, 0); - asn1_write_uint8(data, 0); + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); data->data[nesting->start+1] = len>>8; data->data[nesting->start+2] = len&0xff; @@ -99,10 +106,10 @@ BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) unsigned v, v2; char *p = (char *)OID; - asn1_push_tag(data, ASN1_OID); + if (!asn1_push_tag(data, ASN1_OID)) return False; v = strtol(p, &p, 10); v2 = strtol(p, &p, 10); - asn1_write_uint8(data, 40*v + v2); + if (!asn1_write_uint8(data, 40*v + v2)) return False; while (*p) { v = strtol(p, &p, 10); @@ -110,10 +117,9 @@ BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) if (v >= (1<<21)) asn1_write_uint8(data, 0x80 | ((v>>21)&0xff)); if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff)); if (v >= (1<<7)) asn1_write_uint8(data, 0x80 | ((v>>7)&0xff)); - asn1_write_uint8(data, v&0x7f); + if (!asn1_write_uint8(data, v&0x7f)) return False; } - asn1_pop_tag(data); - return True; + return asn1_pop_tag(data); } /* write an octet string */ @@ -122,7 +128,7 @@ BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) asn1_push_tag(data, ASN1_OCTET_STRING); asn1_write(data, p, length); asn1_pop_tag(data); - return True; + return !data->has_error; } /* write a general string */ @@ -131,7 +137,7 @@ BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) asn1_push_tag(data, ASN1_GENERAL_STRING); asn1_write(data, s, strlen(s)); asn1_pop_tag(data); - return True; + return !data->has_error; } /* write a BOOLEAN */ @@ -139,17 +145,20 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) { asn1_write_uint8(data, ASN1_BOOLEAN); asn1_write_uint8(data, v); - return True; + return !data->has_error; } /* load a ASN1_DATA structure with a lump of data, ready to be parsed */ -BOOL asn1_load(ASN1_DATA *data, void *p, size_t length) +BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) { ZERO_STRUCTP(data); - data->data = memdup(p, length); - if (!data->data) return False; - data->length = length; + data->data = memdup(blob.data, blob.length); + if (!data->data) { + data->has_error = True; + return False; + } + data->length = blob.length; return True; } @@ -157,6 +166,7 @@ BOOL asn1_load(ASN1_DATA *data, void *p, size_t length) BOOL asn1_read(ASN1_DATA *data, void *p, int len) { if (data->ofs + len > data->length) { + data->has_error = True; return False; } memcpy(p, data->data + data->ofs, len); @@ -164,4 +174,144 @@ BOOL asn1_read(ASN1_DATA *data, void *p, int len) return True; } +/* read a uint8 from a ASN1 buffer */ +BOOL asn1_read_uint8(ASN1_DATA *data, uint8 *v) +{ + return asn1_read(data, v, 1); +} +/* start reading a nested asn1 structure */ +BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) +{ + uint8 b; + struct nesting *nesting; + + asn1_read_uint8(data, &b); + if (b != tag) { + data->has_error = True; + return False; + } + nesting = (struct nesting *)malloc(sizeof(struct nesting)); + if (!nesting) { + data->has_error = True; + return False; + } + + asn1_read_uint8(data, &b); + if (b & 0x80) { + int n = b & 0x7f; + if (n != 2) { + data->has_error = True; + return False; + } + asn1_read_uint8(data, &b); + nesting->taglen = b<<8; + asn1_read_uint8(data, &b); + nesting->taglen |= b; + } else { + nesting->taglen = b; + } + nesting->start = data->ofs; + nesting->next = data->nesting; + data->nesting = nesting; + return !data->has_error; +} + + +/* stop reading a tag */ +BOOL asn1_end_tag(ASN1_DATA *data) +{ + struct nesting *nesting; + + /* make sure we read it all */ + if (asn1_tag_remaining(data) != 0) { + data->has_error = True; + return False; + } + + nesting = data->nesting; + + if (!nesting) { + data->has_error = True; + return False; + } + + data->nesting = nesting->next; + free(nesting); + return True; +} + +/* work out how many bytes are left in this nested tag */ +int asn1_tag_remaining(ASN1_DATA *data) +{ + if (!data->nesting) { + data->has_error = True; + return -1; + } + return data->nesting->taglen - (data->ofs - data->nesting->start); +} + +/* read an object ID from a ASN1 buffer */ +BOOL asn1_read_OID(ASN1_DATA *data, char **OID) +{ + uint8 b; + pstring oid; + fstring el; + + if (!asn1_start_tag(data, ASN1_OID)) return False; + asn1_read_uint8(data, &b); + + oid[0] = 0; + snprintf(el, sizeof(el), "%u", b/40); + pstrcat(oid, el); + snprintf(el, sizeof(el), " %u", b%40); + pstrcat(oid, el); + + while (asn1_tag_remaining(data) > 0) { + unsigned v = 0; + do { + asn1_read_uint8(data, &b); + v = (v<<7) | (b&0x7f); + } while (!data->has_error && b & 0x80); + snprintf(el, sizeof(el), " %u", v); + pstrcat(oid, el); + } + + asn1_end_tag(data); + + *OID = strdup(oid); + + return !data->has_error; +} + +/* check that the next object ID is correct */ +BOOL asn1_check_OID(ASN1_DATA *data, char *OID) +{ + char *id; + + if (!asn1_read_OID(data, &id)) return False; + + if (strcmp(id, OID) != 0) { + data->has_error = True; + return False; + } + free(id); + return True; +} + +/* read a GeneralString from a ASN1 buffer */ +BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) +{ + int len; + if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; + len = asn1_tag_remaining(data); + *s = malloc(len+1); + if (! *s) { + data->has_error = True; + return False; + } + asn1_read(data, *s, len); + (*s)[len] = 0; + asn1_end_tag(data); + return !data->has_error; +} diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 77a8232ed5..36aedf2d59 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -325,8 +325,39 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, uint32 capabilities = cli_session_setup_capabilities(cli); char *p; DATA_BLOB blob2, negTokenTarg; + char *principle; + char *OIDs[ASN1_MAX_OIDS]; + uint8 guid[16]; + int i; + BOOL got_kerberos_mechanism = False; + + /* the server sent us the first part of the SPNEGO exchange in the negprot + reply */ + if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principle)) { + return False; + } + + /* make sure the server understands kerberos */ + for (i=0;OIDs[i];i++) { + DEBUG(3,("got OID=%s\n", OIDs[i])); + if (strcmp(OIDs[i], "1 2 840 48018 1 2 2") == 0) { + got_kerberos_mechanism = True; + } + free(OIDs[i]); + } + DEBUG(3,("got principle=%s\n", principle)); + + if (!got_kerberos_mechanism) { + DEBUG(1,("Server didn't offer kerberos5 mechanism!?\n")); + return False; + } + + /* generate the encapsulated kerberos5 ticket */ + negTokenTarg = spnego_gen_negTokenTarg(cli, principle); + + free(principle); - negTokenTarg = spnego_gen_negTokenTarg(cli); + if (!negTokenTarg.data) return False; capabilities |= CAP_EXTENDED_SECURITY; diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 0e049c14a1..fb442f7f09 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -27,6 +27,8 @@ #define OID_SPNEGO "1 3 6 1 5 5 2" #define OID_KERBEROS5 "1 2 840 113554 1 2 2" +#define CHECK_CALL(x) if (! x) goto failed + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ @@ -34,60 +36,62 @@ static krb5_error_code krb5_mk_req2(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, const char *service, - krb5_data *in_data, + const char *realm, krb5_ccache ccache, krb5_data *outbuf) { - krb5_error_code retval; - krb5_principal server; - krb5_creds * credsp; - krb5_creds creds; - char *realm; - - /* we should really get the realm from the negTargInit packet, - but this will do until I've done the asn1 decoder for that */ - if ((retval = krb5_get_default_realm(context, &realm))) { - return retval; - } - - retval = krb5_build_principal(context, &server, strlen(realm), - realm, service, NULL); - if (retval) - return retval; - - /* obtain ticket & session key */ - memset((char *)&creds, 0, sizeof(creds)); - if ((retval = krb5_copy_principal(context, server, &creds.server))) - goto cleanup_princ; - - if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) - goto cleanup_creds; - - if ((retval = krb5_get_credentials(context, 0, - ccache, &creds, &credsp))) - goto cleanup_creds; - - retval = krb5_mk_req_extended(context, auth_context, ap_req_options, - in_data, credsp, outbuf); + krb5_error_code retval; + krb5_principal server; + krb5_creds * credsp; + krb5_creds creds; + krb5_data in_data; + + retval = krb5_build_principal(context, &server, strlen(realm), + realm, service, NULL); + if (retval) { + DEBUG(1,("Failed to build principle for %s@%s\n", service, realm)); + return retval; + } + + /* obtain ticket & session key */ + memset((char *)&creds, 0, sizeof(creds)); + if ((retval = krb5_copy_principal(context, server, &creds.server))) + goto cleanup_princ; + + if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) + goto cleanup_creds; + + if ((retval = krb5_get_credentials(context, 0, + ccache, &creds, &credsp))) { + DEBUG(1,("krb5_get_credentials failed (%d)\n", retval)); + goto cleanup_creds; + } - krb5_free_creds(context, credsp); + in_data.length = 0; + retval = krb5_mk_req_extended(context, auth_context, ap_req_options, + &in_data, credsp, outbuf); + if (retval) { + DEBUG(1,("krb5_mk_req_extended failed (%d)\n", retval)); + } + + krb5_free_creds(context, credsp); cleanup_creds: - krb5_free_cred_contents(context, &creds); + krb5_free_cred_contents(context, &creds); cleanup_princ: - krb5_free_principal(context, server); + krb5_free_principal(context, server); - return retval; + return retval; } /* get a kerberos5 ticket for the given service */ -static DATA_BLOB krb5_get_ticket(char *service) +static DATA_BLOB krb5_get_ticket(char *service, char *realm) { krb5_error_code retval; - krb5_data packet, inbuf; + krb5_data packet; krb5_ccache ccdef; krb5_context context; krb5_auth_context auth_context = NULL; @@ -99,8 +103,6 @@ static DATA_BLOB krb5_get_ticket(char *service) goto failed; } - inbuf.length = 0; - if ((retval = krb5_cc_default(context, &ccdef))) { DEBUG(1,("krb5_cc_default failed\n")); goto failed; @@ -109,8 +111,8 @@ static DATA_BLOB krb5_get_ticket(char *service) if ((retval = krb5_mk_req2(context, &auth_context, AP_OPTS_MUTUAL_REQUIRED, - service, - &inbuf, ccdef, &packet))) { + service, realm, + ccdef, &packet))) { DEBUG(1,("krb5_mk_req2 failed\n")); goto failed; } @@ -139,16 +141,16 @@ ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], memset(&data, 0, sizeof(data)); - asn1_write(&data, guid, 16); - asn1_push_tag(&data,ASN1_APPLICATION(0)); - asn1_write_OID(&data,OID_SPNEGO); - asn1_push_tag(&data,ASN1_CONTEXT(0)); - asn1_push_tag(&data,ASN1_SEQUENCE(0)); + CHECK_CALL(asn1_write(&data, guid, 16)); + CHECK_CALL(asn1_push_tag(&data,ASN1_APPLICATION(0))); + CHECK_CALL(asn1_write_OID(&data,OID_SPNEGO)); + CHECK_CALL(asn1_push_tag(&data,ASN1_CONTEXT(0))); + CHECK_CALL(asn1_push_tag(&data,ASN1_SEQUENCE(0))); - asn1_push_tag(&data,ASN1_CONTEXT(0)); - asn1_push_tag(&data,ASN1_SEQUENCE(0)); + CHECK_CALL(asn1_push_tag(&data,ASN1_CONTEXT(0))); + CHECK_CALL(asn1_push_tag(&data,ASN1_SEQUENCE(0))); for (i=0; OIDs[i]; i++) { - asn1_write_OID(&data,OIDs[i]); + CHECK_CALL(asn1_write_OID(&data,OIDs[i])); } asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -167,6 +169,62 @@ ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], asn1_pop_tag(&data); return data; + +failed: + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + return data; +} + + +/* + parse a negTokenInit packet giving a GUID, a list of supported + OIDs (the mechanisms) and a principle name string +*/ +BOOL spnego_parse_negTokenInit(DATA_BLOB blob, + uint8 guid[16], + char *OIDs[ASN1_MAX_OIDS], + char **principle) +{ + int i; + BOOL ret; + ASN1_DATA data; + + asn1_load(&data, blob); + + asn1_read(&data, guid, 16); + asn1_start_tag(&data,ASN1_APPLICATION(0)); + asn1_check_OID(&data,OID_SPNEGO); + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + char *oid = NULL; + asn1_read_OID(&data,&oid); + OIDs[i] = oid; + } + OIDs[i] = NULL; + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_start_tag(&data, ASN1_CONTEXT(3)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_GeneralString(&data,principle); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + + ret = !data.has_error; + asn1_free(&data); + return ret; } @@ -229,25 +287,28 @@ static ASN1_DATA spnego_gen_krb5_wrap(DATA_BLOB ticket) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli) +DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) { char *p; fstring service; + char *realm; DATA_BLOB tkt, ret; ASN1_DATA tkt_wrapped, targ; const char *krb_mechs[] = {"1 2 840 48018 1 2 2", "1 3 6 1 4 1 311 2 2 10", NULL}; - /* the service name is the WINS name of the server in lowercase with - a $ on the end */ - fstrcpy(service, cli->desthost); - p = strchr_m(service, '.'); - if (p) *p = 0; - fstrcat(service, "$"); - strlower(service); + fstrcpy(service, principle); + p = strchr_m(service, '@'); + if (!p) { + DEBUG(1,("Malformed principle [%s] in spnego_gen_negTokenTarg\n", + principle)); + return data_blob(NULL, 0); + } + *p = 0; + realm = p+1; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(service); + tkt = krb5_get_ticket(service, realm); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); -- cgit From 2b09ef2a2d8a94fb146a17a50604f0e0081fe09d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Oct 2001 13:49:08 +0000 Subject: improve the error handling in the ASN1 code a bit (This used to be commit 8b692d8326a1548a7dbbd2cecee9ece6aa60473a) --- source3/libsmb/clikrb5.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index fb442f7f09..b4847e4c2a 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -27,8 +27,6 @@ #define OID_SPNEGO "1 3 6 1 5 5 2" #define OID_KERBEROS5 "1 2 840 113554 1 2 2" -#define CHECK_CALL(x) if (! x) goto failed - /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ @@ -141,16 +139,16 @@ ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], memset(&data, 0, sizeof(data)); - CHECK_CALL(asn1_write(&data, guid, 16)); - CHECK_CALL(asn1_push_tag(&data,ASN1_APPLICATION(0))); - CHECK_CALL(asn1_write_OID(&data,OID_SPNEGO)); - CHECK_CALL(asn1_push_tag(&data,ASN1_CONTEXT(0))); - CHECK_CALL(asn1_push_tag(&data,ASN1_SEQUENCE(0))); + asn1_write(&data, guid, 16); + asn1_push_tag(&data,ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); - CHECK_CALL(asn1_push_tag(&data,ASN1_CONTEXT(0))); - CHECK_CALL(asn1_push_tag(&data,ASN1_SEQUENCE(0))); + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); for (i=0; OIDs[i]; i++) { - CHECK_CALL(asn1_write_OID(&data,OIDs[i])); + asn1_write_OID(&data,OIDs[i]); } asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -168,11 +166,11 @@ ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], asn1_pop_tag(&data); - return data; + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } -failed: - DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); - asn1_free(&data); return data; } @@ -260,6 +258,11 @@ static ASN1_DATA gen_negTokenTarg(const char *OIDs[], ASN1_DATA blob) asn1_pop_tag(&data); + if (data.has_error) { + DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + return data; } @@ -279,6 +282,11 @@ static ASN1_DATA spnego_gen_krb5_wrap(DATA_BLOB ticket) asn1_write(&data, ticket.data, ticket.length); asn1_pop_tag(&data); + if (data.has_error) { + DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + return data; } -- cgit From 9f7cb41f11c0d2fc09104f6998f75c59bc363b26 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Oct 2001 04:49:42 +0000 Subject: added NTLMSSP authentication to libsmb. It seems to work well so I have enabled it by default if the server supports it. Let me know if this breaks anything. Choose kerberos with the -k flag to smbclient, otherwise it will use SPNEGO/NTLMSSP/NTLM (This used to be commit 076aa97bee54d182288d9e93ae160ae22a5f7757) --- source3/libsmb/asn1.c | 27 +++ source3/libsmb/cliconnect.c | 206 +++++++++++++++++------ source3/libsmb/clientgen.c | 5 +- source3/libsmb/clikrb5.c | 221 +------------------------ source3/libsmb/clispnego.c | 395 ++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 585 insertions(+), 269 deletions(-) create mode 100644 source3/libsmb/clispnego.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 17b1ee1089..6a92a6be00 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -315,3 +315,30 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) asn1_end_tag(data); return !data->has_error; } + +/* read a octet string blob */ +BOOL asn1_read_octet_string(ASN1_DATA *data, DATA_BLOB *blob) +{ + int len; + if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; + len = asn1_tag_remaining(data); + blob->data = malloc(len); + if (!blob->data) { + data->has_error = True; + return False; + } + asn1_read(data, blob->data, len); + blob->length = len; + asn1_end_tag(data); + return !data->has_error; +} + +/* check a enumarted value is correct */ +BOOL asn1_check_enumerated(ASN1_DATA *data, int v) +{ + uint8 b; + if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; + asn1_read_uint8(data, &b); + asn1_end_tag(data); + return !data->has_error && (v == b); +} diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 36aedf2d59..11852a09cc 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -34,6 +34,7 @@ prots[] = {PROTOCOL_LANMAN1,"LANMAN1.0"}, {PROTOCOL_LANMAN1,"Windows for Workgroups 3.1a"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_NT1,"Samba"}, {PROTOCOL_NT1,"LANMAN2.1"}, {PROTOCOL_NT1,"NT LM 0.12"}, {-1,NULL} @@ -315,49 +316,17 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, return True; } -#if HAVE_KRB5 + /**************************************************************************** -do a spnego encrypted session setup +send a extended security session setup blob, returning a reply blob ****************************************************************************/ -static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, - char *pass, char *workgroup) +static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; - DATA_BLOB blob2, negTokenTarg; - char *principle; - char *OIDs[ASN1_MAX_OIDS]; - uint8 guid[16]; - int i; - BOOL got_kerberos_mechanism = False; - - /* the server sent us the first part of the SPNEGO exchange in the negprot - reply */ - if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principle)) { - return False; - } - - /* make sure the server understands kerberos */ - for (i=0;OIDs[i];i++) { - DEBUG(3,("got OID=%s\n", OIDs[i])); - if (strcmp(OIDs[i], "1 2 840 48018 1 2 2") == 0) { - got_kerberos_mechanism = True; - } - free(OIDs[i]); - } - DEBUG(3,("got principle=%s\n", principle)); - - if (!got_kerberos_mechanism) { - DEBUG(1,("Server didn't offer kerberos5 mechanism!?\n")); - return False; - } - - /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(cli, principle); - - free(principle); + DATA_BLOB blob2; - if (!negTokenTarg.data) return False; + blob2 = data_blob(NULL, 0); capabilities |= CAP_EXTENDED_SECURITY; @@ -373,23 +342,24 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,0); SIVAL(cli->outbuf,smb_vwv5,0); - SSVAL(cli->outbuf,smb_vwv7,negTokenTarg.length); + SSVAL(cli->outbuf,smb_vwv7,blob.length); SIVAL(cli->outbuf,smb_vwv10,capabilities); p = smb_buf(cli->outbuf); - memcpy(p, negTokenTarg.data, negTokenTarg.length); - p += negTokenTarg.length; + memcpy(p, blob.data, blob.length); + p += blob.length; p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) - return False; + return blob2; show_msg(cli->inbuf); - if (cli_is_error(cli)) { - return False; + if (cli_is_error(cli) && !NT_STATUS_EQUAL(cli_nt_error(cli), + NT_STATUS_MORE_PROCESSING_REQUIRED)) { + return blob2; } /* use the returned vuid from now on */ @@ -404,17 +374,154 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); - fstrcpy(cli->user_name, user); + return blob2; +} - data_blob_free(negTokenTarg); - /* we don't need this blob until we do NTLMSSP */ +#if HAVE_KRB5 +/**************************************************************************** +do a spnego/kerberos encrypted session setup +****************************************************************************/ +static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principle, char *workgroup) +{ + DATA_BLOB blob2, negTokenTarg; + + /* generate the encapsulated kerberos5 ticket */ + negTokenTarg = spnego_gen_negTokenTarg(cli, principle); + + if (!negTokenTarg.data) return False; + + blob2 = cli_session_setup_blob(cli, negTokenTarg); + + /* we don't need this blob for kerberos */ data_blob_free(blob2); - return True; + return !cli_is_error(cli); } #endif +/**************************************************************************** +do a spnego/NTLMSSP encrypted session setup +****************************************************************************/ +static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, + char *pass, char *workgroup) +{ + const char *mechs[] = {"1 3 6 1 4 1 311 2 2 10", NULL}; + DATA_BLOB msg1; + DATA_BLOB blob, chal1, chal2, auth; + uint8 challenge[8]; + uint8 nthash[24], lmhash[24], sess_key[16]; + uint32 neg_flags; + + neg_flags = NTLMSSP_NEGOTIATE_UNICODE | + NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_NTLM; + + memset(sess_key, 0, 16); + + /* generate the ntlmssp negotiate packet */ + msrpc_gen(&blob, "CddB", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + neg_flags, + sess_key, 16); + + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenTarg(mechs, blob); + data_blob_free(blob); + + /* now send that blob on its way */ + blob = cli_session_setup_blob(cli, msg1); + + data_blob_free(msg1); + + if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) { + return False; + } + + /* the server gives us back two challenges */ + if (!spnego_parse_challenge(blob, &chal1, &chal2)) { + return False; + } + + data_blob_free(blob); + + /* encrypt the password with the challenge */ + memcpy(challenge, chal1.data + 24, 8); + SMBencrypt(pass, challenge,lmhash); + SMBNTencrypt(pass, challenge,nthash); + + data_blob_free(chal1); + data_blob_free(chal2); + + /* this generates the actual auth packet */ + msrpc_gen(&blob, "CdBBUUUBd", + "NTLMSSP", + NTLMSSP_AUTH, + lmhash, 24, + nthash, 24, + workgroup, + user, + cli->calling.name, + sess_key, 16, + neg_flags); + + /* wrap it in SPNEGO */ + auth = spnego_gen_auth(blob); + + data_blob_free(blob); + + /* now send the auth packet and we should be done */ + blob = cli_session_setup_blob(cli, auth); + + data_blob_free(auth); + data_blob_free(blob); + + return !cli_is_error(cli); +} + + +/**************************************************************************** +do a spnego encrypted session setup +****************************************************************************/ +static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, + char *pass, char *workgroup) +{ + char *principle; + char *OIDs[ASN1_MAX_OIDS]; + uint8 guid[16]; + int i; + BOOL got_kerberos_mechanism = False; + + /* the server sent us the first part of the SPNEGO exchange in the negprot + reply */ + if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principle)) { + return False; + } + + /* make sure the server understands kerberos */ + for (i=0;OIDs[i];i++) { + DEBUG(3,("got OID=%s\n", OIDs[i])); + if (strcmp(OIDs[i], "1 2 840 48018 1 2 2") == 0) { + got_kerberos_mechanism = True; + } + free(OIDs[i]); + } + DEBUG(3,("got principle=%s\n", principle)); + + fstrcpy(cli->user_name, user); + +#if HAVE_KRB5 + if (got_kerberos_mechanism && cli->use_kerberos) { + return cli_session_setup_kerberos(cli, principle, workgroup); + } +#endif + + free(principle); + + return cli_session_setup_ntlmssp(cli, user, pass, workgroup); +} + /**************************************************************************** Send a session setup. The username and workgroup is in UNIX character @@ -674,11 +781,6 @@ BOOL cli_negprot(struct cli_state *cli) CVAL(smb_buf(cli->outbuf),0) = 2; - if (cli->use_spnego) { - SSVAL(cli->outbuf, smb_flg2, - SVAL(cli->outbuf, smb_flg2) | FLAGS2_EXTENDED_SECURITY); - } - cli_send_smb(cli); if (!cli_receive_smb(cli)) return False; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b5eddd5644..25dc070024 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,10 +112,7 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_STATUS32) { flags2 |= FLAGS2_32_BIT_ERROR_CODES; } - if (cli->use_spnego) { - /* once we have NTLMSSP we can enable this unconditionally */ - flags2 |= FLAGS2_EXTENDED_SECURITY; - } + flags2 |= FLAGS2_EXTENDED_SECURITY; SSVAL(cli->outbuf,smb_flg2, flags2); } } diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index b4847e4c2a..59a547b171 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1,7 +1,7 @@ /* Unix SMB/Netbios implementation. Version 3.0 - simple kerberos5/SPNEGO routines + simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 This program is free software; you can redistribute it and/or modify @@ -24,9 +24,6 @@ #if HAVE_KRB5 #include -#define OID_SPNEGO "1 3 6 1 5 5 2" -#define OID_KERBEROS5 "1 2 840 113554 1 2 2" - /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ @@ -86,7 +83,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -static DATA_BLOB krb5_get_ticket(char *service, char *realm) +DATA_BLOB krb5_get_ticket(char *service, char *realm) { krb5_error_code retval; krb5_data packet; @@ -126,213 +123,11 @@ failed: } -/* - generate a negTokenInit packet given a GUID, a list of supported - OIDs (the mechanisms) and a principle name string -*/ -ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], - const char *OIDs[], - const char *principle) -{ - int i; - ASN1_DATA data; - - memset(&data, 0, sizeof(data)); - - asn1_write(&data, guid, 16); - asn1_push_tag(&data,ASN1_APPLICATION(0)); - asn1_write_OID(&data,OID_SPNEGO); - asn1_push_tag(&data,ASN1_CONTEXT(0)); - asn1_push_tag(&data,ASN1_SEQUENCE(0)); - - asn1_push_tag(&data,ASN1_CONTEXT(0)); - asn1_push_tag(&data,ASN1_SEQUENCE(0)); - for (i=0; OIDs[i]; i++) { - asn1_write_OID(&data,OIDs[i]); - } - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_push_tag(&data, ASN1_CONTEXT(3)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_GeneralString(&data,principle); - asn1_pop_tag(&data); - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); - asn1_free(&data); - } - - return data; -} - - -/* - parse a negTokenInit packet giving a GUID, a list of supported - OIDs (the mechanisms) and a principle name string -*/ -BOOL spnego_parse_negTokenInit(DATA_BLOB blob, - uint8 guid[16], - char *OIDs[ASN1_MAX_OIDS], - char **principle) -{ - int i; - BOOL ret; - ASN1_DATA data; - - asn1_load(&data, blob); - - asn1_read(&data, guid, 16); - asn1_start_tag(&data,ASN1_APPLICATION(0)); - asn1_check_OID(&data,OID_SPNEGO); - asn1_start_tag(&data,ASN1_CONTEXT(0)); - asn1_start_tag(&data,ASN1_SEQUENCE(0)); - - asn1_start_tag(&data,ASN1_CONTEXT(0)); - asn1_start_tag(&data,ASN1_SEQUENCE(0)); - for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *oid = NULL; - asn1_read_OID(&data,&oid); - OIDs[i] = oid; - } - OIDs[i] = NULL; - asn1_end_tag(&data); - asn1_end_tag(&data); - - asn1_start_tag(&data, ASN1_CONTEXT(3)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(&data,principle); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_end_tag(&data); - - asn1_end_tag(&data); - asn1_end_tag(&data); - - asn1_end_tag(&data); - - ret = !data.has_error; - asn1_free(&data); - return ret; -} - - -/* - generate a negTokenTarg packet given a list of OIDs and a security blob -*/ -static ASN1_DATA gen_negTokenTarg(const char *OIDs[], ASN1_DATA blob) -{ - int i; - ASN1_DATA data; - - memset(&data, 0, sizeof(data)); - - asn1_push_tag(&data, ASN1_APPLICATION(0)); - asn1_write_OID(&data,OID_SPNEGO); - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - - asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_push_tag(&data, ASN1_SEQUENCE(0)); - for (i=0; OIDs[i]; i++) { - asn1_write_OID(&data,OIDs[i]); - } - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_push_tag(&data, ASN1_CONTEXT(2)); - asn1_write_OctetString(&data,blob.data,blob.length); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - asn1_pop_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data.ofs)); - asn1_free(&data); - } - - return data; -} - - -/* - generate a krb5 GSS-API wrapper packet given a ticket -*/ -static ASN1_DATA spnego_gen_krb5_wrap(DATA_BLOB ticket) -{ - ASN1_DATA data; - - memset(&data, 0, sizeof(data)); - - asn1_push_tag(&data, ASN1_APPLICATION(0)); - asn1_write_OID(&data, OID_KERBEROS5); - asn1_write_BOOLEAN(&data, 0); - asn1_write(&data, ticket.data, ticket.length); - asn1_pop_tag(&data); - - if (data.has_error) { - DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs)); - asn1_free(&data); - } - - return data; -} - - -/* - generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY - kerberos session setup -*/ -DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) -{ - char *p; - fstring service; - char *realm; - DATA_BLOB tkt, ret; - ASN1_DATA tkt_wrapped, targ; - const char *krb_mechs[] = - {"1 2 840 48018 1 2 2", "1 3 6 1 4 1 311 2 2 10", NULL}; - - fstrcpy(service, principle); - p = strchr_m(service, '@'); - if (!p) { - DEBUG(1,("Malformed principle [%s] in spnego_gen_negTokenTarg\n", - principle)); - return data_blob(NULL, 0); - } - *p = 0; - realm = p+1; - - /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(service, realm); - - /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt); - - /* and wrap that in a shiny SPNEGO wrapper */ - targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); - - ret = data_blob(targ.data, targ.length); - - asn1_free(&tkt_wrapped); - asn1_free(&targ); - data_blob_free(tkt); - - return ret; -} - #else /* HAVE_KRB5 */ - void clikrb5_dummy(void) {} + /* this saves a few linking headaches */ + DATA_BLOB krb5_get_ticket(char *service, char *realm) + { + DEBUG(0,("NO KERBEROS SUPPORT\n")); + return data_blob(NULL, 0); + } #endif diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c new file mode 100644 index 0000000000..6c6b18a923 --- /dev/null +++ b/source3/libsmb/clispnego.c @@ -0,0 +1,395 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + simple kerberos5/SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#define OID_SPNEGO "1 3 6 1 5 5 2" +#define OID_KERBEROS5 "1 2 840 113554 1 2 2" + +/* + generate a negTokenInit packet given a GUID, a list of supported + OIDs (the mechanisms) and a principle name string +*/ +ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], + const char *OIDs[], + const char *principle) +{ + int i; + ASN1_DATA data; + + memset(&data, 0, sizeof(data)); + + asn1_write(&data, guid, 16); + asn1_push_tag(&data,ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + for (i=0; OIDs[i]; i++) { + asn1_write_OID(&data,OIDs[i]); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_write_GeneralString(&data,principle); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + return data; +} + + +/* + parse a negTokenInit packet giving a GUID, a list of supported + OIDs (the mechanisms) and a principle name string +*/ +BOOL spnego_parse_negTokenInit(DATA_BLOB blob, + uint8 guid[16], + char *OIDs[ASN1_MAX_OIDS], + char **principle) +{ + int i; + BOOL ret; + ASN1_DATA data; + + asn1_load(&data, blob); + + asn1_read(&data, guid, 16); + asn1_start_tag(&data,ASN1_APPLICATION(0)); + asn1_check_OID(&data,OID_SPNEGO); + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + char *oid = NULL; + asn1_read_OID(&data,&oid); + OIDs[i] = oid; + } + OIDs[i] = NULL; + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_start_tag(&data, ASN1_CONTEXT(3)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_GeneralString(&data,principle); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + + ret = !data.has_error; + asn1_free(&data); + return ret; +} + + +/* + generate a negTokenTarg packet given a list of OIDs and a security blob +*/ +DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) +{ + int i; + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; OIDs[i]; i++) { + asn1_write_OID(&data,OIDs[i]); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} + + +/* + generate a krb5 GSS-API wrapper packet given a ticket +*/ +static DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data, OID_KERBEROS5); + asn1_write_BOOLEAN(&data, 0); + asn1_write(&data, ticket.data, ticket.length); + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} + + +/* + generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY + kerberos session setup +*/ +DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) +{ + char *p; + fstring service; + char *realm; + DATA_BLOB tkt, tkt_wrapped, targ; + const char *krb_mechs[] = + {"1 2 840 48018 1 2 2", "1 3 6 1 4 1 311 2 2 10", NULL}; + + fstrcpy(service, principle); + p = strchr_m(service, '@'); + if (!p) { + DEBUG(1,("Malformed principle [%s] in spnego_gen_negTokenTarg\n", + principle)); + return data_blob(NULL, 0); + } + *p = 0; + realm = p+1; + + /* get a kerberos ticket for the service */ + tkt = krb5_get_ticket(service, realm); + + /* wrap that up in a nice GSS-API wrapping */ + tkt_wrapped = spnego_gen_krb5_wrap(tkt); + + /* and wrap that in a shiny SPNEGO wrapper */ + targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); + + data_blob_free(tkt_wrapped); + data_blob_free(tkt); + + return targ; +} + + +/* + parse a spnego NTLMSSP challenge packet giving two security blobs +*/ +BOOL spnego_parse_challenge(DATA_BLOB blob, + DATA_BLOB *chal1, DATA_BLOB *chal2) +{ + BOOL ret; + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_check_enumerated(&data,1); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_check_OID(&data, "1 3 6 1 4 1 311 2 2 10"); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_octet_string(&data, chal1); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(3)); + asn1_read_octet_string(&data, chal2); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + ret = !data.has_error; + asn1_free(&data); + return ret; +} + +/* + generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords +*/ +DATA_BLOB spnego_gen_auth(DATA_BLOB blob) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_CONTEXT(1)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + ret = data_blob(data.data, data.length); + + asn1_free(&data); + + return ret; + +} + + +/* + this is a tiny msrpc packet generator. I am only using this to + avoid tying this code to a particular varient of our rpc code. This + generator is not general enough for all our rpc needs, its just + enough for the spnego/ntlmssp code + + format specifiers are: + + U = unicode string (input is unix string) + B = data blob (pointer + length) + d = word (4 bytes) + C = constant ascii string + */ +BOOL msrpc_gen(DATA_BLOB *blob, + const char *format, ...) +{ + int i, n; + va_list ap; + char *s; + uint8 *b; + int head_size=0, data_size=0; + int head_ofs, data_ofs; + + /* first scan the format to work out the header and body size */ + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_charnum(s) * 2; + break; + case 'B': + b = va_arg(ap, uint8 *); + head_size += 8; + data_size += va_arg(ap, int); + break; + case 'd': + n = va_arg(ap, int); + head_size += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_size += str_charnum(s) + 1; + break; + } + } + va_end(ap); + + /* allocate the space, then scan the format again to fill in the values */ + blob->data = malloc(head_size + data_size); + blob->length = head_size + data_size; + if (!blob->data) return False; + + head_ofs = 0; + data_ofs = head_size; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); + data_ofs += n*2; + break; + case 'B': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + memcpy(blob->data+data_ofs, b, n); + data_ofs += n; + break; + case 'd': + n = va_arg(ap, int); + SIVAL(blob->data, head_ofs, n); head_ofs += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, + STR_ASCII|STR_TERMINATE); + break; + } + } + va_end(ap); + + return True; +} -- cgit From d726eb216ad431d2bbd4ee07f4098b72446cdca2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Oct 2001 04:54:53 +0000 Subject: moved some OIDs to the ASN.1 header (This used to be commit 7092beef9d7a68018ede569883b22c822300c7ff) --- source3/libsmb/cliconnect.c | 4 ++-- source3/libsmb/clispnego.c | 8 ++------ 2 files changed, 4 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 11852a09cc..9186208d62 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -406,7 +406,7 @@ do a spnego/NTLMSSP encrypted session setup static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { - const char *mechs[] = {"1 3 6 1 4 1 311 2 2 10", NULL}; + const char *mechs[] = {OID_NTLMSSP, NULL}; DATA_BLOB msg1; DATA_BLOB blob, chal1, chal2, auth; uint8 challenge[8]; @@ -502,7 +502,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { DEBUG(3,("got OID=%s\n", OIDs[i])); - if (strcmp(OIDs[i], "1 2 840 48018 1 2 2") == 0) { + if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0) { got_kerberos_mechanism = True; } free(OIDs[i]); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6c6b18a923..6b705658c3 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -21,9 +21,6 @@ #include "includes.h" -#define OID_SPNEGO "1 3 6 1 5 5 2" -#define OID_KERBEROS5 "1 2 840 113554 1 2 2" - /* generate a negTokenInit packet given a GUID, a list of supported OIDs (the mechanisms) and a principle name string @@ -207,8 +204,7 @@ DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) fstring service; char *realm; DATA_BLOB tkt, tkt_wrapped, targ; - const char *krb_mechs[] = - {"1 2 840 48018 1 2 2", "1 3 6 1 4 1 311 2 2 10", NULL}; + const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; fstrcpy(service, principle); p = strchr_m(service, '@'); @@ -254,7 +250,7 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, asn1_end_tag(&data); asn1_start_tag(&data,ASN1_CONTEXT(1)); - asn1_check_OID(&data, "1 3 6 1 4 1 311 2 2 10"); + asn1_check_OID(&data, OID_NTLMSSP); asn1_end_tag(&data); asn1_start_tag(&data,ASN1_CONTEXT(2)); -- cgit From 81756ba7440e255f750d13858e1147d3976e70e2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Oct 2001 05:42:28 +0000 Subject: fixed two bugs in the NTLMSSP code - handle servers that don't send a kerberos principle (non-member servers) - enable spnego without KRB5 (This used to be commit b218d465a1968a11d2d6a42afa7e552fea8b7f5e) --- source3/libsmb/cliconnect.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9186208d62..4a9d2fe59c 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -493,6 +493,12 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, int i; BOOL got_kerberos_mechanism = False; + /* the server might not even do spnego */ + if (cli->secblob.length == 16) { + DEBUG(3,("server didn't supply a full spnego negprot\n")); + goto ntlmssp; + } + /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principle)) { @@ -519,6 +525,8 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, free(principle); +ntlmssp: + return cli_session_setup_ntlmssp(cli, user, pass, workgroup); } @@ -576,12 +584,10 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, pass, workgroup); } -#if HAVE_KRB5 /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { return cli_session_setup_spnego(cli, user, pass, workgroup); } -#endif /* otherwise do a NT1 style session setup */ return cli_session_setup_nt1(cli, user, -- cgit From b46f6d865efa6dd50ed8b83d498f9e04919c9bc9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Oct 2001 06:14:11 +0000 Subject: fixed NTLMSSP with XP servers (who don't send the duplicate challenge in the asn1 spnego structures) (This used to be commit 131010e9fb842b4d5a8660c538a3313c95fadae7) --- source3/libsmb/cliconnect.c | 8 ++++++++ source3/libsmb/clispnego.c | 12 +++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4a9d2fe59c..94eda90a3b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -439,6 +439,10 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, return False; } +#if 0 + file_save("chal.dat", blob.data, blob.length); +#endif + /* the server gives us back two challenges */ if (!spnego_parse_challenge(blob, &chal1, &chal2)) { return False; @@ -499,6 +503,10 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, goto ntlmssp; } +#if 0 + file_save("negprot.dat", cli->secblob.data, cli->secblob.length); +#endif + /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principle)) { diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6b705658c3..da8c6450ae 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -241,6 +241,9 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, BOOL ret; ASN1_DATA data; + ZERO_STRUCTP(chal1); + ZERO_STRUCTP(chal2); + asn1_load(&data, blob); asn1_start_tag(&data,ASN1_CONTEXT(1)); asn1_start_tag(&data,ASN1_SEQUENCE(0)); @@ -257,9 +260,12 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, asn1_read_octet_string(&data, chal1); asn1_end_tag(&data); - asn1_start_tag(&data,ASN1_CONTEXT(3)); - asn1_read_octet_string(&data, chal2); - asn1_end_tag(&data); + /* the second challenge is optional (XP doesn't send it) */ + if (asn1_tag_remaining(&data)) { + asn1_start_tag(&data,ASN1_CONTEXT(3)); + asn1_read_octet_string(&data, chal2); + asn1_end_tag(&data); + } asn1_end_tag(&data); asn1_end_tag(&data); -- cgit From 0567d2d969af381fc691a5e3b02ed4a0af2383de Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Oct 2001 09:25:19 +0000 Subject: minor Realloc() fix - pedantic (This used to be commit 1bcdf9106afacbe18437e87178bc1f219695c1e9) --- source3/libsmb/asn1.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 6a92a6be00..e72da897b9 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -32,11 +32,14 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { - data->data = Realloc(data->data, data->ofs+len); - if (!data->data) { + uint8 *p; + p = Realloc(data->data, data->ofs+len); + if (!p) { + SAFE_FREE(data->data); data->has_error = True; return False; } + data->data = p; data->length = data->ofs+len; } memcpy(data->data + data->ofs, p, len); -- cgit From b886c3b3fa5866ac6f82a25e11c6f4ed954085dc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Oct 2001 12:02:18 +0000 Subject: fix heimdal compilation (This used to be commit 888183a17cfb12c0cbf7d1ed515064d6f1716114) --- source3/libsmb/clikrb5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 59a547b171..68e941f2aa 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -113,7 +113,8 @@ DATA_BLOB krb5_get_ticket(char *service, char *realm) } ret = data_blob(packet.data, packet.length); - krb5_free_data_contents(context, &packet); +/* Hmm, heimdal dooesn't have this - what's the correct call? */ +/* krb5_free_data_contents(context, &packet); */ krb5_free_context(context); return ret; -- cgit From b728042334f67738fd1a6fdd03e619bdb78fe06a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Oct 2001 08:54:19 +0000 Subject: added basic NTLMSSP support in smbd. This is still quite rough, and loses things like username mapping. I wanted to get this in then discuss it a bit to see how we want to split up the existing session setup code (This used to be commit b74fda69bf23207c26d8b2af23910d8f2eb89875) --- source3/libsmb/asn1.c | 28 ++++-- source3/libsmb/cliconnect.c | 32 ++++--- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clispnego.c | 222 ++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 258 insertions(+), 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index e72da897b9..59763408cf 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -87,13 +87,18 @@ BOOL asn1_pop_tag(ASN1_DATA *data) /* yes, this is ugly. We don't know in advance how many bytes the length of a tag will take, so we assumed 1 byte. If we were wrong then we need to correct our mistake */ - if (len > 127) { + if (len > 255) { data->data[nesting->start] = 0x82; if (!asn1_write_uint8(data, 0)) return False; if (!asn1_write_uint8(data, 0)) return False; memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); data->data[nesting->start+1] = len>>8; data->data[nesting->start+2] = len&0xff; + } else if (len > 127) { + data->data[nesting->start] = 0x81; + if (!asn1_write_uint8(data, 0)) return False; + memmove(data->data+nesting->start+2, data->data+nesting->start+1, len); + data->data[nesting->start+1] = len; } else { data->data[nesting->start] = len; } @@ -203,14 +208,16 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) asn1_read_uint8(data, &b); if (b & 0x80) { int n = b & 0x7f; - if (n != 2) { + if (n > 2) { data->has_error = True; return False; } asn1_read_uint8(data, &b); - nesting->taglen = b<<8; - asn1_read_uint8(data, &b); - nesting->taglen |= b; + nesting->taglen = b; + if (n == 2) { + asn1_read_uint8(data, &b); + nesting->taglen = (nesting->taglen << 8) | b; + } } else { nesting->taglen = b; } @@ -320,7 +327,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) } /* read a octet string blob */ -BOOL asn1_read_octet_string(ASN1_DATA *data, DATA_BLOB *blob) +BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) { int len; if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; @@ -345,3 +352,12 @@ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) asn1_end_tag(data); return !data->has_error && (v == b); } + +/* check a enumarted value is correct */ +BOOL asn1_write_enumerated(ASN1_DATA *data, uint8 v) +{ + if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; + asn1_write_uint8(data, v); + asn1_pop_tag(data); + return !data->has_error; +} diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 94eda90a3b..6a01744240 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -31,11 +31,12 @@ static struct { prots[] = { {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, {PROTOCOL_LANMAN1,"LANMAN1.0"}, - {PROTOCOL_LANMAN1,"Windows for Workgroups 3.1a"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_NT1,"Samba"}, - {PROTOCOL_NT1,"LANMAN2.1"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, {-1,NULL} }; @@ -394,7 +395,7 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principle, c blob2 = cli_session_setup_blob(cli, negTokenTarg); /* we don't need this blob for kerberos */ - data_blob_free(blob2); + data_blob_free(&blob2); return !cli_is_error(cli); } @@ -428,12 +429,12 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenTarg(mechs, blob); - data_blob_free(blob); + data_blob_free(&blob); /* now send that blob on its way */ blob = cli_session_setup_blob(cli, msg1); - data_blob_free(msg1); + data_blob_free(&msg1); if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) { return False; @@ -445,18 +446,25 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, /* the server gives us back two challenges */ if (!spnego_parse_challenge(blob, &chal1, &chal2)) { + DEBUG(3,("Failed to parse challenges\n")); return False; } - data_blob_free(blob); + data_blob_free(&blob); /* encrypt the password with the challenge */ memcpy(challenge, chal1.data + 24, 8); SMBencrypt(pass, challenge,lmhash); SMBNTencrypt(pass, challenge,nthash); - data_blob_free(chal1); - data_blob_free(chal2); +#if 0 + file_save("nthash.dat", nthash, 24); + file_save("lmhash.dat", lmhash, 24); + file_save("chal1.dat", chal1.data, chal1.length); +#endif + + data_blob_free(&chal1); + data_blob_free(&chal2); /* this generates the actual auth packet */ msrpc_gen(&blob, "CdBBUUUBd", @@ -473,13 +481,13 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, /* wrap it in SPNEGO */ auth = spnego_gen_auth(blob); - data_blob_free(blob); + data_blob_free(&blob); /* now send the auth packet and we should be done */ blob = cli_session_setup_blob(cli, auth); - data_blob_free(auth); - data_blob_free(blob); + data_blob_free(&auth); + data_blob_free(&blob); return !cli_is_error(cli); } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 25dc070024..ed0bc6481e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -216,7 +216,7 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); - data_blob_free(cli->secblob); + data_blob_free(&cli->secblob); if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index da8c6450ae..78cae3315a 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -25,12 +25,13 @@ generate a negTokenInit packet given a GUID, a list of supported OIDs (the mechanisms) and a principle name string */ -ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], +DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], const char *OIDs[], const char *principle) { int i; ASN1_DATA data; + DATA_BLOB ret; memset(&data, 0, sizeof(data)); @@ -66,7 +67,10 @@ ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], asn1_free(&data); } - return data; + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; } @@ -166,6 +170,50 @@ DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) } +/* + parse a negTokenTarg packet giving a list of OIDs and a security blob +*/ +BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) +{ + int i; + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_APPLICATION(0)); + asn1_check_OID(&data,OID_SPNEGO); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + char *oid = NULL; + asn1_read_OID(&data,&oid); + OIDs[i] = oid; + } + OIDs[i] = NULL; + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_start_tag(&data, ASN1_CONTEXT(2)); + asn1_read_OctetString(&data,secblob); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data.ofs)); + asn1_free(&data); + return False; + } + + asn1_free(&data); + return True; +} + /* generate a krb5 GSS-API wrapper packet given a ticket */ @@ -225,8 +273,8 @@ DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) /* and wrap that in a shiny SPNEGO wrapper */ targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); - data_blob_free(tkt_wrapped); - data_blob_free(tkt); + data_blob_free(&tkt_wrapped); + data_blob_free(&tkt); return targ; } @@ -257,13 +305,13 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, asn1_end_tag(&data); asn1_start_tag(&data,ASN1_CONTEXT(2)); - asn1_read_octet_string(&data, chal1); + asn1_read_OctetString(&data, chal1); asn1_end_tag(&data); /* the second challenge is optional (XP doesn't send it) */ if (asn1_tag_remaining(&data)) { asn1_start_tag(&data,ASN1_CONTEXT(3)); - asn1_read_octet_string(&data, chal2); + asn1_read_OctetString(&data, chal2); asn1_end_tag(&data); } @@ -275,6 +323,52 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, return ret; } + +/* + generate a spnego NTLMSSP challenge packet given two security blobs + The second challenge is optional +*/ +BOOL spnego_gen_challenge(DATA_BLOB *blob, + DATA_BLOB *chal1, DATA_BLOB *chal2) +{ + ASN1_DATA data; + + ZERO_STRUCT(data); + + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_write_enumerated(&data,1); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_write_OID(&data, OID_NTLMSSP); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(2)); + asn1_write_OctetString(&data, chal1->data, chal1->length); + asn1_pop_tag(&data); + + /* the second challenge is optional (XP doesn't send it) */ + if (chal2) { + asn1_push_tag(&data,ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, chal2->data, chal2->length); + asn1_pop_tag(&data); + } + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + if (data.has_error) { + return False; + } + + *blob = data_blob(data.data, data.length); + asn1_free(&data); + return True; +} + /* generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords */ @@ -298,7 +392,32 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) asn1_free(&data); return ret; - +} + +/* + parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords +*/ +BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) +{ + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(2)); + asn1_read_OctetString(&data,auth); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + + if (data.has_error) { + DEBUG(3,("spnego_parse_auth failed at %d\n", (int)data.ofs)); + asn1_free(&data); + return False; + } + + asn1_free(&data); + return True; } @@ -312,6 +431,7 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) U = unicode string (input is unix string) B = data blob (pointer + length) + b = data blob in header (pointer + length) d = word (4 bytes) C = constant ascii string */ @@ -339,6 +459,10 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += va_arg(ap, int); break; + case 'b': + b = va_arg(ap, uint8 *); + head_size += va_arg(ap, int); + break; case 'd': n = va_arg(ap, int); head_size += 4; @@ -384,6 +508,12 @@ BOOL msrpc_gen(DATA_BLOB *blob, n = va_arg(ap, int); SIVAL(blob->data, head_ofs, n); head_ofs += 4; break; + case 'b': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + memcpy(blob->data + head_ofs, b, n); + head_ofs += n; + break; case 'C': s = va_arg(ap, char *); head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, @@ -395,3 +525,81 @@ BOOL msrpc_gen(DATA_BLOB *blob, return True; } + + +/* + this is a tiny msrpc packet parser. This the the partner of msrpc_gen + + format specifiers are: + + U = unicode string (input is unix string) + B = data blob + b = data blob in header + d = word (4 bytes) + C = constant ascii string + */ +BOOL msrpc_parse(DATA_BLOB *blob, + const char *format, ...) +{ + int i; + va_list ap; + char **ps, *s; + DATA_BLOB *b; + int head_ofs = 0; + uint16 len1, len2; + uint32 ptr; + uint32 *v; + pstring p; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + /* make sure its in the right format - be strict */ + if (len1 != len2 || (len1&1) || ptr + len1 > blob->length) { + return False; + } + ps = va_arg(ap, char **); + pull_string(NULL, p, blob->data + ptr, -1, len1, + STR_UNICODE|STR_NOALIGN); + (*ps) = strdup(p); + break; + case 'B': + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + b = (DATA_BLOB *)va_arg(ap, void *); + *b = data_blob(blob->data + ptr, len1); + break; + case 'b': + b = (DATA_BLOB *)va_arg(ap, void *); + len1 = va_arg(ap, unsigned); + *b = data_blob(blob->data + head_ofs, len1); + head_ofs += len1; + break; + case 'd': + v = va_arg(ap, uint32 *); + *v = IVAL(blob->data, head_ofs); head_ofs += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += pull_string(NULL, p, blob->data+head_ofs, -1, + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); + if (strcmp(s, p) != 0) { + return False; + } + break; + } + } + va_end(ap); + + return True; +} -- cgit From 5ad7448359c7bc1d3b1579f105b7324290bf21ec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Oct 2001 10:26:06 +0000 Subject: the beginnings of kerberos support in smbd. It doesn't work yet, but it should give something for others to hack on and possibly find what I'm doing wrong. (This used to be commit 353c290f059347265b9be2aa1010c2956da06485) --- source3/libsmb/asn1.c | 18 ++++++++++++++++++ source3/libsmb/cliconnect.c | 4 ++++ source3/libsmb/clikrb5.c | 4 +--- source3/libsmb/clispnego.c | 23 +++++++++++++++++++++++ 4 files changed, 46 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 59763408cf..a8c0eebb94 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -156,6 +156,24 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) return !data->has_error; } +/* check a BOOLEAN */ +BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) +{ + uint8 b = 0; + + asn1_read_uint8(data, &b); + if (b != ASN1_BOOLEAN) { + data->has_error = True; + return False; + } + asn1_read_uint8(data, &b); + if (b != v) { + data->has_error = True; + return False; + } + return !data->has_error; +} + /* load a ASN1_DATA structure with a lump of data, ready to be parsed */ BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6a01744240..4fba54900d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -392,6 +392,10 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principle, c if (!negTokenTarg.data) return False; +#if 0 + file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); +#endif + blob2 = cli_session_setup_blob(cli, negTokenTarg); /* we don't need this blob for kerberos */ diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 68e941f2aa..51b6e6e8cf 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -22,8 +22,6 @@ #include "includes.h" #if HAVE_KRB5 -#include - /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ @@ -105,7 +103,7 @@ DATA_BLOB krb5_get_ticket(char *service, char *realm) if ((retval = krb5_mk_req2(context, &auth_context, - AP_OPTS_MUTUAL_REQUIRED, + 0, service, realm, ccdef, &packet))) { DEBUG(1,("krb5_mk_req2 failed\n")); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 78cae3315a..c421d75913 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -241,6 +241,29 @@ static DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) return ret; } +/* + parse a krb5 GSS-API wrapper packet giving a ticket +*/ +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) +{ + BOOL ret; + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_APPLICATION(0)); + asn1_check_OID(&data, OID_KERBEROS5); + asn1_check_BOOLEAN(&data, 0); + *ticket = data_blob(data.data, asn1_tag_remaining(&data)); + asn1_read(&data, ticket->data, ticket->length); + asn1_end_tag(&data); + + ret = !data.has_error; + + asn1_free(&data); + + return ret; +} + /* generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY -- cgit From d09527532656b92abb87308bd9065bb057935da1 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 19 Oct 2001 16:50:15 +0000 Subject: Add additional client RAP calls (This used to be commit b94427ddd55c177145da2665afe3d3a3682db031) --- source3/libsmb/clirap2.c | 1832 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1832 insertions(+) create mode 100644 source3/libsmb/clirap2.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c new file mode 100644 index 0000000000..5da67de95c --- /dev/null +++ b/source3/libsmb/clirap2.c @@ -0,0 +1,1832 @@ +/* + Samba Unix/Linux SMB client library + Version 3.0 + More client RAP (SMB Remote Procedure Calls) functions + Copyright (C) 2001 Steve French (sfrench@us.ibm.com) + Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com) + + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +/*****************************************************/ +/* */ +/* Additional RAP functionality */ +/* */ +/* RAP is the original SMB RPC, documented */ +/* by Microsoft and X/Open in the 1990s and */ +/* supported by most SMB/CIFS servers although */ +/* it is unlikely that any one implementation */ +/* supports all RAP command codes since some */ +/* are quite obsolete and a few are specific */ +/* to a particular network operating system */ +/* */ +/* Although it has largely been replaced */ +/* for complex remote admistration and management */ +/* (of servers) by the relatively newer */ +/* DCE/RPC based remote API (which better handles */ +/* large >64K data structures), there are many */ +/* important administrative and resource location */ +/* tasks and user tasks (e.g. password change) */ +/* that are performed via RAP. */ +/* */ +/* Although a few of the RAP calls are implemented */ +/* in the Samba client library already (clirap.c) */ +/* the new ones are in clirap2.c for easy patching */ +/* and integration and a corresponding header */ +/* file, rap.h, has been created. */ +/* */ +/* This is based on data from the CIFS spec */ +/* and the LAN Server and LAN Manager */ +/* Programming Reference books and published */ +/* RAP document and CIFS forum postings and */ +/* lots of trial and error */ +/* */ +/* Function names changed from API_ (as they are */ +/* in the CIFS specification) to RAP_ in order */ +/* to avoid confusion with other API calls */ +/* sent via DCE RPC */ +/* */ +/*****************************************************/ + +/*****************************************************/ +/* */ +/* cifsrap.c already includes support for: */ +/* */ +/* WshareEnum ( API number 0, level 1) */ +/* NetServerEnum2 (API num 104, level 1) */ +/* WWkstaUserLogon (132) */ +/* SamOEMchgPasswordUser2_P (214) */ +/* */ +/* cifsprint.c already includes support for: */ +/* */ +/* WPrintJobEnum (API num 76, level 2) */ +/* WPrintJobDel (API num 81) */ +/* */ +/*****************************************************/ + +#define NO_SYSLOG + +#include "includes.h" + +#define WORDSIZE 2 +#define DWORDSIZE 4 + +#define PUTBYTE(p,b) do {SCVAL(p,0,b); p++;} while(0) +#define GETBYTE(p,b) do {b = CVAL(p,0); p++;} while(0) +#define PUTWORD(p,w) do {SSVAL(p,0,w); p += WORDSIZE;} while(0) +#define GETWORD(p,w) do {w = SVAL(p,0); p += WORDSIZE;} while(0) +#define PUTDWORD(p,d) do {SIVAL(p,0,d); p += DWORDSIZE;} while(0) +#define GETDWORD(p,d) do {d = IVAL(p,0); p += DWORDSIZE;} while(0) +#define GETRES(p) p ? SVAL(p,0) : -1 +/* put string s at p with max len n and increment p past string */ +#define PUTSTRING(p,s,n) do {\ + push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\ + p = skip_string(p,1);\ + } while(0) +/* put string s and p, using fixed len l, and increment p by l */ +#define PUTSTRINGF(p,s,l) do {\ + push_ascii(p,s?s:"",l,STR_TERMINATE);\ + p += l;\ + } while (0) +/* put string pointer at p, supplying offset o from rdata r, store */ +/* dword offset at p, increment p by 4 and o by length of s. This */ +/* means on the first call, you must calc the offset yourself! */ +#define PUTSTRINGP(p,s,r,o) do {\ + if (s) {\ + push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\ + PUTDWORD(p,o);\ + o += strlen(s) + 1;\ + } else PUTDWORD(p,0);\ + }while(0); +/* get asciiz string s from p, increment p past string */ +#define GETSTRING(p,s) do {\ + pull_ascii_pstring(s,p);\ + p = skip_string(p,1);\ + } while(0) +/* get fixed length l string s from p, increment p by l */ +#define GETSTRINGF(p,s,l) do {\ + pull_ascii_pstring(s,p);\ + p += l;\ + } while(0) +/* get string s from offset (obtained at p) from rdata r - converter c */ +#define GETSTRINGP(p,s,r,c) do {\ + uint32 off;\ + GETDWORD(p,off);\ + off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */ \ + pull_ascii_pstring(s, off?(r+off-c):"");\ + } while(0) + +static char *make_header(char *param, uint16 apinum, char *reqfmt, char *datafmt) +{ + PUTWORD(param,apinum); + if (reqfmt) + PUTSTRING(param,reqfmt,0); + else + *param++ = (char) 0; + + if (datafmt) + PUTSTRING(param,datafmt,0); + else + *param++ = (char) 0; + + return param; +} + + +/**************************************************************************** + call a NetGroupDelete - delete user group from remote server +****************************************************************************/ +int cli_NetGroupDelete(struct cli_state *cli, char * group_name ) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt, res; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetGroupDel_REQ) /* parm string */ + +1 /* no ret string */ + +RAP_GROUPNAME_LEN /* group to del */ + +WORDSIZE]; /* reserved word */ + + /* now send a SMBtrans command with api GroupDel */ + p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL); + PUTSTRING(p, group_name, RAP_GROUPNAME_LEN); + PUTWORD(p,0); /* reserved word MBZ on input */ + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, 200, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + res = GETRES(rparam); + + if (res == 0) { + /* nothing to do */ + } + else if ((res == 5) || (res == 65)) { + DEBUG(1, ("Access Denied\n")); + } + else if (res == 2220) { + DEBUG (1, ("Group does not exist\n")); + } + else { + DEBUG(4,("NetGroupDelete res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetGroupDelete failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; +} + +/**************************************************************************** + call a NetGroupAdd - add user group to remote server +****************************************************************************/ +int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt,res; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetGroupAdd_REQ) /* req string */ + +sizeof(RAP_GROUP_INFO_L1) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* reserved word */ + + char data[1024]; + + /* offset into data of free format strings. Will be updated */ + /* by PUTSTRINGP macro and end up with total data length. */ + int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE; + + /* now send a SMBtrans command with api WGroupAdd */ + + p = make_header(param, RAP_WGroupAdd, + RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1); + PUTWORD(p, 1); /* info level */ + PUTWORD(p, 0); /* reserved word 0 */ + + p = data; + PUTSTRINGF(p, grinfo->group_name, RAP_GROUPNAME_LEN); + PUTBYTE(p, 0); /* pad byte 0 */ + PUTSTRINGP(p, grinfo->comment, data, soffset); + + if (cli_api(cli, + param, sizeof(param), 1024, /* Param, length, maxlen */ + data, soffset, sizeof(data), /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + res = GETRES(rparam); + + if (res == 0) { + /* nothing to do */ + } else if ((res == 5) || (res == 65)) { + DEBUG(1, ("Access Denied\n")); + } + else if (res == 2223) { + DEBUG (1, ("Group already exists\n")); + } + else { + DEBUG(4,("NetGroupAdd res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetGroupAdd failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; +} + +/**************************************************************************** +call a NetGroupEnum - try and list user groups on a different host +****************************************************************************/ +int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state) +{ + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetGroupEnum_REQ) /* parm string */ + +sizeof(RAP_GROUP_INFO_L1) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + char *p; + char *rparam = NULL; + char *rdata = NULL; + int rprcnt, rdrcnt; + int res = -1; + + + bzero(param, sizeof(param)); + p = make_header(param, RAP_WGroupEnum, + RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L1); + PUTWORD(p,1); /* Info level 1 */ /* add level 0 */ + PUTWORD(p,0xFFE0); /* Return buffer size */ + + if (cli_api(cli, + param, PTR_DIFF(p,param),8, + NULL, 0, 0xFFE0 /* data area size */, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { + res = GETRES(rparam); + cli->rap_error = res; + if(cli->rap_error == 234) + DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n")); + else if (cli->rap_error != 0) { + DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error)); + } + } + + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + + p = rparam + WORDSIZE; /* skip result */ + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata;irap_error = res; + if (res != 0) { + DEBUG(1,("NetGroupGetUsers gave error %d\n", res)); + } + } + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + fstring username; + p = rparam +WORDSIZE; + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata; ipasswrd) + PUTWORD(p,strnlen(userinfo->passwrd, RAP_UPASSWD_LEN)); + else + PUTWORD(p, 0); /* password length */ + + p = data; + bzero(data, soffset); + + PUTSTRINGF(p, userinfo->user_name, RAP_USERNAME_LEN); + PUTBYTE(p, 0); /* pad byte 0 */ + PUTSTRINGF(p, userinfo->passwrd, RAP_UPASSWD_LEN); + PUTDWORD(p, 0); /* pw age - n.a. on user add */ + PUTWORD(p, userinfo->priv); + PUTSTRINGP(p, userinfo->home_dir, data, soffset); + PUTSTRINGP(p, userinfo->comment, data, soffset); + PUTWORD(p, userinfo->userflags); + PUTSTRINGP(p, userinfo->logon_script, data, soffset); + + if (cli_api(cli, + param, sizeof(param), 1024, /* Param, length, maxlen */ + data, soffset, sizeof(data), /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + res = GETRES(rparam); + + if (res == 0) { + /* nothing to do */ + } + else if ((res == 5) || (res == 65)) { + DEBUG(1, ("Access Denied\n")); + } + else if (res == 2224) { + DEBUG (1, ("User already exists\n")); + } + else { + DEBUG(4,("NetUserAdd res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetUserAdd failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; +} + +/**************************************************************************** +call a NetUserEnum - try and list users on a different host +****************************************************************************/ +int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char *, const char *, const char *, void *), void *state) +{ + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetUserEnum_REQ) /* parm string */ + +sizeof(RAP_USER_INFO_L1) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + char *p; + char *rparam = NULL; + char *rdata = NULL; + int rprcnt, rdrcnt; + int res = -1; + + + bzero(param, sizeof(param)); + p = make_header(param, RAP_WUserEnum, + RAP_NetUserEnum_REQ, RAP_USER_INFO_L1); + PUTWORD(p,1); /* Info level 1 */ + PUTWORD(p,0xFF00); /* Return buffer size */ + +/* BB Fix handling of large numbers of users to be returned */ + if (cli_api(cli, + param, PTR_DIFF(p,param),8, + NULL, 0, CLI_BUFFER_SIZE, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { + res = GETRES(rparam); + cli->rap_error = res; + if (cli->rap_error != 0) { + DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error)); + } + } + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + char username[RAP_USERNAME_LEN]; + char userpw[RAP_UPASSWD_LEN]; + pstring comment, homedir, logonscript; + int pwage, priv, flags; + + p = rparam + WORDSIZE; /* skip result */ + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata;ishare_name, RAP_SHARENAME_LEN); + PUTBYTE(p, 0); /* pad byte 0 */ + + PUTWORD(p, sinfo->share_type); + PUTSTRINGP(p, sinfo->comment, data, soffset); + PUTWORD(p, sinfo->perms); + PUTWORD(p, sinfo->maximum_users); + PUTWORD(p, sinfo->active_users); + PUTSTRINGP(p, sinfo->path, data, soffset); + PUTSTRINGF(p, sinfo->password, RAP_SPASSWD_LEN); + SCVAL(p,-1,0x0A); /* required 0x0A at end of password */ + + if (cli_api(cli, + param, sizeof(param), 1024, /* Param, length, maxlen */ + data, soffset, sizeof(data), /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + res = rparam? SVAL(rparam,0) : -1; + + if (res == 0) { + /* nothing to do */ + } + else { + DEBUG(4,("NetShareAdd res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetShareAdd failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; +} +/**************************************************************************** + call a NetShareDelete - unshare exported directory on remote server +****************************************************************************/ +int cli_NetShareDelete(struct cli_state *cli, char * share_name ) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt, res; + char param[WORDSIZE /* api number */ + +sizeof(RAP_WShareDel_REQ) /* req string */ + +1 /* no ret string */ + +RAP_SHARENAME_LEN /* share to del */ + +WORDSIZE]; /* reserved word */ + + + /* now send a SMBtrans command with api RNetShareDelete */ + p = make_header(param, RAP_WshareDel, RAP_WShareDel_REQ, NULL); + PUTSTRING(p,share_name,RAP_SHARENAME_LEN); + PUTWORD(p,0); /* reserved word MBZ on input */ + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, 200, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + res = GETRES(rparam); + + if (res == 0) { + /* nothing to do */ + } + else { + DEBUG(4,("NetShareDelete res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetShareDelete failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; +} +/************************************************************************* +* +* Function Name: cli_get_pdc_name +* +* PURPOSE: Remotes a NetServerEnum API call to the current server +* requesting the name of a server matching the server +* type of SV_TYPE_DOMAIN_CTRL (PDC). +* +* Dependencies: none +* +* Parameters: +* cli - pointer to cli_state structure +* workgroup - pointer to string containing name of domain +* pdc_name - pointer to string that will contain PDC name +* on successful return +* +* Returns: +* True - success +* False - failure +* +************************************************************************/ +BOOL cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) +{ + char *rparam = NULL; + char *rdata = NULL; + int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetServerEnum2_REQ) /* req string */ + +sizeof(RAP_SERVER_INFO_L1) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE /* buffer size */ + +DWORDSIZE /* server type */ + +RAP_MACHNAME_LEN]; /* workgroup */ + int count = -1; + + *pdc_name = '\0'; + + /* send a SMBtrans command with api NetServerEnum */ + p = make_header(param, RAP_NetServerEnum2, + RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L1); + PUTWORD(p, 1); /* info level */ + PUTWORD(p, CLI_BUFFER_SIZE); + PUTDWORD(p, SV_TYPE_DOMAIN_CTRL); + PUTSTRING(p, workgroup, RAP_MACHNAME_LEN); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + cli->rap_error = GETRES(rparam); + + /* + * We only really care to copy a name if the + * API succeeded and we got back a name. + */ + if (cli->rap_error == 0) { + p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ + GETWORD(p, count); + p = rdata; + + if (count > 0) + GETSTRING(p, pdc_name); + } + else { + DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. " + "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return(count > 0); +} + + +/************************************************************************* +* +* Function Name: cli_get_server_domain +* +* PURPOSE: Remotes a NetWkstaGetInfo API call to the current server +* requesting wksta_info_10 level information to determine +* the domain the server belongs to. On success, this +* routine sets the server_domain field in the cli_state structure +* to the server's domain name. +* +* Dependencies: none +* +* Parameters: +* cli - pointer to cli_state structure +* +* Returns: +* True - success +* False - failure +* +* Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum() +* +************************************************************************/ +BOOL cli_get_server_domain(struct cli_state *cli) +{ + char *rparam = NULL; + char *rdata = NULL; + int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_WWkstaGetInfo_REQ) /* req string */ + +sizeof(RAP_WKSTA_INFO_L10) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + int res = -1; + + /* send a SMBtrans command with api NetWkstaGetInfo */ + p = make_header(param, RAP_WWkstaGetInfo, + RAP_WWkstaGetInfo_REQ, RAP_WKSTA_INFO_L10); + PUTWORD(p, 10); /* info level */ + PUTWORD(p, CLI_BUFFER_SIZE); + + if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt)) { /* return data, return size */ + res = GETRES(rparam); + p = rdata; + + if (res == 0) { + int converter; + + p = rparam + WORDSIZE; + GETWORD(p, converter); + + p = rdata + DWORDSIZE + DWORDSIZE; /* skip computer & user names */ + GETSTRINGP(p, cli->server_domain, rdata, converter); + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return(res == 0); +} + + +/************************************************************************* +* +* Function Name: cli_get_server_type +* +* PURPOSE: Remotes a NetServerGetInfo API call to the current server +* requesting server_info_1 level information to retrieve +* the server type. +* +* Dependencies: none +* +* Parameters: +* cli - pointer to cli_state structure +* pstype - pointer to uint32 to contain returned server type +* +* Returns: +* True - success +* False - failure +* +* Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum() +* +************************************************************************/ +BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype) +{ + char *rparam = NULL; + char *rdata = NULL; + int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_WserverGetInfo_REQ) /* req string */ + +sizeof(RAP_SERVER_INFO_L1) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + int res = -1; + + /* send a SMBtrans command with api NetServerGetInfo */ + p = make_header(param, RAP_WserverGetInfo, + RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1); + PUTWORD(p, 1); /* info level */ + PUTWORD(p, CLI_BUFFER_SIZE); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + + res = GETRES(rparam); + + if (res == 0 || res == ERRmoredata) { + p = rdata; + *pstype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return(res == 0 || res == ERRmoredata); +} + + +/************************************************************************* +* +* Function Name: cli_ns_check_server_type +* +* PURPOSE: Remotes a NetServerEnum2 API call to the current server +* requesting server_info_0 level information of machines +* matching the given server type. If the returned server +* list contains the machine name contained in cli->desthost +* then we conclude the server type checks out. This routine +* is useful to retrieve list of server's of a certain +* type when all you have is a null session connection and +* can't remote API calls such as NetWkstaGetInfo or +* NetServerGetInfo. +* +* Dependencies: none +* +* Parameters: +* cli - pointer to cli_state structure +* workgroup - pointer to string containing domain +* stype - server type +* +* Returns: +* True - success +* False - failure +* +************************************************************************/ +BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype) +{ + char *rparam = NULL; + char *rdata = NULL; + int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetServerEnum2_REQ) /* req string */ + +sizeof(RAP_SERVER_INFO_L0) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE /* buffer size */ + +DWORDSIZE /* server type */ + +RAP_MACHNAME_LEN]; /* workgroup */ + BOOL found_server = False; + int res = -1; + + /* send a SMBtrans command with api NetServerEnum */ + p = make_header(param, RAP_NetServerEnum2, + RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L0); + PUTWORD(p, 0); /* info level 0 */ + PUTWORD(p, CLI_BUFFER_SIZE); + PUTDWORD(p, stype); + PUTSTRING(p, workgroup, RAP_MACHNAME_LEN); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + + res = GETRES(rparam); + cli->rap_error = res; + + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + + p = rparam + WORDSIZE; + GETWORD(p, converter); + GETWORD(p, count); + + p = rdata; + for (i = 0;i < count;i++, p += 16) { + char ret_server[RAP_MACHNAME_LEN]; + + GETSTRINGF(p, ret_server, RAP_MACHNAME_LEN); + if (strequal(ret_server, cli->desthost)) { + found_server = True; + break; + } + } + } + else { + DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. " + "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return found_server; + } + + +/**************************************************************************** + perform a NetWkstaUserLogoff +****************************************************************************/ +BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string */ + +sizeof(RAP_USER_LOGOFF_INFO_L1) /* return string */ + +RAP_USERNAME_LEN+1 /* user name+pad */ + +RAP_MACHNAME_LEN /* wksta name */ + +WORDSIZE /* buffer size */ + +WORDSIZE]; /* buffer size? */ + fstring upperbuf; + + memset(param, 0, sizeof(param)); + + /* send a SMBtrans command with api NetWkstaUserLogoff */ + p = make_header(param, RAP_WWkstaUserLogoff, + RAP_NetWkstaUserLogoff_REQ, RAP_USER_LOGOFF_INFO_L1); + PUTDWORD(p, 0); /* Null pointer */ + PUTDWORD(p, 0); /* Null pointer */ + fstrcpy(upperbuf, user); + strupper(upperbuf); + PUTSTRINGF(p, upperbuf, RAP_USERNAME_LEN); + p++; /* strange format, but ok */ + fstrcpy(upperbuf, workstation); + strupper(upperbuf); + PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN); + PUTWORD(p, CLI_BUFFER_SIZE); + PUTWORD(p, CLI_BUFFER_SIZE); + + if (cli_api(cli, + param, PTR_DIFF(p,param),1024, /* param, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + cli->rap_error = GETRES(rparam); + + if (cli->rap_error != 0) { + DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli->rap_error)); + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return (cli->rap_error == 0); +} + +int cli_NetPrintQEnum(struct cli_state *cli, void (*qfn)(char*,uint16,uint16,uint16,char*,char*,char*,char*,char*,uint16,uint16),void (*jfn)(uint16,char*,char*,char*,char*,uint16,uint16,char*,uint,uint,char*)) +{ + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetPrintQEnum_REQ) /* req string */ + +sizeof(RAP_PRINTQ_INFO_L2) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE /* buffer size */ + +sizeof(RAP_SMB_PRINT_JOB_L1)]; /* more ret data */ + char *p; + char *rparam = NULL; + char *rdata = NULL; + int rprcnt, rdrcnt; + int res = -1; + + + bzero(param, sizeof(param)); + p = make_header(param, RAP_WPrintQEnum, + RAP_NetPrintQEnum_REQ, RAP_PRINTQ_INFO_L2); + PUTWORD(p,2); /* Info level 2 */ + PUTWORD(p,0xFFE0); /* Return buffer size */ + PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0); + + if (cli_api(cli, + param, PTR_DIFF(p,param),1024, + NULL, 0, CLI_BUFFER_SIZE, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { + res = GETRES(rparam); + cli->rap_error = res; + if (res != 0) { + DEBUG(1,("NetPrintQEnum gave error %d\n", res)); + } + } + + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + + p = rparam + WORDSIZE; + GETWORD(p, converter); + GETWORD(p, count); + + p = rdata; + for (i=0;irap_error = res; + if (res != 0) { + DEBUG(1,("NetPrintQGetInfo gave error %d\n", res)); + } + } + + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int rsize, converter; + pstring qname, sep_file, print_proc, dest, parms, comment; + uint16 jobcount, priority, start_time, until_time, status; + + p = rparam + WORDSIZE; + GETWORD(p, converter); + GETWORD(p, rsize); + + p = rdata; + GETSTRINGF(p, qname, RAP_SHARENAME_LEN); + p++; /* pad */ + GETWORD(p, priority); + GETWORD(p, start_time); + GETWORD(p, until_time); + GETSTRINGP(p, sep_file, rdata, converter); + GETSTRINGP(p, print_proc, rdata, converter); + GETSTRINGP(p, dest, rdata, converter); + GETSTRINGP(p, parms, rdata, converter); + GETSTRINGP(p, comment, rdata, converter); + GETWORD(p, status); + GETWORD(p, jobcount); + qfn(qname, priority, start_time, until_time, sep_file, print_proc, + dest, parms, comment, status, jobcount); + if (jobcount) { + int j; + for (j=0;(jrap_error = res; + if (res != 0) { + DEBUG(1,("NetSessionEnum gave error %d\n", res)); + } + } + + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + + p = rparam + WORDSIZE; + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata;irap_error = SVAL(rparam,0); + if (cli->rap_error != 0) { + DEBUG(1,("NetSessionGetInfo gave error %d\n", cli->rap_error)); + } + } + + if (rdata) { + res = GETRES(rparam); + + if (res == 0 || res == ERRmoredata) { + int rsize, converter; + pstring wsname, username, clitype_name; + uint16 num_conns, num_opens, num_users; + uint sess_time, idle_time, user_flags; + + p = rparam + WORDSIZE; + GETWORD(p, converter); + GETWORD(p, rsize); + + p = rdata; + GETSTRINGP(p, wsname, rdata, converter); + GETSTRINGP(p, username, rdata, converter); + GETWORD(p, num_conns); + GETWORD(p, num_opens); + GETWORD(p, num_users); + GETDWORD(p, sess_time); + GETDWORD(p, idle_time); + GETDWORD(p, user_flags); + GETSTRINGP(p, clitype_name, rdata, converter); + + fn(wsname, username, num_conns, num_opens, num_users, sess_time, + idle_time, user_flags, clitype_name); + } else { + DEBUG(4,("NetSessionGetInfo res=%d\n", res)); + } + } else { + DEBUG(4,("NetSessionGetInfo no data returned\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; +} + +/**************************************************************************** +call a NetSessionDel - close a session to an SMB server +****************************************************************************/ +int cli_NetSessionDel(struct cli_state *cli, char *workstation) +{ + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetSessionDel_REQ) /* req string */ + +1 /* no return string */ + +RAP_MACHNAME_LEN /* workstation name */ + +WORDSIZE]; /* reserved (0) */ + char *p; + char *rparam = NULL; + char *rdata = NULL; + int rprcnt, rdrcnt; + int res; + + bzero(param, sizeof(param)); + p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL); + PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1); + PUTWORD(p,0); /* reserved word of 0 */ + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, 200, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + res = GETRES(rparam); + cli->rap_error = res; + + if (res == 0) { + /* nothing to do */ + } + else { + DEBUG(4,("NetFileClose2 res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetFileClose2 failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; +} + + +int cli_NetConnectionEnum(struct cli_state *cli, char *qualifier, void (*fn)(uint16 conid, uint16 contype, uint16 numopens, uint16 numusers, uint32 contime, char *username, char *netname)) +{ + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetConnectionEnum_REQ) /* req string */ + +sizeof(RAP_CONNECTION_INFO_L1) /* return string */ + +RAP_MACHNAME_LEN /* wksta name */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + char *p; + char *rparam = NULL; + char *rdata = NULL; + int rprcnt, rdrcnt; + int res = -1; + + bzero(param, sizeof(param)); + p = make_header(param, RAP_WconnectionEnum, + RAP_NetConnectionEnum_REQ, RAP_CONNECTION_INFO_L1); + PUTSTRING(p, qualifier, RAP_MACHNAME_LEN-1);/* Workstation name */ + PUTWORD(p,1); /* Info level 1 */ + PUTWORD(p,0xFFE0); /* Return buffer size */ + + if (cli_api(cli, + param, PTR_DIFF(p,param),PTR_DIFF(p,param), + NULL, 0, CLI_BUFFER_SIZE, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { + res = GETRES(rparam); + cli->rap_error = res; + if (res != 0) { + DEBUG(1,("NetConnectionEnum gave error %d\n", res)); + } + } + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + + p = rparam + WORDSIZE; + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata;i Date: Sat, 20 Oct 2001 06:50:24 +0000 Subject: better krb5 error handling (thanks andrewb!) (This used to be commit fd3a3daef3b8f7140e7006d30d23d739ac3aad2f) --- source3/libsmb/clikrb5.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 51b6e6e8cf..5fef97c571 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -48,15 +48,22 @@ static krb5_error_code krb5_mk_req2(krb5_context context, /* obtain ticket & session key */ memset((char *)&creds, 0, sizeof(creds)); - if ((retval = krb5_copy_principal(context, server, &creds.server))) + if ((retval = krb5_copy_principal(context, server, &creds.server))) { + DEBUG(1,("krb5_copy_principal failed (%s)\n", + error_message(retval))); goto cleanup_princ; + } - if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) + if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { + DEBUG(1,("krb5_cc_get_principal failed (%s)\n", + error_message(retval))); goto cleanup_creds; + } if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { - DEBUG(1,("krb5_get_credentials failed (%d)\n", retval)); + DEBUG(1,("krb5_get_credentials failed (%s)\n", + error_message(retval))); goto cleanup_creds; } @@ -64,7 +71,8 @@ static krb5_error_code krb5_mk_req2(krb5_context context, retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); if (retval) { - DEBUG(1,("krb5_mk_req_extended failed (%d)\n", retval)); + DEBUG(1,("krb5_mk_req_extended failed (%s)\n", + error_message(retval))); } krb5_free_creds(context, credsp); @@ -92,12 +100,14 @@ DATA_BLOB krb5_get_ticket(char *service, char *realm) retval = krb5_init_context(&context); if (retval) { - DEBUG(1,("krb5_init_context failed\n")); + DEBUG(1,("krb5_init_context failed (%s)\n", + error_message(retval))); goto failed; } if ((retval = krb5_cc_default(context, &ccdef))) { - DEBUG(1,("krb5_cc_default failed\n")); + DEBUG(1,("krb5_cc_default failed (%s)\n", + error_message(retval))); goto failed; } @@ -106,7 +116,6 @@ DATA_BLOB krb5_get_ticket(char *service, char *realm) 0, service, realm, ccdef, &packet))) { - DEBUG(1,("krb5_mk_req2 failed\n")); goto failed; } -- cgit From 88b55f47b4914f7d390939e4394ec3edd42be91f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 20 Oct 2001 21:59:34 +0000 Subject: Move from timestamp to gen count file id's for finding oplocked files in a tdb. Jeremy. (This used to be commit 058ae6b58f61ef46013dd076af3a84de5fbaaab1) --- source3/libsmb/clirap2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 5da67de95c..5a834e7b7a 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -586,7 +586,7 @@ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo ) PUTWORD(p, 0); /* pwencrypt */ if(userinfo->passwrd) - PUTWORD(p,strnlen(userinfo->passwrd, RAP_UPASSWD_LEN)); + PUTWORD(p,MIN(strlen(userinfo->passwrd), RAP_UPASSWD_LEN)); else PUTWORD(p, 0); /* password length */ -- cgit From cbe31055f8deb5844b34e8f1b32e27c830d134ed Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 21 Oct 2001 00:11:22 +0000 Subject: support both old and new kerberos OIDs (This used to be commit eac164c7e650a8f855e7b662b126a5dfc5516927) --- source3/libsmb/cliconnect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4fba54900d..e24f081c69 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -528,7 +528,8 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { DEBUG(3,("got OID=%s\n", OIDs[i])); - if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0) { + if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || + strcmp(OIDs[i], OID_KERBEROS5) == 0) { got_kerberos_mechanism = True; } free(OIDs[i]); -- cgit From bbcd9deb07fe0cfcb2911093e1c99d30b210e7d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 21 Oct 2001 03:25:34 +0000 Subject: made smbclient cope better with arbitrary principle forms (This used to be commit d1341d74b7aa5f6b3f72e5409b245f87f1ad670b) --- source3/libsmb/cliconnect.c | 4 ++++ source3/libsmb/clikrb5.c | 12 +++++------- source3/libsmb/clispnego.c | 15 +-------------- 3 files changed, 10 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e24f081c69..11825ab036 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -387,6 +387,8 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principle, c { DATA_BLOB blob2, negTokenTarg; + d_printf("Doing kerberos session setup\n"); + /* generate the encapsulated kerberos5 ticket */ negTokenTarg = spnego_gen_negTokenTarg(cli, principle); @@ -509,6 +511,8 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, int i; BOOL got_kerberos_mechanism = False; + d_printf("Doing spnego session setup\n"); + /* the server might not even do spnego */ if (cli->secblob.length == 16) { DEBUG(3,("server didn't supply a full spnego negprot\n")); diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5fef97c571..98e27fb9c4 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -28,8 +28,7 @@ static krb5_error_code krb5_mk_req2(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, - const char *service, - const char *realm, + const char *principle, krb5_ccache ccache, krb5_data *outbuf) { @@ -39,10 +38,9 @@ static krb5_error_code krb5_mk_req2(krb5_context context, krb5_creds creds; krb5_data in_data; - retval = krb5_build_principal(context, &server, strlen(realm), - realm, service, NULL); + retval = krb5_parse_name(context, principle, &server); if (retval) { - DEBUG(1,("Failed to build principle for %s@%s\n", service, realm)); + DEBUG(1,("Failed to parse principle %s\n", principle)); return retval; } @@ -89,7 +87,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(char *service, char *realm) +DATA_BLOB krb5_get_ticket(char *principle) { krb5_error_code retval; krb5_data packet; @@ -114,7 +112,7 @@ DATA_BLOB krb5_get_ticket(char *service, char *realm) if ((retval = krb5_mk_req2(context, &auth_context, 0, - service, realm, + principle, ccdef, &packet))) { goto failed; } diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index c421d75913..bcce0f6173 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -271,24 +271,11 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) */ DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) { - char *p; - fstring service; - char *realm; DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; - fstrcpy(service, principle); - p = strchr_m(service, '@'); - if (!p) { - DEBUG(1,("Malformed principle [%s] in spnego_gen_negTokenTarg\n", - principle)); - return data_blob(NULL, 0); - } - *p = 0; - realm = p+1; - /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(service, realm); + tkt = krb5_get_ticket(principle); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); -- cgit From c41b64d81408e252a2cf5bc52d5ca5e07120a9c7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 21 Oct 2001 04:08:15 +0000 Subject: Fix for compilation on non-krb5 systems (This used to be commit 44bdb8b12b3d6a7bf3148c2ac651a79f10776db6) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 98e27fb9c4..5641692f2e 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -131,7 +131,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(char *service, char *realm) + DATA_BLOB krb5_get_ticket(char *principle) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); -- cgit From cfd68eaac48a29dec245dc6de03aae0d58698862 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 21 Oct 2001 20:51:27 +0000 Subject: Ok, I know it's a language thing and it shouldn't matter.... but a kerberos name is a "principal", not a principle. English majors will complain :-). Jeremy. (This used to be commit b668d7d656cdd066820fb8044f24bcd4fda29524) --- source3/libsmb/cliconnect.c | 14 +++++++------- source3/libsmb/clikrb5.c | 12 ++++++------ source3/libsmb/clispnego.c | 16 ++++++++-------- 3 files changed, 21 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 11825ab036..dc8c7c2957 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -383,14 +383,14 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /**************************************************************************** do a spnego/kerberos encrypted session setup ****************************************************************************/ -static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principle, char *workgroup) +static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, char *workgroup) { DATA_BLOB blob2, negTokenTarg; d_printf("Doing kerberos session setup\n"); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(cli, principle); + negTokenTarg = spnego_gen_negTokenTarg(cli, principal); if (!negTokenTarg.data) return False; @@ -505,7 +505,7 @@ do a spnego encrypted session setup static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, char *pass, char *workgroup) { - char *principle; + char *principal; char *OIDs[ASN1_MAX_OIDS]; uint8 guid[16]; int i; @@ -525,7 +525,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ - if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principle)) { + if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principal)) { return False; } @@ -538,17 +538,17 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, } free(OIDs[i]); } - DEBUG(3,("got principle=%s\n", principle)); + DEBUG(3,("got principal=%s\n", principal)); fstrcpy(cli->user_name, user); #if HAVE_KRB5 if (got_kerberos_mechanism && cli->use_kerberos) { - return cli_session_setup_kerberos(cli, principle, workgroup); + return cli_session_setup_kerberos(cli, principal, workgroup); } #endif - free(principle); + free(principal); ntlmssp: diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5641692f2e..b4ce271235 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -28,7 +28,7 @@ static krb5_error_code krb5_mk_req2(krb5_context context, krb5_auth_context *auth_context, const krb5_flags ap_req_options, - const char *principle, + const char *principal, krb5_ccache ccache, krb5_data *outbuf) { @@ -38,9 +38,9 @@ static krb5_error_code krb5_mk_req2(krb5_context context, krb5_creds creds; krb5_data in_data; - retval = krb5_parse_name(context, principle, &server); + retval = krb5_parse_name(context, principal, &server); if (retval) { - DEBUG(1,("Failed to parse principle %s\n", principle)); + DEBUG(1,("Failed to parse principal %s\n", principal)); return retval; } @@ -87,7 +87,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(char *principle) +DATA_BLOB krb5_get_ticket(char *principal) { krb5_error_code retval; krb5_data packet; @@ -112,7 +112,7 @@ DATA_BLOB krb5_get_ticket(char *principle) if ((retval = krb5_mk_req2(context, &auth_context, 0, - principle, + principal, ccdef, &packet))) { goto failed; } @@ -131,7 +131,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(char *principle) + DATA_BLOB krb5_get_ticket(char *principal) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index bcce0f6173..784463566f 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -23,11 +23,11 @@ /* generate a negTokenInit packet given a GUID, a list of supported - OIDs (the mechanisms) and a principle name string + OIDs (the mechanisms) and a principal name string */ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], const char *OIDs[], - const char *principle) + const char *principal) { int i; ASN1_DATA data; @@ -52,7 +52,7 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_GeneralString(&data,principle); + asn1_write_GeneralString(&data,principal); asn1_pop_tag(&data); asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -76,12 +76,12 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], /* parse a negTokenInit packet giving a GUID, a list of supported - OIDs (the mechanisms) and a principle name string + OIDs (the mechanisms) and a principal name string */ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, uint8 guid[16], char *OIDs[ASN1_MAX_OIDS], - char **principle) + char **principal) { int i; BOOL ret; @@ -109,7 +109,7 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data, ASN1_CONTEXT(3)); asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(&data,principle); + asn1_read_GeneralString(&data,principal); asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); @@ -269,13 +269,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) +DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principal) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principle); + tkt = krb5_get_ticket(principal); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); -- cgit From 18ffa22657b694857cc948949e567a514bc68d65 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 22 Oct 2001 02:50:20 +0000 Subject: Fix for @ in pathname from Kian Win. Jeremy. (This used to be commit 070fd5180fef921efb363ff24f04a298254f108b) --- source3/libsmb/libsmbclient.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 9dca4637f4..6a00855bff 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -92,6 +92,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, static pstring s; pstring userinfo; char *p; + char *q, *r; int len; server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; @@ -133,7 +134,10 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, * exists ... */ - if (strchr_m(p, '@')) { + /* check that '@' occurs before '/', if '/' exists at all */ + q = strchr_m(p, '@'); + r = strchr_m(p, '/'); + if (q && (!r || q < r)) { pstring username, passwd, domain; char *u = userinfo; -- cgit From 4ccdb15532ef707dea44e2c7316e2a3334abab86 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 Oct 2001 06:48:35 +0000 Subject: a quick fix to get rpcclient working again. This just disables NTLMSSP in cli_establish_connection() What we really need to do is kill off the pwd_cache code. It is horrible, and assumes the challenge comes in the negprot reply. (This used to be commit 3f919b4360b3bfcc133f7d88bc5177e9d93f2db2) --- source3/libsmb/cliconnect.c | 4 ++++ source3/libsmb/clientgen.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index dc8c7c2957..2dad0247b2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1087,6 +1087,10 @@ BOOL cli_establish_connection(struct cli_state *cli, return False; } + /* cli_establish_connection() can't handle spnego yet. Once we get rid of + pwd_cache and other horrors we can get rid of this */ + cli->use_spnego = False; + if (cli->fd == -1) { if (!cli_connect(cli, dest_host, dest_ip)) diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ed0bc6481e..ec8d2e2bfc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -112,7 +112,9 @@ void cli_setup_packet(struct cli_state *cli) if (cli->capabilities & CAP_STATUS32) { flags2 |= FLAGS2_32_BIT_ERROR_CODES; } - flags2 |= FLAGS2_EXTENDED_SECURITY; + if (cli->use_spnego) { + flags2 |= FLAGS2_EXTENDED_SECURITY; + } SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -179,6 +181,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; + cli->use_spnego = True; if (!cli->outbuf || !cli->inbuf) goto error; -- cgit From b8fe0f6711977412f8a7103022b01f3428d9c3a0 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 23 Oct 2001 20:39:38 +0000 Subject: more compiler warnings (This used to be commit 12c10e876ea528fdf33e8ecfe42ab0ebb346b143) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2dad0247b2..680f30900e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -460,8 +460,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, /* encrypt the password with the challenge */ memcpy(challenge, chal1.data + 24, 8); - SMBencrypt(pass, challenge,lmhash); - SMBNTencrypt(pass, challenge,nthash); + SMBencrypt((unsigned char *)pass, challenge,lmhash); + SMBNTencrypt((unsigned char *)pass, challenge,nthash); #if 0 file_save("nthash.dat", nthash, 24); -- cgit From d9d7f023d8d11943ca0375e1573e6ec9921889bc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Oct 2001 07:35:11 +0000 Subject: This commit is number 4 of 4. In particular this commit focuses on: Actually adding the 'const' to the passdb interface, and the flow-on changes. Also kill off the 'disp_info' stuff, as its no longer used. While these changes have been mildly tested, and are pretty small, any assistance in this is appreciated. ---- These changes introduces a large dose of 'const' to the Samba tree. There are a number of good reasons to do this: - I want to allow the SAM_ACCOUNT structure to move from wasteful pstrings and fstrings to allocated strings. We can't do that if people are modifying these outputs, as they may well make assumptions about getting pstrings and fstrings - I want --with-pam_smbpass to compile with a slightly sane volume of warnings, currently its pretty bad, even in 2.2 where is compiles at all. - Tridge assures me that he no longer opposes 'const religion' based on the ability to #define const the problem away. - Changed Get_Pwnam(x,y) into two variants (so that the const parameter can work correctly): - Get_Pwnam(const x) and Get_Pwnam_Modify(x). - Reworked smbd/chgpasswd.c to work with these mods, passing around a 'struct passwd' rather than the modified username --- This finishes this line of commits off, your tree should now compile again :-) Andrew Bartlett (This used to be commit c95f5aeb9327347674589ae313b75bee3bf8e317) --- source3/libsmb/smbdes.c | 10 +++++----- source3/libsmb/smbencrypt.c | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 30a5746934..866fc0c7e0 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -319,19 +319,19 @@ void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24 smbhash(p24+16, c8, p21+14, 1); } -void D_P16(unsigned char *p14, unsigned char *in, unsigned char *out) +void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out) { smbhash(out, in, p14, 0); smbhash(out+8, in+8, p14+7, 0); } -void E_old_pw_hash( unsigned char *p14, unsigned char *in, unsigned char *out) +void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out) { smbhash(out, in, p14, 1); smbhash(out+8, in+8, p14+7, 1); } -void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) +void cred_hash1(unsigned char *out, const unsigned char *in,unsigned char *key) { unsigned char buf[8]; @@ -339,7 +339,7 @@ void cred_hash1(unsigned char *out,unsigned char *in,unsigned char *key) smbhash(out, buf, key+9, 1); } -void cred_hash2(unsigned char *out,unsigned char *in,unsigned char *key) +void cred_hash2(unsigned char *out, const unsigned char *in,unsigned char *key) { unsigned char buf[8]; static unsigned char key2[8]; @@ -358,7 +358,7 @@ void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int for smbhash(out + 8, in + 8, key2, forw); } -void SamOEMhash( unsigned char *data, unsigned char *key, int val) +void SamOEMhash( unsigned char *data, const unsigned char *key, int val) { unsigned char s_box[256]; unsigned char index_i = 0; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 4b127051b4..9b0ef37eb6 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -29,13 +29,13 @@ This implements the X/Open SMB password encryption It takes a password, a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) +void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) { uchar p14[15], p21[21]; memset(p21,'\0',21); memset(p14,'\0',14); - StrnCpy((char *)p14,(char *)passwd,14); + StrnCpy((char *)p14,(const char *)passwd,14); strupper((char *)p14); E_P16(p14, p21); @@ -45,7 +45,7 @@ void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24) #ifdef DEBUG_PASSWORD DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); dump_data(100, (char *)p21, 16); - dump_data(100, (char *)c8, 8); + dump_data(100, (const char *)c8, 8); dump_data(100, (char *)p24, 24); #endif } @@ -72,7 +72,7 @@ void E_md4hash(uchar *passwd, uchar *p16) } /* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16]) +void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) { char passwd[514]; @@ -147,7 +147,7 @@ void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) } /* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */ -void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) +void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p24[24]) { uchar p21[21]; @@ -159,7 +159,7 @@ void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24]) #ifdef DEBUG_PASSWORD DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); dump_data(100, (char *)p21, 21); - dump_data(100, (char *)ntlmchalresp, 8); + dump_data(100, (const char *)ntlmchalresp, 8); dump_data(100, (char *)p24, 24); #endif } -- cgit From fab88997b021ad66dd7f03220d95d1f7ee315140 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Oct 2001 08:12:44 +0000 Subject: This patch applied, except without the structure changes to nmblib.c Andrew Bartlett. From kai@cmail.ru Mon Oct 29 18:50:42 2001 Date: Fri, 19 Oct 2001 17:26:06 +0300 From: Andrew V. Samoilov To: samba-technical@lists.samba.org Subject: [patch]: makes some arrays const to be shared between processes Hi! This patch makes some arrays const. So these arrays go to text/rodata segment and are shared between all of the processes which use shared library with these arrays. Regards, Andrew V. Samoilov. P.S. Please cc your answer to kai@cmail.ru, I don't subscribed to this list. ChangeLog: * cliconnect.c (prots): Make const. * clierror.c (rap_errmap): Likewise. * nmblib.c (nmb_header_opcode_names): Likewise. (lookup_opcode_name): Make opcode_namep const. Eliminate i. * nterr.c (nt_err_code_struct): Typedef const. * smberr.c (err_code_struct): Make const. (err_classes): Likewise. (This used to be commit cb84485a2b0e1fdcb6fa90e0bfb97e125ae1b3dd) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clierror.c | 2 +- source3/libsmb/nmblib.c | 6 +++--- source3/libsmb/nterr.c | 2 +- source3/libsmb/smberr.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 680f30900e..aae21cb6d9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -24,7 +24,7 @@ #include "includes.h" -static struct { +static const struct { int prot; const char *name; } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index bcecc92d77..fe793d4b0e 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -27,7 +27,7 @@ RAP error codes - a small start but will be extended. *******************************************************/ -static struct +static const struct { int err; char *message; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d7bd7b49a0..dc39924818 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -25,7 +25,7 @@ int num_good_sends = 0; int num_good_receives = 0; -static struct opcode_names { +static const struct opcode_names { char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { @@ -42,9 +42,9 @@ static struct opcode_names { /**************************************************************************** * Lookup a nmb opcode name. ****************************************************************************/ -static char *lookup_opcode_name( int opcode ) +static const char *lookup_opcode_name( int opcode ) { - struct opcode_names *op_namep; + const struct opcode_names *op_namep; int i; for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 1f61e648c2..ab0a425633 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -23,7 +23,7 @@ #include "includes.h" -typedef struct +typedef const struct { char *nt_errstr; NTSTATUS nt_errcode; diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 0b59b5b1a5..66256d2385 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -25,7 +25,7 @@ /* error code stuff - put together by Merik Karman merik@blackadder.dsh.oz.au */ -typedef struct +typedef const struct { char *name; int code; @@ -125,7 +125,7 @@ err_code_struct hard_msgs[] = { {NULL,-1,NULL}}; -struct +const struct { int code; char *class; -- cgit From 5c3ccf77666ab63e8dfc980188c365a7b15bafcf Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 30 Oct 2001 01:49:44 +0000 Subject: Added samlogon command to test against win2k native mode server. I think there's a bug in the marshalling of net_sam_logon. (This used to be commit 7c5ac46b8ad0be681d102e7ef3478d64d7a2b8e6) --- source3/libsmb/cli_netlogon.c | 72 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 98f448c6a7..21a97466a0 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -392,3 +392,75 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Logon domain user */ + +NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *username, char *password, + int validation_level) +{ + prs_struct qbuf, rbuf; + NET_Q_SAM_LOGON q; + NET_R_SAM_LOGON r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + DOM_CRED clnt_creds, dummy_rtn_creds; + extern pstring global_myname; + NET_ID_INFO_CTR ctr; + uint8 chal[8]; + unsigned char local_lm_response[24]; + unsigned char local_nt_response[24]; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + gen_next_creds(cli, &clnt_creds); + + q.validation_level = validation_level; + + memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); + dummy_rtn_creds.timestamp.time = time(NULL); + + generate_random_buffer(chal, 8, False); + + SMBencrypt(password, chal, local_lm_response); + SMBNTencrypt(password, chal, local_nt_response); + + ctr.switch_value = NET_LOGON_TYPE; + init_id_info2(&ctr.auth.id2, lp_workgroup(), 0, + 0xdead, 0xbeef, /* LUID? */ + username, global_myname, chal, + local_lm_response, 24, local_nt_response, 24); + + init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, + &clnt_creds, &dummy_rtn_creds, ctr.switch_value, + &ctr); + + /* Marshall data and send request */ + + if (!net_io_q_sam_logon("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return results */ + + result = r.status; + + done: + return result; +} -- cgit From f441ccd4844915c25b8b3420b2c6c10aa31212bd Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 30 Oct 2001 05:38:41 +0000 Subject: Allow the logon level to be passed to cli_netlogon_sam_logon() rather than the validation level. This allows us to test interactive or network logons. Interestingly enough a win2k native mode server generates a rpc fault when presented with a network logon! (This used to be commit 0758c0ea845dd0b552e4dab3ce05f0811fa9658e) --- source3/libsmb/cli_netlogon.c | 54 ++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 21a97466a0..45564ae27c 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -397,7 +397,7 @@ NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *username, char *password, - int validation_level) + int logon_type) { prs_struct qbuf, rbuf; NET_Q_SAM_LOGON q; @@ -406,9 +406,8 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED clnt_creds, dummy_rtn_creds; extern pstring global_myname; NET_ID_INFO_CTR ctr; - uint8 chal[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_response[24]; + NET_USER_INFO_3 user; + int validation_level = 3; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -427,19 +426,46 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); dummy_rtn_creds.timestamp.time = time(NULL); - generate_random_buffer(chal, 8, False); + ctr.switch_value = logon_type; - SMBencrypt(password, chal, local_lm_response); - SMBNTencrypt(password, chal, local_nt_response); + switch (logon_type) { + case INTERACTIVE_LOGON_TYPE: { + unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; - ctr.switch_value = NET_LOGON_TYPE; - init_id_info2(&ctr.auth.id2, lp_workgroup(), 0, - 0xdead, 0xbeef, /* LUID? */ - username, global_myname, chal, - local_lm_response, 24, local_nt_response, 24); + nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); + + init_id_info1(&ctr.auth.id1, lp_workgroup(), 0, + 0xdead, 0xbeef, /* LUID? */ + username, global_myname, + cli->sess_key, lm_owf_user_pwd, + nt_owf_user_pwd); + + break; + } + case NET_LOGON_TYPE: { + uint8 chal[8]; + unsigned char local_lm_response[24]; + unsigned char local_nt_response[24]; + + generate_random_buffer(chal, 8, False); + + SMBencrypt(password, chal, local_lm_response); + SMBNTencrypt(password, chal, local_nt_response); + + init_id_info2(&ctr.auth.id2, lp_workgroup(), 0, + 0xdead, 0xbeef, /* LUID? */ + username, global_myname, chal, + local_lm_response, 24, local_nt_response, 24); + break; + } + default: + DEBUG(0, ("switch value %d not supported\n", + ctr.switch_value)); + break; + } init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, - &clnt_creds, &dummy_rtn_creds, ctr.switch_value, + &clnt_creds, &dummy_rtn_creds, logon_type, &ctr); /* Marshall data and send request */ @@ -452,6 +478,8 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Unmarshall response */ + r.user = &user; + if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { result = NT_STATUS_UNSUCCESSFUL; goto done; -- cgit From a947591674d6baf747809464b34b03ea165d2b13 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 30 Oct 2001 05:54:38 +0000 Subject: Fix debug in domain_client_validate() when password server = *. (This used to be commit c78fec86c97075bb5726fcb7ed197bc75dd88ac0) --- source3/libsmb/domain_client_validate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 255b37883d..26f53f0297 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -330,7 +330,7 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, DEBUG(0,("domain_client_validate: unable to validate password " "for user %s in domain %s to Domain controller %s. " "Error was %s.\n", user_info->smb_username.str, - user_info->domain.str, remote_machine, + user_info->domain.str, cli.srv_name_slash, get_nt_error_msg(status))); } -- cgit From 2fc8e32ad342e3285e0d30a3a102e06ec4af5199 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 01:52:34 +0000 Subject: Parionia to ensure people don't install libsmb based programs setuid root. libsmb has not been written to be setuid, with things like LIBSMB_PROG allowing all sort of fun and games. Andrew Bartlett (This used to be commit 0c8e9339d8238de92e9146d04091694b62874c33) --- source3/libsmb/clientgen.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ec8d2e2bfc..d509924a26 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -154,6 +154,12 @@ struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; + /* Check the effective uid - make sure we are not setuid */ + if (is_setuid_root()) { + DEBUG(0,("libsmb based programs must *NOT* be setuid root.\n")); + return NULL; + } + if (!cli) { cli = (struct cli_state *)malloc(sizeof(*cli)); if (!cli) -- cgit From 3e2f355a2ed4b372585d259839ff67d20e5d61d1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 31 Oct 2001 04:26:36 +0000 Subject: Some tweaking to make the samlogon function look more like NT on the wire. (This used to be commit b30232e2b7ddb5eab419d4e6237176f695a534ad) --- source3/libsmb/cli_netlogon.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 45564ae27c..7499d9ca7b 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -434,9 +434,10 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); - init_id_info1(&ctr.auth.id1, lp_workgroup(), 0, + init_id_info1(&ctr.auth.id1, lp_workgroup(), + 0, /* param_ctrl */ 0xdead, 0xbeef, /* LUID? */ - username, global_myname, + username, cli->clnt_name_slash, cli->sess_key, lm_owf_user_pwd, nt_owf_user_pwd); @@ -452,16 +453,17 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, SMBencrypt(password, chal, local_lm_response); SMBNTencrypt(password, chal, local_nt_response); - init_id_info2(&ctr.auth.id2, lp_workgroup(), 0, + init_id_info2(&ctr.auth.id2, lp_workgroup(), + 0, /* param_ctrl */ 0xdead, 0xbeef, /* LUID? */ - username, global_myname, chal, + username, cli->clnt_name_slash, chal, local_lm_response, 24, local_nt_response, 24); break; } default: DEBUG(0, ("switch value %d not supported\n", ctr.switch_value)); - break; + goto done; } init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, @@ -472,7 +474,6 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (!net_io_q_sam_logon("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } @@ -481,7 +482,6 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, r.user = &user; if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; goto done; } -- cgit From 6f0b8a38ec036a0027e9f938834e241b41db40c5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 31 Oct 2001 06:20:58 +0000 Subject: Added some extra fields to the auth_serversupplied_info structure. To obtain the full group membership of a user (i.e nested groups on a win2k native mode server) it is necessary to merge this list of groups with the groups returned by winbindd when creating an nt access token. This breaks winbindd linking while AB and I sync up our changes to the authentication subsystem. (This used to be commit 4eeb7bcd783d7cfb3ac232f1faa035773007401d) --- source3/libsmb/domain_client_validate.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 26f53f0297..26a727b1f1 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -326,6 +326,7 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, status = cli_nt_login_network(&cli, user_info, smb_uid_low, &ctr, &info3); + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("domain_client_validate: unable to validate password " "for user %s in domain %s to Domain controller %s. " @@ -335,8 +336,28 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, } /* - * Here, if we really want it, we have lots of info about the user in info3. - */ + * Here, if we really want it, we have lots of info about the user + * in info3. + */ + + /* Store the user group information in the server_info returned to + the caller. */ + + if ((server_info->group_rids = malloc(info3.num_groups2 * + sizeof(uint32))) == NULL) { + DEBUG(1, ("out of memory allocating rid group membership\n")); + status = NT_STATUS_NO_MEMORY; + } else { + int i; + + server_info->n_rids = info3.num_groups2; + + for (i = 0; i < server_info->n_rids; i++) { + server_info->group_rids[i] = info3.gids[i].g_rid; + DEBUG(5, ("** adding group rid 0x%x\n", + info3.gids[i].g_rid)); + } + } #if 0 /* -- cgit From 83575bd3868ef3993107460d2c8e05f382eae351 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 06:57:28 +0000 Subject: More const. (This used to be commit ceba373aa30e09be948bd0980040cba204d12084) --- source3/libsmb/smbencrypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 9b0ef37eb6..2868b02ed9 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -54,13 +54,13 @@ void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) * Creates the MD4 Hash of the users password in NT UNICODE. */ -void E_md4hash(uchar *passwd, uchar *p16) +void E_md4hash(const uchar *passwd, uchar *p16) { int len; smb_ucs2_t wpwd[129]; /* Password cannot be longer than 128 characters */ - len = strlen((char *)passwd); + len = strlen((const char *)passwd); if(len > 128) len = 128; /* Password must be converted to NT unicode - null terminated. */ -- cgit From 60f0627afb167faad57385d44f0b587186a7ac2b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 10:46:25 +0000 Subject: This is a farily large patch (3300 lines) and reworks most of the AuthRewrite code. In particular this assists tpot in some of his work, becouse it provides the connection between the authenticaion and the vuid generation. Major Changes: - Fully malloc'ed structures. - Massive rework of the code so that all structures are made and destroyed using malloc and free, rather than hanging around on the stack. - SAM_ACCOUNT unix uids and gids are now pointers to the same, to allow them to be declared 'invalid' without the chance that people might get ROOT by default. - kill off some of the "DOMAIN\user" lookups. These can be readded at a more appropriate place (probably domain_client_validate.c) in the future. They don't belong in session setups. - Massive introduction of DATA_BLOB structures, particularly for passwords. - Use NTLMSSP flags to tell the backend what its getting, rather than magic lenghths. - Fix winbind back up again, but tpot is redoing this soon anyway. - Abstract much of the work in srv_netlog_nt back into auth helper functions. This is a LARGE change, and any assistance is testing it is appriciated. Domain logons are still broken (as far as I can tell) but other functionality seems intact. Needs testing with a wide variety of MS clients. Andrew Bartlett (This used to be commit f70fb819b2f57bd57232b51808345e2319d52f6c) --- source3/libsmb/domain_client_validate.c | 61 ++++++++++++++++++++------------- source3/libsmb/smbencrypt.c | 16 ++++----- 2 files changed, 46 insertions(+), 31 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 26a727b1f1..20db1ee4d6 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -271,7 +271,7 @@ static BOOL find_connect_pdc(struct cli_state *pcli, ************************************************************************/ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, - auth_serversupplied_info *server_info, + auth_serversupplied_info **server_info, char *server, unsigned char *trust_passwd, time_t last_change_time) { @@ -282,6 +282,7 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, uint32 smb_uid_low; BOOL connected_ok = False; NTSTATUS status; + struct passwd *pass; /* * Check that the requested domain is not our own machine name. @@ -330,34 +331,48 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("domain_client_validate: unable to validate password " "for user %s in domain %s to Domain controller %s. " - "Error was %s.\n", user_info->smb_username.str, + "Error was %s.\n", user_info->smb_name.str, user_info->domain.str, cli.srv_name_slash, get_nt_error_msg(status))); - } + } else { - /* - * Here, if we really want it, we have lots of info about the user - * in info3. - */ + /* + * Here, if we really want it, we have lots of info about the user + * in info3. + */ + + pass = Get_Pwnam(user_info->internal_username.str); + if (pass) { + make_server_info_pw(server_info, pass); + if (!server_info) { + status = NT_STATUS_NO_MEMORY; + } + } else { + status = NT_STATUS_NO_SUCH_USER; + } + } /* Store the user group information in the server_info returned to the caller. */ - - if ((server_info->group_rids = malloc(info3.num_groups2 * - sizeof(uint32))) == NULL) { - DEBUG(1, ("out of memory allocating rid group membership\n")); - status = NT_STATUS_NO_MEMORY; - } else { - int i; - - server_info->n_rids = info3.num_groups2; - - for (i = 0; i < server_info->n_rids; i++) { - server_info->group_rids[i] = info3.gids[i].g_rid; - DEBUG(5, ("** adding group rid 0x%x\n", - info3.gids[i].g_rid)); - } - } + + if (NT_STATUS_IS_OK(status)) { + if (((*server_info)->group_rids = malloc(info3.num_groups2 * + sizeof(uint32))) == NULL) { + DEBUG(1, ("out of memory allocating rid group membership\n")); + status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + } else { + int i; + + (*server_info)->n_rids = info3.num_groups2; + + for (i = 0; i < (*server_info)->n_rids; i++) { + (*server_info)->group_rids[i] = info3.gids[i].g_rid; + DEBUG(5, ("** adding group rid 0x%x\n", + info3.gids[i].g_rid)); + } + } + } #if 0 /* diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 2868b02ed9..c1c4750e05 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -216,27 +216,27 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ /* Does the md5 encryption from the NT hash for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], - const uchar * srv_chal, int srv_chal_len, - const uchar * cli_chal, int cli_chal_len, + const DATA_BLOB srv_chal, + const DATA_BLOB cli_chal, char resp_buf[16]) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(srv_chal, srv_chal_len, &ctx); - hmac_md5_update(cli_chal, cli_chal_len, &ctx); + hmac_md5_update(srv_chal.data, srv_chal.length, &ctx); + hmac_md5_update(cli_chal.data, cli_chal.length, &ctx); hmac_md5_final((unsigned char *)resp_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); - dump_data(100, srv_chal, srv_chal_len); - dump_data(100, cli_chal, cli_chal_len); + dump_data(100, srv_chal.data, srv_chal.length); + dump_data(100, cli_chal.data, cli_chal.length); dump_data(100, resp_buf, 16); #endif } void SMBsesskeygen_ntv2(const uchar kr[16], - const uchar * nt_resp, char sess_key[16]) + const uchar * nt_resp, uint8 sess_key[16]) { HMACMD5Context ctx; @@ -251,7 +251,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], } void SMBsesskeygen_ntv1(const uchar kr[16], - const uchar * nt_resp, char sess_key[16]) + const uchar * nt_resp, uint8 sess_key[16]) { mdfour((unsigned char *)sess_key, kr, 16); -- cgit From 22926c814d238c462f9957f2753c7ce7dc7a6797 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sat, 3 Nov 2001 21:12:44 +0000 Subject: Added support for UserListGroups, ServiceEnum (This used to be commit 4e882289b0e291bb57d48fc2b2120919632daa5f) --- source3/libsmb/clirap2.c | 125 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 5a834e7b7a..f19ec3e758 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -497,6 +497,62 @@ int cli_NetGroupGetUsers(struct cli_state * cli, char * group_name, void (*fn)(c return res; } +int cli_NetUserGetGroups(struct cli_state * cli, char * user_name, void (*fn)(const char *, void *), void *state ) +{ + char *rparam = NULL; + char *rdata = NULL; + char *p; + int rdrcnt,rprcnt; + int res = -1; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetUserGetGroups_REQ)/* parm string */ + +sizeof(RAP_GROUP_USERS_INFO_0) /* return string */ + +RAP_USERNAME_LEN /* user name */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + + /* now send a SMBtrans command with api GroupGetUsers */ + p = make_header(param, RAP_WUserGetGroups, + RAP_NetUserGetGroups_REQ, RAP_GROUP_USERS_INFO_0); + PUTSTRING(p,user_name,RAP_USERNAME_LEN-1); + PUTWORD(p,0); /* info level 0 */ + PUTWORD(p,0xFFE0); /* return buffer size */ + + if (cli_api(cli, + param, PTR_DIFF(p,param),PTR_DIFF(p,param), + NULL, 0, CLI_BUFFER_SIZE, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { + res = GETRES(rparam); + cli->rap_error = res; + if (res != 0) { + DEBUG(1,("NetUserGetGroups gave error %d\n", res)); + } + } + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + fstring groupname; + p = rparam +WORDSIZE; + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata; irap_error = res; + if(cli->rap_error == 234) + DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n")); + else if (cli->rap_error != 0) { + DEBUG(1,("NetServiceEnum gave error %d\n", cli->rap_error)); + } + } + + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + + p = rparam + WORDSIZE; /* skip result */ + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata;i Date: Sat, 3 Nov 2001 23:34:24 +0000 Subject: Added NT_USER_TOKEN into server_info to fix extra groups problem. Got "medieval on our ass" about const warnings (as many as I could :-). Jeremy. (This used to be commit ee5e7ca547eff016818ba5c43b8ea0c9fa69b808) --- source3/libsmb/asn1.c | 29 +++++++++++-------- source3/libsmb/clifile.c | 6 ++-- source3/libsmb/domain_client_validate.c | 50 ++++++++++++++++++++++----------- source3/libsmb/pwd_cache.c | 16 ++--------- 4 files changed, 58 insertions(+), 43 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index a8c0eebb94..50cf6a7142 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -32,14 +32,14 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { - uint8 *p; - p = Realloc(data->data, data->ofs+len); - if (!p) { + uint8 *newp; + newp = Realloc(data->data, data->ofs+len); + if (!newp) { SAFE_FREE(data->data); data->has_error = True; return False; } - data->data = p; + data->data = newp; data->length = data->ofs+len; } memcpy(data->data + data->ofs, p, len); @@ -112,20 +112,27 @@ BOOL asn1_pop_tag(ASN1_DATA *data) BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) { unsigned v, v2; - char *p = (char *)OID; + const char *p = (const char *)OID; + char *newp; - if (!asn1_push_tag(data, ASN1_OID)) return False; - v = strtol(p, &p, 10); - v2 = strtol(p, &p, 10); - if (!asn1_write_uint8(data, 40*v + v2)) return False; + if (!asn1_push_tag(data, ASN1_OID)) + return False; + v = strtol(p, &newp, 10); + p = newp; + v2 = strtol(p, &newp, 10); + p = newp; + if (!asn1_write_uint8(data, 40*v + v2)) + return False; while (*p) { - v = strtol(p, &p, 10); + v = strtol(p, &newp, 10); + p = newp; if (v >= (1<<28)) asn1_write_uint8(data, 0x80 | ((v>>28)&0xff)); if (v >= (1<<21)) asn1_write_uint8(data, 0x80 | ((v>>21)&0xff)); if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff)); if (v >= (1<<7)) asn1_write_uint8(data, 0x80 | ((v>>7)&0xff)); - if (!asn1_write_uint8(data, v&0x7f)) return False; + if (!asn1_write_uint8(data, v&0x7f)) + return False; } return asn1_pop_tag(data); } diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index e9981d7205..d9f8e19910 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -212,7 +212,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) Used in smbtorture. ****************************************************************************/ -int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, +int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess, uint32 FileAttributes, uint32 ShareAccess, uint32 CreateDisposition, uint32 CreateOptions) { @@ -268,7 +268,7 @@ int cli_nt_create_full(struct cli_state *cli, char *fname, uint32 DesiredAccess, open a file ****************************************************************************/ -int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) +int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess) { return cli_nt_create_full(cli, fname, DesiredAccess, 0, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0); @@ -278,7 +278,7 @@ int cli_nt_create(struct cli_state *cli, char *fname, uint32 DesiredAccess) open a file WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ -int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) +int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode) { char *p; unsigned openfn=0; diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 20db1ee4d6..7a8fa66841 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -352,25 +352,41 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, } } - /* Store the user group information in the server_info returned to - the caller. */ + /* Store the user group information in the server_info returned to the caller. */ - if (NT_STATUS_IS_OK(status)) { - if (((*server_info)->group_rids = malloc(info3.num_groups2 * - sizeof(uint32))) == NULL) { - DEBUG(1, ("out of memory allocating rid group membership\n")); + if (NT_STATUS_IS_OK(status) && (info3.num_groups2 != 0)) { + DOM_SID domain_sid; + int i; + NT_USER_TOKEN *ptok; + auth_serversupplied_info *pserver_info = *server_info; + + if ((pserver_info->ptok = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { + DEBUG(0, ("domain_client_validate: out of memory allocating rid group membership\n")); status = NT_STATUS_NO_MEMORY; free_server_info(server_info); - } else { - int i; - - (*server_info)->n_rids = info3.num_groups2; - - for (i = 0; i < (*server_info)->n_rids; i++) { - (*server_info)->group_rids[i] = info3.gids[i].g_rid; - DEBUG(5, ("** adding group rid 0x%x\n", - info3.gids[i].g_rid)); - } + goto done; + } + + ptok = pserver_info->ptok; + ptok->num_sids = (size_t)info3.num_groups2; + + if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) { + DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n")); + status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { + DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n")); + status = NT_STATUS_NO_MEMORY; + free_server_info(server_info); + goto done; + } + + for (i = 0; i < ptok->num_sids; i++) { + sid_copy(&ptok->user_sids[i], &domain_sid); + sid_append_rid(&ptok->user_sids[i], info3.gids[i].g_rid); } } @@ -390,6 +406,8 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, } #endif /* 0 */ + done: + /* Note - once the cli stream is shutdown the mem_ctx used to allocate the other_sids and gids structures has been deleted - so these pointers are no longer valid..... */ diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 64e23e0feb..4a2c5f1604 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -49,41 +49,31 @@ BOOL pwd_is_nullpwd(const struct pwd_info *pwd) /**************************************************************************** compares two passwords. hmm, not as trivial as expected. hmm. ****************************************************************************/ -BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2) +BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2) { - if (pwd1->cleartext && pwd2->cleartext) - { + if (pwd1->cleartext && pwd2->cleartext) { if (strequal(pwd1->password, pwd2->password)) - { return True; - } } if (pwd1->null_pwd && pwd2->null_pwd) - { return True; - } if (!pwd1->null_pwd && !pwd2->null_pwd && - !pwd1->cleartext && !pwd2->cleartext) - { + !pwd1->cleartext && !pwd2->cleartext) { #ifdef DEBUG_PASSWORD DEBUG(100,("pwd compare: nt#\n")); dump_data(100, pwd1->smb_nt_pwd, 16); dump_data(100, pwd2->smb_nt_pwd, 16); #endif if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) - { return True; - } #ifdef DEBUG_PASSWORD DEBUG(100,("pwd compare: lm#\n")); dump_data(100, pwd1->smb_lm_pwd, 16); dump_data(100, pwd2->smb_lm_pwd, 16); #endif if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) - { return True; - } } return False; } -- cgit From 30be58a857e874fe439256726fbe182a2b578f11 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 4 Nov 2001 00:14:08 +0000 Subject: Got serious about const again. REMOVED BZERO CALLS YET AGAIN !!! Why do these keep creeping back in.... They are *NOT* POSIX. I'm also thinking of removing strncpy as I'm sure it's not being used correctly.... Jeremy. (This used to be commit b1930abb35dee74f858a3f7190276c418af2322b) --- source3/libsmb/clidgram.c | 8 +-- source3/libsmb/clifile.c | 133 ++++++++++++++++++++++----------------------- source3/libsmb/clirap2.c | 53 ++++++++++-------- source3/libsmb/namequery.c | 4 +- 4 files changed, 100 insertions(+), 98 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index fc1453dce1..e990739de5 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -41,7 +41,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, char *ptr, *p2; char tmp[4]; - bzero((char *)&p, sizeof(p)); + memset((char *)&p, '\0', sizeof(p)); /* * Next, build the DGRAM ... @@ -183,7 +183,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) /* Now, bind a local addr to it ... Try port 138 first ... */ - bzero((char *)&sock_out, sizeof(sock_out)); + memset((char *)&sock_out, '\0', sizeof(sock_out)); sock_out.sin_addr.s_addr = INADDR_ANY; sock_out.sin_port = htons(138); sock_out.sin_family = AF_INET; @@ -213,8 +213,8 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) /* Now, build the request */ - bzero(cli_backup_list, sizeof(cli_backup_list)); - bzero(outbuf, sizeof(outbuf)); + memset(cli_backup_list, '\0', sizeof(cli_backup_list)); + memset(outbuf, '\0', sizeof(outbuf)); p = outbuf; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d9f8e19910..5c37255278 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -24,49 +24,47 @@ #include "includes.h" /**************************************************************************** -rename a file + Rename a file. ****************************************************************************/ -BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst) + +BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst) { - char *p; + char *p; - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 0, True); + set_message(cli->outbuf,1, 0, True); - CVAL(cli->outbuf,smb_com) = SMBmv; - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + CVAL(cli->outbuf,smb_com) = SMBmv; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); - p = smb_buf(cli->outbuf); - *p++ = 4; - p += clistr_push(cli, p, fname_src, -1, - STR_TERMINATE); - *p++ = 4; - p += clistr_push(cli, p, fname_dst, -1, - STR_TERMINATE); + p = smb_buf(cli->outbuf); + *p++ = 4; + p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + *p++ = 4; + p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; - if (cli_is_error(cli)) { - return False; - } + if (cli_is_error(cli)) + return False; - return True; + return True; } /**************************************************************************** -delete a file + Delete a file. ****************************************************************************/ -BOOL cli_unlink(struct cli_state *cli, char *fname) + +BOOL cli_unlink(struct cli_state *cli, const char *fname) { char *p; @@ -99,9 +97,10 @@ BOOL cli_unlink(struct cli_state *cli, char *fname) } /**************************************************************************** -create a directory + Create a directory. ****************************************************************************/ -BOOL cli_mkdir(struct cli_state *cli, char *dname) + +BOOL cli_mkdir(struct cli_state *cli, const char *dname) { char *p; @@ -133,9 +132,10 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname) } /**************************************************************************** -remove a directory + Remove a directory. ****************************************************************************/ -BOOL cli_rmdir(struct cli_state *cli, char *dname) + +BOOL cli_rmdir(struct cli_state *cli, const char *dname) { char *p; @@ -208,7 +208,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) } /**************************************************************************** - open a file - exposing the full horror of the NT API :-). + Open a file - exposing the full horror of the NT API :-). Used in smbtorture. ****************************************************************************/ @@ -265,7 +265,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA } /**************************************************************************** -open a file + Open a file. ****************************************************************************/ int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess) @@ -275,9 +275,10 @@ int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess } /**************************************************************************** -open a file -WARNING: if you open with O_WRONLY then getattrE won't work! + Open a file + WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ + int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode) { char *p; @@ -352,12 +353,10 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode return SVAL(cli->inbuf,smb_vwv2); } - - - /**************************************************************************** - close a file + Close a file. ****************************************************************************/ + BOOL cli_close(struct cli_state *cli, int fnum) { memset(cli->outbuf,'\0',smb_size); @@ -380,15 +379,15 @@ BOOL cli_close(struct cli_state *cli, int fnum) return !cli_is_error(cli); } - /**************************************************************************** - lock a file + Lock a file. ****************************************************************************/ + BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout, enum brl_type lock_type) { char *p; - int saved_timeout = cli->timeout; + int saved_timeout = cli->timeout; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); @@ -417,10 +416,10 @@ BOOL cli_lock(struct cli_state *cli, int fnum, cli_send_smb(cli); - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); if (!cli_receive_smb(cli)) { - cli->timeout = saved_timeout; + cli->timeout = saved_timeout; return False; } @@ -434,8 +433,9 @@ BOOL cli_lock(struct cli_state *cli, int fnum, } /**************************************************************************** - unlock a file + Unlock a file. ****************************************************************************/ + BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) { char *p; @@ -474,10 +474,10 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) return True; } - /**************************************************************************** - lock a file with 64 bit offsets + Lock a file with 64 bit offsets. ****************************************************************************/ + BOOL cli_lock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type) { @@ -534,8 +534,9 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, } /**************************************************************************** - unlock a file with 64 bit offsets + Unlock a file with 64 bit offsets. ****************************************************************************/ + BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len) { char *p; @@ -578,13 +579,10 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ return True; } - - - - /**************************************************************************** -do a SMBgetattrE call + Do a SMBgetattrE call. ****************************************************************************/ + BOOL cli_getattrE(struct cli_state *cli, int fd, uint16 *attr, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time) @@ -632,11 +630,11 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, return True; } - /**************************************************************************** -do a SMBgetatr call + Do a SMBgetatr call ****************************************************************************/ -BOOL cli_getatr(struct cli_state *cli, char *fname, + +BOOL cli_getatr(struct cli_state *cli, const char *fname, uint16 *attr, size_t *size, time_t *t) { char *p; @@ -681,11 +679,11 @@ BOOL cli_getatr(struct cli_state *cli, char *fname, return True; } - /**************************************************************************** -do a SMBsetatr call + Do a SMBsetatr call. ****************************************************************************/ -BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) + +BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) { char *p; @@ -720,11 +718,11 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t) return True; } - /**************************************************************************** -check for existance of a dir + Check for existance of a dir. ****************************************************************************/ -BOOL cli_chkpath(struct cli_state *cli, char *path) + +BOOL cli_chkpath(struct cli_state *cli, const char *path) { pstring path2; char *p; @@ -754,11 +752,10 @@ BOOL cli_chkpath(struct cli_state *cli, char *path) return True; } - - /**************************************************************************** -query disk space + Query disk space. ****************************************************************************/ + BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { memset(cli->outbuf,'\0',smb_size); @@ -779,11 +776,11 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) return True; } - /**************************************************************************** -create and open a temporary file + Create and open a temporary file. ****************************************************************************/ -int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path) + +int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) { int len; char *p; diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index f19ec3e758..2fde0c70e5 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -149,7 +149,7 @@ static char *make_header(char *param, uint16 apinum, char *reqfmt, char *datafmt /**************************************************************************** call a NetGroupDelete - delete user group from remote server ****************************************************************************/ -int cli_NetGroupDelete(struct cli_state *cli, char * group_name ) +int cli_NetGroupDelete(struct cli_state *cli, const char *group_name ) { char *rparam = NULL; char *rdata = NULL; @@ -277,7 +277,7 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char int res = -1; - bzero(param, sizeof(param)); + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WGroupEnum, RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L1); PUTWORD(p,1); /* Info level 1 */ /* add level 0 */ @@ -328,7 +328,7 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char return res; } -int cli_NetGroupDelUser(struct cli_state * cli, char * group_name, char * user_name) +int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const char *user_name) { char *rparam = NULL; char *rdata = NULL; @@ -386,7 +386,7 @@ int cli_NetGroupDelUser(struct cli_state * cli, char * group_name, char * user_n return res; } -int cli_NetGroupAddUser(struct cli_state * cli, char * group_name, char * user_name) +int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const char *user_name) { char *rparam = NULL; char *rdata = NULL; @@ -442,7 +442,7 @@ int cli_NetGroupAddUser(struct cli_state * cli, char * group_name, char * user_n } -int cli_NetGroupGetUsers(struct cli_state * cli, char * group_name, void (*fn)(const char *, void *), void *state ) +int cli_NetGroupGetUsers(struct cli_state * cli, const char *group_name, void (*fn)(const char *, void *), void *state ) { char *rparam = NULL; char *rdata = NULL; @@ -497,7 +497,7 @@ int cli_NetGroupGetUsers(struct cli_state * cli, char * group_name, void (*fn)(c return res; } -int cli_NetUserGetGroups(struct cli_state * cli, char * user_name, void (*fn)(const char *, void *), void *state ) +int cli_NetUserGetGroups(struct cli_state * cli, const char *user_name, void (*fn)(const char *, void *), void *state ) { char *rparam = NULL; char *rdata = NULL; @@ -556,7 +556,7 @@ int cli_NetUserGetGroups(struct cli_state * cli, char * user_name, void (*fn)(co /**************************************************************************** call a NetUserDelete - delete user from remote server ****************************************************************************/ -int cli_NetUserDelete(struct cli_state *cli, char * user_name ) +int cli_NetUserDelete(struct cli_state *cli, const char * user_name ) { char *rparam = NULL; char *rdata = NULL; @@ -647,7 +647,7 @@ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo ) PUTWORD(p, 0); /* password length */ p = data; - bzero(data, soffset); + memset(data, '\0', soffset); PUTSTRINGF(p, userinfo->user_name, RAP_USERNAME_LEN); PUTBYTE(p, 0); /* pad byte 0 */ @@ -707,7 +707,7 @@ int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char int res = -1; - bzero(param, sizeof(param)); + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WUserEnum, RAP_NetUserEnum_REQ, RAP_USER_INFO_L1); PUTWORD(p,1); /* Info level 1 */ @@ -984,7 +984,7 @@ int cli_NetShareAdd(struct cli_state *cli, RAP_SHARE_INFO_2 * sinfo ) + DWORDSIZE /* share path */ + RAP_SPASSWD_LEN + 1; /* share password + pad */ - bzero(param,sizeof(param)); + memset(param,'\0',sizeof(param)); /* now send a SMBtrans command with api RNetShareAdd */ p = make_header(param, RAP_WshareAdd, RAP_WShareAdd_REQ, RAP_SHARE_INFO_L2); @@ -1031,7 +1031,7 @@ int cli_NetShareAdd(struct cli_state *cli, RAP_SHARE_INFO_2 * sinfo ) /**************************************************************************** call a NetShareDelete - unshare exported directory on remote server ****************************************************************************/ -int cli_NetShareDelete(struct cli_state *cli, char * share_name ) +int cli_NetShareDelete(struct cli_state *cli, const char * share_name ) { char *rparam = NULL; char *rdata = NULL; @@ -1424,7 +1424,9 @@ BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) return (cli->rap_error == 0); } -int cli_NetPrintQEnum(struct cli_state *cli, void (*qfn)(char*,uint16,uint16,uint16,char*,char*,char*,char*,char*,uint16,uint16),void (*jfn)(uint16,char*,char*,char*,char*,uint16,uint16,char*,uint,uint,char*)) +int cli_NetPrintQEnum(struct cli_state *cli, + void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), + void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*)) { char param[WORDSIZE /* api number */ +sizeof(RAP_NetPrintQEnum_REQ) /* req string */ @@ -1439,7 +1441,7 @@ int cli_NetPrintQEnum(struct cli_state *cli, void (*qfn)(char*,uint16,uint16,ui int res = -1; - bzero(param, sizeof(param)); + memset(param, '\0',sizeof(param)); p = make_header(param, RAP_WPrintQEnum, RAP_NetPrintQEnum_REQ, RAP_PRINTQ_INFO_L2); PUTWORD(p,2); /* Info level 2 */ @@ -1525,7 +1527,9 @@ int cli_NetPrintQEnum(struct cli_state *cli, void (*qfn)(char*,uint16,uint16,ui return res; } -int cli_NetPrintQGetInfo(struct cli_state *cli, char *printer, void (*qfn)(char*,uint16,uint16,uint16,char*,char*,char*,char*,char*,uint16,uint16),void (*jfn)(uint16,char*,char*,char*,char*,uint16,uint16,char*,uint,uint,char*)) +int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, + void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), + void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*)) { char param[WORDSIZE /* api number */ +sizeof(RAP_NetPrintQGetInfo_REQ) /* req string */ @@ -1541,7 +1545,7 @@ int cli_NetPrintQGetInfo(struct cli_state *cli, char *printer, void (*qfn)(char* int res = -1; - bzero(param, sizeof(param)); + memset(param, '\0',sizeof(param)); p = make_header(param, RAP_WPrintQGetInfo, RAP_NetPrintQGetInfo_REQ, RAP_PRINTQ_INFO_L2); PUTSTRING(p, printer, RAP_SHARENAME_LEN-1); @@ -1640,7 +1644,7 @@ int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const ch int res = -1; - bzero(param, sizeof(param)); + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WServiceEnum, RAP_NetServiceEnum_REQ, RAP_SERVICE_INFO_L2); PUTWORD(p,2); /* Info level 2 */ @@ -1708,7 +1712,7 @@ int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, int rprcnt, rdrcnt; int res = -1; - bzero(param, sizeof(param)); + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WsessionEnum, RAP_NetSessionEnum_REQ, RAP_SESSION_INFO_L2); PUTWORD(p,2); /* Info level 2 */ @@ -1767,9 +1771,10 @@ int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, } /**************************************************************************** -call a NetSessionGetInfo - get information about other session to an SMB server + Call a NetSessionGetInfo - get information about other session to an SMB server. ****************************************************************************/ -int cli_NetSessionGetInfo(struct cli_state *cli, char *workstation, void (*fn)(char *, char *, uint16, uint16, uint16, uint, uint, uint, char *)) + +int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void (*fn)(const char *, const char *, uint16, uint16, uint16, uint, uint, uint, const char *)) { char param[WORDSIZE /* api number */ +sizeof(RAP_NetSessionGetInfo_REQ) /* req string */ @@ -1784,7 +1789,7 @@ int cli_NetSessionGetInfo(struct cli_state *cli, char *workstation, void (*fn)(c int res = -1; - bzero(param, sizeof(param)); + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WsessionGetInfo, RAP_NetSessionGetInfo_REQ, RAP_SESSION_INFO_L2); PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1); @@ -1844,7 +1849,7 @@ int cli_NetSessionGetInfo(struct cli_state *cli, char *workstation, void (*fn)(c /**************************************************************************** call a NetSessionDel - close a session to an SMB server ****************************************************************************/ -int cli_NetSessionDel(struct cli_state *cli, char *workstation) +int cli_NetSessionDel(struct cli_state *cli, const char *workstation) { char param[WORDSIZE /* api number */ +sizeof(RAP_NetSessionDel_REQ) /* req string */ @@ -1857,7 +1862,7 @@ int cli_NetSessionDel(struct cli_state *cli, char *workstation) int rprcnt, rdrcnt; int res; - bzero(param, sizeof(param)); + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL); PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1); PUTWORD(p,0); /* reserved word of 0 */ @@ -1888,7 +1893,7 @@ int cli_NetSessionDel(struct cli_state *cli, char *workstation) } -int cli_NetConnectionEnum(struct cli_state *cli, char *qualifier, void (*fn)(uint16 conid, uint16 contype, uint16 numopens, uint16 numusers, uint32 contime, char *username, char *netname)) +int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*fn)(uint16 conid, uint16 contype, uint16 numopens, uint16 numusers, uint32 contime, const char *username, const char *netname)) { char param[WORDSIZE /* api number */ +sizeof(RAP_NetConnectionEnum_REQ) /* req string */ @@ -1902,7 +1907,7 @@ int cli_NetConnectionEnum(struct cli_state *cli, char *qualifier, void (*fn)(uin int rprcnt, rdrcnt; int res = -1; - bzero(param, sizeof(param)); + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WconnectionEnum, RAP_NetConnectionEnum_REQ, RAP_CONNECTION_INFO_L1); PUTSTRING(p, qualifier, RAP_MACHNAME_LEN-1);/* Workstation name */ diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0dbf4b4564..1e284aab19 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -205,7 +205,7 @@ BOOL name_register(int fd, const char *name, int name_type, register_ip.s_addr = name_ip.s_addr; /* Fix this ... */ - bzero((char *)&p, sizeof(p)); + memset((char *)&p, '\0', sizeof(p)); *count = 0; @@ -237,7 +237,7 @@ BOOL name_register(int fd, const char *name, int name_type, } - bzero((char *)nmb->additional, sizeof(struct res_rec)); + memset((char *)nmb->additional, '\0', sizeof(struct res_rec)); nmb->additional->rr_name = nmb->question.question_name; nmb->additional->rr_type = RR_TYPE_NB; -- cgit From b09c745991e133d455fd8db586729b7e82d92935 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 5 Nov 2001 05:41:32 +0000 Subject: merge from 2.2. Why is STR_CONVERT missing when comparing 2.2 to HEAD? (This used to be commit 4f47daf97b9e74ec75287f46e2c4aeddc944779e) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index aae21cb6d9..2a84b69faa 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -89,7 +89,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p += clistr_push(cli, p, user, -1, STR_UPPER|STR_TERMINATE); + p += clistr_push(cli, p, user, -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); -- cgit From 366026d2f46848152bb769181867f8cde2eaaf4e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Nov 2001 15:18:17 +0000 Subject: free the negTokenInit structure (This used to be commit 5b1c942a5cab828ebfcf2e8f5decb754c4cdb70e) --- source3/libsmb/cliconnect.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2a84b69faa..096d8cb24a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -403,6 +403,8 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c /* we don't need this blob for kerberos */ data_blob_free(&blob2); + data_blob_free(&negTokenTarg); + return !cli_is_error(cli); } #endif -- cgit From fbc4e1daba427643466c39fc992ae4403856bb56 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 5 Nov 2001 23:00:46 +0000 Subject: Fixed looking up domain (winbind) users ahead of local users in domain_client_validate() (This used to be commit df0db8edb12dc8b8d290e5ac599fa7b517e9d263) --- source3/libsmb/domain_client_validate.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 7a8fa66841..a8c3ff2f6b 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -325,9 +325,14 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, ZERO_STRUCT(info3); + /* + * If this call succeeds, we now have lots of info about the user + * in the info3 structure. + */ + status = cli_nt_login_network(&cli, user_info, smb_uid_low, &ctr, &info3); - + if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("domain_client_validate: unable to validate password " "for user %s in domain %s to Domain controller %s. " @@ -335,13 +340,20 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, user_info->domain.str, cli.srv_name_slash, get_nt_error_msg(status))); } else { + char *dom_user; - /* - * Here, if we really want it, we have lots of info about the user - * in info3. - */ + /* Check DOMAIN\username first to catch winbind users, then + just the username for local users. */ + + asprintf(&dom_user, "%s%s%s", user_info->domain.str, + lp_winbind_separator(), + user_info->internal_username.str); + + if (!(pass = Get_Pwnam(dom_user))) + pass = Get_Pwnam(user_info->internal_username.str); + + free(dom_user); - pass = Get_Pwnam(user_info->internal_username.str); if (pass) { make_server_info_pw(server_info, pass); if (!server_info) { -- cgit From 2113e2ba08fc5e55c9f1b4d1f70d87683f48d4d3 Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 7 Nov 2001 23:01:44 +0000 Subject: Add function to add those hosts who have added msbrowse (domain master browsers) (This used to be commit 3fd96a47543c268fd2828793df4006cc47a9e95b) --- source3/libsmb/namequery.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1e284aab19..18bab5e7fd 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1176,3 +1176,11 @@ BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *coun { return internal_resolve_name(group, pdc_only ? 0x1B : 0x1C, ip_list, count); } + +/******************************************************** + Get the IP address list of the Domain Master Browsers + ********************************************************/ +BOOL get_dmb_list(struct in_addr **ip_list, int *count) +{ + return internal_resolve_name( MSBROWSE, 0x1, ip_list, count); +} -- cgit From e903a34b2ecf6bca515dbe57274f4186d7f3955e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 11 Nov 2001 11:00:38 +0000 Subject: Minor updates. A small dose of const. (This used to be commit 80667cb0dd1a2cdef17711c8580af9f524971cea) --- source3/libsmb/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index c1c4750e05..2e27455362 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -167,7 +167,7 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p /* Does the NT MD4 hash then des encryption. */ -void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24) +void SMBNTencrypt(const uchar *passwd, uchar *c8, uchar *p24) { uchar p21[21]; -- cgit From 742dc2313c951f85ff66f0a8121790d0e291a19c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Nov 2001 04:15:36 +0000 Subject: Removed the "reestablish" code. Tridge - scream if this was needed.... Jeremy. (This used to be commit e6afe40f85d7dbe79322c82dac735d901e7e71df) --- source3/libsmb/cliconnect.c | 51 --------------------------------------------- source3/libsmb/clientgen.c | 11 ++-------- 2 files changed, 2 insertions(+), 60 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 096d8cb24a..a6632803b2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1018,57 +1018,6 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) return True; } -/**************************************************************************** -re-establishes a connection -****************************************************************************/ -BOOL cli_reestablish_connection(struct cli_state *cli) -{ - struct nmb_name calling; - struct nmb_name called; - fstring dest_host; - fstring share; - fstring dev; - BOOL do_tcon = False; - int oldfd = cli->fd; - - if (!cli->initialised || cli->fd == -1) - { - DEBUG(3,("cli_reestablish_connection: not connected\n")); - return False; - } - - /* copy the parameters necessary to re-establish the connection */ - - if (cli->cnum != 0) - { - fstrcpy(share, cli->share); - fstrcpy(dev , cli->dev); - do_tcon = True; - } - - memcpy(&called , &(cli->called ), sizeof(called )); - memcpy(&calling, &(cli->calling), sizeof(calling)); - fstrcpy(dest_host, cli->full_dest_host_name); - - DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n", - nmb_namestr(&calling), nmb_namestr(&called), - inet_ntoa(cli->dest_ip), - cli->user_name, cli->domain)); - - cli->fd = -1; - - if (cli_establish_connection(cli, - dest_host, &cli->dest_ip, - &calling, &called, - share, dev, False, do_tcon)) { - if ((cli->fd != oldfd) && (oldfd != -1)) { - close( oldfd ); - } - return True; - } - return False; -} - /**************************************************************************** establishes a connection right up to doing tconX, reading in a password. ****************************************************************************/ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d509924a26..d3623ad94e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -62,26 +62,19 @@ BOOL cli_receive_smb(struct cli_state *cli) } /**************************************************************************** - send an smb to a fd and re-establish if necessary + send an smb to a fd. ****************************************************************************/ + BOOL cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; ssize_t ret; - BOOL reestablished=False; len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); - if (ret <= 0 && errno == EPIPE && !reestablished) { - if (cli_reestablish_connection(cli)) { - reestablished = True; - nwritten=0; - continue; - } - } if (ret <= 0) { DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); -- cgit From 641f3070ab59f5fb681ccedb692de2ef7d9d90db Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 14 Nov 2001 05:58:51 +0000 Subject: Close the socket and set the file descriptor to -1 if there was a socket error in cli_receive_smb() and cli_send_smb(). (This used to be commit bedd9c821521dad46df50e8b31e4a58bb0a9a604) --- source3/libsmb/clientgen.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d3623ad94e..133408dff4 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -58,6 +58,13 @@ BOOL cli_receive_smb(struct cli_state *cli) } } + /* If the server is not responding, note that now */ + + if (!ret) { + close(cli->fd); + cli->fd = -1; + } + return ret; } @@ -76,6 +83,8 @@ BOOL cli_send_smb(struct cli_state *cli) while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0) { + close(cli->fd); + cli->fd = -1; DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); return False; -- cgit From ea40fa55f0c385dd714300a7dcf89393f831ca79 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Thu, 15 Nov 2001 06:03:22 +0000 Subject: Doxygen demo for Tim. (This used to be commit 5c892badbcad43b8a2e002d1a42483c402f2d3e9) --- source3/libsmb/cli_lsarpc.c | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index f2fc167606..046422abc6 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -25,15 +25,28 @@ #include "includes.h" -/* Opens a SMB connection to the lsa pipe */ - +/** @defgroup rpc_client RPC Client + * + * @{ + **/ + +/** + * @file cli_lsarpc.c + * + * RPC client routines for the LSA RPC pipe. LSA means "local + * security authority", which is half of a password database. + **/ + +/** Opens a SMB connection to the lsa pipe + * + * @param system_name NETBIOS name of the machine to connect to. */ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { return cli_pipe_initialise(cli, system_name, PIPE_LSASS, creds); } -/* Open a LSA policy handle */ +/** Open a LSA policy handle */ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, BOOL sec_qos, uint32 des_access, POLICY_HND *pol) @@ -89,7 +102,7 @@ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Open a LSA policy handle */ +/** Open a LSA policy handle */ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, BOOL sec_qos, uint32 des_access, POLICY_HND *pol) @@ -147,7 +160,7 @@ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Close a LSA policy handle */ +/** Close a LSA policy handle */ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol) @@ -195,7 +208,7 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Lookup a list of sids */ +/** Lookup a list of sids */ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, int num_sids, DOM_SID *sids, @@ -305,7 +318,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Lookup a list of names */ +/** Lookup a list of names */ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, int num_names, char **names, @@ -406,7 +419,7 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Query info policy */ +/** Query info policy */ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint16 info_class, @@ -493,7 +506,7 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Enumerate list of trusted domains */ +/** Enumerate list of trusted domains */ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 *enum_ctx, @@ -591,3 +604,5 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/** @} **/ -- cgit From 8220662c13b70930ee2650a3608f0cef0d0fe6ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Nov 2001 19:40:00 +0000 Subject: Tidyup formatting a bit (spaces->tabs) whilst reading new code to understand connection caching. Getting ready for back-merge to 2.2.3. Jeremy. (This used to be commit 5e8df83ba9924adf9df6827c06ed1a2adbe36edf) --- source3/libsmb/pwd_cache.c | 80 ++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 4a2c5f1604..3c3d5cb741 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -22,8 +22,9 @@ #include "includes.h" /**************************************************************************** -initialises a password structure + Initialises a password structure. ****************************************************************************/ + void pwd_init(struct pwd_info *pwd) { memset((char *)pwd->password , '\0', sizeof(pwd->password )); @@ -38,17 +39,18 @@ void pwd_init(struct pwd_info *pwd) } /**************************************************************************** -returns NULL password flag + Returns NULL password flag. ****************************************************************************/ + BOOL pwd_is_nullpwd(const struct pwd_info *pwd) { return pwd->null_pwd; } - /**************************************************************************** -compares two passwords. hmm, not as trivial as expected. hmm. + Compares two passwords. hmm, not as trivial as expected. hmm. ****************************************************************************/ + BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2) { if (pwd1->cleartext && pwd2->cleartext) { @@ -79,8 +81,9 @@ BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2) } /**************************************************************************** -reads a password + Reads a password. ****************************************************************************/ + void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) { /* grab a password */ @@ -99,24 +102,19 @@ void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) */ #if 0 if (user_pass == NULL || user_pass[0] == 0) - { pwd_set_nullpwd(pwd); - } else if (do_encrypt) #endif if (do_encrypt) - { pwd_make_lm_nt_16(pwd, user_pass); - } else - { pwd_set_cleartext(pwd, user_pass); - } } /**************************************************************************** - stores a cleartext password - ****************************************************************************/ + Stores a cleartext password. +****************************************************************************/ + void pwd_set_nullpwd(struct pwd_info *pwd) { pwd_init(pwd); @@ -127,8 +125,9 @@ void pwd_set_nullpwd(struct pwd_info *pwd) } /**************************************************************************** - stores a cleartext password - ****************************************************************************/ + Stores a cleartext password. +****************************************************************************/ + void pwd_set_cleartext(struct pwd_info *pwd, char *clr) { pwd_init(pwd); @@ -139,41 +138,34 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) } /**************************************************************************** - gets a cleartext password - ****************************************************************************/ + Gets a cleartext password. +****************************************************************************/ + void pwd_get_cleartext(struct pwd_info *pwd, char *clr) { - if (pwd->cleartext) { + if (pwd->cleartext) fstrcpy(clr, pwd->password); - } else { + else clr[0] = 0; - } } /**************************************************************************** - stores lm and nt hashed passwords - ****************************************************************************/ + Stores lm and nt hashed passwords. +****************************************************************************/ + void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { pwd_init(pwd); if (lm_pwd) - { memcpy(pwd->smb_lm_pwd, lm_pwd, 16); - } else - { memset((char *)pwd->smb_lm_pwd, '\0', 16); - } if (nt_pwd) - { memcpy(pwd->smb_nt_pwd, nt_pwd, 16); - } else - { memset((char *)pwd->smb_nt_pwd, '\0', 16); - } pwd->null_pwd = False; pwd->cleartext = False; @@ -181,23 +173,21 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) } /**************************************************************************** - gets lm and nt hashed passwords - ****************************************************************************/ + Gets lm and nt hashed passwords. +****************************************************************************/ + void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) { if (lm_pwd != NULL) - { memcpy(lm_pwd, pwd->smb_lm_pwd, 16); - } if (nt_pwd != NULL) - { memcpy(nt_pwd, pwd->smb_nt_pwd, 16); - } } /**************************************************************************** - makes lm and nt hashed passwords - ****************************************************************************/ + Makes lm and nt hashed passwords. +****************************************************************************/ + void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) { pstring dos_passwd; @@ -213,8 +203,9 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) } /**************************************************************************** - makes lm and nt OWF crypts - ****************************************************************************/ + Makes lm and nt OWF crypts. +****************************************************************************/ + void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) { @@ -245,16 +236,13 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) } /**************************************************************************** - gets lm and nt crypts - ****************************************************************************/ + Gets lm and nt crypts. +****************************************************************************/ + void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) { if (lm_owf != NULL) - { memcpy(lm_owf, pwd->smb_lm_owf, 24); - } if (nt_owf != NULL) - { memcpy(nt_owf, pwd->smb_nt_owf, 24); - } } -- cgit From 15ca82215e015149b4ac9ac7df96a081741ef37a Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 17 Nov 2001 07:30:19 +0000 Subject: Fix problems with lp_workgroup() being passed to routines that will modify it and fix smb://. (This used to be commit ac2562a0fb7eafd94d53a2c36d33e8f5236d60ff) --- source3/libsmb/libsmbclient.c | 68 ++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 24 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 6a00855bff..d6c37ff9b2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -538,7 +538,7 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) int smbc_open(const char *fname, int flags, mode_t mode) { - fstring server, share, user, password; + fstring server, share, user, password, workgroup; pstring path; struct smbc_server *srv = NULL; int fd; @@ -561,7 +561,9 @@ int smbc_open(const char *fname, int flags, mode_t mode) if (user[0] == (char)0) pstrcpy(user, smbc_user); - srv = smbc_server(server, share, lp_workgroup(), user, password); + pstrcpy(workgroup, lp_workgroup()); + + srv = smbc_server(server, share, workgroup, user, password); if (!srv) { @@ -832,7 +834,7 @@ int smbc_close(int fd) int smbc_unlink(const char *fname) { - fstring server, share, user, password; + fstring server, share, user, password, workgroup; pstring path; struct smbc_server *srv = NULL; @@ -854,7 +856,9 @@ int smbc_unlink(const char *fname) if (user[0] == (char)0) pstrcpy(user, smbc_user); - srv = smbc_server(server, share, lp_workgroup(), user, password); + pstrcpy(workgroup, lp_workgroup()); + + srv = smbc_server(server, share, workgroup, user, password); if (!srv) { @@ -923,7 +927,7 @@ int smbc_unlink(const char *fname) int smbc_rename(const char *oname, const char *nname) { - fstring server1, share1, server2, share2, user1, user2, password1, password2; + fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup; pstring path1, path2; struct smbc_server *srv = NULL; @@ -961,7 +965,9 @@ int smbc_rename(const char *oname, const char *nname) } - srv = smbc_server(server1, share1, lp_workgroup(), user1, password1); + pstrcpy(workgroup, lp_workgroup()); + + srv = smbc_server(server1, share1, workgroup, user1, password1); if (!srv) { return -1; @@ -1152,7 +1158,7 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, int smbc_stat(const char *fname, struct stat *st) { struct smbc_server *srv; - fstring server, share, user, password; + fstring server, share, user, password, workgroup; pstring path; time_t m_time = 0, a_time = 0, c_time = 0; size_t size = 0; @@ -1179,7 +1185,9 @@ int smbc_stat(const char *fname, struct stat *st) if (user[0] == (char)0) pstrcpy(user, smbc_user); - srv = smbc_server(server, share, lp_workgroup(), user, password); + pstrcpy(workgroup, lp_workgroup()); + + srv = smbc_server(server, share, workgroup, user, password); if (!srv) { @@ -1454,7 +1462,7 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) int smbc_opendir(const char *fname) { - fstring server, share, user, password; + fstring server, share, user, password, workgroup; pstring path; struct smbc_server *srv = NULL; struct in_addr rem_ip; @@ -1483,6 +1491,8 @@ int smbc_opendir(const char *fname) if (user[0] == (char)0) pstrcpy(user, smbc_user); + pstrcpy(workgroup, lp_workgroup()); + /* Get a file entry ... */ slot = 0; @@ -1531,7 +1541,7 @@ int smbc_opendir(const char *fname) /* We have server and share and path empty ... so list the workgroups */ - /*cli_get_backup_server(my_netbios_name, lp_workgroup(), server, sizeof(server));*/ + /*cli_get_backup_server(my_netbios_name, workgroup, server, sizeof(server));*/ if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) { @@ -1556,7 +1566,7 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(server, "IPC$", lp_workgroup(), user, password); + srv = smbc_server(server, "IPC$", workgroup, user, password); if (!srv) { @@ -1572,7 +1582,7 @@ int smbc_opendir(const char *fname) /* Now, list the stuff ... */ - if (!cli_NetServerEnum(&srv->cli, lp_workgroup(), 0x80000000, list_fn, + if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn, (void *)smbc_file_table[slot])) { if (smbc_file_table[slot]) { @@ -1600,8 +1610,10 @@ int smbc_opendir(const char *fname) } /* Check to see if <1D> translates, or <20> translates */ + /* However, we check to see if is an IP address first */ - if (resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ + if (!is_ipaddress(server) && /* Not an IP addr so check next */ + resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ pstring buserver; smbc_file_table[slot]->dir_type = SMBC_SERVER; @@ -1624,7 +1636,7 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(buserver, "IPC$", lp_workgroup(), user, password); + srv = smbc_server(buserver, "IPC$", workgroup, user, password); if (!srv) { @@ -1661,7 +1673,7 @@ int smbc_opendir(const char *fname) smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, "IPC$", lp_workgroup(), user, password); + srv = smbc_server(server, "IPC$", workgroup, user, password); if (!srv) { @@ -1710,7 +1722,7 @@ int smbc_opendir(const char *fname) smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, share, lp_workgroup(), user, password); + srv = smbc_server(server, share, workgroup, user, password); if (!srv) { @@ -1969,7 +1981,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) int smbc_mkdir(const char *fname, mode_t mode) { struct smbc_server *srv; - fstring server, share, user, password; + fstring server, share, user, password, workgroup; pstring path; if (!smbc_initialized) { @@ -1992,7 +2004,9 @@ int smbc_mkdir(const char *fname, mode_t mode) if (user[0] == (char)0) pstrcpy(user, smbc_user); - srv = smbc_server(server, share, lp_workgroup(), user, password); + pstrcpy(workgroup, lp_workgroup()); + + srv = smbc_server(server, share, workgroup, user, password); if (!srv) { @@ -2053,7 +2067,7 @@ static void rmdir_list_fn(file_info *finfo, const char *mask, void *state) int smbc_rmdir(const char *fname) { struct smbc_server *srv; - fstring server, share, user, password; + fstring server, share, user, password, workgroup; pstring path; if (!smbc_initialized) { @@ -2076,7 +2090,9 @@ int smbc_rmdir(const char *fname) if (user[0] == (char)0) pstrcpy(user, smbc_user); - srv = smbc_server(server, share, lp_workgroup(), user, password); + pstrcpy(workgroup, lp_workgroup()); + + srv = smbc_server(server, share, workgroup, user, password); if (!srv) { @@ -2418,7 +2434,7 @@ int smbc_open_print_job(const char *fname) int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) { struct smbc_server *srv; - fstring server, share, user, password; + fstring server, share, user, password, workgroup; pstring path; if (!smbc_initialized) { @@ -2441,7 +2457,9 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) if (user[0] == (char)0) pstrcpy(user, smbc_user); - srv = smbc_server(server, share, lp_workgroup(), user, password); + pstrcpy(workgroup, lp_workgroup()); + + srv = smbc_server(server, share, workgroup, user, password); if (!srv) { @@ -2467,7 +2485,7 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) int smbc_unlink_print_job(const char *fname, int id) { struct smbc_server *srv; - fstring server, share, user, password; + fstring server, share, user, password, workgroup; pstring path; int err; @@ -2491,7 +2509,9 @@ int smbc_unlink_print_job(const char *fname, int id) if (user[0] == (char)0) pstrcpy(user, smbc_user); - srv = smbc_server(server, share, lp_workgroup(), user, password); + pstrcpy(workgroup, lp_workgroup()); + + srv = smbc_server(server, share, workgroup, user, password); if (!srv) { -- cgit From 8654a161c8722a0059b15af12cdb81b27d49e71a Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Mon, 19 Nov 2001 03:12:10 +0000 Subject: LMHOSTSFILE is now dynamically configured too. (This used to be commit a779710fff5fddcbf65a8ddc8e9169b586b85481) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 18bab5e7fd..0e696a085b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -748,7 +748,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type)); - fp = startlmhosts( LMHOSTSFILE ); + fp = startlmhosts(dyn_LMHOSTSFILE); if(fp) { while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) { if (strequal(name, lmhost_name) && -- cgit From fcbcfb667feaa5f670d589d084aa85cdb66443e0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Nov 2001 08:45:22 +0000 Subject: - make sure we use a non-zero session id so we can have multiple conns open to w2k - fix the string handling in the device name to match NT and smbd - don't pull the domain from negprot if CAP_EXTENDED_SECURITY is set (This used to be commit 618989b386b5564ba140afdc17ce7a07040c3c4e) --- source3/libsmb/cliconnect.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a6632803b2..f5d6c5a7f4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -341,7 +341,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,0); + SSVAL(cli->outbuf,smb_vwv4,1); SIVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv7,blob.length); SIVAL(cli->outbuf,smb_vwv10,capabilities); @@ -710,17 +710,12 @@ BOOL cli_send_tconX(struct cli_state *cli, return False; } - fstrcpy(cli->dev, "A:"); - - if (cli->protocol >= PROTOCOL_NT1) { - clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE); - } + clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII); if (strcasecmp(share,"IPC$")==0) { fstrcpy(cli->dev, "IPC"); } - /* only grab the device if we have a recent protocol level */ if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ @@ -844,7 +839,8 @@ BOOL cli_negprot(struct cli_state *cli) cli->writebraw_supported = True; } /* work out if they sent us a workgroup */ - if (smb_buflen(cli->inbuf) > 8) { + if (!(cli->capabilities & CAP_EXTENDED_SECURITY) && + smb_buflen(cli->inbuf) > 8) { clistr_pull(cli, cli->server_domain, smb_buf(cli->inbuf)+8, sizeof(cli->server_domain), smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); -- cgit From 4254f9151b4b355b78e494f7c05dacc59fe546e1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Nov 2001 08:46:02 +0000 Subject: add asn1 integer handling ready for the ldap netjoin code (This used to be commit 74303b75e43856bfb127c143d27e5c5fdcf32c91) --- source3/libsmb/asn1.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 50cf6a7142..93e95b52bb 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -108,6 +108,18 @@ BOOL asn1_pop_tag(ASN1_DATA *data) return True; } + +/* write an integer */ +BOOL asn1_write_Integer(ASN1_DATA *data, int i) +{ + if (!asn1_push_tag(data, ASN1_INTEGER)) return False; + do { + asn1_write_uint8(data, i); + i = i >> 8; + } while (i); + return asn1_pop_tag(data); +} + /* write an object ID to a ASN1 buffer */ BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) { @@ -368,6 +380,20 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) return !data->has_error; } +/* read an interger */ +BOOL asn1_read_Integer(ASN1_DATA *data, int *i) +{ + uint8 b; + *i = 0; + + if (!asn1_start_tag(data, ASN1_INTEGER)) return False; + while (asn1_tag_remaining(data)>0) { + *i = (*i << 8) + asn1_read_uint8(data, &b); + } + return asn1_end_tag(data); + +} + /* check a enumarted value is correct */ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) { -- cgit From 7c74cc5cab1d9db431197192a44b5fc08e0412f1 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 21 Nov 2001 03:55:59 +0000 Subject: Fix up libsmbclient in head. Apply the patches from Tom Jansen, get rid of fprintfs and change them to DEBUGs, etc ... (This used to be commit 7ac404c85303c9c3fbd48054fc4876bd4bc1567b) --- source3/libsmb/libsmbclient.c | 2779 +++++++++++++++++++++-------------------- 1 file changed, 1413 insertions(+), 1366 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index d6c37ff9b2..74a42990f7 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -29,31 +29,31 @@ */ struct smbc_server { - struct smbc_server *next, *prev; - struct cli_state cli; - dev_t dev; - char *server_name; - char *share_name; - char *workgroup; - char *username; - BOOL no_pathinfo2; + struct smbc_server *next, *prev; + struct cli_state cli; + dev_t dev; + char *server_name; + char *share_name; + char *workgroup; + char *username; + BOOL no_pathinfo2; }; /* Keep directory entries in a list */ struct smbc_dir_list { - struct smbc_dir_list *next; - struct smbc_dirent *dirent; + struct smbc_dir_list *next; + struct smbc_dirent *dirent; }; struct smbc_file { - int cli_fd; - int smbc_fd; - char *fname; - off_t offset; - struct smbc_server *srv; - BOOL file; - struct smbc_dir_list *dir_list, *dir_end, *dir_next; - int dir_type, dir_error; + int cli_fd; + int smbc_fd; + char *fname; + off_t offset; + struct smbc_server *srv; + BOOL file; + struct smbc_dir_list *dir_list, *dir_end, *dir_next; + int dir_type, dir_error; }; int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ @@ -63,6 +63,7 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, SMB_INO_T *ino); extern BOOL in_client; +extern pstring global_myname; static int smbc_initialized = 0; static smbc_get_auth_data_fn smbc_auth_fn = NULL; /*static int smbc_debug;*/ @@ -89,108 +90,108 @@ static int smbc_parse_path(const char *fname, char *server, char *share, char *path, char *user, char *password) /* FIXME, lengths of strings */ { - static pstring s; - pstring userinfo; - char *p; - char *q, *r; - int len; + static pstring s; + pstring userinfo; + char *p; + char *q, *r; + int len; - server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; - pstrcpy(s, fname); + server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; + pstrcpy(s, fname); - /* clean_fname(s); causing problems ... */ + /* clean_fname(s); causing problems ... */ - /* see if it has the right prefix */ - len = strlen(smbc_prefix); - if (strncmp(s,smbc_prefix,len) || - (s[len] != '/' && s[len] != 0)) return -1; /* What about no smb: ? */ + /* see if it has the right prefix */ + len = strlen(smbc_prefix); + if (strncmp(s,smbc_prefix,len) || + (s[len] != '/' && s[len] != 0)) return -1; /* What about no smb: ? */ - p = s + len; + p = s + len; - /* Watch the test below, we are testing to see if we should exit */ + /* Watch the test below, we are testing to see if we should exit */ - if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { + if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { - return -1; + return -1; - } - - p += 2; /* Skip the // or \\ */ + } - if (*p == (char)0) - return 0; + p += 2; /* Skip the // or \\ */ - if (*p == '/') { + if (*p == (char)0) + return 0; - strncpy(server, (char *)lp_workgroup(), 16); /* FIXME: Danger here */ - return 0; + if (*p == '/') { - } + strncpy(server, (char *)lp_workgroup(), 16); /* FIXME: Danger here */ + return 0; + + } - /* - * ok, its for us. Now parse out the server, share etc. - * - * However, we want to parse out [[domain;]user[:password]@] if it - * exists ... - */ + /* + * ok, its for us. Now parse out the server, share etc. + * + * However, we want to parse out [[domain;]user[:password]@] if it + * exists ... + */ - /* check that '@' occurs before '/', if '/' exists at all */ - q = strchr_m(p, '@'); - r = strchr_m(p, '/'); - if (q && (!r || q < r)) { - pstring username, passwd, domain; - char *u = userinfo; + /* check that '@' occurs before '/', if '/' exists at all */ + q = strchr_m(p, '@'); + r = strchr_m(p, '/'); + if (q && (!r || q < r)) { + pstring username, passwd, domain; + char *u = userinfo; - next_token(&p, userinfo, "@", sizeof(fstring)); + next_token(&p, userinfo, "@", sizeof(fstring)); - username[0] = passwd[0] = domain[0] = 0; + username[0] = passwd[0] = domain[0] = 0; - if (strchr_m(u, ';')) { + if (strchr_m(u, ';')) { - next_token(&u, domain, ";", sizeof(fstring)); - - } - - if (strchr_m(u, ':')) { + next_token(&u, domain, ";", sizeof(fstring)); + + } - next_token(&u, username, ":", sizeof(fstring)); + if (strchr_m(u, ':')) { - pstrcpy(passwd, u); + next_token(&u, username, ":", sizeof(fstring)); - } - else { + pstrcpy(passwd, u); - pstrcpy(username, u); + } + else { - } + pstrcpy(username, u); - if (username[0]) - strncpy(user, username, sizeof(fstring)); /* FIXME, size and domain */ + } - if (passwd[0]) - strncpy(password, passwd, sizeof(fstring)); /* FIXME, size */ + if (username[0]) + strncpy(user, username, sizeof(fstring)); /* FIXME, size and domain */ - } + if (passwd[0]) + strncpy(password, passwd, sizeof(fstring)); /* FIXME, size */ - if (!next_token(&p, server, "/", sizeof(fstring))) { - - return -1; + } - } + if (!next_token(&p, server, "/", sizeof(fstring))) { + + return -1; + + } - if (*p == (char)0) return 0; /* That's it ... */ + if (*p == (char)0) return 0; /* That's it ... */ - if (!next_token(&p, share, "/", sizeof(fstring))) { + if (!next_token(&p, share, "/", sizeof(fstring))) { - return -1; + return -1; - } + } - pstrcpy(path, p); + pstrcpy(path, p); - all_string_sub(path, "/", "\\", 0); + all_string_sub(path, "/", "\\", 0); - return 0; + return 0; } /* @@ -238,297 +239,332 @@ struct smbc_server *smbc_server(char *server, char *share, char *workgroup, char *username, char *password) { - struct smbc_server *srv=NULL; - struct cli_state c; - struct nmb_name called, calling; - char *p, *server_n = server; - fstring group; - pstring ipenv; - struct in_addr ip; - extern struct in_addr ipzero; + struct smbc_server *srv=NULL; + struct cli_state c; + struct nmb_name called, calling; + char *p, *server_n = server; + fstring group; + pstring ipenv; + struct in_addr ip; + extern struct in_addr ipzero; - ip = ipzero; - ZERO_STRUCT(c); - - /* try to use an existing connection */ - for (srv=smbc_srvs;srv;srv=srv->next) { - if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0 && - strcmp(workgroup,srv->workgroup)==0 && - strcmp(username, srv->username) == 0) - return srv; - } - - if (server[0] == 0) { - errno = EPERM; - return NULL; - } - - /* - * Pick up the auth info here, once we know we need to connect - * But only if we do not have a username and password ... - */ - - if (!username[0] || !password[0]) - smbc_auth_fn(server, share, workgroup, sizeof(fstring), - username, sizeof(fstring), password, sizeof(fstring)); - - /* - * However, smbc_auth_fn may have picked up info relating to an - * existing connection, so try for an existing connection again ... - */ - - for (srv=smbc_srvs;srv;srv=srv->next) { - if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0 && - strcmp(workgroup,srv->workgroup)==0 && - strcmp(username, srv->username) == 0) - return srv; - } - - make_nmb_name(&calling, my_netbios_name, 0x0); - make_nmb_name(&called , server, 0x20); - - DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); + ip = ipzero; + ZERO_STRUCT(c); + + /* try to use an existing connection */ + for (srv=smbc_srvs;srv;srv=srv->next) { + if (strcmp(server,srv->server_name)==0 && + strcmp(share,srv->share_name)==0 && + strcmp(workgroup,srv->workgroup)==0 && + strcmp(username, srv->username) == 0) + return srv; + } + + if (server[0] == 0) { + errno = EPERM; + return NULL; + } + + /* + * Pick up the auth info here, once we know we need to connect + * But only if we do not have a username and password ... + */ + + if (!username[0] || !password[0]) + smbc_auth_fn(server, share, workgroup, sizeof(fstring), + username, sizeof(fstring), password, sizeof(fstring)); + + /* + * However, smbc_auth_fn may have picked up info relating to an + * existing connection, so try for an existing connection again ... + */ + + for (srv=smbc_srvs;srv;srv=srv->next) { + if (strcmp(server,srv->server_name)==0 && + strcmp(share,srv->share_name)==0 && + strcmp(workgroup,srv->workgroup)==0 && + strcmp(username, srv->username) == 0) + return srv; + } + + make_nmb_name(&calling, my_netbios_name, 0x0); + make_nmb_name(&called , server, 0x20); + + DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - if ((p=strchr_m(server_n,'#')) && - (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { + if ((p=strchr_m(server_n,'#')) && + (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { - fstrcpy(group, server_n); - p = strchr_m(group,'#'); - *p = 0; + fstrcpy(group, server_n); + p = strchr_m(group,'#'); + *p = 0; - } + } - DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); + DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again: - slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); - - ip = ipzero; - - /* have to open a new connection */ - if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { - errno = ENOENT; - return NULL; - } - - if (!cli_session_request(&c, &calling, &called)) { - cli_shutdown(&c); - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } - errno = ENOENT; - return NULL; - } + slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); + + ip = ipzero; + + /* have to open a new connection */ + if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { + errno = ENOENT; + return NULL; + } + + if (!cli_session_request(&c, &calling, &called)) { + cli_shutdown(&c); + if (strcmp(called.name, "*SMBSERVER")) { + make_nmb_name(&called , "*SMBSERVER", 0x20); + goto again; + } + errno = ENOENT; + return NULL; + } - DEBUG(4,(" session request ok\n")); + DEBUG(4,(" session request ok\n")); - if (!cli_negprot(&c)) { - cli_shutdown(&c); - errno = ENOENT; - return NULL; - } - - if (!cli_session_setup(&c, username, - password, strlen(password), - password, strlen(password), - workgroup) && - /* try an anonymous login if it failed */ - !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) { - cli_shutdown(&c); - errno = EPERM; - return NULL; - } - - DEBUG(4,(" session setup ok\n")); - - if (!cli_send_tconX(&c, share, "?????", - password, strlen(password)+1)) { - errno = smbc_errno(&c); - cli_shutdown(&c); - return NULL; - } + if (!cli_negprot(&c)) { + cli_shutdown(&c); + errno = ENOENT; + return NULL; + } + + if (!cli_session_setup(&c, username, + password, strlen(password), + password, strlen(password), + workgroup) && + /* try an anonymous login if it failed */ + !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) { + cli_shutdown(&c); + errno = EPERM; + return NULL; + } + + DEBUG(4,(" session setup ok\n")); + + if (!cli_send_tconX(&c, share, "?????", + password, strlen(password)+1)) { + errno = smbc_errno(&c); + cli_shutdown(&c); + return NULL; + } - DEBUG(4,(" tconx ok\n")); + DEBUG(4,(" tconx ok\n")); - srv = (struct smbc_server *)malloc(sizeof(*srv)); - if (!srv) { - errno = ENOMEM; - goto failed; - } + srv = (struct smbc_server *)malloc(sizeof(*srv)); + if (!srv) { + errno = ENOMEM; + goto failed; + } - ZERO_STRUCTP(srv); + ZERO_STRUCTP(srv); - srv->cli = c; + srv->cli = c; - srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); + srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); - srv->server_name = strdup(server); - if (!srv->server_name) { - errno = ENOMEM; - goto failed; - } + srv->server_name = strdup(server); + if (!srv->server_name) { + errno = ENOMEM; + goto failed; + } - srv->share_name = strdup(share); - if (!srv->share_name) { - errno = ENOMEM; - goto failed; - } + srv->share_name = strdup(share); + if (!srv->share_name) { + errno = ENOMEM; + goto failed; + } - srv->workgroup = strdup(workgroup); - if (!srv->workgroup) { - errno = ENOMEM; - goto failed; - } + srv->workgroup = strdup(workgroup); + if (!srv->workgroup) { + errno = ENOMEM; + goto failed; + } - srv->username = strdup(username); - if (!srv->username) { - errno = ENOMEM; - goto failed; - } + srv->username = strdup(username); + if (!srv->username) { + errno = ENOMEM; + goto failed; + } - DLIST_ADD(smbc_srvs, srv); + DLIST_ADD(smbc_srvs, srv); - return srv; + return srv; failed: - cli_shutdown(&c); - if (!srv) return NULL; + cli_shutdown(&c); + if (!srv) return NULL; - SAFE_FREE(srv->server_name); - SAFE_FREE(srv->share_name); - SAFE_FREE(srv); - return NULL; + SAFE_FREE(srv->server_name); + SAFE_FREE(srv->share_name); + SAFE_FREE(srv->workgroup); + SAFE_FREE(srv->username); + SAFE_FREE(srv); + return NULL; +} + +/* + *Remove a server from the list smbc_srvs if it's unused -- Tom (tom@ninja.nl) + * + * We accept a *srv + */ +BOOL smbc_remove_unused_server(struct smbc_server * s) +{ + int p; + + /* are we being fooled ? */ + if (!s) return False; + + /* close all open files/directories on this server */ + for (p = 0; p < SMBC_MAX_FD; p++) { + if (smbc_file_table[p] && + smbc_file_table[p]->srv == s) { + /* Still used .. DARN */ + DEBUG(3, ("smbc_remove_usused_server: %x still used by %s (%d).\n", (int) s, + smbc_file_table[p]->fname, smbc_file_table[p]->smbc_fd)); + return False; + } + } + + cli_shutdown(&s->cli); + + SAFE_FREE(s->username); + SAFE_FREE(s->workgroup); + SAFE_FREE(s->server_name); + SAFE_FREE(s->share_name); + DLIST_REMOVE(smbc_srvs, s); + DEBUG(3, ("smbc_remove_usused_server: %x removed.\n", (int) s)); + SAFE_FREE(s); + return True; } /* *Initialise the library etc * - * We accept valiv values for debug from 0 to 100, + * We accept valid values for debug from 0 to 100, * and insist that fn must be non-null. */ int smbc_init(smbc_get_auth_data_fn fn, int debug) { - pstring conf; - int p, pid; - char *user = NULL, *home = NULL, *pname="libsmbclient"; - - /* - * Next lot ifdef'd out until test suite fixed ... - */ - - if (!fn || debug < 0 || debug > 100) { - - errno = EINVAL; - return -1; - - } + pstring conf; + int p, pid; + char *user = NULL, *home = NULL, *pname="libsmbclient"; - if (smbc_initialized) { /* Don't go through this if we have already done it */ + if (!fn || debug < 0 || debug > 100) { - return 0; + errno = EINVAL; + return -1; - } - - smbc_initialized = 1; - smbc_auth_fn = fn; - /* smbc_debug = debug; */ - - DEBUGLEVEL = -1; + } - setup_logging(pname, False); + if (smbc_initialized) { /* Don't go through this if we have already done it */ - /* - * We try to construct our netbios name from our hostname etc - */ + return 0; - user = getenv("USER"); - if (!user) user = ""; /* FIXME: What to do about this? */ + } - /* - * FIXME: Is this the best way to get the user info? */ + smbc_initialized = 1; + smbc_auth_fn = fn; + /* smbc_debug = debug; */ - pstrcpy(smbc_user, user); /* Save for use elsewhere */ + DEBUGLEVEL = -1; - pid = getpid(); + setup_logging(pname, False); - /* - * Hmmm, I want to get hostname as well, but I am too lazy for the moment - */ + /* Here we would open the smb.conf file if needed ... */ - slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); + home = getenv("HOME"); - /* Here we would open the smb.conf file if needed ... */ + slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - home = getenv("HOME"); + load_interfaces(); /* Load the list of interfaces ... */ - slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); + in_client = True; /* FIXME, make a param */ - load_interfaces(); /* Load the list of interfaces ... */ + if (!lp_load(conf, True, False, False)) { - in_client = True; /* FIXME, make a param */ + /* + * Hmmm, what the hell do we do here ... we could not parse the + * config file ... We must return an error ... and keep info around + * about why we failed + */ + + errno = ENOENT; /* FIXME: Figure out the correct error response */ + return -1; - if (!lp_load(conf, True, False, False)) { + } - /* - * Hmmm, what the hell do we do here ... we could not parse the - * config file ... We must return an error ... and keep info around - * about why we failed - */ - - errno = ENOENT; /* FIXME: Figure out the correct error response */ - return -1; + reopen_logs(); /* Get logging working ... */ - } + /* + * FIXME: Is this the best way to get the user info? + */ - reopen_logs(); /* Get logging working ... */ + user = getenv("USER"); + /* walk around as "guest" if no username can be found */ + if (!user) user = strdup("guest"); + pstrcpy(smbc_user, user); /* Save for use elsewhere */ + + /* + * We try to get our netbios name from the config. If that fails we fall + * back on constructing our netbios name from our hostname etc + */ + if (global_myname) { + pstrcpy(my_netbios_name, global_myname); + } + else { + /* + * Hmmm, I want to get hostname as well, but I am too lazy for the moment + */ + pid = getpid(); + slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); + } + DEBUG(0,("Using netbios name %s.\n", my_netbios_name)); - name_register_wins(my_netbios_name, 0); + name_register_wins(my_netbios_name, 0); - /* - * Now initialize the file descriptor array and figure out what the - * max open files is, so we can return FD's that are above the max - * open file, and separated by a guard band - */ + /* + * Now initialize the file descriptor array and figure out what the + * max open files is, so we can return FD's that are above the max + * open file, and separated by a guard band + */ #if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) - do { - struct rlimit rlp; + do { + struct rlimit rlp; - if (getrlimit(RLIMIT_NOFILE, &rlp)) { + if (getrlimit(RLIMIT_NOFILE, &rlp)) { - DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno))); + DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno))); - smbc_start_fd = 1000000; - smbc_max_fd = 10000; /* FIXME, should be a define ... */ + smbc_start_fd = 1000000; - } - else { + } + else { - smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */ - smbc_max_fd = 10000; + smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */ - } - } while ( 0 ); + } + } while ( 0 ); #else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */ - smbc_start_fd = 1000000; - smbc_max_fd = 10000; /* FIXME, should be a define ... */ + smbc_start_fd = 1000000; #endif - smbc_file_table = malloc(smbc_max_fd * sizeof(struct smbc_file *)); + smbc_file_table = malloc(SMBC_MAX_FD * sizeof(struct smbc_file *)); - for (p = 0; p < smbc_max_fd; p++) - smbc_file_table[p] = NULL; + for (p = 0; p < SMBC_MAX_FD; p++) + smbc_file_table[p] = NULL; - if (!smbc_file_table) - return ENOMEM; + if (!smbc_file_table) + return ENOMEM; - return 0; /* Success */ + return 0; /* Success */ } @@ -538,108 +574,108 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) int smbc_open(const char *fname, int flags, mode_t mode) { - fstring server, share, user, password, workgroup; - pstring path; - struct smbc_server *srv = NULL; - int fd; + fstring server, share, user, password, workgroup; + pstring path; + struct smbc_server *srv = NULL; + int fd; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; /* Best I can think of ... */ - return -1; + errno = EINVAL; /* Best I can think of ... */ + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, smbc_user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(server, share, workgroup, user, password); - if (!srv) { + if (!srv) { - if (errno == EPERM) errno = EACCES; - return -1; /* smbc_server sets errno */ + if (errno == EPERM) errno = EACCES; + return -1; /* smbc_server sets errno */ - } + } - /* Hmmm, the test for a directory is suspect here ... FIXME */ + /* Hmmm, the test for a directory is suspect here ... FIXME */ - if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { + if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { - fd = -1; + fd = -1; - } - else { + } + else { - int slot = 0; + int slot = 0; - /* Find a free slot first */ + /* Find a free slot first */ - while (smbc_file_table[slot]) - slot++; + while (smbc_file_table[slot]) + slot++; - if (slot > smbc_max_fd) { + if (slot > SMBC_MAX_FD) { - errno = ENOMEM; /* FIXME, is this best? */ - return -1; + errno = ENOMEM; /* FIXME, is this best? */ + return -1; - } + } - smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); + smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); - if (!smbc_file_table[slot]) { + if (!smbc_file_table[slot]) { - errno = ENOMEM; - return -1; + errno = ENOMEM; + return -1; - } + } - if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) { + if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) { - /* Handle the error ... */ + /* Handle the error ... */ - SAFE_FREE(smbc_file_table[slot]); - errno = smbc_errno(&srv->cli); - return -1; + SAFE_FREE(smbc_file_table[slot]); + errno = smbc_errno(&srv->cli); + return -1; - } + } - /* Fill in file struct */ + /* Fill in file struct */ - smbc_file_table[slot]->cli_fd = fd; - smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; - smbc_file_table[slot]->fname = strdup(fname); - smbc_file_table[slot]->srv = srv; - smbc_file_table[slot]->offset = 0; - smbc_file_table[slot]->file = True; + smbc_file_table[slot]->cli_fd = fd; + smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; + smbc_file_table[slot]->fname = strdup(fname); + smbc_file_table[slot]->srv = srv; + smbc_file_table[slot]->offset = 0; + smbc_file_table[slot]->file = True; - return smbc_file_table[slot]->smbc_fd; + return smbc_file_table[slot]->smbc_fd; - } + } - /* Check if opendir needed ... */ + /* Check if opendir needed ... */ - if (fd == -1) { - int eno = 0; + if (fd == -1) { + int eno = 0; - eno = smbc_errno(&srv->cli); - fd = smbc_opendir(fname); - if (fd < 0) errno = eno; - return fd; + eno = smbc_errno(&srv->cli); + fd = smbc_opendir(fname); + if (fd < 0) errno = eno; + return fd; - } + } - return 1; /* Success, with fd ... */ + return 1; /* Success, with fd ... */ } @@ -652,14 +688,14 @@ static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this int smbc_creat(const char *path, mode_t mode) { - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - return smbc_open(path, creat_bits, mode); + return smbc_open(path, creat_bits, mode); } /* @@ -668,57 +704,57 @@ int smbc_creat(const char *path, mode_t mode) ssize_t smbc_read(int fd, void *buf, size_t count) { - struct smbc_file *fe; - int ret; + struct smbc_file *fe; + int ret; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count)); + DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count)); - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - /* Check that the buffer exists ... */ + /* Check that the buffer exists ... */ - if (buf == NULL) { + if (buf == NULL) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe || !fe->file) { + if (!fe || !fe->file) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count); + ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count); - if (ret < 0) { + if (ret < 0) { - errno = smbc_errno(&fe->srv->cli); - return -1; + errno = smbc_errno(&fe->srv->cli); + return -1; - } + } - fe->offset += ret; + fe->offset += ret; - DEBUG(4, (" --> %d\n", ret)); + DEBUG(4, (" --> %d\n", ret)); - return ret; /* Success, ret bytes of data ... */ + return ret; /* Success, ret bytes of data ... */ } @@ -728,53 +764,53 @@ ssize_t smbc_read(int fd, void *buf, size_t count) ssize_t smbc_write(int fd, void *buf, size_t count) { - int ret; - struct smbc_file *fe; + int ret; + struct smbc_file *fe; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - /* Check that the buffer exists ... */ + /* Check that the buffer exists ... */ - if (buf == NULL) { + if (buf == NULL) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe || !fe->file) { + if (!fe || !fe->file) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count); + ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count); - if (ret <= 0) { + if (ret <= 0) { - errno = smbc_errno(&fe->srv->cli); - return -1; + errno = smbc_errno(&fe->srv->cli); + return -1; - } + } - fe->offset += ret; + fe->offset += ret; - return ret; /* Success, 0 bytes of data ... */ + return ret; /* Success, 0 bytes of data ... */ } /* @@ -783,49 +819,60 @@ ssize_t smbc_write(int fd, void *buf, size_t count) int smbc_close(int fd) { - struct smbc_file *fe; + struct smbc_file *fe; + struct smbc_server *srv; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe) { + if (!fe) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - if (!fe->file) { + if (!fe->file) { - return smbc_closedir(fd); + return smbc_closedir(fd); - } + } + + if (!cli_close(&fe->srv->cli, fe->cli_fd)) { - if (!cli_close(&fe->srv->cli, fe->cli_fd)) { + DEBUG(3, ("cli_close failed on %s (%d). purging server.\n", + fe->fname, fe->smbc_fd)); + /* Deallocate slot and remove the server + * from the server cache if unused */ + errno = smbc_errno(&fe->srv->cli); + srv = fe->srv; + SAFE_FREE(fe->fname); + SAFE_FREE(fe); + smbc_file_table[fd - smbc_start_fd] = NULL; + smbc_remove_unused_server(srv); - errno = smbc_errno(&fe->srv->cli); /* FIXME, should we deallocate slot? */ - return -1; + return -1; - } + } - SAFE_FREE(fe->fname); - SAFE_FREE(fe); - smbc_file_table[fd - smbc_start_fd] = NULL; + SAFE_FREE(fe->fname); + SAFE_FREE(fe); + smbc_file_table[fd - smbc_start_fd] = NULL; - return 0; + return 0; } /* @@ -834,90 +881,90 @@ int smbc_close(int fd) int smbc_unlink(const char *fname) { - fstring server, share, user, password, workgroup; - pstring path; - struct smbc_server *srv = NULL; + fstring server, share, user, password, workgroup; + pstring path; + struct smbc_server *srv = NULL; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; /* Best I can think of ... */ - return -1; + errno = EINVAL; /* Best I can think of ... */ + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, smbc_user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(server, share, workgroup, user, password); - if (!srv) { + if (!srv) { - return -1; /* smbc_server sets errno */ + return -1; /* smbc_server sets errno */ - } + } - /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) { + /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - int job = smbc_stat_printjob(srv, path, NULL, NULL); - if (job == -1) { + int job = smbc_stat_printjob(srv, path, NULL, NULL); + if (job == -1) { - return -1; + return -1; - } - if ((err = cli_printjob_del(&srv->cli, job)) != 0) { + } + if ((err = cli_printjob_del(&srv->cli, job)) != 0) { - return -1; + return -1; - } - } else */ + } + } else */ - if (!cli_unlink(&srv->cli, path)) { + if (!cli_unlink(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(&srv->cli); - if (errno == EACCES) { /* Check if the file is a directory */ + if (errno == EACCES) { /* Check if the file is a directory */ - int saverr = errno; - size_t size = 0; - uint16 mode = 0; - time_t m_time = 0, a_time = 0, c_time = 0; - SMB_INO_T ino = 0; + int saverr = errno; + size_t size = 0; + uint16 mode = 0; + time_t m_time = 0, a_time = 0, c_time = 0; + SMB_INO_T ino = 0; - if (!smbc_getatr(srv, path, &mode, &size, - &c_time, &a_time, &m_time, &ino)) { + if (!smbc_getatr(srv, path, &mode, &size, + &c_time, &a_time, &m_time, &ino)) { - /* Hmmm, bad error ... What? */ + /* Hmmm, bad error ... What? */ - errno = smbc_errno(&srv->cli); - return -1; + errno = smbc_errno(&srv->cli); + return -1; - } - else { + } + else { - if (IS_DOS_DIR(mode)) - errno = EISDIR; - else - errno = saverr; /* Restore this */ + if (IS_DOS_DIR(mode)) + errno = EISDIR; + else + errno = saverr; /* Restore this */ - } - } + } + } - return -1; + return -1; - } + } - return 0; /* Success ... */ + return 0; /* Success ... */ } @@ -927,67 +974,67 @@ int smbc_unlink(const char *fname) int smbc_rename(const char *oname, const char *nname) { - fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup; - pstring path1, path2; - struct smbc_server *srv = NULL; + fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup; + pstring path1, path2; + struct smbc_server *srv = NULL; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; /* Best I can think of ... */ - return -1; + errno = EINVAL; /* Best I can think of ... */ + return -1; - } + } - if (!oname || !nname) { + if (!oname || !nname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - smbc_parse_path(oname, server1, share1, path1, user1, password1); + smbc_parse_path(oname, server1, share1, path1, user1, password1); - if (user1[0] == (char)0) pstrcpy(user1, smbc_user); + if (user1[0] == (char)0) pstrcpy(user1, smbc_user); - smbc_parse_path(nname, server2, share2, path2, user2, password2); + smbc_parse_path(nname, server2, share2, path2, user2, password2); - if (user2[0] == (char)0) pstrcpy(user2, smbc_user); + if (user2[0] == (char)0) pstrcpy(user2, smbc_user); - if (strcmp(server1, server2) || strcmp(share1, share2) || - strcmp(user1, user2)) { + if (strcmp(server1, server2) || strcmp(share1, share2) || + strcmp(user1, user2)) { - /* Can't rename across file systems, or users?? */ + /* Can't rename across file systems, or users?? */ - errno = EXDEV; - return -1; + errno = EXDEV; + return -1; - } + } - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - srv = smbc_server(server1, share1, workgroup, user1, password1); - if (!srv) { + srv = smbc_server(server1, share1, workgroup, user1, password1); + if (!srv) { - return -1; + return -1; - } + } - if (!cli_rename(&srv->cli, path1, path2)) { - int eno = smbc_errno(&srv->cli); + if (!cli_rename(&srv->cli, path1, path2)) { + int eno = smbc_errno(&srv->cli); - if (eno != EEXIST || - !cli_unlink(&srv->cli, path2) || - !cli_rename(&srv->cli, path1, path2)) { + if (eno != EEXIST || + !cli_unlink(&srv->cli, path2) || + !cli_rename(&srv->cli, path1, path2)) { - errno = eno; - return -1; + errno = eno; + return -1; - } - } + } + } - return 0; /* Success */ + return 0; /* Success */ } @@ -997,67 +1044,67 @@ int smbc_rename(const char *oname, const char *nname) off_t smbc_lseek(int fd, off_t offset, int whence) { - struct smbc_file *fe; - size_t size; + struct smbc_file *fe; + size_t size; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe) { + if (!fe) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - if (!fe->file) { + if (!fe->file) { - errno = EINVAL; - return -1; /* Can't lseek a dir ... */ + errno = EINVAL; + return -1; /* Can't lseek a dir ... */ - } + } - switch (whence) { - case SEEK_SET: - fe->offset = offset; - break; + switch (whence) { + case SEEK_SET: + fe->offset = offset; + break; - case SEEK_CUR: - fe->offset += offset; - break; + case SEEK_CUR: + fe->offset += offset; + break; - case SEEK_END: - if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, - NULL, NULL, NULL) && - !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, - NULL)) { + case SEEK_END: + if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + NULL, NULL, NULL) && + !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + NULL)) { - errno = EINVAL; - return -1; - } - fe->offset = size + offset; - break; + errno = EINVAL; + return -1; + } + fe->offset = size + offset; + break; - default: - errno = EINVAL; - break; + default: + errno = EINVAL; + break; - } + } - return fe->offset; + return fe->offset; } @@ -1069,8 +1116,8 @@ static ino_t smbc_inode(const char *name) { - if (!*name) return 2; /* FIXME, why 2 ??? */ - return (ino_t)str_checksum(name); + if (!*name) return 2; /* FIXME, why 2 ??? */ + return (ino_t)str_checksum(name); } @@ -1083,36 +1130,36 @@ static int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) { - st->st_mode = 0; - - if (IS_DOS_DIR(mode)) { - st->st_mode = SMBC_DIR_MODE; - } else { - st->st_mode = SMBC_FILE_MODE; - } - - if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; - if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; - if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; - if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; + st->st_mode = 0; - st->st_size = size; - st->st_blksize = 512; - st->st_blocks = (size+511)/512; - st->st_uid = getuid(); - st->st_gid = getgid(); + if (IS_DOS_DIR(mode)) { + st->st_mode = SMBC_DIR_MODE; + } else { + st->st_mode = SMBC_FILE_MODE; + } - if (IS_DOS_DIR(mode)) { - st->st_nlink = 2; - } else { - st->st_nlink = 1; - } + if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; + if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; + if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; + if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; + + st->st_size = size; + st->st_blksize = 512; + st->st_blocks = (size+511)/512; + st->st_uid = getuid(); + st->st_gid = getgid(); + + if (IS_DOS_DIR(mode)) { + st->st_nlink = 2; + } else { + st->st_nlink = 1; + } - if (st->st_ino == 0) { - st->st_ino = smbc_inode(fname); - } + if (st->st_ino == 0) { + st->st_ino = smbc_inode(fname); + } - return True; /* FIXME: Is this needed ? */ + return True; /* FIXME: Is this needed ? */ } @@ -1127,28 +1174,28 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, SMB_INO_T *ino) { - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4,("smbc_getatr: sending qpathinfo\n")); + DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - if (!srv->no_pathinfo2 && - cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, - size, mode, ino)) return True; - - /* if this is NT then don't bother with the getatr */ - if (srv->cli.capabilities & CAP_NT_SMBS) return False; - - if (cli_getatr(&srv->cli, path, mode, size, m_time)) { - a_time = c_time = m_time; - srv->no_pathinfo2 = True; - return True; - } - return False; + if (!srv->no_pathinfo2 && + cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, + size, mode, ino)) return True; + + /* if this is NT then don't bother with the getatr */ + if (srv->cli.capabilities & CAP_NT_SMBS) return False; + + if (cli_getatr(&srv->cli, path, mode, size, m_time)) { + a_time = c_time = m_time; + srv->no_pathinfo2 = True; + return True; + } + return False; } /* @@ -1157,85 +1204,85 @@ BOOL smbc_getatr(struct smbc_server *srv, char *path, int smbc_stat(const char *fname, struct stat *st) { - struct smbc_server *srv; - fstring server, share, user, password, workgroup; - pstring path; - time_t m_time = 0, a_time = 0, c_time = 0; - size_t size = 0; - uint16 mode = 0; - SMB_INO_T ino = 0; + struct smbc_server *srv; + fstring server, share, user, password, workgroup; + pstring path; + time_t m_time = 0, a_time = 0, c_time = 0; + size_t size = 0; + uint16 mode = 0; + SMB_INO_T ino = 0; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; /* Best I can think of ... */ - return -1; + errno = EINVAL; /* Best I can think of ... */ + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4, ("smbc_stat(%s)\n", fname)); + DEBUG(4, ("smbc_stat(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, smbc_user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(server, share, workgroup, user, password); - if (!srv) { + if (!srv) { - return -1; /* errno set by smbc_server */ + return -1; /* errno set by smbc_server */ - } + } - /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { + /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { - mode = aDIR | aRONLY; + mode = aDIR | aRONLY; - } - else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { + } + else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - if (strcmp(path, "\\") == 0) { + if (strcmp(path, "\\") == 0) { - mode = aDIR | aRONLY; + mode = aDIR | aRONLY; - } - else { + } + else { - mode = aRONLY; - smbc_stat_printjob(srv, path, &size, &m_time); - c_time = a_time = m_time; + mode = aRONLY; + smbc_stat_printjob(srv, path, &size, &m_time); + c_time = a_time = m_time; - } - else { */ + } + else { */ - if (!smbc_getatr(srv, path, &mode, &size, - &c_time, &a_time, &m_time, &ino)) { + if (!smbc_getatr(srv, path, &mode, &size, + &c_time, &a_time, &m_time, &ino)) { - errno = smbc_errno(&srv->cli); - return -1; + errno = smbc_errno(&srv->cli); + return -1; - } + } - /* } */ + /* } */ - st->st_ino = ino; + st->st_ino = ino; - smbc_setup_stat(st, path, size, mode); + smbc_setup_stat(st, path, size, mode); - st->st_atime = a_time; - st->st_ctime = c_time; - st->st_mtime = m_time; - st->st_dev = srv->dev; + st->st_atime = a_time; + st->st_ctime = c_time; + st->st_mtime = m_time; + st->st_dev = srv->dev; - return 0; + return 0; } @@ -1245,61 +1292,61 @@ int smbc_stat(const char *fname, struct stat *st) int smbc_fstat(int fd, struct stat *st) { - struct smbc_file *fe; - time_t c_time, a_time, m_time; - size_t size; - uint16 mode; - SMB_INO_T ino = 0; + struct smbc_file *fe; + time_t c_time, a_time, m_time; + size_t size; + uint16 mode; + SMB_INO_T ino = 0; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe) { + if (!fe) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - if (!fe->file) { + if (!fe->file) { - return smbc_fstatdir(fd, st); + return smbc_fstatdir(fd, st); - } + } - if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, - &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) && - !cli_getattrE(&fe->srv->cli, fe->cli_fd, - &mode, &size, &c_time, &a_time, &m_time)) { + if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, + &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) && + !cli_getattrE(&fe->srv->cli, fe->cli_fd, + &mode, &size, &c_time, &a_time, &m_time)) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - st->st_ino = ino; + st->st_ino = ino; - smbc_setup_stat(st, fe->fname, size, mode); + smbc_setup_stat(st, fe->fname, size, mode); - st->st_atime = a_time; - st->st_ctime = c_time; - st->st_mtime = m_time; - st->st_dev = fe->srv->dev; + st->st_atime = a_time; + st->st_ctime = c_time; + st->st_mtime = m_time; + st->st_dev = fe->srv->dev; - return 0; + return 0; } @@ -1313,136 +1360,139 @@ int smbc_fstat(int fd, struct stat *st) * smb:workgroup//server * smb://server * smb://server/share + * smb:// which should list shares on server + * smb:///share which should list files on share */ static void smbc_remove_dir(struct smbc_file *dir) { - struct smbc_dir_list *d,*f; + struct smbc_dir_list *d,*f; - d = dir->dir_list; - while (d) { + d = dir->dir_list; + while (d) { - f = d; d = d->next; + f = d; d = d->next; - SAFE_FREE(f->dirent); - SAFE_FREE(f); + SAFE_FREE(f->dirent); + SAFE_FREE(f); - } + } - dir->dir_list = dir->dir_end = dir->dir_next = NULL; + dir->dir_list = dir->dir_end = dir->dir_next = NULL; } static int add_dirent(struct smbc_file *dir, const char *name, const char *comment, uint32 type) { - struct smbc_dirent *dirent; - int size; + struct smbc_dirent *dirent; + int size; - /* - * Allocate space for the dirent, which must be increased by the - * size of the name and the comment and 1 for the null on the comment. - * The null on the name is already accounted for. - */ + /* + * Allocate space for the dirent, which must be increased by the + * size of the name and the comment and 1 for the null on the comment. + * The null on the name is already accounted for. + */ - size = sizeof(struct smbc_dirent) + (name?strlen(name):0) + - (comment?strlen(comment):0) + 1; + size = sizeof(struct smbc_dirent) + (name?strlen(name):0) + + (comment?strlen(comment):0) + 1; - dirent = malloc(size); + dirent = malloc(size); - if (!dirent) { + if (!dirent) { - dir->dir_error = ENOMEM; - return -1; + dir->dir_error = ENOMEM; + return -1; - } + } - if (dir->dir_list == NULL) { + if (dir->dir_list == NULL) { - dir->dir_list = malloc(sizeof(struct smbc_dir_list)); - if (!dir->dir_list) { + dir->dir_list = malloc(sizeof(struct smbc_dir_list)); + if (!dir->dir_list) { - SAFE_FREE(dirent); - dir->dir_error = ENOMEM; - return -1; + SAFE_FREE(dirent); + dir->dir_error = ENOMEM; + return -1; - } + } - dir->dir_end = dir->dir_next = dir->dir_list; + dir->dir_end = dir->dir_next = dir->dir_list; - } - else { + } + else { - dir->dir_end->next = malloc(sizeof(struct smbc_dir_list)); + dir->dir_end->next = malloc(sizeof(struct smbc_dir_list)); - if (!dir->dir_end) { + if (!dir->dir_end) { - SAFE_FREE(dirent); - dir->dir_error = ENOMEM; - return -1; + SAFE_FREE(dirent); + dir->dir_error = ENOMEM; + return -1; - } + } - dir->dir_end = dir->dir_end->next; + dir->dir_end = dir->dir_end->next; - } + } - dir->dir_end->next = NULL; - dir->dir_end->dirent = dirent; + dir->dir_end->next = NULL; + dir->dir_end->dirent = dirent; - dirent->smbc_type = type; - dirent->namelen = (name?strlen(name):0); - dirent->commentlen = (comment?strlen(comment):0); - dirent->dirlen = size; + dirent->smbc_type = type; + dirent->namelen = (name?strlen(name):0); + dirent->commentlen = (comment?strlen(comment):0); + dirent->dirlen = size; - strncpy(dirent->name, (name?name:""), dirent->namelen + 1); + strncpy(dirent->name, (name?name:""), dirent->namelen + 1); - dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); - strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); + dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); + strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); - return 0; + return 0; } static void list_fn(const char *name, uint32 type, const char *comment, void *state) { - struct smbc_file *dir = (struct smbc_file *)state; - int dirent_type; + struct smbc_file *dir = (struct smbc_file *)state; + int dirent_type; - /* We need to process the type a little ... */ + /* We need to process the type a little ... */ - if (dir->dir_type == SMBC_FILE_SHARE) { + if (dir->dir_type == SMBC_FILE_SHARE) { - switch (type) { - case 0: /* Directory tree */ - dirent_type = SMBC_FILE_SHARE; - break; + switch (type) { + case 0: /* Directory tree */ + dirent_type = SMBC_FILE_SHARE; + break; - case 1: - dirent_type = SMBC_PRINTER_SHARE; - break; + case 1: + dirent_type = SMBC_PRINTER_SHARE; + break; - case 2: - dirent_type = SMBC_COMMS_SHARE; - break; + case 2: + dirent_type = SMBC_COMMS_SHARE; + break; - case 3: - dirent_type = SMBC_IPC_SHARE; - break; + case 3: + dirent_type = SMBC_IPC_SHARE; + break; - default: - dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ - break; - } + default: + dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ + break; + } - } - else dirent_type = dir->dir_type; + } + else dirent_type = dir->dir_type; - if (add_dirent(dir, name, comment, dirent_type) < 0) { + if (add_dirent(dir, name, comment, dirent_type) < 0) { - /* An error occurred, what do we do? */ + /* An error occurred, what do we do? */ + /* FIXME: Add some code here */ - } + } } @@ -1450,312 +1500,309 @@ static void dir_list_fn(file_info *finfo, const char *mask, void *state) { - /* fprintf(stderr, "Finfo->name=%s, mask=%s, mode=%0X\n", finfo->name, mask, finfo->mode);*/ - if (add_dirent((struct smbc_file *)state, finfo->name, "", - (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { + if (add_dirent((struct smbc_file *)state, finfo->name, "", + (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { - /* Handle an error ... */ + /* Handle an error ... */ + /* FIXME: Add some code ... */ - } + } } int smbc_opendir(const char *fname) { - fstring server, share, user, password, workgroup; - pstring path; - struct smbc_server *srv = NULL; - struct in_addr rem_ip; - int slot = 0; + fstring server, share, user, password, workgroup; + pstring path; + struct smbc_server *srv = NULL; + struct in_addr rem_ip; + int slot = 0; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (smbc_parse_path(fname, server, share, path, user, password)) { + if (smbc_parse_path(fname, server, share, path, user, password)) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, smbc_user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - /* Get a file entry ... */ + /* Get a file entry ... */ - slot = 0; + slot = 0; - while (smbc_file_table[slot]) - slot++; + while (smbc_file_table[slot]) + slot++; - if (slot > smbc_max_fd) { + if (slot > SMBC_MAX_FD) { - errno = ENOMEM; - return -1; /* FIXME, ... move into a func */ + errno = ENOMEM; + return -1; /* FIXME, ... move into a func */ - } + } - smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); + smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); - if (!smbc_file_table[slot]) { + if (!smbc_file_table[slot]) { - errno = ENOMEM; - return -1; + errno = ENOMEM; + return -1; - } + } - smbc_file_table[slot]->cli_fd = 0; - smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; - smbc_file_table[slot]->fname = strdup(fname); - smbc_file_table[slot]->srv = NULL; - smbc_file_table[slot]->offset = 0; - smbc_file_table[slot]->file = False; - smbc_file_table[slot]->dir_list = - smbc_file_table[slot]->dir_next = - smbc_file_table[slot]->dir_end = NULL; + smbc_file_table[slot]->cli_fd = 0; + smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; + smbc_file_table[slot]->fname = strdup(fname); + smbc_file_table[slot]->srv = NULL; + smbc_file_table[slot]->offset = 0; + smbc_file_table[slot]->file = False; + smbc_file_table[slot]->dir_list = + smbc_file_table[slot]->dir_next = + smbc_file_table[slot]->dir_end = NULL; - if (server[0] == (char)0) { + if (server[0] == (char)0) { - if (share[0] != (char)0 || path[0] != (char)0) { + if (share[0] != (char)0 || path[0] != (char)0) { - errno = EINVAL; - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - return -1; - - } + errno = EINVAL; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + return -1; - /* We have server and share and path empty ... so list the workgroups */ + } - /*cli_get_backup_server(my_netbios_name, workgroup, server, sizeof(server));*/ + /* We have server and share and path empty ... so list the workgroups */ - if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) { + if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) { - errno = EINVAL; /* Something wrong with smb.conf? */ - return -1; + errno = EINVAL; /* Something wrong with smb.conf? */ + return -1; - } + } - smbc_file_table[slot]->dir_type = SMBC_WORKGROUP; + smbc_file_table[slot]->dir_type = SMBC_WORKGROUP; - /* find the name of the server ... */ + /* find the name of the server ... */ - if (!name_status_find(0, rem_ip, server)) { + if (!name_status_find(0, rem_ip, server)) { - fprintf(stderr, "Could not get the name of local master browser ...\n"); - errno = EINVAL; - return -1; + DEBUG(0, ("Could not get the name of local master browser for server %s\n", server); + errno = EINVAL; + return -1; - } + } - /* - * Get a connection to IPC$ on the server if we do not already have one - */ + /* + * Get a connection to IPC$ on the server if we do not already have one + */ - srv = smbc_server(server, "IPC$", workgroup, user, password); + srv = smbc_server(server, "IPC$", workgroup, user, password); - if (!srv) { + if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - return -1; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + return -1; - } + } - smbc_file_table[slot]->srv = srv; + smbc_file_table[slot]->srv = srv; - /* Now, list the stuff ... */ + /* Now, list the stuff ... */ - if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn, - (void *)smbc_file_table[slot])) { + if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn, + (void *)smbc_file_table[slot])) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - errno = cli_errno(&srv->cli); - return -1; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + errno = cli_errno(&srv->cli); + return -1; - } - } - else { /* Server not an empty string ... Check the rest and see what gives */ + } + } + else { /* Server not an empty string ... Check the rest and see what gives */ - if (share[0] == (char)0) { + if (share[0] == (char)0) { - if (path[0] != (char)0) { /* Should not have empty share with path */ + if (path[0] != (char)0) { /* Should not have empty share with path */ - errno = EINVAL; - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - return -1; + errno = EINVAL; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + return -1; - } + } - /* Check to see if <1D> translates, or <20> translates */ - /* However, we check to see if is an IP address first */ + /* Check to see if <1D> translates, or <20> translates */ + /* However, we check to see if is an IP address first */ - if (!is_ipaddress(server) && /* Not an IP addr so check next */ - resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ - pstring buserver; + if (!is_ipaddress(server) && /* Not an IP addr so check next */ + resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ + pstring buserver; - smbc_file_table[slot]->dir_type = SMBC_SERVER; + smbc_file_table[slot]->dir_type = SMBC_SERVER; - /* - * Get the backup list ... - */ + /* + * Get the backup list ... + */ - /*cli_get_backup_server(my_netbios_name, server, buserver, sizeof(buserver)); */ - if (!name_status_find(0, rem_ip, buserver)) { + if (!name_status_find(0, rem_ip, buserver)) { - fprintf(stderr, "Could not get name of local master browser ...\n"); - errno = EPERM; /* FIXME, is this correct */ - return -1; + DEBUG(0, ("Could not get name of local master browser %s\n", server)); + errno = EPERM; /* FIXME, is this correct */ + return -1; - } + } - /* - * Get a connection to IPC$ on the server if we do not already have one - */ + /* + * Get a connection to IPC$ on the server if we do not already have one + */ - srv = smbc_server(buserver, "IPC$", workgroup, user, password); + srv = smbc_server(buserver, "IPC$", workgroup, user, password); - if (!srv) { + if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - return -1; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + return -1; - } + } - smbc_file_table[slot]->srv = srv; + smbc_file_table[slot]->srv = srv; - /* Now, list the servers ... */ + /* Now, list the servers ... */ - if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn, - (void *)smbc_file_table[slot])) { + if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn, + (void *)smbc_file_table[slot])) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - errno = cli_errno(&srv->cli); - return -1; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + errno = cli_errno(&srv->cli); + return -1; - } + } - } - else { + } + else { - if (resolve_name(server, &rem_ip, 0x20)) { + if (resolve_name(server, &rem_ip, 0x20)) { - /* Now, list the shares ... */ + /* Now, list the shares ... */ - smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, "IPC$", workgroup, user, password); + srv = smbc_server(server, "IPC$", workgroup, user, password); - if (!srv) { + if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - return -1; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + return -1; - } + } - smbc_file_table[slot]->srv = srv; + smbc_file_table[slot]->srv = srv; - /* Now, list the servers ... */ + /* Now, list the servers ... */ - if (cli_RNetShareEnum(&srv->cli, list_fn, - (void *)smbc_file_table[slot]) < 0) { + if (cli_RNetShareEnum(&srv->cli, list_fn, + (void *)smbc_file_table[slot]) < 0) { - errno = cli_errno(&srv->cli); - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - return -1; + errno = cli_errno(&srv->cli); + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + return -1; - } + } - } - else { + } + else { - errno = ENODEV; /* Neither the workgroup nor server exists */ - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - return -1; + errno = ENODEV; /* Neither the workgroup nor server exists */ + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + return -1; - } + } - } + } - } - else { /* The server and share are specified ... work from there ... */ + } + else { /* The server and share are specified ... work from there ... */ - /* Well, we connect to the server and list the directory */ + /* Well, we connect to the server and list the directory */ - smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(server, share, workgroup, user, password); - if (!srv) { + if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - return -1; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + return -1; - } + } - smbc_file_table[slot]->srv = srv; + smbc_file_table[slot]->srv = srv; - /* Now, list the files ... */ + /* Now, list the files ... */ - pstrcat(path, "\\*"); + pstrcat(path, "\\*"); - if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, - (void *)smbc_file_table[slot]) < 0) { + if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, + (void *)smbc_file_table[slot]) < 0) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); - } - errno = smbc_errno(&srv->cli); - return -1; + if (smbc_file_table[slot]) { + SAFE_FREE(smbc_file_table[slot]->fname); + SAFE_FREE(smbc_file_table[slot]); + } + errno = smbc_errno(&srv->cli); + return -1; - } - } + } + } - } + } - return smbc_file_table[slot]->smbc_fd; + return smbc_file_table[slot]->smbc_fd; } @@ -1765,43 +1812,43 @@ int smbc_opendir(const char *fname) int smbc_closedir(int fd) { - struct smbc_file *fe; + struct smbc_file *fe; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe) { + if (!fe) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - smbc_remove_dir(fe); /* Clean it up */ + smbc_remove_dir(fe); /* Clean it up */ - if (fe) { + if (fe) { - SAFE_FREE(fe->fname); - SAFE_FREE(fe); /* Free the space too */ + SAFE_FREE(fe->fname); + SAFE_FREE(fe); /* Free the space too */ - } + } - smbc_file_table[fd - smbc_start_fd] = NULL; + smbc_file_table[fd - smbc_start_fd] = NULL; - return 0; + return 0; } @@ -1813,66 +1860,66 @@ static char smbc_local_dirent[512]; /* Make big enough */ struct smbc_dirent *smbc_readdir(unsigned int fd) { - struct smbc_file *fe; - struct smbc_dirent *dirp, *dirent; + struct smbc_file *fe; + struct smbc_dirent *dirp, *dirent; - /* Check that all is ok first ... */ + /* Check that all is ok first ... */ - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return NULL; + errno = EINVAL; + return NULL; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return NULL; + errno = EBADF; + return NULL; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe) { + if (!fe) { - errno = EBADF; - return NULL; + errno = EBADF; + return NULL; - } + } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (fe->file != False) { /* FIXME, should be dir, perhaps */ - errno = ENOTDIR; - return NULL; + errno = ENOTDIR; + return NULL; - } + } - if (!fe->dir_next) - return NULL; - else { + if (!fe->dir_next) + return NULL; + else { - dirent = fe->dir_next->dirent; + dirent = fe->dir_next->dirent; - if (!dirent) { + if (!dirent) { - errno = ENOENT; - return NULL; + errno = ENOENT; + return NULL; - } + } - /* Hmmm, do I even need to copy it? */ + /* Hmmm, do I even need to copy it? */ - bcopy(dirent, smbc_local_dirent, dirent->dirlen); /* Copy the dirent */ + bcopy(dirent, smbc_local_dirent, dirent->dirlen); /* Copy the dirent */ - dirp = (struct smbc_dirent *)smbc_local_dirent; + dirp = (struct smbc_dirent *)smbc_local_dirent; - dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); + dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); - fe->dir_next = fe->dir_next->next; + fe->dir_next = fe->dir_next->next; - return (struct smbc_dirent *)smbc_local_dirent; - } + return (struct smbc_dirent *)smbc_local_dirent; + } } @@ -1882,95 +1929,95 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) { - struct smbc_file *fe; - struct smbc_dir_list *dir; - int rem = count, reqd; - char *ndir = (char *)dirp; + struct smbc_file *fe; + struct smbc_dir_list *dir; + int rem = count, reqd; + char *ndir = (char *)dirp; - /* Check that all is ok first ... */ + /* Check that all is ok first ... */ - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe) { + if (!fe) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (fe->file != False) { /* FIXME, should be dir, perhaps */ - errno = ENOTDIR; - return -1; + errno = ENOTDIR; + return -1; - } + } - /* - * Now, retrieve the number of entries that will fit in what was passed - * We have to figure out if the info is in the list, or we need to - * send a request to the server to get the info. - */ + /* + * Now, retrieve the number of entries that will fit in what was passed + * We have to figure out if the info is in the list, or we need to + * send a request to the server to get the info. + */ - while ((dir = fe->dir_next)) { - struct smbc_dirent *dirent; + while ((dir = fe->dir_next)) { + struct smbc_dirent *dirent; - if (!dir->dirent) { + if (!dir->dirent) { - errno = ENOENT; /* Bad error */ - return -1; + errno = ENOENT; /* Bad error */ + return -1; - } + } - if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen + - dir->dirent->commentlen + 1))) { + if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen + + dir->dirent->commentlen + 1))) { - if (rem < count) { /* We managed to copy something */ + if (rem < count) { /* We managed to copy something */ - errno = 0; - return count - rem; + errno = 0; + return count - rem; - } - else { /* Nothing copied ... */ + } + else { /* Nothing copied ... */ - errno = EINVAL; /* Not enough space ... */ - return -1; + errno = EINVAL; /* Not enough space ... */ + return -1; - } + } - } + } - dirent = dir->dirent; + dirent = dir->dirent; - bcopy(dirent, ndir, reqd); /* Copy the data in ... */ + bcopy(dirent, ndir, reqd); /* Copy the data in ... */ - ((struct smbc_dirent *)ndir)->comment = - (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1); + ((struct smbc_dirent *)ndir)->comment = + (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1); - ndir += reqd; + ndir += reqd; - rem -= reqd; + rem -= reqd; - fe->dir_next = dir = dir -> next; - } + fe->dir_next = dir = dir -> next; + } - if (rem == count) - return 0; - else - return count - rem; + if (rem == count) + return 0; + else + return count - rem; } @@ -1980,69 +2027,69 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) int smbc_mkdir(const char *fname, mode_t mode) { - struct smbc_server *srv; - fstring server, share, user, password, workgroup; - pstring path; + struct smbc_server *srv; + fstring server, share, user, password, workgroup; + pstring path; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4, ("smbc_mkdir(%s)\n", fname)); + DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, smbc_user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(server, share, workgroup, user, password); - if (!srv) { + if (!srv) { - return -1; /* errno set by smbc_server */ + return -1; /* errno set by smbc_server */ - } + } - /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { + /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { - mode = aDIR | aRONLY; + mode = aDIR | aRONLY; - } - else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { + } + else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - if (strcmp(path, "\\") == 0) { + if (strcmp(path, "\\") == 0) { - mode = aDIR | aRONLY; + mode = aDIR | aRONLY; - } - else { + } + else { - mode = aRONLY; - smbc_stat_printjob(srv, path, &size, &m_time); - c_time = a_time = m_time; + mode = aRONLY; + smbc_stat_printjob(srv, path, &size, &m_time); + c_time = a_time = m_time; - } - else { */ + } + else { */ - if (!cli_mkdir(&srv->cli, path)) { + if (!cli_mkdir(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); - return -1; + errno = smbc_errno(&srv->cli); + return -1; - } + } - return 0; + return 0; } @@ -2055,8 +2102,8 @@ static int smbc_rmdir_dirempty = True; static void rmdir_list_fn(file_info *finfo, const char *mask, void *state) { - if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0) - smbc_rmdir_dirempty = False; + if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0) + smbc_rmdir_dirempty = False; } @@ -2066,97 +2113,97 @@ static void rmdir_list_fn(file_info *finfo, const char *mask, void *state) int smbc_rmdir(const char *fname) { - struct smbc_server *srv; - fstring server, share, user, password, workgroup; - pstring path; + struct smbc_server *srv; + fstring server, share, user, password, workgroup; + pstring path; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4, ("smbc_rmdir(%s)\n", fname)); + DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, smbc_user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(server, share, workgroup, user, password); - if (!srv) { + if (!srv) { - return -1; /* errno set by smbc_server */ + return -1; /* errno set by smbc_server */ - } + } - /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { + /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { - mode = aDIR | aRONLY; + mode = aDIR | aRONLY; - } - else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { + } + else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - if (strcmp(path, "\\") == 0) { + if (strcmp(path, "\\") == 0) { - mode = aDIR | aRONLY; + mode = aDIR | aRONLY; - } - else { + } + else { - mode = aRONLY; - smbc_stat_printjob(srv, path, &size, &m_time); - c_time = a_time = m_time; + mode = aRONLY; + smbc_stat_printjob(srv, path, &size, &m_time); + c_time = a_time = m_time; - } - else { */ + } + else { */ - if (!cli_rmdir(&srv->cli, path)) { + if (!cli_rmdir(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(&srv->cli); - if (errno == EACCES) { /* Check if the dir empty or not */ + if (errno == EACCES) { /* Check if the dir empty or not */ - pstring lpath; /* Local storage to avoid buffer overflows */ + pstring lpath; /* Local storage to avoid buffer overflows */ - smbc_rmdir_dirempty = True; /* Make this so ... */ + smbc_rmdir_dirempty = True; /* Make this so ... */ - pstrcpy(lpath, path); - pstrcat(lpath, "\\*"); + pstrcpy(lpath, path); + pstrcat(lpath, "\\*"); - if (cli_list(&srv->cli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn, - NULL) < 0) { + if (cli_list(&srv->cli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn, + NULL) < 0) { - /* Fix errno to ignore latest error ... */ + /* Fix errno to ignore latest error ... */ - DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n", - smbc_errno(&srv->cli))); - errno = EACCES; + DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n", + smbc_errno(&srv->cli))); + errno = EACCES; - } + } - if (smbc_rmdir_dirempty) - errno = EACCES; - else - errno = ENOTEMPTY; + if (smbc_rmdir_dirempty) + errno = EACCES; + else + errno = ENOTEMPTY; - } + } - return -1; + return -1; - } + } - return 0; + return 0; } @@ -2166,39 +2213,39 @@ int smbc_rmdir(const char *fname) off_t smbc_telldir(int fd) { - struct smbc_file *fe; + struct smbc_file *fe; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe) { + if (!fe) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (fe->file != False) { /* FIXME, should be dir, perhaps */ - errno = ENOTDIR; - return -1; + errno = ENOTDIR; + return -1; - } + } - return (off_t) fe->dir_next; + return (off_t) fe->dir_next; } @@ -2210,24 +2257,24 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, struct smbc_dirent *dirent) { - /* Run down the list looking for what we want */ + /* Run down the list looking for what we want */ - if (dirent) { + if (dirent) { - struct smbc_dir_list *tmp = list; + struct smbc_dir_list *tmp = list; - while (tmp) { + while (tmp) { - if (tmp->dirent == dirent) - return tmp; + if (tmp->dirent == dirent) + return tmp; - tmp = tmp->next; + tmp = tmp->next; - } + } - } + } - return NULL; /* Not found, or an error */ + return NULL; /* Not found, or an error */ } @@ -2238,62 +2285,62 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, int smbc_lseekdir(int fd, off_t offset) { - struct smbc_file *fe; - struct smbc_dirent *dirent = (struct smbc_dirent *)offset; - struct smbc_dir_list *list_ent = NULL; + struct smbc_file *fe; + struct smbc_dirent *dirent = (struct smbc_dirent *)offset; + struct smbc_dir_list *list_ent = NULL; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + smbc_max_fd)) { + if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - fe = smbc_file_table[fd - smbc_start_fd]; + fe = smbc_file_table[fd - smbc_start_fd]; - if (!fe) { + if (!fe) { - errno = EBADF; - return -1; + errno = EBADF; + return -1; - } + } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (fe->file != False) { /* FIXME, should be dir, perhaps */ - errno = ENOTDIR; - return -1; + errno = ENOTDIR; + return -1; - } + } - /* Now, check what we were passed and see if it is OK ... */ + /* Now, check what we were passed and see if it is OK ... */ - if (dirent == NULL) { /* Seek to the begining of the list */ + if (dirent == NULL) { /* Seek to the begining of the list */ - fe->dir_next = fe->dir_list; - return 0; + fe->dir_next = fe->dir_list; + return 0; - } + } - /* Now, run down the list and make sure that the entry is OK */ - /* This may need to be changed if we change the format of the list */ + /* Now, run down the list and make sure that the entry is OK */ + /* This may need to be changed if we change the format of the list */ - if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) { + if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) { - errno = EINVAL; /* Bad entry */ - return -1; + errno = EINVAL; /* Bad entry */ + return -1; - } + } - fe->dir_next = list_ent; + fe->dir_next = list_ent; - return 0; + return 0; } @@ -2304,16 +2351,16 @@ int smbc_lseekdir(int fd, off_t offset) int smbc_fstatdir(int fd, struct stat *st) { - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - /* No code yet ... */ + /* No code yet ... */ - return 0; + return 0; } @@ -2326,71 +2373,71 @@ int smbc_fstatdir(int fd, struct stat *st) int smbc_print_file(const char *fname, const char *printq) { - int fid1, fid2, bytes, saverr, tot_bytes = 0; - char buf[4096]; + int fid1, fid2, bytes, saverr, tot_bytes = 0; + char buf[4096]; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (!fname && !printq) { + if (!fname && !printq) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - /* Try to open the file for reading ... */ + /* Try to open the file for reading ... */ - if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { + if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { - fprintf(stderr, "Error, fname=%s, errno=%i\n", fname, errno); - return -1; /* smbc_open sets errno */ + DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); + return -1; /* smbc_open sets errno */ - } + } - /* Now, try to open the printer file for writing */ + /* Now, try to open the printer file for writing */ - if ((fid2 = smbc_open_print_job(printq)) < 0) { + if ((fid2 = smbc_open_print_job(printq)) < 0) { - saverr = errno; /* Save errno */ - smbc_close(fid1); - errno = saverr; - return -1; + saverr = errno; /* Save errno */ + smbc_close(fid1); + errno = saverr; + return -1; - } + } - while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) { + while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) { - tot_bytes += bytes; + tot_bytes += bytes; - if ((smbc_write(fid2, buf, bytes)) < 0) { + if ((smbc_write(fid2, buf, bytes)) < 0) { - saverr = errno; - smbc_close(fid1); - smbc_close(fid2); - errno = saverr; + saverr = errno; + smbc_close(fid1); + smbc_close(fid2); + errno = saverr; - } + } - } + } - saverr = errno; + saverr = errno; - smbc_close(fid1); /* We have to close these anyway */ - smbc_close(fid2); + smbc_close(fid1); /* We have to close these anyway */ + smbc_close(fid2); - if (bytes < 0) { + if (bytes < 0) { - errno = saverr; - return -1; + errno = saverr; + return -1; - } + } - return tot_bytes; + return tot_bytes; } @@ -2400,30 +2447,30 @@ int smbc_print_file(const char *fname, const char *printq) int smbc_open_print_job(const char *fname) { - fstring server, share, user, password; - pstring path; + fstring server, share, user, password; + pstring path; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4, ("smbc_open_print_job(%s)\n", fname)); + DEBUG(4, ("smbc_open_print_job(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - /* What if the path is empty, or the file exists? */ + /* What if the path is empty, or the file exists? */ - return smbc_open(fname, O_WRONLY, 666); + return smbc_open(fname, O_WRONLY, 666); } @@ -2433,48 +2480,48 @@ int smbc_open_print_job(const char *fname) int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) { - struct smbc_server *srv; - fstring server, share, user, password, workgroup; - pstring path; + struct smbc_server *srv; + fstring server, share, user, password, workgroup; + pstring path; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, smbc_user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(server, share, workgroup, user, password); - if (!srv) { + if (!srv) { - return -1; /* errno set by smbc_server */ + return -1; /* errno set by smbc_server */ - } + } - if (cli_print_queue(&srv->cli, fn) < 0) { + if (cli_print_queue(&srv->cli, fn) < 0) { - errno = smbc_errno(&srv->cli); - return -1; + errno = smbc_errno(&srv->cli); + return -1; - } + } - return 0; + return 0; } @@ -2484,53 +2531,53 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) int smbc_unlink_print_job(const char *fname, int id) { - struct smbc_server *srv; - fstring server, share, user, password, workgroup; - pstring path; - int err; + struct smbc_server *srv; + fstring server, share, user, password, workgroup; + pstring path; + int err; - if (!smbc_initialized) { + if (!smbc_initialized) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - if (!fname) { + if (!fname) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; - } + } - DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, smbc_user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, lp_workgroup()); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(server, share, workgroup, user, password); - if (!srv) { + if (!srv) { - return -1; /* errno set by smbc_server */ + return -1; /* errno set by smbc_server */ - } + } - if ((err = cli_printjob_del(&srv->cli, id)) != 0) { + if ((err = cli_printjob_del(&srv->cli, id)) != 0) { - if (err < 0) - errno = smbc_errno(&srv->cli); - else if (err == ERRnosuchprintjob) - errno = EINVAL; - return -1; + if (err < 0) + errno = smbc_errno(&srv->cli); + else if (err == ERRnosuchprintjob) + errno = EINVAL; + return -1; - } + } - return 0; + return 0; } -- cgit From cade2944094b7c2ea9a4d58ebfd364bc3f51ee30 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 21 Nov 2001 05:19:13 +0000 Subject: Fix up the build again... Andrew Bartlett (This used to be commit a34c07377b1de61e145f699047474a82962ccd5b) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 74a42990f7..af2daac3fc 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1604,7 +1604,7 @@ int smbc_opendir(const char *fname) if (!name_status_find(0, rem_ip, server)) { - DEBUG(0, ("Could not get the name of local master browser for server %s\n", server); + DEBUG(0, ("Could not get the name of local master browser for server %s\n", server)); errno = EINVAL; return -1; -- cgit From e734163ac472f64457ec4bcfd3e9bd364ee91c6c Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 21 Nov 2001 11:04:49 +0000 Subject: One more patch from Tom Jansen. Hope I didn't break the tree :-) (This used to be commit 6d7c0f0bb4cbfdcd9a83416345432e07556f6cfc) --- source3/libsmb/clientgen.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 133408dff4..0f1fa2e42e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -38,6 +38,10 @@ recv an smb BOOL cli_receive_smb(struct cli_state *cli) { BOOL ret; + + /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ + if (cli->fd == -1) return False; + again: ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); @@ -78,6 +82,9 @@ BOOL cli_send_smb(struct cli_state *cli) size_t nwritten=0; ssize_t ret; + /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ + if (cli->fd == -1) return False; + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { -- cgit From f146325e7df80b26616225017ef6a60ff5f2e349 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Nov 2001 23:00:59 +0000 Subject: W2K doesn't seem to respond to *#0 names in node status. Ensure name lookup uses password server parameter when looking for PDCs. Jeremy. (This used to be commit 54c968913d6553c6d834b068234ab176917075eb) --- source3/libsmb/domain_client_validate.c | 2 +- source3/libsmb/libsmbclient.c | 4 +-- source3/libsmb/namequery.c | 63 ++++++++++++++++++++++++++++----- 3 files changed, 58 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index a8c3ff2f6b..2fd17e1fa4 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -53,7 +53,7 @@ static BOOL connect_to_domain_password_server(struct cli_state *pcli, return False; } - if (!name_status_find(0x20, to_ip, remote_machine)) { + if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) { DEBUG(0, ("connect_to_domain_password_server: Can't " "resolve name for IP %s\n", server)); return False; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index af2daac3fc..ce00548518 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1602,7 +1602,7 @@ int smbc_opendir(const char *fname) /* find the name of the server ... */ - if (!name_status_find(0, rem_ip, server)) { + if (!name_status_find("*", 0, 0, rem_ip, server)) { DEBUG(0, ("Could not get the name of local master browser for server %s\n", server)); errno = EINVAL; @@ -1671,7 +1671,7 @@ int smbc_opendir(const char *fname) */ - if (!name_status_find(0, rem_ip, buserver)) { + if (!name_status_find("*", 0, 0, rem_ip, buserver)) { DEBUG(0, ("Could not get name of local master browser %s\n", server)); errno = EPERM; /* FIXME, is this correct */ diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0e696a085b..f8688ddb25 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -160,7 +160,8 @@ find the first type XX name in a node status reply - used for finding a servers name given its IP return the matched name in *name **************************************************************************/ -BOOL name_status_find(int type, struct in_addr to_ip, char *name) + +BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name) { struct node_status *status; struct nmb_name nname; @@ -168,17 +169,22 @@ BOOL name_status_find(int type, struct in_addr to_ip, char *name) int sock; sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); - if (sock == -1) return False; + if (sock == -1) + return False; - make_nmb_name(&nname, "*", 0); + /* W2K PDC's seem not to respond to '*'#0. JRA */ + make_nmb_name(&nname, q_name, q_type); status = node_status_query(sock, &nname, to_ip, &count); close(sock); - if (!status) return False; + if (!status) + return False; for (i=0;i Date: Thu, 22 Nov 2001 08:31:50 +0000 Subject: Got positive and negative name caching working correctly with lookupname/lookupsid. There was a bug in cli_lsa_lookup_name/lookup_sid where NT_STATUS_NONE_MAPPED was being mapped to NT_STATUS_OK, and also the *wrong* number of entries mapped was being returned. The correct field is mapped_count, *NOT* num_entries. Jeremy. (This used to be commit 9f8c644abc455510c06dbd5dbac49c6270746560) --- source3/libsmb/cli_lsarpc.c | 46 +++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 046422abc6..4850e2a8bb 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -255,36 +255,37 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_FILES_OPEN) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NONE_MAPPED)) { - + if (!NT_STATUS_IS_OK(result) && + NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_FILES_OPEN)) { /* An actual error occured */ goto done; } - result = NT_STATUS_OK; /* Return output parameters */ - (*num_names) = r.names->num_entries; - - if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * - r.names->num_entries))) { + if (r.mapped_count == 0) { + result = NT_STATUS_NONE_MAPPED; + goto done; + } + + (*num_names) = r.mapped_count; + result = NT_STATUS_OK; + + if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * - r.names->num_entries))) { + if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - for (i = 0; i < r.names->num_entries; i++) { + for (i = 0; i < r.mapped_count; i++) { fstring name, dom_name, full_name; uint32 dom_idx = t_names.name[i].domain_idx; @@ -361,35 +362,36 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NONE_MAPPED)) { - + if (!NT_STATUS_IS_OK(result)) { /* An actual error occured */ goto done; } - result = NT_STATUS_OK; /* Return output parameters */ - (*num_sids) = r.num_entries; + if (r.mapped_count == 0) { + result = NT_STATUS_NONE_MAPPED; + goto done; + } + + (*num_sids) = r.mapped_count; + result = NT_STATUS_OK; - if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * - r.num_entries)))) { + if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.mapped_count)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * - r.num_entries)))) { + if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - for (i = 0; i < r.num_entries; i++) { + for (i = 0; i < r.mapped_count; i++) { DOM_RID2 *t_rids = r.dom_rid; uint32 dom_idx = t_rids[i].rid_idx; uint32 dom_rid = t_rids[i].rid; -- cgit From 2e8ae887857249822b84461fd503105555873508 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Thu, 22 Nov 2001 16:12:43 +0000 Subject: add a command to rpcclient: enumprivs J.F. (This used to be commit fa63cb78e326040f68d858d593ba98e06c26c92e) --- source3/libsmb/cli_lsarpc.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 4850e2a8bb..e8ed50206c 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -607,4 +607,86 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** Enumerate privileges*/ + +NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length, + uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low) +{ + prs_struct qbuf, rbuf; + LSA_Q_ENUM_PRIVS q; + LSA_R_ENUM_PRIVS r; + NTSTATUS result; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_q_enum_privs(&q, pol, *enum_context, pref_max_length); + + if (!lsa_io_q_enum_privs("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_ENUM_PRIVS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_enum_privs("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + /* Return output parameters */ + + *enum_context = r.enum_context; + *count = r.count; + + if (!((*privs_name = (char **)talloc(mem_ctx, sizeof(char *) * r.count)))) { + DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!((*privs_high = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) { + DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!((*privs_low = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) { + DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + for (i = 0; i < r.count; i++) { + fstring name; + + rpcstr_pull_unistr2_fstring( name, &r.privs[i].name); + + (*privs_name)[i] = talloc_strdup(mem_ctx, name); + + (*privs_high)[i] = r.privs[i].luid_high; + (*privs_low)[i] = r.privs[i].luid_low; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 33e20222e03482b20224b0b077beefb4079baa34 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Thu, 22 Nov 2001 16:54:48 +0000 Subject: add another command to rpcclient: getdispname. Show the full description of a privilege. J.F. (This used to be commit 84035ae72f422edadd9fa7e493c3d8176bb6a53d) --- source3/libsmb/cli_lsarpc.c | 53 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index e8ed50206c..c789badc72 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -689,4 +689,57 @@ NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** Get privilege name */ + +NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys, + fstring description, uint16 *lang_id_desc) +{ + prs_struct qbuf, rbuf; + LSA_Q_PRIV_GET_DISPNAME q; + LSA_R_PRIV_GET_DISPNAME r; + NTSTATUS result; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys); + + if (!lsa_io_q_priv_get_dispname("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_priv_get_dispname("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + /* Return output parameters */ + + rpcstr_pull_unistr2_fstring(description , &r.desc); + *lang_id_desc = r.lang_id; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From e996ac23f7f40fcb36616d26d3d8093f66f3c243 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 22 Nov 2001 22:45:52 +0000 Subject: Oops - opening wrong pipe name in cli_lsa_initialise() helper function. (This used to be commit d2034bc5f7dc9b5b9d5e4f17ee8e468307dcb2d5) --- source3/libsmb/cli_lsarpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index c789badc72..bb59bc011e 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -43,7 +43,7 @@ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { - return cli_pipe_initialise(cli, system_name, PIPE_LSASS, creds); + return cli_pipe_initialise(cli, system_name, PIPE_LSARPC, creds); } /** Open a LSA policy handle */ -- cgit From 9927b5b392592e8ab5e64d4da22d8d965924ba2c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 22 Nov 2001 23:38:37 +0000 Subject: Removed unused variable. (This used to be commit d1dee2d0323fe6fc498e50201535b1718a88abaf) --- source3/libsmb/cli_lsarpc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index bb59bc011e..d7eaaeafc6 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -699,7 +699,6 @@ NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx, LSA_Q_PRIV_GET_DISPNAME q; LSA_R_PRIV_GET_DISPNAME r; NTSTATUS result; - int i; ZERO_STRUCT(q); ZERO_STRUCT(r); -- cgit From fbfd27a495afa8673d472957867e58b34499760e Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Thu, 22 Nov 2001 23:50:16 +0000 Subject: added lsa_enum_sids to rpcclient fixed lsa_enum_rpivs server code. This time it works as W2K. fixed smbgroupedit to compile and work. J.F. (This used to be commit 646651018a2736833e49e76f6ca735a4647d9746) --- source3/libsmb/cli_lsarpc.c | 69 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index d7eaaeafc6..b533fe7449 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -741,4 +741,73 @@ NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** Enumerate list of SIDs */ + +NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length, + uint32 *num_sids, DOM_SID **sids) +{ + prs_struct qbuf, rbuf; + LSA_Q_ENUM_ACCOUNTS q; + LSA_R_ENUM_ACCOUNTS r; + NTSTATUS result; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length); + + if (!lsa_io_q_enum_accounts("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_enum_accounts("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + result = r.status; + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + + /* Return output parameters */ + + *sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.sids.num_entries); + if (!*sids) { + DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Copy across names and sids */ + + for (i = 0; i < r.sids.num_entries; i++) { + sid_copy(&(*sids)[i], &r.sids.sid[i].sid); + } + + *num_sids= r.sids.num_entries; + *enum_ctx = r.enum_context; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 554d387ab33220e7dc02d7a8c1aba854277b92f3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Nov 2001 05:37:40 +0000 Subject: Added constants and error message for dos error code 1326 (logon failure). (This used to be commit 6ce1eec09de64f19d969a67fc236abd4ae277926) --- source3/libsmb/errormap.c | 2 +- source3/libsmb/smberr.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 65dcdf4bdf..18e70eed36 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -133,7 +133,7 @@ static struct { {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, {ERRDOS, 1324, NT_STATUS_ILL_FORMED_PASSWORD}, {ERRDOS, 1325, NT_STATUS_PASSWORD_RESTRICTION}, - {ERRDOS, 1326, NT_STATUS_LOGON_FAILURE}, + {ERRDOS, ERRlogonfailure, NT_STATUS_LOGON_FAILURE}, {ERRDOS, 1327, NT_STATUS_ACCOUNT_RESTRICTION}, {ERRDOS, 1328, NT_STATUS_INVALID_LOGON_HOURS}, {ERRDOS, 1329, NT_STATUS_INVALID_WORKSTATION}, diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 66256d2385..a43e4764e8 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -25,6 +25,17 @@ /* error code stuff - put together by Merik Karman merik@blackadder.dsh.oz.au */ + +/* There is a big list of error codes and their meanings at: + + http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/errlist_7oz7.asp + + and if you don't like MSDN try: + + http://www.siris.gr/computers/library/error.htm + +*/ + typedef const struct { char *name; @@ -64,6 +75,7 @@ err_code_struct dos_msgs[] = { {"ERRnotconnected",ERRnotconnected,"No process on other end of pipe."}, {"ERRmoredata",ERRmoredata,"There is more data to be returned."}, {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"}, + {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, {NULL,-1,NULL}}; /* Server Error Messages */ -- cgit From a2e136a8a0c9836420db0b595c8d45c106a0663c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Nov 2001 05:50:05 +0000 Subject: Finally worked out why a enumerate trusted domains was returning a NT_STATUS_UNABLE_TO_FREE_VM error. This error code was mis-defined as 0x8000001a instead of 0xc000001a. The former is actually a NT_STATUS_NO_MORE_ENTRIES warning which is what we see in the status code. Removed the & 0xffffff from the loop in get_nt_error_msg() as all the error constants now have the correct high bits set. (This used to be commit 80dca2c9e46753d87e673d712c96c76ffde0b276) --- source3/libsmb/cli_lsarpc.c | 21 ++++++++++++--------- source3/libsmb/nterr.c | 5 +++-- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index b533fe7449..97f604fcb5 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -25,7 +25,8 @@ #include "includes.h" -/** @defgroup rpc_client RPC Client +/** @defgroup lsa LSA rpc client routines + * @ingroup rpc_client * * @{ **/ @@ -37,16 +38,22 @@ * security authority", which is half of a password database. **/ -/** Opens a SMB connection to the lsa pipe +/** Opens a SMB connection and connects to the LSARPC pipe. * - * @param system_name NETBIOS name of the machine to connect to. */ + * @param cli Uninitialised client handle. + * @param system_name NETBIOS name of the machine to connect to. + * @param creds User credentials to connect as. + * @returns Initialised client handle. + */ struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, struct ntuser_creds *creds) { return cli_pipe_initialise(cli, system_name, PIPE_LSARPC, creds); } -/** Open a LSA policy handle */ +/** Open a LSA policy handle + * + * @param cli Handle on an initialised SMB connection */ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, BOOL sec_qos, uint32 des_access, POLICY_HND *pol) @@ -548,12 +555,8 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - /* For some undocumented reason this function sometimes returns - 0x8000001a (NT_STATUS_UNABLE_TO_FREE_VM) so we ignore it and - pretend everything is OK. */ - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_UNABLE_TO_FREE_VM)) { + NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NO_MORE_ENTRIES)) { /* An actual error ocured */ diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index ab0a425633..238908d6cd 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, + { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { NULL, NT_STATUS(0) } }; @@ -548,8 +549,8 @@ char *get_nt_error_msg(NTSTATUS nt_code) slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); while (nt_errs[idx].nt_errstr != NULL) { - if ((NT_STATUS_V(nt_errs[idx].nt_errcode) & 0xFFFFFF) == - (NT_STATUS_V(nt_code) & 0xFFFFFF)) { + if (NT_STATUS_V(nt_errs[idx].nt_errcode) == + NT_STATUS_V(nt_code)) { return nt_errs[idx].nt_errstr; } idx++; -- cgit From d1b5508a7b8c9a8085db4bb9f0c0fa26b7eb542a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 23 Nov 2001 07:08:20 +0000 Subject: Update some of the error mapping, based on on-the-wire observations of an NT4 server. This lets our Win9X clients give sane error messages when you get passwords wrong and the like. Andrew Bartlett (This used to be commit f199e9518226ed57a011113bdf06c85265e49674) --- source3/libsmb/errormap.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 18e70eed36..f4208e7f5e 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -135,10 +135,10 @@ static struct { {ERRDOS, 1325, NT_STATUS_PASSWORD_RESTRICTION}, {ERRDOS, ERRlogonfailure, NT_STATUS_LOGON_FAILURE}, {ERRDOS, 1327, NT_STATUS_ACCOUNT_RESTRICTION}, - {ERRDOS, 1328, NT_STATUS_INVALID_LOGON_HOURS}, - {ERRDOS, 1329, NT_STATUS_INVALID_WORKSTATION}, - {ERRDOS, 1330, NT_STATUS_PASSWORD_EXPIRED}, - {ERRDOS, 1331, NT_STATUS_ACCOUNT_DISABLED}, + {ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, + {ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, + {ERRSRV, 2242, NT_STATUS_PASSWORD_EXPIRED}, + {ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, {ERRDOS, 1332, NT_STATUS_NONE_MAPPED}, {ERRDOS, 1333, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, {ERRDOS, 1334, NT_STATUS_LUIDS_EXHAUSTED}, @@ -374,7 +374,7 @@ static struct { {ERRDOS, 1501, NT_STATUS_EVENTLOG_CANT_START}, {ERRDOS, 1790, NT_STATUS_TRUST_FAILURE}, {ERRDOS, 1792, NT_STATUS_NETLOGON_NOT_STARTED}, - {ERRDOS, 1793, NT_STATUS_ACCOUNT_EXPIRED}, + {ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, {ERRDOS, 1131, NT_STATUS_POSSIBLE_DEADLOCK}, {ERRDOS, 1219, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, {ERRDOS, 1220, NT_STATUS_REMOTE_SESSION_LIMIT}, @@ -408,14 +408,14 @@ static struct { {ERRDOS, 6118, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, {ERRDOS, 1132, NT_STATUS_MAPPED_ALIGNMENT}, {ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, - {ERRDOS, 1907, NT_STATUS_PASSWORD_MUST_CHANGE}, + {ERRSRV, 2242, NT_STATUS_PASSWORD_MUST_CHANGE}, {ERRDOS, 1168, NT_STATUS_NOT_FOUND}, {ERRDOS, 554, NT_STATUS_DUPLICATE_OBJECTID}, {ERRDOS, 555, NT_STATUS_OBJECTID_EXISTS}, {ERRDOS, 1237, NT_STATUS_RETRY}, {ERRDOS, 1170, NT_STATUS_PROPSET_NOT_FOUND}, {ERRDOS, 1908, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, - {ERRDOS, 1909, NT_STATUS_ACCOUNT_LOCKED_OUT}, + {ERRDOS, ERRnoaccess, NT_STATUS_ACCOUNT_LOCKED_OUT}, {ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, {ERRDOS, 1225, NT_STATUS_CONNECTION_REFUSED}, {ERRDOS, 1226, NT_STATUS_GRACEFUL_DISCONNECT}, -- cgit From 2527f5ef52400294c98b4f4345a4f18b981ff22f Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 23 Nov 2001 15:11:22 +0000 Subject: Changed how the privileges are stored in the group mapping code. It's now an array of uint32. That's not perfect but that's better. Added more privileges too. Changed the local_lookup_rid/name functions in passdb.c to check if the group is mapped. Makes the LSA rpc calls return correct groups Corrected the return code in the LSA server code enum_sids. Only enumerate well known aliases if they are mapped to real unix groups. Won't confuse user seeing groups not available. Added a short/long view to smbgroupedit. now decoding rpc calls to add/remove privileges to sid. J.F. (This used to be commit f29774e58973f421bfa163c45bfae201a140f28c) --- source3/libsmb/cli_lsarpc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 97f604fcb5..e944734292 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -787,6 +787,8 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } + if (r.sids.num_entries==0) + goto done; /* Return output parameters */ -- cgit From ca477a61e7a202ba7df756780149a14c1159a73f Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sat, 24 Nov 2001 00:13:41 +0000 Subject: added lsaenumprivsaccount and lsalookupprivvalue to rpcclient and more to come ... J.F. (This used to be commit 1748d5a2af1f2dcf718d6f162ed483b001542494) --- source3/libsmb/cli_lsarpc.c | 174 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index e944734292..ffe86eccd5 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -815,4 +815,178 @@ NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** Open a LSA user handle + * + * @param cli Handle on an initialised SMB connection */ + +NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access, + POLICY_HND *user_pol) +{ + prs_struct qbuf, rbuf; + LSA_Q_OPENACCOUNT q; + LSA_R_OPENACCOUNT r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_lsa_q_open_account(&q, dom_pol, sid, des_access); + + /* Marshall data and send request */ + + if (!lsa_io_q_open_account("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_OPENACCOUNT, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_open_account("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if (NT_STATUS_IS_OK(result = r.status)) { + *user_pol = r.pol; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/** Enumerate user privileges + * + * @param cli Handle on an initialised SMB connection */ + +NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *count, LUID_ATTR **set) +{ + prs_struct qbuf, rbuf; + LSA_Q_ENUMPRIVSACCOUNT q; + LSA_R_ENUMPRIVSACCOUNT r; + NTSTATUS result; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_lsa_q_enum_privsaccount(&q, pol); + + /* Marshall data and send request */ + + if (!lsa_io_q_enum_privsaccount("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_enum_privsaccount("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + if (r.count == 0) + goto done; + + if (!((*set = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR) * r.count)))) { + DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + for (i=0; i Date: Sat, 24 Nov 2001 12:12:38 +0000 Subject: This is another rather major change to the samba authenticaion subystem. The particular aim is to modularized the interface - so that we can have arbitrary password back-ends. This code adds one such back-end, a 'winbind' module to authenticate against the winbind_auth_crap functionality. While fully-functional this code is mainly useful as a demonstration, because we don't get back the info3 as we would for direct ntdomain authentication. This commit introduced the new 'auth methods' parameter, in the spirit of the 'auth order' discussed on the lists. It is renamed because not all the methods may be consulted, even if previous methods fail - they may not have a suitable challenge for example. Also, we have a 'local' authentication method, for old-style 'unix if plaintext, sam if encrypted' authentication and a 'guest' module to handle guest logins in a single place. While this current design is not ideal, I feel that it does provide a better infrastructure than the current design, and can be built upon. The following parameters have changed: - use rhosts = This has been replaced by the 'rhosts' authentication method, and can be specified like 'auth methods = guest rhosts' - hosts equiv = This needs both this parameter and an 'auth methods' entry to be effective. (auth methods = guest hostsequiv ....) - plaintext to smbpasswd = This is replaced by specifying 'sam' rather than 'local' in the auth methods. The security = parameter is unchanged, and now provides defaults for the 'auth methods' parameter. The available auth methods are: guest rhosts hostsequiv sam (passdb direct hash access) unix (PAM, crypt() etc) local (the combination of the above, based on encryption) smbserver (old security=server) ntdomain (old security=domain) winbind (use winbind to cache DC connections) Assistance in testing, or the production of new and interesting authentication modules is always appreciated. Andrew Bartlett (This used to be commit 8d31eae52a9757739711dbb82035a4dfe6b40c99) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/domain_client_validate.c | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f5d6c5a7f4..4ea19db9ec 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -197,7 +197,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, int passlen; char *p; - passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII); set_message(cli->outbuf,13,0,True); CVAL(cli->outbuf,smb_com) = SMBsesssetupX; diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c index 2fd17e1fa4..df263e7ae9 100644 --- a/source3/libsmb/domain_client_validate.c +++ b/source3/libsmb/domain_client_validate.c @@ -271,9 +271,10 @@ static BOOL find_connect_pdc(struct cli_state *pcli, ************************************************************************/ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, - auth_serversupplied_info **server_info, - char *server, unsigned char *trust_passwd, - time_t last_change_time) + uchar chal[8], + auth_serversupplied_info **server_info, + char *server, unsigned char *trust_passwd, + time_t last_change_time) { fstring remote_machine; NET_ID_INFO_CTR ctr; @@ -330,7 +331,7 @@ NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, * in the info3 structure. */ - status = cli_nt_login_network(&cli, user_info, smb_uid_low, + status = cli_nt_login_network(&cli, user_info, chal, smb_uid_low, &ctr, &info3); if (!NT_STATUS_IS_OK(status)) { -- cgit From ad2974cd05b4d08c8b92f505bf95aa8e8533235f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 24 Nov 2001 14:16:41 +0000 Subject: added "net join" command this completes the first stage of the smbd ADS support (This used to be commit 058a5aee901e6609969ef7e1d482a720a84a4a12) --- source3/libsmb/clikrb5.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index b4ce271235..37b92b8d99 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -95,6 +95,7 @@ DATA_BLOB krb5_get_ticket(char *principal) krb5_context context; krb5_auth_context auth_context = NULL; DATA_BLOB ret; + krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; retval = krb5_init_context(&context); if (retval) { @@ -109,6 +110,12 @@ DATA_BLOB krb5_get_ticket(char *principal) goto failed; } + if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { + DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n", + error_message(retval))); + goto failed; + } + if ((retval = krb5_mk_req2(context, &auth_context, 0, -- cgit From a71f3f66a1b47a70e402c4d82736f376449b923c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Nov 2001 02:35:37 +0000 Subject: Add a new torture test to extract a NT->DOS error map from an NT member of a samba domain. The PDC must be running a special authenticaion module that spits out NT errors based on username. Andrew Bartlett (This used to be commit adc7a6048c13342b79b6228beafb5142c50f318d) --- source3/libsmb/cliconnect.c | 5 +---- source3/libsmb/clientgen.c | 7 +++++++ source3/libsmb/nterr.c | 21 +++++++++++++++++++++ source3/libsmb/smberr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 74 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4ea19db9ec..ed4bfcd9e3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -117,10 +117,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) { uint32 capabilities = CAP_NT_SMBS; - /* Set the CLI_FORCE_DOSERR environment variable to test - client routines using DOS errors instead of STATUS32 - ones. This intended only as a temporary hack. */ - if (!getenv("CLI_FORCE_DOSERR")) { + if (!cli->force_dos_errors) { capabilities |= CAP_STATUS32; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0f1fa2e42e..0e09388803 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -198,6 +198,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->oplock_handler = cli_oplock_ack; cli->use_spnego = True; + /* Set the CLI_FORCE_DOSERR environment variable to test + client routines using DOS errors instead of STATUS32 + ones. This intended only as a temporary hack. */ + if (getenv("CLI_FORCE_DOSERR")) { + cli->force_dos_errors = True; + } + if (!cli->outbuf || !cli->inbuf) goto error; diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 238908d6cd..25286156ee 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -558,3 +558,24 @@ char *get_nt_error_msg(NTSTATUS nt_code) return msg; } + +/***************************************************************************** + returns an NT_STATUS constant as a string for inclusion in autogen C code + *****************************************************************************/ +char *get_nt_error_c_code(NTSTATUS nt_code) +{ + static pstring out; + int idx = 0; + + while (nt_errs[idx].nt_errstr != NULL) { + if (NT_STATUS_V(nt_errs[idx].nt_errcode) == + NT_STATUS_V(nt_code)) { + return nt_errs[idx].nt_errstr; + } + idx++; + } + + slprintf(out, sizeof(out), "NT_STATUS(0x%08x)", NT_STATUS_V(nt_code)); + + return out; +} diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index a43e4764e8..d0aa8f6024 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -156,7 +156,51 @@ const struct /**************************************************************************** -return a SMB error string from a SMB buffer +return a SMB error name from a class and code +****************************************************************************/ +char *smb_dos_err_name(uint8 class, uint16 num) +{ + static pstring ret; + int i,j; + + for (i=0;err_classes[i].class;i++) + if (err_classes[i].code == class) { + if (err_classes[i].err_msgs) { + err_code_struct *err = err_classes[i].err_msgs; + for (j=0;err[j].name;j++) + if (num == err[j].code) { + return err[j].name; + } + } + slprintf(ret, sizeof(ret) - 1, "%d",num); + return ret; + } + + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error class (%d,%d)",class,num); + return(ret); +} + + +/**************************************************************************** +return a SMB error class name as a string. +****************************************************************************/ +char *smb_dos_err_class(uint8 class) +{ + static pstring ret; + int i; + + for (i=0;err_classes[i].class;i++) { + if (err_classes[i].code == class) { + return err_classes[i].class; + } + } + + slprintf(ret, sizeof(ret) - 1, "Error: Unknown class (%d)",class); + return(ret); +} + +/**************************************************************************** +return a SMB string from an SMB buffer ****************************************************************************/ char *smb_dos_errstr(char *inbuf) { -- cgit From 86dee43f390d7fdfdfb90c67189a38ed8398f8d9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 25 Nov 2001 06:38:17 +0000 Subject: Use "password server" for searching for BDC's also as Tim suggested. Jeremy. (This used to be commit 4aca67761fbe601e27f8f768c28a11241f088bba) --- source3/libsmb/namequery.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f8688ddb25..dff3570842 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1181,12 +1181,14 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *count) { + int name_type = pdc_only ? 0x1B : 0x1C; + /* - * If we're looking for a PDC and it's our domain then + * If it's our domain then * use the 'password server' parameter. */ - if (pdc_only && strequal(group, lp_workgroup())) { + if (strequal(group, lp_workgroup())) { char *p; char *pserver = lp_passwordserver(); fstring name; @@ -1194,16 +1196,16 @@ BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *coun struct in_addr *return_iplist = NULL; if (! *pserver) - return internal_resolve_name(group, 0x1B, ip_list, count); + return internal_resolve_name(group, name_type, ip_list, count); p = pserver; while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) - return internal_resolve_name(group, 0x1B, ip_list, count); + return internal_resolve_name(group, name_type, ip_list, count); num_adresses++; } if (num_adresses == 0) - return internal_resolve_name(group, 0x1B, ip_list, count); + return internal_resolve_name(group, name_type, ip_list, count); return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr)); if(return_iplist == NULL) { @@ -1221,7 +1223,7 @@ BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *coun *ip_list = return_iplist; return (*count != 0); } else - return internal_resolve_name(group, pdc_only ? 0x1B : 0x1C, ip_list, count); + return internal_resolve_name(group, name_type, ip_list, count); } /******************************************************** -- cgit From 26f1e3f83cb14c5edef081b6cb20d965bc6ba5b7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Nov 2001 00:45:51 +0000 Subject: use DEBUG() not d_printf() in libraries (This used to be commit 5100ae4ae032545edaf525de1dfbe5dc9dafecfc) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ed4bfcd9e3..ffbc54ea5e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -384,7 +384,7 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c { DATA_BLOB blob2, negTokenTarg; - d_printf("Doing kerberos session setup\n"); + DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ negTokenTarg = spnego_gen_negTokenTarg(cli, principal); @@ -510,7 +510,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, int i; BOOL got_kerberos_mechanism = False; - d_printf("Doing spnego session setup\n"); + DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ if (cli->secblob.length == 16) { -- cgit From f6e94b64b49ac865bae786516b4a045ee8242423 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Nov 2001 01:37:44 +0000 Subject: And delete domain_client_validate.c... Andrew Bartlett (This used to be commit 6caca4301ba88d026ce1989cefd3e9eeb65df376) --- source3/libsmb/domain_client_validate.c | 432 -------------------------------- 1 file changed, 432 deletions(-) delete mode 100644 source3/libsmb/domain_client_validate.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/domain_client_validate.c b/source3/libsmb/domain_client_validate.c deleted file mode 100644 index df263e7ae9..0000000000 --- a/source3/libsmb/domain_client_validate.c +++ /dev/null @@ -1,432 +0,0 @@ -/* - Unix SMB/Netbios implementation. - Version 1.9. - Authenticate against a remote domain - Copyright (C) Andrew Tridgell 1992-1998 - Copyright (C) Andrew Bartlett 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -extern struct in_addr ipzero; - -extern pstring global_myname; - -/*********************************************************************** - Connect to a remote machine for domain security authentication - given a name or IP address. - ***********************************************************************/ - -static BOOL connect_to_domain_password_server(struct cli_state *pcli, - char *server, unsigned char *trust_passwd) -{ - struct in_addr dest_ip; - fstring remote_machine; - NTSTATUS result; - - if(cli_initialise(pcli) == NULL) { - DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); - return False; - } - - if (is_ipaddress(server)) { - struct in_addr to_ip; - - /* we shouldn't have 255.255.255.255 forthe IP address of - a password server anyways */ - if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) { - DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server)); - return False; - } - - if (!name_status_find("*", 0x20, 0x20, to_ip, remote_machine)) { - DEBUG(0, ("connect_to_domain_password_server: Can't " - "resolve name for IP %s\n", server)); - return False; - } - } else { - fstrcpy(remote_machine, server); - } - - standard_sub_basic(remote_machine); - strupper(remote_machine); - - if(!resolve_name( remote_machine, &dest_ip, 0x20)) { - DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine)); - cli_shutdown(pcli); - return False; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n", - remote_machine)); - cli_shutdown(pcli); - return False; - } - - if (!cli_connect(pcli, remote_machine, &dest_ip)) { - DEBUG(0,("connect_to_domain_password_server: unable to connect to SMB server on \ -machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - cli_shutdown(pcli); - return False; - } - - if (!attempt_netbios_session_request(pcli, global_myname, remote_machine, &dest_ip)) { - DEBUG(0,("connect_to_password_server: machine %s rejected the NetBIOS \ -session request. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - return False; - } - - pcli->protocol = PROTOCOL_NT1; - - if (!cli_negprot(pcli)) { - DEBUG(0,("connect_to_domain_password_server: machine %s rejected the negotiate protocol. \ -Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - cli_shutdown(pcli); - return False; - } - - if (pcli->protocol != PROTOCOL_NT1) { - DEBUG(0,("connect_to_domain_password_server: machine %s didn't negotiate NT protocol.\n", - remote_machine)); - cli_shutdown(pcli); - return False; - } - - /* - * Do an anonymous session setup. - */ - - if (!cli_session_setup(pcli, "", "", 0, "", 0, "")) { - DEBUG(0,("connect_to_domain_password_server: machine %s rejected the session setup. \ -Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - cli_shutdown(pcli); - return False; - } - - if (!(pcli->sec_mode & 1)) { - DEBUG(1,("connect_to_domain_password_server: machine %s isn't in user level security mode\n", - remote_machine)); - cli_shutdown(pcli); - return False; - } - - if (!cli_send_tconX(pcli, "IPC$", "IPC", "", 1)) { - DEBUG(0,("connect_to_domain_password_server: machine %s rejected the tconX on the IPC$ share. \ -Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - cli_shutdown(pcli); - return False; - } - - /* - * We now have an anonymous connection to IPC$ on the domain password server. - */ - - /* - * Even if the connect succeeds we need to setup the netlogon - * pipe here. We do this as we may just have changed the domain - * account password on the PDC and yet we may be talking to - * a BDC that doesn't have this replicated yet. In this case - * a successful connect to a DC needs to take the netlogon connect - * into account also. This patch from "Bjart Kvarme" . - */ - - if(cli_nt_session_open(pcli, PIPE_NETLOGON) == False) { - DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ -machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); - cli_nt_session_close(pcli); - cli_ulogoff(pcli); - cli_shutdown(pcli); - return False; - } - - result = cli_nt_setup_creds(pcli, trust_passwd); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ -%s. Error was : %s.\n", remote_machine, get_nt_error_msg(result))); - cli_nt_session_close(pcli); - cli_ulogoff(pcli); - cli_shutdown(pcli); - return(False); - } - - return True; -} - -/*********************************************************************** - Utility function to attempt a connection to an IP address of a DC. -************************************************************************/ - -static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, - unsigned char *trust_passwd) -{ - fstring dc_name; - - /* - * Ignore addresses we have already tried. - */ - - if (ip_equal(ipzero, *ip)) - return False; - - if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) - return False; - - return connect_to_domain_password_server(pcli, dc_name, trust_passwd); -} - -/*********************************************************************** - We have been asked to dynamcially determine the IP addresses of - the PDC and BDC's for this DOMAIN, and query them in turn. -************************************************************************/ -static BOOL find_connect_pdc(struct cli_state *pcli, - unsigned char *trust_passwd, - time_t last_change_time) -{ - struct in_addr *ip_list = NULL; - int count = 0; - int i; - BOOL connected_ok = False; - time_t time_now = time(NULL); - BOOL use_pdc_only = False; - - /* - * If the time the machine password has changed - * was less than an hour ago then we need to contact - * the PDC only, as we cannot be sure domain replication - * has yet taken place. Bug found by Gerald (way to go - * Gerald !). JRA. - */ - - if (time_now - last_change_time < 3600) - use_pdc_only = True; - - if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count)) - return False; - - /* - * Firstly try and contact a PDC/BDC who has the same - * network address as any of our interfaces. - */ - for(i = 0; i < count; i++) { - if(!is_local_net(ip_list[i])) - continue; - - if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) - break; - - ip_list[i] = ipzero; /* Tried and failed. */ - } - - /* - * Secondly try and contact a random PDC/BDC. - */ - if(!connected_ok) { - i = (sys_random() % count); - - if (!(connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) - ip_list[i] = ipzero; /* Tried and failed. */ - } - - /* - * Finally go through the IP list in turn, ignoring any addresses - * we have already tried. - */ - if(!connected_ok) { - /* - * Try and connect to any of the other IP addresses in the PDC/BDC list. - * Note that from a WINS server the #1 IP address is the PDC. - */ - for(i = 0; i < count; i++) { - if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) - break; - } - } - - SAFE_FREE(ip_list); - - - return connected_ok; -} - -/*********************************************************************** - Do the same as security=server, but using NT Domain calls and a session - key from the machine password. If the server parameter is specified - use it, otherwise figure out a server from the 'password server' param. -************************************************************************/ - -NTSTATUS domain_client_validate(const auth_usersupplied_info *user_info, - uchar chal[8], - auth_serversupplied_info **server_info, - char *server, unsigned char *trust_passwd, - time_t last_change_time) -{ - fstring remote_machine; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 info3; - struct cli_state cli; - uint32 smb_uid_low; - BOOL connected_ok = False; - NTSTATUS status; - struct passwd *pass; - - /* - * Check that the requested domain is not our own machine name. - * If it is, we should never check the PDC here, we use our own local - * password file. - */ - - if(strequal(user_info->domain.str, global_myname)) { - DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); - return NT_STATUS_LOGON_FAILURE; - } - - /* - * At this point, smb_apasswd points to the lanman response to - * the challenge in local_challenge, and smb_ntpasswd points to - * the NT response to the challenge in local_challenge. Ship - * these over the secure channel to a domain controller and - * see if they were valid. - */ - - ZERO_STRUCT(cli); - - while (!connected_ok && - next_token(&server,remote_machine,LIST_SEP,sizeof(remote_machine))) { - if(strequal(remote_machine, "*")) { - connected_ok = find_connect_pdc(&cli, trust_passwd, last_change_time); - } else { - connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); - } - } - - if (!connected_ok) { - DEBUG(0,("domain_client_validate: Domain password server not available.\n")); - cli_shutdown(&cli); - return NT_STATUS_LOGON_FAILURE; - } - - /* We really don't care what LUID we give the user. */ - generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - - ZERO_STRUCT(info3); - - /* - * If this call succeeds, we now have lots of info about the user - * in the info3 structure. - */ - - status = cli_nt_login_network(&cli, user_info, chal, smb_uid_low, - &ctr, &info3); - - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("domain_client_validate: unable to validate password " - "for user %s in domain %s to Domain controller %s. " - "Error was %s.\n", user_info->smb_name.str, - user_info->domain.str, cli.srv_name_slash, - get_nt_error_msg(status))); - } else { - char *dom_user; - - /* Check DOMAIN\username first to catch winbind users, then - just the username for local users. */ - - asprintf(&dom_user, "%s%s%s", user_info->domain.str, - lp_winbind_separator(), - user_info->internal_username.str); - - if (!(pass = Get_Pwnam(dom_user))) - pass = Get_Pwnam(user_info->internal_username.str); - - free(dom_user); - - if (pass) { - make_server_info_pw(server_info, pass); - if (!server_info) { - status = NT_STATUS_NO_MEMORY; - } - } else { - status = NT_STATUS_NO_SUCH_USER; - } - } - - /* Store the user group information in the server_info returned to the caller. */ - - if (NT_STATUS_IS_OK(status) && (info3.num_groups2 != 0)) { - DOM_SID domain_sid; - int i; - NT_USER_TOKEN *ptok; - auth_serversupplied_info *pserver_info = *server_info; - - if ((pserver_info->ptok = malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) { - DEBUG(0, ("domain_client_validate: out of memory allocating rid group membership\n")); - status = NT_STATUS_NO_MEMORY; - free_server_info(server_info); - goto done; - } - - ptok = pserver_info->ptok; - ptok->num_sids = (size_t)info3.num_groups2; - - if ((ptok->user_sids = (DOM_SID *)malloc( sizeof(DOM_SID) * ptok->num_sids )) == NULL) { - DEBUG(0, ("domain_client_validate: Out of memory allocating group SIDS\n")); - status = NT_STATUS_NO_MEMORY; - free_server_info(server_info); - goto done; - } - - if (!secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) { - DEBUG(0, ("domain_client_validate: unable to fetch domain sid.\n")); - status = NT_STATUS_NO_MEMORY; - free_server_info(server_info); - goto done; - } - - for (i = 0; i < ptok->num_sids; i++) { - sid_copy(&ptok->user_sids[i], &domain_sid); - sid_append_rid(&ptok->user_sids[i], info3.gids[i].g_rid); - } - } - -#if 0 - /* - * We don't actually need to do this - plus it fails currently with - * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to - * send here. JRA. - */ - - if (NT_STATUS_IS_OK(status)) { - if(cli_nt_logoff(&cli, &ctr) == False) { - DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); - status = NT_STATUS_LOGON_FAILURE; - } - } -#endif /* 0 */ - - done: - - /* Note - once the cli stream is shutdown the mem_ctx used - to allocate the other_sids and gids structures has been deleted - so - these pointers are no longer valid..... */ - - cli_nt_session_close(&cli); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return status; -} -- cgit From 585d0efbc6428e5876d354fee49c241c1bad809d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 26 Nov 2001 03:11:44 +0000 Subject: Got medieval on another pointless extern. Removed extern struct ipzero and replaced with two functions: void zero_ip(struct in_adder *ip); BOOL is_zero_ip(struct in_addr ip); (This used to be commit 778f5f77a66cda76348a7c6f64cd63afe2bfe077) --- source3/libsmb/cliconnect.c | 3 +-- source3/libsmb/libsmbclient.c | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ffbc54ea5e..314ac6638a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -972,12 +972,11 @@ open the client sockets ****************************************************************************/ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { - extern struct in_addr ipzero; extern pstring user_socket_options; fstrcpy(cli->desthost, host); - if (!ip || ip_equal(*ip, ipzero)) { + if (!ip || is_zero_ip(*ip)) { if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) { return False; } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ce00548518..a85d9e45fc 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -246,9 +246,8 @@ struct smbc_server *smbc_server(char *server, char *share, fstring group; pstring ipenv; struct in_addr ip; - extern struct in_addr ipzero; - ip = ipzero; + zero_ip(&ip); ZERO_STRUCT(c); /* try to use an existing connection */ @@ -306,7 +305,7 @@ struct smbc_server *smbc_server(char *server, char *share, again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); - ip = ipzero; + zero_ip(&ip); /* have to open a new connection */ if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { -- cgit From fc93f4f403a5160a4bd0e365b2312f32198598c8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Nov 2001 07:53:33 +0000 Subject: Fix --enable-developer shadow warning (This used to be commit 6a919bcf3d5848e09ddba1e8946f985661af8f67) --- source3/libsmb/clierror.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index fe793d4b0e..e4d931b965 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -67,7 +67,7 @@ static char *cli_smb_errstr(struct cli_state *cli) char *cli_errstr(struct cli_state *cli) { - static fstring error_message; + static fstring cli_error_message; uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum; uint8 errclass; int i; @@ -93,10 +93,10 @@ char *cli_errstr(struct cli_state *cli) } } - slprintf(error_message, sizeof(error_message) - 1, "code %d", + slprintf(cli_error_message, sizeof(cli_error_message) - 1, "code %d", cli->rap_error); - return error_message; + return cli_error_message; } -- cgit From df81a6ec23b9eebcf544b23d6028fe9469234818 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Nov 2001 09:28:00 +0000 Subject: increment the value not the pointer (This used to be commit e3698259afa79fcd318592b1d628803695406337) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index dff3570842..e9b1116d07 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1218,7 +1218,7 @@ BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *coun struct in_addr name_ip; if (resolve_name( name, &name_ip, 0x20) == False) continue; - return_iplist[*count++] = name_ip; + return_iplist[(*count)++] = name_ip; } *ip_list = return_iplist; return (*count != 0); -- cgit From 701ecfc7a0a944844cadfd0b2c19f104ab7984b0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 Nov 2001 03:29:20 +0000 Subject: prevent a memory leak of cli structures (This used to be commit 911c57403bd116405876e73913ad73efd15f659b) --- source3/libsmb/clientgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0e09388803..610af9cc23 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -217,6 +217,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->nt_pipe_fnum = 0; cli->initialised = 1; + cli->allocated = alloced_cli; return cli; @@ -238,6 +239,7 @@ shutdown a client structure ****************************************************************************/ void cli_shutdown(struct cli_state *cli) { + BOOL allocated; SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); @@ -252,7 +254,11 @@ void cli_shutdown(struct cli_state *cli) #endif /* WITH_SSL */ if (cli->fd != -1) close(cli->fd); - memset(cli, 0, sizeof(*cli)); + allocated = cli->allocated; + ZERO_STRUCTP(cli); + if (allocated) { + free(cli); + } } -- cgit From 4d726d00918045d77d13b37a8d033926fc811422 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 27 Nov 2001 03:50:53 +0000 Subject: prevent a bogus insure wild ptr message (This used to be commit 1976a8f87544140363449a361f7c7347ef2c44f5) --- source3/libsmb/nmblib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index dc39924818..0061a4b977 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -171,13 +171,14 @@ static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, parse a nmb name from "compressed" format to something readable return the space taken by the name, or 0 if the name is invalid ******************************************************************/ -static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *name) +static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) { int m,n=0; uchar *ubuf = (uchar *)inbuf; int ret = 0; BOOL got_pointer=False; int loop_count=0; + int offset = ofs; if (length - offset < 2) return(0); -- cgit From 7527ec3ffd1aa4ec0bb7f99e0b40676e32391391 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 27 Nov 2001 10:42:39 +0000 Subject: Fix another memory leak spotted by Tom Jansen. (This used to be commit 6e2c06a6e6173e68a75fd1adfaa73fe9a9210fef) --- source3/libsmb/libsmbclient.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index a85d9e45fc..33aeb62af8 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -309,6 +309,7 @@ struct smbc_server *smbc_server(char *server, char *share, /* have to open a new connection */ if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { + if (c.initialised) cli_shutdown(&c); errno = ENOENT; return NULL; } -- cgit From a6b73b9767524fa6997bd31398d558a7cf1e4ac8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Nov 2001 02:42:55 +0000 Subject: Cross merge to make 2.2 and HEAD closer. Jeremy. (This used to be commit 39f076b56cf457cc780dd30a4d3150d8bfc60d13) --- source3/libsmb/namequery.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e9b1116d07..a181e3183f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -336,8 +336,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, retries--; - while (1) - { + while (1) { struct timeval tval2; struct in_addr *tmp_ip_list; @@ -365,8 +364,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, if( DEBUGLVL( 3 ) ) { /* Only executed if DEBUGLEVEL >= 3 */ - dbgtext( "Negative name query response, rcode 0x%02x: ", - nmb2->header.rcode ); + dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode ); switch( nmb2->header.rcode ) { case 0x01: dbgtext( "Request was invalidly formatted.\n" ); @@ -399,7 +397,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, /* * XXXX what do we do with this? Could be a * redirect, but we'll discard it for the - * moment. */ + * moment. + */ free_packet(p2); continue; } @@ -415,8 +414,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, ip_list = tmp_ip_list; if (ip_list) { - DEBUG(2,("Got a positive name query response from %s ( ", - inet_ntoa(p2->ip))); + DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); for (i=0;ianswers->rdlength/6;i++) { putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); @@ -439,8 +437,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, } /* Reach here if we've timed out waiting for replies.. */ - if( !bcast && !found ) - { + if( !bcast && !found ) { /* Timed out wating for WINS server to respond. Mark it dead. */ wins_srv_died( to_ip ); } -- cgit From eec9e8a052407611df223fec982588e7a2bd7f49 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Nov 2001 03:56:30 +0000 Subject: fix a bunch of places where we can double-free a cli structure (This used to be commit e2ba2383c9f679c076749a8f4fccefc3559e37ec) --- source3/libsmb/cliconnect.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 314ac6638a..ba4bedf8ab 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1144,7 +1144,7 @@ BOOL cli_establish_connection(struct cli_state *cli, { DEBUG(1,("failed tcon_X\n")); if (do_shutdown) - cli_shutdown(cli); + cli_shutdown(cli); return False; } } @@ -1196,9 +1196,9 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } + cli_shutdown(cli); + return False; + } cli_shutdown(cli); -- cgit From b1ade347057438e05fcb412ba6d4c59d9ad0a4db Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Nov 2001 05:49:36 +0000 Subject: fixed a core dump in server level security (This used to be commit e790bb21d3895bef97522b68c6f00812e6c286f2) --- source3/libsmb/cliconnect.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ba4bedf8ab..0fceac70e2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -258,8 +258,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. */ passlen = 24; ntpasslen = 24; - clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); - clistr_push(cli, ntpword, ntpass, sizeof(ntpword), STR_TERMINATE); + clistr_push(cli, pword, + pass?pass:"", sizeof(pword), STR_TERMINATE|STR_ASCII); + clistr_push(cli, ntpword, + ntpass?ntpass:"", sizeof(ntpword), STR_TERMINATE|STR_ASCII); SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); SMBNTencrypt((uchar *)ntpword,cli->secblob.data,(uchar *)ntpword); } else { -- cgit From f6b962fba37a1ac105301d699708e541ce34d3b4 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 28 Nov 2001 23:54:07 +0000 Subject: fixed some krb5 ifdefs (This used to be commit 23ef22f11700bbaa5778a9678a990a2b041fcefe) --- source3/libsmb/cliconnect.c | 4 ++-- source3/libsmb/clikrb5.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0fceac70e2..cfbb6d6222 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -378,7 +378,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) } -#if HAVE_KRB5 +#ifdef HAVE_KRB5 /**************************************************************************** do a spnego/kerberos encrypted session setup ****************************************************************************/ @@ -543,7 +543,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, fstrcpy(cli->user_name, user); -#if HAVE_KRB5 +#ifdef HAVE_KRB5 if (got_kerberos_mechanism && cli->use_kerberos) { return cli_session_setup_kerberos(cli, principal, workgroup); } diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 37b92b8d99..03fb6a5669 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -21,7 +21,7 @@ #include "includes.h" -#if HAVE_KRB5 +#ifdef HAVE_KRB5 /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From ff27a326f17223cba12b7e0b41ec84aad8238385 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 29 Nov 2001 05:50:32 +0000 Subject: I think the lookup_pdc_name() should be called lookup_dc_name() and the name_status_find() call here should look up a #1c name instead of #1d. This fixes some bugs currently with BDC authentication in winbindd and in smbd as you can't query the #1d name with the ip address of a BDC. Who is Uncle Tom Cobbley anyway? (This used to be commit 4215048f7b20a8f9e5877bdbb2f54841b2f7fa64) --- source3/libsmb/namequery.c | 43 ++++++++++++++++++++++--------------------- 1 file changed, 22 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a181e3183f..8d00c50914 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -927,7 +927,7 @@ BOOL resolve_srv_name(const char* srv_name, fstring dest_host, if (strcmp(dest_host,"*") == 0) { extern pstring global_myname; ret = resolve_name(lp_workgroup(), ip, 0x1B); - lookup_pdc_name(global_myname, lp_workgroup(), ip, dest_host); + lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host); } else { ret = resolve_name(dest_host, ip, 0x20); } @@ -966,31 +966,32 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip) } /******************************************************** - Lookup a PDC name given a Domain name and IP address. + Lookup a DC name given a Domain name and IP address. *********************************************************/ -BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name) +BOOL lookup_dc_name(const char *srcname, const char *domain, + struct in_addr *dc_ip, char *ret_name) { #if !defined(I_HATE_WINDOWS_REPLY_CODE) + + fstring dc_name; + BOOL ret; + + /* + * Due to the fact win WinNT *sucks* we must do a node status + * query here... JRA. + */ + + *dc_name = '\0'; + + ret = name_status_find(domain, 0x1c, 0x20, *dc_ip, dc_name); - fstring pdc_name; - BOOL ret; - - /* - * Due to the fact win WinNT *sucks* we must do a node status - * query here... JRA. - */ - - *pdc_name = '\0'; - - ret = name_status_find(domain, 0x1b, 0x20,*pdc_ip,pdc_name); - - if(ret && *pdc_name) { - fstrcpy(ret_name, pdc_name); - return True; - } - - return False; + if(ret && *dc_name) { + fstrcpy(ret_name, dc_name); + return True; + } + + return False; #else /* defined(I_HATE_WINDOWS_REPLY_CODE) */ -- cgit From d78f6366e81913d01e3efac3854aee7e6689b922 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sat, 1 Dec 2001 23:57:11 +0000 Subject: added samr_query_sec_obj for rpcclient J.F. (This used to be commit d8809c58614cd97ef78d398645788e41022a8c39) --- source3/libsmb/cli_samr.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 4a04d67887..d609572942 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -1082,3 +1082,49 @@ NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Query user security object */ + +NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint16 switch_value, + TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_SEC_OBJ q; + SAMR_R_QUERY_SEC_OBJ r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_query_sec_obj(&q, user_pol, switch_value); + + if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + result = r.status; + *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf); + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 633ee99afa1f25fcd16796bedec571471f3617ca Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Sun, 2 Dec 2001 01:45:50 +0000 Subject: added queryuseraliases to rpcclient and some comments to the samr server code, to explain what we should return here. J.F. (This used to be commit 06cb20a46d9d9f8abf0d92ba4cfa4d23187ad715) --- source3/libsmb/cli_samr.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index d609572942..49010324e3 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -407,6 +407,55 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Query user aliases */ + +NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid, + uint32 *num_aliases, uint32 **als_rids) +{ + prs_struct qbuf, rbuf; + SAMR_Q_QUERY_USERALIASES q; + SAMR_R_QUERY_USERALIASES r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint ptr=1; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid); + + if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + if (NT_STATUS_IS_OK(result = r.status)) { + *num_aliases = r.num_entries; + *als_rids = r.rid; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Query user groups */ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, -- cgit From 3ea7519b061a464ecec55341f218802ca0c2eb47 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Dec 2001 07:42:18 +0000 Subject: This change reworkes the connection code for both rpcclient and net new 'net' untility. This should make it easier to port rpcclient code across to net. It also allows SPNEGO (the NTLMSSP subsystem in particular) to work, becouse it kills off the early destruction of the clear-text password. Andrew Bartlett (This used to be commit eee925861a3af3aa16efa3b1700a980c9510c14e) --- source3/libsmb/cliconnect.c | 114 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cfbb6d6222..1494608f8d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1013,7 +1013,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } /**************************************************************************** -establishes a connection right up to doing tconX, reading in a password. +establishes a connection right up to doing tconX, password in cache. ****************************************************************************/ BOOL cli_establish_connection(struct cli_state *cli, char *dest_host, struct in_addr *dest_ip, @@ -1158,6 +1158,118 @@ BOOL cli_establish_connection(struct cli_state *cli, return True; } +/* Initialise client credentials for authenticated pipe access */ + +static void init_creds(struct ntuser_creds *creds, char* username, + char* domain, char* password, int pass_len) +{ + ZERO_STRUCTP(creds); + + pwd_set_cleartext(&creds->pwd, password); + + fstrcpy(creds->user_name, username); + fstrcpy(creds->domain, domain); + + if (!*username) { + creds->pwd.null_pwd = True; + } +} + +/**************************************************************************** +establishes a connection right up to doing tconX, password specified. +****************************************************************************/ +NTSTATUS cli_full_connection(struct cli_state **output_cli, + const char *my_name, const char *dest_host, + struct in_addr *dest_ip, int port, + char *service, char *service_type, + char *user, char *domain, + char *password, int pass_len) +{ + struct ntuser_creds creds; + NTSTATUS nt_status; + struct nmb_name calling; + struct nmb_name called; + struct cli_state *cli; + struct in_addr ip; + + make_nmb_name(&calling, my_name, 0x0); + make_nmb_name(&called , dest_host, 0x20); + +again: + + if (!(cli = cli_initialise(NULL))) { + return NT_STATUS_NO_MEMORY; + } + + if (cli_set_port(cli, port) != port) { + return NT_STATUS_UNSUCCESSFUL; + } + + ip = *dest_ip; + + DEBUG(3,("Connecting to host=%s share=%s\n\n", + dest_host, service)); + + if (!cli_connect(cli, dest_host, &ip)) + { + DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", + nmb_namestr(&called), inet_ntoa(*dest_ip))); + return NT_STATUS_UNSUCCESSFUL; + } + + if (!cli_session_request(cli, &calling, &called)) { + char *p; + DEBUG(1,("session request to %s failed (%s)\n", + called.name, cli_errstr(cli))); + cli_shutdown(cli); + if ((p=strchr(called.name, '.'))) { + *p = 0; + goto again; + } + if (strcmp(called.name, "*SMBSERVER")) { + make_nmb_name(&called , "*SMBSERVER", 0x20); + goto again; + } + return NT_STATUS_UNSUCCESSFUL; + } + + if (!cli_negprot(cli)) + { + DEBUG(1,("failed negprot\n")); + nt_status = cli_nt_error(cli); + cli_shutdown(cli); + return nt_status; + } + + if (!cli_session_setup(cli, user, + password, pass_len, + NULL, 0, + domain)) + { + DEBUG(1,("failed session setup\n")); + nt_status = cli_nt_error(cli); + cli_shutdown(cli); + return nt_status; + } + + if (service) + { + if (!cli_send_tconX(cli, service, service_type, + (char*)password, pass_len)) + { + DEBUG(1,("failed tcon_X\n")); + nt_status = cli_nt_error(cli); + cli_shutdown(cli); + return nt_status; + } + } + + init_creds(&creds, user, domain, password, pass_len); + cli_init_creds(cli, &creds); + + *output_cli = cli; + return NT_STATUS_OK; +} /**************************************************************************** Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. -- cgit From b6b84cf7099c3b2cee777cf9514b3e6665a4025f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Dec 2001 08:16:51 +0000 Subject: const religion (This used to be commit 359ca8f246c46b1700418fe0226458023f808d67) --- source3/libsmb/cli_lsarpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index ffe86eccd5..9526da94a8 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -329,7 +329,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /** Lookup a list of names */ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, char **names, + POLICY_HND *pol, int num_names, const char **names, DOM_SID **sids, uint32 **types, int *num_sids) { prs_struct qbuf, rbuf; -- cgit From 0dc386855fb341ee820be591d92300d7518f7a7b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Dec 2001 00:07:08 +0000 Subject: when using non-encrypted password ignore the ntpass variable to session setup (This used to be commit c7665706cd5633ede710afe41413624124038238) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1494608f8d..512607fc11 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -255,13 +255,13 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, } if (passlen != 24) { - /* non encrypted password supplied. */ + /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; clistr_push(cli, pword, pass?pass:"", sizeof(pword), STR_TERMINATE|STR_ASCII); clistr_push(cli, ntpword, - ntpass?ntpass:"", sizeof(ntpword), STR_TERMINATE|STR_ASCII); + pass?pass:"", sizeof(ntpword), STR_TERMINATE|STR_ASCII); SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); SMBNTencrypt((uchar *)ntpword,cli->secblob.data,(uchar *)ntpword); } else { -- cgit From bca2bcd87e3054c46651563024d1a91bcdf42d78 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 4 Dec 2001 00:46:12 +0000 Subject: Added error message for ERRdiskfull. (This used to be commit 9f5d7e8a04c36395570247bc5e1b7b3fc5d1a322) --- source3/libsmb/smberr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index d0aa8f6024..71e609ff3a 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -76,6 +76,7 @@ err_code_struct dos_msgs[] = { {"ERRmoredata",ERRmoredata,"There is more data to be returned."}, {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"}, {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, + {"ERRdiskfull",ERRdiskfull,"Disk full"}, {NULL,-1,NULL}}; /* Server Error Messages */ -- cgit From 7b0b5568046a3b5ff8b01acd63777a2283c47b38 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 4 Dec 2001 04:45:17 +0000 Subject: Fix up funtion name, as this finds local, not domain master browsers. (as per tridge's instructions) (This used to be commit 0692d792f24f1c82c69532e50a6c4373c9a8b476) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8d00c50914..2c235417a8 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1225,9 +1225,9 @@ BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *coun } /******************************************************** - Get the IP address list of the Domain Master Browsers + Get the IP address list of the Local Master Browsers ********************************************************/ -BOOL get_dmb_list(struct in_addr **ip_list, int *count) +BOOL get_lmb_list(struct in_addr **ip_list, int *count) { return internal_resolve_name( MSBROWSE, 0x1, ip_list, count); } -- cgit From 3bc87626ae7894269535333aadb45ec786f3908d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 4 Dec 2001 05:03:03 +0000 Subject: Add 'net rpc join' to match the ADS equiv. This kills off the offending code in smbpasswd -j -Uab%c In the process we have changed from unsing compelatly random passwords to random, 15 char ascii strings. While this does produce a decrese in entropy, it is still vastly greater than we need, considering the application. In the meantime this allows us to actually *type* the machine account password duruign debugging. This code also adds a 'check' step to the join, confirming that the stored password does indeed do somthing of value :-) Andrew Bartlett (This used to be commit c0b7ee6ee547dc7ff798eaf8cb63fbe344073029) --- source3/libsmb/pwd_cache.c | 2 ++ source3/libsmb/smbencrypt.c | 17 +++++------------ 2 files changed, 7 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 3c3d5cb741..9404588223 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -135,6 +135,7 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) pwd->cleartext = True; pwd->null_pwd = False; pwd->crypted = False; + pwd_make_lm_nt_16(pwd, clr); } /**************************************************************************** @@ -147,6 +148,7 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) fstrcpy(clr, pwd->password); else clr[0] = 0; + } /**************************************************************************** diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 2e27455362..b0fecd1c19 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -262,27 +262,20 @@ void SMBsesskeygen_ntv1(const uchar kr[16], } /*********************************************************** - encode a password buffer + encode a password buffer. The caller gets to figure out + what to put in it. ************************************************************/ -BOOL encode_pw_buffer(char buffer[516], const char *new_pass, - int new_pw_len, BOOL nt_pass_set) +BOOL encode_pw_buffer(char buffer[516], char *new_pw, int new_pw_length) { generate_random_buffer((unsigned char *)buffer, 516, True); - if (nt_pass_set) { - new_pw_len *= 2; - push_ucs2(NULL, &buffer[512 - new_pw_len], new_pass, - new_pw_len, 0); - } else { - push_ascii(&buffer[512 - new_pw_len], new_pass, - new_pw_len, 0); - } + memcpy(&buffer[512 - new_pw_length], new_pw, new_pw_length); /* * The length of the new password is in the last 4 bytes of * the data buffer. */ - SIVAL(buffer, 512, new_pw_len); + SIVAL(buffer, 512, new_pw_length); return True; } -- cgit From 8818847c85647cd824a33de57c0e544558fece77 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 5 Dec 2001 00:24:57 +0000 Subject: Ditto on the const religion. (This used to be commit e1b940c91b748230664544fd9191123247dd1f24) --- source3/libsmb/cli_samr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 49010324e3..b7e0e70030 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -129,7 +129,7 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *connect_pol, uint32 access_mask, - DOM_SID *domain_sid, POLICY_HND *domain_pol) + const DOM_SID *domain_sid, POLICY_HND *domain_pol) { prs_struct qbuf, rbuf; SAMR_Q_OPEN_DOMAIN q; @@ -940,7 +940,7 @@ NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Create a domain user */ NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, char *acct_name, + POLICY_HND *domain_pol, const char *acct_name, uint32 acb_info, uint32 unknown, POLICY_HND *user_pol, uint32 *rid) { -- cgit From 8ba00d147bbdb705b411e182433632c81a036188 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 5 Dec 2001 11:00:26 +0000 Subject: OK. Smbpasswd -j is DEAD. This moves the rest of the functionality into the 'net rpc join' code. Futhermore, this moves that entire area over to the libsmb codebase, rather than the crufty old rpc_client stuff. I have also fixed up the smbpasswd -a -m bug in the process. We also have a new 'net rpc changetrustpw' that can be called from a cron-job to regularly change the trust account password, for sites that run winbind but not smbd. With a little more work, we can kill rpc_client from smbd entirly! (It is mostly the domain auth stuff - which I can rework - and the spoolss stuff that sombody else will need to look over). Andrew Bartlett (This used to be commit 575897e879fc175ba702adf245384033342c903d) --- source3/libsmb/cli_netlogon.c | 83 +++++++++++++++++++++++++++++- source3/libsmb/trust_passwd.c | 116 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 source3/libsmb/trust_passwd.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 7499d9ca7b..d20e466cc9 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -2,9 +2,12 @@ Unix SMB/Netbios implementation. Version 1.9. NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-2000 + Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 Copyright (C) Tim Potter 2001 + Copyright (C) Paul Ashton 1997. + Copyright (C) Jeremy Allison 1998. + Copyright (C) Andrew Bartlett 2001. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -492,3 +495,81 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, done: return result; } + +/*************************************************************************** +LSA Server Password Set. +****************************************************************************/ + +NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char* machine_name, uint8 hashed_mach_pwd[16]) +{ + prs_struct rbuf; + prs_struct buf; + DOM_CRED new_clnt_cred; + NET_Q_SRV_PWSET q_s; + uint16 sec_chan_type = 2; + NTSTATUS nt_status; + char *mach_acct; + + gen_next_creds( cli, &new_clnt_cred); + + prs_init(&buf , 1024, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* create and send a MSRPC command with api NET_SRV_PWSET */ + + mach_acct = talloc_asprintf(mem_ctx, "%s$", machine_name); + + if (!mach_acct) { + DEBUG(0,("talloc_asprintf failed!\n")); + return NT_STATUS_NO_MEMORY; + } + + DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", + cli->srv_name_slash, mach_acct, sec_chan_type, machine_name, + credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); + + /* store the parameters */ + init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->sess_key, + mach_acct, sec_chan_type, machine_name, + &new_clnt_cred, (char *)hashed_mach_pwd); + + /* turn parameters into data stream */ + if(!net_io_q_srv_pwset("", &q_s, &buf, 0)) { + DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + /* send the data on \PIPE\ */ + if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf)) + { + NET_R_SRV_PWSET r_s; + + if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) { + return NT_STATUS_UNSUCCESSFUL; + } + + nt_status = r_s.status; + + if (!NT_STATUS_IS_OK(r_s.status)) + { + /* report error code */ + DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(nt_status))); + return nt_status; + } + + /* Update the credentials. */ + if (!clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred))) + { + /* + * Server replied with bad credential. Fail. + */ + DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \ +password ?).\n", cli->desthost )); + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } + + return nt_status; +} + diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c new file mode 100644 index 0000000000..7f7a5d29dc --- /dev/null +++ b/source3/libsmb/trust_passwd.c @@ -0,0 +1,116 @@ +/* + * Unix SMB/Netbios implementation. + * Version 3.0 + * Routines to change + * Copyright (C) Andrew Bartlett 2001. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +extern pstring global_myname; + +/********************************************************* + Change the domain password on the PDC. + + Just changes the password betwen the two values specified. + + Caller must have the cli connected to the netlogon pipe + already. +**********************************************************/ +static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, + unsigned char orig_trust_passwd_hash[16], + unsigned char new_trust_passwd_hash[16]) +{ + NTSTATUS result; + result = new_cli_nt_setup_creds(cli, orig_trust_passwd_hash); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("just_change_the_password: unable to setup creds (%s)!\n", + get_nt_error_msg(result))); + return result; + } + + result = cli_net_srv_pwset(cli, mem_ctx, global_myname, new_trust_passwd_hash); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", + get_nt_error_msg(result))); + } + return result; +} + +/********************************************************* + Change the domain password on the PDC. + Store the password ourselves, but use the supplied password + Caller must have already setup the connection to the NETLOGON pipe +**********************************************************/ + +NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, + unsigned char orig_trust_passwd_hash[16]) +{ + unsigned char new_trust_passwd_hash[16]; + char *new_trust_passwd; + char *str; + NTSTATUS nt_status; + + /* Create a random machine account password */ + str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); + new_trust_passwd = talloc_strdup(mem_ctx, str); + + E_md4hash((uchar *)new_trust_passwd, new_trust_passwd_hash); + + nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, + new_trust_passwd_hash); + + if (NT_STATUS_IS_OK(nt_status)) { + DEBUG(3,("%s : change_trust_account_password: Changed password.\n", timestring(False))); + /* + * Return the result of trying to write the new password + * back into the trust account file. + */ + if (!secrets_store_machine_password(new_trust_passwd)) { + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } + + return nt_status; +} + +/********************************************************* + Change the domain password on the PDC. + Do most of the legwork ourselfs. Caller must have + already setup the connection to the NETLOGON pipe +**********************************************************/ + +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *domain) +{ + unsigned char old_trust_passwd_hash[16]; + char *up_domain; + + up_domain = talloc_strdup(mem_ctx, domain); + + if (!secrets_fetch_trust_account_password(domain, + old_trust_passwd_hash, + NULL)) { + DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); + return NT_STATUS_UNSUCCESSFUL; + } + + return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); + +} + -- cgit From 7077558fb36d20dce626e1e3daede416ef9d3efc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Dec 2001 19:33:35 +0000 Subject: Added fetch_domain_sid. Not used in current code, but a nice example of how to use this interface. Jeremy. (This used to be commit 291985123515f99bb3fd86605d5b8a08301070a2) --- source3/libsmb/cli_lsarpc.c | 96 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 9526da94a8..c528ff48a9 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -988,5 +988,101 @@ NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** Fetch a DOMAIN sid. Does complete cli setup / teardown anonymously. */ +BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid) +{ + extern pstring global_myname; + struct cli_state cli; + NTSTATUS result; + POLICY_HND lsa_pol; + BOOL ret = False; + + ZERO_STRUCT(cli); + if(cli_initialise(&cli) == False) { + DEBUG(0,("fetch_domain_sid: unable to initialize client connection.\n")); + return False; + } + + if(!resolve_name( remote_machine, &cli.dest_ip, 0x20)) { + DEBUG(0,("fetch_domain_sid: Can't resolve address for %s\n", remote_machine)); + goto done; + } + + if (!cli_connect(&cli, remote_machine, &cli.dest_ip)) { + DEBUG(0,("fetch_domain_sid: unable to connect to SMB server on \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + goto done; + } + + if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) { + DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS \ +session request. Error was %s\n", remote_machine, cli_errstr(&cli) )); + goto done; + } + + cli.protocol = PROTOCOL_NT1; + + if (!cli_negprot(&cli)) { + DEBUG(0,("fetch_domain_sid: machine %s rejected the negotiate protocol. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + goto done; + } + + if (cli.protocol != PROTOCOL_NT1) { + DEBUG(0,("fetch_domain_sid: machine %s didn't negotiate NT protocol.\n", + remote_machine)); + goto done; + } + + /* + * Do an anonymous session setup. + */ + + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + DEBUG(0,("fetch_domain_sid: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + goto done; + } + + if (!(cli.sec_mode & 1)) { + DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n", + remote_machine)); + goto done; + } + + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("fetch_domain_sid: machine %s rejected the tconX on the IPC$ share. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + goto done; + } + + /* Fetch domain sid */ + + if (!cli_nt_session_open(&cli, PIPE_LSARPC)) { + DEBUG(0, ("fetch_domain_sid: Error connecting to SAM pipe\n")); + goto done; + } + + result = cli_lsa_open_policy(&cli, cli.mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n", + get_nt_error_msg(result) )); + goto done; + } + + result = cli_lsa_query_info_policy(&cli, cli.mem_ctx, &lsa_pol, 5, domain, psid); + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n", + get_nt_error_msg(result) )); + goto done; + } + + ret = True; + + done: + + cli_shutdown(&cli); + return ret; +} /** @} **/ -- cgit From 3c64bd4c509eebf6fc9bd101a405fbff651ba184 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 8 Dec 2001 02:14:56 +0000 Subject: Leak less memory. Now, is there any reason that the prs_init() doesn't use the talloc context that it is supplied as an argument for the actual data buffer? It would seem logical to replace the malloc with a talloc, but I'm sure there is some method to the madness (extrnal use/Reallocing of it I presume) Andrew Bartlett (This used to be commit ad18f33bfa79ce93024f3cb3a334cff622fe82a4) --- source3/libsmb/cli_netlogon.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index d20e466cc9..896af0d7c9 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -493,6 +493,9 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } @@ -504,7 +507,7 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, char* machine_name, uint8 hashed_mach_pwd[16]) { prs_struct rbuf; - prs_struct buf; + prs_struct qbuf; DOM_CRED new_clnt_cred; NET_Q_SRV_PWSET q_s; uint16 sec_chan_type = 2; @@ -513,7 +516,7 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, gen_next_creds( cli, &new_clnt_cred); - prs_init(&buf , 1024, mem_ctx, MARSHALL); + prs_init(&qbuf , 1024, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* create and send a MSRPC command with api NET_SRV_PWSET */ @@ -522,7 +525,8 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (!mach_acct) { DEBUG(0,("talloc_asprintf failed!\n")); - return NT_STATUS_NO_MEMORY; + nt_status = NT_STATUS_NO_MEMORY; + goto done; } DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", @@ -535,18 +539,20 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, &new_clnt_cred, (char *)hashed_mach_pwd); /* turn parameters into data stream */ - if(!net_io_q_srv_pwset("", &q_s, &buf, 0)) { + if(!net_io_q_srv_pwset("", &q_s, &qbuf, 0)) { DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n")); - return NT_STATUS_UNSUCCESSFUL; + nt_status = NT_STATUS_UNSUCCESSFUL; + goto done; } /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, NET_SRVPWSET, &buf, &rbuf)) + if (rpc_api_pipe_req(cli, NET_SRVPWSET, &qbuf, &rbuf)) { NET_R_SRV_PWSET r_s; if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) { - return NT_STATUS_UNSUCCESSFUL; + nt_status = NT_STATUS_UNSUCCESSFUL; + goto done; } nt_status = r_s.status; @@ -555,7 +561,7 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, { /* report error code */ DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(nt_status))); - return nt_status; + goto done; } /* Update the credentials. */ @@ -569,6 +575,10 @@ password ?).\n", cli->desthost )); nt_status = NT_STATUS_UNSUCCESSFUL; } } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return nt_status; } -- cgit From 5d378a280f74405fccbadbfb28e1066613c76fd8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Dec 2001 11:18:56 +0000 Subject: added internal sasl/gssapi code. This means we are no longer dependent on cyrus-sasl which makes the code much less fragile. Also added code to auto-determine the server name or realm (This used to be commit 435fdf276a79c2a517adcd7726933aeef3fa924b) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 784463566f..bc3873bf18 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -217,7 +217,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -static DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) { ASN1_DATA data; DATA_BLOB ret; -- cgit From 4f53486d78102d8080293eeafd7b4ed701d81a2e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 10 Dec 2001 05:03:17 +0000 Subject: Added client and server code for the GetPrintProcessorDirectory SPOOLSS rpc. This was supposed to fix a printer driver download bug but it didn't but it seemed a shame to trash all this code so I'm commiting it #ifdef'ed out in case someone needs it one day. (This used to be commit bef43656471741c6c10b12e7516c15de9ae76394) --- source3/libsmb/cli_spoolss.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 59 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 2663e311e0..d455bb7196 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1070,4 +1070,63 @@ done: return result; } +NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + char *name, + char *environment, + fstring procdir) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTPROCESSORDIRECTORY q; + SPOOL_R_GETPRINTPROCESSORDIRECTORY r; + NTSTATUS result; + int level = 1; + NEW_BUFFER buffer; + uint32 needed = 100; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + + /* Initialise input parameters */ + + do { + init_buffer(&buffer, needed, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + make_spoolss_q_getprintprocessordirectory(&q, name, + environment, level, + &buffer, needed); + + /* Marshall data and send request */ + if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Return output parameters */ + + result = werror_to_ntstatus(r.status); + + } while (NT_STATUS_V(result) == + NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 775c3876dbd02a2beae0626b2e735583ccedffbb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Dec 2001 19:18:56 +0000 Subject: RAP error strings take precedence as they are not encoded in the SMB header (ie. the call can succeed, but still be an encoded error). Jeremy. (This used to be commit 3c68b94199ff08b205d1eb14da56804936b900a8) --- source3/libsmb/clierror.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index e4d931b965..cd1f86a476 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -72,7 +72,14 @@ char *cli_errstr(struct cli_state *cli) uint8 errclass; int i; - /* Case #1: 32-bit NT errors */ + /* Case #1: RAP error */ + for (i = 0; rap_errmap[i].message != NULL; i++) { + if (rap_errmap[i].err == cli->rap_error) { + return rap_errmap[i].message; + } + } + + /* Case #2: 32-bit NT errors */ if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls)); @@ -81,18 +88,11 @@ char *cli_errstr(struct cli_state *cli) cli_dos_error(cli, &errclass, &errnum); - /* Case #2: SMB error */ + /* Case #3: SMB error */ if (errclass != 0) return cli_smb_errstr(cli); - /* Case #3: RAP error */ - for (i = 0; rap_errmap[i].message != NULL; i++) { - if (rap_errmap[i].err == cli->rap_error) { - return rap_errmap[i].message; - } - } - slprintf(cli_error_message, sizeof(cli_error_message) - 1, "code %d", cli->rap_error); -- cgit From a427fafc1f95d472189e867781a4b75ab0c8adcb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Dec 2001 19:48:43 +0000 Subject: Treat RAP codes differently. Jeremy. (This used to be commit 919b11a787145139e6255674179b2ff7e587475d) --- source3/libsmb/clierror.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index cd1f86a476..81e8be36a8 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -69,34 +69,35 @@ char *cli_errstr(struct cli_state *cli) { static fstring cli_error_message; uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum; - uint8 errclass; - int i; + uint8 errclass; + int i; - /* Case #1: RAP error */ - for (i = 0; rap_errmap[i].message != NULL; i++) { - if (rap_errmap[i].err == cli->rap_error) { - return rap_errmap[i].message; + /* Case #1: RAP error */ + if (cli->rap_error) { + for (i = 0; rap_errmap[i].message != NULL; i++) { + if (rap_errmap[i].err == cli->rap_error) { + return rap_errmap[i].message; + } } - } - /* Case #2: 32-bit NT errors */ - if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { - NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls)); + slprintf(cli_error_message, sizeof(cli_error_message) - 1, "RAP code %d", + cli->rap_error); - return get_nt_error_msg(status); - } + return cli_error_message; + } - cli_dos_error(cli, &errclass, &errnum); + /* Case #2: 32-bit NT errors */ + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { + NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls)); - /* Case #3: SMB error */ + return get_nt_error_msg(status); + } - if (errclass != 0) - return cli_smb_errstr(cli); + cli_dos_error(cli, &errclass, &errnum); - slprintf(cli_error_message, sizeof(cli_error_message) - 1, "code %d", - cli->rap_error); + /* Case #3: SMB error */ - return cli_error_message; + return cli_smb_errstr(cli); } -- cgit From ecf7017eca3f838c37072a6fa1aa895d7d39bd26 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 10 Dec 2001 22:30:31 +0000 Subject: added enum alias groups to rpcclient (This used to be commit d4bc8f02f7dc856ffb29e95a81ffcc3a9d4b1695) --- source3/libsmb/cli_samr.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index b7e0e70030..ddcfe89078 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -583,6 +583,84 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Enumerate domain groups */ + +NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *start_idx, + uint32 size, struct acct_info **dom_groups, + uint32 *num_dom_groups) +{ + prs_struct qbuf, rbuf; + SAMR_Q_ENUM_DOM_ALIASES q; + SAMR_R_ENUM_DOM_ALIASES r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + uint32 name_idx, i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size); + + if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) { + goto done; + } + + /* Return output parameters */ + + result = r.status; + + if (!NT_STATUS_IS_OK(result) && + NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { + goto done; + } + + *num_dom_groups = r.num_entries2; + + if (!((*dom_groups) = (struct acct_info *) + talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); + + name_idx = 0; + + for (i = 0; i < *num_dom_groups; i++) { + + (*dom_groups)[i].rid = r.sam[i].rid; + + if (r.sam[i].hdr_name.buffer) { + unistr2_to_ascii((*dom_groups)[i].acct_name, + &r.uni_grp_name[name_idx], + sizeof(fstring) - 1); + name_idx++; + } + + *start_idx = r.next_idx; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Query alias members */ NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, -- cgit From bf5a0e6717f786d4f623e3cca9f846a9413f82d5 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 10 Dec 2001 23:34:32 +0000 Subject: NT_STATUS(0x80000005) maps to ERRDOS,234 J.F. (This used to be commit 80e36549b61cc2bb5148f6abb175d31a0c7782a1) --- source3/libsmb/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index f4208e7f5e..ab524a01f5 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -537,7 +537,7 @@ static struct { {ERRDOS, 998, NT_STATUS(0x80000002)}, {ERRDOS, ERRbadpath, NT_STATUS(0x80000003)}, {ERRDOS, ERRnofids, NT_STATUS(0x80000004)}, - {ERRDOS, 111, NT_STATUS(0x80000005)}, + {ERRDOS, 234, NT_STATUS(0x80000005)}, {ERRDOS, ERRnofiles, NT_STATUS(0x80000006)}, {ERRDOS, 1391, NT_STATUS(0x8000000b)}, {ERRDOS, 299, NT_STATUS(0x8000000d)}, -- cgit From b872787f01f0e72db3c03676e46432375fcce787 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 11 Dec 2001 02:17:26 +0000 Subject: Doing some research into ACLs on the LSA and SAM policy objects. - added lsaquerysecobj to rpcclient - renamed querysecobj to samquerysecobj - removed duplicated display_sec_acl() code from cmd_spoolss.c and cmd_samr.c and moved it into display_sec.c (This used to be commit 59b2e3f408a5ff22f2d81a927d010a7df5f19f7f) --- source3/libsmb/cli_lsarpc.c | 52 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index c528ff48a9..ff4c4dfe30 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -988,6 +988,58 @@ NTSTATUS cli_lsa_lookupprivvalue(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** Query LSA security object */ + +NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 sec_info, + SEC_DESC_BUF **psdb) +{ + prs_struct qbuf, rbuf; + LSA_Q_QUERY_SEC_OBJ q; + LSA_R_QUERY_SEC_OBJ r; + NTSTATUS result; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_q_query_sec_obj(&q, pol, sec_info); + + if (!lsa_io_q_query_sec_obj("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, LSA_QUERYSECOBJ, &qbuf, &rbuf)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* Unmarshall response */ + + if (!lsa_io_r_query_sec_obj("", &r, &rbuf, 0)) { + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + if (!NT_STATUS_IS_OK(result = r.status)) { + goto done; + } + + /* Return output parameters */ + + if (psdb) + *psdb = r.buf; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** Fetch a DOMAIN sid. Does complete cli setup / teardown anonymously. */ BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid) -- cgit From 5ffe722a5585314cb1ba4533c0867c777e6b369b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Dec 2001 05:16:48 +0000 Subject: detect attempts to connect to names of the type NAME#xx and do a netbios lookup for name NAME with node type xx. This affects all our client progs. Very useful :) (This used to be commit b4304c5231159fc6295c445f2eb4470c179b8d5e) --- source3/libsmb/cliconnect.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 512607fc11..27034b012d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -975,11 +975,19 @@ open the client sockets BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern pstring user_socket_options; + int name_type = 0x20; + char *p; fstrcpy(cli->desthost, host); + + /* allow hostnames of the form NAME#xx and do a netbios lookup */ + if ((p = strchr(cli->desthost, '#'))) { + name_type = strtol(p+1, NULL, 16); + *p = 0; + } if (!ip || is_zero_ip(*ip)) { - if (!resolve_name( cli->desthost, &cli->dest_ip, 0x20)) { + if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) { return False; } if (ip) *ip = cli->dest_ip; @@ -1328,3 +1336,5 @@ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); return True; } + + -- cgit From 70095b09c3cede75fdda6f52823957fab5dd980d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Dec 2001 05:48:27 +0000 Subject: handle a NULL hostname in cli_connect() (This used to be commit a181f49b4269baa1752ce6ed4f9093e38d2d3ce5) --- source3/libsmb/cliconnect.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 27034b012d..fc50e8e02f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -978,6 +978,9 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) int name_type = 0x20; char *p; + /* reasonable default hostname */ + if (!host) host = "*SMBSERVER"; + fstrcpy(cli->desthost, host); /* allow hostnames of the form NAME#xx and do a netbios lookup */ -- cgit From a85390ae696998096b9323fd388fe0f1a9e1795c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Dec 2001 19:40:22 +0000 Subject: Always use ASCII strings when changing passwords with RAP. Jeremy. (This used to be commit d3ac2265b1b83e2e030688ee8e0d43918ce4d203) --- source3/libsmb/clirap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 2136ba118b..4484b61381 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -318,10 +318,10 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char * use this as the key to make_oem_passwd_hash(). */ memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); - clistr_push(cli, upper_case_old_pw, old_password, -1,STR_TERMINATE|STR_UPPER); + clistr_push(cli, upper_case_old_pw, old_password, -1,STR_TERMINATE|STR_UPPER|STR_ASCII); E_P16((uchar *)upper_case_old_pw, old_pw_hash); - clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE); + clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE|STR_ASCII); if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) return False; @@ -330,7 +330,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char * Now place the old password hash in the data. */ memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); - clistr_push(cli, upper_case_new_pw, new_password, -1, STR_TERMINATE|STR_UPPER); + clistr_push(cli, upper_case_new_pw, new_password, -1, STR_TERMINATE|STR_UPPER|STR_ASCII); E_P16((uchar *)upper_case_new_pw, new_pw_hash); -- cgit From 9f59fc64b8c1772b6a73d1649013d2187c298868 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Thu, 13 Dec 2001 18:09:29 +0000 Subject: update the ldap support code. it compiles. Ignacio you can update your howto ;-) samsync: a small patch to try chaning challenges. J.F. (This used to be commit c99bc305599698f2291efbfe20024355cb2bcde0) --- source3/libsmb/cli_netlogon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 896af0d7c9..8840a6264b 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -282,7 +282,7 @@ static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) /* Sam synchronisation */ -NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, +NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds, uint32 database_id, uint32 *num_deltas, SAM_DELTA_HDR **hdr_deltas, SAM_DELTA_CTR **deltas) @@ -306,7 +306,7 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, gen_next_creds(cli, &clnt_creds); init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2, - &clnt_creds, database_id); + &clnt_creds, ret_creds, database_id); /* Marshall data and send request */ @@ -330,6 +330,8 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, *hdr_deltas = r.hdr_deltas; *deltas = r.deltas; + memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds)); + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); -- cgit From 63bd99aec2cfc75ac9a4ec22f6f5fe46c7bdf15c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 13 Dec 2001 23:43:44 +0000 Subject: Added comment. (This used to be commit 594634ff1a1d5f780ddb9909f5365ee3e420a76c) --- source3/libsmb/cli_spoolss.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index d455bb7196..c87a36e302 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1070,6 +1070,8 @@ done: return result; } +/* Get print processor directory */ + NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *name, -- cgit From 6e76486505287124eb62e32c4387a9608364a568 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Mon, 17 Dec 2001 23:03:23 +0000 Subject: there is no unknown field in LSA_SEC_QOS some cleanup of the lsa_open_policy and lsa_open_policy2 parser. the length fields are not correct but that's what NT send. We don't anymore underflow or overflow the decoding. added the domain admins group to the default SD. we are now checking the desired access flag in the lsa_open_policy_X() calls and in most functions also. J.F. (This used to be commit a217c4e4ff4d13122703d22258792fe5e8e9f02f) --- source3/libsmb/cli_lsarpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index ff4c4dfe30..0720cadfbd 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -75,7 +75,7 @@ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0, des_access); + init_lsa_sec_qos(&qos, 2, 1, 0); init_q_open_pol(&q, '\\', 0, des_access, &qos); } else { init_q_open_pol(&q, '\\', 0, des_access, NULL); @@ -131,7 +131,7 @@ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0, des_access); + init_lsa_sec_qos(&qos, 2, 1, 0); init_q_open_pol2(&q, cli->clnt_name_slash, 0, des_access, &qos); } else { -- cgit From 9126a40e2c33e0eb4cd57ab381634e08fa59e7a7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Dec 2001 09:53:30 +0000 Subject: added trusted realm support to ADS authentication the method used for checking if a domain is a trusted domain is very crude, we should really call a backend fn of some sort. For now I'm using winbindd to do the dirty work. (This used to be commit adf44a9bd0d997ba4dcfadc564a29149531525af) --- source3/libsmb/clikrb5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 03fb6a5669..cc77c08d26 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -60,8 +60,8 @@ static krb5_error_code krb5_mk_req2(krb5_context context, if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { - DEBUG(1,("krb5_get_credentials failed (%s)\n", - error_message(retval))); + DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", + principal, error_message(retval))); goto cleanup_creds; } -- cgit From 384ce26f5bdf27aadaea967b17ee6ca8549aca5a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Dec 2001 11:58:30 +0000 Subject: try to handle end of packet for not null terminated domain strings (This used to be commit 1da988456dbd885820093ae43c74e0ac66f72802) --- source3/libsmb/cliconnect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index fc50e8e02f..d636e7e839 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -372,7 +372,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += blob2.length; p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); - p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), + smb_buflen(cli->inbuf) - PTR_DIFF(p, smb_buf(cli->inbuf)), + 0); return blob2; } -- cgit From caaac2803a52969312a633c2f6e0c446a944dffe Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 21 Dec 2001 12:29:51 +0000 Subject: - handle kerberos session setup reply with broken null termination - don't display Domain=[] for auth protocols that don't give us a domain (This used to be commit 20368455ea59e6e9b85632848bbe92069e7b0f38) --- source3/libsmb/cliconnect.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d636e7e839..75560da676 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -325,6 +325,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) uint32 capabilities = cli_session_setup_capabilities(cli); char *p; DATA_BLOB blob2; + uint32 len; blob2 = data_blob(NULL, 0); @@ -371,10 +372,10 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += blob2.length; p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); - p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); - p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), - smb_buflen(cli->inbuf) - PTR_DIFF(p, smb_buf(cli->inbuf)), - 0); + + /* w2k with kerberos doesn't properly null terminate this field */ + len = smb_buflen(cli->inbuf) - PTR_DIFF(p, smb_buf(cli->inbuf)); + p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), len, 0); return blob2; } -- cgit From 72898d48212c0af7d76620521f4b961f7afe11b2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Dec 2001 10:19:56 +0000 Subject: Finish idra's cleanup of the RPC remote shutdown code. (This used to be commit 79031b68ce6bdf882d9c9bd4f3310f597e0c1fda) --- source3/libsmb/cli_reg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c index 73eea58cb7..948534c29b 100644 --- a/source3/libsmb/cli_reg.c +++ b/source3/libsmb/cli_reg.c @@ -38,7 +38,7 @@ struct cli_state *cli_winreg_initialise(struct cli_state *cli, /* Shutdown a server */ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, - const char *srv_name, const char *msg, + const char *msg, uint32 timeout, uint16 flags) { prs_struct qbuf; @@ -78,8 +78,7 @@ done: /* Abort a server shutdown */ -NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, - const char *srv_name) +NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx) { prs_struct rbuf; prs_struct qbuf; -- cgit From 0608a60390db336bf179564aefdf16c43f1793ad Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 30 Dec 2001 19:21:25 +0000 Subject: util_sid.c - respect a const variabile (addedd strdup) cli_reg.c - indentation pdb_ldap.c - some checks on init fns parameters pdb_tdb.c - some checks on init fns parameters + make sure we close the db on failure (This used to be commit 49f5cb7a3df6d673f86e6769319aa657e30d8380) --- source3/libsmb/cli_reg.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c index 948534c29b..b88b3532ef 100644 --- a/source3/libsmb/cli_reg.c +++ b/source3/libsmb/cli_reg.c @@ -7,7 +7,7 @@ Copyright (C) Luke Kenneth Casson Leighton 1996-1998, Copyright (C) Paul Ashton 1997-1998. Copyright (C) Jeremy Allison 1999. - Copyright (C) Simo Sorce 2000 + Copyright (C) Simo Sorce 2001 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -38,8 +38,7 @@ struct cli_state *cli_winreg_initialise(struct cli_state *cli, /* Shutdown a server */ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, - const char *msg, - uint32 timeout, uint16 flags) + const char *msg, uint32 timeout, uint16 flags) { prs_struct qbuf; prs_struct rbuf; -- cgit From 82cfa2b248f3d1515bf70f147a406caaba317f47 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Dec 2001 12:50:44 +0000 Subject: Fix up the comment in the copyright header (This used to be commit 45042bef7cdede6f991572677654903bbf7d9144) --- source3/libsmb/trust_passwd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 7f7a5d29dc..c096a1354d 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -1,7 +1,7 @@ /* * Unix SMB/Netbios implementation. * Version 3.0 - * Routines to change + * Routines to change trust account passwords. * Copyright (C) Andrew Bartlett 2001. * * This program is free software; you can redistribute it and/or modify @@ -113,4 +113,3 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *me return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); } - -- cgit From af7bd393dabc51cedafc1ea24cc9f7101c81f4bf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 31 Dec 2001 13:06:10 +0000 Subject: Ensure the output cli can't have spurious values if the connection fails... (This used to be commit 2d1612dd3560bb5ef35fa1eeee00e3d7976bcd62) --- source3/libsmb/cliconnect.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 75560da676..bd79f23213 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1205,7 +1205,13 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct nmb_name called; struct cli_state *cli; struct in_addr ip; - + + if (!output_cli) { + DEBUG(0, ("output_cli is NULL!?!")); + } + + *output_cli = NULL; + make_nmb_name(&calling, my_name, 0x0); make_nmb_name(&called , dest_host, 0x20); -- cgit From ef40945a5b206730e19713dfd3c50f9032a9e36c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 1 Jan 2002 02:34:29 +0000 Subject: Add a specialised version of tpot's libsmb samlogon code for use with presupplied challange-response pairs, and only using the 'network' version. This will be used to move the auth subsystem over to a libsmb (rather than rpc_client) base. Andrew Bartlett (This used to be commit fe9d77791583737320f8c7560861168df7388c2f) --- source3/libsmb/cli_netlogon.c | 86 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 8840a6264b..9223683854 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -501,6 +501,92 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/** + * Logon domain user with an 'network' SAM logon + * + * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller. + **/ + +NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *username, char *domain, char *workstation, + uint8 chal[8], + DATA_BLOB lm_response, DATA_BLOB nt_response, + NET_USER_INFO_3 *info3) + +{ + prs_struct qbuf, rbuf; + NET_Q_SAM_LOGON q; + NET_R_SAM_LOGON r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + DOM_CRED clnt_creds, dummy_rtn_creds; + NET_ID_INFO_CTR ctr; + extern pstring global_myname; + int validation_level = 3; + char *workstation_name_slash; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation); + + if (!workstation_name_slash) { + DEBUG(0, ("talloc_asprintf failed!\n")); + return NT_STATUS_NO_MEMORY; + } + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + gen_next_creds(cli, &clnt_creds); + + q.validation_level = validation_level; + + memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); + dummy_rtn_creds.timestamp.time = time(NULL); + + ctr.switch_value = NET_LOGON_TYPE; + + init_id_info2(&ctr.auth.id2, domain, + 0, /* param_ctrl */ + 0xdead, 0xbeef, /* LUID? */ + username, workstation_name_slash, (uchar*)chal, + lm_response.data, lm_response.length, nt_response.data, nt_response.length); + + init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, + &clnt_creds, &dummy_rtn_creds, NET_LOGON_TYPE, + &ctr); + + /* Marshall data and send request */ + + if (!net_io_q_sam_logon("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + r.user = info3; + + if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { + goto done; + } + + /* Return results */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /*************************************************************************** LSA Server Password Set. ****************************************************************************/ -- cgit From 02ad29785b6eea290019163a41bffc27f0eb7855 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 1 Jan 2002 05:52:02 +0000 Subject: Add a function to convert 'NT_STATUS...' strings back into their actual error code. Andrew Bartlett (This used to be commit f0089b089b319009576bb39a076397bb44aff628) --- source3/libsmb/nterr.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 25286156ee..f4d64653e4 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -579,3 +579,19 @@ char *get_nt_error_c_code(NTSTATUS nt_code) return out; } + +/***************************************************************************** + returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) + *****************************************************************************/ +NTSTATUS nt_status_string_to_code(char *nt_status_str) +{ + int idx = 0; + + while (nt_errs[idx].nt_errstr != NULL) { + if (strcmp(nt_errs[idx].nt_errstr, nt_status_str) == 0) { + return nt_errs[idx].nt_errcode; + } + idx++; + } + return NT_STATUS_UNSUCCESSFUL; +} -- cgit From 8d09eecf6987fe55c06cd1bcf202170cd8a47d8e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 1 Jan 2002 06:16:43 +0000 Subject: This brings the NT->DOS error mapping into better line with what NT does. I'll post the changes to the actual map to the list for comment, but this fixes the 'unknown' case. Andrew Bartlett (This used to be commit 024843a2cedb0b9f06a3351c5838caea372b6c5c) --- source3/libsmb/errormap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index ab524a01f5..cf3dc34618 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1396,8 +1396,8 @@ void ntstatus_to_dos(NTSTATUS ntstatus, uint8 *eclass, uint32 *ecode) return; } } - *eclass = ERRSRV; - *ecode = ERRerror; + *eclass = ERRHRD; + *ecode = ERRgeneral; } -- cgit From 71c04c5f9fd00a5ed130d361797301fda037edb6 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Jan 2002 02:36:08 +0000 Subject: The werror<->nt status code map has changed and has broken all the spoolss commands in rpcclient. Replacing ERROR_INSUFFICIENT_BUFFER with NT_STATUS_BUFFER_TOO_SMALL fixes it. Yay! I always thought the caller (i.e cmd_spoolss.c) should take care of the whole requested/needed buffer size thingy though... (This used to be commit 6c950db05a2772f11b20cc13c65a123ea8b878c2) --- source3/libsmb/cli_spoolss.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index c87a36e302..6b1a5ff249 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -460,7 +460,7 @@ NTSTATUS cli_spoolss_enum_printers( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); return result; } @@ -535,7 +535,7 @@ NTSTATUS cli_spoolss_enum_ports( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); return result; } @@ -605,7 +605,7 @@ NTSTATUS cli_spoolss_getprinter( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); return result; } @@ -735,7 +735,7 @@ NTSTATUS cli_spoolss_getprinterdriver ( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); return result; } @@ -817,7 +817,7 @@ NTSTATUS cli_spoolss_enumprinterdrivers ( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); return result; } @@ -890,7 +890,7 @@ NTSTATUS cli_spoolss_getprinterdriverdir ( prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (NT_STATUS_V(result) == NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); return result; } @@ -1124,7 +1124,7 @@ NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli, result = werror_to_ntstatus(r.status); } while (NT_STATUS_V(result) == - NT_STATUS_V(ERROR_INSUFFICIENT_BUFFER)); + NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); done: prs_mem_free(&qbuf); -- cgit From 9164ed6220225ed14e167ba2166ad2f9ef7ba629 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 3 Jan 2002 02:47:50 +0000 Subject: Initialise result on success in cli_spoolss_enum_printers() so we don't get stuck in an infinite loop. (This used to be commit fe1fb6589a0a4b4cff7a0ee0267f6e09e10e2a85) --- source3/libsmb/cli_spoolss.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 6b1a5ff249..e6a6bf5258 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -439,6 +439,8 @@ NTSTATUS cli_spoolss_enum_printers( goto done; } + result = NT_STATUS_OK; + if ((*returned = r.returned)) { switch (level) { case 1: -- cgit From 80437a4cc0d88f47fb20901abf28590c35f3b09a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 3 Jan 2002 08:36:47 +0000 Subject: Update the NT_STATUS -> DOS error table. This new table is rather different to the old one (see diff posted to the list for a sorted list of differences) and needs a *lot* of testing. It does however seem to line up much better with what NT is using, as exampled by the change to the OBJECT_NAME_COLLISION DOS error, it now matches win2k where it didn't before. I can't see any critical errors we now get wrong, and I know that the auth errors are correct as per my on-the-wire observations. This table was produced (and I hope to comment this better later) by using the ERRMAPEXTRACT smbtorture tool, a Win2k domain member and the 'name_to_ntstatus' auth module on the HEAD PDC. This module returned the username as the error, and the NT box was forced to give me a dos error becouse thats all I negotiated on that connection. Hence the map. Andrew Bartlett (This used to be commit a855dfb2e0b899d03087860e5462c2aed3ca4cad) --- source3/libsmb/errormap.c | 831 ++++++++++++++++++++++++---------------------- source3/libsmb/smberr.c | 6 +- 2 files changed, 430 insertions(+), 407 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index cf3dc34618..74711e01bf 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -27,186 +27,217 @@ static struct { uint32 dos_code; NTSTATUS ntstatus; } ntstatus_to_dos_map[] = { - {ERRDOS, 997, NT_STATUS(0x00000103)}, - {ERRDOS, 111, STATUS_MORE_ENTRIES}, - {ERRDOS, 1300, NT_STATUS(0x00000106)}, - {ERRDOS, 1301, NT_STATUS(0x00000107)}, - {ERRDOS, 1022, NT_STATUS(0x0000010c)}, - {ERRDOS, 1302, NT_STATUS(0x0000010d)}, - {ERRDOS, 8201, NT_STATUS(0x00000121)}, {ERRDOS, 31, NT_STATUS_UNSUCCESSFUL}, - {ERRSRV, ERRsmbcmd, NT_STATUS_NOT_IMPLEMENTED}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_INFO_CLASS}, + {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, + {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, {ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, - {ERRDOS, 998, NT_STATUS_ACCESS_VIOLATION}, - {ERRDOS, 999, NT_STATUS_IN_PAGE_ERROR}, - {ERRDOS, 1454, NT_STATUS_PAGEFILE_QUOTA}, + {ERRHRD, ERRgeneral, NT_STATUS_ACCESS_VIOLATION}, + {ERRHRD, ERRgeneral, NT_STATUS_IN_PAGE_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA}, {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, - {ERRDOS, 1001, NT_STATUS_BAD_INITIAL_STACK}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_INITIAL_STACK}, {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_CID}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER}, + {ERRDOS, 87, NT_STATUS_INVALID_CID}, + {ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, - {ERRSRV, ERRsmbcmd, NT_STATUS_INVALID_DEVICE_REQUEST}, + {ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, {ERRDOS, 38, NT_STATUS_END_OF_FILE}, {ERRDOS, 34, NT_STATUS_WRONG_VOLUME}, {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, - {ERRDOS, 1785, NT_STATUS_UNRECOGNIZED_MEDIA}, + {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_MEDIA}, {ERRDOS, 27, NT_STATUS_NONEXISTENT_SECTOR}, - {ERRDOS, 111, NT_STATUS_MORE_PROCESSING_REQUIRED}, +/** Session setup succeeded. This shouldn't happen...*/ +/** Session setup succeeded. This shouldn't happen...*/ +/** NT error on DOS connection! (NT_STATUS_OK) */ +/* { This NT error code was 'sqashed' + from NT_STATUS_MORE_PROCESSING_REQUIRED to NT_STATUS_OK + during the session setup } +*/ +#if 0 + {SUCCESS, 0, NT_STATUS_OK}, +#endif {ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY}, {ERRDOS, 487, NT_STATUS_CONFLICTING_ADDRESSES}, {ERRDOS, 487, NT_STATUS_NOT_MAPPED_VIEW}, - {ERRDOS, ERRbadpipe, NT_STATUS(0xc000001a)}, - {ERRDOS, ERRbadpipe, NT_STATUS_UNABLE_TO_DELETE_SECTION}, - {ERRSRV, ERRsmbcmd, NT_STATUS_INVALID_SYSTEM_SERVICE}, - {ERRDOS, 29, NT_STATUS_ILLEGAL_INSTRUCTION}, - {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, - {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_VIEW_SIZE}, + {ERRDOS, 87, NT_STATUS_UNABLE_TO_FREE_VM}, + {ERRDOS, 87, NT_STATUS_UNABLE_TO_DELETE_SECTION}, + {ERRDOS, 2142, NT_STATUS_INVALID_SYSTEM_SERVICE}, + {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_INSTRUCTION}, + {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRDOS, ERRnoaccess, NT_STATUS_INVALID_VIEW_SIZE}, {ERRDOS, 193, NT_STATUS_INVALID_FILE_FOR_SECTION}, - {ERRDOS, ERRbadaccess, NT_STATUS_ALREADY_COMMITTED}, - {ERRDOS, ERRbadaccess, NT_STATUS_ACCESS_DENIED}, - {ERRDOS, ERRinsufficientbuffer, NT_STATUS_BUFFER_TOO_SMALL}, + {ERRDOS, ERRnoaccess, NT_STATUS_ALREADY_COMMITTED}, +/* { This NT error code was 'sqashed' + from NT_STATUS_ACCESS_DENIED to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE + during the session setup } +*/ + {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, + {ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL}, {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, - {ERRDOS, 37, NT_STATUS_NONCONTINUABLE_EXCEPTION}, - {ERRDOS, 38, NT_STATUS_INVALID_DISPOSITION}, + {ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, + {ERRHRD, ERRgeneral, NT_STATUS_UNWIND}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_STACK}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_UNWIND_TARGET}, {ERRDOS, 158, NT_STATUS_NOT_LOCKED}, - {ERRDOS, 43, NT_STATUS_PARITY_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_PARITY_ERROR}, {ERRDOS, 487, NT_STATUS_UNABLE_TO_DECOMMIT_VM}, {ERRDOS, 487, NT_STATUS_NOT_COMMITTED}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_MIX}, - {ERRDOS, 26, NT_STATUS_DISK_CORRUPT_ERROR}, - {ERRSRV, 206, NT_STATUS_OBJECT_NAME_INVALID}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PORT_ATTRIBUTES}, + {ERRHRD, ERRgeneral, NT_STATUS_PORT_MESSAGE_TOO_LONG}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_MIX}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_QUOTA_LOWER}, + {ERRHRD, ERRgeneral, NT_STATUS_DISK_CORRUPT_ERROR}, + {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, {ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND}, - {ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRDOS, 183, NT_STATUS_OBJECT_NAME_COLLISION}, + {ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, + {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, {ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, - {ERRDOS, 1117, NT_STATUS_DATA_OVERRUN}, - {ERRDOS, 1117, NT_STATUS_DATA_LATE_ERROR}, - {ERRDOS, ERRbaddata, NT_STATUS_DATA_ERROR}, - {ERRDOS, ERRbaddata, NT_STATUS_CRC_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, + {ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, + {ERRDOS, 23, NT_STATUS_DATA_ERROR}, + {ERRDOS, 23, NT_STATUS_CRC_ERROR}, {ERRDOS, ERRnomem, NT_STATUS_SECTION_TOO_BIG}, - {ERRDOS, ERRbadaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, + {ERRDOS, ERRnoaccess, NT_STATUS_PORT_CONNECTION_REFUSED}, {ERRDOS, ERRbadfid, NT_STATUS_INVALID_PORT_HANDLE}, {ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION}, - {ERRDOS, 1816, NT_STATUS_QUOTA_EXCEEDED}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PAGE_PROTECTION}, + {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_EXCEEDED}, + {ERRDOS, 87, NT_STATUS_INVALID_PAGE_PROTECTION}, {ERRDOS, 288, NT_STATUS_MUTANT_NOT_OWNED}, {ERRDOS, 298, NT_STATUS_SEMAPHORE_LIMIT_EXCEEDED}, - {ERRDOS, ERRbadpipe, NT_STATUS_PORT_ALREADY_SET}, - {ERRDOS, ERRbadpipe, NT_STATUS_SECTION_NOT_IMAGE}, + {ERRDOS, 87, NT_STATUS_PORT_ALREADY_SET}, + {ERRDOS, 87, NT_STATUS_SECTION_NOT_IMAGE}, {ERRDOS, 156, NT_STATUS_SUSPEND_COUNT_EXCEEDED}, - {ERRDOS, ERRbadaccess, NT_STATUS_THREAD_IS_TERMINATING}, - {ERRDOS, ERRbadpipe, NT_STATUS_BAD_WORKING_SET_LIMIT}, - {ERRDOS, ERRbadpipe, NT_STATUS_INCOMPATIBLE_FILE_MAP}, - {ERRDOS, ERRbadpipe, NT_STATUS_SECTION_PROTECTION}, + {ERRDOS, ERRnoaccess, NT_STATUS_THREAD_IS_TERMINATING}, + {ERRDOS, 87, NT_STATUS_BAD_WORKING_SET_LIMIT}, + {ERRDOS, 87, NT_STATUS_INCOMPATIBLE_FILE_MAP}, + {ERRDOS, 87, NT_STATUS_SECTION_PROTECTION}, {ERRDOS, 282, NT_STATUS_EAS_NOT_SUPPORTED}, - {ERRDOS, 275, NT_STATUS_EA_TOO_LARGE}, - {ERRDOS, 276, NT_STATUS_NONEXISTENT_EA_ENTRY}, - {ERRDOS, 276, NT_STATUS_NO_EAS_ON_FILE}, - {ERRDOS, 276, NT_STATUS_EA_CORRUPT_ERROR}, + {ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, + {ERRHRD, ERRgeneral, NT_STATUS_NONEXISTENT_EA_ENTRY}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_EAS_ON_FILE}, + {ERRHRD, ERRgeneral, NT_STATUS_EA_CORRUPT_ERROR}, {ERRDOS, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, {ERRDOS, ERRlock, NT_STATUS_LOCK_NOT_GRANTED}, - {ERRDOS, ERRbadaccess, NT_STATUS_DELETE_PENDING}, + {ERRDOS, ERRnoaccess, NT_STATUS_DELETE_PENDING}, {ERRDOS, ERRunsup, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, - {ERRDOS, 1305, NT_STATUS_UNKNOWN_REVISION}, - {ERRDOS, 1306, NT_STATUS_REVISION_MISMATCH}, - {ERRDOS, 1307, NT_STATUS_INVALID_OWNER}, - {ERRDOS, 1308, NT_STATUS_INVALID_PRIMARY_GROUP}, - {ERRDOS, 1309, NT_STATUS_NO_IMPERSONATION_TOKEN}, - {ERRDOS, 1310, NT_STATUS_CANT_DISABLE_MANDATORY}, - {ERRDOS, 1311, NT_STATUS_NO_LOGON_SERVERS}, - {ERRDOS, 1312, NT_STATUS_NO_SUCH_LOGON_SESSION}, - {ERRDOS, 1313, NT_STATUS_NO_SUCH_PRIVILEGE}, - {ERRDOS, 1314, NT_STATUS_PRIVILEGE_NOT_HELD}, - {ERRDOS, 1315, NT_STATUS_INVALID_ACCOUNT_NAME}, - {ERRDOS, 1316, NT_STATUS_USER_EXISTS}, - {ERRDOS, 1317, NT_STATUS_NO_SUCH_USER}, - {ERRDOS, 1318, NT_STATUS_GROUP_EXISTS}, - {ERRDOS, 1319, NT_STATUS_NO_SUCH_GROUP}, - {ERRDOS, 1320, NT_STATUS_MEMBER_IN_GROUP}, - {ERRDOS, 1321, NT_STATUS_MEMBER_NOT_IN_GROUP}, - {ERRDOS, 1322, NT_STATUS_LAST_ADMIN}, - {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, - {ERRDOS, 1324, NT_STATUS_ILL_FORMED_PASSWORD}, - {ERRDOS, 1325, NT_STATUS_PASSWORD_RESTRICTION}, - {ERRDOS, ERRlogonfailure, NT_STATUS_LOGON_FAILURE}, - {ERRDOS, 1327, NT_STATUS_ACCOUNT_RESTRICTION}, + {ERRHRD, ERRgeneral, NT_STATUS_UNKNOWN_REVISION}, + {ERRHRD, ERRgeneral, NT_STATUS_REVISION_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_OWNER}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PRIMARY_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_IMPERSONATION_TOKEN}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_DISABLE_MANDATORY}, + {ERRDOS, 2215, NT_STATUS_NO_LOGON_SERVERS}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_LOGON_SESSION}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PRIVILEGE}, + {ERRDOS, ERRnoaccess, NT_STATUS_PRIVILEGE_NOT_HELD}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACCOUNT_NAME}, + {ERRHRD, ERRgeneral, NT_STATUS_USER_EXISTS}, +/* { This NT error code was 'sqashed' + from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE + during the session setup } +*/ + {ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, + {ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_LAST_ADMIN}, +/* { This NT error code was 'sqashed' + from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE + during the session setup } +*/ + {ERRDOS, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, + {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, + {ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, + {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, {ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, {ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, {ERRSRV, 2242, NT_STATUS_PASSWORD_EXPIRED}, {ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, - {ERRDOS, 1332, NT_STATUS_NONE_MAPPED}, - {ERRDOS, 1333, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, - {ERRDOS, 1334, NT_STATUS_LUIDS_EXHAUSTED}, - {ERRDOS, 1335, NT_STATUS_INVALID_SUB_AUTHORITY}, - {ERRDOS, 1336, NT_STATUS_INVALID_ACL}, - {ERRDOS, 1337, NT_STATUS_INVALID_SID}, - {ERRDOS, 1338, NT_STATUS_INVALID_SECURITY_DESCR}, + {ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, + {ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SUB_AUTHORITY}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ACL}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SID}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SECURITY_DESCR}, {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_FORMAT}, - {ERRDOS, 1008, NT_STATUS_NO_TOKEN}, - {ERRDOS, 1340, NT_STATUS_BAD_INHERITANCE_ACL}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_TOKEN}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_INHERITANCE_ACL}, {ERRDOS, 158, NT_STATUS_RANGE_NOT_LOCKED}, - {ERRSRV, ERRnoroom, NT_STATUS_DISK_FULL}, - {ERRDOS, 1341, NT_STATUS_SERVER_DISABLED}, - {ERRDOS, 1342, NT_STATUS_SERVER_NOT_DISABLED}, + {ERRDOS, 112, NT_STATUS_DISK_FULL}, + {ERRHRD, ERRgeneral, NT_STATUS_SERVER_DISABLED}, + {ERRHRD, ERRgeneral, NT_STATUS_SERVER_NOT_DISABLED}, {ERRDOS, 68, NT_STATUS_TOO_MANY_GUIDS_REQUESTED}, {ERRDOS, 259, NT_STATUS_GUIDS_EXHAUSTED}, - {ERRDOS, 1343, NT_STATUS_INVALID_ID_AUTHORITY}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ID_AUTHORITY}, {ERRDOS, 259, NT_STATUS_AGENTS_EXHAUSTED}, {ERRDOS, 154, NT_STATUS_INVALID_VOLUME_LABEL}, - {ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, + {ERRDOS, ERRres, NT_STATUS_SECTION_NOT_EXTENDED}, {ERRDOS, 487, NT_STATUS_NOT_MAPPED_DATA}, - {ERRDOS, 1812, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, - {ERRDOS, 1813, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, - {ERRDOS, 1814, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, - {ERRDOS, 140, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, - {ERRDOS, 141, NT_STATUS_FLOAT_DENORMAL_OPERAND}, - {ERRDOS, 142, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, - {ERRDOS, 143, NT_STATUS_FLOAT_INEXACT_RESULT}, - {ERRDOS, 144, NT_STATUS_FLOAT_INVALID_OPERATION}, - {ERRDOS, 145, NT_STATUS_FLOAT_OVERFLOW}, - {ERRDOS, 146, NT_STATUS_FLOAT_STACK_CHECK}, - {ERRDOS, 147, NT_STATUS_FLOAT_UNDERFLOW}, - {ERRDOS, 148, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, + {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_DATA_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_TYPE_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_NAME_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_ARRAY_BOUNDS_EXCEEDED}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DENORMAL_OPERAND}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_DIVIDE_BY_ZERO}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INEXACT_RESULT}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_INVALID_OPERATION}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_STACK_CHECK}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOAT_UNDERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_INTEGER_DIVIDE_BY_ZERO}, {ERRDOS, 534, NT_STATUS_INTEGER_OVERFLOW}, - {ERRDOS, 150, NT_STATUS_PRIVILEGED_INSTRUCTION}, + {ERRHRD, ERRgeneral, NT_STATUS_PRIVILEGED_INSTRUCTION}, {ERRDOS, ERRnomem, NT_STATUS_TOO_MANY_PAGING_FILES}, - {ERRDOS, 1006, NT_STATUS_FILE_INVALID}, - {ERRDOS, 1344, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, + {ERRHRD, ERRgeneral, NT_STATUS_FILE_INVALID}, + {ERRHRD, ERRgeneral, NT_STATUS_ALLOTTED_SPACE_EXCEEDED}, +/* { This NT error code was 'sqashed' + from NT_STATUS_INSUFFICIENT_RESOURCES to NT_STATUS_INSUFF_SERVER_RESOURCES + during the session setup } +*/ {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, {ERRDOS, ERRbadpath, NT_STATUS_DFS_EXIT_PATH_FOUND}, - {ERRDOS, ERRbaddata, NT_STATUS_DEVICE_DATA_ERROR}, - {ERRDOS, 1167, NT_STATUS_DEVICE_NOT_CONNECTED}, + {ERRDOS, 23, NT_STATUS_DEVICE_DATA_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_CONNECTED}, {ERRDOS, 21, NT_STATUS_DEVICE_POWER_FAILURE}, {ERRDOS, 487, NT_STATUS_FREE_VM_NOT_AT_BASE}, {ERRDOS, 487, NT_STATUS_MEMORY_NOT_ALLOCATED}, - {ERRDOS, 1453, NT_STATUS_WORKING_SET_QUOTA}, + {ERRHRD, ERRgeneral, NT_STATUS_WORKING_SET_QUOTA}, {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, {ERRDOS, 21, NT_STATUS_DEVICE_NOT_READY}, - {ERRDOS, 1345, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, - {ERRDOS, 1346, NT_STATUS_BAD_IMPERSONATION_LEVEL}, - {ERRDOS, 1347, NT_STATUS_CANT_OPEN_ANONYMOUS}, - {ERRDOS, 1348, NT_STATUS_BAD_VALIDATION_CLASS}, - {ERRDOS, 1349, NT_STATUS_BAD_TOKEN_TYPE}, - {ERRDOS, ERRbadpipe, NT_STATUS_BAD_MASTER_BOOT_RECORD}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_GROUP_ATTRIBUTES}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_IMPERSONATION_LEVEL}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_OPEN_ANONYMOUS}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_VALIDATION_CLASS}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_TOKEN_TYPE}, + {ERRDOS, 87, NT_STATUS_BAD_MASTER_BOOT_RECORD}, + {ERRHRD, ERRgeneral, NT_STATUS_INSTRUCTION_MISALIGNMENT}, {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_NOT_AVAILABLE}, {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PIPE_STATE}, {ERRDOS, ERRpipebusy, NT_STATUS_PIPE_BUSY}, - {ERRSRV, ERRsmbcmd, NT_STATUS_ILLEGAL_FUNCTION}, + {ERRDOS, ERRbadfunc, NT_STATUS_ILLEGAL_FUNCTION}, {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, - {ERRDOS, 535, NT_STATUS_PIPE_CONNECTED}, - {ERRDOS, 536, NT_STATUS_PIPE_LISTENING}, + {ERRHRD, ERRgeneral, NT_STATUS_PIPE_CONNECTED}, + {ERRHRD, ERRgeneral, NT_STATUS_PIPE_LISTENING}, {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_READ_MODE}, {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, {ERRDOS, 38, NT_STATUS_FILE_FORCED_CLOSED}, - {ERRDOS, ERRbadaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, + {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STARTED}, + {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_NOT_STOPPED}, + {ERRHRD, ERRgeneral, NT_STATUS_COULD_NOT_INTERPRET}, + {ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, {ERRDOS, ERRunsup, NT_STATUS_NOT_SUPPORTED}, {ERRDOS, 51, NT_STATUS_REMOTE_NOT_LISTENING}, {ERRDOS, 52, NT_STATUS_DUPLICATE_NAME}, @@ -218,183 +249,241 @@ static struct { {ERRDOS, 58, NT_STATUS_INVALID_NETWORK_RESPONSE}, {ERRDOS, 59, NT_STATUS_UNEXPECTED_NETWORK_ERROR}, {ERRDOS, 60, NT_STATUS_BAD_REMOTE_ADAPTER}, - {ERRSRV, ERRqfull, NT_STATUS_PRINT_QUEUE_FULL}, - {ERRSRV, ERRqtoobig, NT_STATUS_NO_SPOOL_SPACE}, - {ERRSRV, ERRinvpfid, NT_STATUS_PRINT_CANCELLED}, - {ERRSRV, ERRinvnid, NT_STATUS_NETWORK_NAME_DELETED}, - {ERRSRV, ERRaccess, NT_STATUS_NETWORK_ACCESS_DENIED}, - {ERRSRV, ERRbadtype, NT_STATUS_BAD_DEVICE_TYPE}, - {ERRSRV, ERRinvnetname, NT_STATUS_BAD_NETWORK_NAME}, + {ERRDOS, 61, NT_STATUS_PRINT_QUEUE_FULL}, + {ERRDOS, 62, NT_STATUS_NO_SPOOL_SPACE}, + {ERRDOS, 63, NT_STATUS_PRINT_CANCELLED}, + {ERRDOS, 64, NT_STATUS_NETWORK_NAME_DELETED}, + {ERRDOS, 65, NT_STATUS_NETWORK_ACCESS_DENIED}, + {ERRDOS, 66, NT_STATUS_BAD_DEVICE_TYPE}, + {ERRDOS, ERRnosuchshare, NT_STATUS_BAD_NETWORK_NAME}, {ERRDOS, 68, NT_STATUS_TOO_MANY_NAMES}, - {ERRSRV, ERRtoomanyuids, NT_STATUS_TOO_MANY_SESSIONS}, - {ERRSRV, ERRpaused, NT_STATUS_SHARING_PAUSED}, - {ERRSRV, ERRmsgoff, NT_STATUS_REQUEST_NOT_ACCEPTED}, + {ERRDOS, 69, NT_STATUS_TOO_MANY_SESSIONS}, + {ERRDOS, 70, NT_STATUS_SHARING_PAUSED}, + {ERRDOS, 71, NT_STATUS_REQUEST_NOT_ACCEPTED}, {ERRDOS, 72, NT_STATUS_REDIRECTOR_PAUSED}, {ERRDOS, 88, NT_STATUS_NET_WRITE_FAULT}, + {ERRHRD, ERRgeneral, NT_STATUS_PROFILING_AT_LIMIT}, {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, - {ERRDOS, ERRbadaccess, NT_STATUS_FILE_RENAMED}, + {ERRDOS, ERRnoaccess, NT_STATUS_FILE_RENAMED}, {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, - {ERRDOS, 1350, NT_STATUS_NO_SECURITY_ON_OBJECT}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SECURITY_ON_OBJECT}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_WAIT}, {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_EMPTY}, - {ERRDOS, 1351, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, - {ERRDOS, 1352, NT_STATUS_INVALID_SERVER_STATE}, - {ERRDOS, 1353, NT_STATUS_INVALID_DOMAIN_STATE}, - {ERRDOS, 1354, NT_STATUS_INVALID_DOMAIN_ROLE}, - {ERRDOS, 1355, NT_STATUS_NO_SUCH_DOMAIN}, - {ERRDOS, 1356, NT_STATUS_DOMAIN_EXISTS}, - {ERRDOS, 1357, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_ACCESS_DOMAIN_INFO}, + {ERRHRD, ERRgeneral, NT_STATUS_CANT_TERMINATE_SELF}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_SERVER_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DOMAIN_ROLE}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_DOMAIN}, + {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_EXISTS}, + {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_LIMIT_EXCEEDED}, {ERRDOS, 300, NT_STATUS_OPLOCK_NOT_GRANTED}, {ERRDOS, 301, NT_STATUS_INVALID_OPLOCK_PROTOCOL}, - {ERRDOS, 1358, NT_STATUS_INTERNAL_DB_CORRUPTION}, - {ERRDOS, 1359, NT_STATUS_INTERNAL_ERROR}, - {ERRDOS, 1360, NT_STATUS_GENERIC_NOT_MAPPED}, - {ERRDOS, 1361, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, - {ERRDOS, 1784, NT_STATUS_INVALID_USER_BUFFER}, - {ERRDOS, 1362, NT_STATUS_NOT_LOGON_PROCESS}, - {ERRDOS, 1363, NT_STATUS_LOGON_SESSION_EXISTS}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_1}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_2}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_3}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_4}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_5}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_6}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_7}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_8}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_9}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_10}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_11}, - {ERRDOS, ERRbadpipe, NT_STATUS_INVALID_PARAMETER_12}, + {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_CORRUPTION}, + {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_GENERIC_NOT_MAPPED}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_DESCRIPTOR_FORMAT}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_USER_BUFFER}, + {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_IO_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_CREATE_ERR}, + {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_MAP_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_UNEXPECTED_MM_EXTEND_ERR}, + {ERRHRD, ERRgeneral, NT_STATUS_NOT_LOGON_PROCESS}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_EXISTS}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_1}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_2}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_3}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_4}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_5}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_6}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_7}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_8}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_9}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_10}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_11}, + {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER_12}, {ERRDOS, ERRbadpath, NT_STATUS_REDIRECTOR_NOT_STARTED}, - {ERRDOS, 1001, NT_STATUS_STACK_OVERFLOW}, - {ERRDOS, 1364, NT_STATUS_NO_SUCH_PACKAGE}, + {ERRHRD, ERRgeneral, NT_STATUS_REDIRECTOR_STARTED}, + {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_PACKAGE}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_FUNCTION_TABLE}, {ERRDOS, 203, NT_STATUS(0xc0000100)}, - {ERRDOS, ERRremcd, NT_STATUS_DIRECTORY_NOT_EMPTY}, - {ERRDOS, 276, NT_STATUS_FILE_CORRUPT_ERROR}, + {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, + {ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR}, {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, - {ERRDOS, 1365, NT_STATUS_BAD_LOGON_SESSION_STATE}, - {ERRDOS, 1366, NT_STATUS_LOGON_SESSION_COLLISION}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION}, {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, {ERRDOS, 2401, NT_STATUS_FILES_OPEN}, {ERRDOS, 2404, NT_STATUS_CONNECTION_IN_USE}, - {ERRDOS, ERRbadaccess, NT_STATUS_PROCESS_IS_TERMINATING}, - {ERRDOS, 1367, NT_STATUS_INVALID_LOGON_TYPE}, - {ERRDOS, 1368, NT_STATUS_CANNOT_IMPERSONATE}, - {ERRDOS, 1056, NT_STATUS_IMAGE_ALREADY_LOADED}, - {ERRDOS, 1444, NT_STATUS_NO_LDT}, + {ERRHRD, ERRgeneral, NT_STATUS_MESSAGE_NOT_FOUND}, + {ERRDOS, ERRnoaccess, NT_STATUS_PROCESS_IS_TERMINATING}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LOGON_TYPE}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_GUID_TRANSLATION}, + {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_IMPERSONATE}, + {ERRHRD, ERRgeneral, NT_STATUS_IMAGE_ALREADY_LOADED}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_PRESENT}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_NOT_EXIST}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_LID_ALREADY_OWNED}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_NOT_LID_OWNER}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_COMMAND}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_LID}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_SELECTOR_NOT_AVAILABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_ABIOS_INVALID_SELECTOR}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_LDT}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_SIZE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_OFFSET}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_LDT_DESCRIPTOR}, {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NE_FORMAT}, - {ERRDOS, 1369, NT_STATUS_RXACT_INVALID_STATE}, - {ERRDOS, 1370, NT_STATUS_RXACT_COMMIT_FAILURE}, - {ERRDOS, 1006, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, + {ERRHRD, ERRgeneral, NT_STATUS_RXACT_INVALID_STATE}, + {ERRHRD, ERRgeneral, NT_STATUS_RXACT_COMMIT_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_FILE_SIZE_ZERO}, {ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES}, - {ERRDOS, 995, NT_STATUS_CANCELLED}, - {ERRDOS, ERRbadaccess, NT_STATUS_CANNOT_DELETE}, - {ERRDOS, 1210, NT_STATUS_INVALID_COMPUTER_NAME}, - {ERRDOS, ERRbadaccess, NT_STATUS_FILE_DELETED}, - {ERRDOS, 1371, NT_STATUS_SPECIAL_ACCOUNT}, - {ERRDOS, 1372, NT_STATUS_SPECIAL_GROUP}, - {ERRDOS, 1373, NT_STATUS_SPECIAL_USER}, - {ERRDOS, 1374, NT_STATUS_MEMBERS_PRIMARY_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_CANCELLED}, + {ERRDOS, ERRnoaccess, NT_STATUS_CANNOT_DELETE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_COMPUTER_NAME}, + {ERRDOS, ERRnoaccess, NT_STATUS_FILE_DELETED}, + {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_ACCOUNT}, + {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_GROUP}, + {ERRHRD, ERRgeneral, NT_STATUS_SPECIAL_USER}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBERS_PRIMARY_GROUP}, {ERRDOS, ERRbadfid, NT_STATUS_FILE_CLOSED}, - {ERRDOS, 1375, NT_STATUS_TOKEN_ALREADY_IN_USE}, - {ERRDOS, 1455, NT_STATUS_COMMITMENT_LIMIT}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_THREADS}, + {ERRHRD, ERRgeneral, NT_STATUS_THREAD_NOT_IN_PROCESS}, + {ERRHRD, ERRgeneral, NT_STATUS_TOKEN_ALREADY_IN_USE}, + {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_QUOTA_EXCEEDED}, + {ERRHRD, ERRgeneral, NT_STATUS_COMMITMENT_LIMIT}, {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_LE_FORMAT}, {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_NOT_MZ}, {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_PROTECT}, {ERRDOS, 193, NT_STATUS_INVALID_IMAGE_WIN_16}, - {ERRDOS, 1398, NT_STATUS_TIME_DIFFERENCE_AT_DC}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SERVER_CONFLICT}, + {ERRHRD, ERRgeneral, NT_STATUS_TIME_DIFFERENCE_AT_DC}, + {ERRHRD, ERRgeneral, NT_STATUS_SYNCHRONIZATION_REQUIRED}, {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_OPEN_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_IO_PRIVILEGE_FAILED}, {ERRDOS, 182, NT_STATUS_ORDINAL_NOT_FOUND}, {ERRDOS, 127, NT_STATUS_ENTRYPOINT_NOT_FOUND}, - {ERRSRV, ERRinvnid, NT_STATUS_LOCAL_DISCONNECT}, - {ERRSRV, ERRinvnid, NT_STATUS_REMOTE_DISCONNECT}, + {ERRHRD, ERRgeneral, NT_STATUS_CONTROL_C_EXIT}, + {ERRDOS, 64, NT_STATUS_LOCAL_DISCONNECT}, + {ERRDOS, 64, NT_STATUS_REMOTE_DISCONNECT}, {ERRDOS, 51, NT_STATUS_REMOTE_RESOURCES}, {ERRDOS, 59, NT_STATUS_LINK_FAILED}, {ERRDOS, 59, NT_STATUS_LINK_TIMEOUT}, {ERRDOS, 59, NT_STATUS_INVALID_CONNECTION}, {ERRDOS, 59, NT_STATUS_INVALID_ADDRESS}, - {ERRDOS, 1114, NT_STATUS_DLL_INIT_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_DLL_INIT_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_MISSING_SYSTEMFILE}, + {ERRHRD, ERRgeneral, NT_STATUS_UNHANDLED_EXCEPTION}, + {ERRHRD, ERRgeneral, NT_STATUS_APP_INIT_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_CREATE_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_PAGEFILE}, {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, - {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD_CORE}, + {ERRDOS, 86, NT_STATUS_WRONG_PASSWORD_CORE}, + {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, - {ERRDOS, 1009, NT_STATUS_REGISTRY_CORRUPT}, - {ERRDOS, 1016, NT_STATUS_REGISTRY_IO_FAILED}, - {ERRDOS, 1005, NT_STATUS_UNRECOGNIZED_VOLUME}, - {ERRDOS, 1118, NT_STATUS_SERIAL_NO_DEVICE_INITED}, - {ERRDOS, 1376, NT_STATUS_NO_SUCH_ALIAS}, - {ERRDOS, 1377, NT_STATUS_MEMBER_NOT_IN_ALIAS}, - {ERRDOS, 1378, NT_STATUS_MEMBER_IN_ALIAS}, - {ERRDOS, 1379, NT_STATUS_ALIAS_EXISTS}, - {ERRDOS, 1380, NT_STATUS_LOGON_NOT_GRANTED}, - {ERRDOS, 1381, NT_STATUS_TOO_MANY_SECRETS}, - {ERRDOS, 1382, NT_STATUS_SECRET_TOO_LONG}, - {ERRDOS, 1383, NT_STATUS_INTERNAL_DB_ERROR}, - {ERRDOS, 1007, NT_STATUS_FULLSCREEN_MODE}, - {ERRDOS, 1384, NT_STATUS_TOO_MANY_CONTEXT_IDS}, - {ERRDOS, 1385, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, - {ERRDOS, 1017, NT_STATUS_NOT_REGISTRY_FILE}, - {ERRDOS, 1386, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, - {ERRDOS, 1117, NT_STATUS_FT_MISSING_MEMBER}, - {ERRDOS, 1113, NT_STATUS_UNMAPPABLE_CHARACTER}, - {ERRDOS, 1122, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, - {ERRDOS, 1123, NT_STATUS_FLOPPY_WRONG_CYLINDER}, - {ERRDOS, 1124, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, - {ERRDOS, 1125, NT_STATUS_FLOPPY_BAD_REGISTERS}, - {ERRDOS, 1126, NT_STATUS_DISK_RECALIBRATE_FAILED}, - {ERRDOS, 1127, NT_STATUS_DISK_OPERATION_FAILED}, - {ERRDOS, 1128, NT_STATUS_DISK_RESET_FAILED}, - {ERRDOS, 1119, NT_STATUS_SHARED_IRQ_BUSY}, - {ERRDOS, 1117, NT_STATUS_FT_ORPHANING}, - {ERRDOS, 1105, NT_STATUS_PARTITION_FAILURE}, - {ERRDOS, 1106, NT_STATUS_INVALID_BLOCK_LENGTH}, - {ERRDOS, 1107, NT_STATUS_DEVICE_NOT_PARTITIONED}, - {ERRDOS, 1108, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, - {ERRDOS, 1109, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, - {ERRDOS, 1129, NT_STATUS_EOM_OVERFLOW}, - {ERRDOS, 1112, NT_STATUS_NO_MEDIA}, - {ERRDOS, 1387, NT_STATUS_NO_SUCH_MEMBER}, - {ERRDOS, 1388, NT_STATUS_INVALID_MEMBER}, - {ERRDOS, 1018, NT_STATUS_KEY_DELETED}, - {ERRDOS, 1019, NT_STATUS_NO_LOG_SPACE}, - {ERRDOS, 1389, NT_STATUS_TOO_MANY_SIDS}, - {ERRDOS, 1390, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, - {ERRDOS, 1020, NT_STATUS_KEY_HAS_CHILDREN}, - {ERRDOS, 1021, NT_STATUS_CHILD_MUST_BE_VOLATILE}, - {ERRDOS, ERRbadpipe, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, - {ERRDOS, 1117, NT_STATUS_DRIVER_INTERNAL_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_CORRUPT}, + {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_IO_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_EVENT_PAIR}, + {ERRHRD, ERRgeneral, NT_STATUS_UNRECOGNIZED_VOLUME}, + {ERRHRD, ERRgeneral, NT_STATUS_SERIAL_NO_DEVICE_INITED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_ALIAS}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_NOT_IN_ALIAS}, + {ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_ALIAS}, + {ERRHRD, ERRgeneral, NT_STATUS_ALIAS_EXISTS}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGON_NOT_GRANTED}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SECRETS}, + {ERRHRD, ERRgeneral, NT_STATUS_SECRET_TOO_LONG}, + {ERRHRD, ERRgeneral, NT_STATUS_INTERNAL_DB_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_FULLSCREEN_MODE}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_CONTEXT_IDS}, + {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_TYPE_NOT_GRANTED}, + {ERRHRD, ERRgeneral, NT_STATUS_NOT_REGISTRY_FILE}, + {ERRHRD, ERRgeneral, NT_STATUS_NT_CROSS_ENCRYPTION_REQUIRED}, + {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CTRLR_CONFIG_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_FT_MISSING_MEMBER}, + {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_SERVICE_ENTRY}, + {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_CHARACTER}, + {ERRHRD, ERRgeneral, NT_STATUS_UNMAPPABLE_CHARACTER}, + {ERRHRD, ERRgeneral, NT_STATUS_UNDEFINED_CHARACTER}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_VOLUME}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_ID_MARK_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_WRONG_CYLINDER}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_UNKNOWN_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_FLOPPY_BAD_REGISTERS}, + {ERRHRD, ERRgeneral, NT_STATUS_DISK_RECALIBRATE_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_DISK_OPERATION_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_DISK_RESET_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_SHARED_IRQ_BUSY}, + {ERRHRD, ERRgeneral, NT_STATUS_FT_ORPHANING}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000016e)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000016f)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc0000170)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc0000171)}, + {ERRHRD, ERRgeneral, NT_STATUS_PARTITION_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BLOCK_LENGTH}, + {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_NOT_PARTITIONED}, + {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_LOCK_MEDIA}, + {ERRHRD, ERRgeneral, NT_STATUS_UNABLE_TO_UNLOAD_MEDIA}, + {ERRHRD, ERRgeneral, NT_STATUS_EOM_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_MEDIA}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc0000179)}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_MEMBER}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_MEMBER}, + {ERRHRD, ERRgeneral, NT_STATUS_KEY_DELETED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_LOG_SPACE}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_SIDS}, + {ERRHRD, ERRgeneral, NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED}, + {ERRHRD, ERRgeneral, NT_STATUS_KEY_HAS_CHILDREN}, + {ERRHRD, ERRgeneral, NT_STATUS_CHILD_MUST_BE_VOLATILE}, + {ERRDOS, 87, NT_STATUS_DEVICE_CONFIGURATION_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_INTERNAL_ERROR}, {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, - {ERRDOS, 1117, NT_STATUS_IO_DEVICE_ERROR}, - {ERRDOS, 1117, NT_STATUS_DEVICE_PROTOCOL_ERROR}, - {ERRDOS, 1502, NT_STATUS_LOG_FILE_FULL}, + {ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_PROTOCOL_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_BACKUP_CONTROLLER}, + {ERRHRD, ERRgeneral, NT_STATUS_LOG_FILE_FULL}, {ERRDOS, 19, NT_STATUS_TOO_LATE}, - {ERRDOS, 1786, NT_STATUS_NO_TRUST_LSA_SECRET}, - {ERRDOS, 1787, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, - {ERRDOS, 1788, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, - {ERRDOS, 1789, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, - {ERRDOS, 1500, NT_STATUS_EVENTLOG_FILE_CORRUPT}, - {ERRDOS, 1501, NT_STATUS_EVENTLOG_CANT_START}, - {ERRDOS, 1790, NT_STATUS_TRUST_FAILURE}, - {ERRDOS, 1792, NT_STATUS_NETLOGON_NOT_STARTED}, + {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_LSA_SECRET}, +/* { This NT error code was 'sqashed' + from NT_STATUS_NO_TRUST_SAM_ACCOUNT to NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE + during the session setup } +*/ + {ERRDOS, ERRnoaccess, NT_STATUS_NO_TRUST_SAM_ACCOUNT}, + {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_DOMAIN_FAILURE}, + {ERRDOS, ERRnoaccess, NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CORRUPT}, + {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_CANT_START}, + {ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, + {ERRDOS, ERRinvgroup, NT_STATUS_NETLOGON_NOT_STARTED}, {ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, - {ERRDOS, 1131, NT_STATUS_POSSIBLE_DEADLOCK}, - {ERRDOS, 1219, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, - {ERRDOS, 1220, NT_STATUS_REMOTE_SESSION_LIMIT}, - {ERRDOS, 1503, NT_STATUS_EVENTLOG_FILE_CHANGED}, - {ERRDOS, 1807, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, - {ERRDOS, 1808, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, - {ERRDOS, 1809, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, - {ERRDOS, 1810, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, - {ERRDOS, 1394, NT_STATUS_NO_USER_SESSION_KEY}, + {ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, + {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, + {ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, + {ERRHRD, ERRgeneral, NT_STATUS_EVENTLOG_FILE_CHANGED}, + {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT}, + {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT}, + {ERRDOS, ERRnoaccess, NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT}, +/* { This NT error code was 'sqashed' + from NT_STATUS_DOMAIN_TRUST_INCONSISTENT to NT_STATUS_LOGON_FAILURE + during the session setup } +*/ + {ERRDOS, ERRnoaccess, NT_STATUS_DOMAIN_TRUST_INCONSISTENT}, + {ERRHRD, ERRgeneral, NT_STATUS_FS_DRIVER_REQUIRED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_USER_SESSION_KEY}, {ERRDOS, 59, NT_STATUS_USER_SESSION_DELETED}, - {ERRDOS, 1815, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, - {ERRDOS, 1130, NT_STATUS_INSUFF_SERVER_RESOURCES}, - {ERRDOS, 1784, NT_STATUS_INVALID_BUFFER_SIZE}, - {ERRDOS, 1214, NT_STATUS_INVALID_ADDRESS_COMPONENT}, - {ERRDOS, 1214, NT_STATUS_INVALID_ADDRESS_WILDCARD}, + {ERRHRD, ERRgeneral, NT_STATUS_RESOURCE_LANG_NOT_FOUND}, + {ERRDOS, ERRnomem, NT_STATUS_INSUFF_SERVER_RESOURCES}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_BUFFER_SIZE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_COMPONENT}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_ADDRESS_WILDCARD}, {ERRDOS, 68, NT_STATUS_TOO_MANY_ADDRESSES}, {ERRDOS, 52, NT_STATUS_ADDRESS_ALREADY_EXISTS}, - {ERRSRV, ERRinvnid, NT_STATUS_ADDRESS_CLOSED}, - {ERRSRV, ERRinvnid, NT_STATUS_CONNECTION_DISCONNECTED}, - {ERRSRV, ERRinvnid, NT_STATUS_CONNECTION_RESET}, + {ERRDOS, 64, NT_STATUS_ADDRESS_CLOSED}, + {ERRDOS, 64, NT_STATUS_CONNECTION_DISCONNECTED}, + {ERRDOS, 64, NT_STATUS_CONNECTION_RESET}, {ERRDOS, 68, NT_STATUS_TOO_MANY_NODES}, {ERRDOS, 59, NT_STATUS_TRANSACTION_ABORTED}, {ERRDOS, 59, NT_STATUS_TRANSACTION_TIMED_OUT}, @@ -405,162 +494,96 @@ static struct { {ERRDOS, 59, NT_STATUS_TRANSACTION_INVALID_TYPE}, {ERRDOS, ERRunsup, NT_STATUS_NOT_SERVER_SESSION}, {ERRDOS, ERRunsup, NT_STATUS_NOT_CLIENT_SESSION}, - {ERRDOS, 6118, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, - {ERRDOS, 1132, NT_STATUS_MAPPED_ALIGNMENT}, + {ERRHRD, ERRgeneral, NT_STATUS_CANNOT_LOAD_REGISTRY_FILE}, + {ERRHRD, ERRgeneral, NT_STATUS_DEBUG_ATTACH_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_SYSTEM_PROCESS_TERMINATED}, + {ERRHRD, ERRgeneral, NT_STATUS_DATA_NOT_ACCEPTED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_BROWSER_SERVERS_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_VDM_HARD_ERROR}, + {ERRHRD, ERRgeneral, NT_STATUS_DRIVER_CANCEL_TIMEOUT}, + {ERRHRD, ERRgeneral, NT_STATUS_REPLY_MESSAGE_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS_MAPPED_ALIGNMENT}, {ERRDOS, 193, NT_STATUS_IMAGE_CHECKSUM_MISMATCH}, + {ERRHRD, ERRgeneral, NT_STATUS_LOST_WRITEBEHIND_DATA}, + {ERRHRD, ERRgeneral, NT_STATUS_CLIENT_SERVER_PARAMETERS_INVALID}, {ERRSRV, 2242, NT_STATUS_PASSWORD_MUST_CHANGE}, - {ERRDOS, 1168, NT_STATUS_NOT_FOUND}, - {ERRDOS, 554, NT_STATUS_DUPLICATE_OBJECTID}, - {ERRDOS, 555, NT_STATUS_OBJECTID_EXISTS}, - {ERRDOS, 1237, NT_STATUS_RETRY}, - {ERRDOS, 1170, NT_STATUS_PROPSET_NOT_FOUND}, - {ERRDOS, 1908, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_NOT_TINY_STREAM}, + {ERRHRD, ERRgeneral, NT_STATUS_RECOVERY_FAILURE}, + {ERRHRD, ERRgeneral, NT_STATUS_STACK_OVERFLOW_READ}, + {ERRHRD, ERRgeneral, NT_STATUS_FAIL_CHECK}, + {ERRHRD, ERRgeneral, NT_STATUS_DUPLICATE_OBJECTID}, + {ERRHRD, ERRgeneral, NT_STATUS_OBJECTID_EXISTS}, + {ERRHRD, ERRgeneral, NT_STATUS_CONVERT_TO_LARGE}, + {ERRHRD, ERRgeneral, NT_STATUS_RETRY}, + {ERRHRD, ERRgeneral, NT_STATUS_FOUND_OUT_OF_SCOPE}, + {ERRHRD, ERRgeneral, NT_STATUS_ALLOCATE_BUCKET}, + {ERRHRD, ERRgeneral, NT_STATUS_PROPSET_NOT_FOUND}, + {ERRHRD, ERRgeneral, NT_STATUS_MARSHALL_OVERFLOW}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_VARIANT}, + {ERRHRD, ERRgeneral, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND}, {ERRDOS, ERRnoaccess, NT_STATUS_ACCOUNT_LOCKED_OUT}, {ERRDOS, ERRbadfid, NT_STATUS_HANDLE_NOT_CLOSABLE}, - {ERRDOS, 1225, NT_STATUS_CONNECTION_REFUSED}, - {ERRDOS, 1226, NT_STATUS_GRACEFUL_DISCONNECT}, - {ERRDOS, 1227, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, - {ERRDOS, 1228, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, - {ERRDOS, 1229, NT_STATUS_CONNECTION_INVALID}, - {ERRDOS, 1230, NT_STATUS_CONNECTION_ACTIVE}, - {ERRDOS, 1231, NT_STATUS_NETWORK_UNREACHABLE}, - {ERRDOS, 1232, NT_STATUS_HOST_UNREACHABLE}, - {ERRDOS, 1233, NT_STATUS_PROTOCOL_UNREACHABLE}, - {ERRDOS, 1234, NT_STATUS_PORT_UNREACHABLE}, - {ERRDOS, 1235, NT_STATUS_REQUEST_ABORTED}, - {ERRDOS, 1236, NT_STATUS_CONNECTION_ABORTED}, - {ERRDOS, 1224, NT_STATUS_USER_MAPPED_FILE}, - {ERRDOS, 1238, NT_STATUS_CONNECTION_COUNT_LIMIT}, - {ERRDOS, 1239, NT_STATUS_LOGIN_TIME_RESTRICTION}, - {ERRDOS, 1240, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_REFUSED}, + {ERRHRD, ERRgeneral, NT_STATUS_GRACEFUL_DISCONNECT}, + {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_ALREADY_ASSOCIATED}, + {ERRHRD, ERRgeneral, NT_STATUS_ADDRESS_NOT_ASSOCIATED}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_INVALID}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ACTIVE}, + {ERRHRD, ERRgeneral, NT_STATUS_NETWORK_UNREACHABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_HOST_UNREACHABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_PROTOCOL_UNREACHABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_PORT_UNREACHABLE}, + {ERRHRD, ERRgeneral, NT_STATUS_REQUEST_ABORTED}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_ABORTED}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_COMPRESSION_BUFFER}, + {ERRHRD, ERRgeneral, NT_STATUS_USER_MAPPED_FILE}, + {ERRHRD, ERRgeneral, NT_STATUS_AUDIT_FAILED}, + {ERRHRD, ERRgeneral, NT_STATUS_TIMER_RESOLUTION_NOT_SET}, + {ERRHRD, ERRgeneral, NT_STATUS_CONNECTION_COUNT_LIMIT}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_TIME_RESTRICTION}, + {ERRHRD, ERRgeneral, NT_STATUS_LOGIN_WKSTA_RESTRICTION}, {ERRDOS, 193, NT_STATUS_IMAGE_MP_UP_MISMATCH}, - {ERRDOS, 1359, NT_STATUS_LPC_REPLY_LOST}, - {ERRDOS, 1232, NT_STATUS_PATH_NOT_COVERED}, - {ERRDOS, 1395, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, - {ERRDOS, 1058, NT_STATUS_PLUGPLAY_NO_DEVICE}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024a)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024b)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024c)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024d)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024e)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000024f)}, + {ERRHRD, ERRgeneral, NT_STATUS_INSUFFICIENT_LOGON_INFO}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_DLL_ENTRYPOINT}, + {ERRHRD, ERRgeneral, NT_STATUS_BAD_SERVICE_ENTRYPOINT}, + {ERRHRD, ERRgeneral, NT_STATUS_LPC_REPLY_LOST}, + {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT1}, + {ERRHRD, ERRgeneral, NT_STATUS_IP_ADDRESS_CONFLICT2}, + {ERRHRD, ERRgeneral, NT_STATUS_REGISTRY_QUOTA_LIMIT}, + {ERRSRV, ERRbadtype, NT_STATUS_PATH_NOT_COVERED}, + {ERRHRD, ERRgeneral, NT_STATUS_NO_CALLBACK_ACTIVE}, + {ERRHRD, ERRgeneral, NT_STATUS_LICENSE_QUOTA_EXCEEDED}, + {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_SHORT}, + {ERRHRD, ERRgeneral, NT_STATUS_PWD_TOO_RECENT}, + {ERRHRD, ERRgeneral, NT_STATUS_PWD_HISTORY_CONFLICT}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000025d)}, + {ERRHRD, ERRgeneral, NT_STATUS_PLUGPLAY_NO_DEVICE}, + {ERRHRD, ERRgeneral, NT_STATUS_UNSUPPORTED_COMPRESSION}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_HW_PROFILE}, + {ERRHRD, ERRgeneral, NT_STATUS_INVALID_PLUGPLAY_DEVICE_PATH}, {ERRDOS, 182, NT_STATUS_DRIVER_ORDINAL_NOT_FOUND}, {ERRDOS, 127, NT_STATUS_DRIVER_ENTRYPOINT_NOT_FOUND}, {ERRDOS, 288, NT_STATUS_RESOURCE_NOT_OWNED}, - {ERRDOS, 1142, NT_STATUS_TOO_MANY_LINKS}, - {ERRDOS, 4350, NT_STATUS_FILE_IS_OFFLINE}, - {ERRDOS, 2001, NT_STATUS(0xc000026c)}, - {ERRDOS, 1201, NT_STATUS(0xc000026d)}, + {ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LINKS}, + {ERRHRD, ERRgeneral, NT_STATUS_QUOTA_LIST_INCONSISTENT}, + {ERRHRD, ERRgeneral, NT_STATUS_FILE_IS_OFFLINE}, {ERRDOS, 21, NT_STATUS(0xc000026e)}, - {ERRDOS, 1169, NT_STATUS(0xc0000272)}, - {ERRDOS, 4390, NT_STATUS(0xc0000275)}, - {ERRDOS, 4393, NT_STATUS(0xc0000276)}, - {ERRDOS, 4394, NT_STATUS(0xc0000277)}, - {ERRDOS, 4392, NT_STATUS(0xc0000278)}, - {ERRDOS, 1920, NT_STATUS(0xc0000279)}, - {ERRDOS, 1921, NT_STATUS(0xc0000280)}, {ERRDOS, 161, NT_STATUS(0xc0000281)}, - {ERRDOS, 1160, NT_STATUS(0xc0000283)}, - {ERRDOS, 1161, NT_STATUS(0xc0000284)}, - {ERRDOS, 1162, NT_STATUS(0xc0000285)}, - {ERRDOS, 1163, NT_STATUS(0xc0000286)}, - {ERRDOS, 1164, NT_STATUS(0xc0000287)}, - {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028a)}, - {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028b)}, - {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028d)}, - {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028e)}, - {ERRDOS, ERRbadaccess, NT_STATUS(0xc000028f)}, - {ERRDOS, ERRbadaccess, NT_STATUS(0xc0000290)}, - {ERRDOS, 6007, NT_STATUS(0xc0000291)}, - {ERRDOS, 6008, NT_STATUS(0xc0000292)}, - {ERRDOS, 6002, NT_STATUS(0xc0000293)}, - {ERRDOS, 4200, NT_STATUS(0xc0000295)}, - {ERRDOS, 4201, NT_STATUS(0xc0000296)}, - {ERRDOS, 4202, NT_STATUS(0xc0000297)}, - {ERRDOS, 4203, NT_STATUS(0xc0000298)}, - {ERRDOS, 8218, NT_STATUS(0xc0000299)}, - {ERRDOS, 8219, NT_STATUS(0xc000029a)}, - {ERRDOS, 8220, NT_STATUS(0xc000029b)}, - {ERRSRV, ERRsmbcmd, NT_STATUS(0xc000029c)}, - {ERRDOS, 4351, NT_STATUS(0xc000029d)}, - {ERRDOS, 4352, NT_STATUS(0xc000029e)}, - {ERRDOS, 1172, NT_STATUS(0xc000029f)}, - {ERRDOS, 8202, NT_STATUS(0xc00002a1)}, - {ERRDOS, 8203, NT_STATUS(0xc00002a2)}, - {ERRDOS, 8204, NT_STATUS(0xc00002a3)}, - {ERRDOS, 8205, NT_STATUS(0xc00002a4)}, - {ERRDOS, 8206, NT_STATUS(0xc00002a5)}, - {ERRDOS, 8207, NT_STATUS(0xc00002a6)}, - {ERRDOS, 8208, NT_STATUS(0xc00002a7)}, - {ERRDOS, 8209, NT_STATUS(0xc00002a8)}, - {ERRDOS, 8210, NT_STATUS(0xc00002a9)}, - {ERRDOS, 8211, NT_STATUS(0xc00002aa)}, - {ERRDOS, 8212, NT_STATUS(0xc00002ab)}, - {ERRDOS, 8213, NT_STATUS(0xc00002ac)}, - {ERRDOS, 8214, NT_STATUS(0xc00002ad)}, - {ERRDOS, 8215, NT_STATUS(0xc00002ae)}, - {ERRDOS, 8216, NT_STATUS(0xc00002af)}, - {ERRDOS, 8217, NT_STATUS(0xc00002b0)}, - {ERRDOS, 8478, NT_STATUS(0xc00002b1)}, - {ERRDOS, 4391, NT_STATUS(0xc00002b2)}, - {ERRDOS, 1617, NT_STATUS(0xc00002b6)}, - {ERRDOS, 1178, NT_STATUS(0xc00002b7)}, - {ERRDOS, 1179, NT_STATUS(0xc00002b8)}, - {ERRDOS, 8228, NT_STATUS(0xc00002c1)}, - {ERRDOS, 1397, NT_STATUS(0xc00002c3)}, - {ERRDOS, 998, NT_STATUS(0xc00002c5)}, - {ERRDOS, 4213, NT_STATUS(0xc00002c6)}, - {ERRDOS, 4214, NT_STATUS(0xc00002c7)}, - {ERRDOS, 4328, NT_STATUS(0xc00002ca)}, - {ERRDOS, 8504, NT_STATUS(0xc00002cb)}, - {ERRDOS, 1251, NT_STATUS(0xc00002cc)}, - {ERRDOS, 8505, NT_STATUS(0xc00002cd)}, - {ERRDOS, 1181, NT_STATUS(0xc00002cf)}, - {ERRDOS, 8506, NT_STATUS(0xc00002d0)}, - {ERRDOS, 8513, NT_STATUS(0xc00002d4)}, - {ERRDOS, 8514, NT_STATUS(0xc00002d5)}, - {ERRDOS, 8515, NT_STATUS(0xc00002d6)}, - {ERRDOS, 8516, NT_STATUS(0xc00002d7)}, - {ERRDOS, 8517, NT_STATUS(0xc00002d8)}, - {ERRDOS, 8518, NT_STATUS(0xc00002d9)}, - {ERRDOS, 8519, NT_STATUS(0xc00002da)}, - {ERRDOS, 8520, NT_STATUS(0xc00002db)}, - {ERRDOS, 8521, NT_STATUS(0xc00002dc)}, - {ERRDOS, ERRunsup, NT_STATUS(0xc00002dd)}, - {ERRDOS, 8529, NT_STATUS(0xc00002df)}, - {ERRDOS, 8530, NT_STATUS(0xc00002e0)}, - {ERRDOS, 8531, NT_STATUS(0xc00002e1)}, - {ERRDOS, 8532, NT_STATUS(0xc00002e2)}, - {ERRDOS, 8541, NT_STATUS(0xc00002e3)}, - {ERRDOS, 8547, NT_STATUS(0xc00002e4)}, - {ERRDOS, 8548, NT_STATUS(0xc00002e5)}, - {ERRDOS, 8549, NT_STATUS(0xc00002e6)}, - {ERRDOS, 8557, NT_STATUS(0xc00002e7)}, - {ERRDOS, 1115, NT_STATUS(0xc00002fe)}, - {ERRDOS, 1255, NT_STATUS(0xc00002ff)}, - {ERRDOS, 1254, NT_STATUS(0xc0000300)}, - {ERRDOS, ERRbadfunc, NT_STATUS(0x80000001)}, - {ERRDOS, 998, NT_STATUS(0x80000002)}, - {ERRDOS, ERRbadpath, NT_STATUS(0x80000003)}, - {ERRDOS, ERRnofids, NT_STATUS(0x80000004)}, - {ERRDOS, 234, NT_STATUS(0x80000005)}, - {ERRDOS, ERRnofiles, NT_STATUS(0x80000006)}, - {ERRDOS, 1391, NT_STATUS(0x8000000b)}, - {ERRDOS, 299, NT_STATUS(0x8000000d)}, - {ERRDOS, 28, NT_STATUS(0x8000000e)}, - {ERRDOS, 21, NT_STATUS(0x8000000f)}, - {ERRDOS, 21, NT_STATUS(0x80000010)}, - {ERRDOS, 170, NT_STATUS(0x80000011)}, - {ERRDOS, 259, NT_STATUS(0x80000012)}, - {ERRDOS, 254, NT_STATUS(0x80000013)}, - {ERRDOS, 275, NT_STATUS(0x80000014)}, - {ERRDOS, 275, NT_STATUS(0x80000015)}, - {ERRDOS, 1110, NT_STATUS(0x80000016)}, - {ERRDOS, 259, NT_STATUS_UNABLE_TO_FREE_VM}, - {ERRDOS, 1101, NT_STATUS(0x8000001b)}, - {ERRDOS, 1110, NT_STATUS(0x8000001c)}, - {ERRDOS, 1111, NT_STATUS(0x8000001d)}, - {ERRDOS, 1100, NT_STATUS(0x8000001e)}, - {ERRDOS, 1102, NT_STATUS(0x8000001f)}, - {ERRDOS, 1103, NT_STATUS(0x80000021)}, - {ERRDOS, 1104, NT_STATUS(0x80000022)}, - {ERRDOS, 2402, NT_STATUS(0x80000025)}, - {ERRDOS, 1165, NT_STATUS(0x80000288)}, - {ERRDOS, 1166, NT_STATUS(0x80000289)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028a)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028b)}, + {ERRHRD, ERRgeneral, NT_STATUS(0xc000028c)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028d)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028e)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc000028f)}, + {ERRDOS, ERRnoaccess, NT_STATUS(0xc0000290)}, + {ERRDOS, ERRbadfunc, NT_STATUS(0xc000029c)}, }; @@ -647,7 +670,7 @@ static struct { {ERRDOS, ERRpipebusy, NT_STATUS_INSTANCE_NOT_AVAILABLE}, {ERRDOS, ERRpipeclosing, NT_STATUS_PIPE_CLOSING}, {ERRDOS, ERRnotconnected, NT_STATUS_PIPE_DISCONNECTED}, - {ERRDOS, ERRmoredata, STATUS_MORE_ENTRIES}, + {ERRDOS, ERRmoredata, NT_STATUS_MORE_PROCESSING_REQUIRED}, {ERRDOS, 240, NT_STATUS_VIRTUAL_CIRCUIT_CLOSED}, {ERRDOS, 254, NT_STATUS(0x80000013)}, {ERRDOS, 255, NT_STATUS_EA_TOO_LARGE}, diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 71e609ff3a..b6e6f03740 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -51,14 +51,14 @@ err_code_struct dos_msgs[] = { {"ERRnofids",ERRnofids,"No file descriptors available"}, {"ERRnoaccess",ERRnoaccess,"Access denied."}, {"ERRbadfid",ERRbadfid,"Invalid file handle."}, - {"ERRbadmcb",7,"Memory control blocks destroyed."}, + {"ERRbadmcb",ERRbadmcb,"Memory control blocks destroyed."}, {"ERRnomem",ERRnomem,"Insufficient server memory to perform the requested function."}, {"ERRbadmem",ERRbadmem,"Invalid memory block address."}, {"ERRbadenv",ERRbadenv,"Invalid environment."}, {"ERRbadformat",11,"Invalid format."}, {"ERRbadaccess",ERRbadaccess,"Invalid open mode."}, {"ERRbaddata",ERRbaddata,"Invalid data."}, - {"ERR",ERRres,"reserved."}, + {"ERRres",ERRres,"reserved."}, {"ERRbaddrive",ERRbaddrive,"Invalid drive specified."}, {"ERRremcd",ERRremcd,"A Delete Directory request attempted to remove the server's current directory."}, {"ERRdiffdevice",ERRdiffdevice,"Not same device."}, @@ -74,7 +74,7 @@ err_code_struct dos_msgs[] = { {"ERRpipeclosing",ERRpipeclosing,"Pipe close in progress."}, {"ERRnotconnected",ERRnotconnected,"No process on other end of pipe."}, {"ERRmoredata",ERRmoredata,"There is more data to be returned."}, - {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"}, + {"ERRinvgroup",ERRinvgroup,"Invalid workgroup (try the -W option)"}, {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, {"ERRdiskfull",ERRdiskfull,"Disk full"}, {NULL,-1,NULL}}; -- cgit From f358c516185ab617902f91da558ada50709e1ebd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jan 2002 01:33:45 +0000 Subject: Add a touch of const (This used to be commit b2af4372b1dac2e8f283184191fbb0231409a625) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2c235417a8..d11b1ffd78 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1177,7 +1177,7 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... Get the IP address list of the PDC/BDC's of a Domain. *********************************************************/ -BOOL get_dc_list(BOOL pdc_only, char *group, struct in_addr **ip_list, int *count) +BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count) { int name_type = pdc_only ? 0x1B : 0x1C; -- cgit From aa045c08b26b9fad2b2f4f314b6ce2bfbefe4380 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 5 Jan 2002 04:04:03 +0000 Subject: Add a comment on how this error map was derrived. This applies only to the NT->Dos map, I'm still trying to come up with a way to do the reverse. (This used to be commit 323dd422bd4bdeeee72c9200821e28f86d3072c8) --- source3/libsmb/errormap.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 74711e01bf..b2b638b229 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -21,6 +21,28 @@ #include "includes.h" +/* This map was extracted by the ERRMAPEXTRACT smbtorture command. + The setup was a Samba HEAD (2002-01-03) PDC and an Win2k member + workstation. The PDC was modified (by using the 'name_to_nt_status' + authentication module) to convert the username (in hex) into the + corresponding NTSTATUS error return. + + By opening two nbt sessions to the Win2k workstation, one negotiating + DOS and one negotiating NT errors it was possible to extract the + error mapping. (Because the server only supplies NT errors, the + NT4 workstation had to use its own error tables to convert these + to dos errors). + + Some errors show up as 'squashed' because the NT error connection + got back a different error to the one it sent, so a mapping could + not be determined (a guess has been made in this case, to map the + error as squashed). This is done mainly to prevent users from getting + NT_STATUS_WRONG_PASSWORD and NT_STATUS_NO_SUCH_USER errors (they get + NT_STATUS_LOGON_FAILURE instead. + + -- abartlet (2002-01-03) +*/ + /* NT status -> dos error map */ static struct { uint8 dos_class; -- cgit From b0e4827b9750edd358230890fdc671f378da9626 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Jan 2002 23:30:59 +0000 Subject: simple fix for creating blank data blobs (This used to be commit 08bb2dfec2ca0282e9268d09da2b966d3bdf493a) --- source3/libsmb/clispnego.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index bc3873bf18..035b47b417 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -486,9 +486,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, va_end(ap); /* allocate the space, then scan the format again to fill in the values */ - blob->data = malloc(head_size + data_size); - blob->length = head_size + data_size; - if (!blob->data) return False; + *blob = data_blob(NULL, head_size + data_size); head_ofs = 0; data_ofs = head_size; -- cgit From cba3586456925cc6fd91a233f5c84cabb778798c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Jan 2002 23:34:06 +0000 Subject: fixed another DATA_BLOB constructor (This used to be commit c6affae4bf749a67c90468702eb6d4eeb97a4363) --- source3/libsmb/asn1.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 93e95b52bb..1175a7fe65 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -369,13 +369,8 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) int len; if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; len = asn1_tag_remaining(data); - blob->data = malloc(len); - if (!blob->data) { - data->has_error = True; - return False; - } + *blob = data_blob(NULL, len); asn1_read(data, blob->data, len); - blob->length = len; asn1_end_tag(data); return !data->has_error; } -- cgit From d1baa1fda928bfcc1998575f2af71aaa001402aa Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 6 Jan 2002 02:55:37 +0000 Subject: DOS error 31 is ERRgeneral, General Failure. This is the WERROR equivalent to NT_STATUS_UNSUCCESSFUL according to AB's funky new error map. (This used to be commit 9c968fbb017d3369ac207e65348a9a22dbed0213) --- source3/libsmb/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index b2b638b229..1c44675c83 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -49,7 +49,7 @@ static struct { uint32 dos_code; NTSTATUS ntstatus; } ntstatus_to_dos_map[] = { - {ERRDOS, 31, NT_STATUS_UNSUCCESSFUL}, + {ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {ERRDOS, 87, NT_STATUS_INVALID_INFO_CLASS}, {ERRDOS, 24, NT_STATUS_INFO_LENGTH_MISMATCH}, -- cgit From bf4c3d3659081a034110cffb2ae6bf5bd3767a22 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 6 Jan 2002 03:41:29 +0000 Subject: Added a get_dos_error_msg() function to mirror the get_nt_error_msg() One day I'll get around to refactoring the DOS error handling so it mirrors the NT error handling code. (This used to be commit f4535721d350f3068e8dfb612331eb609ea03da0) --- source3/libsmb/smberr.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index b6e6f03740..3ef4eaf989 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -77,6 +77,7 @@ err_code_struct dos_msgs[] = { {"ERRinvgroup",ERRinvgroup,"Invalid workgroup (try the -W option)"}, {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, {"ERRdiskfull",ERRdiskfull,"Disk full"}, + {"ERRgeneral",ERRgeneral, "General failure"}, {NULL,-1,NULL}}; /* Server Error Messages */ @@ -181,6 +182,16 @@ char *smb_dos_err_name(uint8 class, uint16 num) return(ret); } +/* Return a string for a DOS error */ + +char *get_dos_error_msg(WERROR result) +{ + uint16 errnum; + + errnum = W_ERROR_V(result); + + return smb_dos_err_name(ERRDOS, errnum); +} /**************************************************************************** return a SMB error class name as a string. -- cgit From 21881b9c35501b5ad7f79381a45a8712ac95703a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 6 Jan 2002 03:48:41 +0000 Subject: Minor doc cleanups. (This used to be commit 5c8f6be290e78c4e72c821abdc9f06b7150e68e7) --- source3/libsmb/cli_lsarpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 0720cadfbd..95169afd7c 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -1,6 +1,5 @@ /* Unix SMB/Netbios implementation. - Version 2.2 RPC pipe client Copyright (C) Tim Potter 2000-2001, Copyright (C) Andrew Tridgell 1992-1997,2000, @@ -25,7 +24,7 @@ #include "includes.h" -/** @defgroup lsa LSA rpc client routines +/** @defgroup lsa LSA - Local Security Architecture * @ingroup rpc_client * * @{ @@ -1137,4 +1136,5 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); cli_shutdown(&cli); return ret; } + /** @} **/ -- cgit From 009d7414d2f4dfbc681d3bcfadbe4e8fee6df62d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 6 Jan 2002 03:49:28 +0000 Subject: Define a rpc_client doc group. (This used to be commit 87bc0a71ecb0fc047fec5e0d240045fab09dd5d0) --- source3/libsmb/cli_pipe_util.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_pipe_util.c b/source3/libsmb/cli_pipe_util.c index 9521d817fa..d0028e83eb 100644 --- a/source3/libsmb/cli_pipe_util.c +++ b/source3/libsmb/cli_pipe_util.c @@ -21,6 +21,9 @@ #include "includes.h" +/** \defgroup rpc_client RPC Client routines + */ + /* Opens a SMB connection to a named pipe */ struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name, -- cgit From cd0772e51e0c5344fdeba70f8dc5b227854910df Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 6 Jan 2002 03:54:40 +0000 Subject: spoolss rpc client cleanup: - converted OpenPrinterEx and ClosePrinter to WERROR instead of NT_STATUS - doc (This used to be commit 248d114f856f1adb76c903b683e0927530771443) --- source3/libsmb/cli_spoolss.c | 116 ++++++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 56 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index e6a6bf5258..ceb82ef3ec 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1,13 +1,12 @@ /* Unix SMB/Netbios implementation. - Version 2.2 RPC pipe client Copyright (C) Gerald Carter 2001, - Copyright (C) Tim Potter 2000, - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Jean-Francois Micouleau 1999-2000 + Copyright (C) Tim Potter 2000-2001, + Copyright (C) Andrew Tridgell 1994-2000, + Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + Copyright (C) Jean-Francois Micouleau 1999-2000. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,33 +25,43 @@ #include "includes.h" -extern pstring global_myname; +/** @defgroup spoolss SPOOLSS - NT printing routines + * @ingroup rpc_client + * + * @{ + **/ + +/** Return a handle to the specified printer or print server. + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param printername The name of the printer or print server to be + * opened in UNC format. + * + * @param datatype Specifies the default data type for the printer. + * + * @param access_required The access rights requested on the printer or + * print server. + * + * @param station The UNC name of the requesting workstation. + * + * @param username The name of the user requesting the open. + * + * @param pol Returned policy handle. + */ -/* Opens a SMB connection to the SPOOLSS pipe */ -struct cli_state *cli_spoolss_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds); -} - -/* Open printer ex */ - -NTSTATUS cli_spoolss_open_printer_ex( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - char *printername, - char *datatype, - uint32 access_required, - char *station, - char *username, - POLICY_HND *pol -) +WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *printername, char *datatype, + uint32 access_required, char *station, + char *username, POLICY_HND *pol) { prs_struct qbuf, rbuf; SPOOL_Q_OPEN_PRINTER_EX q; SPOOL_R_OPEN_PRINTER_EX r; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -70,26 +79,20 @@ NTSTATUS cli_spoolss_open_printer_ex( /* Marshall data and send request */ if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; + !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ - if (W_ERROR_IS_OK(r.status)) { - result = NT_STATUS_OK; + result = r.status; + + if (W_ERROR_IS_OK(result)) *pol = r.handle; - } else { - result = werror_to_ntstatus(r.status); - } done: prs_mem_free(&qbuf); @@ -98,18 +101,23 @@ NTSTATUS cli_spoolss_open_printer_ex( return result; } -/* Close a printer handle */ +/** Close a printer handle + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param pol Policy handle of printer or print server to close. + */ -NTSTATUS cli_spoolss_close_printer( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol -) +WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) { prs_struct qbuf, rbuf; SPOOL_Q_CLOSEPRINTER q; SPOOL_R_CLOSEPRINTER r; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -126,26 +134,20 @@ NTSTATUS cli_spoolss_close_printer( /* Marshall data and send request */ if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; + !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ - if (W_ERROR_IS_OK(r.status)) { + result = r.status; + + if (W_ERROR_IS_OK(result)) *pol = r.handle; - result = NT_STATUS_OK; - } else { - result = werror_to_ntstatus(r.status); - } done: prs_mem_free(&qbuf); @@ -1134,3 +1136,5 @@ NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli, return result; } + +/** @} **/ -- cgit From 969d82ef25a7ae13cc1c7ba2a4f2f920e37b41be Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 6 Jan 2002 04:03:26 +0000 Subject: Check for winbind separator in user name for cli_session_setup() Patch from Alexander Bokovoy (This used to be commit 6c42bf208976ed3020e57efff6281f984d9fe893) --- source3/libsmb/cliconnect.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index bd79f23213..a3b22485cf 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -576,7 +576,8 @@ BOOL cli_session_setup(struct cli_state *cli, /* allow for workgroups as part of the username */ fstrcpy(user2, user); - if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/'))) { + if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) || + (p=strchr_m(user2,*lp_winbind_separator()))) { *p = 0; user = p+1; workgroup = user2; -- cgit From b77eec91dc6b6df63dcff57fe465f0b4eb73d7a1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 6 Jan 2002 09:02:14 +0000 Subject: Converted enumprinters and enumports cli functions to return WERRORs. Make the offered and needed buffer size into parameters. (This used to be commit 9d9e7fb74d420913cda1c592765b498fd64384f0) --- source3/libsmb/cli_spoolss.c | 235 ++++++++++++++++++++++++------------------- 1 file changed, 129 insertions(+), 106 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index ceb82ef3ec..e1f624053c 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -385,24 +385,35 @@ static void decode_printerdriverdir_1 ( *info=inf; } +/** Enumerate printers on a print server. + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param offered Buffer size offered in the request. + * @param needed Number of bytes needed to complete the request. + * may be NULL. + * + * @param flags Selected from PRINTER_ENUM_* flags. + * @param level Request information level. + * + * @param num_printers Pointer to number of printers returned. May be + * NULL. + * @param ctr Return structure for printer information. May + * be NULL. + */ -/* Enumerate printers */ - -NTSTATUS cli_spoolss_enum_printers( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 flags, - uint32 level, - int *returned, - PRINTER_INFO_CTR *ctr -) +WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + uint32 flags, uint32 level, + uint32 *num_printers, PRINTER_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMPRINTERS q; SPOOL_R_ENUMPRINTERS r; NEW_BUFFER buffer; - uint32 needed = 100; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); @@ -411,79 +422,90 @@ NTSTATUS cli_spoolss_enum_printers( fstrcpy (server, cli->desthost); strupper (server); - do { - /* Initialise input parameters */ + /* Initialise input parameters */ - init_buffer(&buffer, needed, mem_ctx); + init_buffer(&buffer, offered, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, - needed); + make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, + offered); - /* Marshall data and send request */ + /* Marshall data and send request */ + + if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf)) + goto done; - if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + /* Unmarshall response */ - /* Unmarshall response */ - if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { - needed = r.needed; - } - - /* Return output parameters */ - if (!W_ERROR_IS_OK(r.status)) { - result = werror_to_ntstatus(r.status); - goto done; - } + if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { + if (needed) + *needed = r.needed; + } + + result = r.status; - result = NT_STATUS_OK; + /* Return output parameters */ - if ((*returned = r.returned)) { - switch (level) { - case 1: - decode_printer_info_1(mem_ctx, r.buffer, r.returned, - &ctr->printers_1); - break; - case 2: - decode_printer_info_2(mem_ctx, r.buffer, r.returned, - &ctr->printers_2); - break; - case 3: - decode_printer_info_3(mem_ctx, r.buffer, r.returned, - &ctr->printers_3); - break; - } - } + if (!W_ERROR_IS_OK(r.status)) + goto done; - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); + if (num_printers) + *num_printers = r.returned; - } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); + if (!ctr) + goto done; + + switch (level) { + case 1: + decode_printer_info_1(mem_ctx, r.buffer, r.returned, + &ctr->printers_1); + break; + case 2: + decode_printer_info_2(mem_ctx, r.buffer, r.returned, + &ctr->printers_2); + break; + case 3: + decode_printer_info_3(mem_ctx, r.buffer, r.returned, + &ctr->printers_3); + break; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return result; } -/* Enumerate printer ports */ -NTSTATUS cli_spoolss_enum_ports( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 level, - int *returned, - PORT_INFO_CTR *ctr -) +/** Enumerate printer ports on a print server. + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param offered Buffer size offered in the request. + * @param needed Number of bytes needed to complete the request. + * May be NULL. + * + * @param level Requested information level. + * + * @param num_ports Pointer to number of ports returned. May be NULL. + * @param ctr Pointer to structure holding port information. + * May be NULL. + */ + +WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + uint32 level, int *num_ports, PORT_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMPORTS q; SPOOL_R_ENUMPORTS r; NEW_BUFFER buffer; - uint32 needed = 100; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); @@ -492,55 +514,56 @@ NTSTATUS cli_spoolss_enum_ports( slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - do { - /* Initialise input parameters */ - - init_buffer(&buffer, needed, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_enumports(&q, server, level, &buffer, needed); + /* Initialise input parameters */ + + init_buffer(&buffer, offered, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + make_spoolss_q_enumports(&q, server, level, &buffer, offered); + + /* Marshall data and send request */ - /* Marshall data and send request */ + if (!spoolss_io_q_enumports("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf)) + goto done; - if (!spoolss_io_q_enumports("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + /* Unmarshall response */ - /* Unmarshall response */ - if (spoolss_io_r_enumports("", &r, &rbuf, 0)) { - needed = r.needed; - } + if (spoolss_io_r_enumports("", &r, &rbuf, 0)) { + if (needed) + *needed = r.needed; + } - /* Return output parameters */ - result = werror_to_ntstatus(r.status); - - if (NT_STATUS_IS_OK(result) && - r.returned > 0) { + result = r.status; - *returned = r.returned; + /* Return output parameters */ - switch (level) { - case 1: - decode_port_info_1(mem_ctx, r.buffer, r.returned, - &ctr->port.info_1); - break; - case 2: - decode_port_info_2(mem_ctx, r.buffer, r.returned, - &ctr->port.info_2); - break; - } - } + if (!W_ERROR_IS_OK(result)) + goto done; - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); + if (num_ports) + *num_ports = r.returned; - } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); + if (!ctr) + goto done; + + switch (level) { + case 1: + decode_port_info_1(mem_ctx, r.buffer, r.returned, + &ctr->port.info_1); + break; + case 2: + decode_port_info_2(mem_ctx, r.buffer, r.returned, + &ctr->port.info_2); + break; + } + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } -- cgit From 9a02c6b4e8dcdd8bb6f2d394b1c5e9110c11a7a9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 7 Jan 2002 03:33:46 +0000 Subject: Converted getprinterdriver to WERROR - it always returns dos error 6 (invalid handle) though. )-: (This used to be commit 7bfd1f35e4e194f8a2f07046e4a6c005c256c05b) --- source3/libsmb/cli_spoolss.c | 118 +++++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 54 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index e1f624053c..b828640c3b 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -687,24 +687,36 @@ done: return result; } -/********************************************************************** - * Get installed printer drivers for a given printer +/** Get installed printer drivers for a given printer + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param offered Buffer size offered in the request. + * @param needed Number of bytes needed to complete the request. + * may be NULL. + * + * @param pol Pointer to an open policy handle for the printer + * opened with cli_spoolss_open_printer_ex(). + * @param level Requested information level. + * @param env The print environment or archictecture. This is + * "Windows NT x86" for NT4. + * @param ctr Returned printer driver information. */ -NTSTATUS cli_spoolss_getprinterdriver ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint32 level, - char* env, - PRINTER_DRIVER_CTR *ctr -) + +WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *pol, uint32 level, + char *env, PRINTER_DRIVER_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTERDRIVER2 q; SPOOL_R_GETPRINTERDRIVER2 r; NEW_BUFFER buffer; - uint32 needed = 1024; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); @@ -713,57 +725,55 @@ NTSTATUS cli_spoolss_getprinterdriver ( fstrcpy (server, cli->desthost); strupper (server); - do - { - /* Initialise input parameters */ + /* Initialise input parameters */ - init_buffer(&buffer, needed, mem_ctx); + init_buffer(&buffer, offered, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2, + &buffer, offered); - /* write the request */ - make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2, &buffer, needed); + /* Marshall data and send request */ - /* Marshall data and send request */ - if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf)) - { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf)) + goto done; - /* Unmarshall response */ - if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) - { - needed = r.needed; - } - - /* Return output parameters */ - result = werror_to_ntstatus(r.status); - if (NT_STATUS_IS_OK(result)) - { - switch (level) - { - case 1: - decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1); - break; - case 2: - decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2); - break; - case 3: - decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); - break; - } - } + /* Unmarshall response */ - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); + if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) { + if (needed) + *needed = r.needed; + } - } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); + result = r.status; + + /* Return output parameters */ + + if (!W_ERROR_IS_OK(result)) + goto done; + + if (!ctr) + goto done; + + switch (level) { + case 1: + decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1); + break; + case 2: + decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2); + break; + case 3: + decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); + break; + } + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; } -- cgit From d42fc03e9ba137a5af4982ae6c7f2d0392cee9dc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 9 Jan 2002 04:26:41 +0000 Subject: Merge from appliance-head: - put in some level 10 debugs so we can see what internal_resolve_name() is doing - remove duplicates from returned ip list of internal_resolve_name() (This used to be commit 08d2bcef1a4fc77d28bc0fa9e4ff5f3131cedea5) --- source3/libsmb/namequery.c | 76 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index d11b1ffd78..6bf34c730c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -822,9 +822,15 @@ static BOOL internal_resolve_name(const char *name, int name_type, BOOL allones = (strcmp(name,"255.255.255.255") == 0); BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); BOOL is_address = is_ipaddress(name); + BOOL result = False; + struct in_addr *nodupes_iplist; + int i; + *return_iplist = NULL; *return_count = 0; + DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); + if (allzeros || allones || is_address) { *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); if(*return_iplist == NULL) { @@ -849,29 +855,91 @@ static BOOL internal_resolve_name(const char *name, int name_type, while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) { - return True; + result = True; + goto done; } } else if(strequal( tok, "lmhosts")) { if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { - return True; + result = True; + goto done; } } else if(strequal( tok, "wins")) { /* don't resolve 1D via WINS */ if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) { - return True; + result = True; + goto done; } } else if(strequal( tok, "bcast")) { if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { - return True; + result = True; + goto done; } } else { DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); } } + /* All of the resolve_* functions above have returned false. */ + SAFE_FREE(*return_iplist); + *return_count = 0; + return False; + + done: + + /* Remove duplicate entries. Some queries, notably #1c (domain + controllers) return the PDC in iplist[0] and then all domain + controllers including the PDC in iplist[1..n]. Iterating over + the iplist when the PDC is down will cause two sets of timeouts. */ + + if ((nodupes_iplist = (struct in_addr *) + malloc(sizeof(struct in_addr) * (*return_count)))) { + int nodupes_count = 0; + + /* Iterate over return_iplist looking for duplicates */ + + for (i = 0; i < *return_count; i++) { + BOOL is_dupe = False; + int j; + + for (j = i + 1; j < *return_count; j++) { + if (ip_equal((*return_iplist)[i], + (*return_iplist)[j])) { + is_dupe = True; + break; + } + } + + if (!is_dupe) { + + /* This one not a duplicate */ + + nodupes_iplist[nodupes_count] = (*return_iplist)[i]; + nodupes_count++; + } + } + + /* Switcheroo with original list */ + + free(*return_iplist); + + *return_iplist = nodupes_iplist; + *return_count = nodupes_count; + } + + /* Display some debugging info */ + + DEBUG(10, ("internal_resolve_name: returning %d addresses: ", + *return_count)); + + for (i = 0; i < *return_count; i++) + DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i]))); + + DEBUG(10, ("\n")); + + return result; } /******************************************************** -- cgit From 3fb5e2867c947de65d0c75a2ea1b9be46bbc5346 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Jan 2002 00:23:29 +0000 Subject: make sure resolve_name() only returns valid IP addresses this is actually a workaround for old broken nmbd daemons, especially from Samba 2.0 (This used to be commit 12021a8de6a1dc2e43cc62f094a57c57283dfaf4) --- source3/libsmb/namequery.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6bf34c730c..d7e0af11df 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -954,10 +954,19 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) struct in_addr *ip_list = NULL; int count = 0; - if(internal_resolve_name(name, name_type, &ip_list, &count)) { - *return_ip = ip_list[0]; - SAFE_FREE(ip_list); - return True; + if (internal_resolve_name(name, name_type, &ip_list, &count)) { + int i; + /* only return valid addresses for TCP connections */ + for (i=0; i Date: Fri, 11 Jan 2002 04:50:45 +0000 Subject: Fix up 'net ads join' to delete and rejoin if the account already exists. This fixes up a problem where a machine would join (or downgrade by trust password change) to NT4 membership and not be able to regain full ADS membership until a 'net ads leave'. Andrew Bartlett (This used to be commit ab8ff85f03b25a0dfe4ab63886a10da81207393c) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a3b22485cf..7649a88ffd 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1257,7 +1257,7 @@ again: if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); - nt_status = cli_nt_error(cli); + nt_status = NT_STATUS_UNSUCCESSFUL; cli_shutdown(cli); return nt_status; } -- cgit From 034a855d73471c4c94ee71ea7644c6e3e02b8b74 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Jan 2002 09:48:27 +0000 Subject: cope with direct IP addresses in resolve_name() (This used to be commit 73a59170e6fab3b0f91938a74302750915a04a7a) --- source3/libsmb/namequery.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index d7e0af11df..e410363de8 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -954,6 +954,11 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) struct in_addr *ip_list = NULL; int count = 0; + if (is_ipaddress(name)) { + *return_ip = *interpret_addr2(name); + return True; + } + if (internal_resolve_name(name, name_type, &ip_list, &count)) { int i; /* only return valid addresses for TCP connections */ -- cgit From 27655be3c1708d447b046a2b0d8b2013eeb21835 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 11 Jan 2002 13:14:28 +0000 Subject: fixed a crash bug in domain auth caused by an uninitialised nt_status (This used to be commit 0b0b937b58f4bf4e005fb622f0db19175fc46a47) --- source3/libsmb/cliconnect.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7649a88ffd..1812416426 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1270,6 +1270,7 @@ again: DEBUG(1,("failed session setup\n")); nt_status = cli_nt_error(cli); cli_shutdown(cli); + if (NT_STATUS_IS_OK(nt_status)) nt_status = NT_STATUS_UNSUCCESSFUL; return nt_status; } @@ -1281,6 +1282,7 @@ again: DEBUG(1,("failed tcon_X\n")); nt_status = cli_nt_error(cli); cli_shutdown(cli); + if (NT_STATUS_IS_OK(nt_status)) nt_status = NT_STATUS_UNSUCCESSFUL; return nt_status; } } -- cgit From d6823366b881612234ab0655adb11c594f864c4a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jan 2002 19:10:25 +0000 Subject: Same fix as went into 2.2 (I'm waiting for jerry to finish some code). Jeremy. (This used to be commit 01ff6ce4963e1daff019f2b936cef218e1c93f67) --- source3/libsmb/cliconnect.c | 36 +++++++++++++++--------------- source3/libsmb/clidgram.c | 2 +- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clifile.c | 52 +++++++++++++++++++++---------------------- source3/libsmb/clilist.c | 4 ++-- source3/libsmb/climessage.c | 6 ++--- source3/libsmb/clioplock.c | 2 +- source3/libsmb/clireadwrite.c | 12 +++++----- source3/libsmb/clitrans.c | 8 +++---- 9 files changed, 62 insertions(+), 62 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1812416426..08d9f3b382 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -76,10 +76,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,10, 0, True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,cli->max_xmit); SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,1); @@ -142,10 +142,10 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) uint32 capabilities = cli_session_setup_capabilities(cli); set_message(cli->outbuf,13,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); @@ -197,10 +197,10 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII); set_message(cli->outbuf,13,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); @@ -273,10 +273,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,13,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); @@ -335,10 +335,10 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,12,0,True); - CVAL(cli->outbuf,smb_com) = SMBsesssetupX; + SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,1); @@ -633,7 +633,7 @@ BOOL cli_ulogoff(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBulogoffX; + SCVAL(cli->outbuf,smb_com,SMBulogoffX); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ @@ -691,7 +691,7 @@ BOOL cli_send_tconX(struct cli_state *cli, } set_message(cli->outbuf,4, 0, True); - CVAL(cli->outbuf,smb_com) = SMBtconX; + SCVAL(cli->outbuf,smb_com,SMBtconX); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); @@ -737,7 +737,7 @@ BOOL cli_tdis(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBtdis; + SCVAL(cli->outbuf,smb_com,SMBtdis); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -770,11 +770,11 @@ void cli_negprot_send(struct cli_state *cli) p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE); } - CVAL(cli->outbuf,smb_com) = SMBnegprot; + SCVAL(cli->outbuf,smb_com,SMBnegprot); cli_setup_bcc(cli, p); cli_setup_packet(cli); - CVAL(smb_buf(cli->outbuf),0) = 2; + SCVAL(smb_buf(cli->outbuf),0,2); cli_send_smb(cli); } @@ -807,10 +807,10 @@ BOOL cli_negprot(struct cli_state *cli) p += clistr_push(cli, p, prots[numprots].name, -1, STR_TERMINATE); } - CVAL(cli->outbuf,smb_com) = SMBnegprot; + SCVAL(cli->outbuf,smb_com,SMBnegprot); cli_setup_packet(cli); - CVAL(smb_buf(cli->outbuf),0) = 2; + SCVAL(smb_buf(cli->outbuf),0,2); cli_send_smb(cli); if (!cli_receive_smb(cli)) @@ -905,7 +905,7 @@ BOOL cli_session_request(struct cli_state *cli, /* setup the packet length */ _smb_setlen(cli->outbuf,len); - CVAL(cli->outbuf,0) = 0x81; + SCVAL(cli->outbuf,0,0x81); #ifdef WITH_SSL retry: diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index e990739de5..ded47b7d06 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -71,7 +71,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, set_message(ptr,17,17 + len,True); memcpy(ptr,tmp,4); - CVAL(ptr,smb_com) = SMBtrans; + SCVAL(ptr,smb_com,SMBtrans); SSVAL(ptr,smb_vwv1,len); SSVAL(ptr,smb_vwv11,len); SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 610af9cc23..022046ceb2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -57,7 +57,7 @@ BOOL cli_receive_smb(struct cli_state *cli) if (!cli->oplock_handler(cli, fnum, level)) return False; } /* try to prevent loops */ - CVAL(cli->inbuf,smb_com) = 0xFF; + SCVAL(cli->inbuf,smb_com,0xFF); goto again; } } diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 5c37255278..7cd1e4ddb1 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -36,7 +36,7 @@ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ set_message(cli->outbuf,1, 0, True); - CVAL(cli->outbuf,smb_com) = SMBmv; + SCVAL(cli->outbuf,smb_com,SMBmv); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -73,7 +73,7 @@ BOOL cli_unlink(struct cli_state *cli, const char *fname) set_message(cli->outbuf,1, 0,True); - CVAL(cli->outbuf,smb_com) = SMBunlink; + SCVAL(cli->outbuf,smb_com,SMBunlink); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -109,7 +109,7 @@ BOOL cli_mkdir(struct cli_state *cli, const char *dname) set_message(cli->outbuf,0, 0,True); - CVAL(cli->outbuf,smb_com) = SMBmkdir; + SCVAL(cli->outbuf,smb_com,SMBmkdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -144,7 +144,7 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname) set_message(cli->outbuf,0, 0, True); - CVAL(cli->outbuf,smb_com) = SMBrmdir; + SCVAL(cli->outbuf,smb_com,SMBrmdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -224,7 +224,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA set_message(cli->outbuf,24,0,True); - CVAL(cli->outbuf,smb_com) = SMBntcreateX; + SCVAL(cli->outbuf,smb_com,SMBntcreateX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -317,7 +317,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode set_message(cli->outbuf,15,0,True); - CVAL(cli->outbuf,smb_com) = SMBopenX; + SCVAL(cli->outbuf,smb_com,SMBopenX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -331,8 +331,8 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode if (cli->use_oplocks) { /* if using oplocks then ask for a batch oplock via core and extended methods */ - CVAL(cli->outbuf,smb_flg) |= - FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; + SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)| + FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK); SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); } @@ -364,7 +364,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) set_message(cli->outbuf,3,0,True); - CVAL(cli->outbuf,smb_com) = SMBclose; + SCVAL(cli->outbuf,smb_com,SMBclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -394,13 +394,13 @@ BOOL cli_lock(struct cli_state *cli, int fnum, set_message(cli->outbuf,8,0,True); - CVAL(cli->outbuf,smb_com) = SMBlockingX; + SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = (lock_type == READ_LOCK? 1 : 0); + SCVAL(cli->outbuf,smb_vwv3,(lock_type == READ_LOCK? 1 : 0)); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,0); SSVAL(cli->outbuf,smb_vwv7,1); @@ -445,13 +445,13 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) set_message(cli->outbuf,8,0,True); - CVAL(cli->outbuf,smb_com) = SMBlockingX; + SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; + SCVAL(cli->outbuf,smb_vwv3,0); SIVALS(cli->outbuf, smb_vwv4, 0); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); @@ -497,13 +497,13 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, set_message(cli->outbuf,8,0,True); - CVAL(cli->outbuf,smb_com) = SMBlockingX; + SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = ltype; + SCVAL(cli->outbuf,smb_vwv3,ltype); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,0); SSVAL(cli->outbuf,smb_vwv7,1); @@ -550,13 +550,13 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ set_message(cli->outbuf,8,0,True); - CVAL(cli->outbuf,smb_com) = SMBlockingX; + SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = LOCKING_ANDX_LARGE_FILES; + SCVAL(cli->outbuf,smb_vwv3,LOCKING_ANDX_LARGE_FILES); SIVALS(cli->outbuf, smb_vwv4, 0); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); @@ -592,7 +592,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, set_message(cli->outbuf,1,0,True); - CVAL(cli->outbuf,smb_com) = SMBgetattrE; + SCVAL(cli->outbuf,smb_com,SMBgetattrE); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -644,7 +644,7 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBgetatr; + SCVAL(cli->outbuf,smb_com,SMBgetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -692,7 +692,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) set_message(cli->outbuf,8,0,True); - CVAL(cli->outbuf,smb_com) = SMBsetatr; + SCVAL(cli->outbuf,smb_com,SMBsetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -760,7 +760,7 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBdskattr; + SCVAL(cli->outbuf,smb_com,SMBdskattr); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -790,7 +790,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) set_message(cli->outbuf,3,0,True); - CVAL(cli->outbuf,smb_com) = SMBctemp; + SCVAL(cli->outbuf,smb_com,SMBctemp); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a9212c9dba..0c80044b68 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -358,7 +358,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBsearch; + SCVAL(cli->outbuf,smb_com,SMBsearch); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -416,7 +416,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBfclose; + SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index d32c5de042..5ded79de96 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -35,7 +35,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, /* send a SMBsendstrt command */ memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendstrt; + SCVAL(cli->outbuf,smb_com,SMBsendstrt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -70,7 +70,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,1,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendtxt; + SCVAL(cli->outbuf,smb_com,SMBsendtxt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -101,7 +101,7 @@ BOOL cli_message_end(struct cli_state *cli, int grp) { memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,1,0,True); - CVAL(cli->outbuf,smb_com) = SMBsendend; + SCVAL(cli->outbuf,smb_com,SMBsendend); SSVAL(cli->outbuf,smb_tid,cli->cnum); SSVAL(cli->outbuf,smb_vwv0,grp); diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index b38933181e..dca0e96cb4 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -37,7 +37,7 @@ BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) memset(buf,'\0',smb_size); set_message(buf,8,0,True); - CVAL(buf,smb_com) = SMBlockingX; + SCVAL(buf,smb_com,SMBlockingX); SSVAL(buf,smb_tid, cli->cnum); cli_setup_packet(cli); SSVAL(buf,smb_vwv0,0xFF); diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index f141a208bf..93333bff95 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -35,11 +35,11 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, set_message(cli->outbuf,10,0,True); - CVAL(cli->outbuf,smb_com) = SMBreadX; + SCVAL(cli->outbuf,smb_com,SMBreadX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,fnum); SIVAL(cli->outbuf,smb_vwv3,offset); SSVAL(cli->outbuf,smb_vwv5,size); @@ -61,7 +61,7 @@ static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, set_message(cli->outbuf,10,0,True); - CVAL(cli->outbuf,smb_com) = SMBreadbraw; + SCVAL(cli->outbuf,smb_com,SMBreadbraw); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -232,11 +232,11 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 else set_message(cli->outbuf,12,0,True); - CVAL(cli->outbuf,smb_com) = SMBwriteX; + SCVAL(cli->outbuf,smb_com,SMBwriteX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,fnum); SIVAL(cli->outbuf,smb_vwv3,offset); @@ -327,7 +327,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, set_message(cli->outbuf,5, 0,True); - CVAL(cli->outbuf,smb_com) = SMBwrite; + SCVAL(cli->outbuf,smb_com,SMBwrite); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 8da1cc665f..5b53413012 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -46,7 +46,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,14+lsetup,0,True); - CVAL(cli->outbuf,smb_com) = trans; + SCVAL(cli->outbuf,smb_com,trans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); @@ -101,7 +101,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); - CVAL(cli->outbuf,smb_com) = trans==SMBtrans ? SMBtranss : SMBtranss2; + SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); outparam = smb_buf(cli->outbuf); outdata = outparam+this_lparam; @@ -271,7 +271,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,19+lsetup,0,True); - CVAL(cli->outbuf,smb_com) = SMBnttrans; + SCVAL(cli->outbuf,smb_com,SMBnttrans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); @@ -319,7 +319,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); set_message(cli->outbuf,18,0,True); - CVAL(cli->outbuf,smb_com) = SMBnttranss; + SCVAL(cli->outbuf,smb_com,SMBnttranss); /* XXX - these should probably be aligned */ outparam = smb_buf(cli->outbuf); -- cgit From e895b9004e57c62d7517198618f9fd788107629e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 12 Jan 2002 23:57:10 +0000 Subject: Many thanks to Alexander Bokovoy . This work was sponsored by Optifacio Software Services, Inc. Andrew Bartlett (various e-mails announcements merged into some form of commit message below:) This patch which adds basics of universal groups support into Samba 3. Currently, only Winbind with RPC calls supports this, ADS support requires additional (possibly huge) work on KRB5 PAC. However, basic infrastructure is here. This patch adds: 1. Storing of universal groups for particular user logged into Samba software (smbd/ two winbind-pam methods) into netlogon_unigrp.tdb as array of uint32 supplemental group rids keyed as DOMAIN_SID/USER_RID in tdb. 2. Fetching of unversal groups for given user rid and domain sid from netlogon_unigrp.tdb. Since this is used in both smbd and winbindd, main code is in source/lib/netlogon_uingrp.c. Dependencies are added to AUTH_OBJ as UNIGRP_OBJ and WINBINDD_OBJ as UNIGRP_OBJ. This patch has had a few versions, the final version in particular: Many thanks to Andrew Bartlett for critics and comments, and partly rewritten code. New: - updated fetching code to changed byte order macros - moved functions to proper namespace - optimized memory usage by reusing caller's memory context - enhanced code to more follow Samba coding rules Todo: - proper universal group expiration after timeout (This used to be commit 80c2aefbe7c1aa363dd286a47d50c5d8b4595f43) --- source3/libsmb/netlogon_unigrp.c | 152 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 source3/libsmb/netlogon_unigrp.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c new file mode 100644 index 0000000000..317a5bc3d0 --- /dev/null +++ b/source3/libsmb/netlogon_unigrp.c @@ -0,0 +1,152 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + Universal groups helpers + Copyright (C) Alexander Bokovoy 2002. + Copyright (C) Andrew Bartlett 2002. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + This work was sponsored by Optifacio Software Services, Inc. +*/ + +#include "includes.h" + +/* + Handle for netlogon_unigrp.tdb database. It is used internally + in cli_store_uni_groups_*() and cli_fetch_uni_groups() + and is initialized on first call to cli_store_uni_groups_*() +*/ +static TDB_CONTEXT *netlogon_unigrp_tdb = NULL; + +/* + Store universal groups info into netlogon_unigrp.tdb for + later usage. We use 'domain_SID/user_rid' as key and + array of uint32 where array[0] is number of elements + and elements are array[1] ... array[array[0]] +*/ +void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) +{ + TDB_DATA key,data; + fstring keystr; + int i; + + if (!netlogon_unigrp_tdb) { + netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0, + TDB_NOLOCK, O_RDWR | O_CREAT, 0644); + } + + if (!netlogon_unigrp_tdb) { + DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n")); + return; + } + + /* Prepare key as DOMAIN-SID/USER-RID string */ + slprintf(keystr, sizeof(keystr), "%s/%d", + sid_string_static(&user->dom_sid.sid), user->user_rid); + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + + /* Prepare data */ + data.dsize = (user->num_groups2+1)*sizeof(uint32); + data.dptr = talloc(mem_ctx, data.dsize); + if(!data.dptr) { + DEBUG(0,("uni_group_cache_store_netlogon: cannot allocate memory!\n")); + talloc_destroy(mem_ctx); + return; + } + + /* Store data in byteorder-independent format */ + SIVAL(&((uint32*)data.dptr)[0],0,user->num_groups2); + for(i=1; i<=user->num_groups2; i++) { + SIVAL(&((uint32*)data.dptr)[i],0,user->gids[i-1].g_rid); + } + tdb_store(netlogon_unigrp_tdb, key, data, TDB_REPLACE); +} + +/* + Fetch universal groups info from netlogon_unigrp.tdb for given + domain sid and user rid and allocate it using given mem_ctx. + Universal groups are returned as array of uint32 elements + and elements are array[0] ... array[num_elements-1] + +*/ +uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, + TALLOC_CTX *mem_ctx, uint32 *num_groups) +{ + TDB_DATA key,data; + fstring keystr; + uint32 *groups; + uint32 i; + uint32 group_count; + + if (!domain) { + DEBUG(1,("uni_group_cache_fetch: expected non-null domain sid\n")); + return NULL; + } + if (!mem_ctx) { + DEBUG(1,("uni_group_cache_fetch: expected non-null memory context\n")); + return NULL; + } + if (!num_groups) { + DEBUG(1,("uni_group_cache_fetch: expected non-null num_groups\n")); + return NULL; + } + if (!netlogon_unigrp_tdb) { + netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0, + TDB_NOLOCK, O_RDWR, 0644); + } + if (!netlogon_unigrp_tdb) { + DEBUG(5,("uni_group_cache_fetch: cannot open netlogon_unigrp.tdb for read - normal if not created yet\n")); + return NULL; + } + + *num_groups = 0; + + /* Fetch universal groups */ + slprintf(keystr, sizeof(keystr), "%s/%d", + sid_string_static(domain), user_rid); + key.dptr = keystr; + key.dsize = strlen(keystr) + 1; + data = tdb_fetch(netlogon_unigrp_tdb, key); + + /* There is no cached universal groups in netlogon_unigrp.tdb */ + /* for this user. */ + if (!data.dptr) return NULL; + + /* Transfer data to receiver's memory context */ + group_count = IVAL(&((uint32*)data.dptr)[0],0); + groups = talloc(mem_ctx, (group_count)*sizeof(uint32)); + if (groups) { + for(i=0; i Date: Mon, 14 Jan 2002 02:22:31 +0000 Subject: Removed fprintf(stderr, ...); calls which should not be present in library functions. (This used to be commit e69a22290e5c923f31223906461df4874e3b2aac) --- source3/libsmb/clidgram.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index ded47b7d06..1dffe67968 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -21,8 +21,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /* @@ -54,9 +52,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, dgram->header.flags.more = False; dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100); dgram->header.source_ip.s_addr = src_ip.s_addr; - /*fprintf(stderr, "Source IP = %0X\n", dgram->header.source_ip); */ dgram->header.source_port = ntohs(src_port); - fprintf(stderr, "Source Port = %0X\n", dgram->header.source_port); dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ dgram->header.packet_offset = 0; -- cgit From bf7c56665c8483c7731eedde4ab567b2b86a5bd6 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 16 Jan 2002 01:41:30 +0000 Subject: Merge of name_status_find() debugs. (This used to be commit cfac669017afa763100e335d1516fbed18049e00) --- source3/libsmb/namequery.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e410363de8..8ac7ae2c6a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -163,33 +163,46 @@ return the matched name in *name BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name) { - struct node_status *status; + struct node_status *status = NULL; struct nmb_name nname; int count, i; int sock; + BOOL result = False; + + DEBUG(10, ("name_status_find: looking up %s#%x\n", q_name, q_type)); sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); if (sock == -1) - return False; + goto done; /* W2K PDC's seem not to respond to '*'#0. JRA */ make_nmb_name(&nname, q_name, q_type); status = node_status_query(sock, &nname, to_ip, &count); close(sock); if (!status) - return False; + goto done; for (i=0;i Date: Wed, 16 Jan 2002 20:13:28 +0000 Subject: Added CIFS UNIX extension code to client. Jeremy. (This used to be commit 794c3e2c76aae57d054e46b185def104ca02977c) --- source3/libsmb/clifile.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 7cd1e4ddb1..e282c9a6ab 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -3,6 +3,7 @@ Version 3.0 client file operations Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Jeremy Allison 2001-2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +24,169 @@ #include "includes.h" +/**************************************************************************** + Hard/Symlink a file (UNIX extensions). +****************************************************************************/ + +static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const char *fname_dst, BOOL hard_link) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_SETPATHINFO; + char param[sizeof(pstring)+6]; + pstring data; + char *rparam=NULL, *rdata=NULL; + char *p; + + memset(param, 0, sizeof(param)); + SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK); + p = ¶m[6]; + + p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + p = data; + p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + data_len = PTR_DIFF(p, data); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + +/**************************************************************************** + Map standard UNIX permissions onto wire representations. +****************************************************************************/ + +uint32 unix_perms_to_wire(mode_t perms) +{ + uint ret = 0; + + ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0); + ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0); + ret |= ((perms & S_IROTH) ? UNIX_R_OTH : 0); + ret |= ((perms & S_IXGRP) ? UNIX_X_GRP : 0); + ret |= ((perms & S_IWGRP) ? UNIX_W_GRP : 0); + ret |= ((perms & S_IRGRP) ? UNIX_R_GRP : 0); + ret |= ((perms & S_IXUSR) ? UNIX_X_USR : 0); + ret |= ((perms & S_IWUSR) ? UNIX_W_USR : 0); + ret |= ((perms & S_IRUSR) ? UNIX_R_USR : 0); +#ifdef S_ISVTX + ret |= ((perms & S_ISVTX) ? UNIX_STICKY : 0); +#endif +#ifdef S_ISGID + ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0); +#endif +#ifdef S_ISUID + ret |= ((perms & S_ISVTX) ? UNIX_SET_UID : 0); +#endif + return ret; +} + +/**************************************************************************** + Symlink a file (UNIX extensions). +****************************************************************************/ + +BOOL cli_unix_symlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + return cli_link_internal(cli, fname_src, fname_dst, False); +} + +/**************************************************************************** + Hard a file (UNIX extensions). +****************************************************************************/ + +BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + return cli_link_internal(cli, fname_src, fname_dst, True); +} + +/**************************************************************************** + Chmod or chown a file internal (UNIX extensions). +****************************************************************************/ + +static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_SETPATHINFO; + char param[sizeof(pstring)+6]; + char data[100]; + char *rparam=NULL, *rdata=NULL; + char *p; + + memset(param, 0, sizeof(param)); + memset(data, 0, sizeof(data)); + SSVAL(param,0,SMB_SET_FILE_UNIX_BASIC); + p = ¶m[6]; + + p += clistr_push(cli, p, fname, -1, STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + SIVAL(data,40,uid); + SIVAL(data,48,gid); + SIVAL(data,84,mode); + + data_len = 100; + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + +/**************************************************************************** + chmod a file (UNIX extensions). +****************************************************************************/ + +BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) +{ + return cli_unix_chmod_chown_internal(cli, fname, + unix_perms_to_wire(mode), UID_NO_CHANGE, GID_NO_CHANGE); +} + +/**************************************************************************** + chown a file (UNIX extensions). +****************************************************************************/ + +BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid) +{ + return cli_unix_chmod_chown_internal(cli, fname, MODE_NO_CHANGE, (uint32)uid, (uint32)gid); +} + /**************************************************************************** Rename a file. ****************************************************************************/ -- cgit From 04ec469c72c6a220108312cdec3d30081cfe938a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2002 21:27:57 +0000 Subject: Fixup error mapping so we have only one table containing errno -> dos error -> NT STATUS maps. Fixes problem with disk full returning incorrect error. Jeremy. (This used to be commit 16fcbf3c1ccf1d704765653f68395dd596c0d841) --- source3/libsmb/errormap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 1c44675c83..401a07b77d 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -773,6 +773,7 @@ static struct { {ERRHRD, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, {ERRHRD, ERRwrongdisk, NT_STATUS_WRONG_VOLUME}, {ERRHRD, 38, NT_STATUS_END_OF_FILE}, + {ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL}, {ERRHRD, 50, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, {ERRHRD, 51, NT_STATUS_REMOTE_NOT_LISTENING}, {ERRHRD, 52, NT_STATUS_DUPLICATE_NAME}, -- cgit From 5cf6457bcc1182eac99f5618b647153707fa41ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2002 23:32:10 +0000 Subject: Merged in %S fixes and XX_NOT_CHANGED fixes from 2.2. Jeremy. (This used to be commit 0fcca6c627a5c9c2219ec9714df5e0bc1a44cc29) --- source3/libsmb/clifile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index e282c9a6ab..4b7c173a63 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -175,7 +175,7 @@ static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) { return cli_unix_chmod_chown_internal(cli, fname, - unix_perms_to_wire(mode), UID_NO_CHANGE, GID_NO_CHANGE); + unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE); } /**************************************************************************** @@ -184,7 +184,7 @@ BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid) { - return cli_unix_chmod_chown_internal(cli, fname, MODE_NO_CHANGE, (uint32)uid, (uint32)gid); + return cli_unix_chmod_chown_internal(cli, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid); } /**************************************************************************** -- cgit From ab3cae976800edd206d6c5b88bb4bd40b133f970 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 17 Jan 2002 01:05:34 +0000 Subject: fixed a typo in the error map for WRONG_PASSWORD (This used to be commit fb300e411bb385dcba2c3ca166598a71ed693b35) --- source3/libsmb/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 401a07b77d..28b4cb0431 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -175,7 +175,7 @@ static struct { from NT_STATUS_WRONG_PASSWORD to NT_STATUS_LOGON_FAILURE during the session setup } */ - {ERRDOS, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, + {ERRSRV, ERRbadpw, NT_STATUS_WRONG_PASSWORD}, {ERRHRD, ERRgeneral, NT_STATUS_ILL_FORMED_PASSWORD}, {ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, {ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, -- cgit From 21a6c3448527ddff1c7053784116694f064570b5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 17 Jan 2002 05:07:36 +0000 Subject: Made a debug look nicer. (This used to be commit aca0edc819e892944c65b3feb60250994a79e88a) --- source3/libsmb/namequery.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8ac7ae2c6a..926cda9dcb 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -169,7 +169,8 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t int sock; BOOL result = False; - DEBUG(10, ("name_status_find: looking up %s#%x\n", q_name, q_type)); + DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, + q_type, inet_ntoa(to_ip))); sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); if (sock == -1) -- cgit From 1fb9ccc4e2a91bf7124fba076ffa5458a1cbf404 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jan 2002 02:37:55 +0000 Subject: This is the 'winbind default domain' patch from Alexander Bokovoy . The idea is the domain\username is rather harsh for unix systems - people don't expect to have to FTP, SSH and (in particular) e-mail with a username like that. This 'corrects' that - but is not without its own problems. As you can see from the changes to files like username.c and wb_client.c (smbd's winbind client code) a lot of assumptions are made in a lot of places about lp_winbind_seperator determining a users's status as a domain or local user. The main change I will shortly be making is to investigate and kill off winbind_initgroups() - as far as I know it was a workaround for an old bug in winbind itself (and a bug in RH 5.2) and should no longer be relevent. I am also going to move to using the 'winbind uid' and 'winbind gid' paramaters to determine a user/groups's 'local' status, rather than the presence of the seperator. As such, this functionality is recommended for servers providing unix services, but is currently less than optimal for windows clients. (TODO: remove all references to lp_winbind_seperator() and lp_winbind_use_default_domain() from smbd) Andrew Bartlett (This used to be commit 07a21fcd2311d2d9b430b99303e3532a8c1159e4) --- source3/libsmb/cli_netlogon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 9223683854..f95ee89a29 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -509,8 +509,8 @@ NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, **/ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *username, char *domain, char *workstation, - uint8 chal[8], + const char *username, const char *domain, const char *workstation, + const uint8 chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, NET_USER_INFO_3 *info3) @@ -554,7 +554,7 @@ NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_c init_id_info2(&ctr.auth.id2, domain, 0, /* param_ctrl */ 0xdead, 0xbeef, /* LUID? */ - username, workstation_name_slash, (uchar*)chal, + username, workstation_name_slash, (const uchar*)chal, lm_response.data, lm_response.length, nt_response.data, nt_response.length); init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, -- cgit From 93a8358910d2b8788ffea33c04244ffd5ffecabf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Jan 2002 01:24:59 +0000 Subject: This patch makes the 'winbind use default domain' code interact better with smbd, and also makes it much cleaner inside winbindd. It is mostly my code, with a few changes and testing performed by Alexander Bokovoy . ab has tested it in security=domain and security=ads, but more testing is always appricatiated. The idea is that we no longer cart around a 'domain\user' string, we keep them seperate until the last moment - when we push that string into a pwent on onto the socket. This removes the need to be constantly parsing that string - the domain prefix is almost always already provided, (only a couple of functions actually changed arguments in all this). Some consequential changes to the RPC client code, to stop it concatonating the two strings (it now passes them both back as params). I havn't changed the cache code, however the usernames will no longer have a double domain prefix in the key string. The actual structures are unchanged - but the meaning of 'username' in the 'rid' will have changed. (The cache is invalidated at startup, so on-disk formats are not an issue here). Andrew Bartlett (This used to be commit e870f0e727952aeb8599cf93ad2650ae56eca033) --- source3/libsmb/cli_lsarpc.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 95169afd7c..66504d8355 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -218,7 +218,7 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***names, uint32 **types, int *num_names) + char ***domains, char ***names, uint32 **types, int *num_names) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; @@ -279,6 +279,12 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, (*num_names) = r.mapped_count; result = NT_STATUS_OK; + if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { + DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } + if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; @@ -292,7 +298,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, } for (i = 0; i < r.mapped_count; i++) { - fstring name, dom_name, full_name; + fstring name, dom_name; uint32 dom_idx = t_names.name[i].domain_idx; /* Translate optimised name through domain index array */ @@ -304,13 +310,15 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, rpcstr_pull_unistr2_fstring( name, &t_names.uni_name[i]); - slprintf(full_name, sizeof(full_name) - 1, - "%s%s%s", dom_name, - (dom_name[0] && name[0]) ? - lp_winbind_separator() : "", name); - - (*names)[i] = talloc_strdup(mem_ctx, full_name); + (*names)[i] = talloc_strdup(mem_ctx, name); + (*domains)[i] = talloc_strdup(mem_ctx, dom_name); (*types)[i] = t_names.name[i].sid_name_use; + + if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) { + DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); + result = NT_STATUS_UNSUCCESSFUL; + goto done; + } } else { (*names)[i] = NULL; @@ -328,7 +336,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /** Lookup a list of names */ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, const char **names, + POLICY_HND *pol, int num_names, const char **dom_names, const char **names, DOM_SID **sids, uint32 **types, int *num_sids) { prs_struct qbuf, rbuf; @@ -348,7 +356,7 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ - init_q_lookup_names(mem_ctx, &q, pol, num_names, names); + init_q_lookup_names(mem_ctx, &q, pol, num_names, dom_names, names); if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { -- cgit From 8d2d97b17647d4a9c6bc39cb87ae99dc3c86cc06 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Jan 2002 07:13:05 +0000 Subject: Fix a couple of memory leaks in the cli_establish_connection() code's failure case. Thanks to Nigel Williams for spotting these! Andrew Bartlett (This used to be commit 20e0b562283f75606ac9a36f3f104c6aaa294c40) --- source3/libsmb/cliconnect.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 08d9f3b382..86ff6b5c92 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1223,6 +1223,7 @@ again: } if (cli_set_port(cli, port) != port) { + cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } @@ -1235,6 +1236,7 @@ again: { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", nmb_namestr(&called), inet_ntoa(*dest_ip))); + cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } -- cgit From 1f670cfb275ee34e66f504cd35b1c790840999bf Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 20 Jan 2002 22:50:23 +0000 Subject: Spelling fixes. (This used to be commit e67c7c5852624bcdd5c565ea5f00b143aaf7fee4) --- source3/libsmb/namequery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 926cda9dcb..d90cd6a7ea 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -64,6 +64,8 @@ static struct node_status *parse_node_status(char *p, int *num_names) ret[i].type = CVAL(p,15); ret[i].flags = p[16]; p += 18; + DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, + ret[i].type, ret[i].flags)); } return ret; } -- cgit From c69d1b943470aeebcee0dfcb4fd1051b8b070e29 Mon Sep 17 00:00:00 2001 From: Martin Pool Date: Tue, 22 Jan 2002 05:11:28 +0000 Subject: Add more string explanations of RAP errors that are already documented in clirap2. (This used to be commit 935955b50ff503d18265f745e6e0df90d3e5dd4b) --- source3/libsmb/clierror.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 81e8be36a8..637f362ae8 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -25,6 +25,10 @@ /***************************************************** RAP error codes - a small start but will be extended. + + XXX: Perhaps these should move into a common function because they're + duplicated in clirap2.c + *******************************************************/ static const struct @@ -33,14 +37,19 @@ static const struct char *message; } rap_errmap[] = { - {5, "User has insufficient privilege" }, - {86, "The specified password is invalid" }, - {2226, "Operation only permitted on a Primary Domain Controller" }, - {2242, "The password of this user has expired." }, - {2243, "The password of this user cannot change." }, - {2244, "This password cannot be used now (password history conflict)." }, - {2245, "The password is shorter than required." }, - {2246, "The password of this user is too recent to change."}, + {5, "RAP5: User has insufficient privilege" }, + {50, "RAP50: Not supported by server" }, + {65, "RAP65: Access denied" }, + {86, "RAP86: The specified password is invalid" }, + {2220, "RAP2220: Group does not exist" }, + {2221, "RAP2221: User does not exist" }, + {2226, "RAP2226: Operation only permitted on a Primary Domain Controller" }, + {2237, "RAP2237: User is not in group" }, + {2242, "RAP2242: The password of this user has expired." }, + {2243, "RAP2243: The password of this user cannot change." }, + {2244, "RAP2244: This password cannot be used now (password history conflict)." }, + {2245, "RAP2245: The password is shorter than required." }, + {2246, "RAP2246: The password of this user is too recent to change."}, /* these really shouldn't be here ... */ {0x80, "Not listening on called name"}, -- cgit From 9731bbe06d86edfb4584d79a57299e4969ba5a46 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 25 Jan 2002 04:26:16 +0000 Subject: Removed unused static variable. (This used to be commit 7c2d7205938ddd958b8399599febbf63ac4c8a88) --- source3/libsmb/libsmbclient.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 33aeb62af8..3b6252dd54 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -68,7 +68,6 @@ static int smbc_initialized = 0; static smbc_get_auth_data_fn smbc_auth_fn = NULL; /*static int smbc_debug;*/ static int smbc_start_fd; -static int smbc_max_fd = 10000; static struct smbc_file **smbc_file_table; static struct smbc_server *smbc_srvs; static pstring my_netbios_name; -- cgit From 714cdd47cb3e0e1f683c0a22396f9167a85e7df3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 26 Jan 2002 06:24:53 +0000 Subject: Fix up a security issue with the way we handle domain groups retuned on the info3. These are RIDs, and it only makes sense to combine them with the domain SID returned with them. This is important for trusted domains, where that sid might be other than the one we currently reterive from the secrets.tdb. Also remove the become_root()/unbecome_root() wrapper from around both remaining TDB users: Both are now initialised at smbd startup. Andrew Bartlett (This used to be commit 554842e0a55155193f25aefca6480b89d5c512ca) --- source3/libsmb/netlogon_unigrp.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index 317a5bc3d0..d4063242f6 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -37,18 +37,24 @@ static TDB_CONTEXT *netlogon_unigrp_tdb = NULL; array of uint32 where array[0] is number of elements and elements are array[1] ... array[array[0]] */ + +BOOL uni_group_cache_init(void) +{ + if (!netlogon_unigrp_tdb) { + netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0, + TDB_NOLOCK, O_RDWR | O_CREAT, 0644); + } + + return (netlogon_unigrp_tdb != NULL); +} + void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) { TDB_DATA key,data; fstring keystr; int i; - - if (!netlogon_unigrp_tdb) { - netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0, - TDB_NOLOCK, O_RDWR | O_CREAT, 0644); - } - if (!netlogon_unigrp_tdb) { + if (!uni_group_cache_init()) { DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n")); return; } @@ -145,8 +151,8 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, /* Shutdown netlogon_unigrp database */ void uni_group_cache_shutdown(void) { - if(netlogon_unigrp_tdb) { - tdb_close(netlogon_unigrp_tdb); - } + if(netlogon_unigrp_tdb) { + tdb_close(netlogon_unigrp_tdb); + } } -- cgit From ba8c1c6e459aef204aa93e9cf7e717209335a06b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 26 Jan 2002 11:48:42 +0000 Subject: Back out some of the less well thought out ideas from last weeks work on winbind default domains, particulary now I understand whats going on a lot better. This ensures that the RPC client code does as little 'magic' as possible - this is up to the application/user. (Where - for to name->sid code - it was all along). This leaves the change that allows the sid->name code to return domains and usernames in seperate paramaters. Andrew Bartlett (This used to be commit 5dfba2cf536f761b0aee314ed9e30dc53900b691) --- source3/libsmb/cli_lsarpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 66504d8355..7e0abd583c 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -336,7 +336,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /** Lookup a list of names */ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, const char **dom_names, const char **names, + POLICY_HND *pol, int num_names, const char **names, DOM_SID **sids, uint32 **types, int *num_sids) { prs_struct qbuf, rbuf; @@ -356,7 +356,7 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ - init_q_lookup_names(mem_ctx, &q, pol, num_names, dom_names, names); + init_q_lookup_names(mem_ctx, &q, pol, num_names, names); if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { -- cgit From 7c822ae3fff114d796ab18a0ff0fb8abde560659 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jan 2002 00:54:37 +0000 Subject: Name another talloc. (This used to be commit 9d62f25f5d3c25d71d8b87801084d42ae9b66f8c) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 022046ceb2..50f9a7dc81 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -208,7 +208,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (!cli->outbuf || !cli->inbuf) goto error; - if ((cli->mem_ctx = talloc_init()) == NULL) + if ((cli->mem_ctx = talloc_init_named("cli based talloc")) == NULL) goto error; memset(cli->outbuf, 0, cli->bufsize); -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libsmb/asn1.c | 3 +-- source3/libsmb/cli_dfs.c | 3 +-- source3/libsmb/cli_lsarpc.c | 2 +- source3/libsmb/cli_netlogon.c | 3 +-- source3/libsmb/cli_pipe_util.c | 3 +-- source3/libsmb/cli_reg.c | 3 +-- source3/libsmb/cli_samr.c | 3 +-- source3/libsmb/cli_spoolss.c | 2 +- source3/libsmb/cli_srvsvc.c | 3 +-- source3/libsmb/cliconnect.c | 3 +-- source3/libsmb/clidgram.c | 3 +-- source3/libsmb/clientgen.c | 3 +-- source3/libsmb/clierror.c | 3 +-- source3/libsmb/clifile.c | 3 +-- source3/libsmb/clikrb5.c | 3 +-- source3/libsmb/clilist.c | 3 +-- source3/libsmb/climessage.c | 3 +-- source3/libsmb/clioplock.c | 3 +-- source3/libsmb/cliprint.c | 3 +-- source3/libsmb/clirap.c | 3 +-- source3/libsmb/clirap2.c | 1 - source3/libsmb/clireadwrite.c | 3 +-- source3/libsmb/clisecdesc.c | 3 +-- source3/libsmb/clispnego.c | 3 +-- source3/libsmb/clistr.c | 3 +-- source3/libsmb/clitrans.c | 3 +-- source3/libsmb/credentials.c | 3 +-- source3/libsmb/errormap.c | 3 +-- source3/libsmb/libsmbclient.c | 3 +-- source3/libsmb/namequery.c | 3 +-- source3/libsmb/netlogon_unigrp.c | 3 +-- source3/libsmb/nmblib.c | 3 +-- source3/libsmb/nterr.c | 3 +-- source3/libsmb/passchange.c | 3 +-- source3/libsmb/pwd_cache.c | 3 +-- source3/libsmb/smbdes.c | 3 +-- source3/libsmb/smbencrypt.c | 3 +-- source3/libsmb/smberr.c | 3 +-- source3/libsmb/trust_passwd.c | 3 +-- source3/libsmb/unexpected.c | 3 +-- 40 files changed, 39 insertions(+), 77 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 1175a7fe65..b4ad3ad0b8 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. simple SPNEGO routines Copyright (C) Andrew Tridgell 2001 diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index 83220fd1af..312275926c 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 2.2 + Unix SMB/CIFS implementation. RPC pipe client Copyright (C) Tim Potter 2000-2001, diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 7e0abd583c..7ba47d3a18 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -1,5 +1,5 @@ /* - Unix SMB/Netbios implementation. + Unix SMB/CIFS implementation. RPC pipe client Copyright (C) Tim Potter 2000-2001, Copyright (C) Andrew Tridgell 1992-1997,2000, diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index f95ee89a29..d550c3e9fa 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. NT Domain Authentication SMB / MSRPC client Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 diff --git a/source3/libsmb/cli_pipe_util.c b/source3/libsmb/cli_pipe_util.c index d0028e83eb..de1c832e44 100644 --- a/source3/libsmb/cli_pipe_util.c +++ b/source3/libsmb/cli_pipe_util.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 2.2 + Unix SMB/CIFS implementation. RPC pipe client utility functions Copyright (C) Tim Potter 2001, diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c index b88b3532ef..c09ccabb29 100644 --- a/source3/libsmb/cli_reg.c +++ b/source3/libsmb/cli_reg.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 2.2 + Unix SMB/CIFS implementation. RPC Pipe client Copyright (C) Andrew Tridgell 1992-1998, diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index ddcfe89078..53203e3d79 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 2.2 + Unix SMB/CIFS implementation. RPC pipe client Copyright (C) Tim Potter 2000-2001, Copyright (C) Andrew Tridgell 1992-1997,2000, diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index b828640c3b..1bc71c9718 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1,5 +1,5 @@ /* - Unix SMB/Netbios implementation. + Unix SMB/CIFS implementation. RPC pipe client Copyright (C) Gerald Carter 2001, diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index c9bd464362..297ca1e8e0 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. NT Domain Authentication SMB / MSRPC client Copyright (C) Andrew Tridgell 1994-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 86ff6b5c92..b7828f4993 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 1dffe67968..0b07bc2c99 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client dgram calls Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Richard Sharpe 2001 diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 50f9a7dc81..7d6258b24a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. SMB client generic functions Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 637f362ae8..89550d18ed 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client error handling routines Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 4b7c173a63..71b3f44b0d 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client file operations Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Jeremy Allison 2001-2002 diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index cc77c08d26..685c4a25e0 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 0c80044b68..8b28e05a47 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client directory list routines Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 5ded79de96..1587e6f4cd 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client message handling routines Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index dca0e96cb4..0ffeb1926b 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. SMB client oplock functions Copyright (C) Andrew Tridgell 2001 diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 57e2c049d8..92fbf02e91 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client print routines Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 4484b61381..42f1f652eb 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client RAP calls Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 2fde0c70e5..00cd4b15f3 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1,6 +1,5 @@ /* Samba Unix/Linux SMB client library - Version 3.0 More client RAP (SMB Remote Procedure Calls) functions Copyright (C) 2001 Steve French (sfrench@us.ibm.com) Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com) diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 93333bff95..627bab88a5 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client file read/write routines Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 0e0884b843..5de67b1e05 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client security descriptor functions Copyright (C) Andrew Tridgell 2000 diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 035b47b417..a962953b90 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index baec3e5da8..3c9964368e 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client string routines Copyright (C) Andrew Tridgell 2001 diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 5b53413012..3d862a1796 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client transaction calls Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 5f65c13edd..fb874fc1db 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. code to manipulate domain credentials Copyright (C) Andrew Tridgell 1997-1998 diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 28b4cb0431..a4a5a8741e 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1,6 +1,5 @@ /* - * Unix SMB/Netbios implementation. - * Version 3.0 + * Unix SMB/CIFS implementation. * error mapping functions * Copyright (C) Andrew Tridgell 2001 * diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3b6252dd54..67e95d09d7 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 2.0 + Unix SMB/CIFS implementation. SMB client library implementation Copyright (C) Andrew Tridgell 1998 Copyright (C) Richard Sharpe 2000 diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index d90cd6a7ea..f03ede10cd 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. name query routines Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index d4063242f6..707baba10b 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. Universal groups helpers Copyright (C) Alexander Bokovoy 2002. Copyright (C) Andrew Bartlett 2002. diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 0061a4b977..0d14461547 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. NBT netbios library routines Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index f4d64653e4..4d13caba91 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -1,6 +1,5 @@ /* - * Unix SMB/Netbios implementation. - * Version 1.9. + * Unix SMB/CIFS implementation. * RPC Pipe client / server routines * Copyright (C) Luke Kenneth Casson Leighton 1997-2001. * diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 335d9a7d1a..b96bdc95a1 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. SMB client password change routine Copyright (C) Andrew Tridgell 1994-1998 diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 9404588223..7d1185d9a7 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. Password cacheing. obfuscation is planned Copyright (C) Luke Kenneth Casson Leighton 1996-1998 diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 866fc0c7e0..dd50feb44d 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. a partial implementation of DES designed for use in the SMB authentication protocol diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index b0fecd1c19..6fa8de418a 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. SMB parameters and setup Copyright (C) Andrew Tridgell 1992-1998 Modified by Jeremy Allison 1995. diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 3ef4eaf989..757629a2d5 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. Copyright (C) Andrew Tridgell 1998 This program is free software; you can redistribute it and/or modify diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index c096a1354d..069be7f15e 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -1,6 +1,5 @@ /* - * Unix SMB/Netbios implementation. - * Version 3.0 + * Unix SMB/CIFS implementation. * Routines to change trust account passwords. * Copyright (C) Andrew Bartlett 2001. * diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index b77e7490a0..f74a05f75f 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. handle unexpected packets Copyright (C) Andrew Tridgell 2000 -- cgit From 359dfddcda49f03003747df4ec9a37a11bb35bad Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 31 Jan 2002 11:37:48 +0000 Subject: Added addform, setform and deleteform cli functions. (This used to be commit a7e67dc00ae1a9a80875f2708def6565af0c6f0e) --- source3/libsmb/cli_spoolss.c | 164 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 1bc71c9718..d5ea9d4e20 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1170,4 +1170,168 @@ NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli, return result; } +/** Add a form to a printer. + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param handle Policy handle opened with cli_spoolss_open_printer_ex + * or cli_spoolss_addprinterex. + * @param level Form info level to add - should always be 1. + * @param form A pointer to the form to be added. + * + */ + +WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *handle, uint32 level, FORM *form) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ADDFORM q; + SPOOL_R_ADDFORM r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_addform(&q, handle, level, form); + + /* Marshall data and send request */ + + if (!spoolss_io_q_addform("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_addform("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/** Set a form on a printer - this doesn't seem to work very well. + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param handle Policy handle opened with cli_spoolss_open_printer_ex + * or cli_spoolss_addprinterex. + * @param level Form info level to set - should always be 1. + * @param form A pointer to the form to be set. + * + */ + +WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *handle, uint32 level, FORM *form) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETFORM q; + SPOOL_R_SETFORM r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setform(&q, handle, level, form); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setform("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setform("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/** Delete a form on a printer - this doesn't seem to work very well. + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param handle Policy handle opened with cli_spoolss_open_printer_ex + * or cli_spoolss_addprinterex. + * @param form The name of the form to delete. + * + */ + +WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *handle, char *form) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_DELETEFORM q; + SPOOL_R_DELETEFORM r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_deleteform(&q, handle, form); + + /* Marshall data and send request */ + + if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_deleteform("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 69adbb0ce3bb9d5bd569c13aaa3ac8f390c1586a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Jan 2002 23:26:12 +0000 Subject: Fix from Michael Steffens to make signal processing work correctly in winbindd. This is a really good patch that gives full select semantics to the Samba modified select. Jeremy. (This used to be commit 3af16ade173cac24c1ac5eff4a36b439f16ac036) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 0d14461547..c78946fa09 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -952,7 +952,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - if ((ret = sys_select_intr(fd+1,&fds,&timeout)) == -1) { + if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) { /* errno should be EBADF or EINVAL. */ DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); return NULL; -- cgit From 5d2302899a78382dfbdf08ced2cca252cd1f4d63 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 5 Feb 2002 01:30:02 +0000 Subject: fixed a bug in qpathinfo client code (This used to be commit 22f348a1f9501cc00d46d6c6064f71198558c0ee) --- source3/libsmb/clirap.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 42f1f652eb..1cbadb4344 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -372,6 +372,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, { int data_len = 0; int param_len = 0; + int rparam_len, rdata_len; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -397,9 +398,10 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, NULL, data_len, cli->max_xmit /* data, length, max */ ) && cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)); - if (!ret && cli_is_dos_error(cli)) { + &rparam, &rparam_len, + &rdata, &rdata_len)); + if (!cli_is_dos_error(cli)) break; + if (!ret) { /* we need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; @@ -410,7 +412,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, } } while (count-- && ret==False); - if (!ret || !rdata || data_len < 22) { + if (!ret || !rdata || rdata_len < 22) { return False; } -- cgit From 8cd8cfd4cfc916cab4e5d695722da91d9b1f05df Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 13 Feb 2002 16:44:49 +0000 Subject: merge from 2.2 (This used to be commit 50fa21c995d33601920b3b56a3e03b09262e7fd9) --- source3/libsmb/cli_lsarpc.c | 4 ++-- source3/libsmb/clierror.c | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 7ba47d3a18..d3c7db70a2 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -1075,8 +1075,8 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); } if (!attempt_netbios_session_request(&cli, global_myname, remote_machine, &cli.dest_ip)) { - DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS \ -session request. Error was %s\n", remote_machine, cli_errstr(&cli) )); + DEBUG(0,("fetch_domain_sid: machine %s rejected the NetBIOS session request.\n", + remote_machine)); goto done; } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 89550d18ed..13ea6b1997 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -80,6 +80,11 @@ char *cli_errstr(struct cli_state *cli) uint8 errclass; int i; + if (!cli->initialised) { + fstrcpy(cli_error_message, "[Programmer's error] cli_errstr called on unitialized cli_stat struct!\n"); + return cli_error_message; + } + /* Case #1: RAP error */ if (cli->rap_error) { for (i = 0; rap_errmap[i].message != NULL; i++) { -- cgit From ba9341c7de216acea5fc194fb42944714553a1a5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 15 Feb 2002 23:11:13 +0000 Subject: Try not to malloc -1 bytes (apx 4GB) when the data is already in error. Andrew Bartlett (This used to be commit ad1faf8fa4019cb57fbb7f311f6d4943359bcd45) --- source3/libsmb/clispnego.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a962953b90..a4fcfa5d9a 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -247,13 +247,23 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) { BOOL ret; ASN1_DATA data; + int data_remaining; asn1_load(&data, blob); asn1_start_tag(&data, ASN1_APPLICATION(0)); asn1_check_OID(&data, OID_KERBEROS5); asn1_check_BOOLEAN(&data, 0); - *ticket = data_blob(data.data, asn1_tag_remaining(&data)); - asn1_read(&data, ticket->data, ticket->length); + + data_remaining = asn1_tag_remaining(&data); + + if (data_remaining < 1) { + data.has_error = True; + } else { + + *ticket = data_blob(data.data, data_remaining); + asn1_read(&data, ticket->data, ticket->length); + } + asn1_end_tag(&data); ret = !data.has_error; -- cgit From e13465b19aaa1df7ab0f18a23c5ad1118975d46f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 19 Feb 2002 01:06:14 +0000 Subject: Added cli_spoolss_initialise() function. Converted cli_spoolss_enumprinterdrivers() to pass offered and *needed as parameters and return a WERROR. (This used to be commit b595c258295ecc4824fe89ba1136c778a1700e28) --- source3/libsmb/cli_spoolss.c | 133 +++++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 61 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index d5ea9d4e20..181852ef7f 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -3,7 +3,7 @@ RPC pipe client Copyright (C) Gerald Carter 2001, - Copyright (C) Tim Potter 2000-2001, + Copyright (C) Tim Potter 2000-2002, Copyright (C) Andrew Tridgell 1994-2000, Copyright (C) Luke Kenneth Casson Leighton 1996-2000, Copyright (C) Jean-Francois Micouleau 1999-2000. @@ -31,6 +31,20 @@ * @{ **/ +/** Opens a SMB connection and connects to the SPOOLSS pipe. + * + * @param cli Uninitialised client handle. + * @param system_name NETBIOS name of the machine to connect to. + * @param creds User credentials to connect as. + * @returns Initialised client handle. + */ +struct cli_state *cli_spoolss_initialise(struct cli_state *cli, + char *system_name, + struct ntuser_creds *creds) +{ + return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds); +} + /** Return a handle to the specified printer or print server. * * @param cli Pointer to client state structure which is open @@ -780,22 +794,19 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, /********************************************************************** * Get installed printer drivers for a given printer */ -NTSTATUS cli_spoolss_enumprinterdrivers ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 level, - char* env, - uint32 *returned, - PRINTER_DRIVER_CTR *ctr -) +WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + uint32 level, char *env, + uint32 *num_drivers, + PRINTER_DRIVER_CTR *ctr) { - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDRIVERS q; - SPOOL_R_ENUMPRINTERDRIVERS r; - NEW_BUFFER buffer; - uint32 needed = 0; - NTSTATUS result; - fstring server; + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMPRINTERDRIVERS q; + SPOOL_R_ENUMPRINTERDRIVERS r; + NEW_BUFFER buffer; + WERROR result = W_ERROR(ERRgeneral); + fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -803,60 +814,60 @@ NTSTATUS cli_spoolss_enumprinterdrivers ( slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - do - { - /* Initialise input parameters */ - init_buffer(&buffer, needed, mem_ctx); + /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + init_buffer(&buffer, offered, mem_ctx); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - /* write the request */ - make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, needed); + /* Write the request */ - /* Marshall data and send request */ - if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf)) - { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, + offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf)) + goto done; - /* Unmarshall response */ - if (spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) - { - needed = r.needed; - } - - /* Return output parameters */ - result = werror_to_ntstatus(r.status); - if (NT_STATUS_IS_OK(result) && - (r.returned != 0)) - { - *returned = r.returned; + /* Unmarshall response */ - switch (level) - { - case 1: - decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1); - break; - case 2: - decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2); - break; - case 3: - decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); - break; - } - } + if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) + goto done; - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); + if (needed) + *needed = r.needed; - } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); + if (num_drivers) + *num_drivers = r.returned; - return result; + result = r.status; + + /* Return output parameters */ + + if (W_ERROR_IS_OK(result) && (r.returned != 0)) { + *num_drivers = r.returned; + + switch (level) { + case 1: + decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1); + break; + case 2: + decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2); + break; + case 3: + decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); + break; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; } -- cgit From 902cc03807f83167ff9a1d93a09844b27eba6ada Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 19 Feb 2002 02:12:01 +0000 Subject: Converted {cmd,cli}_spoolss_getprinter() to WERROR and offered/neede. (This used to be commit fccfa034e92bca145b8e0639e405f6af5bb1a50b) --- source3/libsmb/cli_spoolss.c | 94 +++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 49 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 181852ef7f..661543ebfa 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -582,71 +582,67 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, } /* Get printer info */ -NTSTATUS cli_spoolss_getprinter( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint32 level, - PRINTER_INFO_CTR *ctr -) +WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *pol, uint32 level, + PRINTER_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTER q; SPOOL_R_GETPRINTER r; NEW_BUFFER buffer; - uint32 needed = 100; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); ZERO_STRUCT(q); ZERO_STRUCT(r); - do { - /* Initialise input parameters */ + /* Initialise input parameters */ + + init_buffer(&buffer, offered, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - init_buffer(&buffer, needed, mem_ctx); + make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, offered); + + /* Marshall data and send request */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf)) + goto done; - make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, needed); + /* Unmarshall response */ - /* Marshall data and send request */ - if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf)) - { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if (!spoolss_io_r_getprinter("", &r, &rbuf, 0)) + goto done; - /* Unmarshall response */ - if (spoolss_io_r_getprinter("", &r, &rbuf, 0)) { - needed = r.needed; - } - - /* Return output parameters */ - result = werror_to_ntstatus(r.status); - if (NT_STATUS_IS_OK(result)) { - switch (level) { - case 0: - decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); - break; - case 1: - decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1); - break; - case 2: - decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2); - break; - case 3: - decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3); - break; - } - } + if (needed) + *needed = r.needed; + + /* Return output parameters */ - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); + result = r.status; - } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); + if (NT_STATUS_IS_OK(result)) { + switch (level) { + case 0: + decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); + break; + case 1: + decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1); + break; + case 2: + decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2); + break; + case 3: + decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3); + break; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); return result; } -- cgit From e026103a975c3ab16f99118a53f585e7d34ad1da Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 20 Feb 2002 18:41:07 +0000 Subject: Converted remaining spoolss rpcclient functions to werror/needed/offered. I couldn't test some of these because I didn't know the right magic arguments to pass to rpcclient (familiar anyone? (-:) so there may be some bugs lurking. (This used to be commit 029e2b307d91171168040e71d2e5d5e0d01b7633) --- source3/libsmb/cli_spoolss.c | 278 ++++++++++++++++++++----------------------- 1 file changed, 128 insertions(+), 150 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 661543ebfa..c11debba33 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -582,6 +582,7 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, } /* Get printer info */ + WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, POLICY_HND *pol, uint32 level, @@ -647,53 +648,57 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/********************************************************************** - * Set printer info +/** Set printer info + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param pol Policy handle on printer to set info. + * @param level Information level to set. + * @param ctr Pointer to structure holding printer information. + * @param command Specifies the action performed. See + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp + * for details. + * */ -NTSTATUS cli_spoolss_setprinter( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - POLICY_HND *pol, - uint32 level, - PRINTER_INFO_CTR *ctr, - uint32 command -) + +WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 level, + PRINTER_INFO_CTR *ctr, uint32 command) { prs_struct qbuf, rbuf; SPOOL_Q_SETPRINTER q; SPOOL_R_SETPRINTER r; - NTSTATUS result = NT_STATUS_ACCESS_DENIED; + WERROR result = W_ERROR(ERRgeneral); ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); /* Marshall data and send request */ + if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) - { - result = NT_STATUS_ACCESS_DENIED; + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) - { + + if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) goto done; - } - result = werror_to_ntstatus(r.status); - + result = r.status; + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - return result; } @@ -870,20 +875,17 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, /********************************************************************** * Get installed printer drivers for a given printer */ -NTSTATUS cli_spoolss_getprinterdriverdir ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 level, - char* env, - DRIVER_DIRECTORY_CTR *ctr -) +WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + uint32 level, char *env, + DRIVER_DIRECTORY_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTERDRIVERDIR q; SPOOL_R_GETPRINTERDRIVERDIR r; NEW_BUFFER buffer; - uint32 needed = 100; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); @@ -892,67 +894,63 @@ NTSTATUS cli_spoolss_getprinterdriverdir ( slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - do - { - /* Initialise input parameters */ - init_buffer(&buffer, needed, mem_ctx); + /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + init_buffer(&buffer, offered, mem_ctx); + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Write the request */ - /* write the request */ - make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, needed); + make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, + offered); - /* Marshall data and send request */ - if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, &qbuf, &rbuf)) - { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + /* Marshall data and send request */ - /* Unmarshall response */ - if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) - { - needed = r.needed; - } + if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, + &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) { + if (needed) + *needed = r.needed; + } - /* Return output parameters */ - result = werror_to_ntstatus(r.status); - if (NT_STATUS_IS_OK(result)) - { - switch (level) - { - case 1: - decode_printerdriverdir_1(mem_ctx, r.buffer, 1, &ctr->info1); - break; - } - } + /* Return output parameters */ + + result = r.status; + if (W_ERROR_IS_OK(result)) { + switch (level) { + case 1: + decode_printerdriverdir_1(mem_ctx, r.buffer, 1, + &ctr->info1); + break; + } + } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); - } while (NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); - - return result; + return result; } /********************************************************************** * Install a printer driver */ -NTSTATUS cli_spoolss_addprinterdriver ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 level, - PRINTER_DRIVER_CTR *ctr -) +WERROR cli_spoolss_addprinterdriver (struct cli_state *cli, + TALLOC_CTX *mem_ctx, uint32 level, + PRINTER_DRIVER_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ADDPRINTERDRIVER q; SPOOL_R_ADDPRINTERDRIVER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); @@ -962,31 +960,28 @@ NTSTATUS cli_spoolss_addprinterdriver ( strupper (server); /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + /* Write the request */ - /* write the request */ make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr); /* Marshall data and send request */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) - { + !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) goto done; - } - /* Unmarshall response */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0)) - { goto done; - } /* Return output parameters */ - result = werror_to_ntstatus(r.status); + + result = r.status; done: prs_mem_free(&qbuf); @@ -998,17 +993,13 @@ done: /********************************************************************** * Install a printer */ -NTSTATUS cli_spoolss_addprinterex ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 level, - PRINTER_INFO_CTR *ctr -) +WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 level, PRINTER_INFO_CTR*ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ADDPRINTEREX q; SPOOL_R_ADDPRINTEREX r; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server, client, user; @@ -1021,36 +1012,33 @@ NTSTATUS cli_spoolss_addprinterex ( slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); fstrcpy (user, cli->user_name); - /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + /* Write the request */ - /* write the request */ - make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, level, ctr); + make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, + level, ctr); /* Marshall data and send request */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) || !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf)) - { goto done; - } - /* Unmarshall response */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0)) - { goto done; - } /* Return output parameters */ - result = werror_to_ntstatus(r.status); -done: + result = r.status; + + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); @@ -1061,53 +1049,47 @@ done: * Delete a Printer Driver from the server (does not remove * the driver files */ -NTSTATUS cli_spoolss_deleteprinterdriver ( - struct cli_state *cli, - TALLOC_CTX *mem_ctx, - char *arch, - char *driver -) +WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, + TALLOC_CTX *mem_ctx, char *arch, + char *driver) { prs_struct qbuf, rbuf; SPOOL_Q_DELETEPRINTERDRIVER q; SPOOL_R_DELETEPRINTERDRIVER r; - NTSTATUS result; + WERROR result = W_ERROR(ERRgeneral); fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); - /* Initialise input parameters */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); strupper (server); - /* write the request */ - make_spoolss_q_deleteprinterdriver (mem_ctx, &q, server, arch, driver); + /* Write the request */ + + make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver); /* Marshall data and send request */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) - { + !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) goto done; - } - /* Unmarshall response */ - result = NT_STATUS_UNSUCCESSFUL; + if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0)) - { goto done; - } /* Return output parameters */ - result = werror_to_ntstatus(r.status); -done: + result = r.status; + + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); @@ -1116,59 +1098,55 @@ done: /* Get print processor directory */ -NTSTATUS cli_spoolss_getprintprocessordirectory(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - char *name, - char *environment, - fstring procdir) +WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, + TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + char *name, char *environment, + fstring procdir) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTPROCESSORDIRECTORY q; SPOOL_R_GETPRINTPROCESSORDIRECTORY r; - NTSTATUS result; int level = 1; + WERROR result = W_ERROR(ERRgeneral); NEW_BUFFER buffer; - uint32 needed = 100; ZERO_STRUCT(q); ZERO_STRUCT(r); /* Initialise parse structures */ + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); /* Initialise input parameters */ - do { - init_buffer(&buffer, needed, mem_ctx); + init_buffer(&buffer, offered, mem_ctx); - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_getprintprocessordirectory(&q, name, - environment, level, - &buffer, needed); + make_spoolss_q_getprintprocessordirectory( + &q, name, environment, level, &buffer, offered); - /* Marshall data and send request */ + /* Marshall data and send request */ - if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, + &qbuf, &rbuf)) + goto done; - /* Unmarshall response */ + /* Unmarshall response */ - if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } + if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) + goto done; - /* Return output parameters */ + /* Return output parameters */ - result = werror_to_ntstatus(r.status); + result = r.status; + + if (needed) + *needed = r.needed; - } while (NT_STATUS_V(result) == - NT_STATUS_V(NT_STATUS_BUFFER_TOO_SMALL)); + if (W_ERROR_IS_OK(result)) + fstrcpy(procdir, "Not implemented!"); done: prs_mem_free(&qbuf); -- cgit From dc3584b4179f50e556013cb99db4cb3749f02550 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Feb 2002 22:34:35 +0000 Subject: This fixes a bug (spotted by Rafal Szczesniak ) where we pass the client's name. We should pass the servers name. Andrew Bartlett (This used to be commit aeecb7a06b006e69879f00699f4b8b6497553d19) --- source3/libsmb/cli_lsarpc.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index d3c7db70a2..249225d894 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -108,7 +108,10 @@ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Open a LSA policy handle */ +/** Open a LSA policy handle + * + * @param cli Handle on an initialised SMB connection + */ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, BOOL sec_qos, uint32 des_access, POLICY_HND *pol) @@ -131,10 +134,10 @@ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (sec_qos) { init_lsa_sec_qos(&qos, 2, 1, 0); - init_q_open_pol2(&q, cli->clnt_name_slash, 0, des_access, + init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access, &qos); } else { - init_q_open_pol2(&q, cli->clnt_name_slash, 0, des_access, + init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access, NULL); } @@ -435,7 +438,9 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Query info policy */ +/** Query info policy + * + * @param domain_sid - returned remote server's domain sid */ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint16 info_class, -- cgit From 0cbcf49f6cfb91a7251baa5339795436308578ea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 21 Feb 2002 04:25:17 +0000 Subject: added cli_qfilename(), used in trans2 torture test (This used to be commit d37905f20397911e4f74e672ebdee28f1ddf3c2c) --- source3/libsmb/clirap.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 1cbadb4344..a2b6c8bb8b 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -514,6 +514,49 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, } +/**************************************************************************** +send a qfileinfo QUERY_FILE_NAME_INFO call +****************************************************************************/ +BOOL cli_qfilename(struct cli_state *cli, int fnum, + pstring name) +{ + int data_len = 0; + int param_len = 0; + uint16 setup = TRANSACT2_QFILEINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + + param_len = 4; + memset(param, 0, param_len); + SSVAL(param, 0, fnum); + SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + if (!rdata || data_len < 4) { + return False; + } + + clistr_pull(cli, name, rdata+4, sizeof(pstring), IVAL(rdata, 0), STR_UNICODE); + + return True; +} + + /**************************************************************************** send a qfileinfo call ****************************************************************************/ -- cgit From bb117fdca700a34564c1fcfbe607d0e28d2462d0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 25 Feb 2002 06:43:31 +0000 Subject: Implemented client side functions for SPOOLSS addform, getform, setform and enumforms. (This used to be commit e69222f0816878e3211e3dedb049de50ca90fed0) --- source3/libsmb/cli_spoolss.c | 166 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 160 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index c11debba33..3aaff10b49 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1210,7 +1210,7 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Set a form on a printer - this doesn't seem to work very well. +/** Set a form on a printer. * * @param cli Pointer to client state structure which is open * on the SPOOLSS pipe. @@ -1224,7 +1224,8 @@ WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx, */ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, uint32 level, FORM *form) + POLICY_HND *handle, uint32 level, char *form_name, + FORM *form) { prs_struct qbuf, rbuf; SPOOL_Q_SETFORM q; @@ -1241,7 +1242,7 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - make_spoolss_q_setform(&q, handle, level, form); + make_spoolss_q_setform(&q, handle, level, form_name, form); /* Marshall data and send request */ @@ -1258,6 +1259,77 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; + if (!W_ERROR_IS_OK(result)) + goto done; + + + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/** Get a form on a printer. + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param handle Policy handle opened with cli_spoolss_open_printer_ex + * or cli_spoolss_addprinterex. + * @param formname Name of the form to get + * @param level Form info level to get - should always be 1. + * + */ + +WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *handle, char *formname, uint32 level, + FORM_1 *form) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETFORM q; + SPOOL_R_GETFORM r; + WERROR result = W_ERROR(ERRgeneral); + NEW_BUFFER buffer; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + init_buffer(&buffer, offered, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getform(&q, handle, formname, level, &buffer, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getform("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getform("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (needed) + *needed = r.needed; + + if (W_ERROR_IS_OK(result)) + smb_io_form_1("", r.buffer, form, 0); + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); @@ -1265,7 +1337,7 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Delete a form on a printer - this doesn't seem to work very well. +/** Delete a form on a printer. * * @param cli Pointer to client state structure which is open * on the SPOOLSS pipe. @@ -1278,7 +1350,7 @@ WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, */ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, char *form) + POLICY_HND *handle, char *form_name) { prs_struct qbuf, rbuf; SPOOL_Q_DELETEFORM q; @@ -1295,7 +1367,7 @@ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - make_spoolss_q_deleteform(&q, handle, form); + make_spoolss_q_deleteform(&q, handle, form_name); /* Marshall data and send request */ @@ -1319,4 +1391,86 @@ WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 num_forms, FORM_1 **forms) +{ + int i; + + *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1)); + buffer->prs.data_offset = 0; + + for (i = 0; i < num_forms; i++) + smb_io_form_1("", buffer, &((*forms)[i]), 0); +} + +/** Enumerate forms + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param offered Buffer size offered in the request. + * @param needed Number of bytes needed to complete the request. + * may be NULL. + * or cli_spoolss_addprinterex. + * @param level Form info level to get - should always be 1. + * @param handle Open policy handle + * + */ + +WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *handle, int level, uint32 *num_forms, + FORM_1 **forms) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMFORMS q; + SPOOL_R_ENUMFORMS r; + WERROR result = W_ERROR(ERRgeneral); + NEW_BUFFER buffer; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + init_buffer(&buffer, offered, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enumforms(&q, handle, level, &buffer, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enumforms("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (needed) + *needed = r.needed; + + if (num_forms) + *num_forms = r.numofforms; + + decode_forms_1(mem_ctx, r.buffer, *num_forms, forms); + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 62299aa7475bad48ba3e230596f09e794c2b4ce5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 26 Feb 2002 17:40:43 +0000 Subject: bcopy must DIE ! Stop people creeping use of bcopy back into the code (and yes I know who you are..... :-). Jeremy. (This used to be commit 330b0df960329bcf4696b8fa4a7357e6c456f74e) --- source3/libsmb/clidgram.c | 2 +- source3/libsmb/libsmbclient.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 0b07bc2c99..abade68b01 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -117,7 +117,7 @@ int cli_get_response(int dgram_sock, BOOL unique, char *mailslot, char *buf, int /* Copy the data to buffer, respecting sizes ... */ - bcopy(&dgram->data[92], buf, MIN(bufsiz, (dgram->datasize - 92))); + memset(buf, &dgram->data[92], MIN(bufsiz, (dgram->datasize - 92))); } else diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 67e95d09d7..01b4186553 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1908,7 +1908,7 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) /* Hmmm, do I even need to copy it? */ - bcopy(dirent, smbc_local_dirent, dirent->dirlen); /* Copy the dirent */ + memcpy(smbc_local_dirent, dirent, dirent->dirlen); /* Copy the dirent */ dirp = (struct smbc_dirent *)smbc_local_dirent; @@ -2000,7 +2000,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) dirent = dir->dirent; - bcopy(dirent, ndir, reqd); /* Copy the data in ... */ + memcpy(ndir, dirent, reqd); /* Copy the data in ... */ ((struct smbc_dirent *)ndir)->comment = (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1); -- cgit From c72d16a10504d9b26a616aef9d04b131739c8b90 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Feb 2002 17:28:22 +0000 Subject: Fixed dumb typo caught by Herb. Jeremy. (This used to be commit f7c980d61439f42395a457a5b99b28f526cabe69) --- source3/libsmb/clidgram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index abade68b01..8f4bdf7be6 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -117,7 +117,7 @@ int cli_get_response(int dgram_sock, BOOL unique, char *mailslot, char *buf, int /* Copy the data to buffer, respecting sizes ... */ - memset(buf, &dgram->data[92], MIN(bufsiz, (dgram->datasize - 92))); + memcpy(buf, &dgram->data[92], MIN(bufsiz, (dgram->datasize - 92))); } else -- cgit From df43f3d41009f170295f93f6d6df1b6e84077616 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 Feb 2002 01:05:15 +0000 Subject: Ensure that winbindd and smbd both use identical logic to find dc's. Fix bug where zeroip addresses were being checked. Jeremy. (This used to be commit 8ed49fe0df201833329c17b2afe1e3aa70646558) --- source3/libsmb/namequery.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f03ede10cd..0370365953 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1269,6 +1269,14 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ } +/******************************************************** + Get the IP address list of the Local Master Browsers + ********************************************************/ + +BOOL get_lmb_list(struct in_addr **ip_list, int *count) +{ + return internal_resolve_name( MSBROWSE, 0x1, ip_list, count); +} /******************************************************** Get the IP address list of the PDC/BDC's of a Domain. @@ -1320,11 +1328,3 @@ BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int } else return internal_resolve_name(group, name_type, ip_list, count); } - -/******************************************************** - Get the IP address list of the Local Master Browsers - ********************************************************/ -BOOL get_lmb_list(struct in_addr **ip_list, int *count) -{ - return internal_resolve_name( MSBROWSE, 0x1, ip_list, count); -} -- cgit From cd76214b15246553284ca43441780d49cf2f5819 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 1 Mar 2002 02:54:04 +0000 Subject: Another comment fix for mirmir (This used to be commit 7412890adc8f3dfddfabba545003715816e262bc) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7d6258b24a..ba7a327344 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -138,7 +138,7 @@ void cli_setup_bcc(struct cli_state *cli, void *p) /**************************************************************************** -initialise a client structure +initialise credentials of a client structure ****************************************************************************/ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { -- cgit From 75de5a5dfa4ccd2f46e9f1bddad7ca2d0d2e665e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 1 Mar 2002 02:56:35 +0000 Subject: The beginning of trusted and trusting domain support from Rafal Szczesniak This adds the 'net' tools to manipulate the trusted domains. Andrew Bartlett (This used to be commit 770c8a31d9804d3339ffa0de8b5072a5c7eb02df) --- source3/libsmb/cli_wkssvc.c | 112 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 source3/libsmb/cli_wkssvc.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c new file mode 100644 index 0000000000..391aee1782 --- /dev/null +++ b/source3/libsmb/cli_wkssvc.c @@ -0,0 +1,112 @@ +/* + Unix SMB/CIFS implementation. + NT Domain Authentication SMB / MSRPC client + Copyright (C) Andrew Tridgell 1994-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Tim Potter 2001 + Copytight (C) Rafal Szczesniak 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/** + * Opens a SMB connection to the wkssvc pipe + * + * @param cli client structure (not yet initialised) + * @param system_name called rpc server name + * @param creds user credentials + * + * @return client structure with opened pipe + **/ + +struct cli_state *cli_wkssvc_initialise(struct cli_state *cli, + char *system_name, + struct ntuser_creds *creds) +{ + return cli_pipe_initialise(cli, system_name, PIPE_WKSSVC, creds); +} + + +/** + * WksQueryInfo rpc call (like query for server's capabilities) + * + * @param initialised client structure with \PIPE\wkssvc opened + * @param mem_ctx memory context assigned to this rpc binding + * @param wks100 WksQueryInfo structure + * + * @return NTSTATUS of rpc call + */ + +NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, + WKS_INFO_100 *wks100) +{ + prs_struct buf; + prs_struct rbuf; + WKS_Q_QUERY_INFO q_o; + WKS_R_QUERY_INFO r_o; + NTSTATUS nt_status; + + if (cli == NULL || wks100 == NULL) + return NT_STATUS_UNSUCCESSFUL; + + /* init rpc parse structures */ + prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + DEBUG(4, ("WksQueryInfo\n")); + + /* init query structure with rpc call arguments */ + init_wks_q_query_info(&q_o, cli->desthost, 100); + + /* marshall data */ + if (!wks_io_q_query_info("", &q_o, &buf, 0)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return NT_STATUS_UNSUCCESSFUL; + } + + /* actual rpc call over \PIPE\wkssvc */ + if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) { + prs_mem_free(&buf); + prs_mem_free(&rbuf); + return NT_STATUS_UNSUCCESSFUL; + } + + prs_mem_free(&buf); + + r_o.wks100 = wks100; + + /* get call results from response buffer */ + if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) { + prs_mem_free(&rbuf); + return NT_STATUS_UNSUCCESSFUL; + } + + /* check returnet status code */ + if (NT_STATUS_IS_ERR(r_o.status)) { + /* report the error */ + DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status))); + prs_mem_free(&rbuf); + return r_o.status; + } + + /* do clean up */ + prs_mem_free(&rbuf); + + return nt_status; +} + -- cgit From e51c3224d0b8b5760c48ebe4f859f27cf3c202b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 2 Mar 2002 04:41:55 +0000 Subject: Add a dash of const here and there... (This used to be commit 413a46292b4e963343abce2428955305052e9cb4) --- source3/libsmb/credentials.c | 6 +++--- source3/libsmb/smbdes.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index fb874fc1db..0d521bae8a 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -23,7 +23,7 @@ /**************************************************************************** represent a credential as a string ****************************************************************************/ -char *credstr(uchar *cred) +char *credstr(const uchar *cred) { static fstring buf; slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", @@ -41,7 +41,7 @@ Input: 8 byte challenge block Output: 8 byte session key ****************************************************************************/ -void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, +void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass, uchar session_key[8]) { uint32 sum[2]; @@ -53,7 +53,7 @@ void cred_session_key(DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, char *pass, SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(session_key, sum2,(unsigned char *)pass); + cred_hash1(session_key, sum2, pass); /* debug output */ DEBUG(4,("cred_session_key\n")); diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index dd50feb44d..440121d126 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -330,7 +330,7 @@ void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char * smbhash(out+8, in+8, p14+7, 1); } -void cred_hash1(unsigned char *out, const unsigned char *in,unsigned char *key) +void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char *key) { unsigned char buf[8]; @@ -338,7 +338,7 @@ void cred_hash1(unsigned char *out, const unsigned char *in,unsigned char *key) smbhash(out, buf, key+9, 1); } -void cred_hash2(unsigned char *out, const unsigned char *in,unsigned char *key) +void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key) { unsigned char buf[8]; static unsigned char key2[8]; @@ -348,7 +348,7 @@ void cred_hash2(unsigned char *out, const unsigned char *in,unsigned char *key) smbhash(out, buf, key2, 1); } -void cred_hash3(unsigned char *out,unsigned char *in,unsigned char *key, int forw) +void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw) { static unsigned char key2[8]; -- cgit From 81b2d66c970c0df94823ad96f50b992fff0c8b94 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 2 Mar 2002 08:25:44 +0000 Subject: Allow Samba to trust NT4 Domains. This commit builds on the auth subsystem to give Samba support for trusting NT4 domains. It is off by default, but is enabled by adding 'trustdomain' to the 'auth methods' smb.conf paramater. Tested against NT4 only - there are still some issues with the join code for Win2k servers (spnego stuff). The main work TODO involves enumerating the trusted domains (including the RPC calls to match), and getting winbind to run on the PDC correctly. Similarly, work remains on getting NT4 to trust Samba domains. Andrew Bartlett (This used to be commit ac8c24a9a888a3f916e8b40238b936e6ad743ef7) --- source3/libsmb/cli_netlogon.c | 13 +++++++------ source3/libsmb/trust_passwd.c | 3 ++- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index d550c3e9fa..590f5f525e 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -93,14 +93,15 @@ Ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ -NTSTATUS new_cli_net_auth2(struct cli_state *cli, uint16 sec_chan, +NTSTATUS new_cli_net_auth2(struct cli_state *cli, + uint16 sec_chan, uint32 neg_flags, DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; NET_Q_AUTH_2 q; NET_R_AUTH_2 r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - extern pstring global_myname; + extern pstring global_myname; prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); @@ -163,7 +164,8 @@ password ?).\n", cli->desthost )); /* Initialize domain session credentials */ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, - unsigned char mach_pwd[16]) + uint16 sec_chan, + const unsigned char mach_pwd[16]) { DOM_CHAL clnt_chal; DOM_CHAL srv_chal; @@ -185,7 +187,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, /**************** Long-term Session key **************/ /* calculate the session key */ - cred_session_key(&clnt_chal, &srv_chal, (char *)mach_pwd, + cred_session_key(&clnt_chal, &srv_chal, mach_pwd, cli->sess_key); memset((char *)cli->sess_key+8, '\0', 8); @@ -201,8 +203,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, * Receive an auth-2 challenge response and check it. */ - result = new_cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, + result = new_cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed %s\n", diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 069be7f15e..1f52ab3611 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,7 +35,8 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = new_cli_nt_setup_creds(cli, orig_trust_passwd_hash); + result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to setup creds (%s)!\n", -- cgit From 7b07ecb750b137b9e28de5135d7d50b3c732654e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 5 Mar 2002 02:54:02 +0000 Subject: Fix error return. Jeremy. (This used to be commit 3bec83cbe9b863176ca087fd45efa6d1457b502c) --- source3/libsmb/cli_srvsvc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 297ca1e8e0..9d33149540 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -69,7 +69,7 @@ NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, goto done; } - result = r.status; + result = werror_to_ntstatus(r.status); done: prs_mem_free(&qbuf); -- cgit From 87a3a0952c36bed774bcad884d14d749f4bb491d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Mar 2002 22:55:45 +0000 Subject: Removed duplicate \n from debug message. Small tidyups. (This used to be commit 252da94ebb279c47263dfae36fd016d0a29a6dbf) --- source3/libsmb/cliconnect.c | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b7828f4993..d9df1fa640 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1206,9 +1206,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct cli_state *cli; struct in_addr ip; - if (!output_cli) { + if (!output_cli) DEBUG(0, ("output_cli is NULL!?!")); - } *output_cli = NULL; @@ -1217,9 +1216,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, again: - if (!(cli = cli_initialise(NULL))) { + if (!(cli = cli_initialise(NULL))) return NT_STATUS_NO_MEMORY; - } if (cli_set_port(cli, port) != port) { cli_shutdown(cli); @@ -1228,11 +1226,9 @@ again: ip = *dest_ip; - DEBUG(3,("Connecting to host=%s share=%s\n\n", - dest_host, service)); + DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service)); - if (!cli_connect(cli, dest_host, &ip)) - { + if (!cli_connect(cli, dest_host, &ip)) { DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", nmb_namestr(&called), inet_ntoa(*dest_ip))); cli_shutdown(cli); @@ -1255,35 +1251,31 @@ again: return NT_STATUS_UNSUCCESSFUL; } - if (!cli_negprot(cli)) - { + if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); nt_status = NT_STATUS_UNSUCCESSFUL; cli_shutdown(cli); return nt_status; } - if (!cli_session_setup(cli, user, - password, pass_len, - NULL, 0, - domain)) - { + if (!cli_session_setup(cli, user, password, pass_len, NULL, 0, + domain)) { DEBUG(1,("failed session setup\n")); nt_status = cli_nt_error(cli); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) nt_status = NT_STATUS_UNSUCCESSFUL; + if (NT_STATUS_IS_OK(nt_status)) + nt_status = NT_STATUS_UNSUCCESSFUL; return nt_status; } - if (service) - { + if (service) { if (!cli_send_tconX(cli, service, service_type, - (char*)password, pass_len)) - { + (char*)password, pass_len)) { DEBUG(1,("failed tcon_X\n")); nt_status = cli_nt_error(cli); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) nt_status = NT_STATUS_UNSUCCESSFUL; + if (NT_STATUS_IS_OK(nt_status)) + nt_status = NT_STATUS_UNSUCCESSFUL; return nt_status; } } -- cgit From 7d24b502c07174a8ec07c2aea65a5861a5606129 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 8 Mar 2002 04:43:10 +0000 Subject: Added case statment for decoding enumprinters level 0 result. (This used to be commit 33d49ed68c4d6a66217558b13d960764c235089a) --- source3/libsmb/cli_spoolss.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 3aaff10b49..2d81f63f89 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -473,6 +473,10 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; switch (level) { + case 0: + decode_printer_info_0(mem_ctx, r.buffer, r.returned, + &ctr->printers_0); + break; case 1: decode_printer_info_1(mem_ctx, r.buffer, r.returned, &ctr->printers_1); -- cgit From 69b395d2c1aff0d53d077d9fcb72adf8a3dbb4d5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 10 Mar 2002 23:16:15 +0000 Subject: better handling of a zero timeout in cli_lock (This used to be commit 56662a75f58d35cec1a5b2d6c9a4315d95a22420) --- source3/libsmb/clifile.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 71b3f44b0d..102114f871 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -579,7 +579,9 @@ BOOL cli_lock(struct cli_state *cli, int fnum, cli_send_smb(cli); - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + if (timeout != 0) { + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + } if (!cli_receive_smb(cli)) { cli->timeout = saved_timeout; @@ -680,7 +682,9 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, cli_setup_bcc(cli, p); cli_send_smb(cli); - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + if (timeout != 0) { + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 5*1000); + } if (!cli_receive_smb(cli)) { cli->timeout = saved_timeout; -- cgit From cc24c353bb79b18819873d7afb02f704d9a89fec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 Mar 2002 01:33:06 +0000 Subject: added cli_locktype() for testing different lockingX lock types (This used to be commit 136b9752fc9da86f0ad0e1f46dc389b752975aea) --- source3/libsmb/clifile.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 102114f871..05843ac5de 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -542,6 +542,59 @@ BOOL cli_close(struct cli_state *cli, int fnum) return !cli_is_error(cli); } + +/**************************************************************************** + send a lock with a specified locktype + this is used for testing LOCKING_ANDX_CANCEL_LOCK +****************************************************************************/ +NTSTATUS cli_locktype(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, unsigned char locktype) +{ + char *p; + int saved_timeout = cli->timeout; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0', smb_size); + + set_message(cli->outbuf,8,0,True); + + SCVAL(cli->outbuf,smb_com,SMBlockingX); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SCVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,fnum); + SCVAL(cli->outbuf,smb_vwv3,locktype); + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,0); + SSVAL(cli->outbuf,smb_vwv7,1); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + + p += 10; + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + + if (timeout != 0) { + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + } + + if (!cli_receive_smb(cli)) { + cli->timeout = saved_timeout; + return NT_STATUS_UNSUCCESSFUL; + } + + cli->timeout = saved_timeout; + + return cli_nt_error(cli); +} + + /**************************************************************************** Lock a file. ****************************************************************************/ @@ -746,6 +799,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ return True; } + /**************************************************************************** Do a SMBgetattrE call. ****************************************************************************/ -- cgit From 57bd576445e42a55887c41d270f2230f5136b873 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 14 Mar 2002 01:53:04 +0000 Subject: getpid() -> sys_getpid() (This used to be commit a3cea5e9ae3b53ecbc45e61a39cbce0ca1b916aa) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 01b4186553..eb2b7ae25b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -518,7 +518,7 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) /* * Hmmm, I want to get hostname as well, but I am too lazy for the moment */ - pid = getpid(); + pid = sys_getpid(); slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); } DEBUG(0,("Using netbios name %s.\n", my_netbios_name)); -- cgit From 56e3c83af1893fffcf2c54141167e91a864b4b88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 15 Mar 2002 09:19:51 +0000 Subject: this tdb was being opened without locking, which is unsafe for shared databases (This used to be commit 1394e6ed318af5fc740aa5622919f9fd26d5a8d2) --- source3/libsmb/netlogon_unigrp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index 707baba10b..979ff52bd3 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -41,7 +41,7 @@ BOOL uni_group_cache_init(void) { if (!netlogon_unigrp_tdb) { netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0, - TDB_NOLOCK, O_RDWR | O_CREAT, 0644); + TDB_DEFAULT, O_RDWR | O_CREAT, 0644); } return (netlogon_unigrp_tdb != NULL); @@ -111,7 +111,7 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, } if (!netlogon_unigrp_tdb) { netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0, - TDB_NOLOCK, O_RDWR, 0644); + TDB_DEFAULT, O_RDWR, 0644); } if (!netlogon_unigrp_tdb) { DEBUG(5,("uni_group_cache_fetch: cannot open netlogon_unigrp.tdb for read - normal if not created yet\n")); -- cgit From ab13654dc9ac23872e4d1384e1c54e336f113009 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 17 Mar 2002 04:36:35 +0000 Subject: Renamed get_nt_error_msg() to nt_errstr(). (This used to be commit 1f007d3ed41c1b71a89fa6be7d173e67e927c302) --- source3/libsmb/cli_lsarpc.c | 4 ++-- source3/libsmb/cli_netlogon.c | 4 ++-- source3/libsmb/cli_wkssvc.c | 2 +- source3/libsmb/clierror.c | 2 +- source3/libsmb/libsmbclient.c | 2 +- source3/libsmb/nterr.c | 2 +- source3/libsmb/trust_passwd.c | 4 ++-- 7 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 249225d894..90b1cc8d69 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -1131,14 +1131,14 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); result = cli_lsa_open_policy(&cli, cli.mem_ctx, True, SEC_RIGHTS_QUERY_VALUE, &lsa_pol); if (!NT_STATUS_IS_OK(result)) { DEBUG(0, ("fetch_domain_sid: Error opening lsa policy handle. %s\n", - get_nt_error_msg(result) )); + nt_errstr(result) )); goto done; } result = cli_lsa_query_info_policy(&cli, cli.mem_ctx, &lsa_pol, 5, domain, psid); if (!NT_STATUS_IS_OK(result)) { DEBUG(0, ("fetch_domain_sid: Error querying lsa policy handle. %s\n", - get_nt_error_msg(result) )); + nt_errstr(result) )); goto done; } diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 590f5f525e..125590b6d3 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -207,7 +207,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, &srv_chal); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed %s\n", - get_nt_error_msg(result))); + nt_errstr(result))); } return result; @@ -648,7 +648,7 @@ NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(r_s.status)) { /* report error code */ - DEBUG(0,("cli_net_srv_pwset: %s\n", get_nt_error_msg(nt_status))); + DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(nt_status))); goto done; } diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c index 391aee1782..2a84e6b698 100644 --- a/source3/libsmb/cli_wkssvc.c +++ b/source3/libsmb/cli_wkssvc.c @@ -99,7 +99,7 @@ NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* check returnet status code */ if (NT_STATUS_IS_ERR(r_o.status)) { /* report the error */ - DEBUG(0,("WKS_R_QUERY_INFO: %s\n", get_nt_error_msg(r_o.status))); + DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status))); prs_mem_free(&rbuf); return r_o.status; } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 13ea6b1997..591c04db22 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -103,7 +103,7 @@ char *cli_errstr(struct cli_state *cli) if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { NTSTATUS status = NT_STATUS(IVAL(cli->inbuf,smb_rcls)); - return get_nt_error_msg(status); + return nt_errstr(status); } cli_dos_error(cli, &errclass, &errnum); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index eb2b7ae25b..237701b968 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -216,7 +216,7 @@ int smbc_errno(struct cli_state *c) ret = cli_errno_from_nt(status); DEBUG(3,("smbc errno %s -> %d\n", - get_nt_error_msg(status), ret)); + nt_errstr(status), ret)); } return ret; diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 4d13caba91..b74dde9b14 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -540,7 +540,7 @@ nt_err_code_struct nt_errs[] = /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -char *get_nt_error_msg(NTSTATUS nt_code) +char *nt_errstr(NTSTATUS nt_code) { static pstring msg; int idx = 0; diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 1f52ab3611..51ffa1dd95 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -40,7 +40,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to setup creds (%s)!\n", - get_nt_error_msg(result))); + nt_errstr(result))); return result; } @@ -48,7 +48,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", - get_nt_error_msg(result))); + nt_errstr(result))); } return result; } -- cgit From a4cce223d6873400b053872a6e3b2eb8621eea45 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 17 Mar 2002 06:04:15 +0000 Subject: Added dos_errstr() function. Not all errors in list yet. (This used to be commit ddb5753e36b8c5efb48ce5c82c16d970fb8e76b6) --- source3/libsmb/doserr.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smberr.c | 12 ------- 2 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 source3/libsmb/doserr.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c new file mode 100644 index 0000000000..5e9da2fc49 --- /dev/null +++ b/source3/libsmb/doserr.c @@ -0,0 +1,88 @@ +/* + * Unix SMB/CIFS implementation. + * DOS error routines + * Copyright (C) Tim Potter 2002. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* DOS error codes. please read doserr.h */ + +#include "includes.h" + +typedef const struct +{ + char *dos_errstr; + WERROR werror; +} werror_code_struct; + +werror_code_struct dos_errs[] = +{ + { "WERR_OK", WERR_OK }, + { "WERR_BADFILE", WERR_BADFILE }, + { "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED }, + { "WERR_BADFID", WERR_BADFID }, + { "WERR_BADFUNC", WERR_BADFUNC }, + { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, + { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, + { "WERR_ALREADY_EXISTS", WERR_ALREADY_EXISTS }, + { "WERR_INVALID_PARAM", WERR_INVALID_PARAM }, + { "WERR_NOT_SUPPORTED", WERR_NOT_SUPPORTED }, + { "WERR_BAD_PASSWORD", WERR_BAD_PASSWORD }, + { "WERR_NOMEM", WERR_NOMEM }, + { "WERR_INVALID_NAME", WERR_INVALID_NAME }, + { "WERR_UNKNOWN_LEVEL", WERR_UNKNOWN_LEVEL }, + { "WERR_OBJECT_PATH_INVALID", WERR_OBJECT_PATH_INVALID }, + { "WERR_NO_MORE_ITEMS", WERR_NO_MORE_ITEMS }, + { "WERR_MORE_DATA", WERR_MORE_DATA }, + { "WERR_UNKNOWN_PRINTER_DRIVER", WERR_UNKNOWN_PRINTER_DRIVER }, + { "WERR_INVALID_PRINTER_NAME", WERR_INVALID_PRINTER_NAME }, + { "WERR_PRINTER_ALREADY_EXISTS", WERR_PRINTER_ALREADY_EXISTS }, + { "WERR_INVALID_DATATYPE", WERR_INVALID_DATATYPE }, + { "WERR_INVALID_ENVIRONMENT", WERR_INVALID_ENVIRONMENT }, + { "WERR_INVALID_FORM_SIZE", WERR_INVALID_FORM_SIZE }, + { "WERR_BUF_TOO_SMALL", WERR_BUF_TOO_SMALL }, + { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, + { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, + { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, + { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, + { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, + { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, + { "WERR_DFS_NO_SUCH_SHARE", WERR_DFS_NO_SUCH_SHARE }, + { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, + { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, + { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, + { NULL, W_ERROR(0) } +}; + +/***************************************************************************** + returns a DOS error message. not amazingly helpful, but better than a number. + *****************************************************************************/ +char *dos_errstr(WERROR werror) +{ + static pstring msg; + int idx = 0; + + slprintf(msg, sizeof(msg), "DOS code 0x%08x", W_ERROR_V(werror)); + + while (dos_errs[idx].dos_errstr != NULL) { + if (W_ERROR_V(dos_errs[idx].werror) == + W_ERROR_V(werror)) + return dos_errs[idx].dos_errstr; + idx++; + } + + return msg; +} diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 757629a2d5..84b3f507e6 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -245,18 +245,6 @@ char *smb_dos_errstr(char *inbuf) return(ret); } - -/***************************************************************************** - returns an WERROR error message. - *****************************************************************************/ -char *werror_str(WERROR status) -{ - static fstring msg; - slprintf(msg, sizeof(msg), "WIN32 code 0x%08x", W_ERROR_V(status)); - return msg; -} - - /***************************************************************************** map a unix errno to a win32 error *****************************************************************************/ -- cgit From bf555a158a99becb3a6ac0c3b2b9502f01cd2bc2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 19 Mar 2002 05:35:06 +0000 Subject: Don't try to sort a list of zero length in internal_resolve_name() (This used to be commit 5387e4046f67a1c6ef9e98268268b06a729d5ca4) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0370365953..cd175dcd1d 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -909,7 +909,7 @@ static BOOL internal_resolve_name(const char *name, int name_type, controllers including the PDC in iplist[1..n]. Iterating over the iplist when the PDC is down will cause two sets of timeouts. */ - if ((nodupes_iplist = (struct in_addr *) + if (*return_count && (nodupes_iplist = (struct in_addr *) malloc(sizeof(struct in_addr) * (*return_count)))) { int nodupes_count = 0; -- cgit From 5e09ffdc7cfbbf06720af55101512ca88fac7ea2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Mar 2002 01:43:06 +0000 Subject: Test against W2K that we're doing large read/writes correctly (we are). At least with 14 word writes. Jeremy. (This used to be commit 24ef6258a16e6b4673f1088d64b79bddcd268df5) --- source3/libsmb/clireadwrite.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 627bab88a5..402de726e8 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -223,6 +223,14 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 { char *p; + if (size > cli->bufsize) { + cli->outbuf = realloc(cli->outbuf, size + 1024); + cli->inbuf = realloc(cli->inbuf, size + 1024); + if (cli->outbuf == NULL || cli->inbuf == NULL) + return False; + cli->bufsize = size + 1024; + } + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -300,6 +308,7 @@ ssize_t cli_write(struct cli_state *cli, break; bwritten += SVAL(cli->inbuf, smb_vwv2); + bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))>>16); } while (received < issued && cli_receive_smb(cli)) -- cgit From a1249aca906e9624edada1b4e9c654b568897dce Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Mar 2002 01:47:31 +0000 Subject: Correctly increment offset in cli_smbwrite. Jeremy. (This used to be commit 5b04b5f1df3ee509e7314064966be09e2202b0ef) --- source3/libsmb/clireadwrite.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 402de726e8..0a9569fc69 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -366,6 +366,8 @@ ssize_t cli_smbwrite(struct cli_state *cli, size1 -= size; total += size; + offset += size; + } while (size1); return total; -- cgit From 33dd5128961f2a39cd70c7b6766a524aba2443d7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 23 Mar 2002 08:45:03 +0000 Subject: Make a number of the lookup tables 'const'. I'm told this assists in sharing memory between users of shared libs. Andrew Bartlett (This used to be commit 41dd5a4d292bb08fa313f6220014cd9b4490237b) --- source3/libsmb/errormap.c | 6 +++--- source3/libsmb/smbdes.c | 18 +++++++++--------- 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index a4a5a8741e..c30db3ad95 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -43,7 +43,7 @@ */ /* NT status -> dos error map */ -static struct { +const static struct { uint8 dos_class; uint32 dos_code; NTSTATUS ntstatus; @@ -609,7 +609,7 @@ static struct { /* dos -> nt status error map */ -static struct { +const static struct { uint8 dos_class; uint32 dos_code; NTSTATUS ntstatus; @@ -864,7 +864,7 @@ static struct { }; /* errmap NTSTATUS->Win32 */ -static struct { +const static struct { NTSTATUS ntstatus; WERROR werror; } ntstatus_to_werror_map[] = { diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 440121d126..cde77f94a3 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -48,7 +48,7 @@ #define uchar unsigned char -static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, +static const uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, @@ -57,7 +57,7 @@ static uchar perm1[56] = {57, 49, 41, 33, 25, 17, 9, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; -static uchar perm2[48] = {14, 17, 11, 24, 1, 5, +static const uchar perm2[48] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, @@ -66,7 +66,7 @@ static uchar perm2[48] = {14, 17, 11, 24, 1, 5, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; -static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, +static const uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8, @@ -75,7 +75,7 @@ static uchar perm3[64] = {58, 50, 42, 34, 26, 18, 10, 2, 61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7}; -static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, +static const uchar perm4[48] = { 32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, @@ -84,7 +84,7 @@ static uchar perm4[48] = { 32, 1, 2, 3, 4, 5, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; -static uchar perm5[32] = { 16, 7, 20, 21, +static const uchar perm5[32] = { 16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, @@ -94,7 +94,7 @@ static uchar perm5[32] = { 16, 7, 20, 21, 22, 11, 4, 25}; -static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, +static const uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, @@ -104,9 +104,9 @@ static uchar perm6[64] ={ 40, 8, 48, 16, 56, 24, 64, 32, 33, 1, 41, 9, 49, 17, 57, 25}; -static uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; +static const uchar sc[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; -static uchar sbox[8][4][16] = { +static const uchar sbox[8][4][16] = { {{14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7}, {0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8}, {4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0}, @@ -147,7 +147,7 @@ static uchar sbox[8][4][16] = { {7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8}, {2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11}}}; -static void permute(char *out, char *in, uchar *p, int n) +static void permute(char *out, const char *in, const uchar *p, int n) { int i; for (i=0;i Date: Tue, 2 Apr 2002 01:10:41 +0000 Subject: some mergee from SAMBA_2_2. Does compile, but needs some more testing. This is an intermediate check-in. More to come.... (This used to be commit 5b9b152971aa635d484cde45413a7880424ee22d) --- source3/libsmb/cli_spoolss.c | 474 ++++++++++++++++++++++++------------------- 1 file changed, 266 insertions(+), 208 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 2d81f63f89..cbe7da7d50 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1,8 +1,8 @@ -/* +/* Unix SMB/CIFS implementation. RPC pipe client - Copyright (C) Gerald Carter 2001, + Copyright (C) Gerald Carter 2001-2002, Copyright (C) Tim Potter 2000-2002, Copyright (C) Andrew Tridgell 1994-2000, Copyright (C) Luke Kenneth Casson Leighton 1996-2000, @@ -12,12 +12,12 @@ it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. @@ -38,140 +38,16 @@ * @param creds User credentials to connect as. * @returns Initialised client handle. */ -struct cli_state *cli_spoolss_initialise(struct cli_state *cli, - char *system_name, +struct cli_state *cli_spoolss_initialise(struct cli_state *cli, + char *system_name, struct ntuser_creds *creds) { return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds); } -/** Return a handle to the specified printer or print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param printername The name of the printer or print server to be - * opened in UNC format. - * - * @param datatype Specifies the default data type for the printer. - * - * @param access_required The access rights requested on the printer or - * print server. - * - * @param station The UNC name of the requesting workstation. - * - * @param username The name of the user requesting the open. - * - * @param pol Returned policy handle. - */ - -WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *printername, char *datatype, - uint32 access_required, char *station, - char *username, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_OPEN_PRINTER_EX q; - SPOOL_R_OPEN_PRINTER_EX r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_open_printer_ex(&q, printername, datatype, - access_required, station, username); - - /* Marshall data and send request */ - - if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *pol = r.handle; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Close a printer handle - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param pol Policy handle of printer or print server to close. - */ - -WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_CLOSEPRINTER q; - SPOOL_R_CLOSEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_closeprinter(&q, pol); - - /* Marshall data and send request */ - - if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *pol = r.handle; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Initialize a spoolss NEW_BUFFER */ - +/********************************************************************** + Initialize a new spoolss buff for use by a client rpc +**********************************************************************/ static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) { buffer->ptr = (size != 0); @@ -181,15 +57,14 @@ static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) buffer->struct_start = prs_offset(&buffer->prs); } -/* Decode various printer info levels - perhaps this should live in - parse_spoolss.c? */ +/********************************************************************* + Decode various spoolss rpc's and info levels + ********************************************************************/ -static void decode_printer_info_0( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - PRINTER_INFO_0 **info -) +/********************************************************************** +**********************************************************************/ +static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, PRINTER_INFO_0 **info) { uint32 i; PRINTER_INFO_0 *inf; @@ -205,12 +80,10 @@ static void decode_printer_info_0( *info=inf; } -static void decode_printer_info_1( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - PRINTER_INFO_1 **info -) +/********************************************************************** +**********************************************************************/ +static void decode_printer_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, PRINTER_INFO_1 **info) { uint32 i; PRINTER_INFO_1 *inf; @@ -226,12 +99,10 @@ static void decode_printer_info_1( *info=inf; } -static void decode_printer_info_2( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - PRINTER_INFO_2 **info -) +/********************************************************************** +**********************************************************************/ +static void decode_printer_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, PRINTER_INFO_2 **info) { uint32 i; PRINTER_INFO_2 *inf; @@ -249,12 +120,10 @@ static void decode_printer_info_2( *info=inf; } -static void decode_printer_info_3( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - PRINTER_INFO_3 **info -) +/********************************************************************** +**********************************************************************/ +static void decode_printer_info_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, PRINTER_INFO_3 **info) { uint32 i; PRINTER_INFO_3 *inf; @@ -272,14 +141,9 @@ static void decode_printer_info_3( } /********************************************************************** - Decode a PORT_INFO_1 struct from a NEW_BUFFER **********************************************************************/ -static void decode_port_info_1( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - PORT_INFO_1 **info -) +static void decode_port_info_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, PORT_INFO_1 **info) { uint32 i; PORT_INFO_1 *inf; @@ -296,13 +160,9 @@ static void decode_port_info_1( } /********************************************************************** - Decode a PORT_INFO_2 struct from a NEW_BUFFER **********************************************************************/ -static void decode_port_info_2( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - PORT_INFO_2 **info) +static void decode_port_info_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, PORT_INFO_2 **info) { uint32 i; PORT_INFO_2 *inf; @@ -318,12 +178,10 @@ static void decode_port_info_2( *info=inf; } -static void decode_printer_driver_1( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - DRIVER_INFO_1 **info -) +/********************************************************************** +**********************************************************************/ +static void decode_printer_driver_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, DRIVER_INFO_1 **info) { uint32 i; DRIVER_INFO_1 *inf; @@ -339,12 +197,10 @@ static void decode_printer_driver_1( *info=inf; } -static void decode_printer_driver_2( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - DRIVER_INFO_2 **info -) +/********************************************************************** +**********************************************************************/ +static void decode_printer_driver_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, DRIVER_INFO_2 **info) { uint32 i; DRIVER_INFO_2 *inf; @@ -360,12 +216,10 @@ static void decode_printer_driver_2( *info=inf; } -static void decode_printer_driver_3( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - DRIVER_INFO_3 **info -) +/********************************************************************** +**********************************************************************/ +static void decode_printer_driver_3(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, DRIVER_INFO_3 **info) { uint32 i; DRIVER_INFO_3 *inf; @@ -381,11 +235,10 @@ static void decode_printer_driver_3( *info=inf; } -static void decode_printerdriverdir_1 ( - TALLOC_CTX *mem_ctx, - NEW_BUFFER *buffer, - uint32 returned, - DRIVER_DIRECTORY_1 **info +/********************************************************************** +**********************************************************************/ +static void decode_printerdriverdir_1 (TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 returned, DRIVER_DIRECTORY_1 **info ) { DRIVER_DIRECTORY_1 *inf; @@ -399,6 +252,137 @@ static void decode_printerdriverdir_1 ( *info=inf; } +/** Return a handle to the specified printer or print server. + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param printername The name of the printer or print server to be + * opened in UNC format. + * + * @param datatype Specifies the default data type for the printer. + * + * @param access_required The access rights requested on the printer or + * print server. + * + * @param station The UNC name of the requesting workstation. + * + * @param username The name of the user requesting the open. + * + * @param pol Returned policy handle. + */ + +/********************************************************************************* + Win32 API - OpenPrinter() + ********************************************************************************/ + +WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *printername, char *datatype, uint32 access_required, + char *station, char *username, POLICY_HND *pol) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_OPEN_PRINTER_EX q; + SPOOL_R_OPEN_PRINTER_EX r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_open_printer_ex(&q, printername, datatype, + access_required, station, username); + + /* Marshall data and send request */ + + if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (W_ERROR_IS_OK(result)) + *pol = r.handle; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/** Close a printer handle + * + * @param cli Pointer to client state structure which is open + * on the SPOOLSS pipe. + * + * @param mem_ctx Pointer to an initialised talloc context. + * + * @param pol Policy handle of printer or print server to close. + */ +/********************************************************************************* + Win32 API - ClosePrinter() + ********************************************************************************/ + +WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_CLOSEPRINTER q; + SPOOL_R_CLOSEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_closeprinter(&q, pol); + + /* Marshall data and send request */ + + if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (W_ERROR_IS_OK(result)) + *pol = r.handle; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** Enumerate printers on a print server. * * @param cli Pointer to client state structure which is open @@ -417,6 +401,9 @@ static void decode_printerdriverdir_1 ( * @param ctr Return structure for printer information. May * be NULL. */ +/********************************************************************************* + Win32 API - EnumPrinters() + ********************************************************************************/ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, @@ -498,6 +485,9 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/********************************************************************************* + Win32 API - EnumPorts() + ********************************************************************************/ /** Enumerate printer ports on a print server. * * @param cli Pointer to client state structure which is open @@ -585,7 +575,9 @@ WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Get printer info */ +/********************************************************************************* + Win32 API - GetPrinter() + ********************************************************************************/ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, @@ -602,7 +594,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCT(r); /* Initialise input parameters */ - + init_buffer(&buffer, offered, mem_ctx); prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); @@ -652,6 +644,9 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/********************************************************************************* + Win32 API - SetPrinter() + ********************************************************************************/ /** Set printer info * * @param cli Pointer to client state structure which is open @@ -706,6 +701,9 @@ done: return result; } +/********************************************************************************* + Win32 API - GetPrinterDriver() + ********************************************************************************/ /** Get installed printer drivers for a given printer * * @param cli Pointer to client state structure which is open @@ -787,7 +785,7 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, case 3: decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); break; - } + } done: prs_mem_free(&qbuf); @@ -796,6 +794,9 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, return result; } +/********************************************************************************* + Win32 API - EnumPrinterDrivers() + ********************************************************************************/ /********************************************************************** * Get installed printer drivers for a given printer */ @@ -865,7 +866,7 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, case 3: decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); break; - } + } } done: @@ -876,6 +877,9 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, } +/********************************************************************************* + Win32 API - GetPrinterDriverDirectory() + ********************************************************************************/ /********************************************************************** * Get installed printer drivers for a given printer */ @@ -944,6 +948,9 @@ WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, return result; } +/********************************************************************************* + Win32 API - AddPrinterDriver() + ********************************************************************************/ /********************************************************************** * Install a printer driver */ @@ -994,8 +1001,11 @@ done: return result; } +/********************************************************************************* + Win32 API - AddPrinter() + ********************************************************************************/ /********************************************************************** - * Install a printer + * Install a printer */ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 level, PRINTER_INFO_CTR*ctr) @@ -1049,6 +1059,9 @@ WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/********************************************************************************* + Win32 API - DeltePrinterDriver() + ********************************************************************************/ /********************************************************************** * Delete a Printer Driver from the server (does not remove * the driver files @@ -1066,8 +1079,8 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, ZERO_STRUCT(q); ZERO_STRUCT(r); - /* Initialise input parameters */ + /* Initialise input parameters */ prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); @@ -1083,7 +1096,7 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) || !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) goto done; - + /* Unmarshall response */ if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0)) @@ -1100,7 +1113,9 @@ WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, return result; } -/* Get print processor directory */ +/********************************************************************************* + Win32 API - GetPrinterProcessorDirectory() + ********************************************************************************/ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, TALLOC_CTX *mem_ctx, @@ -1133,7 +1148,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, /* Marshall data and send request */ if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, &qbuf, &rbuf)) goto done; @@ -1165,7 +1180,7 @@ WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, * on the SPOOLSS pipe. * @param mem_ctx Pointer to an initialised talloc context. * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex + * @param handle Policy handle opened with cli_spoolss_open_printer_ex * or cli_spoolss_addprinterex. * @param level Form info level to add - should always be 1. * @param form A pointer to the form to be added. @@ -1403,7 +1418,7 @@ static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1)); buffer->prs.data_offset = 0; - for (i = 0; i < num_forms; i++) + for (i = 0; i < num_forms; i++) smb_io_form_1("", buffer, &((*forms)[i]), 0); } @@ -1418,7 +1433,7 @@ static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, * may be NULL. * or cli_spoolss_addprinterex. * @param level Form info level to get - should always be 1. - * @param handle Open policy handle + * @param handle Open policy handle * */ @@ -1446,7 +1461,7 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ make_spoolss_q_enumforms(&q, handle, level, &buffer, offered); - + /* Marshall data and send request */ if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) || @@ -1477,4 +1492,47 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/********************************************************************************* + Win32 API - SetPrinterData() + ********************************************************************************/ + +WERROR cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, char* valname, char* value) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETPRINTERDATA q; + SPOOL_R_SETPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise input parameters */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + + /* write the request */ + make_spoolss_q_setprinterdata(&q, mem_ctx, pol, valname, value); + + /* Marshall data and send request */ + if (!spoolss_io_q_setprinterdata ("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + if (spoolss_io_r_setprinterdata ("", &r, &rbuf, 0)) + goto done; + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + + /** @} **/ -- cgit From 3d3ec9f4fdddfad8432cdd77fb4a30ad49552397 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 4 Apr 2002 06:10:22 +0000 Subject: Fixed memory leak in cli_lsa_enum_trust_dom(). Use talloc_strdup() instead of strdup(). (This used to be commit fb32f7199b8a487757b509555e5a69ec5cae8fbd) --- source3/libsmb/cli_lsarpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 90b1cc8d69..014dc7ae31 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -607,7 +607,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, unistr2_to_ascii(tmp, &r.uni_domain_name[i], sizeof(tmp) - 1); - (*domain_names)[i] = strdup(tmp); + (*domain_names)[i] = talloc_strdup(tmp); sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); } } -- cgit From abc62df25f311ceb20772231a071c21edb30f96d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 4 Apr 2002 06:11:22 +0000 Subject: oops (This used to be commit 6b20a809020821276b0330810317a4d10c9fdb5a) --- source3/libsmb/cli_lsarpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 014dc7ae31..832758df4f 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -607,7 +607,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, unistr2_to_ascii(tmp, &r.uni_domain_name[i], sizeof(tmp) - 1); - (*domain_names)[i] = talloc_strdup(tmp); + (*domain_names)[i] = talloc_strdup(mem_ctx, tmp); sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); } } -- cgit From 31f1c2172ca8a8a32c69a06a9388daecfc9c25ce Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 4 Apr 2002 06:55:32 +0000 Subject: If compiling with Insure, mallocate a byte of memory and attach it to the POLICY_HND structure when passing new handles back from the appropriate cli_* functions. When closing the policy handle free the memory. Insure (and indeed other memory checkers) should detect handles that have not been closed properly as memory leaks. Unfortunately this can only be done when the program terminates (set insure++.summarize leaks in your .psrc file) rather than when the policy handle falls out of scope. Looks like Jeremy has squished all the policy handle leaks at the moment but more are bound to crop up later. (This used to be commit 6dc80d625752f0a3ce6fd7b2278095529c6ec29f) --- source3/libsmb/cli_lsarpc.c | 16 +++++++++++++++- source3/libsmb/cli_samr.c | 18 ++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 832758df4f..3216854608 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -99,6 +99,9 @@ NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(result = r.status)) { *pol = r.pol; +#ifdef __INSURE__ + pol->marker = malloc(1); +#endif } done: @@ -160,6 +163,9 @@ NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(result = r.status)) { *pol = r.pol; +#ifdef __INSURE__ + pol->marker = (char *)malloc(1); +#endif } done: @@ -207,6 +213,9 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ if (NT_STATUS_IS_OK(result = r.status)) { +#ifdef __INSURE__ + SAFE_FREE(pol->marker); +#endif *pol = r.pol; } @@ -1052,7 +1061,10 @@ NTSTATUS cli_lsa_query_secobj(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Fetch a DOMAIN sid. Does complete cli setup / teardown anonymously. */ +#if 0 + +/** An example of how to use the routines in this file. Fetch a DOMAIN + sid. Does complete cli setup / teardown anonymously. */ BOOL fetch_domain_sid( char *domain, char *remote_machine, DOM_SID *psid) { @@ -1150,4 +1162,6 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); return ret; } +#endif + /** @} **/ diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 53203e3d79..85a7375f99 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -69,6 +69,9 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(result = r.status)) { *connect_pol = r.connect_pol; +#ifdef __INSURE__ + connect_pol->marker = malloc(1); +#endif } done: @@ -114,6 +117,9 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ if (NT_STATUS_IS_OK(result = r.status)) { +#ifdef __INSURE__ + SAFE_FREE(connect_pol->marker); +#endif *connect_pol = r.pol; } @@ -162,6 +168,9 @@ NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(result = r.status)) { *domain_pol = r.domain_pol; +#ifdef __INSURE__ + domain_pol->marker = malloc(1); +#endif } done: @@ -209,6 +218,9 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(result = r.status)) { *user_pol = r.user_pol; +#ifdef __INSURE__ + user_pol->marker = malloc(1); +#endif } done: @@ -256,6 +268,9 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(result = r.status)) { *group_pol = r.pol; +#ifdef __INSURE__ + group_pol->marker = malloc(1); +#endif } done: @@ -759,6 +774,9 @@ NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(result = r.status)) { *alias_pol = r.pol; +#ifdef __INSURE__ + alias_pol->marker = malloc(1); +#endif } done: -- cgit From 8ad60283be2c49d9db6d791c6b7f61080035ba7f Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Thu, 4 Apr 2002 15:50:28 +0000 Subject: small change in name_resolve_bcast() spotted by alexander bokovoy. it shouldn't break anything. if it's wrong, feel free to revert but explain why. J.F. (This used to be commit 638c692525c050ecdf414d461ef6b4aed3ce51db) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index cd175dcd1d..7928d44652 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -671,7 +671,7 @@ BOOL name_resolve_bcast(const char *name, int name_type, for( i = num_interfaces-1; i >= 0; i--) { struct in_addr sendto_ip; /* Done this way to fix compiler error on IRIX 5.x */ - sendto_ip = *iface_bcast(*iface_n_ip(i)); + sendto_ip = *iface_n_bcast(i); *return_ip_list = name_query(sock, name, name_type, True, True, sendto_ip, return_count); if(*return_ip_list != NULL) { -- cgit From a9d328bb943de1414a7d1a5a24b9b1b47b879a75 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 6 Apr 2002 01:25:57 +0000 Subject: Always pass NT password as well as Lanman. Jeremy. (This used to be commit 146fb9d12bd3621087193f439e99c13d609ff658) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d9df1fa640..8ddd116679 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1258,7 +1258,7 @@ again: return nt_status; } - if (!cli_session_setup(cli, user, password, pass_len, NULL, 0, + if (!cli_session_setup(cli, user, password, pass_len, password, pass_len, domain)) { DEBUG(1,("failed session setup\n")); nt_status = cli_nt_error(cli); -- cgit From 416165a52c432d722a12b99e0cf1fb3cbb521f86 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 9 Apr 2002 05:11:34 +0000 Subject: Added WERR_INVALID_FORM_NAME constant. (This used to be commit 908b70f3e23846d0b438a68e45e076e65016e95e) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 5e9da2fc49..adc001bf29 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -52,6 +52,7 @@ werror_code_struct dos_errs[] = { "WERR_PRINTER_ALREADY_EXISTS", WERR_PRINTER_ALREADY_EXISTS }, { "WERR_INVALID_DATATYPE", WERR_INVALID_DATATYPE }, { "WERR_INVALID_ENVIRONMENT", WERR_INVALID_ENVIRONMENT }, + { "WERR_INVALID_FORM_NAME", WERR_INVALID_FORM_NAME }, { "WERR_INVALID_FORM_SIZE", WERR_INVALID_FORM_SIZE }, { "WERR_BUF_TOO_SMALL", WERR_BUF_TOO_SMALL }, { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, -- cgit From e8a8b04002e89e6a2c190258f145bd7f2600bd6f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 10 Apr 2002 07:19:37 +0000 Subject: Added cli_spoolss_enumjobs() function. (This used to be commit 952eb866f44ac0d8ba2032cf251d3a4298a750d3) --- source3/libsmb/cli_spoolss.c | 52 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index cbe7da7d50..cf356ef815 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1534,5 +1534,57 @@ done: return result; } +/* Enumerate jobs */ + +WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, uint32 firstjob, uint32 numofjobs, + uint32 level) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMJOBS q; + SPOOL_R_ENUMJOBS r; + WERROR result = W_ERROR(ERRgeneral); + NEW_BUFFER buffer; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + init_buffer(&buffer, offered, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enumjobs(&q, hnd, firstjob, numofjobs, level, &buffer, + offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumjobs("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMJOBS, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enumjobs("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (needed) + *needed = r.needed; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} /** @} **/ -- cgit From 07e6ff5fcfe337bb65a7c3a4493a92a7761cf2ed Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 14 Apr 2002 09:44:16 +0000 Subject: Partly based on the work by mimir (Rafal Szczesniak ) this patch allows samba to correctly enumerate its trusted domains - by exaimining the keys in the secrets.tdb file. This patch has been tested with both NT4 and rpcclient/wbinfo, and adds some extra functionality to talloc and rpc_parse to allow it to deal with already unicode strings. Finally, this cleans up some const warnings that were in net_rpc.c by pushing another dash of const into the rpc client code. Andrew Bartlett (This used to be commit 0bdd94cb992b40942aaf2e5e0efd2868b4686296) --- source3/libsmb/cli_samr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 85a7375f99..f3560ede5d 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -971,7 +971,7 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *domain_pol, uint32 flags, - uint32 num_names, char **names, + uint32 num_names, const char **names, uint32 *num_rids, uint32 **rids, uint32 **rid_types) { -- cgit From 3a139656a336ac0b86632b9a32ed32ed85c969c0 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 14 Apr 2002 11:13:49 +0000 Subject: Added error string for STATUS_SOME_UNMAPPED (This used to be commit f736e115c00e02e3f131ccceb7769559dd4d908a) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index b74dde9b14..faf5147fe2 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, + { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { NULL, NT_STATUS(0) } }; -- cgit From d0386372b2f491cd9281fc6466b1b5d2f5cf59a9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 14 Apr 2002 11:21:25 +0000 Subject: The cli_lsa_lookup_{names,sids} functions were returning useless information when one or more of the names/sids being queried were not resolvable. We now return a list the same length as the parameters passed instead of an array of just the resolvable names/sids. (This used to be commit 245468dbabb7c849ce423cc3cb586fa913d0adfe) --- source3/libsmb/cli_lsarpc.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 3216854608..1989169fd7 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -230,7 +230,7 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***domains, char ***names, uint32 **types, int *num_names) + char ***domains, char ***names, uint32 **types) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; @@ -274,13 +274,13 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_FILES_OPEN)) { + NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { + /* An actual error occured */ goto done; } - /* Return output parameters */ if (r.mapped_count == 0) { @@ -288,28 +288,28 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - (*num_names) = r.mapped_count; - result = NT_STATUS_OK; - - if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { + if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { + if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count))) { + if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - for (i = 0; i < r.mapped_count; i++) { + for (i = 0; i < num_sids; i++) { fstring name, dom_name; uint32 dom_idx = t_names.name[i].domain_idx; @@ -348,8 +348,9 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /** Lookup a list of names */ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, const char **names, - DOM_SID **sids, uint32 **types, int *num_sids) + POLICY_HND *pol, int num_names, + const char **names, DOM_SID **sids, + uint32 **types) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_NAMES q; @@ -388,13 +389,14 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result)) { + if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != + NT_STATUS_V(STATUS_SOME_UNMAPPED)) { + /* An actual error occured */ goto done; } - /* Return output parameters */ if (r.mapped_count == 0) { @@ -402,22 +404,21 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - (*num_sids) = r.mapped_count; - result = NT_STATUS_OK; - - if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.mapped_count)))) { + if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * + num_names)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count)))) { + if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * + num_names)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - for (i = 0; i < r.mapped_count; i++) { + for (i = 0; i < num_names; i++) { DOM_RID2 *t_rids = r.dom_rid; uint32 dom_idx = t_rids[i].rid_idx; uint32 dom_rid = t_rids[i].rid; -- cgit From d9cfe0f3ebdcf053f79ee0bbba59d4dbe2831145 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 15 Apr 2002 05:02:22 +0000 Subject: Merge of lsa lookup names/sids patch from HEAD. (This used to be commit e57c162897d4a7e66bb87091d179ac138f751c64) --- source3/libsmb/cli_lsarpc.c | 41 +++++++++++++++++++++-------------------- source3/libsmb/nterr.c | 1 + 2 files changed, 22 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 3216854608..23cedf1f08 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -230,7 +230,7 @@ NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***domains, char ***names, uint32 **types, int *num_names) + char ***domains, char ***names, uint32 **types) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_SIDS q; @@ -274,13 +274,13 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_FILES_OPEN)) { + NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { + /* An actual error occured */ goto done; } - /* Return output parameters */ if (r.mapped_count == 0) { @@ -288,28 +288,28 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - (*num_names) = r.mapped_count; - result = NT_STATUS_OK; - - if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { + if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * r.mapped_count))) { + if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count))) { + if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * + num_sids))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - for (i = 0; i < r.mapped_count; i++) { + for (i = 0; i < num_sids; i++) { fstring name, dom_name; uint32 dom_idx = t_names.name[i].domain_idx; @@ -348,8 +348,9 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, /** Lookup a list of names */ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, const char **names, - DOM_SID **sids, uint32 **types, int *num_sids) + POLICY_HND *pol, int num_names, + const char **names, DOM_SID **sids, + uint32 **types) { prs_struct qbuf, rbuf; LSA_Q_LOOKUP_NAMES q; @@ -388,13 +389,14 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result)) { + if (!NT_STATUS_IS_OK(result) && + NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { + /* An actual error occured */ goto done; } - /* Return output parameters */ if (r.mapped_count == 0) { @@ -402,22 +404,21 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; } - (*num_sids) = r.mapped_count; - result = NT_STATUS_OK; - - if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.mapped_count)))) { + if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * + num_names)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.mapped_count)))) { + if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * + num_names)))) { DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); result = NT_STATUS_UNSUCCESSFUL; goto done; } - for (i = 0; i < r.mapped_count; i++) { + for (i = 0; i < num_names; i++) { DOM_RID2 *t_rids = r.dom_rid; uint32 dom_idx = t_rids[i].rid_idx; uint32 dom_rid = t_rids[i].rid; diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index b74dde9b14..faf5147fe2 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, + { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { NULL, NT_STATUS(0) } }; -- cgit From b5c61023ff666dcdfda59ebb0bd80fe42837d482 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Apr 2002 06:56:01 +0000 Subject: better handling of DOS LANMAN2.1 protocol (This used to be commit 7f923d738b94eef042b21e4d0143861755620d91) --- source3/libsmb/cliconnect.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8ddd116679..4ed2aae1f3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -34,6 +34,7 @@ prots[] = {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, {PROTOCOL_LANMAN1,"LANMAN1.0"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, @@ -45,7 +46,7 @@ prots[] = do an old lanman2 style session setup ****************************************************************************/ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, - char *pass, int passlen) + char *pass, int passlen, const char *workgroup) { fstring pword; char *p; @@ -88,7 +89,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p += clistr_push(cli, p, user, -1, STR_TERMINATE); + p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); @@ -591,7 +595,7 @@ BOOL cli_session_setup(struct cli_state *cli, /* if its an older server then we have to use the older request format */ if (cli->protocol < PROTOCOL_NT1) { - return cli_session_setup_lanman2(cli, user, pass, passlen); + return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); } /* if no user is supplied then we have to do an anonymous connection. @@ -756,6 +760,10 @@ void cli_negprot_send(struct cli_state *cli) char *p; int numprots; + if (cli->protocol < PROTOCOL_NT1) { + cli->use_spnego = False; + } + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -788,6 +796,10 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; + if (cli->protocol < PROTOCOL_NT1) { + cli->use_spnego = False; + } + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -822,7 +834,7 @@ BOOL cli_negprot(struct cli_state *cli) return(False); } - cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ @@ -848,6 +860,7 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } } else if (cli->protocol >= PROTOCOL_LANMAN1) { + cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); @@ -860,6 +873,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); } else { /* the old core protocol */ + cli->use_spnego = False; cli->sec_mode = 0; cli->serverzone = TimeDiff(time(NULL)); } -- cgit From 37d67c3345e7016cc5e1626e9d0c4ffdebc596fb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Apr 2002 17:34:38 +0000 Subject: libsmb/cli_netlogon.c: Fixed confusing debug messages. param/loadparm.c: Added missing debugs that would have helped me find a misconfiguration I lost a day on.... Jeremy. (This used to be commit 6e9572379784c77f3c4e6a95e18a9641880a8ffc) --- source3/libsmb/cli_netlogon.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 125590b6d3..12651966d7 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -51,7 +51,7 @@ NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, /* create and send a MSRPC command with api NET_REQCHAL */ - DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", + DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", cli->desthost, global_myname, credstr(clnt_chal->data))); /* store the parameters */ @@ -108,7 +108,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* create and send a MSRPC command with api NET_AUTH2 */ - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", + DEBUG(4,("new_cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, credstr(cli->clnt_cred.challenge.data), neg_flags)); @@ -147,7 +147,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* * Server replied with bad credential. Fail. */ - DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ + DEBUG(0,("new_cli_net_auth2: server %s replied with bad credential (bad machine \ password ?).\n", cli->desthost )); result = NT_STATUS_ACCESS_DENIED; goto done; @@ -180,7 +180,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); + DEBUG(0,("new_cli_nt_setup_creds: request challenge failed\n")); return result; } -- cgit From dcb572e0b26858f58ddcf5cac1c94be31cda844d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 19 Apr 2002 00:16:18 +0000 Subject: fixed a namequery bug caused by my recent string length patches (This used to be commit b2329039d255928faf53474ee7ab06b6353b9fbe) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7928d44652..c578df6621 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -191,7 +191,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii(name, status[i].name, 15, 0, STR_TERMINATE); + pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE); result = True; done: -- cgit From 0fb9ea9fa45d28ea6660bab09998e704fd6502f8 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 22 Apr 2002 03:08:33 +0000 Subject: My seven-year-old daughter calls me 'Captain Pedantic'. I don't know which is freakier... the name or the fact that a seven-year-old knows what it means. Small change to correct the value we place in the DGM_LENGTH field of NBT Datagram messages. We have been counting the full datagram, but it's fairly clear in the RFCs that we should only count the source name, destination name, and payload. We've been overcharging by 14 bytes (the size of the NBT DGM header). This fix brings us in line with what Windows does, and what the RFCs say should be done. I'm a little surprised that this didn't cause any bugs or error messages. I guess no one actually checks this field. (This used to be commit 3156c020e5b6f12a448d58669977ad4449789460) --- source3/libsmb/nmblib.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index c78946fa09..9a37b4252a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -766,6 +766,14 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) XXXX This currently doesn't handle packets too big for one datagram. It should split them and use the packet_offset, more and first flags to handle the fragmentation. Yuck. + + [...but it isn't clear that we would ever need to send a + a fragmented NBT Datagram. The IP layer does its own + fragmentation to ensure that messages can fit into the path + MTU. It *is* important to be able to receive and rebuild + fragmented NBT datagrams, just in case someone out there + really has implemented this 'feature'. crh -)------ ] + ******************************************************************/ static int build_dgram(char *buf,struct packet_struct *p) { @@ -795,8 +803,11 @@ static int build_dgram(char *buf,struct packet_struct *p) memcpy(ubuf+offset,dgram->data,dgram->datasize); offset += dgram->datasize; - /* automatically set the dgm_length */ - dgram->header.dgm_length = offset; + /* automatically set the dgm_length + * NOTE: RFC1002 says the dgm_length does *not* + * include the fourteen-byte header. crh + */ + dgram->header.dgm_length = (offset - 14); RSSVAL(ubuf,10,dgram->header.dgm_length); return(offset); -- cgit From 6f366b7809375e4d7b061278a739ce541d291a97 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 22 Apr 2002 03:09:23 +0000 Subject: Copying commit from HEAD. My seven-year-old daughter calls me 'Captain Pedantic'. I don't know which is freakier... the name or the fact that a seven-year-old knows what it means. Small change to correct the value we place in the DGM_LENGTH field of NBT Datagram messages. We have been counting the full datagram, but it's fairly clear in the RFCs that we should only count the source name, destination name, and payload. We've been overcharging by 14 bytes (the size of the NBT DGM header). This fix brings us in line with what Windows does, and what the RFCs say should be done. I'm a little surprised that this didn't cause any bugs or error messages. I guess no one actually checks this field. (This used to be commit c06a2ece7545a9d9f8cde04745b603f7d6c6a716) --- source3/libsmb/nmblib.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index c78946fa09..9a37b4252a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -766,6 +766,14 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) XXXX This currently doesn't handle packets too big for one datagram. It should split them and use the packet_offset, more and first flags to handle the fragmentation. Yuck. + + [...but it isn't clear that we would ever need to send a + a fragmented NBT Datagram. The IP layer does its own + fragmentation to ensure that messages can fit into the path + MTU. It *is* important to be able to receive and rebuild + fragmented NBT datagrams, just in case someone out there + really has implemented this 'feature'. crh -)------ ] + ******************************************************************/ static int build_dgram(char *buf,struct packet_struct *p) { @@ -795,8 +803,11 @@ static int build_dgram(char *buf,struct packet_struct *p) memcpy(ubuf+offset,dgram->data,dgram->datasize); offset += dgram->datasize; - /* automatically set the dgm_length */ - dgram->header.dgm_length = offset; + /* automatically set the dgm_length + * NOTE: RFC1002 says the dgm_length does *not* + * include the fourteen-byte header. crh + */ + dgram->header.dgm_length = (offset - 14); RSSVAL(ubuf,10,dgram->header.dgm_length); return(offset); -- cgit From f2843dec43a4f239a01e167dc322e9808c6e4163 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 24 Apr 2002 05:36:40 +0000 Subject: Added constant and message for invalid security descriptor dos error. (This used to be commit 0827bd4184256a87d6cf6c58bc314309503da7be) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index adc001bf29..116a54e76f 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -65,6 +65,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, + { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { NULL, W_ERROR(0) } }; -- cgit From 9935aaec4766c0a57311301f234e19e79c27c0c1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 24 Apr 2002 05:45:04 +0000 Subject: Merge from HEAD: >Added constant and message for invalid security descriptor dos error. (This used to be commit f16c85caff9adb640c70ce6b932f33bdec696665) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index adc001bf29..116a54e76f 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -65,6 +65,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, + { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { NULL, W_ERROR(0) } }; -- cgit From 236d5effaccd563fda075577eed05db02ad55889 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 7 May 2002 06:16:44 +0000 Subject: DOS error 1307 is returned when an invalid owner for a security descriptor is detected. (This used to be commit 0377448b8c3e2bd8d5bc9f49a585292dc5c5b5a1) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 116a54e76f..02db625685 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -66,6 +66,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { NULL, W_ERROR(0) } }; -- cgit From e8682b6c8e0bf0ed6e2cdec3c2e83e8771f88755 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 7 May 2002 06:18:50 +0000 Subject: Merge from HEAD: >DOS error 1307 is returned when an invalid owner for a security descriptor >is detected. (This used to be commit 8b5cb1c2dda39ab4eaa5f61272cebcba072c332b) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 116a54e76f..02db625685 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -66,6 +66,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { NULL, W_ERROR(0) } }; -- cgit From 099b006c3f0ac1b7cda973121d226f30452711ec Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 7 May 2002 06:28:27 +0000 Subject: Added cli_spoolss_enumjobs() function. (This used to be commit aaa996355287fcd86873697f51a069ccb5a908b9) --- source3/libsmb/cli_spoolss.c | 49 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index cf356ef815..0458b29d54 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1534,12 +1534,36 @@ done: return result; } +static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 num_jobs, JOB_INFO_1 **jobs) +{ + uint32 i; + + *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1)); + buffer->prs.data_offset = 0; + + for (i = 0; i < num_jobs; i++) + smb_io_job_info_1("", buffer, &((*jobs)[i]), 0); +} + +static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 num_jobs, JOB_INFO_2 **jobs) +{ + uint32 i; + + *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2)); + buffer->prs.data_offset = 0; + + for (i = 0; i < num_jobs; i++) + smb_io_job_info_2("", buffer, &((*jobs)[i]), 0); +} + /* Enumerate jobs */ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 firstjob, uint32 numofjobs, - uint32 level) + POLICY_HND *hnd, uint32 level, uint32 firstjob, + uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMJOBS q; @@ -1559,7 +1583,7 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - make_spoolss_q_enumjobs(&q, hnd, firstjob, numofjobs, level, &buffer, + make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer, offered); /* Marshall data and send request */ @@ -1580,6 +1604,25 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (needed) *needed = r.needed; + if (!W_ERROR_IS_OK(r.status)) + goto done; + + *returned = r.returned; + + switch(level) { + case 1: + decode_jobs_1(mem_ctx, r.buffer, r.returned, + &ctr->job.job_info_1); + break; + case 2: + decode_jobs_2(mem_ctx, r.buffer, r.returned, + &ctr->job.job_info_2); + break; + default: + DEBUG(3, ("unsupported info level %d", level)); + break; + } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); -- cgit From ee2306d88156af9b03c135889672e6ce3ec49636 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 7 May 2002 06:36:22 +0000 Subject: Merge from HEAD: >Added cli_spoolss_enumjobs() function. >Added cmd_spoolss_enumjobs() function to rpcclient. > >The semantics of the src_len argument to rpcstr_pull() seem to have changed >breaking most of the spoolss commands in rpcclient. Changed a bunch of >0's to -1's to fix it. (This used to be commit dce534d4373cc0f204d82e0876bb94db8dfeb628) --- source3/libsmb/cli_spoolss.c | 49 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index cf356ef815..0458b29d54 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1534,12 +1534,36 @@ done: return result; } +static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 num_jobs, JOB_INFO_1 **jobs) +{ + uint32 i; + + *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1)); + buffer->prs.data_offset = 0; + + for (i = 0; i < num_jobs; i++) + smb_io_job_info_1("", buffer, &((*jobs)[i]), 0); +} + +static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, + uint32 num_jobs, JOB_INFO_2 **jobs) +{ + uint32 i; + + *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2)); + buffer->prs.data_offset = 0; + + for (i = 0; i < num_jobs; i++) + smb_io_job_info_2("", buffer, &((*jobs)[i]), 0); +} + /* Enumerate jobs */ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 firstjob, uint32 numofjobs, - uint32 level) + POLICY_HND *hnd, uint32 level, uint32 firstjob, + uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMJOBS q; @@ -1559,7 +1583,7 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - make_spoolss_q_enumjobs(&q, hnd, firstjob, numofjobs, level, &buffer, + make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer, offered); /* Marshall data and send request */ @@ -1580,6 +1604,25 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (needed) *needed = r.needed; + if (!W_ERROR_IS_OK(r.status)) + goto done; + + *returned = r.returned; + + switch(level) { + case 1: + decode_jobs_1(mem_ctx, r.buffer, r.returned, + &ctr->job.job_info_1); + break; + case 2: + decode_jobs_2(mem_ctx, r.buffer, r.returned, + &ctr->job.job_info_2); + break; + default: + DEBUG(3, ("unsupported info level %d", level)); + break; + } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); -- cgit From 26b0e0b478da99f4296c99c6e55ced26b44e591b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 8 May 2002 05:48:32 +0000 Subject: Added client side spoolss rpc commands for startpageprinter, endpageprinter, setjob and getjob. (This used to be commit d091a9d300c70b708218067d355c8282a6f14ab6) --- source3/libsmb/cli_spoolss.c | 200 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 200 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 0458b29d54..44bebedb09 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1630,4 +1630,204 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Set job */ + +WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 jobid, uint32 level, + uint32 command) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETJOB q; + SPOOL_R_SETJOB r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setjob(&q, hnd, jobid, level, command); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setjob("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setjob("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Get job */ + +WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, uint32 jobid, uint32 level, + JOB_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETJOB q; + SPOOL_R_GETJOB r; + WERROR result = W_ERROR(ERRgeneral); + NEW_BUFFER buffer; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + init_buffer(&buffer, offered, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getjob("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getjob("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (needed) + *needed = r.needed; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + switch(level) { + case 1: + decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1); + break; + case 2: + decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2); + break; + default: + DEBUG(3, ("unsupported info level %d", level)); + break; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Startpageprinter */ + +WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_STARTPAGEPRINTER q; + SPOOL_R_STARTPAGEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_startpageprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Endpageprinter */ + +WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENDPAGEPRINTER q; + SPOOL_R_ENDPAGEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_endpageprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 9bd8bf5d12f8a94d355e97ccf1ddace09d9d8254 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 13 May 2002 03:25:23 +0000 Subject: RPC client function for startdocprinter and enddocprinter. (This used to be commit 38de5025fb1f6396e456e26bfb071223da247f03) --- source3/libsmb/cli_spoolss.c | 103 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 101 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 44bebedb09..f3bc96fb25 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1742,7 +1742,8 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Startpageprinter */ +/* Startpageprinter. Sent to notify the spooler when a page is about to be + sent to a printer. */ WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd) @@ -1786,7 +1787,8 @@ WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/* Endpageprinter */ +/* Endpageprinter. Sent to notify the spooler when a page has finished + being sent to a printer. */ WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd) @@ -1830,4 +1832,101 @@ WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Startdocprinter. Sent to notify the spooler that a document is about + to be spooled for printing. */ + +WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *docname, + char *outputfile, char *datatype, + uint32 *jobid) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_STARTDOCPRINTER q; + SPOOL_R_STARTDOCPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + uint32 level = 1; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile, + datatype); + + /* Marshall data and send request */ + + if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (W_ERROR_IS_OK(result)) + *jobid = r.jobid; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Enddocprinter. Sent to notify the spooler that a document has finished + being spooled. */ + +WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENDDOCPRINTER q; + SPOOL_R_ENDDOCPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enddocprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 55cc5f4c08ef1eab61cd3d7f0f134c24276cf94a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 May 2002 05:26:50 +0000 Subject: Added getprinterdata and enumprinterdata rpc client routines. The setprinterdata routine was rewritten slightly to take more arguments. (This used to be commit a9a5702c88ea9c4a6a9197cf4e3444b26be858cc) --- source3/libsmb/cli_spoolss.c | 228 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 186 insertions(+), 42 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index f3bc96fb25..6f1024e577 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1492,48 +1492,6 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/********************************************************************************* - Win32 API - SetPrinterData() - ********************************************************************************/ - -WERROR cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, char* valname, char* value) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTERDATA q; - SPOOL_R_SETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - - /* write the request */ - make_spoolss_q_setprinterdata(&q, mem_ctx, pol, valname, value); - - /* Marshall data and send request */ - if (!spoolss_io_q_setprinterdata ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - if (spoolss_io_r_setprinterdata ("", &r, &rbuf, 0)) - goto done; - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, uint32 num_jobs, JOB_INFO_1 **jobs) { @@ -1929,4 +1887,190 @@ WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Get printer data */ + +WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, char *valuename, + uint32 *data_type, char **data, + uint32 *data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTERDATA q; + SPOOL_R_GETPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getprinterdata(&q, hnd, valuename, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (needed) + *needed = r.needed; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return output parameters */ + + if (data_type) + *data_type = r.type; + + if (data) { + *data = (char *)talloc(mem_ctx, r.needed); + memcpy(*data, r.data, r.needed); + } + + if (data_size) + *data_size = r.needed; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Set printer data */ + +WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *value, + uint32 data_type, char *data, + uint32 data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETPRINTERDATA q; + SPOOL_R_SETPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Enum printer data */ + +WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 ndx, + uint32 value_offered, uint32 data_offered, + uint32 *value_needed, uint32 *data_needed, + char **value, uint32 *data_type, char **data, + uint32 *data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMPRINTERDATA q; + SPOOL_R_ENUMPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return data */ + + if (value_needed) + *value_needed = r.realvaluesize; + + if (data_needed) + *data_needed = r.realdatasize; + + if (data_type) + *data_type = r.type; + + if (value) { + fstring the_value; + + rpcstr_pull(the_value, r.value, sizeof(the_value), -1, + STR_TERMINATE); + + *value = talloc_strdup(mem_ctx, the_value); + } + + if (data) + *data = talloc_memdup(mem_ctx, r.data, r.realdatasize); + + if (data_size) + *data_size = r.realdatasize; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 3d95426f2c88b4bc3914d8bf894c990039db7ea5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 May 2002 06:37:54 +0000 Subject: Added writeprinter rpc command. (This used to be commit a1934a7a8eda592e283a01014280ddb373564927) --- source3/libsmb/cli_spoolss.c | 49 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 6f1024e577..575817fb37 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -2073,4 +2073,53 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Write data to printer */ + +WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 data_size, char *data, + uint32 *num_written) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_WRITEPRINTER q; + SPOOL_R_WRITEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_writeprinter(&q, hnd, data_size, data); + + /* Marshall data and send request */ + + if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + if (num_written) + *num_written = r.buffer_written; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From af451af22f745d56bb92f0dbdd270f7fd024ef0d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 May 2002 07:21:57 +0000 Subject: Added deleteprinterdata client rpc. (This used to be commit 217ae50acd8cf088e268e7d2a6a7c192aca9e2f1) --- source3/libsmb/cli_spoolss.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 575817fb37..754b7b20a5 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -2122,4 +2122,49 @@ WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Delete printer data */ + +WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *valuename) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_DELETEPRINTERDATA q; + SPOOL_R_DELETEPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_deleteprinterdata(&q, hnd, valuename); + + /* Marshall data and send request */ + + if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ -- cgit From 6ee4366093b24251aa52c272512b2efacb9582d8 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 17 May 2002 03:37:37 +0000 Subject: Changes to allow head to translate NMB flags ... (This used to be commit c986a19cde0dfa96b512eb24d873203981e68c48) --- source3/libsmb/namequery.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c578df6621..85f33aeda4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -305,7 +305,7 @@ BOOL name_register(int fd, const char *name, int name_type, ****************************************************************************/ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count) + struct in_addr to_ip, int *count, int *flags) { BOOL found=False; int i, retries = 3; @@ -318,6 +318,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, memset((char *)&p,'\0',sizeof(p)); (*count) = 0; + (*flags) = 0; nmb->header.name_trn_id = generate_trn_id(); nmb->header.opcode = 0; @@ -440,6 +441,19 @@ struct in_addr *name_query(int fd,const char *name,int name_type, found=True; retries=0; + /* We add the flags back ... */ + if (nmb2->header.response) + (*flags) |= NM_FLAGS_RS; + if (nmb2->header.nm_flags.authoritative) + (*flags) |= NM_FLAGS_AA; + if (nmb2->header.nm_flags.trunc) + (*flags) |= NM_FLAGS_TC; + if (nmb2->header.nm_flags.recursion_desired) + (*flags) |= NM_FLAGS_RD; + if (nmb2->header.nm_flags.recursion_available) + (*flags) |= NM_FLAGS_RA; + if (nmb2->header.nm_flags.bcast) + (*flags) |= NM_FLAGS_B; free_packet(p2); /* * If we're doing a unicast lookup we only @@ -670,10 +684,11 @@ BOOL name_resolve_bcast(const char *name, int name_type, */ for( i = num_interfaces-1; i >= 0; i--) { struct in_addr sendto_ip; + int flags; /* Done this way to fix compiler error on IRIX 5.x */ sendto_ip = *iface_n_bcast(i); *return_ip_list = name_query(sock, name, name_type, True, - True, sendto_ip, return_count); + True, sendto_ip, return_count, &flags); if(*return_ip_list != NULL) { close(sock); return True; @@ -726,6 +741,7 @@ static BOOL resolve_wins(const char *name, int name_type, DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { + int flags; sock = open_socket_in( SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); @@ -733,7 +749,7 @@ static BOOL resolve_wins(const char *name, int name_type, *return_iplist = name_query( sock, name, name_type, False, True, wins_ip, - return_count); + return_count, &flags); if(*return_iplist != NULL) { close(sock); return True; -- cgit From 7a6a5bc6d758d278e4b39806978ea2b3eeaaaf9d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 17 May 2002 05:33:48 +0000 Subject: NT sends the server name prepended with \\ for a enumerate printers RPC call so we probably should as well. (This used to be commit 39c0218e5b4132e60401c2fc25fcbc88be94f87f) --- source3/libsmb/cli_spoolss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 754b7b20a5..28f4f481fa 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -420,8 +420,8 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCT(q); ZERO_STRUCT(r); - fstrcpy (server, cli->desthost); - strupper (server); + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (server); /* Initialise input parameters */ -- cgit From eed5094264945ca8ccf47030375cc56808ae8ea3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 May 2002 12:42:39 +0000 Subject: This removes --with-ssl from Samba. This option was badly maintained, useless and confused our users and distirbutors. (its SSL, therfore it must be good...) No windows client uses this protocol without help from an SSL tunnel. I can't see any reason why setting up a unix-side SSL wrapper would be any more difficult than the > 10 config options this mess added to samba in any case. On the Samba client end, I think the LIBSMB_PROG hack should be sufficient to start stunnel on the unix side. We might extend this to take %i and %p (IP and port) if there is demand. Andrew Bartlett (This used to be commit b04561d3fd3ee732877790fb4193b20ad72a75f8) --- source3/libsmb/cliconnect.c | 13 ------------- source3/libsmb/clientgen.c | 4 ---- 2 files changed, 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4ed2aae1f3..ec2c33f419 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -920,10 +920,6 @@ BOOL cli_session_request(struct cli_state *cli, _smb_setlen(cli->outbuf,len); SCVAL(cli->outbuf,0,0x81); -#ifdef WITH_SSL -retry: -#endif /* WITH_SSL */ - cli_send_smb(cli); DEBUG(5,("Sent session request\n")); @@ -969,15 +965,6 @@ retry: } } /* C. Hoch 9/14/95 End */ -#ifdef WITH_SSL - if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ - if (!sslutil_fd_is_ssl(cli->fd)){ - if (sslutil_connect(cli->fd) == 0) - goto retry; - } - } -#endif /* WITH_SSL */ - if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ cli->rap_error = CVAL(cli->inbuf,4); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ba7a327344..677a0f4220 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -247,10 +247,6 @@ void cli_shutdown(struct cli_state *cli) if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ if (cli->fd != -1) close(cli->fd); allocated = cli->allocated; -- cgit From 3fe27b7f9df7d2bb2f7799fd46b79928f0e614b0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 May 2002 13:49:01 +0000 Subject: A few more trusted domains updates from mimir. I think we may still need to look at our server enumeration code, but other than that, its much better in the tree than out. Andrew Bartlett (This used to be commit d57a1b4629d12a0374cc6d74dfc6f5d4793fcef8) --- source3/libsmb/cli_lsarpc.c | 31 ++++++++++++++++++++++--------- source3/libsmb/nterr.c | 1 + 2 files changed, 23 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 1989169fd7..8eaf6da2ec 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -5,7 +5,8 @@ Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000. + Copyright (C) Elrond 2000, + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -537,12 +538,25 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Enumerate list of trusted domains */ +/** + * Enumerate list of trusted domains + * + * @param cli client state (cli_state) structure of the connection + * @param mem_ctx memory context + * @param pol opened lsa policy handle + * @param enum_ctx enumeration context ie. index of first returned domain entry + * @param pref_num_domains preferred max number of entries returned in one response + * @param num_domains total number of trusted domains returned by response + * @param domain_names returned trusted domain names + * @param domain_sids returned trusted domain sids + * + * @return nt status code of response + **/ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 *enum_ctx, - uint32 *num_domains, char ***domain_names, - DOM_SID **domain_sids) + uint32 *pref_num_domains, uint32 *num_domains, + char ***domain_names, DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; @@ -560,7 +574,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ - init_q_enum_trust_dom(&q, pol, *enum_ctx, 0xffffffff); + init_q_enum_trust_dom(&q, pol, *enum_ctx, *pref_num_domains); if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) { @@ -577,16 +591,15 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NO_MORE_ENTRIES)) { + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { /* An actual error ocured */ goto done; } - result = NT_STATUS_OK; - /* Return output parameters */ if (r.num_domains) { diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index faf5147fe2..e2da6318e1 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ nt_err_code_struct nt_errs[] = { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, + { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { NULL, NT_STATUS(0) } }; -- cgit From ac03889168cc5b97651ee5e4300ce50210de8800 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 18 May 2002 13:19:38 +0000 Subject: Move client_receive_smb to clientgen.c as a static, as proposed by Elrond. (only function that used it was unused, and this helps bring TNG and HEAD closer) Its also cleaner. Andrew Bartlett (This used to be commit 78f47c83332a6408a718a3dee45645935638b364) --- source3/libsmb/clientgen.c | 35 ++++++++++++++++++++++++++++ source3/libsmb/clireadwrite.c | 53 ++++++++++++++++++++++--------------------- 2 files changed, 62 insertions(+), 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 677a0f4220..dee86b2b05 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,6 +31,41 @@ int cli_set_port(struct cli_state *cli, int port) return port; } +/**************************************************************************** + read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. +****************************************************************************/ + +static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) +{ + BOOL ret; + + for(;;) + { + ret = receive_smb(fd, buffer, timeout); + + if (!ret) + { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != SMBkeepalive) + break; + } + show_msg(buffer); + return ret; +} + + /**************************************************************************** recv an smb ****************************************************************************/ diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 0a9569fc69..6fce1c039b 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -48,31 +48,6 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, return cli_send_smb(cli); } -/**************************************************************************** -Issue a single SMBreadraw and don't wait for a reply. -****************************************************************************/ - -static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, - size_t size, int i) -{ - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,10,0,True); - - SCVAL(cli->outbuf,smb_com,SMBreadbraw); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SIVAL(cli->outbuf,smb_vwv1,offset); - SSVAL(cli->outbuf,smb_vwv2,size); - SSVAL(cli->outbuf,smb_vwv3,size); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - return cli_send_smb(cli); -} - /**************************************************************************** Read size bytes at offset offset using SMBreadX. ****************************************************************************/ @@ -152,6 +127,32 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return total; } +#if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ +/**************************************************************************** +Issue a single SMBreadraw and don't wait for a reply. +****************************************************************************/ + +static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, + size_t size, int i) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,10,0,True); + + SCVAL(cli->outbuf,smb_com,SMBreadbraw); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SIVAL(cli->outbuf,smb_vwv1,offset); + SSVAL(cli->outbuf,smb_vwv2,size); + SSVAL(cli->outbuf,smb_vwv3,size); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + return cli_send_smb(cli); +} + /**************************************************************************** Tester for the readraw call. ****************************************************************************/ @@ -213,7 +214,7 @@ ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, si return total; } - +#endif /**************************************************************************** issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -- cgit From e46a6ecc697418ad7eb9aedb1610d1fbbe419029 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 23 May 2002 14:02:17 +0000 Subject: Given Jeremy's positive response, and a lack of one from tpot, I'll commit this: More code cleanup - this lot a bit more dodgy than the last: The aim is to trim pwd_cache down to size. Its overly complex, and a pain to deal with. With a header comment like this: 'obfusticaion is planned' I think it deserved to die (at least partly). This was being done to allow 'cli_establish_connection' to die - its functionality has been replaced by cli_full_connection(), which does not duplicate code everywhere for creating names etc. This also removes the little 'init' fucntions for the various pipes, becouse they were only used in one place, and even then it was dodgy. (I've reworked smbcacls not to use anonymous connections any more, as this will (should) fail with a 'restrict anonymous' PDC). This allowed me to remove cli_pipe_util.c, which was calling cli_establish_connection. tpot: I'm not sure what direction you were going with the client stuff, and you may well have been wanting the init functions. If thats the case, give me a yell and I'll reimplement them against cli_full_connection. Andrew Bartlett (This used to be commit fa67e4626bed623333c571e76e06ccd52cba5cc5) --- source3/libsmb/cli_dfs.c | 8 --- source3/libsmb/cli_lsarpc.c | 13 ---- source3/libsmb/cli_netlogon.c | 9 --- source3/libsmb/cli_pipe_util.c | 82 ----------------------- source3/libsmb/cli_reg.c | 9 --- source3/libsmb/cli_samr.c | 8 --- source3/libsmb/cli_spoolss.c | 14 ---- source3/libsmb/cli_srvsvc.c | 9 --- source3/libsmb/cli_wkssvc.c | 18 ----- source3/libsmb/cliconnect.c | 148 +---------------------------------------- source3/libsmb/pwd_cache.c | 135 +++++-------------------------------- 11 files changed, 19 insertions(+), 434 deletions(-) delete mode 100644 source3/libsmb/cli_pipe_util.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index 312275926c..7fc27b9c3b 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -20,14 +20,6 @@ #include "includes.h" -/* Opens a SMB connection to the netdfs pipe */ - -struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_NETDFS, creds); -} - /* Query DFS support */ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 8eaf6da2ec..9d07eb1d1e 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -38,19 +38,6 @@ * security authority", which is half of a password database. **/ -/** Opens a SMB connection and connects to the LSARPC pipe. - * - * @param cli Uninitialised client handle. - * @param system_name NETBIOS name of the machine to connect to. - * @param creds User credentials to connect as. - * @returns Initialised client handle. - */ -struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_LSARPC, creds); -} - /** Open a LSA policy handle * * @param cli Handle on an initialised SMB connection */ diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 12651966d7..765f19a5fe 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -25,15 +25,6 @@ #include "includes.h" -/* Opens a SMB connection to the netlogon pipe */ - -struct cli_state *cli_netlogon_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_NETLOGON, creds); -} - /* LSA Request Challenge. Sends our challenge to server, then gets server response. These are used to generate the credentials. */ diff --git a/source3/libsmb/cli_pipe_util.c b/source3/libsmb/cli_pipe_util.c deleted file mode 100644 index de1c832e44..0000000000 --- a/source3/libsmb/cli_pipe_util.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client utility functions - Copyright (C) Tim Potter 2001, - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** \defgroup rpc_client RPC Client routines - */ - -/* Opens a SMB connection to a named pipe */ - -struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name, - char *pipe_name, - struct ntuser_creds *creds) -{ - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, pipe_name)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the SAMR pipe */ - -void cli_pipe_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); -} diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c index c09ccabb29..aaf18882f7 100644 --- a/source3/libsmb/cli_reg.c +++ b/source3/libsmb/cli_reg.c @@ -25,15 +25,6 @@ #include "includes.h" -/* Opens a SMB connection to the WINREG pipe */ - -struct cli_state *cli_winreg_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_WINREG, creds); -} - /* Shutdown a server */ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index f3560ede5d..9a332aa99e 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -24,14 +24,6 @@ #include "includes.h" -/* Opens a SMB connection to the SAMR pipe */ - -struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SAMR, creds); -} - /* Connect to SAMR database */ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 28f4f481fa..5e33e00c68 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -31,20 +31,6 @@ * @{ **/ -/** Opens a SMB connection and connects to the SPOOLSS pipe. - * - * @param cli Uninitialised client handle. - * @param system_name NETBIOS name of the machine to connect to. - * @param creds User credentials to connect as. - * @returns Initialised client handle. - */ -struct cli_state *cli_spoolss_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds); -} - /********************************************************************** Initialize a new spoolss buff for use by a client rpc **********************************************************************/ diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 9d33149540..b5b4478684 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -22,15 +22,6 @@ #include "includes.h" -/* Opens a SMB connection to the svrsvc pipe */ - -struct cli_state *cli_svrsvc_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SRVSVC, creds); -} - NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 switch_value, SRV_INFO_CTR *ctr) diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c index 2a84e6b698..756ff61e5b 100644 --- a/source3/libsmb/cli_wkssvc.c +++ b/source3/libsmb/cli_wkssvc.c @@ -23,24 +23,6 @@ #include "includes.h" -/** - * Opens a SMB connection to the wkssvc pipe - * - * @param cli client structure (not yet initialised) - * @param system_name called rpc server name - * @param creds user credentials - * - * @return client structure with opened pipe - **/ - -struct cli_state *cli_wkssvc_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_WKSSVC, creds); -} - - /** * WksQueryInfo rpc call (like query for server's capabilities) * diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ec2c33f419..f41c3b7701 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1027,152 +1027,6 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) return True; } -/**************************************************************************** -establishes a connection right up to doing tconX, password in cache. -****************************************************************************/ -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon) -{ - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), - cli->user_name, cli->domain)); - - /* establish connection */ - - if ((!cli->initialised)) - { - return False; - } - - /* cli_establish_connection() can't handle spnego yet. Once we get rid of - pwd_cache and other horrors we can get rid of this */ - cli->use_spnego = False; - - if (cli->fd == -1) - { - if (!cli_connect(cli, dest_host, dest_ip)) - { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(called), inet_ntoa(*dest_ip))); - return False; - } - } - - if (!cli_session_request(cli, calling, called)) - { - DEBUG(1,("failed session request\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (!cli_negprot(cli)) - { - DEBUG(1,("failed negprot\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (cli->pwd.cleartext || cli->pwd.null_pwd) - { - fstring passwd; - int pass_len; - - if (cli->pwd.null_pwd) - { - /* attempt null session */ - passwd[0] = 0; - pass_len = 1; - } - else - { - /* attempt clear-text session */ - pwd_get_cleartext(&(cli->pwd), passwd); - pass_len = strlen(passwd); - } - - /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->user_name, - passwd, pass_len, - NULL, 0, - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)passwd, strlen(passwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - } - } - else - { - /* attempt encrypted session */ - unsigned char nt_sess_pwd[24]; - unsigned char lm_sess_pwd[24]; - - /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->secblob.data); - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); - - /* attempt encrypted session */ - if (!cli_session_setup(cli, cli->user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, sizeof(nt_sess_pwd), - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - DEBUG(1,("session setup ok\n")); - - if (*cli->server_domain || *cli->server_os || *cli->server_type) - { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - cli->server_domain, - cli->server_os, - cli->server_type)); - } - - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - } - } - - if (do_shutdown) - cli_shutdown(cli); - - return True; -} - /* Initialise client credentials for authenticated pipe access */ static void init_creds(struct ntuser_creds *creds, char* username, @@ -1230,7 +1084,7 @@ again: DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service)); if (!cli_connect(cli, dest_host, &ip)) { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", + DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n", nmb_namestr(&called), inet_ntoa(*dest_ip))); cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 7d1185d9a7..8b79788fed 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -24,7 +24,7 @@ Initialises a password structure. ****************************************************************************/ -void pwd_init(struct pwd_info *pwd) +static void pwd_init(struct pwd_info *pwd) { memset((char *)pwd->password , '\0', sizeof(pwd->password )); memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd)); @@ -38,89 +38,21 @@ void pwd_init(struct pwd_info *pwd) } /**************************************************************************** - Returns NULL password flag. -****************************************************************************/ - -BOOL pwd_is_nullpwd(const struct pwd_info *pwd) -{ - return pwd->null_pwd; -} - -/**************************************************************************** - Compares two passwords. hmm, not as trivial as expected. hmm. -****************************************************************************/ - -BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2) -{ - if (pwd1->cleartext && pwd2->cleartext) { - if (strequal(pwd1->password, pwd2->password)) - return True; - } - if (pwd1->null_pwd && pwd2->null_pwd) - return True; - - if (!pwd1->null_pwd && !pwd2->null_pwd && - !pwd1->cleartext && !pwd2->cleartext) { -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd compare: nt#\n")); - dump_data(100, pwd1->smb_nt_pwd, 16); - dump_data(100, pwd2->smb_nt_pwd, 16); -#endif - if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) - return True; -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd compare: lm#\n")); - dump_data(100, pwd1->smb_lm_pwd, 16); - dump_data(100, pwd2->smb_lm_pwd, 16); -#endif - if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) - return True; - } - return False; -} - -/**************************************************************************** - Reads a password. + Makes lm and nt hashed passwords. ****************************************************************************/ -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) +static void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) { - /* grab a password */ - char *user_pass; + pstring dos_passwd; pwd_init(pwd); - user_pass = (char*)getpass(passwd_report); - - /* - * Do not assume that an empty string is a NULL password. - * If you do this will break the session key generation for - * and account with an emtpy password. If you wish to use - * a NULL password, use the -N option to smbclient and rpcclient - * --jerry - */ -#if 0 - if (user_pass == NULL || user_pass[0] == 0) - pwd_set_nullpwd(pwd); - else if (do_encrypt) -#endif - if (do_encrypt) - pwd_make_lm_nt_16(pwd, user_pass); - else - pwd_set_cleartext(pwd, user_pass); -} - -/**************************************************************************** - Stores a cleartext password. -****************************************************************************/ - -void pwd_set_nullpwd(struct pwd_info *pwd) -{ - pwd_init(pwd); + push_ascii_pstring(dos_passwd, clr); + nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pwd->null_pwd = False; pwd->cleartext = False; - pwd->null_pwd = True; - pwd->crypted = False; + pwd->crypted = False; } /**************************************************************************** @@ -150,29 +82,6 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) } -/**************************************************************************** - Stores lm and nt hashed passwords. -****************************************************************************/ - -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) -{ - pwd_init(pwd); - - if (lm_pwd) - memcpy(pwd->smb_lm_pwd, lm_pwd, 16); - else - memset((char *)pwd->smb_lm_pwd, '\0', 16); - - if (nt_pwd) - memcpy(pwd->smb_nt_pwd, nt_pwd, 16); - else - memset((char *)pwd->smb_nt_pwd, '\0', 16); - - pwd->null_pwd = False; - pwd->cleartext = False; - pwd->crypted = False; -} - /**************************************************************************** Gets lm and nt hashed passwords. ****************************************************************************/ @@ -185,24 +94,6 @@ void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) memcpy(nt_pwd, pwd->smb_nt_pwd, 16); } -/**************************************************************************** - Makes lm and nt hashed passwords. -****************************************************************************/ - -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) -{ - pstring dos_passwd; - - pwd_init(pwd); - - push_ascii_pstring(dos_passwd, clr); - - nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); - pwd->null_pwd = False; - pwd->cleartext = False; - pwd->crypted = False; -} - /**************************************************************************** Makes lm and nt OWF crypts. ****************************************************************************/ @@ -247,3 +138,13 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) if (nt_owf != NULL) memcpy(nt_owf, pwd->smb_nt_owf, 24); } + + + + + + + + + + -- cgit From 0c4c34d481be2790f0aae9f24a361f2458d1908c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 23 May 2002 14:26:04 +0000 Subject: This function is unused, and doesn't make any sense to me anyway. Wasn't this what got us some of the bugs with big-endien smbpasswd -j FOO -U ? Anyway, it deserves to die. Andrew Bartlett (This used to be commit 7201720048b31e48fb2600de8f7396088cc9b533) --- source3/libsmb/smbencrypt.c | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6fa8de418a..bac64c2e50 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -324,20 +324,3 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } - -/* Calculate the NT owfs of a user's password */ -void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]) -{ - char buf[512]; - int i; - - for (i = 0; i < MIN(pwd->uni_str_len, sizeof(buf) / 2); i++) - { - SIVAL(buf, i * 2, pwd->buffer[i]); - } - /* Calculate the MD4 hash (NT compatible) of the password */ - mdfour(nt_p16, (const unsigned char *)buf, pwd->uni_str_len * 2); - - /* clear out local copy of user's password (just being paranoid). */ - ZERO_STRUCT(buf); -} -- cgit From 9c3d5d6fd0dd9e2e62a33d0822a72d5209fe3ffb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 24 May 2002 05:14:16 +0000 Subject: Remove the password length paramater from cli_full_connection - it really didn't make any sense, and its was always just strlen(password) anyway. This fixes it to be strlen(password)+1 Andrew Bartlett (This used to be commit c205b18bd6b9b69200ff3db55f2c641631d4ab40) --- source3/libsmb/cliconnect.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f41c3b7701..7d18692236 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1030,7 +1030,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) /* Initialise client credentials for authenticated pipe access */ static void init_creds(struct ntuser_creds *creds, char* username, - char* domain, char* password, int pass_len) + char* domain, char* password) { ZERO_STRUCTP(creds); @@ -1052,7 +1052,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr *dest_ip, int port, char *service, char *service_type, char *user, char *domain, - char *password, int pass_len) + char *password) { struct ntuser_creds creds; NTSTATUS nt_status; @@ -1113,7 +1113,8 @@ again: return nt_status; } - if (!cli_session_setup(cli, user, password, pass_len, password, pass_len, + if (!cli_session_setup(cli, user, password, strlen(password)+1, + password, strlen(password)+1, domain)) { DEBUG(1,("failed session setup\n")); nt_status = cli_nt_error(cli); @@ -1125,7 +1126,7 @@ again: if (service) { if (!cli_send_tconX(cli, service, service_type, - (char*)password, pass_len)) { + (char*)password, strlen(password)+1)) { DEBUG(1,("failed tcon_X\n")); nt_status = cli_nt_error(cli); cli_shutdown(cli); @@ -1135,7 +1136,7 @@ again: } } - init_creds(&creds, user, domain, password, pass_len); + init_creds(&creds, user, domain, password); cli_init_creds(cli, &creds); *output_cli = cli; -- cgit From 20efe2fe6cbc4b5cf861a3296e29f5495637f79c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 25 May 2002 07:37:44 +0000 Subject: Clean up a few unused functions, add a bit of static etc. Importantly: The removal of the silly 'delete user script' behaviour when secuity=domain. I have left the name the same - as it still does the (previously documented, but not in smb.conf(5)) sane behaviour of deleting users on request. When we decide what to do with the 'add user' functionality, we might rename it. Andrew Bartlett (This used to be commit cdcfe3671eb7570e15649b77f708e6579055e7bc) --- source3/libsmb/cliconnect.c | 3 ++- source3/libsmb/pwd_cache.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7d18692236..0b6436b508 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1130,8 +1130,9 @@ again: DEBUG(1,("failed tcon_X\n")); nt_status = cli_nt_error(cli); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) + if (NT_STATUS_IS_OK(nt_status)) { nt_status = NT_STATUS_UNSUCCESSFUL; + } return nt_status; } } diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 8b79788fed..fc0602507a 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -73,7 +73,7 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) Gets a cleartext password. ****************************************************************************/ -void pwd_get_cleartext(struct pwd_info *pwd, char *clr) +void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) { if (pwd->cleartext) fstrcpy(clr, pwd->password); -- cgit From ba0b423dfa02b57d66a41ba0cf7dffad00ee19d1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 25 May 2002 08:24:24 +0000 Subject: Update some of the LM hash code to better respect the seperation between unix and DOS strings. This pushes all the 'have to uppercase, must be 14 chars' stuff behind the the interface. Andrew Bartlett (This used to be commit dec650efa8ab1466114c2e6d469320a319499ea0) --- source3/libsmb/cliconnect.c | 27 +++++++++-------- source3/libsmb/clirap.c | 11 ++----- source3/libsmb/smbencrypt.c | 73 +++++++++++++++++++++++++-------------------- 3 files changed, 57 insertions(+), 54 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0b6436b508..8129618fda 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -63,8 +63,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ passlen = 24; - clistr_push(cli, pword, pass, -1, STR_TERMINATE); - SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); + SMBencrypt(pass,cli->secblob.data,(uchar *)pword); } else if ((cli->sec_mode & 2) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ memcpy(pword, pass, passlen); @@ -241,9 +240,15 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, } -/**************************************************************************** -do a NT1 NTLM/LM encrypted session setup -****************************************************************************/ +/** + do a NT1 NTLM/LM encrypted session setup + @param cli client state to create do session setup on + @param user username + @param pass *either* cleartext password (passlen !=24) or LM response. + @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear + @param workgroup The user's domain. +*/ + static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *pass, int passlen, char *ntpass, int ntpasslen, @@ -261,12 +266,8 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; - clistr_push(cli, pword, - pass?pass:"", sizeof(pword), STR_TERMINATE|STR_ASCII); - clistr_push(cli, ntpword, - pass?pass:"", sizeof(ntpword), STR_TERMINATE|STR_ASCII); - SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); - SMBNTencrypt((uchar *)ntpword,cli->secblob.data,(uchar *)ntpword); + SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); + SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); @@ -611,8 +612,8 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, "", workgroup); } - /* if the server doesn't support encryption then we have to use plaintext. The - second password is ignored */ + /* if the server doesn't support encryption then we have to use + plaintext. The second password is ignored */ if ((cli->sec_mode & 2) == 0) { return cli_session_setup_plaintext(cli, user, pass, workgroup); } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a2b6c8bb8b..3eb9586a67 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -283,8 +283,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char param[16+sizeof(fstring)]; char data[532]; char *p = param; - fstring upper_case_old_pw; - fstring upper_case_new_pw; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; int data_len; @@ -316,9 +314,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char * Get the Lanman hash of the old password, we * use this as the key to make_oem_passwd_hash(). */ - memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); - clistr_push(cli, upper_case_old_pw, old_password, -1,STR_TERMINATE|STR_UPPER|STR_ASCII); - E_P16((uchar *)upper_case_old_pw, old_pw_hash); + E_deshash(old_password, old_pw_hash); clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE|STR_ASCII); @@ -328,10 +324,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char /* * Now place the old password hash in the data. */ - memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); - clistr_push(cli, upper_case_new_pw, new_password, -1, STR_TERMINATE|STR_UPPER|STR_ASCII); - - E_P16((uchar *)upper_case_new_pw, new_pw_hash); + E_deshash(new_password, new_pw_hash); E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index bac64c2e50..c298616220 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -26,18 +26,14 @@ /* This implements the X/Open SMB password encryption - It takes a password, a 8 byte "crypt key" and puts 24 bytes of - encrypted password into p24 */ + It takes a password ('unix' string), a 8 byte "crypt key" + and puts 24 bytes of encrypted password into p24 */ void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) { - uchar p14[15], p21[21]; + uchar p21[21]; memset(p21,'\0',21); - memset(p14,'\0',14); - StrnCpy((char *)p14,(const char *)passwd,14); - - strupper((char *)p14); - E_P16(p14, p21); + E_deshash(passwd, p21); SMBOWFencrypt(p21, c8, p24); @@ -49,61 +45,74 @@ void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) #endif } -/* +/** * Creates the MD4 Hash of the users password in NT UNICODE. + * @param passwd password in 'unix' charset. + * @param p16 return password hashed with md4, caller allocated 16 byte buffer */ -void E_md4hash(const uchar *passwd, uchar *p16) +void E_md4hash(const char *passwd, uchar p16[16]) { int len; smb_ucs2_t wpwd[129]; - /* Password cannot be longer than 128 characters */ - len = strlen((const char *)passwd); - if(len > 128) - len = 128; /* Password must be converted to NT unicode - null terminated. */ push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); /* Calculate length in bytes */ len = strlen_w(wpwd) * sizeof(int16); mdfour(p16, (unsigned char *)wpwd, len); + ZERO_STRUCT(wpwd); } -/* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) +/** + * Creates the MD4 Hash of the users password in NT UNICODE. + * @param passwd password in 'unix' charset. + * @param p16 return password hashed with md4, caller allocated 16 byte buffer + */ + +void E_deshash(const char *passwd, uchar p16[16]) { - char passwd[514]; + uchar dospwd[15]; /* Password must not be > 14 chars long. */ + ZERO_STRUCT(dospwd); + ZERO_STRUCTP(p16); + + /* Password must be converted to DOS charset - null terminated. */ + push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - memset(passwd,'\0',514); - safe_strcpy( passwd, pwd, sizeof(passwd)-1); + E_P16(dospwd, p16); + ZERO_STRUCT(dospwd); +} + +/** + * Creates the MD4 and DES (LM) Hash of the users password. + * MD4 is of the NT Unicode, DES is of the DOS UPPERCASE password. + * @param passwd password in 'unix' charset. + * @param nt_p16 return password hashed with md4, caller allocated 16 byte buffer + * @param p16 return password hashed with des, caller allocated 16 byte buffer + */ + +/* Does both the NT and LM owfs of a user's password */ +void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) +{ /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash((uchar *)passwd, nt_p16); + E_md4hash(pwd, nt_p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwd, strlen(pwd)); dump_data(100, (char *)nt_p16, 16); #endif - /* Mangle the passwords into Lanman format */ - passwd[14] = '\0'; - strupper(passwd); - - /* Calculate the SMB (lanman) hash functions of the password */ - - memset(p16, '\0', 16); - E_P16((uchar *) passwd, (uchar *)p16); + E_deshash(pwd, (uchar *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwd, strlen(pwd)); dump_data(100, (char *)p16, 16); #endif - /* clear out local copy of user's password (just being paranoid). */ - memset(passwd, '\0', sizeof(passwd)); } /* Does both the NTLMv2 owfs of a user's password */ -- cgit From 069e6fb9eb4a0bf6720cbbf493d0cb36baac9580 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 26 May 2002 14:59:57 +0000 Subject: Add support for NTLMv2 (tested!) with NTLMSSP. The problem was the NTLMv2 uses extra data in order to make reply/lookup more difficult. That extra data includes the hostname, and the domain. This matches Win2k (sort of) by sending this information. Win2k connects with LMCompatibilityLevel=5 without a problem. We can change the negotiation bits if we want, this should allow us to make NTLMv2 the default for other clients as well. Some of the extra #defines were found in the squid source. Andrew Bartlett (This used to be commit 17a5f67b3d1935baf6197ae967624eb847b66ac8) --- source3/libsmb/clispnego.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a4fcfa5d9a..469b946088 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -549,7 +549,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, format specifiers are: - U = unicode string (input is unix string) + U = unicode string (output is unix string) B = data blob b = data blob in header d = word (4 bytes) @@ -620,3 +620,44 @@ BOOL msrpc_parse(DATA_BLOB *blob, return True; } + +/** + * Print out the NTLMSSP flags for debugging + */ + +void debug_ntlmssp_flags(uint32 neg_flags) +{ + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) + DEBUG(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_OEM) + DEBUG(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + if (neg_flags & NTLMSSP_REQUEST_TARGET) + DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) + DEBUG(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + DEBUG(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) + DEBUG(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) + DEBUG(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_128) + DEBUG(4, (" NTLMSSP_NEGOTIATE_128\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) + DEBUG(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); +} + -- cgit From f00e292be91f76c57637d1e1b2d075ec0e765691 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 May 2002 08:39:12 +0000 Subject: Hmm - you can do NT_STATUS_IS_OK on a WERROR and not get a compile warning/error. (This used to be commit 8d6270cadf7f99ee8ee441ee6c3e58eca623d519) --- source3/libsmb/cli_spoolss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 5e33e00c68..48094f8179 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -606,7 +606,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (NT_STATUS_IS_OK(result)) { + if (W_ERROR_IS_OK(result)) { switch (level) { case 0: decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); -- cgit From 742ed34e470cf1e9c406b5a06a3274146d26b2d5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 28 May 2002 08:43:22 +0000 Subject: Added netshareenum cli command - the rpc structures here are really bizzare so muchos dodgy code is required to copy the results out of the parse buffer into the client's talloc context. (This used to be commit 496d3cf02c15ece7e13fa023deea740ee00486a8) --- source3/libsmb/cli_srvsvc.c | 120 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index b5b4478684..302b45960e 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -68,3 +68,123 @@ NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, return result; } + +WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 info_level, SRV_SHARE_INFO_CTR *ctr, + int preferred_len, ENUM_HND *hnd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_ENUM q; + SRV_R_NET_SHARE_ENUM r; + WERROR result = W_ERROR(ERRgeneral); + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_share_enum( + &q, cli->srv_name_slash, info_level, preferred_len, hnd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NETSHAREENUM_ALL, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_enum("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + /* Oh yuck yuck yuck - we have to copy all the info out of the + SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a + prs_mem_free() it will all be invalidated. The various share + info structures suck badly too. This really is gross. */ + + ZERO_STRUCTP(ctr); + + ctr->info_level = info_level; + ctr->num_entries = r.ctr.num_entries; + + switch(info_level) { + case 1: + ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc( + mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries); + + memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1)); + + for (i = 0; i < ctr->num_entries; i++) { + SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, + sizeof(SH_INFO_1)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname); + if (s) + init_unistr2(&info1->info_1_str.uni_netname, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark); + if (s) + init_unistr2(&info1->info_1_str.uni_remark, s, strlen(s) + 1); + + } + + break; + case 2: + ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc( + mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries); + + memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2)); + + for (i = 0; i < ctr->num_entries; i++) { + SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, + sizeof(SH_INFO_2)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname); + if (s) + init_unistr2(&info2->info_2_str.uni_netname, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark); + if (s) + init_unistr2(&info2->info_2_str.uni_remark, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path); + if (s) + init_unistr2(&info2->info_2_str.uni_path, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd); + if (s) + init_unistr2(&info2->info_2_str.uni_passwd, s, strlen(s) + 1); + } + break; + } + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 43b35364ffda5c779452fb41c015b280fefc6ab6 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 29 May 2002 00:49:26 +0000 Subject: Cleaned up srvsvc constants a bit. (This used to be commit ca61f68d5ca8791bea34732bd358cfb63273fc5c) --- source3/libsmb/cli_srvsvc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 302b45960e..f3d012434e 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -95,7 +95,7 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NETSHAREENUM_ALL, &qbuf, &rbuf)) + !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf)) goto done; /* Unmarshall response */ -- cgit From 568deecbf0bcda46fd9c927ad10b76d748b8c64d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 29 May 2002 01:43:44 +0000 Subject: Added netremotetod to try and figure out which srvsvc commands are denied when using restrictanonymous. (This used to be commit 0c65978ed07903af808da5f32cc29531aef23225) --- source3/libsmb/cli_srvsvc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index f3d012434e..9e2f5a3686 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -188,3 +188,48 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *server, TIME_OF_DAY_INFO *tod) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_REMOTE_TOD q; + SRV_R_NET_REMOTE_TOD r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_remote_tod(&q, cli->srv_name_slash); + + /* Marshall data and send request */ + + if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + r.tod = tod; + + if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 0e3260de6fdaa93ce0dddd98b1413662be972ce3 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 30 May 2002 07:12:32 +0000 Subject: Added netfileenum (sorry - no output though (-:) command. (This used to be commit 099b750b4ed8f04a1fd8a018508d412691e37df6) --- source3/libsmb/cli_srvsvc.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 9e2f5a3686..bc2058fdbd 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -233,3 +233,48 @@ WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 file_level, SRV_FILE_INFO_CTR *ctr, + int preferred_len, ENUM_HND *hnd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_FILE_ENUM q; + SRV_R_NET_FILE_ENUM r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, file_level, + ctr, preferred_len, hnd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_file_enum("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From e422b271da0c07f5c5cfd41df01bb2910d484abc Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 31 May 2002 17:02:09 +0000 Subject: Update netfileenum on both client and server sides to do an arbitrary number of files. This was done to better enable net rpc file. Perhaps we can start giving back real info this way, too. (This used to be commit b3fea72ee9abd2441a49c35442c54819e4ba16ba) --- source3/libsmb/cli_srvsvc.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index bc2058fdbd..8e1c6e0c9d 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1994-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 Copyright (C) Tim Potter 2001 + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -242,6 +243,7 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, SRV_Q_NET_FILE_ENUM q; SRV_R_NET_FILE_ENUM r; WERROR result = W_ERROR(ERRgeneral); + int i; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -272,6 +274,46 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(result)) goto done; + /* copy the data over to the ctr */ + + ZERO_STRUCTP(ctr); + + ctr->switch_value = file_level; + + ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries; + + switch(file_level) { + case 3: + ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc( + mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries); + + memset(ctr->file.info3, 0, + sizeof(SRV_FILE_INFO_3) * ctr->num_entries); + + for (i = 0; i < r.ctr.num_entries; i++) { + SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, + sizeof(FILE_INFO_3)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name); + if (s) + init_unistr2(&info3->info_3_str.uni_path_name, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name); + if (s) + init_unistr2(&info3->info_3_str.uni_user_name, s, strlen(s) + 1); + + } + + break; + } + done: prs_mem_free(&qbuf); prs_mem_free(&rbuf); -- cgit From 0f7e6fd0ec1dbe4a5d75a7df2f5ac32e95fd4d9a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 31 May 2002 21:09:58 +0000 Subject: Add netshareadd and netsharedel client side rpc (This used to be commit f37d85babf1061bb2b5ffdf96c72427f8ad5e832) --- source3/libsmb/cli_srvsvc.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 8e1c6e0c9d..6910ba0c5b 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -190,6 +190,87 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *sharename) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_DEL q; + SRV_R_NET_SHARE_DEL r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_del("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_del("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *netname, uint32 type, char *remark, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_ADD q; + SRV_R_NET_SHARE_ADD r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark, + perms, max_uses, num_uses, path, passwd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_add("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_add("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *server, TIME_OF_DAY_INFO *tod) { -- cgit From 654273856863d861c8be7b46c39e68a81ea3807a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 1 Jun 2002 00:10:08 +0000 Subject: More cleanup work preparing for SMB signing. Jeremy. (This used to be commit 3c05f7c06fc8c45307ea75128b160a5945fc5197) --- source3/libsmb/cli_lsarpc.c | 2 +- source3/libsmb/cliconnect.c | 192 ++++++++++++++++++++++++-------------------- 2 files changed, 105 insertions(+), 89 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 9d07eb1d1e..7dfee46fae 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -1122,7 +1122,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); goto done; } - if (!(cli.sec_mode & 1)) { + if (!(cli.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n", remote_machine)); goto done; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8129618fda..86daafc50b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -24,27 +24,25 @@ static const struct { - int prot; - const char *name; - } -prots[] = - { - {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, - {PROTOCOL_LANMAN1,"LANMAN1.0"}, - {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, - {PROTOCOL_NT1,"NT LM 0.12"}, - {-1,NULL} - }; - + int prot; + const char *name; +} prots[] = { + {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1,"LANMAN1.0"}, + {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {PROTOCOL_NT1,"NT LM 0.12"}, + {-1,NULL} +}; /**************************************************************************** -do an old lanman2 style session setup + Do an old lanman2 style session setup. ****************************************************************************/ + static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, char *pass, int passlen, const char *workgroup) { @@ -56,15 +54,15 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { + if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; } - if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) { + if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ passlen = 24; SMBencrypt(pass,cli->secblob.data,(uchar *)pword); - } else if ((cli->sec_mode & 2) && passlen == 24) { + } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ memcpy(pword, pass, passlen); } else if (passlen > 0) { @@ -111,10 +109,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return True; } - /**************************************************************************** -work out suitable capabilities to offer the server + Work out suitable capabilities to offer the server. ****************************************************************************/ + static uint32 cli_session_setup_capabilities(struct cli_state *cli) { uint32 capabilities = CAP_NT_SMBS; @@ -134,15 +132,18 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) return capabilities; } - /**************************************************************************** -do a NT1 guest session setup + Do a NT1 guest session setup. ****************************************************************************/ + static BOOL cli_session_setup_guest(struct cli_state *cli) { char *p; uint32 capabilities = cli_session_setup_capabilities(cli); + /* Guest cannot use SMB signing. */ + cli->sign_info.use_smb_signing = False; + set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -184,10 +185,10 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) return True; } - /**************************************************************************** -do a NT1 plaintext session setup + Do a NT1 plaintext session setup. ****************************************************************************/ + static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -320,10 +321,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, return True; } - /**************************************************************************** -send a extended security session setup blob, returning a reply blob + Send a extended security session setup blob, returning a reply blob. ****************************************************************************/ + static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); @@ -387,8 +388,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) #ifdef HAVE_KRB5 /**************************************************************************** -do a spnego/kerberos encrypted session setup + Do a spnego/kerberos encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, char *workgroup) { DATA_BLOB blob2, negTokenTarg; @@ -416,8 +418,9 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c #endif /**************************************************************************** -do a spnego/NTLMSSP encrypted session setup + Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -506,10 +509,10 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, return !cli_is_error(cli); } - /**************************************************************************** -do a spnego encrypted session setup + Do a spnego encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -563,12 +566,12 @@ ntlmssp: return cli_session_setup_ntlmssp(cli, user, pass, workgroup); } - /**************************************************************************** Send a session setup. The username and workgroup is in UNIX character format and must be converted to DOS codepage format before sending. If the password is in plaintext, the same should be done. ****************************************************************************/ + BOOL cli_session_setup(struct cli_state *cli, char *user, char *pass, int passlen, @@ -608,13 +611,13 @@ BOOL cli_session_setup(struct cli_state *cli, /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ - if ((cli->sec_mode & 1) == 0) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) { return cli_session_setup_plaintext(cli, user, "", workgroup); } /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ - if ((cli->sec_mode & 2) == 0) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { return cli_session_setup_plaintext(cli, user, pass, workgroup); } @@ -650,8 +653,9 @@ BOOL cli_ulogoff(struct cli_state *cli) } /**************************************************************************** -send a tconX + Send a tconX. ****************************************************************************/ + BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { @@ -663,12 +667,12 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->share, share); /* in user level security don't send a password now */ - if (cli->sec_mode & 1) { + if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { passlen = 1; pass = ""; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { /* * Non-encrypted passwords - convert to DOS codepage before encryption. */ @@ -676,7 +680,7 @@ BOOL cli_send_tconX(struct cli_state *cli, clistr_push(cli, dos_pword, pass, -1, STR_TERMINATE); SMBencrypt((uchar *)dos_pword,cli->secblob.data,(uchar *)pword); } else { - if((cli->sec_mode & 3) == 0) { + if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { /* * Non-encrypted passwords - convert to DOS codepage before using. */ @@ -733,10 +737,10 @@ BOOL cli_send_tconX(struct cli_state *cli, return True; } - /**************************************************************************** -send a tree disconnect + Send a tree disconnect. ****************************************************************************/ + BOOL cli_tdis(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); @@ -752,10 +756,10 @@ BOOL cli_tdis(struct cli_state *cli) return !cli_is_error(cli); } - /**************************************************************************** -send a negprot command + Send a negprot command. ****************************************************************************/ + void cli_negprot_send(struct cli_state *cli) { char *p; @@ -787,10 +791,10 @@ void cli_negprot_send(struct cli_state *cli) cli_send_smb(cli); } - /**************************************************************************** -send a negprot command + Send a negprot command. ****************************************************************************/ + BOOL cli_negprot(struct cli_state *cli) { char *p; @@ -860,6 +864,14 @@ BOOL cli_negprot(struct cli_state *cli) smb_buf(cli->inbuf)+8, sizeof(cli->server_domain), smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } + + /* A way to attempt to force SMB signing */ + if (getenv("CLI_FORCE_SMB_SIGNING")) + cli->sign_info.use_smb_signing = True; + + if (cli->sign_info.use_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) + cli->sign_info.use_smb_signing = False; + } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); @@ -872,11 +884,13 @@ BOOL cli_negprot(struct cli_state *cli) cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); + cli->sign_info.use_smb_signing = False; } else { /* the old core protocol */ cli->use_spnego = False; cli->sec_mode = 0; cli->serverzone = TimeDiff(time(NULL)); + cli->sign_info.use_smb_signing = False; } cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); @@ -889,10 +903,10 @@ BOOL cli_negprot(struct cli_state *cli) return True; } - /**************************************************************************** - send a session request. see rfc1002.txt 4.3 and 4.3.2 + Send a session request. See rfc1002.txt 4.3 and 4.3.2. ****************************************************************************/ + BOOL cli_session_request(struct cli_state *cli, struct nmb_name *calling, struct nmb_name *called) { @@ -975,8 +989,9 @@ BOOL cli_session_request(struct cli_state *cli, } /**************************************************************************** -open the client sockets + Open the client sockets. ****************************************************************************/ + BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern pstring user_socket_options; @@ -1028,7 +1043,9 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) return True; } -/* Initialise client credentials for authenticated pipe access */ +/**************************************************************************** + Initialise client credentials for authenticated pipe access. +****************************************************************************/ static void init_creds(struct ntuser_creds *creds, char* username, char* domain, char* password) @@ -1046,8 +1063,9 @@ static void init_creds(struct ntuser_creds *creds, char* username, } /**************************************************************************** -establishes a connection right up to doing tconX, password specified. + Establishes a connection right up to doing tconX, password specified. ****************************************************************************/ + NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, struct in_addr *dest_ip, int port, @@ -1152,55 +1170,53 @@ again: BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, struct in_addr *pdest_ip) { - struct nmb_name calling, called; + struct nmb_name calling, called; - make_nmb_name(&calling, srchost, 0x0); + make_nmb_name(&calling, srchost, 0x0); - /* - * If the called name is an IP address - * then use *SMBSERVER immediately. - */ + /* + * If the called name is an IP address + * then use *SMBSERVER immediately. + */ - if(is_ipaddress(desthost)) - make_nmb_name(&called, "*SMBSERVER", 0x20); - else - make_nmb_name(&called, desthost, 0x20); + if(is_ipaddress(desthost)) + make_nmb_name(&called, "*SMBSERVER", 0x20); + else + make_nmb_name(&called, desthost, 0x20); - if (!cli_session_request(cli, &calling, &called)) { - struct nmb_name smbservername; + if (!cli_session_request(cli, &calling, &called)) { + struct nmb_name smbservername; - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); - /* - * If the name wasn't *SMBSERVER then - * try with *SMBSERVER if the first name fails. - */ + /* + * If the name wasn't *SMBSERVER then + * try with *SMBSERVER if the first name fails. + */ - if (nmb_name_equal(&called, &smbservername)) { + if (nmb_name_equal(&called, &smbservername)) { - /* - * The name used was *SMBSERVER, don't bother with another name. - */ + /* + * The name used was *SMBSERVER, don't bother with another name. + */ - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } + cli_shutdown(cli); + return False; + } - cli_shutdown(cli); + cli_shutdown(cli); - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, pdest_ip) || - !cli_session_request(cli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ + if (!cli_initialise(cli) || + !cli_connect(cli, desthost, pdest_ip) || + !cli_session_request(cli, &calling, &smbservername)) { + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } - } + cli_shutdown(cli); + return False; + } + } - return True; + return True; } - - -- cgit From 4caf48a7005407e16fca7ea4414c4a00bddb7c85 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Sat, 1 Jun 2002 01:02:04 +0000 Subject: Add rpc for file close, expand file enum to take username (This used to be commit 4b18a94590a25882f06f88c3c7dd1a08bf990044) --- source3/libsmb/cli_srvsvc.c | 48 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 6910ba0c5b..91fd1e00c7 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -317,8 +317,9 @@ WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, } WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_level, SRV_FILE_INFO_CTR *ctr, - int preferred_len, ENUM_HND *hnd) + uint32 file_level, char *user_name, + SRV_FILE_INFO_CTR *ctr, int preferred_len, + ENUM_HND *hnd) { prs_struct qbuf, rbuf; SRV_Q_NET_FILE_ENUM q; @@ -336,8 +337,8 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, file_level, - ctr, preferred_len, hnd); + init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name, + file_level, ctr, preferred_len, hnd); /* Marshall data and send request */ @@ -401,3 +402,42 @@ WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 file_id) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_FILE_CLOSE q; + SRV_R_NET_FILE_CLOSE r; + WERROR result = W_ERROR(ERRgeneral); + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id); + + /* Marshall data and send request */ + + if (!srv_io_q_net_file_close("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_file_close("", &r, &rbuf, 0)) + goto done; + + result = r.status; + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; +} -- cgit From ef5e092bb9a97300b1d6a754f918facd71c77fdb Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jun 2002 02:20:56 +0000 Subject: Removed unused variable. (This used to be commit a8b2e76c5b90d3dcd00f26462614f56936c13110) --- source3/libsmb/cli_srvsvc.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 91fd1e00c7..2dc12d726c 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -410,7 +410,6 @@ WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, SRV_Q_NET_FILE_CLOSE q; SRV_R_NET_FILE_CLOSE r; WERROR result = W_ERROR(ERRgeneral); - int i; ZERO_STRUCT(q); ZERO_STRUCT(r); -- cgit From b433a90f021c86f39fbd1efb3d0de3ddbeb25afc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jun 2002 02:23:05 +0000 Subject: Added cli_samr_get_dom_pwinfo() function. Some reformatting. (This used to be commit d6dd7c7b14a4e3be4d7d435b6ac6bb8189070ff7) --- source3/libsmb/cli_samr.c | 120 ++++++++++++++++++++++++++++------------------ 1 file changed, 74 insertions(+), 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 9a332aa99e..dfc4ccf706 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -47,15 +47,13 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_connect(&q, cli->desthost, access_mask); if (!samr_io_q_connect("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_connect("", &r, &rbuf, 0)) { + if (!samr_io_r_connect("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -96,15 +94,13 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_close_hnd(&q, connect_pol); if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) { + if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -146,15 +142,13 @@ NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid); if (!samr_io_q_open_domain("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_domain("", &r, &rbuf, 0)) { + if (!samr_io_r_open_domain("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -196,15 +190,13 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_user(&q, domain_pol, access_mask, user_rid); if (!samr_io_q_open_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_user("", &r, &rbuf, 0)) { + if (!samr_io_r_open_user("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -246,15 +238,13 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_group(&q, domain_pol, access_mask, group_rid); if (!samr_io_q_open_group("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_group("", &r, &rbuf, 0)) { + if (!samr_io_r_open_group("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -296,15 +286,13 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_userinfo(&q, user_pol, switch_value); if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) { + if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -342,17 +330,15 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_groupinfo(&q, group_pol, info_level); if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ r.ctr = ctr; - if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) { + if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -389,15 +375,13 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_usergroups(&q, user_pol); if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) { + if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -438,15 +422,13 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid); if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) { + if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -486,15 +468,13 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_groupmem(&q, group_pol); if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) { + if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -537,24 +517,21 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_enum_dom_groups(&q, pol, *start_idx, size); if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) { + if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ result = r.status; if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { + NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) goto done; - } *num_dom_groups = r.num_entries2; @@ -1264,3 +1241,54 @@ NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Get domain password info */ + +NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint16 *unk_0, uint16 *unk_1, uint16 *unk_2) +{ + prs_struct qbuf, rbuf; + SAMR_Q_GET_DOM_PWINFO q; + SAMR_R_GET_DOM_PWINFO r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_get_dom_pwinfo(&q, cli->desthost); + + if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (NT_STATUS_IS_OK(result)) { + if (unk_0) + *unk_0 = r.unk_0; + if (unk_1) + *unk_1 = r.unk_1; + if (unk_2) + *unk_2 = r.unk_2; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From ce62a480e51afc584d6a27cae164371fc742d539 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Jun 2002 04:28:53 +0000 Subject: Removed unused function. (This used to be commit f7e75952306296b11a859f425ff5ec7082239dc2) --- source3/libsmb/namequery.c | 46 ---------------------------------------------- 1 file changed, 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 85f33aeda4..a97270b7d4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1008,52 +1008,6 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) return False; } - -/******************************************************** - resolve a name of format \\server_name or \\ipaddress - into a name. also, cut the \\ from the front for us. -*********************************************************/ - -BOOL resolve_srv_name(const char* srv_name, fstring dest_host, - struct in_addr *ip) -{ - BOOL ret; - const char *sv_name = srv_name; - - DEBUG(10,("resolve_srv_name: %s\n", srv_name)); - - if (srv_name == NULL || strequal("\\\\.", srv_name)) - { - extern pstring global_myname; - fstrcpy(dest_host, global_myname); - ip = interpret_addr2("127.0.0.1"); - return True; - } - - if (strnequal("\\\\", srv_name, 2)) - { - sv_name = &srv_name[2]; - } - - fstrcpy(dest_host, sv_name); - /* treat the '*' name specially - it is a magic name for the PDC */ - if (strcmp(dest_host,"*") == 0) { - extern pstring global_myname; - ret = resolve_name(lp_workgroup(), ip, 0x1B); - lookup_dc_name(global_myname, lp_workgroup(), ip, dest_host); - } else { - ret = resolve_name(dest_host, ip, 0x20); - } - - if (is_ipaddress(dest_host)) - { - fstrcpy(dest_host, "*SMBSERVER"); - } - - return ret; -} - - /******************************************************** Find the IP address of the master browser or DMB for a workgroup. *********************************************************/ -- cgit From d5154cb241e38106994a76806f7968619b5ec270 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Jun 2002 12:41:04 +0000 Subject: A couple of updates for the SmbEncrypt code, and some of its users. (const, takes unix string as arg) Also update cli_full_connection to take NULL pointers as 'undefined' correctly, and therefore do its own lookup etc. This what was intended, but previously you needed to supply a 0.0.0.0 IP address. Andrew Bartlett (This used to be commit 8fb1a9c6ba07dbf04a6aa1e30fa7bbd4c676ed28) --- source3/libsmb/cliconnect.c | 44 +++++++++++++++++++++++++++++++------------- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 32 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 86daafc50b..ebd25627c1 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -659,7 +659,7 @@ BOOL cli_ulogoff(struct cli_state *cli) BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { - fstring fullshare, pword, dos_pword; + fstring fullshare, pword; char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -677,8 +677,7 @@ BOOL cli_send_tconX(struct cli_state *cli, * Non-encrypted passwords - convert to DOS codepage before encryption. */ passlen = 24; - clistr_push(cli, dos_pword, pass, -1, STR_TERMINATE); - SMBencrypt((uchar *)dos_pword,cli->secblob.data,(uchar *)pword); + SMBencrypt(pass,cli->secblob.data,(uchar *)pword); } else { if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { /* @@ -1062,9 +1061,18 @@ static void init_creds(struct ntuser_creds *creds, char* username, } } -/**************************************************************************** - Establishes a connection right up to doing tconX, password specified. -****************************************************************************/ +/** + establishes a connection right up to doing tconX, password specified. + @param output_cli A fully initialised cli structure, non-null only on success + @param dest_host The netbios name of the remote host + @param dest_ip (optional) The the destination IP, NULL for name based lookup + @param port (optional) The destination port (0 for default) + @param service The share to make the connection to. Should be 'unqualified' in any way. + @param service_type The 'type' of serivice. + @param user Username, unix string + @param domain User's domain + @param password User's password, unencrypted unix string. +*/ NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, @@ -1079,17 +1087,21 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct nmb_name called; struct cli_state *cli; struct in_addr ip; - - if (!output_cli) + extern pstring global_myname; + + if (!output_cli) { DEBUG(0, ("output_cli is NULL!?!")); + SMB_ASSERT("output_cli for cli_full_connection was NULL.\n"); + } *output_cli = NULL; + + if (!my_name) + my_name = global_myname; make_nmb_name(&calling, my_name, 0x0); make_nmb_name(&called , dest_host, 0x20); -again: - if (!(cli = cli_initialise(NULL))) return NT_STATUS_NO_MEMORY; @@ -1098,13 +1110,19 @@ again: return NT_STATUS_UNSUCCESSFUL; } - ip = *dest_ip; - + if (dest_ip) { + ip = *dest_ip; + } else { + ZERO_STRUCT(ip); + } + +again: + DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service)); if (!cli_connect(cli, dest_host, &ip)) { DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n", - nmb_namestr(&called), inet_ntoa(*dest_ip))); + nmb_namestr(&called), inet_ntoa(ip))); cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index c298616220..fa1eaedb5a 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -28,7 +28,7 @@ This implements the X/Open SMB password encryption It takes a password ('unix' string), a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) +void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24) { uchar p21[21]; -- cgit From 3838eabc0e9ba2ef91d90a406767814ab61bc18a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 12 Jun 2002 01:33:30 +0000 Subject: Removed eff_name field from cli_struct as it wasn't being used anywhere. (This used to be commit aff65bf6c9f339ae1d3122d12114005c017b9b5d) --- source3/libsmb/clirap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 3eb9586a67..2064e14954 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -117,7 +117,8 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->rap_error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); cli->privileges = SVAL(p, 24); - fstrcpy(cli->eff_name,p+2); + /* The cli->eff_name field used to be set here + but it wasn't used anywhere else. */ } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); } -- cgit From caa4262db6115a6880af9618b7fe8130eecd4b98 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jun 2002 22:38:43 +0000 Subject: More of SMB signing for client - not yet finished (should be harmless). Jeremy. (This used to be commit c1b20db4bb4bb1ba485466f50b9795470027327c) --- source3/libsmb/clientgen.c | 23 ++++++++++++++--------- source3/libsmb/smbencrypt.c | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index dee86b2b05..5f42148078 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -107,7 +107,7 @@ BOOL cli_receive_smb(struct cli_state *cli) } /**************************************************************************** - send an smb to a fd. + Send an smb to a fd. ****************************************************************************/ BOOL cli_send_smb(struct cli_state *cli) @@ -117,31 +117,34 @@ BOOL cli_send_smb(struct cli_state *cli) ssize_t ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) return False; + if (cli->fd == -1) + return False; + + if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECUIRTY_SIGNITURES) + cli_caclulate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0) { - close(cli->fd); - cli->fd = -1; - DEBUG(0,("Error writing %d bytes to client. %d\n", - (int)len,(int)ret)); + close(cli->fd); + cli->fd = -1; + DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); return False; } nwritten += ret; } - return True; } /**************************************************************************** -setup basics in a outgoing packet + Setup basics in a outgoing packet. ****************************************************************************/ + void cli_setup_packet(struct cli_state *cli) { - cli->rap_error = 0; + cli->rap_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); @@ -158,6 +161,8 @@ void cli_setup_packet(struct cli_state *cli) if (cli->use_spnego) { flags2 |= FLAGS2_EXTENDED_SECURITY; } + if (cli->sign_info.use_smb_signing) + flags2 |= FLAGS2_SMB_SECUIRTY_SIGNITURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index fa1eaedb5a..de469c0293 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -331,5 +331,32 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, #endif return True; +} + +/*********************************************************** + SMB signing - calculate a MAC to send. +************************************************************/ +void cli_caclulate_sign_mac(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + struct MD5Context md5_ctx; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + SIVAL(cli->outbuf, smb_ss_field, cli->sign_info.send_seq_num); + SIVAL(cli->outbuf, smb_ss_field + 4, 0); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); + MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + cli->sign_info.send_seq_num++; + cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; + cli->sign_info.send_seq_num++; } -- cgit From 998fe278808728231b9c2d2869d5b1fb7ee19293 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jun 2002 23:01:11 +0000 Subject: Ok, now I can try my first client test... Jeremy. (This used to be commit 9d461933766f26ce772f6d5ea849ef9218c4d534) --- source3/libsmb/cliconnect.c | 29 +++++++++++++++++++++-------- source3/libsmb/smbencrypt.c | 12 ++++++++++++ 2 files changed, 33 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ebd25627c1..33e2b28609 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -53,6 +53,9 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return False; } + /* Lanman2 cannot use SMB signing. */ + cli->sign_info.use_smb_signing = False; + /* if in share level security then don't send a password now */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; @@ -199,6 +202,9 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII); + /* Plaintext password cannot use SMB signing. */ + cli->sign_info.use_smb_signing = False; + set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -269,6 +275,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); + cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); @@ -339,6 +346,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); + /* Extended security cannot use SMB signing (for now). */ + cli->sign_info.use_smb_signing = False; + set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -522,6 +532,9 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, int i; BOOL got_kerberos_mechanism = False; + /* spnego security cannot use SMB signing (for now). */ + cli->sign_info.use_smb_signing = False; + DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ @@ -638,18 +651,18 @@ BOOL cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); - SCVAL(cli->outbuf,smb_com,SMBulogoffX); - cli_setup_packet(cli); + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,2,0,True); + SCVAL(cli->outbuf,smb_com,SMBulogoffX); + cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; - return !cli_is_error(cli); + return !cli_is_error(cli); } /**************************************************************************** diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index de469c0293..29e168f7bf 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -333,6 +333,18 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } +/*********************************************************** + SMB signing - setup the MAC key. +************************************************************/ + +void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24]) +{ + /* Get first 16 bytes. */ + E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); + memcpy(&cli->sign_info.mac_key[16],resp,24); + cli->sign_info.mac_key_len = 40; +} + /*********************************************************** SMB signing - calculate a MAC to send. ************************************************************/ -- cgit From 59e0dff0c78add442cb60e72ca7cad7eb1bc7219 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Jun 2002 23:16:00 +0000 Subject: Fix spelling typo. Jeremy. (This used to be commit 0e7e8d44627ad9645a90e96001f8550b68b67a62) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 5f42148078..e7e88687b8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -120,7 +120,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return False; - if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECUIRTY_SIGNITURES) + if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) cli_caclulate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; @@ -162,7 +162,7 @@ void cli_setup_packet(struct cli_state *cli) flags2 |= FLAGS2_EXTENDED_SECURITY; } if (cli->sign_info.use_smb_signing) - flags2 |= FLAGS2_SMB_SECUIRTY_SIGNITURES; + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } -- cgit From 60ad5b69808c0ebfecd13c8f741f4e5687742899 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 Jun 2002 04:21:56 +0000 Subject: Fix up some of the SMB signing code: The problem was that *all* packets were being signed, even packets before signing was set up. (This broke the session request). This fixes it to be an 'opt in' measure - that is, we only attempt to sign things after we have got a valid, non-guest session setup as per the CIFS spec. I've not tested this against an MS server, becouse my VMware is down, but at least it doesn't break the build farm any more. Andrew Bartlett (This used to be commit 1dc5a8765876c1ca822e454651f8fd4a551965e9) --- source3/libsmb/cliconnect.c | 41 ++++++++++++++++++++++++----------------- source3/libsmb/clientgen.c | 3 +-- source3/libsmb/clireadwrite.c | 11 +++++++++++ source3/libsmb/smbencrypt.c | 10 ++++++++++ 4 files changed, 46 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 33e2b28609..135238b9a7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -144,9 +144,6 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) char *p; uint32 capabilities = cli_session_setup_capabilities(cli); - /* Guest cannot use SMB signing. */ - cli->sign_info.use_smb_signing = False; - set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -202,9 +199,6 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII); - /* Plaintext password cannot use SMB signing. */ - cli->sign_info.use_smb_signing = False; - set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -275,12 +269,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); - cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); } + if (cli->sign_info.negotiated_smb_signing) { + cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); + } + /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); @@ -311,10 +308,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, show_msg(cli->inbuf); + if (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */) { + /* We only use it if we have a successful non-guest connect */ + cli->sign_info.use_smb_signing = False; + } + if (cli_is_error(cli)) { return False; } - + /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -346,9 +348,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - /* Extended security cannot use SMB signing (for now). */ - cli->sign_info.use_smb_signing = False; - set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -813,6 +812,11 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send negprot again, particularly after setting up SMB Signing\n")); + return False; + } + if (cli->protocol < PROTOCOL_NT1) { cli->use_spnego = False; } @@ -879,10 +883,10 @@ BOOL cli_negprot(struct cli_state *cli) /* A way to attempt to force SMB signing */ if (getenv("CLI_FORCE_SMB_SIGNING")) - cli->sign_info.use_smb_signing = True; - - if (cli->sign_info.use_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) - cli->sign_info.use_smb_signing = False; + cli->sign_info.negotiated_smb_signing = True; + + if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) + cli->sign_info.negotiated_smb_signing = False; } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; @@ -896,13 +900,11 @@ BOOL cli_negprot(struct cli_state *cli) cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); - cli->sign_info.use_smb_signing = False; } else { /* the old core protocol */ cli->use_spnego = False; cli->sec_mode = 0; cli->serverzone = TimeDiff(time(NULL)); - cli->sign_info.use_smb_signing = False; } cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); @@ -929,6 +931,11 @@ BOOL cli_session_request(struct cli_state *cli, /* 445 doesn't have session request */ if (cli->port == 445) return True; + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); + return False; + } + /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e7e88687b8..c9500ead5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -120,8 +120,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return False; - if (SVAL(cli->outbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) - cli_caclulate_sign_mac(cli); + cli_caclulate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 6fce1c039b..756a6cce2f 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -128,6 +128,11 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ } #if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ + +/* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0 + you must fix ensure you don't attempt to sign the packets - data + *will* be currupted */ + /**************************************************************************** Issue a single SMBreadraw and don't wait for a reply. ****************************************************************************/ @@ -135,6 +140,12 @@ Issue a single SMBreadraw and don't wait for a reply. static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { + + if (!cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot use readraw and SMB Signing\n")); + return False; + } + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 29e168f7bf..9ae6da0ced 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -343,6 +343,8 @@ void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); memcpy(&cli->sign_info.mac_key[16],resp,24); cli->sign_info.mac_key_len = 40; + cli->sign_info.use_smb_signing = True; + } /*********************************************************** @@ -354,6 +356,14 @@ void cli_caclulate_sign_mac(struct cli_state *cli) unsigned char calc_md5_mac[16]; struct MD5Context md5_ctx; + if (!cli->sign_info.use_smb_signing) { + return; + } + + /* These calls are INCONPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. -- cgit From a54afa45be41a46432470b6fa3f29050f09b47ba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 Jun 2002 05:03:11 +0000 Subject: Two things: Check how many paramaters that the LDAP libs take for the rebind proc (some give an extra paramter to pass a void* paramater) and some small changes for the SMB signing code to reset things when the signing starts, and to 'turn off' signing if the session setup failed. Andrew Bartlett (This used to be commit a8805a34e5d96eeb5ffe15681b241d5a449a6144) --- source3/libsmb/cliconnect.c | 11 ++++++----- source3/libsmb/smbencrypt.c | 10 ++++++---- 2 files changed, 12 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 135238b9a7..893d194a87 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -258,6 +258,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, uint32 capabilities = cli_session_setup_capabilities(cli); fstring pword, ntpword; char *p; + BOOL tried_signing = False; if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { return False; @@ -269,15 +270,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); + if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { + cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); + tried_signing = True; + } } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); } - if (cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); - } - /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); @@ -308,7 +309,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, show_msg(cli->inbuf); - if (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */) { + if (tried_signing && (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */)) { /* We only use it if we have a successful non-guest connect */ cli->sign_info.use_smb_signing = False; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 9ae6da0ced..95434d0ae4 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -345,6 +345,12 @@ void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, cli->sign_info.mac_key_len = 40; cli->sign_info.use_smb_signing = True; + /* These calls are INCONPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + + /* Reset the sequence number in case we had a previous (aborted) attempt */ + cli->sign_info.send_seq_num = 0; } /*********************************************************** @@ -360,10 +366,6 @@ void cli_caclulate_sign_mac(struct cli_state *cli) return; } - /* These calls are INCONPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. -- cgit From 904533dc9e1948adcd4df5f2a771d20bedb0f520 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Jun 2002 17:23:20 +0000 Subject: Don't use uint. It doesn't exist on some platforms and we don't define it. Replaced with "unsigned int". Jeremy. (This used to be commit 5841ca54b6a8c36f3d76c12570ff8f2211ed2363) --- source3/libsmb/cli_samr.c | 2 +- source3/libsmb/cliconnect.c | 8 ++++++++ source3/libsmb/clifile.c | 2 +- source3/libsmb/clirap2.c | 10 +++++----- 4 files changed, 15 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index dfc4ccf706..91577b3325 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -407,7 +407,7 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, SAMR_Q_QUERY_USERALIASES q; SAMR_R_QUERY_USERALIASES r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint ptr=1; + unsigned int ptr=1; ZERO_STRUCT(q); ZERO_STRUCT(r); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 893d194a87..cc9821dc29 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -634,10 +634,12 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, pass, workgroup); } +#if 0 /* JRATEST for signing. */ /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { return cli_session_setup_spnego(cli, user, pass, workgroup); } +#endif /* otherwise do a NT1 style session setup */ return cli_session_setup_nt1(cli, user, @@ -822,6 +824,10 @@ BOOL cli_negprot(struct cli_state *cli) cli->use_spnego = False; } +#if 1 /* JRA SIGN TEST */ + cli->use_spnego = False; +#endif + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -886,8 +892,10 @@ BOOL cli_negprot(struct cli_state *cli) if (getenv("CLI_FORCE_SMB_SIGNING")) cli->sign_info.negotiated_smb_signing = True; +#if 0 if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) cli->sign_info.negotiated_smb_signing = False; +#endif } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 05843ac5de..a47c956a55 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -76,7 +76,7 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, cons uint32 unix_perms_to_wire(mode_t perms) { - uint ret = 0; + unsigned int ret = 0; ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0); ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0); diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 00cd4b15f3..9c3ec212d5 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1493,7 +1493,7 @@ int cli_NetPrintQEnum(struct cli_state *cli, for (j=0;j Date: Tue, 25 Jun 2002 07:58:29 +0000 Subject: Kill off unnecessary cast. (This used to be commit 658e853bc6914113dcd4f67d7a1d2761372b562d) --- source3/libsmb/trust_passwd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 51ffa1dd95..fd98e8dca9 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -71,7 +71,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); new_trust_passwd = talloc_strdup(mem_ctx, str); - E_md4hash((uchar *)new_trust_passwd, new_trust_passwd_hash); + E_md4hash(new_trust_passwd, new_trust_passwd_hash); nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, new_trust_passwd_hash); @@ -96,7 +96,8 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx already setup the connection to the NETLOGON pipe **********************************************************/ -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *domain) +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *domain) { unsigned char old_trust_passwd_hash[16]; char *up_domain; -- cgit From 07465761137adf756d771fa1f8592c294488e779 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Jun 2002 08:57:24 +0000 Subject: Update cli_full_connection() to take a 'flags' paramater, and try to get a few more places to use it. Andrew Bartlett (This used to be commit 23689b0746d5ab030d8693abf71dd2e80ec1d7c7) --- source3/libsmb/cliconnect.c | 41 ++++++++++++++++++++++++++--------------- source3/libsmb/trust_passwd.c | 3 ++- 2 files changed, 28 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cc9821dc29..c621d9a34e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Barteltt 2001-2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1096,7 +1097,7 @@ static void init_creds(struct ntuser_creds *creds, char* username, @param dest_host The netbios name of the remote host @param dest_ip (optional) The the destination IP, NULL for name based lookup @param port (optional) The destination port (0 for default) - @param service The share to make the connection to. Should be 'unqualified' in any way. + @param service (optional) The share to make the connection to. Should be 'unqualified' in any way. @param service_type The 'type' of serivice. @param user Username, unix string @param domain User's domain @@ -1104,11 +1105,12 @@ static void init_creds(struct ntuser_creds *creds, char* username, */ NTSTATUS cli_full_connection(struct cli_state **output_cli, - const char *my_name, const char *dest_host, + const char *my_name, + const char *dest_host, struct in_addr *dest_ip, int port, char *service, char *service_type, char *user, char *domain, - char *password) + char *password, int flags) { struct ntuser_creds creds; NTSTATUS nt_status; @@ -1123,17 +1125,15 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, SMB_ASSERT("output_cli for cli_full_connection was NULL.\n"); } - *output_cli = NULL; - if (!my_name) my_name = global_myname; - make_nmb_name(&calling, my_name, 0x0); - make_nmb_name(&called , dest_host, 0x20); - if (!(cli = cli_initialise(NULL))) return NT_STATUS_NO_MEMORY; + make_nmb_name(&calling, my_name, 0x0); + make_nmb_name(&called , dest_host, 0x20); + if (cli_set_port(cli, port) != port) { cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; @@ -1172,6 +1172,12 @@ again: return NT_STATUS_UNSUCCESSFUL; } + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) { + cli->use_spnego = False; + } else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { + cli->use_kerberos = True; + } + if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); nt_status = NT_STATUS_UNSUCCESSFUL; @@ -1182,18 +1188,23 @@ again: if (!cli_session_setup(cli, user, password, strlen(password)+1, password, strlen(password)+1, domain)) { - DEBUG(1,("failed session setup\n")); - nt_status = cli_nt_error(cli); - cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) - nt_status = NT_STATUS_UNSUCCESSFUL; - return nt_status; + if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) + || cli_session_setup(cli, "", "", 0, + "", 0, domain)) { + } else { + nt_status = cli_nt_error(cli); + DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); + cli_shutdown(cli); + if (NT_STATUS_IS_OK(nt_status)) + nt_status = NT_STATUS_UNSUCCESSFUL; + return nt_status; + } } if (service) { if (!cli_send_tconX(cli, service, service_type, (char*)password, strlen(password)+1)) { - DEBUG(1,("failed tcon_X\n")); + DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); nt_status = cli_nt_error(cli); cli_shutdown(cli); if (NT_STATUS_IS_OK(nt_status)) { diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index fd98e8dca9..7491f15f52 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -77,7 +77,8 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx new_trust_passwd_hash); if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("%s : change_trust_account_password: Changed password.\n", timestring(False))); + DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", + timestring(False))); /* * Return the result of trying to write the new password * back into the trust account file. -- cgit From 12658bc7257732b28ffe8e18a47b1527df693510 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 2002 06:39:18 +0000 Subject: reverted some bogus test code that jeremy accidentally committed (This used to be commit 6b28ca8bd2a6613989bb23be951836d173296197) --- source3/libsmb/cliconnect.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c621d9a34e..50d9edf5b2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -635,12 +635,10 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, pass, workgroup); } -#if 0 /* JRATEST for signing. */ /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { return cli_session_setup_spnego(cli, user, pass, workgroup); } -#endif /* otherwise do a NT1 style session setup */ return cli_session_setup_nt1(cli, user, @@ -825,10 +823,6 @@ BOOL cli_negprot(struct cli_state *cli) cli->use_spnego = False; } -#if 1 /* JRA SIGN TEST */ - cli->use_spnego = False; -#endif - memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -893,10 +887,8 @@ BOOL cli_negprot(struct cli_state *cli) if (getenv("CLI_FORCE_SMB_SIGNING")) cli->sign_info.negotiated_smb_signing = True; -#if 0 if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) cli->sign_info.negotiated_smb_signing = False; -#endif } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; -- cgit From 07f35f68e00b48ad6ec4d18c628d0bb57bad85ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 2002 06:44:37 +0000 Subject: - completely rewrote the wins_srv.c code. It is now much simpler, and gives us a good grounding to properly support multiple wins servers for different interfaces (which will be coming soon ...) - fixed our wins registration failover code to actually do failover! We were not trying to register with a secondary wins server at all when the primary was down. We now fallback correctly. - fixed the multi-homed name registration packets so that they work even in a non-connected network (ie. when one of our interfaces is not routable from the wins server. Yes, this really happens in the real world). (This used to be commit a049360d5b0d95a935b06aad43efc17d34de46dc) --- source3/libsmb/namequery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a97270b7d4..d709f997f5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -603,10 +603,12 @@ BOOL name_register_wins(const char *name, int name_type) if (0 == wins_srv_count()) return False; + sendto_ip = wins_srv_ip(); + if( DEBUGLVL( 4 ) ) { dbgtext( "name_register_wins: Registering my name %s ", name ); - dbgtext( "with WINS server %s.\n", wins_srv_name() ); + dbgtext( "with WINS server %s.\n", inet_ntoa(sendto_ip)); } sock = open_socket_in( SOCK_DGRAM, 0, 3, @@ -616,8 +618,6 @@ BOOL name_register_wins(const char *name, int name_type) set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */ - sendto_ip = wins_srv_ip(); - if (num_interfaces > 1) { for (i = 0; i < num_interfaces; i++) { -- cgit From b20ca8b8683e584d7a1843b07f262da34b6dca19 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 2002 08:09:28 +0000 Subject: removed the wins name registration code from libsmbclient it is *completely* bogus for our client code to be doing wins registrations. Not only is it slow as hell (think about when a wins server is down) but how the heck is going to answer the queries that will later come in for our name? And what happens when libsmbclient sends registrations and nmbd then gets the WACK response from the wins server? we end up losing our name! Name registration is a job for nmbd, not for clients. (This used to be commit 62774923ffdce15eded0f37ba99e33e9cd7a358c) --- source3/libsmb/libsmbclient.c | 2 - source3/libsmb/namequery.c | 385 +++++++++++++++++------------------------- 2 files changed, 158 insertions(+), 229 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 237701b968..3066f72280 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -523,8 +523,6 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) } DEBUG(0,("Using netbios name %s.\n", my_netbios_name)); - name_register_wins(my_netbios_name, 0); - /* * Now initialize the file descriptor array and figure out what the * max open files is, so we can return FD's that are above the max diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index d709f997f5..c85c8c48df 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -307,171 +307,171 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, struct in_addr to_ip, int *count, int *flags) { - BOOL found=False; - int i, retries = 3; - int retry_time = bcast?250:2000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - struct in_addr *ip_list = NULL; - - memset((char *)&p,'\0',sizeof(p)); - (*count) = 0; - (*flags) = 0; - - nmb->header.name_trn_id = generate_trn_id(); - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return NULL; - - retries--; - + BOOL found=False; + int i, retries = 3; + int retry_time = bcast?250:2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + struct in_addr *ip_list = NULL; + + memset((char *)&p,'\0',sizeof(p)); + (*count) = 0; + (*flags) = 0; + + nmb->header.name_trn_id = generate_trn_id(); + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = bcast; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = recurse; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return NULL; + + retries--; + while (1) { - struct timeval tval2; - struct in_addr *tmp_ip_list; - - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!found && !send_packet(&p)) - return NULL; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); - - /* If we get a Negative Name Query Response from a WINS - * server, we should report it and give up. - */ - if( 0 == nmb2->header.opcode /* A query response */ - && !(bcast) /* from a WINS server */ - && nmb2->header.rcode /* Error returned */ - ) { - - if( DEBUGLVL( 3 ) ) { - /* Only executed if DEBUGLEVEL >= 3 */ + struct timeval tval2; + struct in_addr *tmp_ip_list; + + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!found && !send_packet(&p)) + return NULL; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + + /* If we get a Negative Name Query Response from a WINS + * server, we should report it and give up. + */ + if( 0 == nmb2->header.opcode /* A query response */ + && !(bcast) /* from a WINS server */ + && nmb2->header.rcode /* Error returned */ + ) { + + if( DEBUGLVL( 3 ) ) { + /* Only executed if DEBUGLEVEL >= 3 */ dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode ); - switch( nmb2->header.rcode ) { - case 0x01: - dbgtext( "Request was invalidly formatted.\n" ); - break; - case 0x02: - dbgtext( "Problem with NBNS, cannot process name.\n"); - break; - case 0x03: - dbgtext( "The name requested does not exist.\n" ); - break; - case 0x04: - dbgtext( "Unsupported request error.\n" ); - break; - case 0x05: - dbgtext( "Query refused error.\n" ); - break; - default: - dbgtext( "Unrecognized error code.\n" ); - break; - } - } - free_packet(p2); - return( NULL ); - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount) { - /* - * XXXX what do we do with this? Could be a - * redirect, but we'll discard it for the + switch( nmb2->header.rcode ) { + case 0x01: + dbgtext( "Request was invalidly formatted.\n" ); + break; + case 0x02: + dbgtext( "Problem with NBNS, cannot process name.\n"); + break; + case 0x03: + dbgtext( "The name requested does not exist.\n" ); + break; + case 0x04: + dbgtext( "Unsupported request error.\n" ); + break; + case 0x05: + dbgtext( "Query refused error.\n" ); + break; + default: + dbgtext( "Unrecognized error code.\n" ); + break; + } + } + free_packet(p2); + return( NULL ); + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount) { + /* + * XXXX what do we do with this? Could be a + * redirect, but we'll discard it for the * moment. */ - free_packet(p2); - continue; - } - - tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] ) - * ( (*count) + nmb2->answers->rdlength/6 ) ); - - if (!tmp_ip_list) { - DEBUG(0,("name_query: Realloc failed.\n")); - SAFE_FREE(ip_list); - } - - ip_list = tmp_ip_list; - - if (ip_list) { + free_packet(p2); + continue; + } + + tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] ) + * ( (*count) + nmb2->answers->rdlength/6 ) ); + + if (!tmp_ip_list) { + DEBUG(0,("name_query: Realloc failed.\n")); + SAFE_FREE(ip_list); + } + + ip_list = tmp_ip_list; + + if (ip_list) { DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); - for (i=0;ianswers->rdlength/6;i++) { - putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); - (*count)++; - } - DEBUGADD(2,(")\n")); - } - - found=True; - retries=0; - /* We add the flags back ... */ - if (nmb2->header.response) - (*flags) |= NM_FLAGS_RS; - if (nmb2->header.nm_flags.authoritative) - (*flags) |= NM_FLAGS_AA; - if (nmb2->header.nm_flags.trunc) - (*flags) |= NM_FLAGS_TC; - if (nmb2->header.nm_flags.recursion_desired) - (*flags) |= NM_FLAGS_RD; - if (nmb2->header.nm_flags.recursion_available) - (*flags) |= NM_FLAGS_RA; - if (nmb2->header.nm_flags.bcast) - (*flags) |= NM_FLAGS_B; - free_packet(p2); - /* - * If we're doing a unicast lookup we only - * expect one reply. Don't wait the full 2 - * seconds if we got one. JRA. - */ - if(!bcast && found) - break; - } - } + for (i=0;ianswers->rdlength/6;i++) { + putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); + DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); + (*count)++; + } + DEBUGADD(2,(")\n")); + } + + found=True; + retries=0; + /* We add the flags back ... */ + if (nmb2->header.response) + (*flags) |= NM_FLAGS_RS; + if (nmb2->header.nm_flags.authoritative) + (*flags) |= NM_FLAGS_AA; + if (nmb2->header.nm_flags.trunc) + (*flags) |= NM_FLAGS_TC; + if (nmb2->header.nm_flags.recursion_desired) + (*flags) |= NM_FLAGS_RD; + if (nmb2->header.nm_flags.recursion_available) + (*flags) |= NM_FLAGS_RA; + if (nmb2->header.nm_flags.bcast) + (*flags) |= NM_FLAGS_B; + free_packet(p2); + /* + * If we're doing a unicast lookup we only + * expect one reply. Don't wait the full 2 + * seconds if we got one. JRA. + */ + if(!bcast && found) + break; + } + } - /* Reach here if we've timed out waiting for replies.. */ - if( !bcast && !found ) { - /* Timed out wating for WINS server to respond. Mark it dead. */ - wins_srv_died( to_ip ); - } + /* Reach here if we've timed out waiting for replies.. */ + if (!bcast && !found) { + /* Timed out wating for WINS server to respond. Mark it dead. */ + wins_srv_died( to_ip ); + } - return ip_list; + return ip_list; } /******************************************************** @@ -583,75 +583,6 @@ void endlmhosts(XFILE *fp) x_fclose(fp); } -BOOL name_register_wins(const char *name, int name_type) -{ - int sock, i, return_count; - int num_interfaces = iface_count(); - struct in_addr sendto_ip; - - /* - * Check if we have any interfaces, prevents a segfault later - */ - - if (num_interfaces <= 0) - return False; /* Should return some indication of the problem */ - - /* - * Do a broadcast register ... - */ - - if (0 == wins_srv_count()) - return False; - - sendto_ip = wins_srv_ip(); - - if( DEBUGLVL( 4 ) ) - { - dbgtext( "name_register_wins: Registering my name %s ", name ); - dbgtext( "with WINS server %s.\n", inet_ntoa(sendto_ip)); - } - - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr("0.0.0.0"), True ); - - if (sock == -1) return False; - - set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */ - - if (num_interfaces > 1) { - - for (i = 0; i < num_interfaces; i++) { - - if (!name_register(sock, name, name_type, *iface_n_ip(i), - NMB_NAME_MULTIHOMED_REG_OPCODE, - True, sendto_ip, &return_count)) { - - close(sock); - return False; - - } - - } - - } - else { - - if (!name_register(sock, name, name_type, *iface_n_ip(0), - NMB_NAME_REG_OPCODE, - True, sendto_ip, &return_count)) { - - close(sock); - return False; - - } - - } - - close(sock); - - return True; - -} /******************************************************** Resolve via "bcast" method. -- cgit From caeaa0acb02f681be6025e3eafded223983960a0 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 26 Jun 2002 12:17:11 +0000 Subject: This commit finally gives us multiple wins server groups. We now accept an extended syntax for 'wins server' like this: wins server = group1:192.168.2.10 group2:192.168.3.99 group1:192.168.0.1 The tags before the IPs don't mean anything, they are just a way of grouping IPs together. If you use the old syntax (ie. no ':') then an implicit group name of '*' is used. In general I'd recommend people use interface names for the group names, but it doesn't matter much. When we register in nmbd we try to register all our IPs with each group of WINS servers. We keep trying until all of them are registered with every group, falling back to the failover WINS servers for each group as we go. When we do a WINS lookup we try each of the WINS servers for each group. If a WINS server for a group gives a negative answer then we give up on that group and move to the next group. If it times out then we move to the next failover wins server in the group. In either case, if a WINS server doesn't respond then we mark it dead for 10 minutes, to prevent lengthy waits for dead servers. (This used to be commit e125f06058b6b51382cf046b1dbb30728b8aeda5) --- source3/libsmb/namequery.c | 111 +++++++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 43 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c85c8c48df..2cdcd49b91 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -302,10 +302,12 @@ BOOL name_register(int fd, const char *name, int name_type, Do a netbios name query to find someones IP. Returns an array of IP addresses or NULL if none. *count will be set to the number of addresses returned. + *timed_out is set if we failed by timing out ****************************************************************************/ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count, int *flags) + struct in_addr to_ip, int *count, int *flags, + BOOL *timed_out) { BOOL found=False; int i, retries = 3; @@ -315,6 +317,10 @@ struct in_addr *name_query(int fd,const char *name,int name_type, struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; struct in_addr *ip_list = NULL; + + if (timed_out) { + *timed_out = False; + } memset((char *)&p,'\0',sizeof(p)); (*count) = 0; @@ -465,10 +471,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, } } - /* Reach here if we've timed out waiting for replies.. */ - if (!bcast && !found) { - /* Timed out wating for WINS server to respond. Mark it dead. */ - wins_srv_died( to_ip ); + if (timed_out) { + *timed_out = True; } return ip_list; @@ -619,7 +623,7 @@ BOOL name_resolve_bcast(const char *name, int name_type, /* Done this way to fix compiler error on IRIX 5.x */ sendto_ip = *iface_n_bcast(i); *return_ip_list = name_query(sock, name, name_type, True, - True, sendto_ip, return_count, &flags); + True, sendto_ip, return_count, &flags, NULL); if(*return_ip_list != NULL) { close(sock); return True; @@ -637,59 +641,80 @@ BOOL name_resolve_bcast(const char *name, int name_type, static BOOL resolve_wins(const char *name, int name_type, struct in_addr **return_iplist, int *return_count) { - int sock; - struct in_addr wins_ip; - BOOL wins_ismyip; + int sock, t, i; + char **wins_tags; *return_iplist = NULL; *return_count = 0; - /* - * "wins" means do a unicast lookup to the WINS server. - * Ignore if there is no WINS server specified or if the - * WINS server is one of our interfaces (if we're being - * called from within nmbd - we can't do this call as we - * would then block). - */ - DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); - if (lp_wins_support()) { - /* - * We're providing WINS support. Call ourselves so - * long as we're not nmbd. - */ - extern struct in_addr loopback_ip; - wins_ip = loopback_ip; - wins_ismyip = True; - } else if( wins_srv_count() < 1 ) { + if (wins_srv_count() < 1) { DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); return False; - } else { - wins_ip = wins_srv_ip(); - wins_ismyip = ismyip(wins_ip); } - DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); - if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { - int flags; - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()), - True ); - if (sock != -1) { - *return_iplist = name_query( sock, name, - name_type, False, - True, wins_ip, - return_count, &flags); - if(*return_iplist != NULL) { - close(sock); - return True; + /* we try a lookup on each of the WINS tags in turn */ + wins_tags = wins_srv_tags(); + + if (!wins_tags) { + /* huh? no tags?? give up in disgust */ + return False; + } + + /* in the worst case we will try every wins server with every + tag! */ + for (t=0; wins_tags && wins_tags[t]; t++) { + for (i=0; i Date: Wed, 26 Jun 2002 12:49:59 +0000 Subject: resolve_wins() now needs to be a public function (This used to be commit 0bce9af615db2eb7e95887ab6b95655d7771dac2) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2cdcd49b91..7cd7d70815 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -638,8 +638,8 @@ BOOL name_resolve_bcast(const char *name, int name_type, Resolve via "wins" method. *********************************************************/ -static BOOL resolve_wins(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) +BOOL resolve_wins(const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) { int sock, t, i; char **wins_tags; -- cgit From cb8dcb0b60d0bdd13ef20cad9784d783c62775dd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Jun 2002 00:13:20 +0000 Subject: Using 1 for a tdb hash size makes for slow inserts.... Jeremy. (This used to be commit d015c08100bf467e3f83143586a234989eca1a49) --- source3/libsmb/unexpected.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index f74a05f75f..4fc3914481 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -46,7 +46,7 @@ void unexpected_packet(struct packet_struct *p) int len=0; if (!tdbd) { - tdbd = tdb_open_log(lock_path("unexpected.tdb"), 1, + tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR | O_CREAT, 0644); if (!tdbd) { -- cgit From 223ddc3f2daf25b16ce60230336747d5fab61e39 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 27 Jun 2002 14:37:17 +0000 Subject: The next phase in the WINS rewrite! We now cope wiith multiple WINS groups and multiple failover servers for release and refresh as well as registration. We also do the regitrations in the same fashion as W2K does, where we don't try to register the next IP in the list for a name until the WINS server has acked the previos IP. This prevents us flooding the WINS server and also seems to make for much more reliable multi-homed registration. I also changed the dead WINS server code to mark pairs of IPs dead, not individual IPs. The idea is that a WINS server might be dead from the point of view of one of our interfaces, but not another, so we need to keep talking to it on one while moving onto a failover WINS server on the other interface. This copes much better with partial LAN outages and weird routing tables. (This used to be commit 313f2c9ff7a513802e4f893324865e70912d419e) --- source3/libsmb/namequery.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7cd7d70815..2c6fb2fd71 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -637,12 +637,12 @@ BOOL name_resolve_bcast(const char *name, int name_type, /******************************************************** Resolve via "wins" method. *********************************************************/ - BOOL resolve_wins(const char *name, int name_type, struct in_addr **return_iplist, int *return_count) { int sock, t, i; char **wins_tags; + struct in_addr src_ip; *return_iplist = NULL; *return_count = 0; @@ -662,15 +662,19 @@ BOOL resolve_wins(const char *name, int name_type, return False; } + /* the address we will be sending from */ + src_ip = *interpret_addr2(lp_socket_address()); + /* in the worst case we will try every wins server with every tag! */ for (t=0; wins_tags && wins_tags[t]; t++) { - for (i=0; i Date: Thu, 27 Jun 2002 14:54:01 +0000 Subject: fixed a link problem with global_in_nmbd (This used to be commit 9a3e323ec261a1ee3a83f8c558583c3d4a53e06a) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2c6fb2fd71..75e2458964 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -22,7 +22,7 @@ #include "includes.h" /* nmbd.c sets this to True. */ -BOOL global_in_nmbd = False; +extern BOOL global_in_nmbd; /**************************************************************************** generate a random trn_id -- cgit From 452eb38df0553886313c9b19a945385d853e19ab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jun 2002 00:17:15 +0000 Subject: Proper merge of all the working printing stuff from APPLIANCE_HEAD. Now let's keep this in sync ! Jeremy. (This used to be commit 3603cd4947df2c10df604447dc542932cb9e5d5a) --- source3/libsmb/cli_spoolss.c | 8 +- source3/libsmb/cli_spoolss_notify.c | 223 ++++++++++++++++++++++++++++++++++++ 2 files changed, 227 insertions(+), 4 deletions(-) create mode 100644 source3/libsmb/cli_spoolss_notify.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 48094f8179..18e17758d6 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -1556,11 +1556,11 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: decode_jobs_1(mem_ctx, r.buffer, r.returned, - &ctr->job.job_info_1); + ctr->job.job_info_1); break; case 2: decode_jobs_2(mem_ctx, r.buffer, r.returned, - &ctr->job.job_info_2); + ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); @@ -1669,10 +1669,10 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: - decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1); + decode_jobs_1(mem_ctx, r.buffer, 1, ctr->job.job_info_1); break; case 2: - decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2); + decode_jobs_2(mem_ctx, r.buffer, 1, ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); diff --git a/source3/libsmb/cli_spoolss_notify.c b/source3/libsmb/cli_spoolss_notify.c new file mode 100644 index 0000000000..922b0fbb1d --- /dev/null +++ b/source3/libsmb/cli_spoolss_notify.c @@ -0,0 +1,223 @@ +/* + Unix SMB/CIFS implementation. + RPC pipe client + + Copyright (C) Gerald Carter 2001-2002, + Copyright (C) Tim Potter 2000-2002, + Copyright (C) Andrew Tridgell 1994-2000, + Copyright (C) Luke Kenneth Casson Leighton 1996-2000, + Copyright (C) Jean-Francois Micouleau 1999-2000. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + * SPOOLSS Client RPC's used by servers as the notification + * back channel. + */ + +/* Send a ReplyOpenPrinter request. This rpc is made by the printer + server to the printer client in response to a rffpcnex request. + The rrfpcnex request names a printer and a handle (the printerlocal + value) and this rpc establishes a back-channel over which printer + notifications are performed. */ + +WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *printer, uint32 printerlocal, uint32 type, + POLICY_HND *handle) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_REPLYOPENPRINTER q; + SPOOL_R_REPLYOPENPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + /* Initialise input parameters */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type); + + /* Marshall data and send request */ + + if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0)) + goto done; + + /* Return result */ + + memcpy(handle, &r.handle, sizeof(r.handle)); + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Close a back-channel notification connection */ + +WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *handle) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_REPLYCLOSEPRINTER q; + SPOOL_R_REPLYCLOSEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + /* Initialise input parameters */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + make_spoolss_q_reply_closeprinter(&q, handle); + + /* Marshall data and send request */ + + if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0)) + goto done; + + /* Return result */ + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/********************************************************************* + This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change + notification event when the registration **did not** use + SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor. + Also see cli_spolss_reply_rrpcn() + *********************************************************************/ + +WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 condition, uint32 change_id) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ROUTERREPLYPRINTER q; + SPOOL_R_ROUTERREPLYPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + /* Initialise input parameters */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id); + + /* Marshall data and send request */ + + if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/********************************************************************* + This SPOOLSS_REPLY_RRPCN function is used to send a change + notification event when the registration **did** use + SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor + Also see cli_spoolss_routereplyprinter() + *********************************************************************/ + +WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 notify_data_len, + SPOOL_NOTIFY_INFO_DATA *notify_data, + uint32 change_low, uint32 change_high) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_REPLY_RRPCN q; + SPOOL_R_REPLY_RRPCN r; + WERROR result = W_ERROR(ERRgeneral); + SPOOL_NOTIFY_INFO notify_info; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + ZERO_STRUCT(notify_info); + + /* Initialise input parameters */ + + notify_info.version = 0x2; + notify_info.flags = 0x00020000; /* ?? */ + notify_info.count = notify_data_len; + notify_info.data = notify_data; + + /* create and send a MSRPC command with api */ + /* store the parameters */ + + make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high, + ¬ify_info); + + /* Marshall data and send request */ + + if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0)) + goto done; + + if (r.unknown0 == 0x00080000) + DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); + + result = r.status; + +done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} -- cgit From 01eec582433744967d35d611e6b153262fa8f9f2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 28 Jun 2002 03:51:31 +0000 Subject: make net join a bit less verbose these errors happen all the time, so they shouldn't be level 0 (This used to be commit abc2aed26c6cb12a86987a3846ca5c9f7df9a5ae) --- source3/libsmb/cli_netlogon.c | 2 +- source3/libsmb/trust_passwd.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 765f19a5fe..4f5ccb1e21 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -197,7 +197,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, result = new_cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed %s\n", + DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", nt_errstr(result))); } diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 7491f15f52..3b77f7330e 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -39,7 +39,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("just_change_the_password: unable to setup creds (%s)!\n", + DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", nt_errstr(result))); return result; } -- cgit From 4b12f559b9fa61309e1a64c8b286136aba9ba3eb Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 1 Jul 2002 03:42:04 +0000 Subject: The 17-bit length field in the header contains the number of bytes which follow the header, not the full packet size. [Yes, the length field is either 17-bits, or (per the RFCs) it is a 16-bit length field preceeded by an 8-bit flags field of which only the low-order bit may be used. If that bit is set, then add 65536 to the 16-bit length field. (In other words, it's a 17-bit unsigned length field.) ...unless, of course, the transport is native TCP [port 445] in which case the length field *might* be 24-bits wide.] Anyway, the change is a very minor one. We were including the four bytes of the header in the length count and, as a result, sending four bytes of garbage at the end of the SESSION REQUEST packet. Small fix in function cli_session_request(). (This used to be commit cd2b1357066a712efcf87ac61922ef871118e8de) --- source3/libsmb/cliconnect.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 50d9edf5b2..f0b02b97b0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -952,7 +952,14 @@ BOOL cli_session_request(struct cli_state *cli, name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); - /* setup the packet length */ + /* setup the packet length + * Remove four bytes from the length count, since the length + * field in the NBT Session Service header counts the number + * of bytes which follow. The cli_send_smb() function knows + * about this and accounts for those four bytes. + * CRH. + */ + len -= 4; _smb_setlen(cli->outbuf,len); SCVAL(cli->outbuf,0,0x81); -- cgit From a2c8ca186f7261fdab49ed40949320a45868d2b5 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Mon, 1 Jul 2002 03:42:28 +0000 Subject: The 17-bit length field in the header contains the number of bytes which follow the header, not the full packet size. [Yes, the length field is either 17-bits, or (per the RFCs) it is a 16-bit length field preceeded by an 8-bit flags field of which only the low-order bit may be used. If that bit is set, then add 65536 to the 16-bit length field. (In other words, it's a 17-bit unsigned length field.) ...unless, of course, the transport is native TCP [port 445] in which case the length field *might* be 24-bits wide.] Anyway, the change is a very minor one. We were including the four bytes of the header in the length count and, as a result, sending four bytes of garbage at the end of the SESSION REQUEST packet. Small fix in function cli_session_request(). (This used to be commit d08471688b65371eb3de73b03a8ffaee86659ba0) --- source3/libsmb/cliconnect.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8ddd116679..4be63b8f2e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -902,7 +902,14 @@ BOOL cli_session_request(struct cli_state *cli, name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); - /* setup the packet length */ + /* setup the packet length + * Remove four bytes from the length count, since the length + * field in the NBT Session Service header counts the number + * of bytes which follow. The cli_send_smb() function knows + * about this and accounts for those four bytes. + * CRH. + */ + len -= 4; _smb_setlen(cli->outbuf,len); SCVAL(cli->outbuf,0,0x81); -- cgit From 2e917ea040d85f06b8e40b6fd178c08ee84797c9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 05:09:29 +0000 Subject: sort name query responses by how far they are from our interface broadcast addresses. This makes it far more likely that we will try to talk to an interface that is routable from one of our interfaces. (This used to be commit bc1a0506868266088ae585a7a5dcb1ac8ca3474d) --- source3/libsmb/namequery.c | 41 +++++++++++++++++++++++++++++++++++++++++ source3/libsmb/nmblib.c | 4 ++-- 2 files changed, 43 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 75e2458964..242601d1da 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -298,6 +298,44 @@ BOOL name_register(int fd, const char *name, int name_type, return True; } + +/* + comparison function used by sort_ip_list +*/ +static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +{ + int max_bits1=0, max_bits2=0; + int num_interfaces = iface_count(); + int i; + + for (i=0;is_addr, (uchar *)&ip.s_addr); + bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr); + max_bits1 = MAX(bits1, max_bits1); + max_bits2 = MAX(bits2, max_bits2); + } + + return max_bits2 - max_bits1; +} + +/* + sort an IP list so that names that are close to one of our interfaces + are at the top. This prevents the problem where a WINS server returns an IP that + is not reachable from our subnet as the first match +*/ +static void sort_ip_list(struct in_addr *iplist, int count) +{ + if (count <= 1) { + return; + } + + qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); +} + + /**************************************************************************** Do a netbios name query to find someones IP. Returns an array of IP addresses or NULL if none. @@ -475,6 +513,9 @@ struct in_addr *name_query(int fd,const char *name,int name_type, *timed_out = True; } + /* sort the ip list so we choose close servers first if possible */ + sort_ip_list(ip_list, *count); + return ip_list; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 9a37b4252a..ba0d8cee5d 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1045,7 +1045,7 @@ BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name) /**************************************************************************** return the number of bits that match between two 4 character buffers ***************************************************************************/ -static int matching_bits(uchar *p1, uchar *p2) +int matching_quad_bits(uchar *p1, uchar *p2) { int i, j, ret = 0; for (i=0; i<4; i++) { @@ -1071,7 +1071,7 @@ compare two query reply records ***************************************************************************/ static int name_query_comp(uchar *p1, uchar *p2) { - return matching_bits(p2+2, sort_ip) - matching_bits(p1+2, sort_ip); + return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); } /**************************************************************************** -- cgit From 3563257247c9444f1b1489fb9f4faba3dc50959e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 05:39:32 +0000 Subject: bias the lookup sorting towards directly reachable IPs (This used to be commit 514b91827a970a0041314af341b8c66a01668e4a) --- source3/libsmb/namequery.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 242601d1da..2bf72fbaac 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -317,6 +317,14 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) max_bits1 = MAX(bits1, max_bits1); max_bits2 = MAX(bits2, max_bits2); } + + /* bias towards directly reachable IPs */ + if (iface_local(*ip1)) { + max_bits1 += 32; + } + if (iface_local(*ip2)) { + max_bits2 += 32; + } return max_bits2 - max_bits1; } -- cgit From 9930b0b0650ae3e38c033c28672398425dd8228c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 1 Jul 2002 09:12:41 +0000 Subject: used findstatic.pl to make some variables static and remove some dead code (This used to be commit 91ad9041e9507d36eb3f40c23c5d4df61f139ef0) --- source3/libsmb/namequery.c | 99 ---------------------------------------------- 1 file changed, 99 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2bf72fbaac..68c09751bd 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -207,97 +207,6 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t return result; } -/**************************************************************************** - Do a NetBIOS name registation to try to claim a name ... -***************************************************************************/ -BOOL name_register(int fd, const char *name, int name_type, - struct in_addr name_ip, int opcode, - BOOL bcast, - struct in_addr to_ip, int *count) -{ - int retries = 3; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - struct in_addr register_ip; - - DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip))); - - register_ip.s_addr = name_ip.s_addr; /* Fix this ... */ - - memset((char *)&p, '\0', sizeof(p)); - - *count = 0; - - nmb->header.name_trn_id = generate_trn_id(); - nmb->header.opcode = opcode; - nmb->header.response = False; - nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = True; /* ? */ - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = True; - - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 1; - - make_nmb_name(&nmb->question.question_name, name, name_type); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - /* Now, create the additional stuff for a registration request */ - - if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) { - - DEBUG(0, ("name_register: malloc fail for additional record.\n")); - return False; - - } - - memset((char *)nmb->additional, '\0', sizeof(struct res_rec)); - - nmb->additional->rr_name = nmb->question.question_name; - nmb->additional->rr_type = RR_TYPE_NB; - nmb->additional->rr_class = RR_CLASS_IN; - - /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */ - if (nmb->header.nm_flags.bcast) - nmb->additional->ttl = PERMANENT_TTL; - else - nmb->additional->ttl = lp_max_ttl(); - - nmb->additional->rdlength = 6; - - nmb->additional->rdata[0] = NB_MFLAG & 0xFF; - - /* Set the address for the name we are registering. */ - putip(&nmb->additional->rdata[2], ®ister_ip); - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return False; - - retries--; - - if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) { - debug_nmb_packet(p2); - SAFE_FREE(p2); /* No memory leaks ... */ - } - - return True; -} - /* comparison function used by sort_ip_list @@ -1248,14 +1157,6 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ } -/******************************************************** - Get the IP address list of the Local Master Browsers - ********************************************************/ - -BOOL get_lmb_list(struct in_addr **ip_list, int *count) -{ - return internal_resolve_name( MSBROWSE, 0x1, ip_list, count); -} /******************************************************** Get the IP address list of the PDC/BDC's of a Domain. -- cgit From 4a0fab59cb70c6bdcbfb8bd8d3492cd1e01ca917 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 3 Jul 2002 07:21:07 +0000 Subject: Add my copyright (which I should have added months ago...) (This used to be commit 2d7eccbeb258b4fdd14323a40f9537eb265f73e1) --- source3/libsmb/errormap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index c30db3ad95..a35108c3de 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -2,6 +2,7 @@ * Unix SMB/CIFS implementation. * error mapping functions * Copyright (C) Andrew Tridgell 2001 + * Copyright (C) Andrew Bartlett 2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by -- cgit From a19c823c3c21af6267018c62b68cce0937a3da13 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 3 Jul 2002 07:22:45 +0000 Subject: Make these functions static. These are not mentioned in the external header, and appear to be functions for internal use. Richard: please check. Andrew Bartlett (This used to be commit cb61e61a113dede4a0b0f5d31d0ec89c4b6ecd65) --- source3/libsmb/libsmbclient.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3066f72280..dcf2755c8d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -55,8 +55,8 @@ struct smbc_file { int dir_type, dir_error; }; -int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ -BOOL smbc_getatr(struct smbc_server *srv, char *path, +static int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ +static BOOL smbc_getatr(struct smbc_server *srv, char *path, uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino); @@ -1164,7 +1164,7 @@ int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo */ -BOOL smbc_getatr(struct smbc_server *srv, char *path, +static BOOL smbc_getatr(struct smbc_server *srv, char *path, uint16 *mode, size_t *size, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino) @@ -2344,7 +2344,7 @@ int smbc_lseekdir(int fd, off_t offset) * Routine to fstat a dir */ -int smbc_fstatdir(int fd, struct stat *st) +static int smbc_fstatdir(int fd, struct stat *st) { if (!smbc_initialized) { -- cgit From bc418dbbc0a8c342335aa24cb58e18c0f8b48cfa Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 4 Jul 2002 03:32:36 +0000 Subject: Fixed incorrect debug. (This used to be commit dd46ff7619129782963ec6ea727e5d731370ee7d) --- source3/libsmb/cli_netlogon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 4f5ccb1e21..d32e0e77e4 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -43,7 +43,7 @@ NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, /* create and send a MSRPC command with api NET_REQCHAL */ DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", - cli->desthost, global_myname, credstr(clnt_chal->data))); + global_myname, cli->desthost, credstr(clnt_chal->data))); /* store the parameters */ init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal); -- cgit From 3593e5baf7c3b334da390b027ef7d236ce318ccd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 Jul 2002 14:47:03 +0000 Subject: fix declaration of global_in_nmbd (This used to be commit 07de8418369dad1f015369e70e9303fea4130295) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 68c09751bd..18564bccf4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -22,7 +22,7 @@ #include "includes.h" /* nmbd.c sets this to True. */ -extern BOOL global_in_nmbd; +BOOL global_in_nmbd = False; /**************************************************************************** generate a random trn_id -- cgit From 669358c05f8300dc14cc462a0d00eab86dc0e84a Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 11 Jul 2002 23:33:00 +0000 Subject: Commit Tom Jansen's changes to head. (This used to be commit d3fdce07ab5955abd1f923127ae9eb5006aea505) --- source3/libsmb/libsmbclient.c | 1718 +++++++++++++++++++++-------------------- 1 file changed, 899 insertions(+), 819 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index dcf2755c8d..77a81c10c8 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1,9 +1,11 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. + Version 2.0 SMB client library implementation Copyright (C) Andrew Tridgell 1998 - Copyright (C) Richard Sharpe 2000 + Copyright (C) Richard Sharpe 2000, 2002 Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,56 +23,41 @@ */ #include "includes.h" + +/* + * Define this to get the real SMBCFILE and SMBCSRV structures + */ +#define _SMBC_INTERNAL + #include "libsmbclient.h" -/* Structure for servers ... Held here so we don't need an include ... - * May be better to put in an include file +/* + * Functions exported by libsmb_cache.c that we need here */ +int smbc_default_cache_functions(SMBCCTX * context); -struct smbc_server { - struct smbc_server *next, *prev; - struct cli_state cli; - dev_t dev; - char *server_name; - char *share_name; - char *workgroup; - char *username; - BOOL no_pathinfo2; -}; - -/* Keep directory entries in a list */ -struct smbc_dir_list { - struct smbc_dir_list *next; - struct smbc_dirent *dirent; -}; - -struct smbc_file { - int cli_fd; - int smbc_fd; - char *fname; - off_t offset; - struct smbc_server *srv; - BOOL file; - struct smbc_dir_list *dir_list, *dir_end, *dir_next; - int dir_type, dir_error; -}; - -static int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ -static BOOL smbc_getatr(struct smbc_server *srv, char *path, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - SMB_INO_T *ino); +/* + * check if an element is part of the list. + * FIXME: Does not belong here ! + * Can anyone put this in a macro in dlinklist.h ? + * -- Tom + */ +static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { + if (!p || !list) return False; + do { + if (p == list) return True; + list = list->next; + } while (list); + return False; +} extern BOOL in_client; extern pstring global_myname; + +/* + * Is the logging working / configfile read ? + */ static int smbc_initialized = 0; -static smbc_get_auth_data_fn smbc_auth_fn = NULL; -/*static int smbc_debug;*/ -static int smbc_start_fd; -static struct smbc_file **smbc_file_table; -static struct smbc_server *smbc_srvs; -static pstring my_netbios_name; -static pstring smbc_user; /* * Function to parse a path and turn it into components @@ -78,14 +65,14 @@ static pstring smbc_user; * We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]] * * smb:// means show all the workgroups - * smb://name/ means, if name<1D> exists, list servers in workgroup, + * smb://name/ means, if name<1D> or name<1B> exists, list servers in workgroup, * else, if name<20> exists, list all shares for server ... */ static const char *smbc_prefix = "smb:"; static int -smbc_parse_path(const char *fname, char *server, char *share, char *path, +smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, char *path, char *user, char *password) /* FIXME, lengths of strings */ { static pstring s; @@ -121,7 +108,8 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, if (*p == '/') { - strncpy(server, (char *)lp_workgroup(), 16); /* FIXME: Danger here */ + strncpy(server, context->workgroup, + (strlen(context->workgroup) < 16)?strlen(context->workgroup):16); return 0; } @@ -134,8 +122,8 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, */ /* check that '@' occurs before '/', if '/' exists at all */ - q = strchr_m(p, '@'); - r = strchr_m(p, '/'); + q = strchr(p, '@'); + r = strchr(p, '/'); if (q && (!r || q < r)) { pstring username, passwd, domain; char *u = userinfo; @@ -144,13 +132,13 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, username[0] = passwd[0] = domain[0] = 0; - if (strchr_m(u, ';')) { + if (strchr(u, ';')) { next_token(&u, domain, ";", sizeof(fstring)); - + } - if (strchr_m(u, ':')) { + if (strchr(u, ':')) { next_token(&u, username, ":", sizeof(fstring)); @@ -172,9 +160,9 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, } if (!next_token(&p, server, "/", sizeof(fstring))) { - + return -1; - + } if (*p == (char)0) return 0; /* That's it ... */ @@ -196,7 +184,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, * Convert an SMB error into a UNIX error ... */ -int smbc_errno(struct cli_state *c) +static int smbc_errno(SMBCCTX *context, struct cli_state *c) { int ret; @@ -216,12 +204,65 @@ int smbc_errno(struct cli_state *c) ret = cli_errno_from_nt(status); DEBUG(3,("smbc errno %s -> %d\n", - nt_errstr(status), ret)); + get_nt_error_msg(status), ret)); } return ret; } +/* + * Check a server_fd. + * returns 0 if the server is in shape. Returns 1 on error + * + * Also useable outside libsmbclient to enable external cache + * to do some checks too. + */ +int smbc_check_server(SMBCCTX * context, SMBCSRV * server) +{ + if ( cli_send_keepalive(&server->cli) == False ) + return 1; + + /* connection is ok */ + return 0; +} + +/* + * Remove a server from the list server_table if it's unused. + * On success, 0 is returned. 1 is returned if the server could not be removed. + * + * Also useable outside libsmbclient + */ +int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) +{ + SMBCFILE * file; + + /* are we being fooled ? */ + if (!context || !context->_initialized || !srv) return 1; + + + /* Check all open files/directories for a relation with this server */ + for (file = context->_files; file; file=file->next) { + if (file->srv == srv) { + /* Still used */ + DEBUG(3, ("smbc_remove_usused_server: %p still used by %p.\n", + srv, file)); + return 1; + } + } + + DLIST_REMOVE(context->_servers, srv); + + cli_shutdown(&srv->cli); + + DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); + + context->callbacks.remove_cached_srv_fn(context, srv); + + SAFE_FREE(srv); + + return 0; +} + /* * Connect to a server, possibly on an existing connection * @@ -233,67 +274,79 @@ int smbc_errno(struct cli_state *c) * info we need, unless the username and password were passed in. */ -struct smbc_server *smbc_server(char *server, char *share, - char *workgroup, char *username, - char *password) +SMBCSRV *smbc_server(SMBCCTX *context, + char *server, char *share, + char *workgroup, char *username, + char *password) { - struct smbc_server *srv=NULL; + SMBCSRV *srv=NULL; + int auth_called = 0; struct cli_state c; struct nmb_name called, calling; char *p, *server_n = server; fstring group; pstring ipenv; struct in_addr ip; + int tried_reverse = 0; - zero_ip(&ip); + zero_ip(&ip); ZERO_STRUCT(c); - /* try to use an existing connection */ - for (srv=smbc_srvs;srv;srv=srv->next) { - if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0 && - strcmp(workgroup,srv->workgroup)==0 && - strcmp(username, srv->username) == 0) - return srv; - } - if (server[0] == 0) { errno = EPERM; return NULL; } - /* - * Pick up the auth info here, once we know we need to connect - * But only if we do not have a username and password ... - */ - - if (!username[0] || !password[0]) - smbc_auth_fn(server, share, workgroup, sizeof(fstring), - username, sizeof(fstring), password, sizeof(fstring)); + check_server_cache: - /* - * However, smbc_auth_fn may have picked up info relating to an - * existing connection, so try for an existing connection again ... - */ - - for (srv=smbc_srvs;srv;srv=srv->next) { - if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0 && - strcmp(workgroup,srv->workgroup)==0 && - strcmp(username, srv->username) == 0) - return srv; + srv = context->callbacks.get_cached_srv_fn(context, server, share, + workgroup, username); + + if (!auth_called && !srv && (!username[0] || !password[0])) { + context->callbacks.auth_fn(server, share, workgroup, sizeof(fstring), + username, sizeof(fstring), password, sizeof(fstring)); + /* + * However, smbc_auth_fn may have picked up info relating to an + * existing connection, so try for an existing connection again ... + */ + auth_called = 1; + goto check_server_cache; + } + + if (srv) { + if (context->callbacks.check_server_fn(context, srv)) { + /* + * This server is no good anymore + * Try to remove it and check for more possible servers in the cache + */ + if (context->callbacks.remove_unused_server_fn(context, srv)) { + /* + * We could not remove the server completely, remove it from the cache + * so we will not get it again. It will be removed when the last file/dir + * is closed. + */ + context->callbacks.remove_cached_srv_fn(context, srv); + } + + /* + * Maybe there are more cached connections to this server + */ + goto check_server_cache; + } + return srv; + } - make_nmb_name(&calling, my_netbios_name, 0x0); + make_nmb_name(&calling, context->netbios_name, 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - if ((p=strchr_m(server_n,'#')) && + if ((p=strchr(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { fstrcpy(group, server_n); - p = strchr_m(group,'#'); + p = strchr(group,'#'); *p = 0; } @@ -303,21 +356,52 @@ struct smbc_server *smbc_server(char *server, char *share, again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); - zero_ip(&ip); + zero_ip(&ip); /* have to open a new connection */ - if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { - if (c.initialised) cli_shutdown(&c); + if (!cli_initialise(&c)) { errno = ENOENT; return NULL; } + c.timeout = context->timeout; + + if (!cli_connect(&c, server_n, &ip)) { + cli_shutdown(&c); + errno = ENOENT; + return NULL; + } + if (!cli_session_request(&c, &calling, &called)) { cli_shutdown(&c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } + else { /* Try one more time, but ensure we don't loop */ + + /* Only try this if server is an IP address ... */ + + if (is_ipaddress(server) && !tried_reverse) { + fstring remote_name; + struct in_addr rem_ip; + + if (!inet_aton(server, &rem_ip)) { + DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server)); + errno = ENOENT; + return NULL; + } + + tried_reverse++; /* Yuck */ + + if (name_status_find("*", 0, 0, rem_ip, remote_name)) { + make_nmb_name(&called, remote_name, 0x20); + goto again; + } + + + } + } errno = ENOENT; return NULL; } @@ -345,50 +429,37 @@ struct smbc_server *smbc_server(char *server, char *share, if (!cli_send_tconX(&c, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(&c); + errno = smbc_errno(context, &c); cli_shutdown(&c); return NULL; } DEBUG(4,(" tconx ok\n")); - srv = (struct smbc_server *)malloc(sizeof(*srv)); + /* + * Ok, we have got a nice connection + * Let's find a free server_fd + */ + + srv = (SMBCSRV *)malloc(sizeof(*srv)); if (!srv) { errno = ENOMEM; goto failed; } ZERO_STRUCTP(srv); - srv->cli = c; - srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); - srv->server_name = strdup(server); - if (!srv->server_name) { - errno = ENOMEM; - goto failed; - } - - srv->share_name = strdup(share); - if (!srv->share_name) { - errno = ENOMEM; - goto failed; - } - - srv->workgroup = strdup(workgroup); - if (!srv->workgroup) { - errno = ENOMEM; + /* now add it to the cache (internal or external) */ + if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { + DEBUG(3, (" Failed to add server to cache\n")); goto failed; } - srv->username = strdup(username); - if (!srv->username) { - errno = ENOMEM; - goto failed; - } - - DLIST_ADD(smbc_srvs, srv); + + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", + server, share, srv)); return srv; @@ -396,212 +467,49 @@ struct smbc_server *smbc_server(char *server, char *share, cli_shutdown(&c); if (!srv) return NULL; - SAFE_FREE(srv->server_name); - SAFE_FREE(srv->share_name); - SAFE_FREE(srv->workgroup); - SAFE_FREE(srv->username); SAFE_FREE(srv); return NULL; } -/* - *Remove a server from the list smbc_srvs if it's unused -- Tom (tom@ninja.nl) - * - * We accept a *srv - */ -BOOL smbc_remove_unused_server(struct smbc_server * s) -{ - int p; - - /* are we being fooled ? */ - if (!s) return False; - - /* close all open files/directories on this server */ - for (p = 0; p < SMBC_MAX_FD; p++) { - if (smbc_file_table[p] && - smbc_file_table[p]->srv == s) { - /* Still used .. DARN */ - DEBUG(3, ("smbc_remove_usused_server: %x still used by %s (%d).\n", (int) s, - smbc_file_table[p]->fname, smbc_file_table[p]->smbc_fd)); - return False; - } - } - - cli_shutdown(&s->cli); - - SAFE_FREE(s->username); - SAFE_FREE(s->workgroup); - SAFE_FREE(s->server_name); - SAFE_FREE(s->share_name); - DLIST_REMOVE(smbc_srvs, s); - DEBUG(3, ("smbc_remove_usused_server: %x removed.\n", (int) s)); - SAFE_FREE(s); - return True; -} - -/* - *Initialise the library etc - * - * We accept valid values for debug from 0 to 100, - * and insist that fn must be non-null. - */ - -int smbc_init(smbc_get_auth_data_fn fn, int debug) -{ - pstring conf; - int p, pid; - char *user = NULL, *home = NULL, *pname="libsmbclient"; - - if (!fn || debug < 0 || debug > 100) { - - errno = EINVAL; - return -1; - - } - - if (smbc_initialized) { /* Don't go through this if we have already done it */ - - return 0; - - } - - smbc_initialized = 1; - smbc_auth_fn = fn; - /* smbc_debug = debug; */ - - DEBUGLEVEL = -1; - - setup_logging(pname, False); - - /* Here we would open the smb.conf file if needed ... */ - - home = getenv("HOME"); - - slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - - load_interfaces(); /* Load the list of interfaces ... */ - - in_client = True; /* FIXME, make a param */ - - if (!lp_load(conf, True, False, False)) { - - /* - * Hmmm, what the hell do we do here ... we could not parse the - * config file ... We must return an error ... and keep info around - * about why we failed - */ - - errno = ENOENT; /* FIXME: Figure out the correct error response */ - return -1; - - } - - reopen_logs(); /* Get logging working ... */ - - /* - * FIXME: Is this the best way to get the user info? - */ - - user = getenv("USER"); - /* walk around as "guest" if no username can be found */ - if (!user) user = strdup("guest"); - pstrcpy(smbc_user, user); /* Save for use elsewhere */ - - /* - * We try to get our netbios name from the config. If that fails we fall - * back on constructing our netbios name from our hostname etc - */ - if (global_myname) { - pstrcpy(my_netbios_name, global_myname); - } - else { - /* - * Hmmm, I want to get hostname as well, but I am too lazy for the moment - */ - pid = sys_getpid(); - slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); - } - DEBUG(0,("Using netbios name %s.\n", my_netbios_name)); - - /* - * Now initialize the file descriptor array and figure out what the - * max open files is, so we can return FD's that are above the max - * open file, and separated by a guard band - */ - -#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) - do { - struct rlimit rlp; - - if (getrlimit(RLIMIT_NOFILE, &rlp)) { - - DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno))); - - smbc_start_fd = 1000000; - - } - else { - - smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */ - - } - } while ( 0 ); -#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */ - - smbc_start_fd = 1000000; - -#endif - - smbc_file_table = malloc(SMBC_MAX_FD * sizeof(struct smbc_file *)); - - for (p = 0; p < SMBC_MAX_FD; p++) - smbc_file_table[p] = NULL; - - if (!smbc_file_table) - return ENOMEM; - - return 0; /* Success */ - -} - /* * Routine to open() a file ... */ -int smbc_open(const char *fname, int flags, mode_t mode) +static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, mode_t mode) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *file = NULL; int fd; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; /* Best I can think of ... */ - return -1; + return NULL; } if (!fname) { errno = EINVAL; - return -1; + return NULL; } - smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { if (errno == EPERM) errno = EACCES; - return -1; /* smbc_server sets errno */ - + return NULL; /* smbc_server sets errno */ + } /* Hmmm, the test for a directory is suspect here ... FIXME */ @@ -612,50 +520,38 @@ int smbc_open(const char *fname, int flags, mode_t mode) } else { + + file = malloc(sizeof(SMBCFILE)); - int slot = 0; - - /* Find a free slot first */ - - while (smbc_file_table[slot]) - slot++; - - if (slot > SMBC_MAX_FD) { - - errno = ENOMEM; /* FIXME, is this best? */ - return -1; - - } - - smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); - - if (!smbc_file_table[slot]) { + if (!file) { errno = ENOMEM; - return -1; + return NULL; } + ZERO_STRUCTP(file); + if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) { /* Handle the error ... */ - SAFE_FREE(smbc_file_table[slot]); - errno = smbc_errno(&srv->cli); - return -1; + SAFE_FREE(file); + errno = smbc_errno(context, &srv->cli); + return NULL; } /* Fill in file struct */ - smbc_file_table[slot]->cli_fd = fd; - smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; - smbc_file_table[slot]->fname = strdup(fname); - smbc_file_table[slot]->srv = srv; - smbc_file_table[slot]->offset = 0; - smbc_file_table[slot]->file = True; + file->cli_fd = fd; + file->fname = strdup(fname); + file->srv = srv; + file->offset = 0; + file->file = True; - return smbc_file_table[slot]->smbc_fd; + DLIST_ADD(context->_files, file); + return file; } @@ -664,14 +560,15 @@ int smbc_open(const char *fname, int flags, mode_t mode) if (fd == -1) { int eno = 0; - eno = smbc_errno(&srv->cli); - fd = smbc_opendir(fname); - if (fd < 0) errno = eno; - return fd; + eno = smbc_errno(context, &srv->cli); + file = context->opendir(context, fname); + if (!file) errno = eno; + return file; } - return 1; /* Success, with fd ... */ + errno = EINVAL; /* FIXME, correct errno ? */ + return NULL; } @@ -681,38 +578,37 @@ int smbc_open(const char *fname, int flags, mode_t mode) static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ -int smbc_creat(const char *path, mode_t mode) +static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) { - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; - return -1; + return NULL; } - return smbc_open(path, creat_bits, mode); + return smbc_open_ctx(context, path, creat_bits, mode); } /* * Routine to read() a file ... */ -ssize_t smbc_read(int fd, void *buf, size_t count) +static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { - struct smbc_file *fe; int ret; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count)); + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; @@ -728,25 +624,16 @@ ssize_t smbc_read(int fd, void *buf, size_t count) } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe || !fe->file) { - - errno = EBADF; - return -1; - - } - - ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count); + ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count); if (ret < 0) { - errno = smbc_errno(&fe->srv->cli); + errno = smbc_errno(context, &file->srv->cli); return -1; } - fe->offset += ret; + file->offset += ret; DEBUG(4, (" --> %d\n", ret)); @@ -758,19 +645,18 @@ ssize_t smbc_read(int fd, void *buf, size_t count) * Routine to write() a file ... */ -ssize_t smbc_write(int fd, void *buf, size_t count) +static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { int ret; - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; @@ -786,25 +672,16 @@ ssize_t smbc_write(int fd, void *buf, size_t count) } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe || !fe->file) { - - errno = EBADF; - return -1; - - } - - ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count); + ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, file->offset, count); if (ret <= 0) { - errno = smbc_errno(&fe->srv->cli); + errno = smbc_errno(context, &file->srv->cli); return -1; } - fe->offset += ret; + file->offset += ret; return ret; /* Success, 0 bytes of data ... */ } @@ -813,75 +690,123 @@ ssize_t smbc_write(int fd, void *buf, size_t count) * Routine to close() a file ... */ -int smbc_close(int fd) +static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { - struct smbc_file *fe; - struct smbc_server *srv; + SMBCSRV *srv; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - fe = smbc_file_table[fd - smbc_start_fd]; + /* IS a dir ... */ + if (!file->file) { + + return context->closedir(context, file); + + } - if (!fe) { + if (!cli_close(&file->srv->cli, file->cli_fd)) { + + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); + /* Deallocate slot and remove the server + * from the server cache if unused */ + errno = smbc_errno(context, &file->srv->cli); + srv = file->srv; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + context->callbacks.remove_unused_server_fn(context, srv); - errno = EBADF; return -1; } - if (!fe->file) { + if (!file->file) { - return smbc_closedir(fd); + return context->closedir(context, file); } - if (!cli_close(&fe->srv->cli, fe->cli_fd)) { - - DEBUG(3, ("cli_close failed on %s (%d). purging server.\n", - fe->fname, fe->smbc_fd)); + if (!cli_close(&file->srv->cli, file->cli_fd)) { + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); /* Deallocate slot and remove the server * from the server cache if unused */ - errno = smbc_errno(&fe->srv->cli); - srv = fe->srv; - SAFE_FREE(fe->fname); - SAFE_FREE(fe); - smbc_file_table[fd - smbc_start_fd] = NULL; - smbc_remove_unused_server(srv); + errno = smbc_errno(context, &file->srv->cli); + srv = file->srv; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + context->callbacks.remove_unused_server_fn(context, srv); return -1; - } - SAFE_FREE(fe->fname); - SAFE_FREE(fe); - smbc_file_table[fd - smbc_start_fd] = NULL; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); return 0; } +/* + * Get info from an SMB server on a file. Use a qpathinfo call first + * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo + */ +static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + SMB_INO_T *ino) +{ + + if (!context || !context->_initialized) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4,("smbc_getatr: sending qpathinfo\n")); + + if (!srv->no_pathinfo2 && + cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, + size, mode, ino)) return True; + + /* if this is NT then don't bother with the getatr */ + if (srv->cli.capabilities & CAP_NT_SMBS) return False; + + if (cli_getatr(&srv->cli, path, mode, size, m_time)) { + a_time = c_time = m_time; + srv->no_pathinfo2 = True; + return True; + } + + return False; + +} + /* * Routine to unlink() a file */ -int smbc_unlink(const char *fname) +static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; - if (!smbc_initialized) { + if (!context || context->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -895,13 +820,13 @@ int smbc_unlink(const char *fname) } - smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -911,23 +836,23 @@ int smbc_unlink(const char *fname) /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - int job = smbc_stat_printjob(srv, path, NULL, NULL); - if (job == -1) { + int job = smbc_stat_printjob(srv, path, NULL, NULL); + if (job == -1) { - return -1; + return -1; - } - if ((err = cli_printjob_del(&srv->cli, job)) != 0) { + } + if ((err = cli_printjob_del(&srv->cli, job)) != 0) { - return -1; + return -1; - } - } else */ + } + } else */ if (!cli_unlink(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); if (errno == EACCES) { /* Check if the file is a directory */ @@ -937,12 +862,12 @@ int smbc_unlink(const char *fname) time_t m_time = 0, a_time = 0, c_time = 0; SMB_INO_T ino = 0; - if (!smbc_getatr(srv, path, &mode, &size, + if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { /* Hmmm, bad error ... What? */ - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; } @@ -968,35 +893,37 @@ int smbc_unlink(const char *fname) * Routine to rename() a file */ -int smbc_rename(const char *oname, const char *nname) +static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, + SMBCCTX *ncontext, const char *nname) { fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup; pstring path1, path2; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; - if (!smbc_initialized) { + if (!ocontext || !ncontext || + !ocontext->_initialized || !ncontext->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; } - + if (!oname || !nname) { errno = EINVAL; return -1; } - + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - smbc_parse_path(oname, server1, share1, path1, user1, password1); + smbc_parse_path(ocontext, oname, server1, share1, path1, user1, password1); - if (user1[0] == (char)0) pstrcpy(user1, smbc_user); + if (user1[0] == (char)0) pstrcpy(user1, ocontext->user); - smbc_parse_path(nname, server2, share2, path2, user2, password2); + smbc_parse_path(ncontext, nname, server2, share2, path2, user2, password2); - if (user2[0] == (char)0) pstrcpy(user2, smbc_user); + if (user2[0] == (char)0) pstrcpy(user2, ncontext->user); if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { @@ -1008,9 +935,9 @@ int smbc_rename(const char *oname, const char *nname) } - pstrcpy(workgroup, lp_workgroup()); - - srv = smbc_server(server1, share1, workgroup, user1, password1); + pstrcpy(workgroup, ocontext->workgroup); + /* HELP !!! Which workgroup should I use ? Or are they always the same -- Tom */ + srv = smbc_server(ocontext, server1, share1, workgroup, user1, password1); if (!srv) { return -1; @@ -1018,7 +945,7 @@ int smbc_rename(const char *oname, const char *nname) } if (!cli_rename(&srv->cli, path1, path2)) { - int eno = smbc_errno(&srv->cli); + int eno = smbc_errno(ocontext, &srv->cli); if (eno != EEXIST || !cli_unlink(&srv->cli, path2) || @@ -1038,35 +965,25 @@ int smbc_rename(const char *oname, const char *nname) * A routine to lseek() a file */ -off_t smbc_lseek(int fd, off_t offset, int whence) +static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence) { - struct smbc_file *fe; size_t size; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; - - } - - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - + } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - if (!fe->file) { + if (!file->file) { errno = EINVAL; return -1; /* Can't lseek a dir ... */ @@ -1075,23 +992,23 @@ off_t smbc_lseek(int fd, off_t offset, int whence) switch (whence) { case SEEK_SET: - fe->offset = offset; + file->offset = offset; break; case SEEK_CUR: - fe->offset += offset; + file->offset += offset; break; case SEEK_END: - if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, NULL, NULL, NULL) && - !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + !cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, NULL)) { errno = EINVAL; return -1; } - fe->offset = size + offset; + file->offset = size + offset; break; default: @@ -1100,7 +1017,7 @@ off_t smbc_lseek(int fd, off_t offset, int whence) } - return fe->offset; + return file->offset; } @@ -1109,9 +1026,16 @@ off_t smbc_lseek(int fd, off_t offset, int whence) */ static -ino_t smbc_inode(const char *name) +ino_t smbc_inode(SMBCCTX *context, const char *name) { + if (!context || !context->_initialized) { + + errno = EINVAL; + return -1; + + } + if (!*name) return 2; /* FIXME, why 2 ??? */ return (ino_t)str_checksum(name); @@ -1123,9 +1047,9 @@ ino_t smbc_inode(const char *name) */ static -int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) +int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, int mode) { - + st->st_mode = 0; if (IS_DOS_DIR(mode)) { @@ -1152,55 +1076,20 @@ int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) } if (st->st_ino == 0) { - st->st_ino = smbc_inode(fname); + st->st_ino = smbc_inode(context, fname); } - + return True; /* FIXME: Is this needed ? */ } -/* - * Get info from an SMB server on a file. Use a qpathinfo call first - * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo - */ - -static BOOL smbc_getatr(struct smbc_server *srv, char *path, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - SMB_INO_T *ino) -{ - - if (!smbc_initialized) { - - errno = EINVAL; - return -1; - - } - - DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - - if (!srv->no_pathinfo2 && - cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, - size, mode, ino)) return True; - - /* if this is NT then don't bother with the getatr */ - if (srv->cli.capabilities & CAP_NT_SMBS) return False; - - if (cli_getatr(&srv->cli, path, mode, size, m_time)) { - a_time = c_time = m_time; - srv->no_pathinfo2 = True; - return True; - } - return False; -} - /* * Routine to stat a file given a name */ -int smbc_stat(const char *fname, struct stat *st) +static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; time_t m_time = 0, a_time = 0, c_time = 0; @@ -1208,11 +1097,11 @@ int smbc_stat(const char *fname, struct stat *st) uint16 mode = 0; SMB_INO_T ino = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; - + } if (!fname) { @@ -1224,13 +1113,13 @@ int smbc_stat(const char *fname, struct stat *st) DEBUG(4, ("smbc_stat(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -1244,9 +1133,9 @@ int smbc_stat(const char *fname, struct stat *st) } else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - + if (strcmp(path, "\\") == 0) { - + mode = aDIR | aRONLY; } @@ -1259,19 +1148,17 @@ int smbc_stat(const char *fname, struct stat *st) } else { */ - if (!smbc_getatr(srv, path, &mode, &size, + if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; - + } - /* } */ - st->st_ino = ino; - smbc_setup_stat(st, path, size, mode); + smbc_setup_stat(context, st, path, size, mode); st->st_atime = a_time; st->st_ctime = c_time; @@ -1286,46 +1173,36 @@ int smbc_stat(const char *fname, struct stat *st) * Routine to stat a file given an fd */ -int smbc_fstat(int fd, struct stat *st) +static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) { - struct smbc_file *fe; time_t c_time, a_time, m_time; size_t size; uint16 mode; SMB_INO_T ino = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - if (!fe->file) { + if (!file->file) { - return smbc_fstatdir(fd, st); + return context->fstatdir(context, file, st); } - if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, + if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) && - !cli_getattrE(&fe->srv->cli, fe->cli_fd, + !cli_getattrE(&file->srv->cli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time)) { errno = EINVAL; @@ -1335,12 +1212,12 @@ int smbc_fstat(int fd, struct stat *st) st->st_ino = ino; - smbc_setup_stat(st, fe->fname, size, mode); + smbc_setup_stat(context, st, file->fname, size, mode); st->st_atime = a_time; st->st_ctime = c_time; st->st_mtime = m_time; - st->st_dev = fe->srv->dev; + st->st_dev = file->srv->dev; return 0; @@ -1360,7 +1237,7 @@ int smbc_fstat(int fd, struct stat *st) * smb:///share which should list files on share */ -static void smbc_remove_dir(struct smbc_file *dir) +static void smbc_remove_dir(SMBCFILE *dir) { struct smbc_dir_list *d,*f; @@ -1378,7 +1255,7 @@ static void smbc_remove_dir(struct smbc_file *dir) } -static int add_dirent(struct smbc_file *dir, const char *name, const char *comment, uint32 type) +static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint32 type) { struct smbc_dirent *dirent; int size; @@ -1401,6 +1278,11 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme } + ZERO_STRUCTP(dirent); + + ZERO_STRUCTP(dirent); + + if (dir->dir_list == NULL) { dir->dir_list = malloc(sizeof(struct smbc_dir_list)); @@ -1411,6 +1293,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme return -1; } + ZERO_STRUCTP(dir->dir_list); dir->dir_end = dir->dir_next = dir->dir_list; @@ -1418,14 +1301,15 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme else { dir->dir_end->next = malloc(sizeof(struct smbc_dir_list)); - - if (!dir->dir_end) { - + + if (!dir->dir_end->next) { + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; } + ZERO_STRUCTP(dir->dir_end->next); dir->dir_end = dir->dir_end->next; @@ -1433,7 +1317,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme dir->dir_end->next = NULL; dir->dir_end->dirent = dirent; - + dirent->smbc_type = type; dirent->namelen = (name?strlen(name):0); dirent->commentlen = (comment?strlen(comment):0); @@ -1451,13 +1335,13 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme static void list_fn(const char *name, uint32 type, const char *comment, void *state) { - struct smbc_file *dir = (struct smbc_file *)state; + SMBCFILE *dir = (SMBCFILE *)state; int dirent_type; /* We need to process the type a little ... */ if (dir->dir_type == SMBC_FILE_SHARE) { - + switch (type) { case 0: /* Directory tree */ dirent_type = SMBC_FILE_SHARE; @@ -1479,6 +1363,7 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ break; } + ZERO_STRUCTP(dir->dir_list); } else dirent_type = dir->dir_type; @@ -1496,113 +1381,103 @@ static void dir_list_fn(file_info *finfo, const char *mask, void *state) { - if (add_dirent((struct smbc_file *)state, finfo->name, "", + if (add_dirent((SMBCFILE *)state, finfo->name, "", (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { /* Handle an error ... */ + /* FIXME: Add some code ... */ } } -int smbc_opendir(const char *fname) +static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *dir = NULL; struct in_addr rem_ip; int slot = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; - return -1; + return NULL; } if (!fname) { errno = EINVAL; - return -1; + return NULL; } - if (smbc_parse_path(fname, server, share, path, user, password)) { + if (smbc_parse_path(context, fname, server, share, path, user, password)) { errno = EINVAL; - return -1; + return NULL; } - if (user[0] == (char)0) pstrcpy(user, smbc_user); - - pstrcpy(workgroup, lp_workgroup()); - - /* Get a file entry ... */ - - slot = 0; + if (user[0] == (char)0) pstrcpy(user, context->user); - while (smbc_file_table[slot]) - slot++; - - if (slot > SMBC_MAX_FD) { - - errno = ENOMEM; - return -1; /* FIXME, ... move into a func */ - - } + pstrcpy(workgroup, context->workgroup); - smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); + dir = malloc(sizeof(*dir)); - if (!smbc_file_table[slot]) { + if (!dir) { errno = ENOMEM; - return -1; + return NULL; } - smbc_file_table[slot]->cli_fd = 0; - smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; - smbc_file_table[slot]->fname = strdup(fname); - smbc_file_table[slot]->srv = NULL; - smbc_file_table[slot]->offset = 0; - smbc_file_table[slot]->file = False; - smbc_file_table[slot]->dir_list = - smbc_file_table[slot]->dir_next = - smbc_file_table[slot]->dir_end = NULL; + ZERO_STRUCTP(dir); + + dir->cli_fd = 0; + dir->fname = strdup(fname); + dir->srv = NULL; + dir->offset = 0; + dir->file = False; + dir->dir_list = dir->dir_next = dir->dir_end = NULL; if (server[0] == (char)0) { if (share[0] != (char)0 || path[0] != (char)0) { errno = EINVAL; - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } /* We have server and share and path empty ... so list the workgroups */ + /* first try to get the LMB for our workgroup, and if that fails, */ + /* try the DMB */ - if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) { + if (!(resolve_name(context->workgroup, &rem_ip, 0x1d) || + resolve_name(context->workgroup, &rem_ip, 0x1b))) { errno = EINVAL; /* Something wrong with smb.conf? */ - return -1; + return NULL; } - smbc_file_table[slot]->dir_type = SMBC_WORKGROUP; + dir->dir_type = SMBC_WORKGROUP; /* find the name of the server ... */ if (!name_status_find("*", 0, 0, rem_ip, server)) { - DEBUG(0, ("Could not get the name of local master browser for server %s\n", server)); + DEBUG(0,("Could not get the name of local/domain master browser for server %s\n", server)); errno = EINVAL; - return -1; + return NULL; } @@ -1610,31 +1485,34 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(server, "IPC$", workgroup, user, password); + srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + + return NULL; } + ZERO_STRUCTP(dir->dir_end); - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the stuff ... */ if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn, - (void *)smbc_file_table[slot])) { + (void *)dir)) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } errno = cli_errno(&srv->cli); - return -1; + + return NULL; } } @@ -1645,22 +1523,23 @@ int smbc_opendir(const char *fname) if (path[0] != (char)0) { /* Should not have empty share with path */ errno = EINVAL; - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - /* Check to see if <1D> translates, or <20> translates */ + /* Check to see if <1D>, <1B>, or <20> translates */ /* However, we check to see if is an IP address first */ if (!is_ipaddress(server) && /* Not an IP addr so check next */ - resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ + (resolve_name(server, &rem_ip, 0x1d) || /* Found LMB */ + resolve_name(server, &rem_ip, 0x1b) )) { /* Found DMB */ pstring buserver; - smbc_file_table[slot]->dir_type = SMBC_SERVER; + dir->dir_type = SMBC_SERVER; /* * Get the backup list ... @@ -1669,9 +1548,9 @@ int smbc_opendir(const char *fname) if (!name_status_find("*", 0, 0, rem_ip, buserver)) { - DEBUG(0, ("Could not get name of local master browser %s\n", server)); + DEBUG(0, ("Could not get name of local/domain master browser for server %s\n", server)); errno = EPERM; /* FIXME, is this correct */ - return -1; + return NULL; } @@ -1679,32 +1558,32 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(buserver, "IPC$", workgroup, user, password); + srv = smbc_server(context, buserver, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the servers ... */ if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn, - (void *)smbc_file_table[slot])) { + (void *)dir)) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } errno = cli_errno(&srv->cli); - return -1; - + return NULL; + } } @@ -1714,33 +1593,33 @@ int smbc_opendir(const char *fname) /* Now, list the shares ... */ - smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, "IPC$", workgroup, user, password); + srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the servers ... */ if (cli_RNetShareEnum(&srv->cli, list_fn, - (void *)smbc_file_table[slot]) < 0) { + (void *)dir) < 0) { errno = cli_errno(&srv->cli); - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } @@ -1748,11 +1627,11 @@ int smbc_opendir(const char *fname) else { errno = ENODEV; /* Neither the workgroup nor server exists */ - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } @@ -1763,42 +1642,43 @@ int smbc_opendir(const char *fname) /* Well, we connect to the server and list the directory */ - smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the files ... */ pstrcat(path, "\\*"); if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, - (void *)smbc_file_table[slot]) < 0) { + (void *)dir) < 0) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - errno = smbc_errno(&srv->cli); - return -1; + errno = smbc_errno(context, &srv->cli); + return NULL; } } } - return smbc_file_table[slot]->smbc_fd; + DLIST_ADD(context->_files, dir); + return dir; } @@ -1806,44 +1686,34 @@ int smbc_opendir(const char *fname) * Routine to close a directory */ -int smbc_closedir(int fd) +static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; - + } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + smbc_remove_dir(dir); /* Clean it up */ - errno = EBADF; - return -1; - - } - - smbc_remove_dir(fe); /* Clean it up */ + DLIST_REMOVE(context->_files, dir); - if (fe) { + if (dir) { - SAFE_FREE(fe->fname); - SAFE_FREE(fe); /* Free the space too */ + SAFE_FREE(dir->fname); + SAFE_FREE(dir); /* Free the space too */ } - smbc_file_table[fd - smbc_start_fd] = NULL; - return 0; } @@ -1852,50 +1722,38 @@ int smbc_closedir(int fd) * Routine to get a directory entry */ -static char smbc_local_dirent[512]; /* Make big enough */ - -struct smbc_dirent *smbc_readdir(unsigned int fd) +struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; struct smbc_dirent *dirp, *dirent; /* Check that all is ok first ... */ - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return NULL; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return NULL; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return NULL; } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return NULL; } - if (!fe->dir_next) + if (!dir->dir_next) return NULL; else { - dirent = fe->dir_next->dirent; + dirent = dir->dir_next->dirent; if (!dirent) { @@ -1906,15 +1764,12 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) /* Hmmm, do I even need to copy it? */ - memcpy(smbc_local_dirent, dirent, dirent->dirlen); /* Copy the dirent */ - - dirp = (struct smbc_dirent *)smbc_local_dirent; - + memcpy(context->_dirent, dirent, dirent->dirlen); /* Copy the dirent */ + dirp = (struct smbc_dirent *)context->_dirent; dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); - - fe->dir_next = fe->dir_next->next; + dir->dir_next = dir->dir_next->next; - return (struct smbc_dirent *)smbc_local_dirent; + return (struct smbc_dirent *)context->_dirent; } } @@ -1923,39 +1778,29 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) * Routine to get directory entries */ -int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) +static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent *dirp, int count) { - struct smbc_file *fe; - struct smbc_dir_list *dir; + struct smbc_dir_list *dirlist; int rem = count, reqd; char *ndir = (char *)dirp; /* Check that all is ok first ... */ - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; - + } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; @@ -1968,18 +1813,18 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) * send a request to the server to get the info. */ - while ((dir = fe->dir_next)) { + while ((dirlist = dir->dir_next)) { struct smbc_dirent *dirent; - if (!dir->dirent) { + if (!dirlist->dirent) { errno = ENOENT; /* Bad error */ return -1; } - if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen + - dir->dirent->commentlen + 1))) { + if (rem < (reqd = (sizeof(struct smbc_dirent) + dirlist->dirent->namelen + + dirlist->dirent->commentlen + 1))) { if (rem < count) { /* We managed to copy something */ @@ -1996,7 +1841,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) } - dirent = dir->dirent; + dirent = dirlist->dirent; memcpy(ndir, dirent, reqd); /* Copy the data in ... */ @@ -2007,7 +1852,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) rem -= reqd; - fe->dir_next = dir = dir -> next; + dir->dir_next = dirlist = dirlist -> next; } if (rem == count) @@ -2021,13 +1866,13 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) * Routine to create a directory ... */ -int smbc_mkdir(const char *fname, mode_t mode) +static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2043,13 +1888,13 @@ int smbc_mkdir(const char *fname, mode_t mode) DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2080,7 +1925,7 @@ int smbc_mkdir(const char *fname, mode_t mode) if (!cli_mkdir(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; } @@ -2107,13 +1952,13 @@ static void rmdir_list_fn(file_info *finfo, const char *mask, void *state) * Routine to remove a directory */ -int smbc_rmdir(const char *fname) +static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2129,13 +1974,13 @@ int smbc_rmdir(const char *fname) DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2160,13 +2005,13 @@ int smbc_rmdir(const char *fname) mode = aRONLY; smbc_stat_printjob(srv, path, &size, &m_time); c_time = a_time = m_time; - + } else { */ if (!cli_rmdir(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); if (errno == EACCES) { /* Check if the dir empty or not */ @@ -2183,7 +2028,7 @@ int smbc_rmdir(const char *fname) /* Fix errno to ignore latest error ... */ DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n", - smbc_errno(&srv->cli))); + smbc_errno(context, &srv->cli))); errno = EACCES; } @@ -2207,41 +2052,31 @@ int smbc_rmdir(const char *fname) * Routine to return the current directory position */ -off_t smbc_telldir(int fd) +static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; } - return (off_t) fe->dir_next; + return (off_t) dir->dir_next; } @@ -2279,36 +2114,19 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, * Routine to seek on a directory */ -int smbc_lseekdir(int fd, off_t offset) +static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) { - struct smbc_file *fe; struct smbc_dirent *dirent = (struct smbc_dirent *)offset; struct smbc_dir_list *list_ent = NULL; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { - - errno = EBADF; - return -1; - - } - - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; @@ -2319,7 +2137,7 @@ int smbc_lseekdir(int fd, off_t offset) if (dirent == NULL) { /* Seek to the begining of the list */ - fe->dir_next = fe->dir_list; + dir->dir_next = dir->dir_list; return 0; } @@ -2327,14 +2145,14 @@ int smbc_lseekdir(int fd, off_t offset) /* Now, run down the list and make sure that the entry is OK */ /* This may need to be changed if we change the format of the list */ - if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) { + if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) { errno = EINVAL; /* Bad entry */ return -1; } - fe->dir_next = list_ent; + dir->dir_next = list_ent; return 0; @@ -2344,10 +2162,10 @@ int smbc_lseekdir(int fd, off_t offset) * Routine to fstat a dir */ -static int smbc_fstatdir(int fd, struct stat *st) +static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) { - if (!smbc_initialized) { + if (context || !context->_initialized) { errno = EINVAL; return -1; @@ -2360,6 +2178,39 @@ static int smbc_fstatdir(int fd, struct stat *st) } +/* + * Open a print file to be written to by other calls + */ + +static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) +{ + fstring server, share, user, password; + pstring path; + + if (!context || context->_initialized) { + + errno = EINVAL; + return NULL; + + } + + if (!fname) { + + errno = EINVAL; + return NULL; + + } + + DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + /* What if the path is empty, or the file exists? */ + + return context->open(context, fname, O_WRONLY, 666); + +} + /* * Routine to print a file on a remote server ... * @@ -2367,12 +2218,14 @@ static int smbc_fstatdir(int fd, struct stat *st) * copy it to a print file on the share specified by printq. */ -int smbc_print_file(const char *fname, const char *printq) +static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq) { - int fid1, fid2, bytes, saverr, tot_bytes = 0; + SMBCFILE *fid1, *fid2; + int bytes, saverr, tot_bytes = 0; char buf[4096]; - if (!smbc_initialized) { + if (!c_file || !c_file->_initialized || !c_print || + !c_print->_initialized) { errno = EINVAL; return -1; @@ -2388,33 +2241,33 @@ int smbc_print_file(const char *fname, const char *printq) /* Try to open the file for reading ... */ - if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { - + if ((fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { + DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); return -1; /* smbc_open sets errno */ - + } /* Now, try to open the printer file for writing */ - if ((fid2 = smbc_open_print_job(printq)) < 0) { + if ((fid2 = c_print->open_print_job(c_print, printq)) < 0) { saverr = errno; /* Save errno */ - smbc_close(fid1); + c_file->close(c_file, fid1); errno = saverr; return -1; } - while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) { + while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) { tot_bytes += bytes; - if ((smbc_write(fid2, buf, bytes)) < 0) { + if ((c_print->write(c_print, fid2, buf, bytes)) < 0) { saverr = errno; - smbc_close(fid1); - smbc_close(fid2); + c_file->close(c_file, fid1); + c_print->close(c_print, fid2); errno = saverr; } @@ -2423,8 +2276,8 @@ int smbc_print_file(const char *fname, const char *printq) saverr = errno; - smbc_close(fid1); /* We have to close these anyway */ - smbc_close(fid2); + c_file->close(c_file, fid1); /* We have to close these anyway */ + c_print->close(c_print, fid2); if (bytes < 0) { @@ -2438,15 +2291,16 @@ int smbc_print_file(const char *fname, const char *printq) } /* - * Open a print file to be written to by other calls + * Routine to list print jobs on a printer share ... */ -int smbc_open_print_job(const char *fname) +static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, void (*fn)(struct print_job_info *)) { - fstring server, share, user, password; + SMBCSRV *srv; + fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2454,33 +2308,51 @@ int smbc_open_print_job(const char *fname) } if (!fname) { - + errno = EINVAL; return -1; } - DEBUG(4, ("smbc_open_print_job(%s)\n", fname)); + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - /* What if the path is empty, or the file exists? */ + if (user[0] == (char)0) pstrcpy(user, context->user); + + pstrcpy(workgroup, context->workgroup); + + srv = smbc_server(context, server, share, workgroup, user, password); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + if (cli_print_queue(&srv->cli, fn) < 0) { + + errno = smbc_errno(context, &srv->cli); + return -1; - return smbc_open(fname, O_WRONLY, 666); + } + + return 0; } /* - * Routine to list print jobs on a printer share ... + * Delete a print job from a remote printer share */ -int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) +static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; + int err; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2494,15 +2366,15 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } - DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2510,9 +2382,12 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } - if (cli_print_queue(&srv->cli, fn) < 0) { + if ((err = cli_printjob_del(&srv->cli, id)) != 0) { - errno = smbc_errno(&srv->cli); + if (err < 0) + errno = smbc_errno(context, &srv->cli); + else if (err == ERRnosuchprintjob) + errno = EINVAL; return -1; } @@ -2522,58 +2397,263 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } /* - * Delete a print job from a remote printer share + * Get a new empty handle to fill in with your own info */ +SMBCCTX * smbc_new_context(void) +{ + SMBCCTX * context; + + context = malloc(sizeof(*context)); + if (!context) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context); + + /* ADD REASONABLE DEFAULTS */ + context->debug = 0; + context->timeout = 20000; /* 20 seconds */ + + context->open = smbc_open_ctx; + context->creat = smbc_creat_ctx; + context->read = smbc_read_ctx; + context->write = smbc_write_ctx; + context->close = smbc_close_ctx; + context->unlink = smbc_unlink_ctx; + context->rename = smbc_rename_ctx; + context->lseek = smbc_lseek_ctx; + context->stat = smbc_stat_ctx; + context->fstat = smbc_fstat_ctx; + context->opendir = smbc_opendir_ctx; + context->closedir = smbc_closedir_ctx; + context->readdir = smbc_readdir_ctx; + context->getdents = smbc_getdents_ctx; + context->mkdir = smbc_mkdir_ctx; + context->rmdir = smbc_rmdir_ctx; + context->telldir = smbc_telldir_ctx; + context->lseekdir = smbc_lseekdir_ctx; + context->fstatdir = smbc_fstatdir_ctx; + context->open_print_job = smbc_open_print_job_ctx; + context->print_file = smbc_print_file_ctx; + context->list_print_jobs = smbc_list_print_jobs_ctx; + context->unlink_print_job = smbc_unlink_print_job_ctx; + + context->callbacks.check_server_fn = smbc_check_server; + context->callbacks.remove_unused_server_fn = smbc_remove_unused_server; + + smbc_default_cache_functions(context); + + return context; +} -int smbc_unlink_print_job(const char *fname, int id) +/* + * Free a context + * + * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed + * and thus you'll be leaking memory if not handled properly. + * + */ +int smbc_free_context(SMBCCTX * context, int shutdown_ctx) { - struct smbc_server *srv; - fstring server, share, user, password, workgroup; - pstring path; - int err; + if (!context) { + errno = EBADF; + return 1; + } + + if (shutdown_ctx) { + SMBCFILE * f; + DEBUG(1,("Performing aggressive shutdown.\n")); + + f = context->_files; + while (f) { + context->close(context, f); + f = f->next; + } + context->_files = NULL; + + /* First try to remove the servers the nice way. */ + if (context->callbacks.purge_cached_fn(context)) { + SMBCSRV * s; + DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); + s = context->_servers; + while (s) { + cli_shutdown(&s->cli); + context->callbacks.remove_cached_srv_fn(context, s); + SAFE_FREE(s); + s = s->next; + } + context->_servers = NULL; + } + } + else { + /* This is the polite way */ + if (context->callbacks.purge_cached_fn(context)) { + DEBUG(1, ("Could not purge all servers, free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->_servers) { + DEBUG(1, ("Active servers in context, free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->_files) { + DEBUG(1, ("Active files in context, free_context failed.\n")); + errno = EBUSY; + return 1; + } + } - if (!smbc_initialized) { + /* Things we have to clean up */ + SAFE_FREE(context->workgroup); + SAFE_FREE(context->netbios_name); + SAFE_FREE(context->user); + + DEBUG(3, ("Context %p succesfully freed\n", context)); + SAFE_FREE(context); + return 0; +} - errno = EINVAL; - return -1; +/* + * Initialise the library etc + * + * We accept a struct containing handle information. + * valid values for info->debug from 0 to 100, + * and insist that info->fn must be non-null. + */ +SMBCCTX * smbc_init_context(SMBCCTX * context) +{ + pstring conf; + int pid; + char *user = NULL, *home = NULL; + + if (!context) { + errno = EBADF; + return NULL; } - if (!fname) { + /* Do not initialise the same client twice */ + if (context->_initialized) { + return 0; + } + + if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) { errno = EINVAL; - return -1; + return NULL; } - - DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (!smbc_initialized) { + /* Do some library wide intialisations the first time we get called */ - pstrcpy(workgroup, lp_workgroup()); + /* Do we still need this ? */ + DEBUGLEVEL = 10; + + setup_logging( "libsmbclient", False); - srv = smbc_server(server, share, workgroup, user, password); + /* Here we would open the smb.conf file if needed ... */ + + home = getenv("HOME"); - if (!srv) { + slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); + + load_interfaces(); /* Load the list of interfaces ... */ + + in_client = True; /* FIXME, make a param */ - return -1; /* errno set by smbc_server */ + if (!lp_load(conf, True, False, False)) { - } + /* + * Hmmm, what the hell do we do here ... we could not parse the + * config file ... We must return an error ... and keep info around + * about why we failed + */ + + errno = ENOENT; /* FIXME: Figure out the correct error response */ + return NULL; + } - if ((err = cli_printjob_del(&srv->cli, id)) != 0) { + reopen_logs(); /* Get logging working ... */ + + /* + * Block SIGPIPE (from lib/util_sock.c: write()) + * It is not needed and should not stop execution + */ + BlockSignals(True, SIGPIPE); + + /* Done with one-time initialisation */ + smbc_initialized = 1; - if (err < 0) - errno = smbc_errno(&srv->cli); - else if (err == ERRnosuchprintjob) - errno = EINVAL; - return -1; + } + + if (!context->user) { + /* + * FIXME: Is this the best way to get the user info? + */ + user = getenv("USER"); + /* walk around as "guest" if no username can be found */ + if (!user) context->user = strdup("guest"); + else context->user = strdup(user); + } + if (!context->netbios_name) { + /* + * We try to get our netbios name from the config. If that fails we fall + * back on constructing our netbios name from our hostname etc + */ + if (global_myname) { + context->netbios_name = strdup(global_myname); + } + else { + /* + * Hmmm, I want to get hostname as well, but I am too lazy for the moment + */ + pid = sys_getpid(); + context->netbios_name = malloc(17); + if (!context->netbios_name) { + errno = ENOMEM; + return NULL; + } + slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); + } + } + DEBUG(0,("Using netbios name %s.\n", context->netbios_name)); + + if (!context->workgroup) { + if (lp_workgroup()) { + context->workgroup = strdup(lp_workgroup()); + } + else { + /* TODO: Think about a decent default workgroup */ + context->workgroup = strdup("samba"); + } + } + DEBUG(0,("Using workgroup %s.\n", context->workgroup)); + + + /* + * I think we can do this more than once for the same name without + * being shot but who am I? -- Tom + * Actually, we probably don't want to register a name, + * but one day the user might want to be able to do so. RJS + */ + if (0) { + name_register_wins(context->netbios_name, 0); } - return 0; + /* shortest timeout is 1 second */ + if (context->timeout > 0 && context->timeout < 1000) + context->timeout = 1000; -} + /* + * FIXME: Should we check the function pointers here? + */ + context->_initialized = 1; + + return context; +} -- cgit From 1e8952c6849d0d5d4984a61080ab49ac2f64e43d Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 13 Jul 2002 05:11:58 +0000 Subject: Fix some multibyte problems that I forgot about. (This used to be commit 481a70f4f005a778a24e2193f8e760217ee3c946) --- source3/libsmb/libsmbclient.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 77a81c10c8..4100005425 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -122,8 +122,8 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, */ /* check that '@' occurs before '/', if '/' exists at all */ - q = strchr(p, '@'); - r = strchr(p, '/'); + q = strchr_m(p, '@'); + r = strchr_m(p, '/'); if (q && (!r || q < r)) { pstring username, passwd, domain; char *u = userinfo; @@ -132,13 +132,13 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, username[0] = passwd[0] = domain[0] = 0; - if (strchr(u, ';')) { + if (strchr_m(u, ';')) { next_token(&u, domain, ";", sizeof(fstring)); } - if (strchr(u, ':')) { + if (strchr_m(u, ':')) { next_token(&u, username, ":", sizeof(fstring)); @@ -342,11 +342,11 @@ SMBCSRV *smbc_server(SMBCCTX *context, DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - if ((p=strchr(server_n,'#')) && + if ((p=strchr_m(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { fstrcpy(group, server_n); - p = strchr(group,'#'); + p = strchr_m(group,'#'); *p = 0; } -- cgit From 5c682b73371c22e3e9abb620d4cdab10f7a78646 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 13 Jul 2002 05:13:02 +0000 Subject: Add these two files I forgot. (This used to be commit 5706e6af168b14a40cb1e306c2911182260ff0d3) --- source3/libsmb/libsmb_cache.c | 191 +++++++++++++++++++++++++++ source3/libsmb/libsmb_compat.c | 285 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 476 insertions(+) create mode 100644 source3/libsmb/libsmb_cache.c create mode 100644 source3/libsmb/libsmb_compat.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c new file mode 100644 index 0000000000..34b818ee74 --- /dev/null +++ b/source3/libsmb/libsmb_cache.c @@ -0,0 +1,191 @@ +/* + Unix SMB/CIFS implementation. + SMB client library implementation (server cache) + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + * Define this to get the real SMBCFILE and SMBCSRV structures + */ +#define _SMBC_INTERNAL +#include "libsmbclient.h" + +/* + * Structure we use if internal caching mechanism is used + * nothing fancy here. + */ +struct smbc_server_cache { + char *server_name; + char *share_name; + char *workgroup; + char *username; + SMBCSRV *server; + + struct smbc_server_cache *next, *prev; +}; + + + +/* + * Add a new connection to the server cache. + * This function is only used if the external cache is not enabled + */ +static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, + char * server, char * share, + char * workgroup, char * username) +{ + struct smbc_server_cache * srvcache = NULL; + + if (!(srvcache = malloc(sizeof(*srvcache)))) { + errno = ENOMEM; + DEBUG(3, ("Not enough space for server cache allocation\n")); + return 1; + } + + ZERO_STRUCTP(srvcache); + + srvcache->server = new; + + srvcache->server_name = strdup(server); + if (!srvcache->server_name) { + errno = ENOMEM; + goto failed; + } + + srvcache->share_name = strdup(share); + if (!srvcache->share_name) { + errno = ENOMEM; + goto failed; + } + + srvcache->workgroup = strdup(workgroup); + if (!srvcache->workgroup) { + errno = ENOMEM; + goto failed; + } + + srvcache->username = strdup(username); + if (!srvcache->username) { + errno = ENOMEM; + goto failed; + } + + DLIST_ADD(((struct smbc_server_cache *)context->server_cache), srvcache); + return 0; + + failed: + SAFE_FREE(srvcache->server_name); + SAFE_FREE(srvcache->share_name); + SAFE_FREE(srvcache->workgroup); + SAFE_FREE(srvcache->username); + + return 1; +} + + + +/* + * Search the server cache for a server + * returns server_fd on success, -1 on error (not found) + * This function is only used if the external cache is not enabled + */ +static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, char * server, + char * share, char * workgroup, char * user) +{ + struct smbc_server_cache * srv = NULL; + + /* Search the cache lines */ + for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { + if (strcmp(server,srv->server_name) == 0 && + strcmp(share,srv->share_name) == 0 && + strcmp(workgroup,srv->workgroup) == 0 && + strcmp(user, srv->username) == 0) + return srv->server; + } + + return NULL; +} + + +/* + * Search the server cache for a server and remove it + * returns 0 on success + * This function is only used if the external cache is not enabled + */ +static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) +{ + struct smbc_server_cache * srv = NULL; + + for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { + if (server == srv->server) { + + /* remove this sucker */ + DLIST_REMOVE(((struct smbc_server_cache *)context->server_cache), srv); + SAFE_FREE(srv->server_name); + SAFE_FREE(srv->share_name); + SAFE_FREE(srv->workgroup); + SAFE_FREE(srv->username); + SAFE_FREE(srv); + return 0; + } + } + /* server not found */ + return 1; +} + + +/* + * Try to remove all the servers in cache + * returns 1 on failure and 0 if all servers could be removed. + */ +static int smbc_purge_cached(SMBCCTX * context) +{ + struct smbc_server_cache * srv = NULL; + int could_not_purge_all = 0; + + for (srv=((struct smbc_server_cache *) context->server_cache);srv;srv=srv->next) { + if (smbc_remove_unused_server(context, srv->server)) { + /* could not be removed */ + could_not_purge_all = 1; + } + } + return could_not_purge_all; +} + + + +/* + * This functions initializes all server-cache related functions + * to the default (internal) system. + * + * We use this to make the rest of the cache system static. + */ + +int smbc_default_cache_functions(SMBCCTX * context) +{ + context->callbacks.add_cached_srv_fn = smbc_add_cached_server; + context->callbacks.get_cached_srv_fn = smbc_get_cached_server; + context->callbacks.remove_cached_srv_fn = smbc_remove_cached_server; + context->callbacks.purge_cached_fn = smbc_purge_cached; + + return 0; +} diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c new file mode 100644 index 0000000000..dbfd860358 --- /dev/null +++ b/source3/libsmb/libsmb_compat.c @@ -0,0 +1,285 @@ +/* + Unix SMB/CIFS implementation. + SMB client library implementation (Old interface compatibility) + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" + +/* + * Define this to get the real SMBCFILE and SMBCSRV structures + */ +#define _SMBC_INTERNAL +#include "libsmbclient.h" + +struct smbc_compat_fdlist { + SMBCFILE * file; + int fd; + struct smbc_compat_fdlist *next, *prev; +}; + +static SMBCCTX * statcont = NULL; +static int smbc_compat_initialized = 0; +static int smbc_currentfd = 10000; +static struct smbc_compat_fdlist * smbc_compat_fdlist = NULL; + + +/* Find an fd and return the SMBCFILE * or NULL on failure */ +static SMBCFILE * find_fd(int fd) +{ + struct smbc_compat_fdlist * f = smbc_compat_fdlist; + while (f) { + if (f->fd == fd) + return f->file; + f = f->next; + } + return NULL; +} + +/* Add an fd, returns 0 on success, -1 on error with errno set */ +static int add_fd(SMBCFILE * file) +{ + struct smbc_compat_fdlist * f = malloc(sizeof(struct smbc_compat_fdlist)); + if (!f) { + errno = ENOMEM; + return -1; + } + + f->fd = smbc_currentfd++; + f->file = file; + + DLIST_ADD(smbc_compat_fdlist, f); + + return f->fd; +} + + + +/* Delete an fd, returns 0 on success */ +static int del_fd(int fd) +{ + struct smbc_compat_fdlist * f = smbc_compat_fdlist; + while (f) { + if (f->fd == fd) + break; + f = f->next; + } + if (f) { + /* found */ + DLIST_REMOVE(smbc_compat_fdlist, f); + SAFE_FREE(f); + return 0; + } + return 1; +} + + + +int smbc_init(smbc_get_auth_data_fn fn, int debug) +{ + if (!smbc_compat_initialized) { + statcont = smbc_new_context(); + if (!statcont) + return -1; + + statcont->debug = debug; + statcont->callbacks.auth_fn = fn; + + if (!smbc_init_context(statcont)) { + smbc_free_context(statcont, False); + return -1; + } + + smbc_compat_initialized = 1; + + return 0; + } + return 0; +} + + +int smbc_open(const char *furl, int flags, mode_t mode) +{ + SMBCFILE * file; + int fd; + + file = statcont->open(statcont, furl, flags, mode); + if (!file) + return -1; + + fd = add_fd(file); + if (fd == -1) + statcont->close(statcont, file); + return fd; +} + + +int smbc_creat(const char *furl, mode_t mode) +{ + SMBCFILE * file; + int fd; + + file = statcont->creat(statcont, furl, mode); + if (!file) + return -1; + + fd = add_fd(file); + if (fd == -1) { + /* Hmm... should we delete the file too ? I guess we could try */ + statcont->close(statcont, file); + statcont->unlink(statcont, furl); + } + return fd; +} + + +ssize_t smbc_read(int fd, void *buf, size_t bufsize) +{ + SMBCFILE * file = find_fd(fd); + return statcont->read(statcont, file, buf, bufsize); +} + +ssize_t smbc_write(int fd, void *buf, size_t bufsize) +{ + SMBCFILE * file = find_fd(fd); + return statcont->write(statcont, file, buf, bufsize); +} + +off_t smbc_lseek(int fd, off_t offset, int whence) +{ + SMBCFILE * file = find_fd(fd); + return statcont->lseek(statcont, file, offset, whence); +} + +int smbc_close(int fd) +{ + SMBCFILE * file = find_fd(fd); + del_fd(fd); + return statcont->close(statcont, file); +} + +int smbc_unlink(const char *fname) +{ + return statcont->unlink(statcont, fname); +} + +int smbc_rename(const char *ourl, const char *nurl) +{ + return statcont->rename(statcont, ourl, statcont, nurl); +} + +int smbc_opendir(const char *durl) +{ + SMBCFILE * file; + int fd; + + file = statcont->opendir(statcont, durl); + if (!file) + return -1; + + fd = add_fd(file); + if (fd == -1) + statcont->closedir(statcont, file); + + return fd; +} + +int smbc_closedir(int dh) +{ + SMBCFILE * file = find_fd(dh); + del_fd(dh); + return statcont->closedir(statcont, file); +} + +int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count) +{ + SMBCFILE * file = find_fd(dh); + return statcont->getdents(statcont, file,dirp, count); +} + +struct smbc_dirent* smbc_readdir(unsigned int dh) +{ + SMBCFILE * file = find_fd(dh); + return statcont->readdir(statcont, file); +} + +off_t smbc_telldir(int dh) +{ + SMBCFILE * file = find_fd(dh); + return statcont->telldir(statcont, file); +} + +int smbc_lseekdir(int fd, off_t offset) +{ + SMBCFILE * file = find_fd(fd); + return statcont->lseekdir(statcont, file, offset); +} + +int smbc_mkdir(const char *durl, mode_t mode) +{ + return statcont->mkdir(statcont, durl, mode); +} + +int smbc_rmdir(const char *durl) +{ + return statcont->rmdir(statcont, durl); +} + +int smbc_stat(const char *url, struct stat *st) +{ + return statcont->stat(statcont, url, st); +} + +int smbc_fstat(int fd, struct stat *st) +{ + SMBCFILE * file = find_fd(fd); + return statcont->fstat(statcont, file, st); +} + +int smbc_chmod(const char *url, mode_t mode) +{ + /* NOT IMPLEMENTED IN LIBSMBCLIENT YET */ + return -1; +} + +int smbc_print_file(const char *fname, const char *printq) +{ + return statcont->print_file(statcont, fname, statcont, printq); +} + +int smbc_open_print_job(const char *fname) +{ + SMBCFILE * file = statcont->open_print_job(statcont, fname); + if (!file) return -1; + return (int) file; +} + +int smbc_list_print_jobs(const char *purl, smbc_get_print_job_info fn) +{ + return statcont->list_print_jobs(statcont, purl, fn); +} + +int smbc_unlink_print_job(const char *purl, int id) +{ + return statcont->unlink_print_job(statcont, purl, id); +} + + -- cgit From 92c597a9b07ebffafd96ba11f0b25f8b97ffb124 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 13 Jul 2002 05:43:34 +0000 Subject: Fix up the include file that had problems as well. (This used to be commit 753df0b89767261420f242da21d5dfb5403c966b) --- source3/libsmb/libsmbclient.c | 11 ----------- 1 file changed, 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 4100005425..05b6b3121f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2633,18 +2633,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) } } DEBUG(0,("Using workgroup %s.\n", context->workgroup)); - - /* - * I think we can do this more than once for the same name without - * being shot but who am I? -- Tom - * Actually, we probably don't want to register a name, - * but one day the user might want to be able to do so. RJS - */ - if (0) { - name_register_wins(context->netbios_name, 0); - } - /* shortest timeout is 1 second */ if (context->timeout > 0 && context->timeout < 1000) context->timeout = 1000; -- cgit From 3faee01c7c49c92eb6859bea19479e88b446e54e Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 13 Jul 2002 07:18:43 +0000 Subject: Some fix ups but committing so Andrew can look at the problem I have. (This used to be commit 146ba3eb49bade732d57691d8ce181ef6608e0cb) --- source3/libsmb/libsmbclient.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 05b6b3121f..0ffc1c1378 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1,6 +1,5 @@ /* Unix SMB/Netbios implementation. - Version 2.0 SMB client library implementation Copyright (C) Andrew Tridgell 1998 Copyright (C) Richard Sharpe 2000, 2002 @@ -24,17 +23,12 @@ #include "includes.h" -/* - * Define this to get the real SMBCFILE and SMBCSRV structures - */ -#define _SMBC_INTERNAL - #include "libsmbclient.h" /* * Functions exported by libsmb_cache.c that we need here */ -int smbc_default_cache_functions(SMBCCTX * context); +int smbc_default_cache_functions(SMBCCTX *context); /* * check if an element is part of the list. -- cgit From f5b6ef1b65bdf99ac31d23c80ead330da2cd1411 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 13 Jul 2002 08:37:06 +0000 Subject: fix directory listing on win9x. it turns out this is tricky to get right for both win9x and w2k with and without unicode. This patch seems to do the trick. (This used to be commit 01ebe5fff2b3cb29f083afb224b1257364ac5d80) --- source3/libsmb/clilist.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 8b28e05a47..17a759f9e3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -54,10 +54,14 @@ static int interpret_long_filename(struct cli_state *cli, len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); + /* the len+2 below looks strange but it is + important to cope with the differences + between win2000 and win9x for this call + (tridge) */ p += clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - len, - STR_TERMINATE); + sizeof(finfo->name), + len+2, + STR_TERMINATE); return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/libsmb/cli_dfs.c | 8 - source3/libsmb/cli_lsarpc.c | 52 +- source3/libsmb/cli_netlogon.c | 21 +- source3/libsmb/cli_reg.c | 9 - source3/libsmb/cli_samr.c | 132 ++-- source3/libsmb/cli_spoolss.c | 645 ++++++++++++++-- source3/libsmb/cli_srvsvc.c | 381 +++++++++- source3/libsmb/cli_wkssvc.c | 18 - source3/libsmb/cliconnect.c | 528 ++++++------- source3/libsmb/clientgen.c | 61 +- source3/libsmb/clifile.c | 2 +- source3/libsmb/clilist.c | 10 +- source3/libsmb/clirap.c | 14 +- source3/libsmb/clirap2.c | 10 +- source3/libsmb/clireadwrite.c | 64 +- source3/libsmb/clispnego.c | 43 +- source3/libsmb/errormap.c | 1 + source3/libsmb/libsmbclient.c | 1691 +++++++++++++++++++++-------------------- source3/libsmb/namequery.c | 662 +++++++--------- source3/libsmb/nmblib.c | 4 +- source3/libsmb/nterr.c | 1 + source3/libsmb/pwd_cache.c | 137 +--- source3/libsmb/smbencrypt.c | 131 ++-- source3/libsmb/trust_passwd.c | 10 +- source3/libsmb/unexpected.c | 2 +- 25 files changed, 2699 insertions(+), 1938 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c index 312275926c..7fc27b9c3b 100644 --- a/source3/libsmb/cli_dfs.c +++ b/source3/libsmb/cli_dfs.c @@ -20,14 +20,6 @@ #include "includes.h" -/* Opens a SMB connection to the netdfs pipe */ - -struct cli_state *cli_dfs_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_NETDFS, creds); -} - /* Query DFS support */ NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 23cedf1f08..7dfee46fae 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -5,7 +5,8 @@ Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000. + Copyright (C) Elrond 2000, + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -37,19 +38,6 @@ * security authority", which is half of a password database. **/ -/** Opens a SMB connection and connects to the LSARPC pipe. - * - * @param cli Uninitialised client handle. - * @param system_name NETBIOS name of the machine to connect to. - * @param creds User credentials to connect as. - * @returns Initialised client handle. - */ -struct cli_state *cli_lsa_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_LSARPC, creds); -} - /** Open a LSA policy handle * * @param cli Handle on an initialised SMB connection */ @@ -275,7 +263,7 @@ NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - + /* An actual error occured */ goto done; @@ -389,8 +377,8 @@ NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { + if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != + NT_STATUS_V(STATUS_SOME_UNMAPPED)) { /* An actual error occured */ @@ -537,12 +525,25 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/** Enumerate list of trusted domains */ +/** + * Enumerate list of trusted domains + * + * @param cli client state (cli_state) structure of the connection + * @param mem_ctx memory context + * @param pol opened lsa policy handle + * @param enum_ctx enumeration context ie. index of first returned domain entry + * @param pref_num_domains preferred max number of entries returned in one response + * @param num_domains total number of trusted domains returned by response + * @param domain_names returned trusted domain names + * @param domain_sids returned trusted domain sids + * + * @return nt status code of response + **/ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 *enum_ctx, - uint32 *num_domains, char ***domain_names, - DOM_SID **domain_sids) + uint32 *pref_num_domains, uint32 *num_domains, + char ***domain_names, DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; @@ -560,7 +561,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Marshall data and send request */ - init_q_enum_trust_dom(&q, pol, *enum_ctx, 0xffffffff); + init_q_enum_trust_dom(&q, pol, *enum_ctx, *pref_num_domains); if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) || !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) { @@ -577,16 +578,15 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(NT_STATUS_NO_MORE_ENTRIES)) { + if (!NT_STATUS_IS_OK(result) && + !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && + !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { /* An actual error ocured */ goto done; } - result = NT_STATUS_OK; - /* Return output parameters */ if (r.num_domains) { @@ -1122,7 +1122,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); goto done; } - if (!(cli.sec_mode & 1)) { + if (!(cli.sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { DEBUG(0,("fetch_domain_sid: machine %s isn't in user level security mode\n", remote_machine)); goto done; diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index 125590b6d3..d32e0e77e4 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -25,15 +25,6 @@ #include "includes.h" -/* Opens a SMB connection to the netlogon pipe */ - -struct cli_state *cli_netlogon_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_NETLOGON, creds); -} - /* LSA Request Challenge. Sends our challenge to server, then gets server response. These are used to generate the credentials. */ @@ -51,8 +42,8 @@ NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, /* create and send a MSRPC command with api NET_REQCHAL */ - DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", - cli->desthost, global_myname, credstr(clnt_chal->data))); + DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", + global_myname, cli->desthost, credstr(clnt_chal->data))); /* store the parameters */ init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal); @@ -108,7 +99,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* create and send a MSRPC command with api NET_AUTH2 */ - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", + DEBUG(4,("new_cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, credstr(cli->clnt_cred.challenge.data), neg_flags)); @@ -147,7 +138,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* * Server replied with bad credential. Fail. */ - DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ + DEBUG(0,("new_cli_net_auth2: server %s replied with bad credential (bad machine \ password ?).\n", cli->desthost )); result = NT_STATUS_ACCESS_DENIED; goto done; @@ -180,7 +171,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); + DEBUG(0,("new_cli_nt_setup_creds: request challenge failed\n")); return result; } @@ -206,7 +197,7 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, result = new_cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed %s\n", + DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", nt_errstr(result))); } diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c index c09ccabb29..aaf18882f7 100644 --- a/source3/libsmb/cli_reg.c +++ b/source3/libsmb/cli_reg.c @@ -25,15 +25,6 @@ #include "includes.h" -/* Opens a SMB connection to the WINREG pipe */ - -struct cli_state *cli_winreg_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_WINREG, creds); -} - /* Shutdown a server */ NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 85a7375f99..91577b3325 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -24,14 +24,6 @@ #include "includes.h" -/* Opens a SMB connection to the SAMR pipe */ - -struct cli_state *cli_samr_initialise(struct cli_state *cli, char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SAMR, creds); -} - /* Connect to SAMR database */ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, @@ -55,15 +47,13 @@ NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_connect(&q, cli->desthost, access_mask); if (!samr_io_q_connect("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_connect("", &r, &rbuf, 0)) { + if (!samr_io_r_connect("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -104,15 +94,13 @@ NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_close_hnd(&q, connect_pol); if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) { + if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -154,15 +142,13 @@ NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid); if (!samr_io_q_open_domain("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_domain("", &r, &rbuf, 0)) { + if (!samr_io_r_open_domain("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -204,15 +190,13 @@ NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_user(&q, domain_pol, access_mask, user_rid); if (!samr_io_q_open_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_user("", &r, &rbuf, 0)) { + if (!samr_io_r_open_user("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -254,15 +238,13 @@ NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_open_group(&q, domain_pol, access_mask, group_rid); if (!samr_io_q_open_group("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_open_group("", &r, &rbuf, 0)) { + if (!samr_io_r_open_group("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -304,15 +286,13 @@ NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_userinfo(&q, user_pol, switch_value); if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) { + if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -350,17 +330,15 @@ NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_groupinfo(&q, group_pol, info_level); if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ r.ctr = ctr; - if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) { + if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -397,15 +375,13 @@ NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_usergroups(&q, user_pol); if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) { + if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -431,7 +407,7 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, SAMR_Q_QUERY_USERALIASES q; SAMR_R_QUERY_USERALIASES r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint ptr=1; + unsigned int ptr=1; ZERO_STRUCT(q); ZERO_STRUCT(r); @@ -446,15 +422,13 @@ NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid); if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) { + if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -494,15 +468,13 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_query_groupmem(&q, group_pol); if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) { + if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ @@ -545,24 +517,21 @@ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, init_samr_q_enum_dom_groups(&q, pol, *start_idx, size); if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) { + !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) goto done; - } /* Unmarshall response */ - if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) { + if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) goto done; - } /* Return output parameters */ result = r.status; if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { + NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) goto done; - } *num_dom_groups = r.num_entries2; @@ -971,7 +940,7 @@ NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *domain_pol, uint32 flags, - uint32 num_names, char **names, + uint32 num_names, const char **names, uint32 *num_rids, uint32 **rids, uint32 **rid_types) { @@ -1272,3 +1241,54 @@ NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + +/* Get domain password info */ + +NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint16 *unk_0, uint16 *unk_1, uint16 *unk_2) +{ + prs_struct qbuf, rbuf; + SAMR_Q_GET_DOM_PWINFO q; + SAMR_R_GET_DOM_PWINFO r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Marshall data and send request */ + + init_samr_q_get_dom_pwinfo(&q, cli->desthost); + + if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (NT_STATUS_IS_OK(result)) { + if (unk_0) + *unk_0 = r.unk_0; + if (unk_1) + *unk_1 = r.unk_1; + if (unk_2) + *unk_2 = r.unk_2; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c index 0458b29d54..18e17758d6 100644 --- a/source3/libsmb/cli_spoolss.c +++ b/source3/libsmb/cli_spoolss.c @@ -31,20 +31,6 @@ * @{ **/ -/** Opens a SMB connection and connects to the SPOOLSS pipe. - * - * @param cli Uninitialised client handle. - * @param system_name NETBIOS name of the machine to connect to. - * @param creds User credentials to connect as. - * @returns Initialised client handle. - */ -struct cli_state *cli_spoolss_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SPOOLSS, creds); -} - /********************************************************************** Initialize a new spoolss buff for use by a client rpc **********************************************************************/ @@ -420,8 +406,8 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCT(q); ZERO_STRUCT(r); - fstrcpy (server, cli->desthost); - strupper (server); + slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); + strupper (server); /* Initialise input parameters */ @@ -620,7 +606,7 @@ WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, result = r.status; - if (NT_STATUS_IS_OK(result)) { + if (W_ERROR_IS_OK(result)) { switch (level) { case 0: decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); @@ -1492,48 +1478,6 @@ WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } -/********************************************************************************* - Win32 API - SetPrinterData() - ********************************************************************************/ - -WERROR cli_spoolss_setprinterdata (struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, char* valname, char* value) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTERDATA q; - SPOOL_R_SETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - - /* write the request */ - make_spoolss_q_setprinterdata(&q, mem_ctx, pol, valname, value); - - /* Marshall data and send request */ - if (!spoolss_io_q_setprinterdata ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - if (spoolss_io_r_setprinterdata ("", &r, &rbuf, 0)) - goto done; - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, uint32 num_jobs, JOB_INFO_1 **jobs) { @@ -1612,11 +1556,123 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: decode_jobs_1(mem_ctx, r.buffer, r.returned, - &ctr->job.job_info_1); + ctr->job.job_info_1); break; case 2: decode_jobs_2(mem_ctx, r.buffer, r.returned, - &ctr->job.job_info_2); + ctr->job.job_info_2); + break; + default: + DEBUG(3, ("unsupported info level %d", level)); + break; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Set job */ + +WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 jobid, uint32 level, + uint32 command) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETJOB q; + SPOOL_R_SETJOB r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setjob(&q, hnd, jobid, level, command); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setjob("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setjob("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Get job */ + +WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, uint32 jobid, uint32 level, + JOB_INFO_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETJOB q; + SPOOL_R_GETJOB r; + WERROR result = W_ERROR(ERRgeneral); + NEW_BUFFER buffer; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + init_buffer(&buffer, offered, mem_ctx); + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getjob("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getjob("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (needed) + *needed = r.needed; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + switch(level) { + case 1: + decode_jobs_1(mem_ctx, r.buffer, 1, ctr->job.job_info_1); + break; + case 2: + decode_jobs_2(mem_ctx, r.buffer, 1, ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); @@ -1630,4 +1686,471 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/* Startpageprinter. Sent to notify the spooler when a page is about to be + sent to a printer. */ + +WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_STARTPAGEPRINTER q; + SPOOL_R_STARTPAGEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_startpageprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Endpageprinter. Sent to notify the spooler when a page has finished + being sent to a printer. */ + +WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENDPAGEPRINTER q; + SPOOL_R_ENDPAGEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_endpageprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Startdocprinter. Sent to notify the spooler that a document is about + to be spooled for printing. */ + +WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *docname, + char *outputfile, char *datatype, + uint32 *jobid) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_STARTDOCPRINTER q; + SPOOL_R_STARTDOCPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + uint32 level = 1; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile, + datatype); + + /* Marshall data and send request */ + + if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + if (W_ERROR_IS_OK(result)) + *jobid = r.jobid; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Enddocprinter. Sent to notify the spooler that a document has finished + being spooled. */ + +WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENDDOCPRINTER q; + SPOOL_R_ENDDOCPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enddocprinter(&q, hnd); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0)) + goto done; + + /* Return output parameters */ + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Get printer data */ + +WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, char *valuename, + uint32 *data_type, char **data, + uint32 *data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTERDATA q; + SPOOL_R_GETPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getprinterdata(&q, hnd, valuename, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (needed) + *needed = r.needed; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return output parameters */ + + if (data_type) + *data_type = r.type; + + if (data) { + *data = (char *)talloc(mem_ctx, r.needed); + memcpy(*data, r.data, r.needed); + } + + if (data_size) + *data_size = r.needed; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Set printer data */ + +WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *value, + uint32 data_type, char *data, + uint32 data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETPRINTERDATA q; + SPOOL_R_SETPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Enum printer data */ + +WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 ndx, + uint32 value_offered, uint32 data_offered, + uint32 *value_needed, uint32 *data_needed, + char **value, uint32 *data_type, char **data, + uint32 *data_size) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMPRINTERDATA q; + SPOOL_R_ENUMPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return data */ + + if (value_needed) + *value_needed = r.realvaluesize; + + if (data_needed) + *data_needed = r.realdatasize; + + if (data_type) + *data_type = r.type; + + if (value) { + fstring the_value; + + rpcstr_pull(the_value, r.value, sizeof(the_value), -1, + STR_TERMINATE); + + *value = talloc_strdup(mem_ctx, the_value); + } + + if (data) + *data = talloc_memdup(mem_ctx, r.data, r.realdatasize); + + if (data_size) + *data_size = r.realdatasize; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Write data to printer */ + +WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, uint32 data_size, char *data, + uint32 *num_written) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_WRITEPRINTER q; + SPOOL_R_WRITEPRINTER r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_writeprinter(&q, hnd, data_size, data); + + /* Marshall data and send request */ + + if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + if (num_written) + *num_written = r.buffer_written; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Delete printer data */ + +WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *valuename) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_DELETEPRINTERDATA q; + SPOOL_R_DELETEPRINTERDATA r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_deleteprinterdata(&q, hnd, valuename); + + /* Marshall data and send request */ + + if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 9d33149540..2dc12d726c 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -4,6 +4,7 @@ Copyright (C) Andrew Tridgell 1994-2000 Copyright (C) Luke Kenneth Casson Leighton 1996-2000 Copyright (C) Tim Potter 2001 + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,15 +23,6 @@ #include "includes.h" -/* Opens a SMB connection to the svrsvc pipe */ - -struct cli_state *cli_svrsvc_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_SRVSVC, creds); -} - NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 switch_value, SRV_INFO_CTR *ctr) @@ -77,3 +69,374 @@ NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, return result; } + +WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 info_level, SRV_SHARE_INFO_CTR *ctr, + int preferred_len, ENUM_HND *hnd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_ENUM q; + SRV_R_NET_SHARE_ENUM r; + WERROR result = W_ERROR(ERRgeneral); + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_share_enum( + &q, cli->srv_name_slash, info_level, preferred_len, hnd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_enum("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + /* Oh yuck yuck yuck - we have to copy all the info out of the + SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a + prs_mem_free() it will all be invalidated. The various share + info structures suck badly too. This really is gross. */ + + ZERO_STRUCTP(ctr); + + ctr->info_level = info_level; + ctr->num_entries = r.ctr.num_entries; + + switch(info_level) { + case 1: + ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc( + mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries); + + memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1)); + + for (i = 0; i < ctr->num_entries; i++) { + SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, + sizeof(SH_INFO_1)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname); + if (s) + init_unistr2(&info1->info_1_str.uni_netname, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark); + if (s) + init_unistr2(&info1->info_1_str.uni_remark, s, strlen(s) + 1); + + } + + break; + case 2: + ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc( + mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries); + + memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2)); + + for (i = 0; i < ctr->num_entries; i++) { + SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, + sizeof(SH_INFO_2)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname); + if (s) + init_unistr2(&info2->info_2_str.uni_netname, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark); + if (s) + init_unistr2(&info2->info_2_str.uni_remark, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path); + if (s) + init_unistr2(&info2->info_2_str.uni_path, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd); + if (s) + init_unistr2(&info2->info_2_str.uni_passwd, s, strlen(s) + 1); + } + break; + } + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *sharename) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_DEL q; + SRV_R_NET_SHARE_DEL r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_del("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_del("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *netname, uint32 type, char *remark, + uint32 perms, uint32 max_uses, uint32 num_uses, + char *path, char *passwd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_SHARE_ADD q; + SRV_R_NET_SHARE_ADD r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark, + perms, max_uses, num_uses, path, passwd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_share_add("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_share_add("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *server, TIME_OF_DAY_INFO *tod) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_REMOTE_TOD q; + SRV_R_NET_REMOTE_TOD r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_remote_tod(&q, cli->srv_name_slash); + + /* Marshall data and send request */ + + if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + r.tod = tod; + + if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 file_level, char *user_name, + SRV_FILE_INFO_CTR *ctr, int preferred_len, + ENUM_HND *hnd) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_FILE_ENUM q; + SRV_R_NET_FILE_ENUM r; + WERROR result = W_ERROR(ERRgeneral); + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name, + file_level, ctr, preferred_len, hnd); + + /* Marshall data and send request */ + + if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_file_enum("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(result)) + goto done; + + /* copy the data over to the ctr */ + + ZERO_STRUCTP(ctr); + + ctr->switch_value = file_level; + + ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries; + + switch(file_level) { + case 3: + ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc( + mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries); + + memset(ctr->file.info3, 0, + sizeof(SRV_FILE_INFO_3) * ctr->num_entries); + + for (i = 0; i < r.ctr.num_entries; i++) { + SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i]; + char *s; + + /* Copy pointer crap */ + + memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, + sizeof(FILE_INFO_3)); + + /* Duplicate strings */ + + s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name); + if (s) + init_unistr2(&info3->info_3_str.uni_path_name, s, strlen(s) + 1); + + s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name); + if (s) + init_unistr2(&info3->info_3_str.uni_user_name, s, strlen(s) + 1); + + } + + break; + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 file_id) +{ + prs_struct qbuf, rbuf; + SRV_Q_NET_FILE_CLOSE q; + SRV_R_NET_FILE_CLOSE r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id); + + /* Marshall data and send request */ + + if (!srv_io_q_net_file_close("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!srv_io_r_net_file_close("", &r, &rbuf, 0)) + goto done; + + result = r.status; + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + return result; +} diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c index 2a84e6b698..756ff61e5b 100644 --- a/source3/libsmb/cli_wkssvc.c +++ b/source3/libsmb/cli_wkssvc.c @@ -23,24 +23,6 @@ #include "includes.h" -/** - * Opens a SMB connection to the wkssvc pipe - * - * @param cli client structure (not yet initialised) - * @param system_name called rpc server name - * @param creds user credentials - * - * @return client structure with opened pipe - **/ - -struct cli_state *cli_wkssvc_initialise(struct cli_state *cli, - char *system_name, - struct ntuser_creds *creds) -{ - return cli_pipe_initialise(cli, system_name, PIPE_WKSSVC, creds); -} - - /** * WksQueryInfo rpc call (like query for server's capabilities) * diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4be63b8f2e..f0b02b97b0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Barteltt 2001-2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,28 +25,27 @@ static const struct { - int prot; - const char *name; - } -prots[] = - { - {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, - {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, - {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, - {PROTOCOL_LANMAN1,"LANMAN1.0"}, - {PROTOCOL_LANMAN2,"LM1.2X002"}, - {PROTOCOL_LANMAN2,"Samba"}, - {PROTOCOL_NT1,"NT LANMAN 1.0"}, - {PROTOCOL_NT1,"NT LM 0.12"}, - {-1,NULL} - }; - + int prot; + const char *name; +} prots[] = { + {PROTOCOL_CORE,"PC NETWORK PROGRAM 1.0"}, + {PROTOCOL_COREPLUS,"MICROSOFT NETWORKS 1.03"}, + {PROTOCOL_LANMAN1,"MICROSOFT NETWORKS 3.0"}, + {PROTOCOL_LANMAN1,"LANMAN1.0"}, + {PROTOCOL_LANMAN2,"LM1.2X002"}, + {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, + {PROTOCOL_LANMAN2,"Samba"}, + {PROTOCOL_NT1,"NT LANMAN 1.0"}, + {PROTOCOL_NT1,"NT LM 0.12"}, + {-1,NULL} +}; /**************************************************************************** -do an old lanman2 style session setup + Do an old lanman2 style session setup. ****************************************************************************/ + static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, - char *pass, int passlen) + char *pass, int passlen, const char *workgroup) { fstring pword; char *p; @@ -54,17 +54,19 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return False; } + /* Lanman2 cannot use SMB signing. */ + cli->sign_info.use_smb_signing = False; + /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & 1)) { + if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; } - if (passlen > 0 && (cli->sec_mode & 2) && passlen != 24) { + if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ passlen = 24; - clistr_push(cli, pword, pass, -1, STR_TERMINATE); - SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); - } else if ((cli->sec_mode & 2) && passlen == 24) { + SMBencrypt(pass,cli->secblob.data,(uchar *)pword); + } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ memcpy(pword, pass, passlen); } else if (passlen > 0) { @@ -88,7 +90,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - p += clistr_push(cli, p, user, -1, STR_TERMINATE); + p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); @@ -108,10 +113,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return True; } - /**************************************************************************** -work out suitable capabilities to offer the server + Work out suitable capabilities to offer the server. ****************************************************************************/ + static uint32 cli_session_setup_capabilities(struct cli_state *cli) { uint32 capabilities = CAP_NT_SMBS; @@ -131,10 +136,10 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) return capabilities; } - /**************************************************************************** -do a NT1 guest session setup + Do a NT1 guest session setup. ****************************************************************************/ + static BOOL cli_session_setup_guest(struct cli_state *cli) { char *p; @@ -181,10 +186,10 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) return True; } - /**************************************************************************** -do a NT1 plaintext session setup + Do a NT1 plaintext session setup. ****************************************************************************/ + static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -237,9 +242,15 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, } -/**************************************************************************** -do a NT1 NTLM/LM encrypted session setup -****************************************************************************/ +/** + do a NT1 NTLM/LM encrypted session setup + @param cli client state to create do session setup on + @param user username + @param pass *either* cleartext password (passlen !=24) or LM response. + @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear + @param workgroup The user's domain. +*/ + static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *pass, int passlen, char *ntpass, int ntpasslen, @@ -248,6 +259,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, uint32 capabilities = cli_session_setup_capabilities(cli); fstring pword, ntpword; char *p; + BOOL tried_signing = False; if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { return False; @@ -257,12 +269,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; - clistr_push(cli, pword, - pass?pass:"", sizeof(pword), STR_TERMINATE|STR_ASCII); - clistr_push(cli, ntpword, - pass?pass:"", sizeof(ntpword), STR_TERMINATE|STR_ASCII); - SMBencrypt((uchar *)pword,cli->secblob.data,(uchar *)pword); - SMBNTencrypt((uchar *)ntpword,cli->secblob.data,(uchar *)ntpword); + SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); + SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); + if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { + cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); + tried_signing = True; + } } else { memcpy(pword, pass, passlen); memcpy(ntpword, ntpass, ntpasslen); @@ -298,10 +310,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, show_msg(cli->inbuf); + if (tried_signing && (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */)) { + /* We only use it if we have a successful non-guest connect */ + cli->sign_info.use_smb_signing = False; + } + if (cli_is_error(cli)) { return False; } - + /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -315,10 +332,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, return True; } - /**************************************************************************** -send a extended security session setup blob, returning a reply blob + Send a extended security session setup blob, returning a reply blob. ****************************************************************************/ + static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); @@ -382,8 +399,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) #ifdef HAVE_KRB5 /**************************************************************************** -do a spnego/kerberos encrypted session setup + Do a spnego/kerberos encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, char *workgroup) { DATA_BLOB blob2, negTokenTarg; @@ -411,8 +429,9 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c #endif /**************************************************************************** -do a spnego/NTLMSSP encrypted session setup + Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -501,10 +520,10 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, return !cli_is_error(cli); } - /**************************************************************************** -do a spnego encrypted session setup + Do a spnego encrypted session setup. ****************************************************************************/ + static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, char *pass, char *workgroup) { @@ -514,6 +533,9 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, int i; BOOL got_kerberos_mechanism = False; + /* spnego security cannot use SMB signing (for now). */ + cli->sign_info.use_smb_signing = False; + DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ @@ -558,12 +580,12 @@ ntlmssp: return cli_session_setup_ntlmssp(cli, user, pass, workgroup); } - /**************************************************************************** Send a session setup. The username and workgroup is in UNIX character format and must be converted to DOS codepage format before sending. If the password is in plaintext, the same should be done. ****************************************************************************/ + BOOL cli_session_setup(struct cli_state *cli, char *user, char *pass, int passlen, @@ -591,7 +613,7 @@ BOOL cli_session_setup(struct cli_state *cli, /* if its an older server then we have to use the older request format */ if (cli->protocol < PROTOCOL_NT1) { - return cli_session_setup_lanman2(cli, user, pass, passlen); + return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); } /* if no user is supplied then we have to do an anonymous connection. @@ -603,13 +625,13 @@ BOOL cli_session_setup(struct cli_state *cli, /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ - if ((cli->sec_mode & 1) == 0) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) { return cli_session_setup_plaintext(cli, user, "", workgroup); } - /* if the server doesn't support encryption then we have to use plaintext. The - second password is ignored */ - if ((cli->sec_mode & 2) == 0) { + /* if the server doesn't support encryption then we have to use + plaintext. The second password is ignored */ + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { return cli_session_setup_plaintext(cli, user, pass, workgroup); } @@ -630,27 +652,28 @@ BOOL cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { - memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); - SCVAL(cli->outbuf,smb_com,SMBulogoffX); - cli_setup_packet(cli); + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,2,0,True); + SCVAL(cli->outbuf,smb_com,SMBulogoffX); + cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; - return !cli_is_error(cli); + return !cli_is_error(cli); } /**************************************************************************** -send a tconX + Send a tconX. ****************************************************************************/ + BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { - fstring fullshare, pword, dos_pword; + fstring fullshare, pword; char *p; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -658,20 +681,19 @@ BOOL cli_send_tconX(struct cli_state *cli, fstrcpy(cli->share, share); /* in user level security don't send a password now */ - if (cli->sec_mode & 1) { + if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { passlen = 1; pass = ""; } - if ((cli->sec_mode & 2) && *pass && passlen != 24) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { /* * Non-encrypted passwords - convert to DOS codepage before encryption. */ passlen = 24; - clistr_push(cli, dos_pword, pass, -1, STR_TERMINATE); - SMBencrypt((uchar *)dos_pword,cli->secblob.data,(uchar *)pword); + SMBencrypt(pass,cli->secblob.data,(uchar *)pword); } else { - if((cli->sec_mode & 3) == 0) { + if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { /* * Non-encrypted passwords - convert to DOS codepage before using. */ @@ -728,10 +750,10 @@ BOOL cli_send_tconX(struct cli_state *cli, return True; } - /**************************************************************************** -send a tree disconnect + Send a tree disconnect. ****************************************************************************/ + BOOL cli_tdis(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); @@ -747,15 +769,19 @@ BOOL cli_tdis(struct cli_state *cli) return !cli_is_error(cli); } - /**************************************************************************** -send a negprot command + Send a negprot command. ****************************************************************************/ + void cli_negprot_send(struct cli_state *cli) { char *p; int numprots; + if (cli->protocol < PROTOCOL_NT1) { + cli->use_spnego = False; + } + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -778,16 +804,25 @@ void cli_negprot_send(struct cli_state *cli) cli_send_smb(cli); } - /**************************************************************************** -send a negprot command + Send a negprot command. ****************************************************************************/ + BOOL cli_negprot(struct cli_state *cli) { char *p; int numprots; int plength; + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send negprot again, particularly after setting up SMB Signing\n")); + return False; + } + + if (cli->protocol < PROTOCOL_NT1) { + cli->use_spnego = False; + } + memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ @@ -822,7 +857,7 @@ BOOL cli_negprot(struct cli_state *cli) return(False); } - cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ @@ -847,7 +882,16 @@ BOOL cli_negprot(struct cli_state *cli) smb_buf(cli->inbuf)+8, sizeof(cli->server_domain), smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } + + /* A way to attempt to force SMB signing */ + if (getenv("CLI_FORCE_SMB_SIGNING")) + cli->sign_info.negotiated_smb_signing = True; + + if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) + cli->sign_info.negotiated_smb_signing = False; + } else if (cli->protocol >= PROTOCOL_LANMAN1) { + cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); @@ -860,6 +904,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); } else { /* the old core protocol */ + cli->use_spnego = False; cli->sec_mode = 0; cli->serverzone = TimeDiff(time(NULL)); } @@ -874,10 +919,10 @@ BOOL cli_negprot(struct cli_state *cli) return True; } - /**************************************************************************** - send a session request. see rfc1002.txt 4.3 and 4.3.2 + Send a session request. See rfc1002.txt 4.3 and 4.3.2. ****************************************************************************/ + BOOL cli_session_request(struct cli_state *cli, struct nmb_name *calling, struct nmb_name *called) { @@ -888,6 +933,11 @@ BOOL cli_session_request(struct cli_state *cli, /* 445 doesn't have session request */ if (cli->port == 445) return True; + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); + return False; + } + /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); @@ -902,7 +952,7 @@ BOOL cli_session_request(struct cli_state *cli, name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); - /* setup the packet length + /* setup the packet length * Remove four bytes from the length count, since the length * field in the NBT Session Service header counts the number * of bytes which follow. The cli_send_smb() function knows @@ -913,10 +963,6 @@ BOOL cli_session_request(struct cli_state *cli, _smb_setlen(cli->outbuf,len); SCVAL(cli->outbuf,0,0x81); -#ifdef WITH_SSL -retry: -#endif /* WITH_SSL */ - cli_send_smb(cli); DEBUG(5,("Sent session request\n")); @@ -962,15 +1008,6 @@ retry: } } /* C. Hoch 9/14/95 End */ -#ifdef WITH_SSL - if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */ - if (!sslutil_fd_is_ssl(cli->fd)){ - if (sslutil_connect(cli->fd) == 0) - goto retry; - } - } -#endif /* WITH_SSL */ - if (CVAL(cli->inbuf,0) != 0x82) { /* This is the wrong place to put the error... JRA. */ cli->rap_error = CVAL(cli->inbuf,4); @@ -980,8 +1017,9 @@ retry: } /**************************************************************************** -open the client sockets + Open the client sockets. ****************************************************************************/ + BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { extern pstring user_socket_options; @@ -1034,155 +1072,11 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } /**************************************************************************** -establishes a connection right up to doing tconX, password in cache. + Initialise client credentials for authenticated pipe access. ****************************************************************************/ -BOOL cli_establish_connection(struct cli_state *cli, - char *dest_host, struct in_addr *dest_ip, - struct nmb_name *calling, struct nmb_name *called, - char *service, char *service_type, - BOOL do_shutdown, BOOL do_tcon) -{ - DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n", - nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip), - cli->user_name, cli->domain)); - - /* establish connection */ - - if ((!cli->initialised)) - { - return False; - } - - /* cli_establish_connection() can't handle spnego yet. Once we get rid of - pwd_cache and other horrors we can get rid of this */ - cli->use_spnego = False; - - if (cli->fd == -1) - { - if (!cli_connect(cli, dest_host, dest_ip)) - { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(called), inet_ntoa(*dest_ip))); - return False; - } - } - - if (!cli_session_request(cli, calling, called)) - { - DEBUG(1,("failed session request\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (!cli_negprot(cli)) - { - DEBUG(1,("failed negprot\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - if (cli->pwd.cleartext || cli->pwd.null_pwd) - { - fstring passwd; - int pass_len; - - if (cli->pwd.null_pwd) - { - /* attempt null session */ - passwd[0] = 0; - pass_len = 1; - } - else - { - /* attempt clear-text session */ - pwd_get_cleartext(&(cli->pwd), passwd); - pass_len = strlen(passwd); - } - - /* attempt clear-text session */ - if (!cli_session_setup(cli, cli->user_name, - passwd, pass_len, - NULL, 0, - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)passwd, strlen(passwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - { - cli_shutdown(cli); - } - return False; - } - } - } - else - { - /* attempt encrypted session */ - unsigned char nt_sess_pwd[24]; - unsigned char lm_sess_pwd[24]; - - /* creates (storing a copy of) and then obtains a 24 byte password OWF */ - pwd_make_lm_nt_owf(&(cli->pwd), cli->secblob.data); - pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd); - - /* attempt encrypted session */ - if (!cli_session_setup(cli, cli->user_name, - (char*)lm_sess_pwd, sizeof(lm_sess_pwd), - (char*)nt_sess_pwd, sizeof(nt_sess_pwd), - cli->domain)) - { - DEBUG(1,("failed session setup\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - - DEBUG(1,("session setup ok\n")); - - if (*cli->server_domain || *cli->server_os || *cli->server_type) - { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - cli->server_domain, - cli->server_os, - cli->server_type)); - } - - if (do_tcon) - { - if (!cli_send_tconX(cli, service, service_type, - (char*)nt_sess_pwd, sizeof(nt_sess_pwd))) - { - DEBUG(1,("failed tcon_X\n")); - if (do_shutdown) - cli_shutdown(cli); - return False; - } - } - } - - if (do_shutdown) - cli_shutdown(cli); - - return True; -} - -/* Initialise client credentials for authenticated pipe access */ static void init_creds(struct ntuser_creds *creds, char* username, - char* domain, char* password, int pass_len) + char* domain, char* password) { ZERO_STRUCTP(creds); @@ -1196,15 +1090,26 @@ static void init_creds(struct ntuser_creds *creds, char* username, } } -/**************************************************************************** -establishes a connection right up to doing tconX, password specified. -****************************************************************************/ +/** + establishes a connection right up to doing tconX, password specified. + @param output_cli A fully initialised cli structure, non-null only on success + @param dest_host The netbios name of the remote host + @param dest_ip (optional) The the destination IP, NULL for name based lookup + @param port (optional) The destination port (0 for default) + @param service (optional) The share to make the connection to. Should be 'unqualified' in any way. + @param service_type The 'type' of serivice. + @param user Username, unix string + @param domain User's domain + @param password User's password, unencrypted unix string. +*/ + NTSTATUS cli_full_connection(struct cli_state **output_cli, - const char *my_name, const char *dest_host, + const char *my_name, + const char *dest_host, struct in_addr *dest_ip, int port, char *service, char *service_type, char *user, char *domain, - char *password, int pass_len) + char *password, int flags) { struct ntuser_creds creds; NTSTATUS nt_status; @@ -1212,32 +1117,40 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct nmb_name called; struct cli_state *cli; struct in_addr ip; - - if (!output_cli) + extern pstring global_myname; + + if (!output_cli) { DEBUG(0, ("output_cli is NULL!?!")); + SMB_ASSERT("output_cli for cli_full_connection was NULL.\n"); + } - *output_cli = NULL; + if (!my_name) + my_name = global_myname; - make_nmb_name(&calling, my_name, 0x0); - make_nmb_name(&called , dest_host, 0x20); - -again: - if (!(cli = cli_initialise(NULL))) return NT_STATUS_NO_MEMORY; + make_nmb_name(&calling, my_name, 0x0); + make_nmb_name(&called , dest_host, 0x20); + if (cli_set_port(cli, port) != port) { cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } - ip = *dest_ip; - + if (dest_ip) { + ip = *dest_ip; + } else { + ZERO_STRUCT(ip); + } + +again: + DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service)); if (!cli_connect(cli, dest_host, &ip)) { - DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n", - nmb_namestr(&called), inet_ntoa(*dest_ip))); + DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n", + nmb_namestr(&called), inet_ntoa(ip))); cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } @@ -1258,6 +1171,12 @@ again: return NT_STATUS_UNSUCCESSFUL; } + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) { + cli->use_spnego = False; + } else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { + cli->use_kerberos = True; + } + if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); nt_status = NT_STATUS_UNSUCCESSFUL; @@ -1265,29 +1184,36 @@ again: return nt_status; } - if (!cli_session_setup(cli, user, password, pass_len, password, pass_len, + if (!cli_session_setup(cli, user, password, strlen(password)+1, + password, strlen(password)+1, domain)) { - DEBUG(1,("failed session setup\n")); - nt_status = cli_nt_error(cli); - cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) - nt_status = NT_STATUS_UNSUCCESSFUL; - return nt_status; + if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) + || cli_session_setup(cli, "", "", 0, + "", 0, domain)) { + } else { + nt_status = cli_nt_error(cli); + DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); + cli_shutdown(cli); + if (NT_STATUS_IS_OK(nt_status)) + nt_status = NT_STATUS_UNSUCCESSFUL; + return nt_status; + } } if (service) { if (!cli_send_tconX(cli, service, service_type, - (char*)password, pass_len)) { - DEBUG(1,("failed tcon_X\n")); + (char*)password, strlen(password)+1)) { + DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); nt_status = cli_nt_error(cli); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) + if (NT_STATUS_IS_OK(nt_status)) { nt_status = NT_STATUS_UNSUCCESSFUL; + } return nt_status; } } - init_creds(&creds, user, domain, password, pass_len); + init_creds(&creds, user, domain, password); cli_init_creds(cli, &creds); *output_cli = cli; @@ -1301,55 +1227,53 @@ again: BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, struct in_addr *pdest_ip) { - struct nmb_name calling, called; + struct nmb_name calling, called; - make_nmb_name(&calling, srchost, 0x0); + make_nmb_name(&calling, srchost, 0x0); - /* - * If the called name is an IP address - * then use *SMBSERVER immediately. - */ + /* + * If the called name is an IP address + * then use *SMBSERVER immediately. + */ - if(is_ipaddress(desthost)) - make_nmb_name(&called, "*SMBSERVER", 0x20); - else - make_nmb_name(&called, desthost, 0x20); + if(is_ipaddress(desthost)) + make_nmb_name(&called, "*SMBSERVER", 0x20); + else + make_nmb_name(&called, desthost, 0x20); - if (!cli_session_request(cli, &calling, &called)) { - struct nmb_name smbservername; + if (!cli_session_request(cli, &calling, &called)) { + struct nmb_name smbservername; - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + make_nmb_name(&smbservername , "*SMBSERVER", 0x20); - /* - * If the name wasn't *SMBSERVER then - * try with *SMBSERVER if the first name fails. - */ + /* + * If the name wasn't *SMBSERVER then + * try with *SMBSERVER if the first name fails. + */ - if (nmb_name_equal(&called, &smbservername)) { + if (nmb_name_equal(&called, &smbservername)) { - /* - * The name used was *SMBSERVER, don't bother with another name. - */ + /* + * The name used was *SMBSERVER, don't bother with another name. + */ - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } + cli_shutdown(cli); + return False; + } - cli_shutdown(cli); + cli_shutdown(cli); - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, pdest_ip) || - !cli_session_request(cli, &calling, &smbservername)) { - DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ + if (!cli_initialise(cli) || + !cli_connect(cli, desthost, pdest_ip) || + !cli_session_request(cli, &calling, &smbservername)) { + DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); - return False; - } - } + cli_shutdown(cli); + return False; + } + } - return True; + return True; } - - diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ba7a327344..c9500ead5d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -31,6 +31,41 @@ int cli_set_port(struct cli_state *cli, int port) return port; } +/**************************************************************************** + read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. +****************************************************************************/ + +static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) +{ + BOOL ret; + + for(;;) + { + ret = receive_smb(fd, buffer, timeout); + + if (!ret) + { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != SMBkeepalive) + break; + } + show_msg(buffer); + return ret; +} + + /**************************************************************************** recv an smb ****************************************************************************/ @@ -72,7 +107,7 @@ BOOL cli_receive_smb(struct cli_state *cli) } /**************************************************************************** - send an smb to a fd. + Send an smb to a fd. ****************************************************************************/ BOOL cli_send_smb(struct cli_state *cli) @@ -82,31 +117,33 @@ BOOL cli_send_smb(struct cli_state *cli) ssize_t ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) return False; + if (cli->fd == -1) + return False; + + cli_caclulate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; while (nwritten < len) { ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0) { - close(cli->fd); - cli->fd = -1; - DEBUG(0,("Error writing %d bytes to client. %d\n", - (int)len,(int)ret)); + close(cli->fd); + cli->fd = -1; + DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); return False; } nwritten += ret; } - return True; } /**************************************************************************** -setup basics in a outgoing packet + Setup basics in a outgoing packet. ****************************************************************************/ + void cli_setup_packet(struct cli_state *cli) { - cli->rap_error = 0; + cli->rap_error = 0; SSVAL(cli->outbuf,smb_pid,cli->pid); SSVAL(cli->outbuf,smb_uid,cli->vuid); SSVAL(cli->outbuf,smb_mid,cli->mid); @@ -123,6 +160,8 @@ void cli_setup_packet(struct cli_state *cli) if (cli->use_spnego) { flags2 |= FLAGS2_EXTENDED_SECURITY; } + if (cli->sign_info.use_smb_signing) + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -247,10 +286,6 @@ void cli_shutdown(struct cli_state *cli) if (cli->mem_ctx) talloc_destroy(cli->mem_ctx); -#ifdef WITH_SSL - if (cli->fd != -1) - sslutil_disconnect(cli->fd); -#endif /* WITH_SSL */ if (cli->fd != -1) close(cli->fd); allocated = cli->allocated; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 05843ac5de..a47c956a55 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -76,7 +76,7 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, cons uint32 unix_perms_to_wire(mode_t perms) { - uint ret = 0; + unsigned int ret = 0; ret |= ((perms & S_IXOTH) ? UNIX_X_OTH : 0); ret |= ((perms & S_IWOTH) ? UNIX_W_OTH : 0); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 8b28e05a47..17a759f9e3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -54,10 +54,14 @@ static int interpret_long_filename(struct cli_state *cli, len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); + /* the len+2 below looks strange but it is + important to cope with the differences + between win2000 and win9x for this call + (tridge) */ p += clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - len, - STR_TERMINATE); + sizeof(finfo->name), + len+2, + STR_TERMINATE); return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a2b6c8bb8b..2064e14954 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -117,7 +117,8 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) if (cli->rap_error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); cli->privileges = SVAL(p, 24); - fstrcpy(cli->eff_name,p+2); + /* The cli->eff_name field used to be set here + but it wasn't used anywhere else. */ } else { DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); } @@ -283,8 +284,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char param[16+sizeof(fstring)]; char data[532]; char *p = param; - fstring upper_case_old_pw; - fstring upper_case_new_pw; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; int data_len; @@ -316,9 +315,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char * Get the Lanman hash of the old password, we * use this as the key to make_oem_passwd_hash(). */ - memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw)); - clistr_push(cli, upper_case_old_pw, old_password, -1,STR_TERMINATE|STR_UPPER|STR_ASCII); - E_P16((uchar *)upper_case_old_pw, old_pw_hash); + E_deshash(old_password, old_pw_hash); clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE|STR_ASCII); @@ -328,10 +325,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char /* * Now place the old password hash in the data. */ - memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw)); - clistr_push(cli, upper_case_new_pw, new_password, -1, STR_TERMINATE|STR_UPPER|STR_ASCII); - - E_P16((uchar *)upper_case_new_pw, new_pw_hash); + E_deshash(new_password, new_pw_hash); E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 00cd4b15f3..9c3ec212d5 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1493,7 +1493,7 @@ int cli_NetPrintQEnum(struct cli_state *cli, for (j=0;joutbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - set_message(cli->outbuf,10,0,True); - - SCVAL(cli->outbuf,smb_com,SMBreadbraw); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SIVAL(cli->outbuf,smb_vwv1,offset); - SSVAL(cli->outbuf,smb_vwv2,size); - SSVAL(cli->outbuf,smb_vwv3,size); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - return cli_send_smb(cli); -} - /**************************************************************************** Read size bytes at offset offset using SMBreadX. ****************************************************************************/ @@ -152,6 +127,43 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return total; } +#if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ + +/* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0 + you must fix ensure you don't attempt to sign the packets - data + *will* be currupted */ + +/**************************************************************************** +Issue a single SMBreadraw and don't wait for a reply. +****************************************************************************/ + +static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, + size_t size, int i) +{ + + if (!cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot use readraw and SMB Signing\n")); + return False; + } + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,10,0,True); + + SCVAL(cli->outbuf,smb_com,SMBreadbraw); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SIVAL(cli->outbuf,smb_vwv1,offset); + SSVAL(cli->outbuf,smb_vwv2,size); + SSVAL(cli->outbuf,smb_vwv3,size); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + return cli_send_smb(cli); +} + /**************************************************************************** Tester for the readraw call. ****************************************************************************/ @@ -213,7 +225,7 @@ ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, si return total; } - +#endif /**************************************************************************** issue a single SMBwrite and don't wait for a reply ****************************************************************************/ diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a4fcfa5d9a..469b946088 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -549,7 +549,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, format specifiers are: - U = unicode string (input is unix string) + U = unicode string (output is unix string) B = data blob b = data blob in header d = word (4 bytes) @@ -620,3 +620,44 @@ BOOL msrpc_parse(DATA_BLOB *blob, return True; } + +/** + * Print out the NTLMSSP flags for debugging + */ + +void debug_ntlmssp_flags(uint32 neg_flags) +{ + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) + DEBUG(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_OEM) + DEBUG(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + if (neg_flags & NTLMSSP_REQUEST_TARGET) + DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) + DEBUG(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + DEBUG(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) + DEBUG(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) + DEBUG(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_128) + DEBUG(4, (" NTLMSSP_NEGOTIATE_128\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) + DEBUG(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); +} + diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index c30db3ad95..a35108c3de 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -2,6 +2,7 @@ * Unix SMB/CIFS implementation. * error mapping functions * Copyright (C) Andrew Tridgell 2001 + * Copyright (C) Andrew Bartlett 2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 237701b968..0ffc1c1378 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1,9 +1,10 @@ /* - Unix SMB/CIFS implementation. + Unix SMB/Netbios implementation. SMB client library implementation Copyright (C) Andrew Tridgell 1998 - Copyright (C) Richard Sharpe 2000 + Copyright (C) Richard Sharpe 2000, 2002 Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,56 +22,36 @@ */ #include "includes.h" + #include "libsmbclient.h" -/* Structure for servers ... Held here so we don't need an include ... - * May be better to put in an include file +/* + * Functions exported by libsmb_cache.c that we need here */ +int smbc_default_cache_functions(SMBCCTX *context); -struct smbc_server { - struct smbc_server *next, *prev; - struct cli_state cli; - dev_t dev; - char *server_name; - char *share_name; - char *workgroup; - char *username; - BOOL no_pathinfo2; -}; - -/* Keep directory entries in a list */ -struct smbc_dir_list { - struct smbc_dir_list *next; - struct smbc_dirent *dirent; -}; - -struct smbc_file { - int cli_fd; - int smbc_fd; - char *fname; - off_t offset; - struct smbc_server *srv; - BOOL file; - struct smbc_dir_list *dir_list, *dir_end, *dir_next; - int dir_type, dir_error; -}; - -int smbc_fstatdir(int fd, struct stat *st); /* Forward decl */ -BOOL smbc_getatr(struct smbc_server *srv, char *path, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - SMB_INO_T *ino); +/* + * check if an element is part of the list. + * FIXME: Does not belong here ! + * Can anyone put this in a macro in dlinklist.h ? + * -- Tom + */ +static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { + if (!p || !list) return False; + do { + if (p == list) return True; + list = list->next; + } while (list); + return False; +} extern BOOL in_client; extern pstring global_myname; + +/* + * Is the logging working / configfile read ? + */ static int smbc_initialized = 0; -static smbc_get_auth_data_fn smbc_auth_fn = NULL; -/*static int smbc_debug;*/ -static int smbc_start_fd; -static struct smbc_file **smbc_file_table; -static struct smbc_server *smbc_srvs; -static pstring my_netbios_name; -static pstring smbc_user; /* * Function to parse a path and turn it into components @@ -78,14 +59,14 @@ static pstring smbc_user; * We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]] * * smb:// means show all the workgroups - * smb://name/ means, if name<1D> exists, list servers in workgroup, + * smb://name/ means, if name<1D> or name<1B> exists, list servers in workgroup, * else, if name<20> exists, list all shares for server ... */ static const char *smbc_prefix = "smb:"; static int -smbc_parse_path(const char *fname, char *server, char *share, char *path, +smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, char *path, char *user, char *password) /* FIXME, lengths of strings */ { static pstring s; @@ -121,7 +102,8 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, if (*p == '/') { - strncpy(server, (char *)lp_workgroup(), 16); /* FIXME: Danger here */ + strncpy(server, context->workgroup, + (strlen(context->workgroup) < 16)?strlen(context->workgroup):16); return 0; } @@ -147,7 +129,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, if (strchr_m(u, ';')) { next_token(&u, domain, ";", sizeof(fstring)); - + } if (strchr_m(u, ':')) { @@ -172,9 +154,9 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, } if (!next_token(&p, server, "/", sizeof(fstring))) { - + return -1; - + } if (*p == (char)0) return 0; /* That's it ... */ @@ -196,7 +178,7 @@ smbc_parse_path(const char *fname, char *server, char *share, char *path, * Convert an SMB error into a UNIX error ... */ -int smbc_errno(struct cli_state *c) +static int smbc_errno(SMBCCTX *context, struct cli_state *c) { int ret; @@ -216,12 +198,65 @@ int smbc_errno(struct cli_state *c) ret = cli_errno_from_nt(status); DEBUG(3,("smbc errno %s -> %d\n", - nt_errstr(status), ret)); + get_nt_error_msg(status), ret)); } return ret; } +/* + * Check a server_fd. + * returns 0 if the server is in shape. Returns 1 on error + * + * Also useable outside libsmbclient to enable external cache + * to do some checks too. + */ +int smbc_check_server(SMBCCTX * context, SMBCSRV * server) +{ + if ( cli_send_keepalive(&server->cli) == False ) + return 1; + + /* connection is ok */ + return 0; +} + +/* + * Remove a server from the list server_table if it's unused. + * On success, 0 is returned. 1 is returned if the server could not be removed. + * + * Also useable outside libsmbclient + */ +int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) +{ + SMBCFILE * file; + + /* are we being fooled ? */ + if (!context || !context->_initialized || !srv) return 1; + + + /* Check all open files/directories for a relation with this server */ + for (file = context->_files; file; file=file->next) { + if (file->srv == srv) { + /* Still used */ + DEBUG(3, ("smbc_remove_usused_server: %p still used by %p.\n", + srv, file)); + return 1; + } + } + + DLIST_REMOVE(context->_servers, srv); + + cli_shutdown(&srv->cli); + + DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); + + context->callbacks.remove_cached_srv_fn(context, srv); + + SAFE_FREE(srv); + + return 0; +} + /* * Connect to a server, possibly on an existing connection * @@ -233,58 +268,70 @@ int smbc_errno(struct cli_state *c) * info we need, unless the username and password were passed in. */ -struct smbc_server *smbc_server(char *server, char *share, - char *workgroup, char *username, - char *password) +SMBCSRV *smbc_server(SMBCCTX *context, + char *server, char *share, + char *workgroup, char *username, + char *password) { - struct smbc_server *srv=NULL; + SMBCSRV *srv=NULL; + int auth_called = 0; struct cli_state c; struct nmb_name called, calling; char *p, *server_n = server; fstring group; pstring ipenv; struct in_addr ip; + int tried_reverse = 0; - zero_ip(&ip); + zero_ip(&ip); ZERO_STRUCT(c); - /* try to use an existing connection */ - for (srv=smbc_srvs;srv;srv=srv->next) { - if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0 && - strcmp(workgroup,srv->workgroup)==0 && - strcmp(username, srv->username) == 0) - return srv; - } - if (server[0] == 0) { errno = EPERM; return NULL; } - /* - * Pick up the auth info here, once we know we need to connect - * But only if we do not have a username and password ... - */ - - if (!username[0] || !password[0]) - smbc_auth_fn(server, share, workgroup, sizeof(fstring), - username, sizeof(fstring), password, sizeof(fstring)); - - /* - * However, smbc_auth_fn may have picked up info relating to an - * existing connection, so try for an existing connection again ... - */ + check_server_cache: - for (srv=smbc_srvs;srv;srv=srv->next) { - if (strcmp(server,srv->server_name)==0 && - strcmp(share,srv->share_name)==0 && - strcmp(workgroup,srv->workgroup)==0 && - strcmp(username, srv->username) == 0) - return srv; + srv = context->callbacks.get_cached_srv_fn(context, server, share, + workgroup, username); + + if (!auth_called && !srv && (!username[0] || !password[0])) { + context->callbacks.auth_fn(server, share, workgroup, sizeof(fstring), + username, sizeof(fstring), password, sizeof(fstring)); + /* + * However, smbc_auth_fn may have picked up info relating to an + * existing connection, so try for an existing connection again ... + */ + auth_called = 1; + goto check_server_cache; + } + + if (srv) { + if (context->callbacks.check_server_fn(context, srv)) { + /* + * This server is no good anymore + * Try to remove it and check for more possible servers in the cache + */ + if (context->callbacks.remove_unused_server_fn(context, srv)) { + /* + * We could not remove the server completely, remove it from the cache + * so we will not get it again. It will be removed when the last file/dir + * is closed. + */ + context->callbacks.remove_cached_srv_fn(context, srv); + } + + /* + * Maybe there are more cached connections to this server + */ + goto check_server_cache; + } + return srv; + } - make_nmb_name(&calling, my_netbios_name, 0x0); + make_nmb_name(&calling, context->netbios_name, 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); @@ -303,21 +350,52 @@ struct smbc_server *smbc_server(char *server, char *share, again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); - zero_ip(&ip); + zero_ip(&ip); /* have to open a new connection */ - if (!cli_initialise(&c) || !cli_connect(&c, server_n, &ip)) { - if (c.initialised) cli_shutdown(&c); + if (!cli_initialise(&c)) { errno = ENOENT; return NULL; } + c.timeout = context->timeout; + + if (!cli_connect(&c, server_n, &ip)) { + cli_shutdown(&c); + errno = ENOENT; + return NULL; + } + if (!cli_session_request(&c, &calling, &called)) { cli_shutdown(&c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } + else { /* Try one more time, but ensure we don't loop */ + + /* Only try this if server is an IP address ... */ + + if (is_ipaddress(server) && !tried_reverse) { + fstring remote_name; + struct in_addr rem_ip; + + if (!inet_aton(server, &rem_ip)) { + DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server)); + errno = ENOENT; + return NULL; + } + + tried_reverse++; /* Yuck */ + + if (name_status_find("*", 0, 0, rem_ip, remote_name)) { + make_nmb_name(&called, remote_name, 0x20); + goto again; + } + + + } + } errno = ENOENT; return NULL; } @@ -345,50 +423,37 @@ struct smbc_server *smbc_server(char *server, char *share, if (!cli_send_tconX(&c, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(&c); + errno = smbc_errno(context, &c); cli_shutdown(&c); return NULL; } DEBUG(4,(" tconx ok\n")); - srv = (struct smbc_server *)malloc(sizeof(*srv)); + /* + * Ok, we have got a nice connection + * Let's find a free server_fd + */ + + srv = (SMBCSRV *)malloc(sizeof(*srv)); if (!srv) { errno = ENOMEM; goto failed; } ZERO_STRUCTP(srv); - srv->cli = c; - srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); - srv->server_name = strdup(server); - if (!srv->server_name) { - errno = ENOMEM; - goto failed; - } - - srv->share_name = strdup(share); - if (!srv->share_name) { - errno = ENOMEM; + /* now add it to the cache (internal or external) */ + if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { + DEBUG(3, (" Failed to add server to cache\n")); goto failed; } - srv->workgroup = strdup(workgroup); - if (!srv->workgroup) { - errno = ENOMEM; - goto failed; - } - - srv->username = strdup(username); - if (!srv->username) { - errno = ENOMEM; - goto failed; - } - - DLIST_ADD(smbc_srvs, srv); + + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", + server, share, srv)); return srv; @@ -396,214 +461,49 @@ struct smbc_server *smbc_server(char *server, char *share, cli_shutdown(&c); if (!srv) return NULL; - SAFE_FREE(srv->server_name); - SAFE_FREE(srv->share_name); - SAFE_FREE(srv->workgroup); - SAFE_FREE(srv->username); SAFE_FREE(srv); return NULL; } -/* - *Remove a server from the list smbc_srvs if it's unused -- Tom (tom@ninja.nl) - * - * We accept a *srv - */ -BOOL smbc_remove_unused_server(struct smbc_server * s) -{ - int p; - - /* are we being fooled ? */ - if (!s) return False; - - /* close all open files/directories on this server */ - for (p = 0; p < SMBC_MAX_FD; p++) { - if (smbc_file_table[p] && - smbc_file_table[p]->srv == s) { - /* Still used .. DARN */ - DEBUG(3, ("smbc_remove_usused_server: %x still used by %s (%d).\n", (int) s, - smbc_file_table[p]->fname, smbc_file_table[p]->smbc_fd)); - return False; - } - } - - cli_shutdown(&s->cli); - - SAFE_FREE(s->username); - SAFE_FREE(s->workgroup); - SAFE_FREE(s->server_name); - SAFE_FREE(s->share_name); - DLIST_REMOVE(smbc_srvs, s); - DEBUG(3, ("smbc_remove_usused_server: %x removed.\n", (int) s)); - SAFE_FREE(s); - return True; -} - -/* - *Initialise the library etc - * - * We accept valid values for debug from 0 to 100, - * and insist that fn must be non-null. - */ - -int smbc_init(smbc_get_auth_data_fn fn, int debug) -{ - pstring conf; - int p, pid; - char *user = NULL, *home = NULL, *pname="libsmbclient"; - - if (!fn || debug < 0 || debug > 100) { - - errno = EINVAL; - return -1; - - } - - if (smbc_initialized) { /* Don't go through this if we have already done it */ - - return 0; - - } - - smbc_initialized = 1; - smbc_auth_fn = fn; - /* smbc_debug = debug; */ - - DEBUGLEVEL = -1; - - setup_logging(pname, False); - - /* Here we would open the smb.conf file if needed ... */ - - home = getenv("HOME"); - - slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - - load_interfaces(); /* Load the list of interfaces ... */ - - in_client = True; /* FIXME, make a param */ - - if (!lp_load(conf, True, False, False)) { - - /* - * Hmmm, what the hell do we do here ... we could not parse the - * config file ... We must return an error ... and keep info around - * about why we failed - */ - - errno = ENOENT; /* FIXME: Figure out the correct error response */ - return -1; - - } - - reopen_logs(); /* Get logging working ... */ - - /* - * FIXME: Is this the best way to get the user info? - */ - - user = getenv("USER"); - /* walk around as "guest" if no username can be found */ - if (!user) user = strdup("guest"); - pstrcpy(smbc_user, user); /* Save for use elsewhere */ - - /* - * We try to get our netbios name from the config. If that fails we fall - * back on constructing our netbios name from our hostname etc - */ - if (global_myname) { - pstrcpy(my_netbios_name, global_myname); - } - else { - /* - * Hmmm, I want to get hostname as well, but I am too lazy for the moment - */ - pid = sys_getpid(); - slprintf(my_netbios_name, 16, "smbc%s%d", user, pid); - } - DEBUG(0,("Using netbios name %s.\n", my_netbios_name)); - - name_register_wins(my_netbios_name, 0); - - /* - * Now initialize the file descriptor array and figure out what the - * max open files is, so we can return FD's that are above the max - * open file, and separated by a guard band - */ - -#if (defined(HAVE_GETRLIMIT) && defined(RLIMIT_NOFILE)) - do { - struct rlimit rlp; - - if (getrlimit(RLIMIT_NOFILE, &rlp)) { - - DEBUG(0, ("smbc_init: getrlimit(1) for RLIMIT_NOFILE failed with error %s\n", strerror(errno))); - - smbc_start_fd = 1000000; - - } - else { - - smbc_start_fd = rlp.rlim_max + 10000; /* Leave a guard space of 10,000 */ - - } - } while ( 0 ); -#else /* !defined(HAVE_GETRLIMIT) || !defined(RLIMIT_NOFILE) */ - - smbc_start_fd = 1000000; - -#endif - - smbc_file_table = malloc(SMBC_MAX_FD * sizeof(struct smbc_file *)); - - for (p = 0; p < SMBC_MAX_FD; p++) - smbc_file_table[p] = NULL; - - if (!smbc_file_table) - return ENOMEM; - - return 0; /* Success */ - -} - /* * Routine to open() a file ... */ -int smbc_open(const char *fname, int flags, mode_t mode) +static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, mode_t mode) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *file = NULL; int fd; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; /* Best I can think of ... */ - return -1; + return NULL; } if (!fname) { errno = EINVAL; - return -1; + return NULL; } - smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { if (errno == EPERM) errno = EACCES; - return -1; /* smbc_server sets errno */ - + return NULL; /* smbc_server sets errno */ + } /* Hmmm, the test for a directory is suspect here ... FIXME */ @@ -614,50 +514,38 @@ int smbc_open(const char *fname, int flags, mode_t mode) } else { + + file = malloc(sizeof(SMBCFILE)); - int slot = 0; - - /* Find a free slot first */ - - while (smbc_file_table[slot]) - slot++; - - if (slot > SMBC_MAX_FD) { - - errno = ENOMEM; /* FIXME, is this best? */ - return -1; - - } - - smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); - - if (!smbc_file_table[slot]) { + if (!file) { errno = ENOMEM; - return -1; + return NULL; } + ZERO_STRUCTP(file); + if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) { /* Handle the error ... */ - SAFE_FREE(smbc_file_table[slot]); - errno = smbc_errno(&srv->cli); - return -1; + SAFE_FREE(file); + errno = smbc_errno(context, &srv->cli); + return NULL; } /* Fill in file struct */ - smbc_file_table[slot]->cli_fd = fd; - smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; - smbc_file_table[slot]->fname = strdup(fname); - smbc_file_table[slot]->srv = srv; - smbc_file_table[slot]->offset = 0; - smbc_file_table[slot]->file = True; + file->cli_fd = fd; + file->fname = strdup(fname); + file->srv = srv; + file->offset = 0; + file->file = True; - return smbc_file_table[slot]->smbc_fd; + DLIST_ADD(context->_files, file); + return file; } @@ -666,14 +554,15 @@ int smbc_open(const char *fname, int flags, mode_t mode) if (fd == -1) { int eno = 0; - eno = smbc_errno(&srv->cli); - fd = smbc_opendir(fname); - if (fd < 0) errno = eno; - return fd; + eno = smbc_errno(context, &srv->cli); + file = context->opendir(context, fname); + if (!file) errno = eno; + return file; } - return 1; /* Success, with fd ... */ + errno = EINVAL; /* FIXME, correct errno ? */ + return NULL; } @@ -683,38 +572,37 @@ int smbc_open(const char *fname, int flags, mode_t mode) static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ -int smbc_creat(const char *path, mode_t mode) +static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) { - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; - return -1; + return NULL; } - return smbc_open(path, creat_bits, mode); + return smbc_open_ctx(context, path, creat_bits, mode); } /* * Routine to read() a file ... */ -ssize_t smbc_read(int fd, void *buf, size_t count) +static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { - struct smbc_file *fe; int ret; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - DEBUG(4, ("smbc_read(%d, %d)\n", fd, (int)count)); + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; @@ -730,25 +618,16 @@ ssize_t smbc_read(int fd, void *buf, size_t count) } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe || !fe->file) { - - errno = EBADF; - return -1; - - } - - ret = cli_read(&fe->srv->cli, fe->cli_fd, buf, fe->offset, count); + ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count); if (ret < 0) { - errno = smbc_errno(&fe->srv->cli); + errno = smbc_errno(context, &file->srv->cli); return -1; } - fe->offset += ret; + file->offset += ret; DEBUG(4, (" --> %d\n", ret)); @@ -760,19 +639,18 @@ ssize_t smbc_read(int fd, void *buf, size_t count) * Routine to write() a file ... */ -ssize_t smbc_write(int fd, void *buf, size_t count) +static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { int ret; - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; @@ -788,25 +666,16 @@ ssize_t smbc_write(int fd, void *buf, size_t count) } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe || !fe->file) { - - errno = EBADF; - return -1; - - } - - ret = cli_write(&fe->srv->cli, fe->cli_fd, 0, buf, fe->offset, count); + ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, file->offset, count); if (ret <= 0) { - errno = smbc_errno(&fe->srv->cli); + errno = smbc_errno(context, &file->srv->cli); return -1; } - fe->offset += ret; + file->offset += ret; return ret; /* Success, 0 bytes of data ... */ } @@ -815,75 +684,123 @@ ssize_t smbc_write(int fd, void *buf, size_t count) * Routine to close() a file ... */ -int smbc_close(int fd) +static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { - struct smbc_file *fe; - struct smbc_server *srv; + SMBCSRV *srv; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - fe = smbc_file_table[fd - smbc_start_fd]; + /* IS a dir ... */ + if (!file->file) { + + return context->closedir(context, file); - if (!fe) { + } + + if (!cli_close(&file->srv->cli, file->cli_fd)) { + + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); + /* Deallocate slot and remove the server + * from the server cache if unused */ + errno = smbc_errno(context, &file->srv->cli); + srv = file->srv; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + context->callbacks.remove_unused_server_fn(context, srv); - errno = EBADF; return -1; } - if (!fe->file) { + if (!file->file) { - return smbc_closedir(fd); + return context->closedir(context, file); } - if (!cli_close(&fe->srv->cli, fe->cli_fd)) { - - DEBUG(3, ("cli_close failed on %s (%d). purging server.\n", - fe->fname, fe->smbc_fd)); + if (!cli_close(&file->srv->cli, file->cli_fd)) { + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); /* Deallocate slot and remove the server * from the server cache if unused */ - errno = smbc_errno(&fe->srv->cli); - srv = fe->srv; - SAFE_FREE(fe->fname); - SAFE_FREE(fe); - smbc_file_table[fd - smbc_start_fd] = NULL; - smbc_remove_unused_server(srv); + errno = smbc_errno(context, &file->srv->cli); + srv = file->srv; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + context->callbacks.remove_unused_server_fn(context, srv); return -1; - } - SAFE_FREE(fe->fname); - SAFE_FREE(fe); - smbc_file_table[fd - smbc_start_fd] = NULL; + DLIST_REMOVE(context->_files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); return 0; } +/* + * Get info from an SMB server on a file. Use a qpathinfo call first + * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo + */ +static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, + uint16 *mode, size_t *size, + time_t *c_time, time_t *a_time, time_t *m_time, + SMB_INO_T *ino) +{ + + if (!context || !context->_initialized) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4,("smbc_getatr: sending qpathinfo\n")); + + if (!srv->no_pathinfo2 && + cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, + size, mode, ino)) return True; + + /* if this is NT then don't bother with the getatr */ + if (srv->cli.capabilities & CAP_NT_SMBS) return False; + + if (cli_getatr(&srv->cli, path, mode, size, m_time)) { + a_time = c_time = m_time; + srv->no_pathinfo2 = True; + return True; + } + + return False; + +} + /* * Routine to unlink() a file */ -int smbc_unlink(const char *fname) +static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; - if (!smbc_initialized) { + if (!context || context->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -897,13 +814,13 @@ int smbc_unlink(const char *fname) } - smbc_parse_path(fname, server, share, path, user, password); /* FIXME, check errors */ + smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -913,23 +830,23 @@ int smbc_unlink(const char *fname) /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - int job = smbc_stat_printjob(srv, path, NULL, NULL); - if (job == -1) { + int job = smbc_stat_printjob(srv, path, NULL, NULL); + if (job == -1) { - return -1; + return -1; - } - if ((err = cli_printjob_del(&srv->cli, job)) != 0) { + } + if ((err = cli_printjob_del(&srv->cli, job)) != 0) { - return -1; + return -1; - } - } else */ + } + } else */ if (!cli_unlink(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); if (errno == EACCES) { /* Check if the file is a directory */ @@ -939,12 +856,12 @@ int smbc_unlink(const char *fname) time_t m_time = 0, a_time = 0, c_time = 0; SMB_INO_T ino = 0; - if (!smbc_getatr(srv, path, &mode, &size, + if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { /* Hmmm, bad error ... What? */ - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; } @@ -970,35 +887,37 @@ int smbc_unlink(const char *fname) * Routine to rename() a file */ -int smbc_rename(const char *oname, const char *nname) +static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, + SMBCCTX *ncontext, const char *nname) { fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup; pstring path1, path2; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; - if (!smbc_initialized) { + if (!ocontext || !ncontext || + !ocontext->_initialized || !ncontext->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; } - + if (!oname || !nname) { errno = EINVAL; return -1; } - + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - smbc_parse_path(oname, server1, share1, path1, user1, password1); + smbc_parse_path(ocontext, oname, server1, share1, path1, user1, password1); - if (user1[0] == (char)0) pstrcpy(user1, smbc_user); + if (user1[0] == (char)0) pstrcpy(user1, ocontext->user); - smbc_parse_path(nname, server2, share2, path2, user2, password2); + smbc_parse_path(ncontext, nname, server2, share2, path2, user2, password2); - if (user2[0] == (char)0) pstrcpy(user2, smbc_user); + if (user2[0] == (char)0) pstrcpy(user2, ncontext->user); if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { @@ -1010,9 +929,9 @@ int smbc_rename(const char *oname, const char *nname) } - pstrcpy(workgroup, lp_workgroup()); - - srv = smbc_server(server1, share1, workgroup, user1, password1); + pstrcpy(workgroup, ocontext->workgroup); + /* HELP !!! Which workgroup should I use ? Or are they always the same -- Tom */ + srv = smbc_server(ocontext, server1, share1, workgroup, user1, password1); if (!srv) { return -1; @@ -1020,7 +939,7 @@ int smbc_rename(const char *oname, const char *nname) } if (!cli_rename(&srv->cli, path1, path2)) { - int eno = smbc_errno(&srv->cli); + int eno = smbc_errno(ocontext, &srv->cli); if (eno != EEXIST || !cli_unlink(&srv->cli, path2) || @@ -1040,35 +959,25 @@ int smbc_rename(const char *oname, const char *nname) * A routine to lseek() a file */ -off_t smbc_lseek(int fd, off_t offset, int whence) +static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence) { - struct smbc_file *fe; size_t size; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; - - } - - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - + } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - if (!fe->file) { + if (!file->file) { errno = EINVAL; return -1; /* Can't lseek a dir ... */ @@ -1077,23 +986,23 @@ off_t smbc_lseek(int fd, off_t offset, int whence) switch (whence) { case SEEK_SET: - fe->offset = offset; + file->offset = offset; break; case SEEK_CUR: - fe->offset += offset; + file->offset += offset; break; case SEEK_END: - if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, NULL, NULL, NULL) && - !cli_getattrE(&fe->srv->cli, fe->cli_fd, NULL, &size, NULL, NULL, + !cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, NULL)) { errno = EINVAL; return -1; } - fe->offset = size + offset; + file->offset = size + offset; break; default: @@ -1102,7 +1011,7 @@ off_t smbc_lseek(int fd, off_t offset, int whence) } - return fe->offset; + return file->offset; } @@ -1111,9 +1020,16 @@ off_t smbc_lseek(int fd, off_t offset, int whence) */ static -ino_t smbc_inode(const char *name) +ino_t smbc_inode(SMBCCTX *context, const char *name) { + if (!context || !context->_initialized) { + + errno = EINVAL; + return -1; + + } + if (!*name) return 2; /* FIXME, why 2 ??? */ return (ino_t)str_checksum(name); @@ -1125,9 +1041,9 @@ ino_t smbc_inode(const char *name) */ static -int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) +int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, int mode) { - + st->st_mode = 0; if (IS_DOS_DIR(mode)) { @@ -1154,55 +1070,20 @@ int smbc_setup_stat(struct stat *st, char *fname, size_t size, int mode) } if (st->st_ino == 0) { - st->st_ino = smbc_inode(fname); + st->st_ino = smbc_inode(context, fname); } - + return True; /* FIXME: Is this needed ? */ } -/* - * Get info from an SMB server on a file. Use a qpathinfo call first - * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo - */ - -BOOL smbc_getatr(struct smbc_server *srv, char *path, - uint16 *mode, size_t *size, - time_t *c_time, time_t *a_time, time_t *m_time, - SMB_INO_T *ino) -{ - - if (!smbc_initialized) { - - errno = EINVAL; - return -1; - - } - - DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - - if (!srv->no_pathinfo2 && - cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, - size, mode, ino)) return True; - - /* if this is NT then don't bother with the getatr */ - if (srv->cli.capabilities & CAP_NT_SMBS) return False; - - if (cli_getatr(&srv->cli, path, mode, size, m_time)) { - a_time = c_time = m_time; - srv->no_pathinfo2 = True; - return True; - } - return False; -} - /* * Routine to stat a file given a name */ -int smbc_stat(const char *fname, struct stat *st) +static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; time_t m_time = 0, a_time = 0, c_time = 0; @@ -1210,11 +1091,11 @@ int smbc_stat(const char *fname, struct stat *st) uint16 mode = 0; SMB_INO_T ino = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; - + } if (!fname) { @@ -1226,13 +1107,13 @@ int smbc_stat(const char *fname, struct stat *st) DEBUG(4, ("smbc_stat(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -1246,9 +1127,9 @@ int smbc_stat(const char *fname, struct stat *st) } else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - + if (strcmp(path, "\\") == 0) { - + mode = aDIR | aRONLY; } @@ -1261,19 +1142,17 @@ int smbc_stat(const char *fname, struct stat *st) } else { */ - if (!smbc_getatr(srv, path, &mode, &size, + if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; - + } - /* } */ - st->st_ino = ino; - smbc_setup_stat(st, path, size, mode); + smbc_setup_stat(context, st, path, size, mode); st->st_atime = a_time; st->st_ctime = c_time; @@ -1288,46 +1167,36 @@ int smbc_stat(const char *fname, struct stat *st) * Routine to stat a file given an fd */ -int smbc_fstat(int fd, struct stat *st) +static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) { - struct smbc_file *fe; time_t c_time, a_time, m_time; size_t size; uint16 mode; SMB_INO_T ino = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!file || !DLIST_CONTAINS(context->_files, file)) { errno = EBADF; return -1; } - fe = smbc_file_table[fd - smbc_start_fd]; + if (!file->file) { - if (!fe) { - - errno = EBADF; - return -1; - - } - - if (!fe->file) { - - return smbc_fstatdir(fd, st); + return context->fstatdir(context, file, st); } - if (!cli_qfileinfo(&fe->srv->cli, fe->cli_fd, + if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) && - !cli_getattrE(&fe->srv->cli, fe->cli_fd, + !cli_getattrE(&file->srv->cli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time)) { errno = EINVAL; @@ -1337,12 +1206,12 @@ int smbc_fstat(int fd, struct stat *st) st->st_ino = ino; - smbc_setup_stat(st, fe->fname, size, mode); + smbc_setup_stat(context, st, file->fname, size, mode); st->st_atime = a_time; st->st_ctime = c_time; st->st_mtime = m_time; - st->st_dev = fe->srv->dev; + st->st_dev = file->srv->dev; return 0; @@ -1362,7 +1231,7 @@ int smbc_fstat(int fd, struct stat *st) * smb:///share which should list files on share */ -static void smbc_remove_dir(struct smbc_file *dir) +static void smbc_remove_dir(SMBCFILE *dir) { struct smbc_dir_list *d,*f; @@ -1380,7 +1249,7 @@ static void smbc_remove_dir(struct smbc_file *dir) } -static int add_dirent(struct smbc_file *dir, const char *name, const char *comment, uint32 type) +static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint32 type) { struct smbc_dirent *dirent; int size; @@ -1403,6 +1272,11 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme } + ZERO_STRUCTP(dirent); + + ZERO_STRUCTP(dirent); + + if (dir->dir_list == NULL) { dir->dir_list = malloc(sizeof(struct smbc_dir_list)); @@ -1413,6 +1287,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme return -1; } + ZERO_STRUCTP(dir->dir_list); dir->dir_end = dir->dir_next = dir->dir_list; @@ -1420,14 +1295,15 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme else { dir->dir_end->next = malloc(sizeof(struct smbc_dir_list)); - - if (!dir->dir_end) { - + + if (!dir->dir_end->next) { + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; } + ZERO_STRUCTP(dir->dir_end->next); dir->dir_end = dir->dir_end->next; @@ -1435,7 +1311,7 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme dir->dir_end->next = NULL; dir->dir_end->dirent = dirent; - + dirent->smbc_type = type; dirent->namelen = (name?strlen(name):0); dirent->commentlen = (comment?strlen(comment):0); @@ -1453,13 +1329,13 @@ static int add_dirent(struct smbc_file *dir, const char *name, const char *comme static void list_fn(const char *name, uint32 type, const char *comment, void *state) { - struct smbc_file *dir = (struct smbc_file *)state; + SMBCFILE *dir = (SMBCFILE *)state; int dirent_type; /* We need to process the type a little ... */ if (dir->dir_type == SMBC_FILE_SHARE) { - + switch (type) { case 0: /* Directory tree */ dirent_type = SMBC_FILE_SHARE; @@ -1481,6 +1357,7 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ break; } + ZERO_STRUCTP(dir->dir_list); } else dirent_type = dir->dir_type; @@ -1498,113 +1375,103 @@ static void dir_list_fn(file_info *finfo, const char *mask, void *state) { - if (add_dirent((struct smbc_file *)state, finfo->name, "", + if (add_dirent((SMBCFILE *)state, finfo->name, "", (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { /* Handle an error ... */ + /* FIXME: Add some code ... */ } } -int smbc_opendir(const char *fname) +static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; pstring path; - struct smbc_server *srv = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *dir = NULL; struct in_addr rem_ip; int slot = 0; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; - return -1; + return NULL; } if (!fname) { errno = EINVAL; - return -1; + return NULL; } - if (smbc_parse_path(fname, server, share, path, user, password)) { + if (smbc_parse_path(context, fname, server, share, path, user, password)) { errno = EINVAL; - return -1; + return NULL; } - if (user[0] == (char)0) pstrcpy(user, smbc_user); - - pstrcpy(workgroup, lp_workgroup()); - - /* Get a file entry ... */ + if (user[0] == (char)0) pstrcpy(user, context->user); - slot = 0; + pstrcpy(workgroup, context->workgroup); - while (smbc_file_table[slot]) - slot++; + dir = malloc(sizeof(*dir)); - if (slot > SMBC_MAX_FD) { + if (!dir) { errno = ENOMEM; - return -1; /* FIXME, ... move into a func */ - - } - - smbc_file_table[slot] = malloc(sizeof(struct smbc_file)); - - if (!smbc_file_table[slot]) { - - errno = ENOMEM; - return -1; + return NULL; } - smbc_file_table[slot]->cli_fd = 0; - smbc_file_table[slot]->smbc_fd = slot + smbc_start_fd; - smbc_file_table[slot]->fname = strdup(fname); - smbc_file_table[slot]->srv = NULL; - smbc_file_table[slot]->offset = 0; - smbc_file_table[slot]->file = False; - smbc_file_table[slot]->dir_list = - smbc_file_table[slot]->dir_next = - smbc_file_table[slot]->dir_end = NULL; + ZERO_STRUCTP(dir); + + dir->cli_fd = 0; + dir->fname = strdup(fname); + dir->srv = NULL; + dir->offset = 0; + dir->file = False; + dir->dir_list = dir->dir_next = dir->dir_end = NULL; if (server[0] == (char)0) { if (share[0] != (char)0 || path[0] != (char)0) { errno = EINVAL; - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } /* We have server and share and path empty ... so list the workgroups */ + /* first try to get the LMB for our workgroup, and if that fails, */ + /* try the DMB */ - if (!resolve_name(lp_workgroup(), &rem_ip, 0x1d)) { + if (!(resolve_name(context->workgroup, &rem_ip, 0x1d) || + resolve_name(context->workgroup, &rem_ip, 0x1b))) { errno = EINVAL; /* Something wrong with smb.conf? */ - return -1; + return NULL; } - smbc_file_table[slot]->dir_type = SMBC_WORKGROUP; + dir->dir_type = SMBC_WORKGROUP; /* find the name of the server ... */ if (!name_status_find("*", 0, 0, rem_ip, server)) { - DEBUG(0, ("Could not get the name of local master browser for server %s\n", server)); + DEBUG(0,("Could not get the name of local/domain master browser for server %s\n", server)); errno = EINVAL; - return -1; + return NULL; } @@ -1612,31 +1479,34 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(server, "IPC$", workgroup, user, password); + srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + + return NULL; } + ZERO_STRUCTP(dir->dir_end); - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the stuff ... */ if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn, - (void *)smbc_file_table[slot])) { + (void *)dir)) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } errno = cli_errno(&srv->cli); - return -1; + + return NULL; } } @@ -1647,22 +1517,23 @@ int smbc_opendir(const char *fname) if (path[0] != (char)0) { /* Should not have empty share with path */ errno = EINVAL; - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - /* Check to see if <1D> translates, or <20> translates */ + /* Check to see if <1D>, <1B>, or <20> translates */ /* However, we check to see if is an IP address first */ if (!is_ipaddress(server) && /* Not an IP addr so check next */ - resolve_name(server, &rem_ip, 0x1d)) { /* Found LMB */ + (resolve_name(server, &rem_ip, 0x1d) || /* Found LMB */ + resolve_name(server, &rem_ip, 0x1b) )) { /* Found DMB */ pstring buserver; - smbc_file_table[slot]->dir_type = SMBC_SERVER; + dir->dir_type = SMBC_SERVER; /* * Get the backup list ... @@ -1671,9 +1542,9 @@ int smbc_opendir(const char *fname) if (!name_status_find("*", 0, 0, rem_ip, buserver)) { - DEBUG(0, ("Could not get name of local master browser %s\n", server)); + DEBUG(0, ("Could not get name of local/domain master browser for server %s\n", server)); errno = EPERM; /* FIXME, is this correct */ - return -1; + return NULL; } @@ -1681,32 +1552,32 @@ int smbc_opendir(const char *fname) * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(buserver, "IPC$", workgroup, user, password); + srv = smbc_server(context, buserver, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the servers ... */ if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn, - (void *)smbc_file_table[slot])) { + (void *)dir)) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } errno = cli_errno(&srv->cli); - return -1; - + return NULL; + } } @@ -1716,33 +1587,33 @@ int smbc_opendir(const char *fname) /* Now, list the shares ... */ - smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, "IPC$", workgroup, user, password); + srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the servers ... */ if (cli_RNetShareEnum(&srv->cli, list_fn, - (void *)smbc_file_table[slot]) < 0) { + (void *)dir) < 0) { errno = cli_errno(&srv->cli); - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } @@ -1750,11 +1621,11 @@ int smbc_opendir(const char *fname) else { errno = ENODEV; /* Neither the workgroup nor server exists */ - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } @@ -1765,42 +1636,43 @@ int smbc_opendir(const char *fname) /* Well, we connect to the server and list the directory */ - smbc_file_table[slot]->dir_type = SMBC_FILE_SHARE; + dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - return -1; + return NULL; } - smbc_file_table[slot]->srv = srv; + dir->srv = srv; /* Now, list the files ... */ pstrcat(path, "\\*"); if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, - (void *)smbc_file_table[slot]) < 0) { + (void *)dir) < 0) { - if (smbc_file_table[slot]) { - SAFE_FREE(smbc_file_table[slot]->fname); - SAFE_FREE(smbc_file_table[slot]); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); } - errno = smbc_errno(&srv->cli); - return -1; + errno = smbc_errno(context, &srv->cli); + return NULL; } } } - return smbc_file_table[slot]->smbc_fd; + DLIST_ADD(context->_files, dir); + return dir; } @@ -1808,44 +1680,34 @@ int smbc_opendir(const char *fname) * Routine to close a directory */ -int smbc_closedir(int fd) +static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; - + } - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { - - errno = EBADF; - return -1; - - } + smbc_remove_dir(dir); /* Clean it up */ - smbc_remove_dir(fe); /* Clean it up */ + DLIST_REMOVE(context->_files, dir); - if (fe) { + if (dir) { - SAFE_FREE(fe->fname); - SAFE_FREE(fe); /* Free the space too */ + SAFE_FREE(dir->fname); + SAFE_FREE(dir); /* Free the space too */ } - smbc_file_table[fd - smbc_start_fd] = NULL; - return 0; } @@ -1854,50 +1716,38 @@ int smbc_closedir(int fd) * Routine to get a directory entry */ -static char smbc_local_dirent[512]; /* Make big enough */ - -struct smbc_dirent *smbc_readdir(unsigned int fd) +struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; struct smbc_dirent *dirp, *dirent; /* Check that all is ok first ... */ - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return NULL; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return NULL; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return NULL; } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return NULL; } - if (!fe->dir_next) + if (!dir->dir_next) return NULL; else { - dirent = fe->dir_next->dirent; + dirent = dir->dir_next->dirent; if (!dirent) { @@ -1908,15 +1758,12 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) /* Hmmm, do I even need to copy it? */ - memcpy(smbc_local_dirent, dirent, dirent->dirlen); /* Copy the dirent */ - - dirp = (struct smbc_dirent *)smbc_local_dirent; - + memcpy(context->_dirent, dirent, dirent->dirlen); /* Copy the dirent */ + dirp = (struct smbc_dirent *)context->_dirent; dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); - - fe->dir_next = fe->dir_next->next; + dir->dir_next = dir->dir_next->next; - return (struct smbc_dirent *)smbc_local_dirent; + return (struct smbc_dirent *)context->_dirent; } } @@ -1925,39 +1772,29 @@ struct smbc_dirent *smbc_readdir(unsigned int fd) * Routine to get directory entries */ -int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) +static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent *dirp, int count) { - struct smbc_file *fe; - struct smbc_dir_list *dir; + struct smbc_dir_list *dirlist; int rem = count, reqd; char *ndir = (char *)dirp; /* Check that all is ok first ... */ - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; - + } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; @@ -1970,18 +1807,18 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) * send a request to the server to get the info. */ - while ((dir = fe->dir_next)) { + while ((dirlist = dir->dir_next)) { struct smbc_dirent *dirent; - if (!dir->dirent) { + if (!dirlist->dirent) { errno = ENOENT; /* Bad error */ return -1; } - if (rem < (reqd = (sizeof(struct smbc_dirent) + dir->dirent->namelen + - dir->dirent->commentlen + 1))) { + if (rem < (reqd = (sizeof(struct smbc_dirent) + dirlist->dirent->namelen + + dirlist->dirent->commentlen + 1))) { if (rem < count) { /* We managed to copy something */ @@ -1998,7 +1835,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) } - dirent = dir->dirent; + dirent = dirlist->dirent; memcpy(ndir, dirent, reqd); /* Copy the data in ... */ @@ -2009,7 +1846,7 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) rem -= reqd; - fe->dir_next = dir = dir -> next; + dir->dir_next = dirlist = dirlist -> next; } if (rem == count) @@ -2023,13 +1860,13 @@ int smbc_getdents(unsigned int fd, struct smbc_dirent *dirp, int count) * Routine to create a directory ... */ -int smbc_mkdir(const char *fname, mode_t mode) +static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2045,13 +1882,13 @@ int smbc_mkdir(const char *fname, mode_t mode) DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2082,7 +1919,7 @@ int smbc_mkdir(const char *fname, mode_t mode) if (!cli_mkdir(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); return -1; } @@ -2109,13 +1946,13 @@ static void rmdir_list_fn(file_info *finfo, const char *mask, void *state) * Routine to remove a directory */ -int smbc_rmdir(const char *fname) +static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2131,13 +1968,13 @@ int smbc_rmdir(const char *fname) DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2162,13 +1999,13 @@ int smbc_rmdir(const char *fname) mode = aRONLY; smbc_stat_printjob(srv, path, &size, &m_time); c_time = a_time = m_time; - + } else { */ if (!cli_rmdir(&srv->cli, path)) { - errno = smbc_errno(&srv->cli); + errno = smbc_errno(context, &srv->cli); if (errno == EACCES) { /* Check if the dir empty or not */ @@ -2185,7 +2022,7 @@ int smbc_rmdir(const char *fname) /* Fix errno to ignore latest error ... */ DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n", - smbc_errno(&srv->cli))); + smbc_errno(context, &srv->cli))); errno = EACCES; } @@ -2209,41 +2046,31 @@ int smbc_rmdir(const char *fname) * Routine to return the current directory position */ -off_t smbc_telldir(int fd) +static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { - struct smbc_file *fe; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { + if (!dir || !DLIST_CONTAINS(context->_files, dir)) { errno = EBADF; return -1; } - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; } - return (off_t) fe->dir_next; + return (off_t) dir->dir_next; } @@ -2281,36 +2108,19 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, * Routine to seek on a directory */ -int smbc_lseekdir(int fd, off_t offset) +static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) { - struct smbc_file *fe; struct smbc_dirent *dirent = (struct smbc_dirent *)offset; struct smbc_dir_list *list_ent = NULL; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; } - if (fd < smbc_start_fd || fd >= (smbc_start_fd + SMBC_MAX_FD)) { - - errno = EBADF; - return -1; - - } - - fe = smbc_file_table[fd - smbc_start_fd]; - - if (!fe) { - - errno = EBADF; - return -1; - - } - - if (fe->file != False) { /* FIXME, should be dir, perhaps */ + if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; return -1; @@ -2321,7 +2131,7 @@ int smbc_lseekdir(int fd, off_t offset) if (dirent == NULL) { /* Seek to the begining of the list */ - fe->dir_next = fe->dir_list; + dir->dir_next = dir->dir_list; return 0; } @@ -2329,14 +2139,14 @@ int smbc_lseekdir(int fd, off_t offset) /* Now, run down the list and make sure that the entry is OK */ /* This may need to be changed if we change the format of the list */ - if ((list_ent = smbc_check_dir_ent(fe->dir_list, dirent)) == NULL) { + if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) { errno = EINVAL; /* Bad entry */ return -1; } - fe->dir_next = list_ent; + dir->dir_next = list_ent; return 0; @@ -2346,10 +2156,10 @@ int smbc_lseekdir(int fd, off_t offset) * Routine to fstat a dir */ -int smbc_fstatdir(int fd, struct stat *st) +static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) { - if (!smbc_initialized) { + if (context || !context->_initialized) { errno = EINVAL; return -1; @@ -2362,6 +2172,39 @@ int smbc_fstatdir(int fd, struct stat *st) } +/* + * Open a print file to be written to by other calls + */ + +static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) +{ + fstring server, share, user, password; + pstring path; + + if (!context || context->_initialized) { + + errno = EINVAL; + return NULL; + + } + + if (!fname) { + + errno = EINVAL; + return NULL; + + } + + DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + /* What if the path is empty, or the file exists? */ + + return context->open(context, fname, O_WRONLY, 666); + +} + /* * Routine to print a file on a remote server ... * @@ -2369,12 +2212,14 @@ int smbc_fstatdir(int fd, struct stat *st) * copy it to a print file on the share specified by printq. */ -int smbc_print_file(const char *fname, const char *printq) +static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq) { - int fid1, fid2, bytes, saverr, tot_bytes = 0; + SMBCFILE *fid1, *fid2; + int bytes, saverr, tot_bytes = 0; char buf[4096]; - if (!smbc_initialized) { + if (!c_file || !c_file->_initialized || !c_print || + !c_print->_initialized) { errno = EINVAL; return -1; @@ -2390,33 +2235,33 @@ int smbc_print_file(const char *fname, const char *printq) /* Try to open the file for reading ... */ - if ((fid1 = smbc_open(fname, O_RDONLY, 0666)) < 0) { - + if ((fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { + DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); return -1; /* smbc_open sets errno */ - + } /* Now, try to open the printer file for writing */ - if ((fid2 = smbc_open_print_job(printq)) < 0) { + if ((fid2 = c_print->open_print_job(c_print, printq)) < 0) { saverr = errno; /* Save errno */ - smbc_close(fid1); + c_file->close(c_file, fid1); errno = saverr; return -1; } - while ((bytes = smbc_read(fid1, buf, sizeof(buf))) > 0) { + while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) { tot_bytes += bytes; - if ((smbc_write(fid2, buf, bytes)) < 0) { + if ((c_print->write(c_print, fid2, buf, bytes)) < 0) { saverr = errno; - smbc_close(fid1); - smbc_close(fid2); + c_file->close(c_file, fid1); + c_print->close(c_print, fid2); errno = saverr; } @@ -2425,8 +2270,8 @@ int smbc_print_file(const char *fname, const char *printq) saverr = errno; - smbc_close(fid1); /* We have to close these anyway */ - smbc_close(fid2); + c_file->close(c_file, fid1); /* We have to close these anyway */ + c_print->close(c_print, fid2); if (bytes < 0) { @@ -2440,15 +2285,16 @@ int smbc_print_file(const char *fname, const char *printq) } /* - * Open a print file to be written to by other calls + * Routine to list print jobs on a printer share ... */ -int smbc_open_print_job(const char *fname) +static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, void (*fn)(struct print_job_info *)) { - fstring server, share, user, password; + SMBCSRV *srv; + fstring server, share, user, password, workgroup; pstring path; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2456,33 +2302,51 @@ int smbc_open_print_job(const char *fname) } if (!fname) { - + errno = EINVAL; return -1; } - DEBUG(4, ("smbc_open_print_job(%s)\n", fname)); + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - /* What if the path is empty, or the file exists? */ + if (user[0] == (char)0) pstrcpy(user, context->user); + + pstrcpy(workgroup, context->workgroup); + + srv = smbc_server(context, server, share, workgroup, user, password); + + if (!srv) { - return smbc_open(fname, O_WRONLY, 666); + return -1; /* errno set by smbc_server */ + + } + + if (cli_print_queue(&srv->cli, fn) < 0) { + + errno = smbc_errno(context, &srv->cli); + return -1; + + } + + return 0; } /* - * Routine to list print jobs on a printer share ... + * Delete a print job from a remote printer share */ -int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) +static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id) { - struct smbc_server *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; + int err; - if (!smbc_initialized) { + if (!context || !context->_initialized) { errno = EINVAL; return -1; @@ -2496,15 +2360,15 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } - DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (user[0] == (char)0) pstrcpy(user, context->user); - pstrcpy(workgroup, lp_workgroup()); + pstrcpy(workgroup, context->workgroup); - srv = smbc_server(server, share, workgroup, user, password); + srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { @@ -2512,9 +2376,12 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } - if (cli_print_queue(&srv->cli, fn) < 0) { + if ((err = cli_printjob_del(&srv->cli, id)) != 0) { - errno = smbc_errno(&srv->cli); + if (err < 0) + errno = smbc_errno(context, &srv->cli); + else if (err == ERRnosuchprintjob) + errno = EINVAL; return -1; } @@ -2524,58 +2391,252 @@ int smbc_list_print_jobs(const char *fname, void (*fn)(struct print_job_info *)) } /* - * Delete a print job from a remote printer share + * Get a new empty handle to fill in with your own info */ +SMBCCTX * smbc_new_context(void) +{ + SMBCCTX * context; -int smbc_unlink_print_job(const char *fname, int id) + context = malloc(sizeof(*context)); + if (!context) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context); + + /* ADD REASONABLE DEFAULTS */ + context->debug = 0; + context->timeout = 20000; /* 20 seconds */ + + context->open = smbc_open_ctx; + context->creat = smbc_creat_ctx; + context->read = smbc_read_ctx; + context->write = smbc_write_ctx; + context->close = smbc_close_ctx; + context->unlink = smbc_unlink_ctx; + context->rename = smbc_rename_ctx; + context->lseek = smbc_lseek_ctx; + context->stat = smbc_stat_ctx; + context->fstat = smbc_fstat_ctx; + context->opendir = smbc_opendir_ctx; + context->closedir = smbc_closedir_ctx; + context->readdir = smbc_readdir_ctx; + context->getdents = smbc_getdents_ctx; + context->mkdir = smbc_mkdir_ctx; + context->rmdir = smbc_rmdir_ctx; + context->telldir = smbc_telldir_ctx; + context->lseekdir = smbc_lseekdir_ctx; + context->fstatdir = smbc_fstatdir_ctx; + context->open_print_job = smbc_open_print_job_ctx; + context->print_file = smbc_print_file_ctx; + context->list_print_jobs = smbc_list_print_jobs_ctx; + context->unlink_print_job = smbc_unlink_print_job_ctx; + + context->callbacks.check_server_fn = smbc_check_server; + context->callbacks.remove_unused_server_fn = smbc_remove_unused_server; + + smbc_default_cache_functions(context); + + return context; +} + +/* + * Free a context + * + * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed + * and thus you'll be leaking memory if not handled properly. + * + */ +int smbc_free_context(SMBCCTX * context, int shutdown_ctx) { - struct smbc_server *srv; - fstring server, share, user, password, workgroup; - pstring path; - int err; + if (!context) { + errno = EBADF; + return 1; + } + + if (shutdown_ctx) { + SMBCFILE * f; + DEBUG(1,("Performing aggressive shutdown.\n")); + + f = context->_files; + while (f) { + context->close(context, f); + f = f->next; + } + context->_files = NULL; + + /* First try to remove the servers the nice way. */ + if (context->callbacks.purge_cached_fn(context)) { + SMBCSRV * s; + DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); + s = context->_servers; + while (s) { + cli_shutdown(&s->cli); + context->callbacks.remove_cached_srv_fn(context, s); + SAFE_FREE(s); + s = s->next; + } + context->_servers = NULL; + } + } + else { + /* This is the polite way */ + if (context->callbacks.purge_cached_fn(context)) { + DEBUG(1, ("Could not purge all servers, free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->_servers) { + DEBUG(1, ("Active servers in context, free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->_files) { + DEBUG(1, ("Active files in context, free_context failed.\n")); + errno = EBUSY; + return 1; + } + } - if (!smbc_initialized) { + /* Things we have to clean up */ + SAFE_FREE(context->workgroup); + SAFE_FREE(context->netbios_name); + SAFE_FREE(context->user); + + DEBUG(3, ("Context %p succesfully freed\n", context)); + SAFE_FREE(context); + return 0; +} - errno = EINVAL; - return -1; +/* + * Initialise the library etc + * + * We accept a struct containing handle information. + * valid values for info->debug from 0 to 100, + * and insist that info->fn must be non-null. + */ +SMBCCTX * smbc_init_context(SMBCCTX * context) +{ + pstring conf; + int pid; + char *user = NULL, *home = NULL; + + if (!context) { + errno = EBADF; + return NULL; } - if (!fname) { + /* Do not initialise the same client twice */ + if (context->_initialized) { + return 0; + } + + if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) { errno = EINVAL; - return -1; + return NULL; } - - DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - - smbc_parse_path(fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, smbc_user); + if (!smbc_initialized) { + /* Do some library wide intialisations the first time we get called */ - pstrcpy(workgroup, lp_workgroup()); + /* Do we still need this ? */ + DEBUGLEVEL = 10; + + setup_logging( "libsmbclient", False); - srv = smbc_server(server, share, workgroup, user, password); + /* Here we would open the smb.conf file if needed ... */ + + home = getenv("HOME"); - if (!srv) { + slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); + + load_interfaces(); /* Load the list of interfaces ... */ + + in_client = True; /* FIXME, make a param */ - return -1; /* errno set by smbc_server */ + if (!lp_load(conf, True, False, False)) { - } + /* + * Hmmm, what the hell do we do here ... we could not parse the + * config file ... We must return an error ... and keep info around + * about why we failed + */ + + errno = ENOENT; /* FIXME: Figure out the correct error response */ + return NULL; + } - if ((err = cli_printjob_del(&srv->cli, id)) != 0) { + reopen_logs(); /* Get logging working ... */ + + /* + * Block SIGPIPE (from lib/util_sock.c: write()) + * It is not needed and should not stop execution + */ + BlockSignals(True, SIGPIPE); + + /* Done with one-time initialisation */ + smbc_initialized = 1; - if (err < 0) - errno = smbc_errno(&srv->cli); - else if (err == ERRnosuchprintjob) - errno = EINVAL; - return -1; + } + + if (!context->user) { + /* + * FIXME: Is this the best way to get the user info? + */ + user = getenv("USER"); + /* walk around as "guest" if no username can be found */ + if (!user) context->user = strdup("guest"); + else context->user = strdup(user); + } + if (!context->netbios_name) { + /* + * We try to get our netbios name from the config. If that fails we fall + * back on constructing our netbios name from our hostname etc + */ + if (global_myname) { + context->netbios_name = strdup(global_myname); + } + else { + /* + * Hmmm, I want to get hostname as well, but I am too lazy for the moment + */ + pid = sys_getpid(); + context->netbios_name = malloc(17); + if (!context->netbios_name) { + errno = ENOMEM; + return NULL; + } + slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); + } + } + DEBUG(0,("Using netbios name %s.\n", context->netbios_name)); + + if (!context->workgroup) { + if (lp_workgroup()) { + context->workgroup = strdup(lp_workgroup()); + } + else { + /* TODO: Think about a decent default workgroup */ + context->workgroup = strdup("samba"); + } } + DEBUG(0,("Using workgroup %s.\n", context->workgroup)); + + /* shortest timeout is 1 second */ + if (context->timeout > 0 && context->timeout < 1000) + context->timeout = 1000; - return 0; + /* + * FIXME: Should we check the function pointers here? + */ + context->_initialized = 1; + + return context; } - diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7928d44652..18564bccf4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -191,7 +191,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii(name, status[i].name, 15, 0, STR_TERMINATE); + pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE); result = True; done: @@ -207,257 +207,233 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t return result; } -/**************************************************************************** - Do a NetBIOS name registation to try to claim a name ... -***************************************************************************/ -BOOL name_register(int fd, const char *name, int name_type, - struct in_addr name_ip, int opcode, - BOOL bcast, - struct in_addr to_ip, int *count) -{ - int retries = 3; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - struct in_addr register_ip; - - DEBUG(4, ("name_register: %s as %s on %s\n", name, inet_ntoa(name_ip), inet_ntoa(to_ip))); - - register_ip.s_addr = name_ip.s_addr; /* Fix this ... */ - - memset((char *)&p, '\0', sizeof(p)); - - *count = 0; - - nmb->header.name_trn_id = generate_trn_id(); - nmb->header.opcode = opcode; - nmb->header.response = False; - nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = True; /* ? */ - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = True; - - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 1; - - make_nmb_name(&nmb->question.question_name, name, name_type); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - /* Now, create the additional stuff for a registration request */ - - if ((nmb->additional = (struct res_rec *)malloc(sizeof(struct res_rec))) == NULL) { - - DEBUG(0, ("name_register: malloc fail for additional record.\n")); - return False; - } - - memset((char *)nmb->additional, '\0', sizeof(struct res_rec)); - - nmb->additional->rr_name = nmb->question.question_name; - nmb->additional->rr_type = RR_TYPE_NB; - nmb->additional->rr_class = RR_CLASS_IN; - - /* See RFC 1002, sections 5.1.1.1, 5.1.1.2 and 5.1.1.3 */ - if (nmb->header.nm_flags.bcast) - nmb->additional->ttl = PERMANENT_TTL; - else - nmb->additional->ttl = lp_max_ttl(); - - nmb->additional->rdlength = 6; - - nmb->additional->rdata[0] = NB_MFLAG & 0xFF; - - /* Set the address for the name we are registering. */ - putip(&nmb->additional->rdata[2], ®ister_ip); - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); +/* + comparison function used by sort_ip_list +*/ +static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +{ + int max_bits1=0, max_bits2=0; + int num_interfaces = iface_count(); + int i; - if (!send_packet(&p)) - return False; + for (i=0;is_addr, (uchar *)&ip.s_addr); + bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr); + max_bits1 = MAX(bits1, max_bits1); + max_bits2 = MAX(bits2, max_bits2); + } + + /* bias towards directly reachable IPs */ + if (iface_local(*ip1)) { + max_bits1 += 32; + } + if (iface_local(*ip2)) { + max_bits2 += 32; + } - retries--; + return max_bits2 - max_bits1; +} - if ((p2 = receive_nmb_packet(fd, 10, nmb->header.name_trn_id))) { - debug_nmb_packet(p2); - SAFE_FREE(p2); /* No memory leaks ... */ - } +/* + sort an IP list so that names that are close to one of our interfaces + are at the top. This prevents the problem where a WINS server returns an IP that + is not reachable from our subnet as the first match +*/ +static void sort_ip_list(struct in_addr *iplist, int count) +{ + if (count <= 1) { + return; + } - return True; + qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); } + /**************************************************************************** Do a netbios name query to find someones IP. Returns an array of IP addresses or NULL if none. *count will be set to the number of addresses returned. + *timed_out is set if we failed by timing out ****************************************************************************/ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, - struct in_addr to_ip, int *count) + struct in_addr to_ip, int *count, int *flags, + BOOL *timed_out) { - BOOL found=False; - int i, retries = 3; - int retry_time = bcast?250:2000; - struct timeval tval; - struct packet_struct p; - struct packet_struct *p2; - struct nmb_packet *nmb = &p.packet.nmb; - struct in_addr *ip_list = NULL; - - memset((char *)&p,'\0',sizeof(p)); - (*count) = 0; - - nmb->header.name_trn_id = generate_trn_id(); - nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; - nmb->header.rcode = 0; - nmb->header.qdcount = 1; - nmb->header.ancount = 0; - nmb->header.nscount = 0; - nmb->header.arcount = 0; - - make_nmb_name(&nmb->question.question_name,name,name_type); - - nmb->question.question_type = 0x20; - nmb->question.question_class = 0x1; - - p.ip = to_ip; - p.port = NMB_PORT; - p.fd = fd; - p.timestamp = time(NULL); - p.packet_type = NMB_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) - return NULL; - - retries--; + BOOL found=False; + int i, retries = 3; + int retry_time = bcast?250:2000; + struct timeval tval; + struct packet_struct p; + struct packet_struct *p2; + struct nmb_packet *nmb = &p.packet.nmb; + struct in_addr *ip_list = NULL; + if (timed_out) { + *timed_out = False; + } + + memset((char *)&p,'\0',sizeof(p)); + (*count) = 0; + (*flags) = 0; + + nmb->header.name_trn_id = generate_trn_id(); + nmb->header.opcode = 0; + nmb->header.response = False; + nmb->header.nm_flags.bcast = bcast; + nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_desired = recurse; + nmb->header.nm_flags.trunc = False; + nmb->header.nm_flags.authoritative = False; + nmb->header.rcode = 0; + nmb->header.qdcount = 1; + nmb->header.ancount = 0; + nmb->header.nscount = 0; + nmb->header.arcount = 0; + + make_nmb_name(&nmb->question.question_name,name,name_type); + + nmb->question.question_type = 0x20; + nmb->question.question_class = 0x1; + + p.ip = to_ip; + p.port = NMB_PORT; + p.fd = fd; + p.timestamp = time(NULL); + p.packet_type = NMB_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) + return NULL; + + retries--; + while (1) { - struct timeval tval2; - struct in_addr *tmp_ip_list; - - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!found && !send_packet(&p)) - return NULL; - GetTimeOfDay(&tval); - retries--; - } - - if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { - struct nmb_packet *nmb2 = &p2->packet.nmb; - debug_nmb_packet(p2); - - /* If we get a Negative Name Query Response from a WINS - * server, we should report it and give up. - */ - if( 0 == nmb2->header.opcode /* A query response */ - && !(bcast) /* from a WINS server */ - && nmb2->header.rcode /* Error returned */ - ) { - - if( DEBUGLVL( 3 ) ) { - /* Only executed if DEBUGLEVEL >= 3 */ + struct timeval tval2; + struct in_addr *tmp_ip_list; + + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!found && !send_packet(&p)) + return NULL; + GetTimeOfDay(&tval); + retries--; + } + + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { + struct nmb_packet *nmb2 = &p2->packet.nmb; + debug_nmb_packet(p2); + + /* If we get a Negative Name Query Response from a WINS + * server, we should report it and give up. + */ + if( 0 == nmb2->header.opcode /* A query response */ + && !(bcast) /* from a WINS server */ + && nmb2->header.rcode /* Error returned */ + ) { + + if( DEBUGLVL( 3 ) ) { + /* Only executed if DEBUGLEVEL >= 3 */ dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode ); - switch( nmb2->header.rcode ) { - case 0x01: - dbgtext( "Request was invalidly formatted.\n" ); - break; - case 0x02: - dbgtext( "Problem with NBNS, cannot process name.\n"); - break; - case 0x03: - dbgtext( "The name requested does not exist.\n" ); - break; - case 0x04: - dbgtext( "Unsupported request error.\n" ); - break; - case 0x05: - dbgtext( "Query refused error.\n" ); - break; - default: - dbgtext( "Unrecognized error code.\n" ); - break; - } - } - free_packet(p2); - return( NULL ); - } - - if (nmb2->header.opcode != 0 || - nmb2->header.nm_flags.bcast || - nmb2->header.rcode || - !nmb2->header.ancount) { - /* - * XXXX what do we do with this? Could be a - * redirect, but we'll discard it for the + switch( nmb2->header.rcode ) { + case 0x01: + dbgtext( "Request was invalidly formatted.\n" ); + break; + case 0x02: + dbgtext( "Problem with NBNS, cannot process name.\n"); + break; + case 0x03: + dbgtext( "The name requested does not exist.\n" ); + break; + case 0x04: + dbgtext( "Unsupported request error.\n" ); + break; + case 0x05: + dbgtext( "Query refused error.\n" ); + break; + default: + dbgtext( "Unrecognized error code.\n" ); + break; + } + } + free_packet(p2); + return( NULL ); + } + + if (nmb2->header.opcode != 0 || + nmb2->header.nm_flags.bcast || + nmb2->header.rcode || + !nmb2->header.ancount) { + /* + * XXXX what do we do with this? Could be a + * redirect, but we'll discard it for the * moment. */ - free_packet(p2); - continue; - } - - tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] ) - * ( (*count) + nmb2->answers->rdlength/6 ) ); - - if (!tmp_ip_list) { - DEBUG(0,("name_query: Realloc failed.\n")); - SAFE_FREE(ip_list); - } - - ip_list = tmp_ip_list; - - if (ip_list) { + free_packet(p2); + continue; + } + + tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] ) + * ( (*count) + nmb2->answers->rdlength/6 ) ); + + if (!tmp_ip_list) { + DEBUG(0,("name_query: Realloc failed.\n")); + SAFE_FREE(ip_list); + } + + ip_list = tmp_ip_list; + + if (ip_list) { DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); - for (i=0;ianswers->rdlength/6;i++) { - putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); - (*count)++; - } - DEBUGADD(2,(")\n")); - } + for (i=0;ianswers->rdlength/6;i++) { + putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); + DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); + (*count)++; + } + DEBUGADD(2,(")\n")); + } + + found=True; + retries=0; + /* We add the flags back ... */ + if (nmb2->header.response) + (*flags) |= NM_FLAGS_RS; + if (nmb2->header.nm_flags.authoritative) + (*flags) |= NM_FLAGS_AA; + if (nmb2->header.nm_flags.trunc) + (*flags) |= NM_FLAGS_TC; + if (nmb2->header.nm_flags.recursion_desired) + (*flags) |= NM_FLAGS_RD; + if (nmb2->header.nm_flags.recursion_available) + (*flags) |= NM_FLAGS_RA; + if (nmb2->header.nm_flags.bcast) + (*flags) |= NM_FLAGS_B; + free_packet(p2); + /* + * If we're doing a unicast lookup we only + * expect one reply. Don't wait the full 2 + * seconds if we got one. JRA. + */ + if(!bcast && found) + break; + } + } - found=True; - retries=0; - free_packet(p2); - /* - * If we're doing a unicast lookup we only - * expect one reply. Don't wait the full 2 - * seconds if we got one. JRA. - */ - if(!bcast && found) - break; - } - } + if (timed_out) { + *timed_out = True; + } - /* Reach here if we've timed out waiting for replies.. */ - if( !bcast && !found ) { - /* Timed out wating for WINS server to respond. Mark it dead. */ - wins_srv_died( to_ip ); - } + /* sort the ip list so we choose close servers first if possible */ + sort_ip_list(ip_list, *count); - return ip_list; + return ip_list; } /******************************************************** @@ -569,75 +545,6 @@ void endlmhosts(XFILE *fp) x_fclose(fp); } -BOOL name_register_wins(const char *name, int name_type) -{ - int sock, i, return_count; - int num_interfaces = iface_count(); - struct in_addr sendto_ip; - - /* - * Check if we have any interfaces, prevents a segfault later - */ - - if (num_interfaces <= 0) - return False; /* Should return some indication of the problem */ - - /* - * Do a broadcast register ... - */ - - if (0 == wins_srv_count()) - return False; - - if( DEBUGLVL( 4 ) ) - { - dbgtext( "name_register_wins: Registering my name %s ", name ); - dbgtext( "with WINS server %s.\n", wins_srv_name() ); - } - - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr("0.0.0.0"), True ); - - if (sock == -1) return False; - - set_socket_options(sock, "SO_BROADCAST"); /* ????! crh */ - - sendto_ip = wins_srv_ip(); - - if (num_interfaces > 1) { - - for (i = 0; i < num_interfaces; i++) { - - if (!name_register(sock, name, name_type, *iface_n_ip(i), - NMB_NAME_MULTIHOMED_REG_OPCODE, - True, sendto_ip, &return_count)) { - - close(sock); - return False; - - } - - } - - } - else { - - if (!name_register(sock, name, name_type, *iface_n_ip(0), - NMB_NAME_REG_OPCODE, - True, sendto_ip, &return_count)) { - - close(sock); - return False; - - } - - } - - close(sock); - - return True; - -} /******************************************************** Resolve via "bcast" method. @@ -670,10 +577,11 @@ BOOL name_resolve_bcast(const char *name, int name_type, */ for( i = num_interfaces-1; i >= 0; i--) { struct in_addr sendto_ip; + int flags; /* Done this way to fix compiler error on IRIX 5.x */ sendto_ip = *iface_n_bcast(i); *return_ip_list = name_query(sock, name, name_type, True, - True, sendto_ip, return_count); + True, sendto_ip, return_count, &flags, NULL); if(*return_ip_list != NULL) { close(sock); return True; @@ -687,62 +595,88 @@ BOOL name_resolve_bcast(const char *name, int name_type, /******************************************************** Resolve via "wins" method. *********************************************************/ - -static BOOL resolve_wins(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) +BOOL resolve_wins(const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) { - int sock; - struct in_addr wins_ip; - BOOL wins_ismyip; + int sock, t, i; + char **wins_tags; + struct in_addr src_ip; *return_iplist = NULL; *return_count = 0; - /* - * "wins" means do a unicast lookup to the WINS server. - * Ignore if there is no WINS server specified or if the - * WINS server is one of our interfaces (if we're being - * called from within nmbd - we can't do this call as we - * would then block). - */ - DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); - if (lp_wins_support()) { - /* - * We're providing WINS support. Call ourselves so - * long as we're not nmbd. - */ - extern struct in_addr loopback_ip; - wins_ip = loopback_ip; - wins_ismyip = True; - } else if( wins_srv_count() < 1 ) { + if (wins_srv_count() < 1) { DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); return False; - } else { - wins_ip = wins_srv_ip(); - wins_ismyip = ismyip(wins_ip); } - DEBUG(3, ("resolve_wins: WINS server == <%s>\n", inet_ntoa(wins_ip)) ); - if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) { - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()), - True ); - if (sock != -1) { - *return_iplist = name_query( sock, name, - name_type, False, - True, wins_ip, - return_count); - if(*return_iplist != NULL) { - close(sock); - return True; + /* we try a lookup on each of the WINS tags in turn */ + wins_tags = wins_srv_tags(); + + if (!wins_tags) { + /* huh? no tags?? give up in disgust */ + return False; + } + + /* the address we will be sending from */ + src_ip = *interpret_addr2(lp_socket_address()); + + /* in the worst case we will try every wins server with every + tag! */ + for (t=0; wins_tags && wins_tags[t]; t++) { + int srv_count = wins_srv_count_tag(wins_tags[t]); + for (i=0; ipassword , '\0', sizeof(pwd->password )); memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd)); @@ -38,89 +38,21 @@ void pwd_init(struct pwd_info *pwd) } /**************************************************************************** - Returns NULL password flag. -****************************************************************************/ - -BOOL pwd_is_nullpwd(const struct pwd_info *pwd) -{ - return pwd->null_pwd; -} - -/**************************************************************************** - Compares two passwords. hmm, not as trivial as expected. hmm. -****************************************************************************/ - -BOOL pwd_compare(const struct pwd_info *pwd1, const struct pwd_info *pwd2) -{ - if (pwd1->cleartext && pwd2->cleartext) { - if (strequal(pwd1->password, pwd2->password)) - return True; - } - if (pwd1->null_pwd && pwd2->null_pwd) - return True; - - if (!pwd1->null_pwd && !pwd2->null_pwd && - !pwd1->cleartext && !pwd2->cleartext) { -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd compare: nt#\n")); - dump_data(100, pwd1->smb_nt_pwd, 16); - dump_data(100, pwd2->smb_nt_pwd, 16); -#endif - if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0) - return True; -#ifdef DEBUG_PASSWORD - DEBUG(100,("pwd compare: lm#\n")); - dump_data(100, pwd1->smb_lm_pwd, 16); - dump_data(100, pwd2->smb_lm_pwd, 16); -#endif - if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0) - return True; - } - return False; -} - -/**************************************************************************** - Reads a password. + Makes lm and nt hashed passwords. ****************************************************************************/ -void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt) +static void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) { - /* grab a password */ - char *user_pass; + pstring dos_passwd; pwd_init(pwd); - user_pass = (char*)getpass(passwd_report); - - /* - * Do not assume that an empty string is a NULL password. - * If you do this will break the session key generation for - * and account with an emtpy password. If you wish to use - * a NULL password, use the -N option to smbclient and rpcclient - * --jerry - */ -#if 0 - if (user_pass == NULL || user_pass[0] == 0) - pwd_set_nullpwd(pwd); - else if (do_encrypt) -#endif - if (do_encrypt) - pwd_make_lm_nt_16(pwd, user_pass); - else - pwd_set_cleartext(pwd, user_pass); -} - -/**************************************************************************** - Stores a cleartext password. -****************************************************************************/ - -void pwd_set_nullpwd(struct pwd_info *pwd) -{ - pwd_init(pwd); + push_ascii_pstring(dos_passwd, clr); + nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pwd->null_pwd = False; pwd->cleartext = False; - pwd->null_pwd = True; - pwd->crypted = False; + pwd->crypted = False; } /**************************************************************************** @@ -141,7 +73,7 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr) Gets a cleartext password. ****************************************************************************/ -void pwd_get_cleartext(struct pwd_info *pwd, char *clr) +void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) { if (pwd->cleartext) fstrcpy(clr, pwd->password); @@ -150,29 +82,6 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr) } -/**************************************************************************** - Stores lm and nt hashed passwords. -****************************************************************************/ - -void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) -{ - pwd_init(pwd); - - if (lm_pwd) - memcpy(pwd->smb_lm_pwd, lm_pwd, 16); - else - memset((char *)pwd->smb_lm_pwd, '\0', 16); - - if (nt_pwd) - memcpy(pwd->smb_nt_pwd, nt_pwd, 16); - else - memset((char *)pwd->smb_nt_pwd, '\0', 16); - - pwd->null_pwd = False; - pwd->cleartext = False; - pwd->crypted = False; -} - /**************************************************************************** Gets lm and nt hashed passwords. ****************************************************************************/ @@ -185,24 +94,6 @@ void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) memcpy(nt_pwd, pwd->smb_nt_pwd, 16); } -/**************************************************************************** - Makes lm and nt hashed passwords. -****************************************************************************/ - -void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) -{ - pstring dos_passwd; - - pwd_init(pwd); - - push_ascii_pstring(dos_passwd, clr); - - nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); - pwd->null_pwd = False; - pwd->cleartext = False; - pwd->crypted = False; -} - /**************************************************************************** Makes lm and nt OWF crypts. ****************************************************************************/ @@ -247,3 +138,13 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) if (nt_owf != NULL) memcpy(nt_owf, pwd->smb_nt_owf, 24); } + + + + + + + + + + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6fa8de418a..95434d0ae4 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -26,18 +26,14 @@ /* This implements the X/Open SMB password encryption - It takes a password, a 8 byte "crypt key" and puts 24 bytes of - encrypted password into p24 */ -void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) + It takes a password ('unix' string), a 8 byte "crypt key" + and puts 24 bytes of encrypted password into p24 */ +void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24) { - uchar p14[15], p21[21]; + uchar p21[21]; memset(p21,'\0',21); - memset(p14,'\0',14); - StrnCpy((char *)p14,(const char *)passwd,14); - - strupper((char *)p14); - E_P16(p14, p21); + E_deshash(passwd, p21); SMBOWFencrypt(p21, c8, p24); @@ -49,61 +45,74 @@ void SMBencrypt(const uchar *passwd, const uchar *c8, uchar *p24) #endif } -/* +/** * Creates the MD4 Hash of the users password in NT UNICODE. + * @param passwd password in 'unix' charset. + * @param p16 return password hashed with md4, caller allocated 16 byte buffer */ -void E_md4hash(const uchar *passwd, uchar *p16) +void E_md4hash(const char *passwd, uchar p16[16]) { int len; smb_ucs2_t wpwd[129]; - /* Password cannot be longer than 128 characters */ - len = strlen((const char *)passwd); - if(len > 128) - len = 128; /* Password must be converted to NT unicode - null terminated. */ push_ucs2(NULL, wpwd, (const char *)passwd, 256, STR_UNICODE|STR_NOALIGN|STR_TERMINATE); /* Calculate length in bytes */ len = strlen_w(wpwd) * sizeof(int16); mdfour(p16, (unsigned char *)wpwd, len); + ZERO_STRUCT(wpwd); } -/* Does both the NT and LM owfs of a user's password */ -void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) +/** + * Creates the MD4 Hash of the users password in NT UNICODE. + * @param passwd password in 'unix' charset. + * @param p16 return password hashed with md4, caller allocated 16 byte buffer + */ + +void E_deshash(const char *passwd, uchar p16[16]) { - char passwd[514]; + uchar dospwd[15]; /* Password must not be > 14 chars long. */ + ZERO_STRUCT(dospwd); + ZERO_STRUCTP(p16); + + /* Password must be converted to DOS charset - null terminated. */ + push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - memset(passwd,'\0',514); - safe_strcpy( passwd, pwd, sizeof(passwd)-1); + E_P16(dospwd, p16); + + ZERO_STRUCT(dospwd); +} +/** + * Creates the MD4 and DES (LM) Hash of the users password. + * MD4 is of the NT Unicode, DES is of the DOS UPPERCASE password. + * @param passwd password in 'unix' charset. + * @param nt_p16 return password hashed with md4, caller allocated 16 byte buffer + * @param p16 return password hashed with des, caller allocated 16 byte buffer + */ + +/* Does both the NT and LM owfs of a user's password */ +void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) +{ /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash((uchar *)passwd, nt_p16); + E_md4hash(pwd, nt_p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwd, strlen(pwd)); dump_data(100, (char *)nt_p16, 16); #endif - /* Mangle the passwords into Lanman format */ - passwd[14] = '\0'; - strupper(passwd); - - /* Calculate the SMB (lanman) hash functions of the password */ - - memset(p16, '\0', 16); - E_P16((uchar *) passwd, (uchar *)p16); + E_deshash(pwd, (uchar *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, passwd, strlen(passwd)); + dump_data(120, pwd, strlen(pwd)); dump_data(100, (char *)p16, 16); #endif - /* clear out local copy of user's password (just being paranoid). */ - memset(passwd, '\0', sizeof(passwd)); } /* Does both the NTLMv2 owfs of a user's password */ @@ -322,22 +331,56 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, #endif return True; +} +/*********************************************************** + SMB signing - setup the MAC key. +************************************************************/ + +void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24]) +{ + /* Get first 16 bytes. */ + E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); + memcpy(&cli->sign_info.mac_key[16],resp,24); + cli->sign_info.mac_key_len = 40; + cli->sign_info.use_smb_signing = True; + + /* These calls are INCONPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + + /* Reset the sequence number in case we had a previous (aborted) attempt */ + cli->sign_info.send_seq_num = 0; } -/* Calculate the NT owfs of a user's password */ -void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16]) +/*********************************************************** + SMB signing - calculate a MAC to send. +************************************************************/ + +void cli_caclulate_sign_mac(struct cli_state *cli) { - char buf[512]; - int i; + unsigned char calc_md5_mac[16]; + struct MD5Context md5_ctx; - for (i = 0; i < MIN(pwd->uni_str_len, sizeof(buf) / 2); i++) - { - SIVAL(buf, i * 2, pwd->buffer[i]); + if (!cli->sign_info.use_smb_signing) { + return; } - /* Calculate the MD4 hash (NT compatible) of the password */ - mdfour(nt_p16, (const unsigned char *)buf, pwd->uni_str_len * 2); - /* clear out local copy of user's password (just being paranoid). */ - ZERO_STRUCT(buf); + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + SIVAL(cli->outbuf, smb_ss_field, cli->sign_info.send_seq_num); + SIVAL(cli->outbuf, smb_ss_field + 4, 0); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); + MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + cli->sign_info.send_seq_num++; + cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; + cli->sign_info.send_seq_num++; } diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 51ffa1dd95..3b77f7330e 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -39,7 +39,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("just_change_the_password: unable to setup creds (%s)!\n", + DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", nt_errstr(result))); return result; } @@ -71,13 +71,14 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); new_trust_passwd = talloc_strdup(mem_ctx, str); - E_md4hash((uchar *)new_trust_passwd, new_trust_passwd_hash); + E_md4hash(new_trust_passwd, new_trust_passwd_hash); nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, new_trust_passwd_hash); if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("%s : change_trust_account_password: Changed password.\n", timestring(False))); + DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", + timestring(False))); /* * Return the result of trying to write the new password * back into the trust account file. @@ -96,7 +97,8 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx already setup the connection to the NETLOGON pipe **********************************************************/ -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, char *domain) +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, + char *domain) { unsigned char old_trust_passwd_hash[16]; char *up_domain; diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index f74a05f75f..4fc3914481 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -46,7 +46,7 @@ void unexpected_packet(struct packet_struct *p) int len=0; if (!tdbd) { - tdbd = tdb_open_log(lock_path("unexpected.tdb"), 1, + tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR | O_CREAT, 0644); if (!tdbd) { -- cgit From 0184f3b6d8accd84cdb74da7dfd89df01e89c8b1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:37:42 +0000 Subject: checking for NULL really is counter-productive, and this one was also generating a warning (This used to be commit cd82ba41b8df024f034fcfa24e967ed8c3c8d035) --- source3/libsmb/cliconnect.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f0b02b97b0..472db69fd0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1119,11 +1119,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr ip; extern pstring global_myname; - if (!output_cli) { - DEBUG(0, ("output_cli is NULL!?!")); - SMB_ASSERT("output_cli for cli_full_connection was NULL.\n"); - } - if (!my_name) my_name = global_myname; -- cgit From 159118de5ce0999b96ebe7cd7dc823087b0cccf5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:54:35 +0000 Subject: fixed a number of real bugs found by warnings on the 64 bit irix compiler (This used to be commit 04de6bbc8055e5547af41b10e284b722f40e726d) --- source3/libsmb/cli_wkssvc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c index 756ff61e5b..97b948bf62 100644 --- a/source3/libsmb/cli_wkssvc.c +++ b/source3/libsmb/cli_wkssvc.c @@ -40,7 +40,6 @@ NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct rbuf; WKS_Q_QUERY_INFO q_o; WKS_R_QUERY_INFO r_o; - NTSTATUS nt_status; if (cli == NULL || wks100 == NULL) return NT_STATUS_UNSUCCESSFUL; @@ -89,6 +88,6 @@ NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* do clean up */ prs_mem_free(&rbuf); - return nt_status; + return NT_STATUS_OK; } -- cgit From b0b28531c8cd76d3fcd95da08389d8a4d2e631a3 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 11:16:26 +0000 Subject: more bug updates from head (This used to be commit 8b769bf5bbbe54b1a39fd85cc24db09c1ab7faab) --- source3/libsmb/cli_wkssvc.c | 3 +-- source3/libsmb/cliconnect.c | 5 ----- 2 files changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c index 756ff61e5b..97b948bf62 100644 --- a/source3/libsmb/cli_wkssvc.c +++ b/source3/libsmb/cli_wkssvc.c @@ -40,7 +40,6 @@ NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_struct rbuf; WKS_Q_QUERY_INFO q_o; WKS_R_QUERY_INFO r_o; - NTSTATUS nt_status; if (cli == NULL || wks100 == NULL) return NT_STATUS_UNSUCCESSFUL; @@ -89,6 +88,6 @@ NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* do clean up */ prs_mem_free(&rbuf); - return nt_status; + return NT_STATUS_OK; } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f0b02b97b0..472db69fd0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1119,11 +1119,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr ip; extern pstring global_myname; - if (!output_cli) { - DEBUG(0, ("output_cli is NULL!?!")); - SMB_ASSERT("output_cli for cli_full_connection was NULL.\n"); - } - if (!my_name) my_name = global_myname; -- cgit From 129b3966c04f4f1be33d35ca720e5946fbe76051 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 06:55:05 +0000 Subject: Add support for a weird behaviour apparently used by Win9X pass-through authentication - we can have an NT hash in the LM hash feild. (I need to double-check this fix with tpot, who discovered it). Also remove silly casts back and forth between uchar and char. Andrew Bartlett (This used to be commit 07e2b36311f91d7a20865a2ccc94716772e53fd7) --- source3/libsmb/smbencrypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 95434d0ae4..d15a83a515 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -226,14 +226,14 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ void SMBOWFencrypt_ntv2(const uchar kr[16], const DATA_BLOB srv_chal, const DATA_BLOB cli_chal, - char resp_buf[16]) + uchar resp_buf[16]) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); hmac_md5_update(srv_chal.data, srv_chal.length, &ctx); hmac_md5_update(cli_chal.data, cli_chal.length, &ctx); - hmac_md5_final((unsigned char *)resp_buf, &ctx); + hmac_md5_final(resp_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); -- cgit From badbae319a860c5590abeb7a947bacb47647c599 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 09:03:50 +0000 Subject: Fix up char/uchar casts etc. Fix up comments on some of the password hash wrappers. Andrew Bartlett (This used to be commit 95519d408caa7da00dbb2a8323cc4374a517cd69) --- source3/libsmb/cliconnect.c | 13 +++++-------- source3/libsmb/smbencrypt.c | 8 ++++---- 2 files changed, 9 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 472db69fd0..3cec5d743d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -54,9 +54,6 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return False; } - /* Lanman2 cannot use SMB signing. */ - cli->sign_info.use_smb_signing = False; - /* if in share level security then don't send a password now */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; @@ -269,10 +266,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; - SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); - SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); + SMBencrypt(pass,cli->secblob.data,(uchar *)pword); + SMBNTencrypt(pass,cli->secblob.data,(uchar *)ntpword); if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); + cli_calculate_mac_key(cli, pass, (uchar *)ntpword); tried_signing = True; } } else { @@ -482,8 +479,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, /* encrypt the password with the challenge */ memcpy(challenge, chal1.data + 24, 8); - SMBencrypt((unsigned char *)pass, challenge,lmhash); - SMBNTencrypt((unsigned char *)pass, challenge,nthash); + SMBencrypt(pass, challenge,lmhash); + SMBNTencrypt(pass, challenge,nthash); #if 0 file_save("nthash.dat", nthash, 24); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index d15a83a515..1ed83042d3 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -66,9 +66,9 @@ void E_md4hash(const char *passwd, uchar p16[16]) } /** - * Creates the MD4 Hash of the users password in NT UNICODE. + * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. - * @param p16 return password hashed with md4, caller allocated 16 byte buffer + * @param p16 return password hashed with DES, caller allocated 16 byte buffer */ void E_deshash(const char *passwd, uchar p16[16]) @@ -77,7 +77,7 @@ void E_deshash(const char *passwd, uchar p16[16]) ZERO_STRUCT(dospwd); ZERO_STRUCTP(p16); - /* Password must be converted to DOS charset - null terminated. */ + /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); E_P16(dospwd, p16); @@ -175,7 +175,7 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p /* Does the NT MD4 hash then des encryption. */ -void SMBNTencrypt(const uchar *passwd, uchar *c8, uchar *p24) +void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) { uchar p21[21]; -- cgit From ea9d3057e9cbd615176a7b98bcd935b6f9b434cb Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 20 Jul 2002 11:58:06 +0000 Subject: Try to fix up warnings - particularly on the IRIX 64 bit compiler (which had a distinction between uchar and char). Lots of const etc. Andrew Bartlett (This used to be commit 8196ee908e10db2119e480fe1b0a71b31a16febc) --- source3/libsmb/cli_srvsvc.c | 2 +- source3/libsmb/cliconnect.c | 28 ++++++++++++++++++++-------- source3/libsmb/namequery.c | 2 +- source3/libsmb/smbencrypt.c | 4 ++-- 4 files changed, 24 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index 2dc12d726c..b92b356241 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -317,7 +317,7 @@ WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, } WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_level, char *user_name, + uint32 file_level, const char *user_name, SRV_FILE_INFO_CTR *ctr, int preferred_len, ENUM_HND *hnd) { diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3cec5d743d..1cf85875b6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -254,11 +254,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); - fstring pword, ntpword; + uchar pword[24]; + uchar ntpword[24]; char *p; BOOL tried_signing = False; - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { return False; } @@ -266,15 +267,21 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; - SMBencrypt(pass,cli->secblob.data,(uchar *)pword); - SMBNTencrypt(pass,cli->secblob.data,(uchar *)ntpword); + SMBencrypt(pass,cli->secblob.data,pword); + SMBNTencrypt(pass,cli->secblob.data,ntpword); if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, pass, (uchar *)ntpword); + cli_calculate_mac_key(cli, pass, ntpword); tried_signing = True; } } else { - memcpy(pword, pass, passlen); - memcpy(ntpword, ntpass, ntpasslen); + /* pre-encrypted password supplied. Only used for security=server, can't do + signing becouse we don't have oringial key */ + memcpy(pword, pass, 24); + if (ntpasslen == 24) { + memcpy(ntpword, ntpass, 24); + } else { + ZERO_STRUCT(ntpword); + } } /* send a session setup command */ @@ -302,8 +309,13 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, cli_setup_bcc(cli, p); cli_send_smb(cli); - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + if (tried_signing) { + /* We only use it if we have a successful non-guest connect */ + cli->sign_info.use_smb_signing = False; + } return False; + } show_msg(cli->inbuf); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 18564bccf4..e2ddfd8280 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -930,7 +930,7 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) Find the IP address of the master browser or DMB for a workgroup. *********************************************************/ -BOOL find_master_ip(char *group, struct in_addr *master_ip) +BOOL find_master_ip(const char *group, struct in_addr *master_ip) { struct in_addr *ip_list = NULL; int count = 0; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 1ed83042d3..dfa355a7ec 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -28,7 +28,7 @@ This implements the X/Open SMB password encryption It takes a password ('unix' string), a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24) +void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) { uchar p21[21]; @@ -337,7 +337,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, SMB signing - setup the MAC key. ************************************************************/ -void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24]) +void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uchar resp[24]) { /* Get first 16 bytes. */ E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); -- cgit From 035738863609b0762a18962f1c471bb385254f10 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 21 Jul 2002 00:49:16 +0000 Subject: Renamed all the new_cli_netlogon_* functions to cli_netlogon_* as they're no longer new! (This used to be commit 277f6bbb9a63541a473a80a7994e9bde5c6f22dc) --- source3/libsmb/cli_netlogon.c | 30 +++++++++++++++--------------- source3/libsmb/trust_passwd.c | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_netlogon.c b/source3/libsmb/cli_netlogon.c index d32e0e77e4..acc9135542 100644 --- a/source3/libsmb/cli_netlogon.c +++ b/source3/libsmb/cli_netlogon.c @@ -28,8 +28,8 @@ /* LSA Request Challenge. Sends our challenge to server, then gets server response. These are used to generate the credentials. */ -NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, - DOM_CHAL *srv_chal) +NTSTATUS cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, + DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; NET_Q_REQ_CHAL q; @@ -42,7 +42,7 @@ NTSTATUS new_cli_net_req_chal(struct cli_state *cli, DOM_CHAL *clnt_chal, /* create and send a MSRPC command with api NET_REQCHAL */ - DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", + DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", global_myname, cli->desthost, credstr(clnt_chal->data))); /* store the parameters */ @@ -84,9 +84,9 @@ Ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ -NTSTATUS new_cli_net_auth2(struct cli_state *cli, - uint16 sec_chan, - uint32 neg_flags, DOM_CHAL *srv_chal) +NTSTATUS cli_net_auth2(struct cli_state *cli, + uint16 sec_chan, + uint32 neg_flags, DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; NET_Q_AUTH_2 q; @@ -99,7 +99,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* create and send a MSRPC command with api NET_AUTH2 */ - DEBUG(4,("new_cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", + DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, credstr(cli->clnt_cred.challenge.data), neg_flags)); @@ -138,7 +138,7 @@ NTSTATUS new_cli_net_auth2(struct cli_state *cli, /* * Server replied with bad credential. Fail. */ - DEBUG(0,("new_cli_net_auth2: server %s replied with bad credential (bad machine \ + DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ password ?).\n", cli->desthost )); result = NT_STATUS_ACCESS_DENIED; goto done; @@ -154,9 +154,9 @@ password ?).\n", cli->desthost )); /* Initialize domain session credentials */ -NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, - uint16 sec_chan, - const unsigned char mach_pwd[16]) +NTSTATUS cli_nt_setup_creds(struct cli_state *cli, + uint16 sec_chan, + const unsigned char mach_pwd[16]) { DOM_CHAL clnt_chal; DOM_CHAL srv_chal; @@ -168,10 +168,10 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, generate_random_buffer(clnt_chal.data, 8, False); /* send a client challenge; receive a server challenge */ - result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal); + result = cli_net_req_chal(cli, &clnt_chal, &srv_chal); if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("new_cli_nt_setup_creds: request challenge failed\n")); + DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); return result; } @@ -194,8 +194,8 @@ NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, * Receive an auth-2 challenge response and check it. */ - result = new_cli_net_auth2(cli, sec_chan, 0x000001ff, - &srv_chal); + result = cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); + if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", nt_errstr(result))); diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 3b77f7330e..fe6b673e39 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,7 +35,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { -- cgit From 88bef55a6efceef72a1378d0c7fa93c277fb1940 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 22 Jul 2002 14:00:40 +0000 Subject: fixed a segv in net time when the host is unavailable (This used to be commit f4f2b613a2a804a6d2e5e78cc7dd7f3482675fcd) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1cf85875b6..d304da7f51 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1071,7 +1071,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } if (cli->fd == -1) { DEBUG(1,("Error connecting to %s (%s)\n", - inet_ntoa(*ip),strerror(errno))); + ip?inet_ntoa(*ip):host,strerror(errno))); return False; } -- cgit From a56490007479b3f23f5159bfb7545136c40dd1fd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 26 Jul 2002 13:05:29 +0000 Subject: Mimir has been busy with patches again, and sent in the following patches: Andrew Bartlett From his e-mail: Below I attach the following patches as a result of my work on trusted domains support: 1) srv_samr_nt.c.diff This fixes a bug which caused to return null string as the first entry of enumerated accounts list (no matter what entry, it was always null string and rid) and possibly spoiled further names, depeding on their length. I found that while testing my 'net rpc trustdom list' against nt servers and samba server. 2) libsmb.diff Now, fallback to anonymous connection works correctly. 3) smbpasswd.c.diff Just a little fix which actually allows one to create a trusting domain account using smbpasswd 4) typos.diff As the name suggests, it's just a few typos fix :) (This used to be commit 888d595fab4f6b28318b743f47378cb7ca35d479) --- source3/libsmb/cliconnect.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d304da7f51..d29a6115fb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1191,9 +1191,8 @@ again: if (!cli_session_setup(cli, user, password, strlen(password)+1, password, strlen(password)+1, domain)) { - if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) - || cli_session_setup(cli, "", "", 0, - "", 0, domain)) { + if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) + && cli_session_setup(cli, "", "", 0, "", 0, domain)) { } else { nt_status = cli_nt_error(cli); DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); -- cgit From 2a03547b6142ab934840332cda37013982cbe723 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Jul 2002 00:15:02 +0000 Subject: Rafal 'Mimir' Szczesniak has been busy again, and has added 'net rpc trustdom list' support. This lists the trusted and trusting domains of a remote PDC. I've applied these almost directly, just fixing some special case code for when there are *no* trusting domains. We still have some parse errors in this case however. Andrew Bartlett. From mimir's e-mail: Here are another patches adding trust relationship features. More details: Better error reporting in cli_lsa_enum_trust_dom(). Implementation of cli_samr_enum_dom_users() which cli_samr.c lacked. More "consts" -- one of arguments in net_find_dc(). Modified implementation of run_rpc_command() -- now it allows to reuse already opened connection (if it is passed) to remote server's IPC$ (e.g. as part of longer exchange of rpc calls). I'm sure Andrew will argue ;-) More neat version of rpc_trustdom_list() function. (This used to be commit f0890026820ee3e432147130b46de4610e583381) --- source3/libsmb/cli_lsarpc.c | 7 +-- source3/libsmb/cli_samr.c | 112 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 115 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c index 7dfee46fae..542fad311c 100644 --- a/source3/libsmb/cli_lsarpc.c +++ b/source3/libsmb/cli_lsarpc.c @@ -543,7 +543,7 @@ NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 *enum_ctx, uint32 *pref_num_domains, uint32 *num_domains, - char ***domain_names, DOM_SID **domain_sids) + char ***domain_names, DOM_SID **domain_sids) { prs_struct qbuf, rbuf; LSA_Q_ENUM_TRUST_DOM q; @@ -598,7 +598,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (!*domain_names) { DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_NO_MEMORY; goto done; } @@ -606,7 +606,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, r.num_domains); if (!domain_sids) { DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; + result = NT_STATUS_NO_MEMORY; goto done; } @@ -632,6 +632,7 @@ NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } + /** Enumerate privileges*/ NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx, diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c index 91577b3325..6581bdbeaf 100644 --- a/source3/libsmb/cli_samr.c +++ b/source3/libsmb/cli_samr.c @@ -5,7 +5,8 @@ Copyright (C) Andrew Tridgell 1992-1997,2000, Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000. + Copyright (C) Elrond 2000, + Copyright (C) Rafal Szczesniak 2002. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -491,6 +492,115 @@ NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +/** + * Enumerate domain users + * + * @param cli client state structure + * @param mem_ctx talloc context + * @param pol opened domain policy handle + * @param start_idx starting index of enumeration, returns context for + next enumeration + * @param acb_mask account control bit mask (to enumerate some particular + * kind of accounts) + * @param size max acceptable size of response + * @param dom_users returned array of domain user names + * @param rids returned array of domain user RIDs + * @param num_dom_users numer returned entries + * + * @return NTSTATUS returned in rpc response + **/ +NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask, + uint32 size, char ***dom_users, uint32 **rids, + uint32 *num_dom_users) +{ + prs_struct qdata; + prs_struct rdata; + SAMR_Q_ENUM_DOM_USERS q; + SAMR_R_ENUM_DOM_USERS r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + if (cli == NULL || pol == NULL) + return result; + + /* initialise parse structures */ + prs_init(&qdata, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rdata, 0, mem_ctx, UNMARSHALL); + + DEBUG(4, ("SAMR Enum Domain Users. start_idx: %d, acb: %d, size: %d\n", + *start_idx, acb_mask, size)); + + /* fill query structure with parameters */ + init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size); + + /* prepare query stream */ + if (!samr_io_q_enum_dom_users("", &q, &qdata, 0)) { + prs_mem_free(&qdata); + prs_mem_free(&rdata); + return result; + } + + /* send rpc call over the pipe */ + if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qdata, &rdata)) { + prs_mem_free(&qdata); + prs_mem_free(&rdata); + return result; + } + + /* unpack received stream */ + if(!samr_io_r_enum_dom_users("", &r, &rdata, 0)) { + prs_mem_free(&qdata); + prs_mem_free(&rdata); + result = r.status; + return result; + } + + /* return the data obtained in response */ + if (!NT_STATUS_IS_OK(r.status) && + (NT_STATUS_EQUAL(r.status, STATUS_MORE_ENTRIES) || + NT_STATUS_EQUAL(r.status, NT_STATUS_NO_MORE_ENTRIES))) { + return r.status; + } + + *start_idx = r.next_idx; + *num_dom_users = r.num_entries2; + result = r.status; + + if (r.num_entries2) { + /* allocate memory needed to return received data */ + *rids = (uint32*)talloc(mem_ctx, sizeof(uint32) * r.num_entries2); + if (!*rids) { + DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n")); + return NT_STATUS_NO_MEMORY; + } + + *dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2); + if (!*dom_users) { + DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n")); + return NT_STATUS_NO_MEMORY; + } + + /* fill output buffers with rpc response */ + for (i = 0; i < r.num_entries2; i++) { + fstring conv_buf; + + (*rids)[i] = r.sam[i].rid; + unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1); + (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf); + } + } + + prs_mem_free(&qdata); + prs_mem_free(&rdata); + + return result; +}; + + /* Enumerate domain groups */ NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, -- cgit From 3130577acb03a06fd8de27ee6c2e4f82bd4b2008 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 30 Jul 2002 04:32:29 +0000 Subject: Some crash fixes for netshareenum returning zero shares. (This used to be commit a5a0ff8bd7ee4a3586647d14fd750ec6df73efa8) --- source3/libsmb/cli_srvsvc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c index b92b356241..1bdd19620b 100644 --- a/source3/libsmb/cli_srvsvc.c +++ b/source3/libsmb/cli_srvsvc.c @@ -116,6 +116,9 @@ WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, ZERO_STRUCTP(ctr); + if (!r.ctr.num_entries) + goto done; + ctr->info_level = info_level; ctr->num_entries = r.ctr.num_entries; -- cgit From 9edc1cd4cfd3c02cfb1b867f8450384c446e8b60 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 30 Jul 2002 15:03:14 +0000 Subject: this fixes plaintext passwords with win2000 there were 2 bugs: 1) we were sending a null challenge when we should have sent an empty challenge 2) the password can be in unicode if unicode is negotiated. This means our client code was wrong too :( (This used to be commit 1a6dfddf6788b30fc81794b1bfe749693183b2c1) --- source3/libsmb/cliconnect.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d29a6115fb..93cf3d95db 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -206,12 +206,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,0); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - memcpy(p, pword, passlen); - p += passlen; + p += clistr_push(cli, p, pword, -1, STR_TERMINATE); /* password */ + SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); -- cgit From dcff12797e3e27abd378c9a7e7c0d036860a86ef Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 31 Jul 2002 05:41:51 +0000 Subject: added 'disable netbios = yes/no' option, default is no When this option is disabled we should not do *any* netbios operations. You should also not start nmbd at all. I have put initial checks in at the major points we do netbios operations in smbd but there are bound to be more needed. Right now I've disabled all netbios name queries, all WINS lookups and node status queries in smbd and winbindd. I've been testing this option and the most noticable thing is how much more responsive things are! wthout those damn netbios timeouts things certainly are much slicker. (This used to be commit 12e7953bf2497eeb7c0bc6585d9fe58b3aabc240) --- source3/libsmb/namequery.c | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e2ddfd8280..ae58c3a062 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -170,6 +170,11 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t int sock; BOOL result = False; + if (lp_disable_netbios()) { + DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type)); + return False; + } + DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, q_type, inet_ntoa(to_ip))); @@ -273,6 +278,11 @@ struct in_addr *name_query(int fd,const char *name,int name_type, struct nmb_packet *nmb = &p.packet.nmb; struct in_addr *ip_list = NULL; + if (lp_disable_netbios()) { + DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type)); + return NULL; + } + if (timed_out) { *timed_out = False; } @@ -556,6 +566,11 @@ BOOL name_resolve_bcast(const char *name, int name_type, int sock, i; int num_interfaces = iface_count(); + if (lp_disable_netbios()) { + DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type)); + return False; + } + *return_ip_list = NULL; *return_count = 0; @@ -602,6 +617,11 @@ BOOL resolve_wins(const char *name, int name_type, char **wins_tags; struct in_addr src_ip; + if (lp_disable_netbios()) { + DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type)); + return False; + } + *return_iplist = NULL; *return_count = 0; @@ -935,6 +955,11 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) struct in_addr *ip_list = NULL; int count = 0; + if (lp_disable_netbios()) { + DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group)); + return False; + } + if (internal_resolve_name(group, 0x1D, &ip_list, &count)) { *master_ip = ip_list[0]; SAFE_FREE(ip_list); @@ -957,10 +982,14 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) BOOL lookup_dc_name(const char *srcname, const char *domain, struct in_addr *dc_ip, char *ret_name) { -#if !defined(I_HATE_WINDOWS_REPLY_CODE) - +#if !defined(I_HATE_WINDOWS_REPLY_CODE) fstring dc_name; BOOL ret; + + if (lp_disable_netbios()) { + DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain)); + return False; + } /* * Due to the fact win WinNT *sucks* we must do a node status -- cgit From e9360f1a45d46a7def3e74c46d170eb843e1fb9e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 2 Aug 2002 07:20:56 +0000 Subject: Moved rpc client routines from libsmb back to rpc_client where they belong. (This used to be commit cb946b5dadf3cfd21bf584437c6a8e9425f6d5a7) --- source3/libsmb/cli_dfs.c | 245 ---- source3/libsmb/cli_lsarpc.c | 1169 ------------------- source3/libsmb/cli_netlogon.c | 664 ----------- source3/libsmb/cli_reg.c | 102 -- source3/libsmb/cli_samr.c | 1404 ----------------------- source3/libsmb/cli_spoolss.c | 2156 ----------------------------------- source3/libsmb/cli_spoolss_notify.c | 223 ---- source3/libsmb/cli_srvsvc.c | 445 -------- source3/libsmb/cli_wkssvc.c | 93 -- 9 files changed, 6501 deletions(-) delete mode 100644 source3/libsmb/cli_dfs.c delete mode 100644 source3/libsmb/cli_lsarpc.c delete mode 100644 source3/libsmb/cli_netlogon.c delete mode 100644 source3/libsmb/cli_reg.c delete mode 100644 source3/libsmb/cli_samr.c delete mode 100644 source3/libsmb/cli_spoolss.c delete mode 100644 source3/libsmb/cli_spoolss_notify.c delete mode 100644 source3/libsmb/cli_srvsvc.c delete mode 100644 source3/libsmb/cli_wkssvc.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c deleted file mode 100644 index 7fc27b9c3b..0000000000 --- a/source3/libsmb/cli_dfs.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Query DFS support */ - -NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL *dfs_exists) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_EXIST q; - DFS_R_DFS_EXIST r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_exist(&q); - - if (!dfs_io_q_dfs_exist("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_EXIST, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_exist("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - *dfs_exists = (r.status != 0); - - result = NT_STATUS_OK; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename, - char *comment, uint32 flags) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_ADD q; - DFS_R_DFS_ADD r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_add(&q, entrypath, servername, sharename, comment, - flags); - - if (!dfs_io_q_dfs_add("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_ADD, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_add("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_REMOVE q; - DFS_R_DFS_REMOVE r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_remove(&q, entrypath, servername, sharename); - - if (!dfs_io_q_dfs_remove("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_REMOVE, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_remove("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename, - uint32 info_level, DFS_INFO_CTR *ctr) - -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_GET_INFO q; - DFS_R_DFS_GET_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_get_info(&q, entrypath, servername, sharename, - info_level); - - if (!dfs_io_q_dfs_get_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_GET_INFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_get_info("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - *ctr = r.ctr; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enumerate dfs shares */ - -NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 info_level, DFS_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_ENUM q; - DFS_R_DFS_ENUM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_enum(&q, info_level, ctr); - - if (!dfs_io_q_dfs_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_ENUM, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!dfs_io_r_dfs_enum("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c deleted file mode 100644 index 542fad311c..0000000000 --- a/source3/libsmb/cli_lsarpc.c +++ /dev/null @@ -1,1169 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - Copyright (C) Andrew Tridgell 1992-1997,2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, - Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000, - Copyright (C) Rafal Szczesniak 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** @defgroup lsa LSA - Local Security Architecture - * @ingroup rpc_client - * - * @{ - **/ - -/** - * @file cli_lsarpc.c - * - * RPC client routines for the LSA RPC pipe. LSA means "local - * security authority", which is half of a password database. - **/ - -/** Open a LSA policy handle - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL sec_qos, uint32 des_access, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPEN_POL q; - LSA_R_OPEN_POL r; - LSA_SEC_QOS qos; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0); - init_q_open_pol(&q, '\\', 0, des_access, &qos); - } else { - init_q_open_pol(&q, '\\', 0, des_access, NULL); - } - - /* Marshall data and send request */ - - if (!lsa_io_q_open_pol("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *pol = r.pol; -#ifdef __INSURE__ - pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Open a LSA policy handle - * - * @param cli Handle on an initialised SMB connection - */ - -NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL sec_qos, uint32 des_access, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPEN_POL2 q; - LSA_R_OPEN_POL2 r; - LSA_SEC_QOS qos; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0); - init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access, - &qos); - } else { - init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access, - NULL); - } - - /* Marshall data and send request */ - - if (!lsa_io_q_open_pol2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENPOLICY2, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_pol2("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *pol = r.pol; -#ifdef __INSURE__ - pol->marker = (char *)malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Close a LSA policy handle */ - -NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_CLOSE q; - LSA_R_CLOSE r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_q_close(&q, pol); - - if (!lsa_io_q_close("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_close("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { -#ifdef __INSURE__ - SAFE_FREE(pol->marker); -#endif - *pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Lookup a list of sids */ - -NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***domains, char ***names, uint32 **types) -{ - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_SIDS q; - LSA_R_LOOKUP_SIDS r; - DOM_R_REF ref; - LSA_TRANS_NAME_ENUM t_names; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1); - - if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - ZERO_STRUCT(ref); - ZERO_STRUCT(t_names); - - r.dom_ref = &ref; - r.names = &t_names; - - if (!lsa_io_r_lookup_sids("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - - /* An actual error occured */ - - goto done; - } - - /* Return output parameters */ - - if (r.mapped_count == 0) { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < num_sids; i++) { - fstring name, dom_name; - uint32 dom_idx = t_names.name[i].domain_idx; - - /* Translate optimised name through domain index array */ - - if (dom_idx != 0xffffffff) { - - rpcstr_pull_unistr2_fstring( - dom_name, &ref.ref_dom[dom_idx].uni_dom_name); - rpcstr_pull_unistr2_fstring( - name, &t_names.uni_name[i]); - - (*names)[i] = talloc_strdup(mem_ctx, name); - (*domains)[i] = talloc_strdup(mem_ctx, dom_name); - (*types)[i] = t_names.name[i].sid_name_use; - - if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - } else { - (*names)[i] = NULL; - (*types)[i] = SID_NAME_UNKNOWN; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Lookup a list of names */ - -NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, - const char **names, DOM_SID **sids, - uint32 **types) -{ - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_NAMES q; - LSA_R_LOOKUP_NAMES r; - DOM_R_REF ref; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_lookup_names(mem_ctx, &q, pol, num_names, names); - - if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - ZERO_STRUCT(ref); - r.dom_ref = &ref; - - if (!lsa_io_r_lookup_names("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != - NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - - /* An actual error occured */ - - goto done; - } - - /* Return output parameters */ - - if (r.mapped_count == 0) { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * - num_names)))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * - num_names)))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < num_names; i++) { - DOM_RID2 *t_rids = r.dom_rid; - uint32 dom_idx = t_rids[i].rid_idx; - uint32 dom_rid = t_rids[i].rid; - DOM_SID *sid = &(*sids)[i]; - - /* Translate optimised sid through domain index array */ - - if (dom_idx != 0xffffffff) { - - sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid); - - if (dom_rid != 0xffffffff) { - sid_append_rid(sid, dom_rid); - } - - (*types)[i] = t_rids[i].type; - } else { - ZERO_STRUCTP(sid); - (*types)[i] = SID_NAME_UNKNOWN; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Query info policy - * - * @param domain_sid - returned remote server's domain sid */ - -NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint16 info_class, - fstring domain_name, DOM_SID *domain_sid) -{ - prs_struct qbuf, rbuf; - LSA_Q_QUERY_INFO q; - LSA_R_QUERY_INFO r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_query(&q, pol, info_class); - - if (!lsa_io_q_query("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_query("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - ZERO_STRUCTP(domain_sid); - domain_name[0] = '\0'; - - switch (info_class) { - - case 3: - if (r.dom.id3.buffer_dom_name != 0) { - unistr2_to_ascii(domain_name, - &r.dom.id3. - uni_domain_name, - sizeof (fstring) - 1); - } - - if (r.dom.id3.buffer_dom_sid != 0) { - *domain_sid = r.dom.id3.dom_sid.sid; - } - - break; - - case 5: - - if (r.dom.id5.buffer_dom_name != 0) { - unistr2_to_ascii(domain_name, &r.dom.id5. - uni_domain_name, - sizeof (fstring) - 1); - } - - if (r.dom.id5.buffer_dom_sid != 0) { - *domain_sid = r.dom.id5.dom_sid.sid; - } - - break; - - default: - DEBUG(3, ("unknown info class %d\n", info_class)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** - * Enumerate list of trusted domains - * - * @param cli client state (cli_state) structure of the connection - * @param mem_ctx memory context - * @param pol opened lsa policy handle - * @param enum_ctx enumeration context ie. index of first returned domain entry - * @param pref_num_domains preferred max number of entries returned in one response - * @param num_domains total number of trusted domains returned by response - * @param domain_names returned trusted domain names - * @param domain_sids returned trusted domain sids - * - * @return nt status code of response - **/ - -NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_ctx, - uint32 *pref_num_domains, uint32 *num_domains, - char ***domain_names, DOM_SID **domain_sids) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_TRUST_DOM q; - LSA_R_ENUM_TRUST_DOM r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_enum_trust_dom(&q, pol, *enum_ctx, *pref_num_domains); - - if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_trust_dom("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && - !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { - - /* An actual error ocured */ - - goto done; - } - - /* Return output parameters */ - - if (r.num_domains) { - - /* Allocate memory for trusted domain names and sids */ - - *domain_names = (char **)talloc(mem_ctx, sizeof(char *) * - r.num_domains); - - if (!*domain_names) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_NO_MEMORY; - goto done; - } - - *domain_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * - r.num_domains); - if (!domain_sids) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_NO_MEMORY; - goto done; - } - - /* Copy across names and sids */ - - for (i = 0; i < r.num_domains; i++) { - fstring tmp; - - unistr2_to_ascii(tmp, &r.uni_domain_name[i], - sizeof(tmp) - 1); - (*domain_names)[i] = talloc_strdup(mem_ctx, tmp); - sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); - } - } - - *num_domains = r.num_domains; - *enum_ctx = r.enum_context; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - - -/** Enumerate privileges*/ - -NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length, - uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_PRIVS q; - LSA_R_ENUM_PRIVS r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_enum_privs(&q, pol, *enum_context, pref_max_length); - - if (!lsa_io_q_enum_privs("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUM_PRIVS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_privs("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - *enum_context = r.enum_context; - *count = r.count; - - if (!((*privs_name = (char **)talloc(mem_ctx, sizeof(char *) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*privs_high = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*privs_low = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < r.count; i++) { - fstring name; - - rpcstr_pull_unistr2_fstring( name, &r.privs[i].name); - - (*privs_name)[i] = talloc_strdup(mem_ctx, name); - - (*privs_high)[i] = r.privs[i].luid_high; - (*privs_low)[i] = r.privs[i].luid_low; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Get privilege name */ - -NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys, - fstring description, uint16 *lang_id_desc) -{ - prs_struct qbuf, rbuf; - LSA_Q_PRIV_GET_DISPNAME q; - LSA_R_PRIV_GET_DISPNAME r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys); - - if (!lsa_io_q_priv_get_dispname("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_priv_get_dispname("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - rpcstr_pull_unistr2_fstring(description , &r.desc); - *lang_id_desc = r.lang_id; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate list of SIDs */ - -NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length, - uint32 *num_sids, DOM_SID **sids) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_ACCOUNTS q; - LSA_R_ENUM_ACCOUNTS r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length); - - if (!lsa_io_q_enum_accounts("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_accounts("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.sids.num_entries==0) - goto done; - - /* Return output parameters */ - - *sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.sids.num_entries); - if (!*sids) { - DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Copy across names and sids */ - - for (i = 0; i < r.sids.num_entries; i++) { - sid_copy(&(*sids)[i], &r.sids.sid[i].sid); - } - - *num_sids= r.sids.num_entries; - *enum_ctx = r.enum_context; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Open a LSA user handle - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access, - POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPENACCOUNT q; - LSA_R_OPENACCOUNT r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_lsa_q_open_account(&q, dom_pol, sid, des_access); - - /* Marshall data and send request */ - - if (!lsa_io_q_open_account("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENACCOUNT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_account("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *user_pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate user privileges - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *count, LUID_ATTR **set) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUMPRIVSACCOUNT q; - LSA_R_ENUMPRIVSACCOUNT r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_lsa_q_enum_privsaccount(&q, pol); - - /* Marshall data and send request */ - - if (!lsa_io_q_enum_privsaccount("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_privsaccount("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.count == 0) - goto done; - - if (!((*set = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i=0; imem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_REQCHAL */ - - DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", - global_myname, cli->desthost, credstr(clnt_chal->data))); - - /* store the parameters */ - init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal); - - /* Marshall data and send request */ - - if (!net_io_q_req_chal("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_REQCHAL, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarhall response */ - - if (!net_io_r_req_chal("", &r, &rbuf, 0)) { - goto done; - } - - result = r.status; - - /* Return result */ - - if (NT_STATUS_IS_OK(result)) { - memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data)); - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/**************************************************************************** -LSA Authenticate 2 - -Send the client credential, receive back a server credential. -Ensure that the server credential returned matches the session key -encrypt of the server challenge originally received. JRA. -****************************************************************************/ - -NTSTATUS cli_net_auth2(struct cli_state *cli, - uint16 sec_chan, - uint32 neg_flags, DOM_CHAL *srv_chal) -{ - prs_struct qbuf, rbuf; - NET_Q_AUTH_2 q; - NET_R_AUTH_2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - extern pstring global_myname; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_AUTH2 */ - - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", - cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, - credstr(cli->clnt_cred.challenge.data), neg_flags)); - - /* store the parameters */ - init_q_auth_2(&q, cli->srv_name_slash, cli->mach_acct, - sec_chan, global_myname, &cli->clnt_cred.challenge, - neg_flags); - - /* turn parameters into data stream */ - - if (!net_io_q_auth_2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_AUTH2, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_auth_2("", &r, &rbuf, 0)) { - goto done; - } - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - UTIME zerotime; - - /* - * Check the returned value using the initial - * server received challenge. - */ - - zerotime.time = 0; - if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, - zerotime) == 0) { - - /* - * Server replied with bad credential. Fail. - */ - DEBUG(0,("cli_net_auth2: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); - result = NT_STATUS_ACCESS_DENIED; - goto done; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Initialize domain session credentials */ - -NTSTATUS cli_nt_setup_creds(struct cli_state *cli, - uint16 sec_chan, - const unsigned char mach_pwd[16]) -{ - DOM_CHAL clnt_chal; - DOM_CHAL srv_chal; - UTIME zerotime; - NTSTATUS result; - - /******************* Request Challenge ********************/ - - generate_random_buffer(clnt_chal.data, 8, False); - - /* send a client challenge; receive a server challenge */ - result = cli_net_req_chal(cli, &clnt_chal, &srv_chal); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("cli_nt_setup_creds: request challenge failed\n")); - return result; - } - - /**************** Long-term Session key **************/ - - /* calculate the session key */ - cred_session_key(&clnt_chal, &srv_chal, mach_pwd, - cli->sess_key); - memset((char *)cli->sess_key+8, '\0', 8); - - /******************* Authenticate 2 ********************/ - - /* calculate auth-2 credentials */ - zerotime.time = 0; - cred_create(cli->sess_key, &clnt_chal, zerotime, - &cli->clnt_cred.challenge); - - /* - * Send client auth-2 challenge. - * Receive an auth-2 challenge response and check it. - */ - - result = cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", - nt_errstr(result))); - } - - return result; -} - -/* Logon Control 2 */ - -NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 query_level) -{ - prs_struct qbuf, rbuf; - NET_Q_LOGON_CTRL2 q; - NET_R_LOGON_CTRL2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_net_q_logon_ctrl2(&q, cli->srv_name_slash, query_level); - - /* Marshall data and send request */ - - if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_logon_ctrl2("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/**************************************************************************** -Generate the next creds to use. Yuck - this is a cut&paste from another -file. They should be combined at some stage. )-: -****************************************************************************/ - -static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) -{ - /* - * Create the new client credentials. - */ - - cli->clnt_cred.timestamp.time = time(NULL); - - memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred)); - - /* Calculate the new credentials. */ - cred_create(cli->sess_key, &(cli->clnt_cred.challenge), - new_clnt_cred->timestamp, &(new_clnt_cred->challenge)); - -} - -/* Sam synchronisation */ - -NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds, - uint32 database_id, uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_SYNC q; - NET_R_SAM_SYNC r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2, - &clnt_creds, ret_creds, database_id); - - /* Marshall data and send request */ - - if (!net_io_q_sam_sync("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_sam_sync("", cli->sess_key, &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds)); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Sam synchronisation */ - -NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 database_id, UINT64_S seqnum, - uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_DELTAS q; - NET_R_SAM_DELTAS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - init_net_q_sam_deltas(&q, cli->srv_name_slash, - cli->clnt_name_slash + 2, &clnt_creds, - database_id, seqnum); - - /* Marshall data and send request */ - - if (!net_io_q_sam_deltas("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAM_DELTAS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_sam_deltas("", cli->sess_key, &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Logon domain user */ - -NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *username, char *password, - int logon_type) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds, dummy_rtn_creds; - extern pstring global_myname; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 user; - int validation_level = 3; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - q.validation_level = validation_level; - - memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); - dummy_rtn_creds.timestamp.time = time(NULL); - - ctr.switch_value = logon_type; - - switch (logon_type) { - case INTERACTIVE_LOGON_TYPE: { - unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; - - nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); - - init_id_info1(&ctr.auth.id1, lp_workgroup(), - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, cli->clnt_name_slash, - cli->sess_key, lm_owf_user_pwd, - nt_owf_user_pwd); - - break; - } - case NET_LOGON_TYPE: { - uint8 chal[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_response[24]; - - generate_random_buffer(chal, 8, False); - - SMBencrypt(password, chal, local_lm_response); - SMBNTencrypt(password, chal, local_nt_response); - - init_id_info2(&ctr.auth.id2, lp_workgroup(), - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, cli->clnt_name_slash, chal, - local_lm_response, 24, local_nt_response, 24); - break; - } - default: - DEBUG(0, ("switch value %d not supported\n", - ctr.switch_value)); - goto done; - } - - init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, - &clnt_creds, &dummy_rtn_creds, logon_type, - &ctr); - - /* Marshall data and send request */ - - if (!net_io_q_sam_logon("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.user = &user; - - if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { - goto done; - } - - /* Return results */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - - -/** - * Logon domain user with an 'network' SAM logon - * - * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller. - **/ - -NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, - const char *username, const char *domain, const char *workstation, - const uint8 chal[8], - DATA_BLOB lm_response, DATA_BLOB nt_response, - NET_USER_INFO_3 *info3) - -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds, dummy_rtn_creds; - NET_ID_INFO_CTR ctr; - extern pstring global_myname; - int validation_level = 3; - char *workstation_name_slash; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation); - - if (!workstation_name_slash) { - DEBUG(0, ("talloc_asprintf failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - q.validation_level = validation_level; - - memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); - dummy_rtn_creds.timestamp.time = time(NULL); - - ctr.switch_value = NET_LOGON_TYPE; - - init_id_info2(&ctr.auth.id2, domain, - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, workstation_name_slash, (const uchar*)chal, - lm_response.data, lm_response.length, nt_response.data, nt_response.length); - - init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, - &clnt_creds, &dummy_rtn_creds, NET_LOGON_TYPE, - &ctr); - - /* Marshall data and send request */ - - if (!net_io_q_sam_logon("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.user = info3; - - if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { - goto done; - } - - /* Return results */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/*************************************************************************** -LSA Server Password Set. -****************************************************************************/ - -NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char* machine_name, uint8 hashed_mach_pwd[16]) -{ - prs_struct rbuf; - prs_struct qbuf; - DOM_CRED new_clnt_cred; - NET_Q_SRV_PWSET q_s; - uint16 sec_chan_type = 2; - NTSTATUS nt_status; - char *mach_acct; - - gen_next_creds( cli, &new_clnt_cred); - - prs_init(&qbuf , 1024, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_SRV_PWSET */ - - mach_acct = talloc_asprintf(mem_ctx, "%s$", machine_name); - - if (!mach_acct) { - DEBUG(0,("talloc_asprintf failed!\n")); - nt_status = NT_STATUS_NO_MEMORY; - goto done; - } - - DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", - cli->srv_name_slash, mach_acct, sec_chan_type, machine_name, - credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); - - /* store the parameters */ - init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->sess_key, - mach_acct, sec_chan_type, machine_name, - &new_clnt_cred, (char *)hashed_mach_pwd); - - /* turn parameters into data stream */ - if(!net_io_q_srv_pwset("", &q_s, &qbuf, 0)) { - DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n")); - nt_status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, NET_SRVPWSET, &qbuf, &rbuf)) - { - NET_R_SRV_PWSET r_s; - - if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) { - nt_status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - nt_status = r_s.status; - - if (!NT_STATUS_IS_OK(r_s.status)) - { - /* report error code */ - DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(nt_status))); - goto done; - } - - /* Update the credentials. */ - if (!clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred))) - { - /* - * Server replied with bad credential. Fail. - */ - DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); - nt_status = NT_STATUS_UNSUCCESSFUL; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return nt_status; -} - diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c deleted file mode 100644 index aaf18882f7..0000000000 --- a/source3/libsmb/cli_reg.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC Pipe client - - Copyright (C) Andrew Tridgell 1992-1998, - Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - Copyright (C) Paul Ashton 1997-1998. - Copyright (C) Jeremy Allison 1999. - Copyright (C) Simo Sorce 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Shutdown a server */ - -NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, - const char *msg, uint32 timeout, uint16 flags) -{ - prs_struct qbuf; - prs_struct rbuf; - REG_Q_SHUTDOWN q_s; - REG_R_SHUTDOWN r_s; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - if (msg == NULL) return NT_STATUS_INVALID_PARAMETER; - - ZERO_STRUCT (q_s); - ZERO_STRUCT (r_s); - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_shutdown(&q_s, msg, timeout, flags); - - if (!reg_io_q_shutdown("", &q_s, &qbuf, 0) || - !rpc_api_pipe_req(cli, REG_SHUTDOWN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if(reg_io_r_shutdown("", &r_s, &rbuf, 0)) - result = r_s.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; -} - - -/* Abort a server shutdown */ - -NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx) -{ - prs_struct rbuf; - prs_struct qbuf; - REG_Q_ABORT_SHUTDOWN q_s; - REG_R_ABORT_SHUTDOWN r_s; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT (q_s); - ZERO_STRUCT (r_s); - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_abort_shutdown(&q_s); - - if (!reg_io_q_abort_shutdown("", &q_s, &qbuf, 0) || - !rpc_api_pipe_req(cli, REG_ABORT_SHUTDOWN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0)) - result = r_s.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf ); - - return result; -} diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c deleted file mode 100644 index 6581bdbeaf..0000000000 --- a/source3/libsmb/cli_samr.c +++ /dev/null @@ -1,1404 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - Copyright (C) Andrew Tridgell 1992-1997,2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, - Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000, - Copyright (C) Rafal Szczesniak 2002. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Connect to SAMR database */ - -NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 access_mask, POLICY_HND *connect_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CONNECT q; - SAMR_R_CONNECT r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_connect(&q, cli->desthost, access_mask); - - if (!samr_io_q_connect("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_connect("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *connect_pol = r.connect_pol; -#ifdef __INSURE__ - connect_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Close SAMR handle */ - -NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CLOSE_HND q; - SAMR_R_CLOSE_HND r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_close_hnd(&q, connect_pol); - - if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { -#ifdef __INSURE__ - SAFE_FREE(connect_pol->marker); -#endif - *connect_pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a domain */ - -NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol, uint32 access_mask, - const DOM_SID *domain_sid, POLICY_HND *domain_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_DOMAIN q; - SAMR_R_OPEN_DOMAIN r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid); - - if (!samr_io_q_open_domain("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_domain("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *domain_pol = r.domain_pol; -#ifdef __INSURE__ - domain_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a user */ - -NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 user_rid, POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_USER q; - SAMR_R_OPEN_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_user(&q, domain_pol, access_mask, user_rid); - - if (!samr_io_q_open_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_user("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *user_pol = r.user_pol; -#ifdef __INSURE__ - user_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a group */ - -NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 group_rid, POLICY_HND *group_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_GROUP q; - SAMR_R_OPEN_GROUP r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_group(&q, domain_pol, access_mask, group_rid); - - if (!samr_io_q_open_group("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_group("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *group_pol = r.pol; -#ifdef __INSURE__ - group_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user info */ - -NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - SAM_USERINFO_CTR **ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERINFO q; - SAMR_R_QUERY_USERINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_userinfo(&q, user_pol, switch_value); - - if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - *ctr = r.ctr; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query group info */ - -NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, uint32 info_level, - GROUP_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_GROUPINFO q; - SAMR_R_QUERY_GROUPINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_groupinfo(&q, group_pol, info_level); - - if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user groups */ - -NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint32 *num_groups, - DOM_GID **gid) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERGROUPS q; - SAMR_R_QUERY_USERGROUPS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_usergroups(&q, user_pol); - - if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_groups = r.num_entries; - *gid = r.gid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user aliases */ - -NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid, - uint32 *num_aliases, uint32 **als_rids) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERALIASES q; - SAMR_R_QUERY_USERALIASES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - unsigned int ptr=1; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid); - - if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_aliases = r.num_entries; - *als_rids = r.rid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user groups */ - -NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, uint32 *num_mem, - uint32 **rid, uint32 **attr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_GROUPMEM q; - SAMR_R_QUERY_GROUPMEM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_groupmem(&q, group_pol); - - if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_mem = r.num_entries; - *rid = r.rid; - *attr = r.attr; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** - * Enumerate domain users - * - * @param cli client state structure - * @param mem_ctx talloc context - * @param pol opened domain policy handle - * @param start_idx starting index of enumeration, returns context for - next enumeration - * @param acb_mask account control bit mask (to enumerate some particular - * kind of accounts) - * @param size max acceptable size of response - * @param dom_users returned array of domain user names - * @param rids returned array of domain user RIDs - * @param num_dom_users numer returned entries - * - * @return NTSTATUS returned in rpc response - **/ -NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask, - uint32 size, char ***dom_users, uint32 **rids, - uint32 *num_dom_users) -{ - prs_struct qdata; - prs_struct rdata; - SAMR_Q_ENUM_DOM_USERS q; - SAMR_R_ENUM_DOM_USERS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - if (cli == NULL || pol == NULL) - return result; - - /* initialise parse structures */ - prs_init(&qdata, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rdata, 0, mem_ctx, UNMARSHALL); - - DEBUG(4, ("SAMR Enum Domain Users. start_idx: %d, acb: %d, size: %d\n", - *start_idx, acb_mask, size)); - - /* fill query structure with parameters */ - init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size); - - /* prepare query stream */ - if (!samr_io_q_enum_dom_users("", &q, &qdata, 0)) { - prs_mem_free(&qdata); - prs_mem_free(&rdata); - return result; - } - - /* send rpc call over the pipe */ - if (!rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qdata, &rdata)) { - prs_mem_free(&qdata); - prs_mem_free(&rdata); - return result; - } - - /* unpack received stream */ - if(!samr_io_r_enum_dom_users("", &r, &rdata, 0)) { - prs_mem_free(&qdata); - prs_mem_free(&rdata); - result = r.status; - return result; - } - - /* return the data obtained in response */ - if (!NT_STATUS_IS_OK(r.status) && - (NT_STATUS_EQUAL(r.status, STATUS_MORE_ENTRIES) || - NT_STATUS_EQUAL(r.status, NT_STATUS_NO_MORE_ENTRIES))) { - return r.status; - } - - *start_idx = r.next_idx; - *num_dom_users = r.num_entries2; - result = r.status; - - if (r.num_entries2) { - /* allocate memory needed to return received data */ - *rids = (uint32*)talloc(mem_ctx, sizeof(uint32) * r.num_entries2); - if (!*rids) { - DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - *dom_users = (char**)talloc(mem_ctx, sizeof(char*) * r.num_entries2); - if (!*dom_users) { - DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n")); - return NT_STATUS_NO_MEMORY; - } - - /* fill output buffers with rpc response */ - for (i = 0; i < r.num_entries2; i++) { - fstring conv_buf; - - (*rids)[i] = r.sam[i].rid; - unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1); - (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf); - } - } - - prs_mem_free(&qdata); - prs_mem_free(&rdata); - - return result; -}; - - -/* Enumerate domain groups */ - -NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, - uint32 size, struct acct_info **dom_groups, - uint32 *num_dom_groups) -{ - prs_struct qbuf, rbuf; - SAMR_Q_ENUM_DOM_GROUPS q; - SAMR_R_ENUM_DOM_GROUPS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 name_idx, i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_enum_dom_groups(&q, pol, *start_idx, size); - - if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) - goto done; - - *num_dom_groups = r.num_entries2; - - if (!((*dom_groups) = (struct acct_info *) - talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); - - name_idx = 0; - - for (i = 0; i < *num_dom_groups; i++) { - - (*dom_groups)[i].rid = r.sam[i].rid; - - if (r.sam[i].hdr_name.buffer) { - unistr2_to_ascii((*dom_groups)[i].acct_name, - &r.uni_grp_name[name_idx], - sizeof(fstring) - 1); - name_idx++; - } - - *start_idx = r.next_idx; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enumerate domain groups */ - -NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, - uint32 size, struct acct_info **dom_groups, - uint32 *num_dom_groups) -{ - prs_struct qbuf, rbuf; - SAMR_Q_ENUM_DOM_ALIASES q; - SAMR_R_ENUM_DOM_ALIASES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 name_idx, i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size); - - if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { - goto done; - } - - *num_dom_groups = r.num_entries2; - - if (!((*dom_groups) = (struct acct_info *) - talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); - - name_idx = 0; - - for (i = 0; i < *num_dom_groups; i++) { - - (*dom_groups)[i].rid = r.sam[i].rid; - - if (r.sam[i].hdr_name.buffer) { - unistr2_to_ascii((*dom_groups)[i].acct_name, - &r.uni_grp_name[name_idx], - sizeof(fstring) - 1); - name_idx++; - } - - *start_idx = r.next_idx; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query alias members */ - -NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *alias_pol, uint32 *num_mem, - DOM_SID **sids) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_ALIASMEM q; - SAMR_R_QUERY_ALIASMEM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_aliasmem(&q, alias_pol); - - if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - *num_mem = r.num_sids; - - if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < *num_mem; i++) { - (*sids)[i] = r.sid[i].sid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on an alias */ - -NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 alias_rid, POLICY_HND *alias_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_ALIAS q; - SAMR_R_OPEN_ALIAS r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid); - - if (!samr_io_q_open_alias("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_open_alias("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *alias_pol = r.pol; -#ifdef __INSURE__ - alias_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query domain info */ - -NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint16 switch_value, - SAM_UNK_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_DOMAIN_INFO q; - SAMR_R_QUERY_DOMAIN_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_dom_info(&q, domain_pol, switch_value); - - if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query display info */ - -NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 *start_idx, - uint16 switch_value, uint32 *num_entries, - uint32 max_entries, SAM_DISPINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_DISPINFO q; - SAMR_R_QUERY_DISPINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_dispinfo(&q, domain_pol, switch_value, - *start_idx, max_entries); - - if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { - goto done; - } - - *num_entries = r.num_entries; - *start_idx += r.num_entries; /* No next_idx in this structure! */ - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are - looked up in one packet. */ - -NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 flags, - uint32 num_rids, uint32 *rids, - uint32 *num_names, char ***names, - uint32 **name_types) -{ - prs_struct qbuf, rbuf; - SAMR_Q_LOOKUP_RIDS q; - SAMR_R_LOOKUP_RIDS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - if (num_rids > 1000) { - DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if " - "more than ~1000 rids are looked up at once.\n")); - } - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags, - num_rids, rids); - - if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.num_names1 == 0) { - *num_names = 0; - *names = NULL; - goto done; - } - - *num_names = r.num_names1; - *names = talloc(mem_ctx, sizeof(char *) * r.num_names1); - *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1); - - for (i = 0; i < r.num_names1; i++) { - fstring tmp; - - unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1); - (*names)[i] = talloc_strdup(mem_ctx, tmp); - (*name_types)[i] = r.type[i]; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Lookup names */ - -NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 flags, - uint32 num_names, const char **names, - uint32 *num_rids, uint32 **rids, - uint32 **rid_types) -{ - prs_struct qbuf, rbuf; - SAMR_Q_LOOKUP_NAMES q; - SAMR_R_LOOKUP_NAMES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags, - num_names, names); - - if (!samr_io_q_lookup_names("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.num_rids1 == 0) { - *num_rids = 0; - goto done; - } - - *num_rids = r.num_rids1; - *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1); - *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1); - - for (i = 0; i < r.num_rids1; i++) { - (*rids)[i] = r.rids[i]; - (*rid_types)[i] = r.types[i]; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Create a domain user */ - -NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, const char *acct_name, - uint32 acb_info, uint32 unknown, - POLICY_HND *user_pol, uint32 *rid) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CREATE_USER q; - SAMR_R_CREATE_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown); - - if (!samr_io_q_create_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_create_user("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (user_pol) - *user_pol = r.user_pol; - - if (rid) - *rid = r.user_rid; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set userinfo */ - -NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_SET_USERINFO q; - SAMR_R_SET_USERINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - q.ctr = ctr; - - init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, - ctr->info.id); - - if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set userinfo2 */ - -NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_SET_USERINFO2 q; - SAMR_R_SET_USERINFO2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr); - - if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Delete domain user */ - -NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_DELETE_DOM_USER q; - SAMR_R_DELETE_DOM_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_delete_dom_user(&q, user_pol); - - if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user security object */ - -NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_SEC_OBJ q; - SAMR_R_QUERY_SEC_OBJ r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_sec_obj(&q, user_pol, switch_value); - - if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get domain password info */ - -NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint16 *unk_0, uint16 *unk_1, uint16 *unk_2) -{ - prs_struct qbuf, rbuf; - SAMR_Q_GET_DOM_PWINFO q; - SAMR_R_GET_DOM_PWINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_get_dom_pwinfo(&q, cli->desthost); - - if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - if (unk_0) - *unk_0 = r.unk_0; - if (unk_1) - *unk_1 = r.unk_1; - if (unk_2) - *unk_2 = r.unk_2; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c deleted file mode 100644 index 18e17758d6..0000000000 --- a/source3/libsmb/cli_spoolss.c +++ /dev/null @@ -1,2156 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - - Copyright (C) Gerald Carter 2001-2002, - Copyright (C) Tim Potter 2000-2002, - Copyright (C) Andrew Tridgell 1994-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean-Francois Micouleau 1999-2000. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** @defgroup spoolss SPOOLSS - NT printing routines - * @ingroup rpc_client - * - * @{ - **/ - -/********************************************************************** - Initialize a new spoolss buff for use by a client rpc -**********************************************************************/ -static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) -{ - buffer->ptr = (size != 0); - buffer->size = size; - buffer->string_at_end = size; - prs_init(&buffer->prs, size, ctx, MARSHALL); - buffer->struct_start = prs_offset(&buffer->prs); -} - -/********************************************************************* - Decode various spoolss rpc's and info levels - ********************************************************************/ - -/********************************************************************** -**********************************************************************/ -static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 returned, PRINTER_INFO_0 **info) -{ - uint32 i; - PRINTER_INFO_0 *inf; - - inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0)); - - buffer->prs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs, 0); - - for (i=0; iprs, 0); - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs, 0); - - smb_io_driverdir_1("", buffer, inf, 0); - - *info=inf; -} - -/** Return a handle to the specified printer or print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param printername The name of the printer or print server to be - * opened in UNC format. - * - * @param datatype Specifies the default data type for the printer. - * - * @param access_required The access rights requested on the printer or - * print server. - * - * @param station The UNC name of the requesting workstation. - * - * @param username The name of the user requesting the open. - * - * @param pol Returned policy handle. - */ - -/********************************************************************************* - Win32 API - OpenPrinter() - ********************************************************************************/ - -WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *printername, char *datatype, uint32 access_required, - char *station, char *username, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_OPEN_PRINTER_EX q; - SPOOL_R_OPEN_PRINTER_EX r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_open_printer_ex(&q, printername, datatype, - access_required, station, username); - - /* Marshall data and send request */ - - if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *pol = r.handle; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Close a printer handle - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param pol Policy handle of printer or print server to close. - */ -/********************************************************************************* - Win32 API - ClosePrinter() - ********************************************************************************/ - -WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_CLOSEPRINTER q; - SPOOL_R_CLOSEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_closeprinter(&q, pol); - - /* Marshall data and send request */ - - if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *pol = r.handle; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate printers on a print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * - * @param flags Selected from PRINTER_ENUM_* flags. - * @param level Request information level. - * - * @param num_printers Pointer to number of printers returned. May be - * NULL. - * @param ctr Return structure for printer information. May - * be NULL. - */ -/********************************************************************************* - Win32 API - EnumPrinters() - ********************************************************************************/ - -WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 flags, uint32 level, - uint32 *num_printers, PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERS q; - SPOOL_R_ENUMPRINTERS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - if (num_printers) - *num_printers = r.returned; - - if (!ctr) - goto done; - - switch (level) { - case 0: - decode_printer_info_0(mem_ctx, r.buffer, r.returned, - &ctr->printers_0); - break; - case 1: - decode_printer_info_1(mem_ctx, r.buffer, r.returned, - &ctr->printers_1); - break; - case 2: - decode_printer_info_2(mem_ctx, r.buffer, r.returned, - &ctr->printers_2); - break; - case 3: - decode_printer_info_3(mem_ctx, r.buffer, r.returned, - &ctr->printers_3); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - EnumPorts() - ********************************************************************************/ -/** Enumerate printer ports on a print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * May be NULL. - * - * @param level Requested information level. - * - * @param num_ports Pointer to number of ports returned. May be NULL. - * @param ctr Pointer to structure holding port information. - * May be NULL. - */ - -WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, int *num_ports, PORT_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPORTS q; - SPOOL_R_ENUMPORTS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_enumports(&q, server, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumports("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_enumports("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(result)) - goto done; - - if (num_ports) - *num_ports = r.returned; - - if (!ctr) - goto done; - - switch (level) { - case 1: - decode_port_info_1(mem_ctx, r.buffer, r.returned, - &ctr->port.info_1); - break; - case 2: - decode_port_info_2(mem_ctx, r.buffer, r.returned, - &ctr->port.info_2); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinter() - ********************************************************************************/ - -WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTER q; - SPOOL_R_GETPRINTER r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprinter("", &r, &rbuf, 0)) - goto done; - - if (needed) - *needed = r.needed; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) { - switch (level) { - case 0: - decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); - break; - case 1: - decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1); - break; - case 2: - decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2); - break; - case 3: - decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - SetPrinter() - ********************************************************************************/ -/** Set printer info - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param pol Policy handle on printer to set info. - * @param level Information level to set. - * @param ctr Pointer to structure holding printer information. - * @param command Specifies the action performed. See - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp - * for details. - * - */ - -WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTER q; - SPOOL_R_SETPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) - goto done; - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinterDriver() - ********************************************************************************/ -/** Get installed printer drivers for a given printer - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * - * @param pol Pointer to an open policy handle for the printer - * opened with cli_spoolss_open_printer_ex(). - * @param level Requested information level. - * @param env The print environment or archictecture. This is - * "Windows NT x86" for NT4. - * @param ctr Returned printer driver information. - */ - -WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *pol, uint32 level, - char *env, PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDRIVER2 q; - SPOOL_R_GETPRINTERDRIVER2 r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - fstrcpy (server, cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2, - &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(result)) - goto done; - - if (!ctr) - goto done; - - switch (level) { - case 1: - decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1); - break; - case 2: - decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2); - break; - case 3: - decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - EnumPrinterDrivers() - ********************************************************************************/ -/********************************************************************** - * Get installed printer drivers for a given printer - */ -WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, char *env, - uint32 *num_drivers, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDRIVERS q; - SPOOL_R_ENUMPRINTERDRIVERS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) - goto done; - - if (needed) - *needed = r.needed; - - if (num_drivers) - *num_drivers = r.returned; - - result = r.status; - - /* Return output parameters */ - - if (W_ERROR_IS_OK(result) && (r.returned != 0)) { - *num_drivers = r.returned; - - switch (level) { - case 1: - decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1); - break; - case 2: - decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2); - break; - case 3: - decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - - -/********************************************************************************* - Win32 API - GetPrinterDriverDirectory() - ********************************************************************************/ -/********************************************************************** - * Get installed printer drivers for a given printer - */ -WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, char *env, - DRIVER_DIRECTORY_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDRIVERDIR q; - SPOOL_R_GETPRINTERDRIVERDIR r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, - &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) { - switch (level) { - case 1: - decode_printerdriverdir_1(mem_ctx, r.buffer, 1, - &ctr->info1); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - AddPrinterDriver() - ********************************************************************************/ -/********************************************************************** - * Install a printer driver - */ -WERROR cli_spoolss_addprinterdriver (struct cli_state *cli, - TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTERDRIVER q; - SPOOL_R_ADDPRINTERDRIVER r; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - AddPrinter() - ********************************************************************************/ -/********************************************************************** - * Install a printer - */ -WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTEREX q; - SPOOL_R_ADDPRINTEREX r; - WERROR result = W_ERROR(ERRgeneral); - fstring server, - client, - user; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (client); - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - fstrcpy (user, cli->user_name); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, - level, ctr); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - DeltePrinterDriver() - ********************************************************************************/ -/********************************************************************** - * Delete a Printer Driver from the server (does not remove - * the driver files - */ -WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, - TALLOC_CTX *mem_ctx, char *arch, - char *driver) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEPRINTERDRIVER q; - SPOOL_R_DELETEPRINTERDRIVER r; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - - /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Write the request */ - - make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinterProcessorDirectory() - ********************************************************************************/ - -WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - char *name, char *environment, - fstring procdir) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTPROCESSORDIRECTORY q; - SPOOL_R_GETPRINTPROCESSORDIRECTORY r; - int level = 1; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - make_spoolss_q_getprintprocessordirectory( - &q, name, environment, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, - &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (W_ERROR_IS_OK(result)) - fstrcpy(procdir, "Not implemented!"); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Add a form to a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param level Form info level to add - should always be 1. - * @param form A pointer to the form to be added. - * - */ - -WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, uint32 level, FORM *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDFORM q; - SPOOL_R_ADDFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_addform(&q, handle, level, form); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Set a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param level Form info level to set - should always be 1. - * @param form A pointer to the form to be set. - * - */ - -WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, uint32 level, char *form_name, - FORM *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETFORM q; - SPOOL_R_SETFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setform(&q, handle, level, form_name, form); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Get a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param formname Name of the form to get - * @param level Form info level to get - should always be 1. - * - */ - -WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *handle, char *formname, uint32 level, - FORM_1 *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETFORM q; - SPOOL_R_GETFORM r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getform(&q, handle, formname, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (W_ERROR_IS_OK(result)) - smb_io_form_1("", r.buffer, form, 0); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Delete a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param form The name of the form to delete. - * - */ - -WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, char *form_name) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEFORM q; - SPOOL_R_DELETEFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_deleteform(&q, handle, form_name); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_forms, FORM_1 **forms) -{ - int i; - - *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_forms; i++) - smb_io_form_1("", buffer, &((*forms)[i]), 0); -} - -/** Enumerate forms - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * or cli_spoolss_addprinterex. - * @param level Form info level to get - should always be 1. - * @param handle Open policy handle - * - */ - -WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *handle, int level, uint32 *num_forms, - FORM_1 **forms) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMFORMS q; - SPOOL_R_ENUMFORMS r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumforms(&q, handle, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumforms("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (num_forms) - *num_forms = r.numofforms; - - decode_forms_1(mem_ctx, r.buffer, *num_forms, forms); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_1 **jobs) -{ - uint32 i; - - *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_jobs; i++) - smb_io_job_info_1("", buffer, &((*jobs)[i]), 0); -} - -static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_2 **jobs) -{ - uint32 i; - - *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_jobs; i++) - smb_io_job_info_2("", buffer, &((*jobs)[i]), 0); -} - -/* Enumerate jobs */ - -WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 level, uint32 firstjob, - uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMJOBS q; - SPOOL_R_ENUMJOBS r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumjobs("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMJOBS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumjobs("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - *returned = r.returned; - - switch(level) { - case 1: - decode_jobs_1(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_1); - break; - case 2: - decode_jobs_2(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_2); - break; - default: - DEBUG(3, ("unsupported info level %d", level)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set job */ - -WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 jobid, uint32 level, - uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETJOB q; - SPOOL_R_SETJOB r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setjob(&q, hnd, jobid, level, command); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setjob("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setjob("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get job */ - -WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 jobid, uint32 level, - JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETJOB q; - SPOOL_R_GETJOB r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getjob("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getjob("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - switch(level) { - case 1: - decode_jobs_1(mem_ctx, r.buffer, 1, ctr->job.job_info_1); - break; - case 2: - decode_jobs_2(mem_ctx, r.buffer, 1, ctr->job.job_info_2); - break; - default: - DEBUG(3, ("unsupported info level %d", level)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Startpageprinter. Sent to notify the spooler when a page is about to be - sent to a printer. */ - -WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_STARTPAGEPRINTER q; - SPOOL_R_STARTPAGEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_startpageprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Endpageprinter. Sent to notify the spooler when a page has finished - being sent to a printer. */ - -WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENDPAGEPRINTER q; - SPOOL_R_ENDPAGEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_endpageprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Startdocprinter. Sent to notify the spooler that a document is about - to be spooled for printing. */ - -WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *docname, - char *outputfile, char *datatype, - uint32 *jobid) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_STARTDOCPRINTER q; - SPOOL_R_STARTDOCPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - uint32 level = 1; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile, - datatype); - - /* Marshall data and send request */ - - if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *jobid = r.jobid; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enddocprinter. Sent to notify the spooler that a document has finished - being spooled. */ - -WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENDDOCPRINTER q; - SPOOL_R_ENDDOCPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enddocprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get printer data */ - -WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, char *valuename, - uint32 *data_type, char **data, - uint32 *data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDATA q; - SPOOL_R_GETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getprinterdata(&q, hnd, valuename, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - /* Return output parameters */ - - if (data_type) - *data_type = r.type; - - if (data) { - *data = (char *)talloc(mem_ctx, r.needed); - memcpy(*data, r.data, r.needed); - } - - if (data_size) - *data_size = r.needed; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set printer data */ - -WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *value, - uint32 data_type, char *data, - uint32 data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTERDATA q; - SPOOL_R_SETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enum printer data */ - -WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 ndx, - uint32 value_offered, uint32 data_offered, - uint32 *value_needed, uint32 *data_needed, - char **value, uint32 *data_type, char **data, - uint32 *data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDATA q; - SPOOL_R_ENUMPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - /* Return data */ - - if (value_needed) - *value_needed = r.realvaluesize; - - if (data_needed) - *data_needed = r.realdatasize; - - if (data_type) - *data_type = r.type; - - if (value) { - fstring the_value; - - rpcstr_pull(the_value, r.value, sizeof(the_value), -1, - STR_TERMINATE); - - *value = talloc_strdup(mem_ctx, the_value); - } - - if (data) - *data = talloc_memdup(mem_ctx, r.data, r.realdatasize); - - if (data_size) - *data_size = r.realdatasize; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Write data to printer */ - -WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 data_size, char *data, - uint32 *num_written) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_WRITEPRINTER q; - SPOOL_R_WRITEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_writeprinter(&q, hnd, data_size, data); - - /* Marshall data and send request */ - - if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - if (num_written) - *num_written = r.buffer_written; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Delete printer data */ - -WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *valuename) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEPRINTERDATA q; - SPOOL_R_DELETEPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_deleteprinterdata(&q, hnd, valuename); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** @} **/ diff --git a/source3/libsmb/cli_spoolss_notify.c b/source3/libsmb/cli_spoolss_notify.c deleted file mode 100644 index 922b0fbb1d..0000000000 --- a/source3/libsmb/cli_spoolss_notify.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - - Copyright (C) Gerald Carter 2001-2002, - Copyright (C) Tim Potter 2000-2002, - Copyright (C) Andrew Tridgell 1994-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean-Francois Micouleau 1999-2000. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* - * SPOOLSS Client RPC's used by servers as the notification - * back channel. - */ - -/* Send a ReplyOpenPrinter request. This rpc is made by the printer - server to the printer client in response to a rffpcnex request. - The rrfpcnex request names a printer and a handle (the printerlocal - value) and this rpc establishes a back-channel over which printer - notifications are performed. */ - -WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *printer, uint32 printerlocal, uint32 type, - POLICY_HND *handle) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLYOPENPRINTER q; - SPOOL_R_REPLYOPENPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type); - - /* Marshall data and send request */ - - if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0)) - goto done; - - /* Return result */ - - memcpy(handle, &r.handle, sizeof(r.handle)); - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Close a back-channel notification connection */ - -WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLYCLOSEPRINTER q; - SPOOL_R_REPLYCLOSEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_reply_closeprinter(&q, handle); - - /* Marshall data and send request */ - - if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0)) - goto done; - - /* Return result */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************* - This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change - notification event when the registration **did not** use - SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor. - Also see cli_spolss_reply_rrpcn() - *********************************************************************/ - -WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 condition, uint32 change_id) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ROUTERREPLYPRINTER q; - SPOOL_R_ROUTERREPLYPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id); - - /* Marshall data and send request */ - - if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************* - This SPOOLSS_REPLY_RRPCN function is used to send a change - notification event when the registration **did** use - SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor - Also see cli_spoolss_routereplyprinter() - *********************************************************************/ - -WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 notify_data_len, - SPOOL_NOTIFY_INFO_DATA *notify_data, - uint32 change_low, uint32 change_high) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLY_RRPCN q; - SPOOL_R_REPLY_RRPCN r; - WERROR result = W_ERROR(ERRgeneral); - SPOOL_NOTIFY_INFO notify_info; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - ZERO_STRUCT(notify_info); - - /* Initialise input parameters */ - - notify_info.version = 0x2; - notify_info.flags = 0x00020000; /* ?? */ - notify_info.count = notify_data_len; - notify_info.data = notify_data; - - /* create and send a MSRPC command with api */ - /* store the parameters */ - - make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high, - ¬ify_info); - - /* Marshall data and send request */ - - if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0)) - goto done; - - if (r.unknown0 == 0x00080000) - DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c deleted file mode 100644 index 1bdd19620b..0000000000 --- a/source3/libsmb/cli_srvsvc.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Tim Potter 2001 - Copyright (C) Jim McDonough 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 switch_value, SRV_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SRV_GET_INFO q; - SRV_R_NET_SRV_GET_INFO r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value); - - /* Marshall data and send request */ - - if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 info_level, SRV_SHARE_INFO_CTR *ctr, - int preferred_len, ENUM_HND *hnd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_ENUM q; - SRV_R_NET_SHARE_ENUM r; - WERROR result = W_ERROR(ERRgeneral); - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_share_enum( - &q, cli->srv_name_slash, info_level, preferred_len, hnd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_enum("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - /* Oh yuck yuck yuck - we have to copy all the info out of the - SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a - prs_mem_free() it will all be invalidated. The various share - info structures suck badly too. This really is gross. */ - - ZERO_STRUCTP(ctr); - - if (!r.ctr.num_entries) - goto done; - - ctr->info_level = info_level; - ctr->num_entries = r.ctr.num_entries; - - switch(info_level) { - case 1: - ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc( - mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries); - - memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1)); - - for (i = 0; i < ctr->num_entries; i++) { - SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, - sizeof(SH_INFO_1)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname); - if (s) - init_unistr2(&info1->info_1_str.uni_netname, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark); - if (s) - init_unistr2(&info1->info_1_str.uni_remark, s, strlen(s) + 1); - - } - - break; - case 2: - ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc( - mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries); - - memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2)); - - for (i = 0; i < ctr->num_entries; i++) { - SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, - sizeof(SH_INFO_2)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname); - if (s) - init_unistr2(&info2->info_2_str.uni_netname, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark); - if (s) - init_unistr2(&info2->info_2_str.uni_remark, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path); - if (s) - init_unistr2(&info2->info_2_str.uni_path, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd); - if (s) - init_unistr2(&info2->info_2_str.uni_passwd, s, strlen(s) + 1); - } - break; - } - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx, - const char *sharename) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_DEL q; - SRV_R_NET_SHARE_DEL r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_del("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_del("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *netname, uint32 type, char *remark, - uint32 perms, uint32 max_uses, uint32 num_uses, - char *path, char *passwd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_ADD q; - SRV_R_NET_SHARE_ADD r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark, - perms, max_uses, num_uses, path, passwd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_add("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_add("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *server, TIME_OF_DAY_INFO *tod) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_REMOTE_TOD q; - SRV_R_NET_REMOTE_TOD r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_remote_tod(&q, cli->srv_name_slash); - - /* Marshall data and send request */ - - if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - r.tod = tod; - - if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_level, const char *user_name, - SRV_FILE_INFO_CTR *ctr, int preferred_len, - ENUM_HND *hnd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_FILE_ENUM q; - SRV_R_NET_FILE_ENUM r; - WERROR result = W_ERROR(ERRgeneral); - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name, - file_level, ctr, preferred_len, hnd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_file_enum("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - /* copy the data over to the ctr */ - - ZERO_STRUCTP(ctr); - - ctr->switch_value = file_level; - - ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries; - - switch(file_level) { - case 3: - ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc( - mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries); - - memset(ctr->file.info3, 0, - sizeof(SRV_FILE_INFO_3) * ctr->num_entries); - - for (i = 0; i < r.ctr.num_entries; i++) { - SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, - sizeof(FILE_INFO_3)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name); - if (s) - init_unistr2(&info3->info_3_str.uni_path_name, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name); - if (s) - init_unistr2(&info3->info_3_str.uni_user_name, s, strlen(s) + 1); - - } - - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_id) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_FILE_CLOSE q; - SRV_R_NET_FILE_CLOSE r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id); - - /* Marshall data and send request */ - - if (!srv_io_q_net_file_close("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_file_close("", &r, &rbuf, 0)) - goto done; - - result = r.status; - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return result; -} diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c deleted file mode 100644 index 97b948bf62..0000000000 --- a/source3/libsmb/cli_wkssvc.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Tim Potter 2001 - Copytight (C) Rafal Szczesniak 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** - * WksQueryInfo rpc call (like query for server's capabilities) - * - * @param initialised client structure with \PIPE\wkssvc opened - * @param mem_ctx memory context assigned to this rpc binding - * @param wks100 WksQueryInfo structure - * - * @return NTSTATUS of rpc call - */ - -NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - WKS_INFO_100 *wks100) -{ - prs_struct buf; - prs_struct rbuf; - WKS_Q_QUERY_INFO q_o; - WKS_R_QUERY_INFO r_o; - - if (cli == NULL || wks100 == NULL) - return NT_STATUS_UNSUCCESSFUL; - - /* init rpc parse structures */ - prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - DEBUG(4, ("WksQueryInfo\n")); - - /* init query structure with rpc call arguments */ - init_wks_q_query_info(&q_o, cli->desthost, 100); - - /* marshall data */ - if (!wks_io_q_query_info("", &q_o, &buf, 0)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - /* actual rpc call over \PIPE\wkssvc */ - if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - prs_mem_free(&buf); - - r_o.wks100 = wks100; - - /* get call results from response buffer */ - if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) { - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - /* check returnet status code */ - if (NT_STATUS_IS_ERR(r_o.status)) { - /* report the error */ - DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status))); - prs_mem_free(&rbuf); - return r_o.status; - } - - /* do clean up */ - prs_mem_free(&rbuf); - - return NT_STATUS_OK; -} - -- cgit From c7597b144a633948e0fed3c5916fe5f36bb4cc99 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Aug 2002 01:55:44 +0000 Subject: fixed a bug where we were truncating the returned names in a netbios name status query to 14 bytes, so we could not join a DC who had a netbios name of 15 bytes in length. (This used to be commit a7588f21c24dac833f098c48e2337c100cf75ba4) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index ae58c3a062..141581e261 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -196,7 +196,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE); + pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE); result = True; done: -- cgit From ab9ff0fa73f33c064a39859e39fa79af77cc088f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 5 Aug 2002 02:47:46 +0000 Subject: This fixes a number of ADS problems, particularly with netbiosless setups. - split up the ads structure into logical pieces. This makes it much easier to keep things like the authentication realm and the server realm separate (they can be different). - allow ads callers to specify that no sasl bind should be performed (used by "net ads info" for example) - fix an error with handing ADS_ERROR_SYSTEM() when errno is 0 - completely rewrote the code for finding the LDAP server. Now try DNS methods first, and try all DNS servers returned from the SRV DNS query, sorted by closeness to our interfaces (using the same sort code as we use in replies from WINS servers). This allows us to cope with ADS DCs that are down, and ensures we don't pick one that is on the other side of the country unless absolutely necessary. - recognise dnsRecords as binary when displaying them - cope with the realm not being configured in smb.conf (work it out from the LDAP server) - look at the trustDirection when looking up trusted domains and don't include trusts that trust our domains but we don't trust theirs. - use LDAP to query the alternate (netbios) name for a realm, and make sure that both and long and short forms of the name are accepted by winbindd. Use the short form by default for listing users/groups. - rescan the list of trusted domains every 5 minutes in case new trust relationships are added while winbindd is running - include transient trust relationships (ie. C trusts B, B trusts A, so C trusts A) in winbindd. - don't do a gratuituous node status lookup when finding an ADS DC (we don't need it and it could fail) - remove unused sid_to_distinguished_name function - make sure we find the allternate name of our primary domain when operating with a netbiosless ADS DC (using LDAP to do the lookup) - fixed the rpc trusted domain enumeration to support up to approx 2000 trusted domains (the old limit was 3) - use the IP for the remote_machine (%m) macro when the client doesn't supply us with a name via a netbios session request (eg. port 445) - if the client uses SPNEGO then use the machine name from the SPNEGO auth packet for remote_machine (%m) macro - add new 'net ads workgroup' command to find the netbios workgroup name for a realm (This used to be commit e358d7b24c86a46d8c361b9e32a25d4f71a6dc00) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 141581e261..3382ce4f4a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -216,7 +216,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t /* comparison function used by sort_ip_list */ -static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +int ip_compare(struct in_addr *ip1, struct in_addr *ip2) { int max_bits1=0, max_bits2=0; int num_interfaces = iface_count(); -- cgit From ec7927a1445cebcfb58a0f613dd9d601390c8c76 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 15 Aug 2002 12:18:25 +0000 Subject: Fix NTLMSSP challenge command and auth response. We can now service joins from win2k AND still use SPNEGO (provided you don't build with kerberos...I still have to fix that, as we are not properly falling back). (This used to be commit 1f9b3d46c7c99e84b2983220f79613b7420c5ced) --- source3/libsmb/clispnego.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 469b946088..16702c375b 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -439,6 +440,28 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) return True; } +/* + generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. +*/ +DATA_BLOB spnego_gen_auth_response(void) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_CONTEXT(1)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_write_enumerated(&data, 0); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + ret = data_blob(data.data, data.length); + asn1_free(&data); + return ret; +} /* this is a tiny msrpc packet generator. I am only using this to @@ -449,6 +472,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) format specifiers are: U = unicode string (input is unix string) + a = address (1 byte type, 1 byte length, unicode string, all inline) B = data blob (pointer + length) b = data blob in header (pointer + length) d = word (4 bytes) @@ -473,6 +497,11 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += str_charnum(s) * 2; break; + case 'a': + n = va_arg(ap, int); + s = va_arg(ap, char *); + data_size += (str_charnum(s) * 2) + 4; + break; case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -512,6 +541,19 @@ BOOL msrpc_gen(DATA_BLOB *blob, push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); data_ofs += n*2; break; + case 'a': + n = va_arg(ap, int); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + break; + case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -550,6 +592,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, format specifiers are: U = unicode string (output is unix string) + A = ascii string B = data blob b = data blob in header d = word (4 bytes) @@ -584,6 +627,24 @@ BOOL msrpc_parse(DATA_BLOB *blob, STR_UNICODE|STR_NOALIGN); (*ps) = strdup(p); break; + case 'A': + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + ps = va_arg(ap, char **); + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, -1, + len1, STR_ASCII|STR_NOALIGN); + (*ps) = strdup(p); + } else { + (*ps) = NULL; + } + break; case 'B': len1 = SVAL(blob->data, head_ofs); head_ofs += 2; len2 = SVAL(blob->data, head_ofs); head_ofs += 2; -- cgit From 88d321becdcff10f52a629946fb300d158fcc2fa Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 16 Aug 2002 00:25:48 +0000 Subject: Merge of netbios namecache code from APPLIANCE_HEAD. Tridge suggested a generic caching mechanism for Samba to avoid the proliferation of little cache files hanging around limpet like in the locks directory. Someone should probably implement this at some stage. (This used to be commit dad31483b3bd1790356ef1e40ac62624a403bce8) --- source3/libsmb/namecache.c | 252 +++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/namequery.c | 28 ++++- 2 files changed, 276 insertions(+), 4 deletions(-) create mode 100644 source3/libsmb/namecache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c new file mode 100644 index 0000000000..fc09d8eac2 --- /dev/null +++ b/source3/libsmb/namecache.c @@ -0,0 +1,252 @@ +/* + Unix SMB/CIFS implementation. + + NetBIOS name cache module. + + Copyright (C) Tim Potter, 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +static BOOL done_namecache_init; +static BOOL enable_namecache; +static TDB_CONTEXT *namecache_tdb; + +struct nc_value { + time_t expiry; /* When entry expires */ + int count; /* Number of addresses */ + struct in_addr ip_list[0]; /* Address list */ +}; + +/* Initialise namecache system */ + +void namecache_enable(void) +{ + /* Check if we have been here before, or name caching disabled + by setting the name cache timeout to zero. */ + + if (done_namecache_init) + return; + + done_namecache_init = True; + + if (lp_name_cache_timeout() == 0) { + DEBUG(5, ("namecache_init: disabling netbios name cache\n")); + return; + } + + /* Open namecache tdb in read/write or readonly mode */ + + namecache_tdb = tdb_open_log( + lock_path("namecache.tdb"), 0, + TDB_DEFAULT, O_RDWR | O_CREAT, 0644); + + if (!namecache_tdb) { + DEBUG(5, ("namecache_init: could not open %s\n", + lock_path("namecache.tdb"))); + return; + } + + DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d " + "seconds\n", lp_name_cache_timeout())); + + enable_namecache = True; +} + +/* Return a key for a name and name type. The caller must free + retval.dptr when finished. */ + +static TDB_DATA namecache_key(const char *name, int name_type) +{ + TDB_DATA retval; + char *keystr; + + asprintf(&keystr, "%s#%02X", strupper_static(name), name_type); + + retval.dsize = strlen(keystr) + 1; + retval.dptr = keystr; + + return retval; +} + +/* Return a data value for an IP list. The caller must free + retval.dptr when finished. */ + +static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, + time_t expiry) +{ + TDB_DATA retval; + struct nc_value *value; + int size; + + size = sizeof(struct nc_value) + sizeof(struct in_addr) * + num_names; + + value = (struct nc_value *)malloc(size); + + value->expiry = expiry; + value->count = num_names; + + memcpy(value->ip_list, ip_list, num_names * sizeof(struct in_addr)); + + retval.dptr = (char *)value; + retval.dsize = size; + + return retval; +} + +/* Store a name in the name cache */ + +void namecache_store(const char *name, int name_type, + int num_names, struct in_addr *ip_list) +{ + TDB_DATA key, value; + time_t expiry; + int i; + + if (!enable_namecache) + return; + + DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", + num_names, num_names == 1 ? "": "es", name, name_type)); + + for (i = 0; i < num_names; i++) + DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]), + i == (num_names - 1) ? "" : ", ")); + + DEBUGADD(5, ("\n")); + + key = namecache_key(name, name_type); + + /* Cache pdc location or dc lists for only a little while + otherwise if we lock on to a bad DC we can potentially be + out of action for the entire cache timeout time! */ + + if (name_type != 0x1b || name_type != 0x1c) + expiry = time(NULL) + 10; + else + expiry = time(NULL) + lp_name_cache_timeout(); + + value = namecache_value(ip_list, num_names, expiry); + + tdb_store(namecache_tdb, key, value, TDB_REPLACE); + + free(key.dptr); + free(value.dptr); +} + +/* Look up a name in the name cache. Return a mallocated list of IP + addresses if the name is contained in the cache. */ + +BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, + int *num_names) +{ + TDB_DATA key, value; + struct nc_value *data; + time_t now; + int i; + + if (!enable_namecache) + return False; + + /* Read value */ + + key = namecache_key(name, name_type); + + value = tdb_fetch(namecache_tdb, key); + + if (!value.dptr) { + DEBUG(5, ("namecache_fetch: %s#%02x not found\n", + name, name_type)); + goto done; + } + + data = (struct nc_value *)value.dptr; + + /* Check expiry time */ + + now = time(NULL); + + if (now > data->expiry) { + + DEBUG(5, ("namecache_fetch: entry for %s#%02x expired\n", + name, name_type)); + + tdb_delete(namecache_tdb, key); + + value = tdb_null; + + goto done; + } + + if ((data->expiry - now) > lp_name_cache_timeout()) { + + /* Someone may have changed the system time on us */ + + DEBUG(5, ("namecache_fetch: entry for %s#%02x has bad expiry\n", + name, name_type)); + + tdb_delete(namecache_tdb, key); + + value = tdb_null; + + goto done; + } + + /* Extract and return namelist */ + + *ip_list = (struct in_addr *)malloc( + sizeof(struct in_addr) * data->count); + + memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * + data->count); + + *num_names = data->count; + + DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", + *num_names, *num_names == 1 ? "" : "es", name, name_type)); + + for (i = 0; i < *num_names; i++) + DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), + i == (*num_names - 1) ? "" : ", ")); + + DEBUGADD(5, ("\n")); + +done: + SAFE_FREE(key.dptr); + SAFE_FREE(value.dptr); + + return value.dsize > 0; +} + +/* Flush all names from the name cache */ + +void namecache_flush(void) +{ + int result; + + if (!namecache_tdb) + return; + + result = tdb_traverse(namecache_tdb, tdb_traverse_delete_fn, NULL); + + if (result == -1) + DEBUG(5, ("namecache_flush: error deleting cache entries\n")); + else + DEBUG(5, ("namecache_flush: deleted %d cache entr%s\n", + result, result == 1 ? "y" : "ies")); +} diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 3382ce4f4a..40a353fa8b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -783,7 +783,7 @@ static BOOL resolve_hosts(const char *name, *********************************************************/ static BOOL internal_resolve_name(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) + struct in_addr **return_iplist, int *return_count) { pstring name_resolve_list; fstring tok; @@ -816,6 +816,15 @@ static BOOL internal_resolve_name(const char *name, int name_type, return True; } + /* Check netbios name cache */ + + if (namecache_fetch(name, name_type, return_iplist, return_count)) { + + /* This could be a negative response */ + + return (*return_count > 0); + } + pstrcpy(name_resolve_list, lp_name_resolve_order()); ptr = name_resolve_list; if (!ptr || !*ptr) @@ -823,9 +832,16 @@ static BOOL internal_resolve_name(const char *name, int name_type, while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) { - result = True; - goto done; + if (name_type == 0x20) { + if (resolve_hosts(name, return_iplist, return_count)) { + result = True; + goto done; + } else { + + /* Store negative lookup result */ + + namecache_store(name, name_type, 0, NULL); + } } } else if(strequal( tok, "lmhosts")) { if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { @@ -897,6 +913,10 @@ static BOOL internal_resolve_name(const char *name, int name_type, *return_iplist = nodupes_iplist; *return_count = nodupes_count; } + + /* Save in name cache */ + + namecache_store(name, name_type, *return_count, *return_iplist); /* Display some debugging info */ -- cgit From b2edf254eda92f775e7d3d9b6793b4d77f9000b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/libsmb/cliconnect.c | 47 +++++++++++++++++------------- source3/libsmb/clispnego.c | 61 +++++++++++++++++++++++++++++++++++++++ source3/libsmb/namequery.c | 67 +++++++++++++++++++++++++++++++++++++------ source3/libsmb/smbencrypt.c | 16 +++++------ source3/libsmb/trust_passwd.c | 2 +- 5 files changed, 155 insertions(+), 38 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 472db69fd0..93cf3d95db 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -54,9 +54,6 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, return False; } - /* Lanman2 cannot use SMB signing. */ - cli->sign_info.use_smb_signing = False; - /* if in share level security then don't send a password now */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { passlen = 0; @@ -209,12 +206,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); SSVAL(cli->outbuf,smb_vwv8,0); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - memcpy(p, pword, passlen); - p += passlen; + p += clistr_push(cli, p, pword, -1, STR_TERMINATE); /* password */ + SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); @@ -257,11 +253,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); - fstring pword, ntpword; + uchar pword[24]; + uchar ntpword[24]; char *p; BOOL tried_signing = False; - if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) { + if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { return False; } @@ -269,15 +266,21 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* non encrypted password supplied. Ignore ntpass. */ passlen = 24; ntpasslen = 24; - SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword); - SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword); + SMBencrypt(pass,cli->secblob.data,pword); + SMBNTencrypt(pass,cli->secblob.data,ntpword); if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword); + cli_calculate_mac_key(cli, pass, ntpword); tried_signing = True; } } else { - memcpy(pword, pass, passlen); - memcpy(ntpword, ntpass, ntpasslen); + /* pre-encrypted password supplied. Only used for security=server, can't do + signing becouse we don't have oringial key */ + memcpy(pword, pass, 24); + if (ntpasslen == 24) { + memcpy(ntpword, ntpass, 24); + } else { + ZERO_STRUCT(ntpword); + } } /* send a session setup command */ @@ -305,8 +308,13 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, cli_setup_bcc(cli, p); cli_send_smb(cli); - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + if (tried_signing) { + /* We only use it if we have a successful non-guest connect */ + cli->sign_info.use_smb_signing = False; + } return False; + } show_msg(cli->inbuf); @@ -482,8 +490,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, /* encrypt the password with the challenge */ memcpy(challenge, chal1.data + 24, 8); - SMBencrypt((unsigned char *)pass, challenge,lmhash); - SMBNTencrypt((unsigned char *)pass, challenge,nthash); + SMBencrypt(pass, challenge,lmhash); + SMBNTencrypt(pass, challenge,nthash); #if 0 file_save("nthash.dat", nthash, 24); @@ -1062,7 +1070,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) } if (cli->fd == -1) { DEBUG(1,("Error connecting to %s (%s)\n", - inet_ntoa(*ip),strerror(errno))); + ip?inet_ntoa(*ip):host,strerror(errno))); return False; } @@ -1182,9 +1190,8 @@ again: if (!cli_session_setup(cli, user, password, strlen(password)+1, password, strlen(password)+1, domain)) { - if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) - || cli_session_setup(cli, "", "", 0, - "", 0, domain)) { + if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) + && cli_session_setup(cli, "", "", 0, "", 0, domain)) { } else { nt_status = cli_nt_error(cli); DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 469b946088..16702c375b 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -439,6 +440,28 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) return True; } +/* + generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. +*/ +DATA_BLOB spnego_gen_auth_response(void) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_CONTEXT(1)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_write_enumerated(&data, 0); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + ret = data_blob(data.data, data.length); + asn1_free(&data); + return ret; +} /* this is a tiny msrpc packet generator. I am only using this to @@ -449,6 +472,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) format specifiers are: U = unicode string (input is unix string) + a = address (1 byte type, 1 byte length, unicode string, all inline) B = data blob (pointer + length) b = data blob in header (pointer + length) d = word (4 bytes) @@ -473,6 +497,11 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += str_charnum(s) * 2; break; + case 'a': + n = va_arg(ap, int); + s = va_arg(ap, char *); + data_size += (str_charnum(s) * 2) + 4; + break; case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -512,6 +541,19 @@ BOOL msrpc_gen(DATA_BLOB *blob, push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); data_ofs += n*2; break; + case 'a': + n = va_arg(ap, int); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + break; + case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -550,6 +592,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, format specifiers are: U = unicode string (output is unix string) + A = ascii string B = data blob b = data blob in header d = word (4 bytes) @@ -584,6 +627,24 @@ BOOL msrpc_parse(DATA_BLOB *blob, STR_UNICODE|STR_NOALIGN); (*ps) = strdup(p); break; + case 'A': + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + ps = va_arg(ap, char **); + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, -1, + len1, STR_ASCII|STR_NOALIGN); + (*ps) = strdup(p); + } else { + (*ps) = NULL; + } + break; case 'B': len1 = SVAL(blob->data, head_ofs); head_ofs += 2; len2 = SVAL(blob->data, head_ofs); head_ofs += 2; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 18564bccf4..40a353fa8b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -170,6 +170,11 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t int sock; BOOL result = False; + if (lp_disable_netbios()) { + DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type)); + return False; + } + DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, q_type, inet_ntoa(to_ip))); @@ -191,7 +196,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE); + pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE); result = True; done: @@ -211,7 +216,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t /* comparison function used by sort_ip_list */ -static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +int ip_compare(struct in_addr *ip1, struct in_addr *ip2) { int max_bits1=0, max_bits2=0; int num_interfaces = iface_count(); @@ -273,6 +278,11 @@ struct in_addr *name_query(int fd,const char *name,int name_type, struct nmb_packet *nmb = &p.packet.nmb; struct in_addr *ip_list = NULL; + if (lp_disable_netbios()) { + DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type)); + return NULL; + } + if (timed_out) { *timed_out = False; } @@ -556,6 +566,11 @@ BOOL name_resolve_bcast(const char *name, int name_type, int sock, i; int num_interfaces = iface_count(); + if (lp_disable_netbios()) { + DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type)); + return False; + } + *return_ip_list = NULL; *return_count = 0; @@ -602,6 +617,11 @@ BOOL resolve_wins(const char *name, int name_type, char **wins_tags; struct in_addr src_ip; + if (lp_disable_netbios()) { + DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type)); + return False; + } + *return_iplist = NULL; *return_count = 0; @@ -763,7 +783,7 @@ static BOOL resolve_hosts(const char *name, *********************************************************/ static BOOL internal_resolve_name(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) + struct in_addr **return_iplist, int *return_count) { pstring name_resolve_list; fstring tok; @@ -796,6 +816,15 @@ static BOOL internal_resolve_name(const char *name, int name_type, return True; } + /* Check netbios name cache */ + + if (namecache_fetch(name, name_type, return_iplist, return_count)) { + + /* This could be a negative response */ + + return (*return_count > 0); + } + pstrcpy(name_resolve_list, lp_name_resolve_order()); ptr = name_resolve_list; if (!ptr || !*ptr) @@ -803,9 +832,16 @@ static BOOL internal_resolve_name(const char *name, int name_type, while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) { - result = True; - goto done; + if (name_type == 0x20) { + if (resolve_hosts(name, return_iplist, return_count)) { + result = True; + goto done; + } else { + + /* Store negative lookup result */ + + namecache_store(name, name_type, 0, NULL); + } } } else if(strequal( tok, "lmhosts")) { if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { @@ -877,6 +913,10 @@ static BOOL internal_resolve_name(const char *name, int name_type, *return_iplist = nodupes_iplist; *return_count = nodupes_count; } + + /* Save in name cache */ + + namecache_store(name, name_type, *return_count, *return_iplist); /* Display some debugging info */ @@ -930,11 +970,16 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) Find the IP address of the master browser or DMB for a workgroup. *********************************************************/ -BOOL find_master_ip(char *group, struct in_addr *master_ip) +BOOL find_master_ip(const char *group, struct in_addr *master_ip) { struct in_addr *ip_list = NULL; int count = 0; + if (lp_disable_netbios()) { + DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group)); + return False; + } + if (internal_resolve_name(group, 0x1D, &ip_list, &count)) { *master_ip = ip_list[0]; SAFE_FREE(ip_list); @@ -957,10 +1002,14 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip) BOOL lookup_dc_name(const char *srcname, const char *domain, struct in_addr *dc_ip, char *ret_name) { -#if !defined(I_HATE_WINDOWS_REPLY_CODE) - +#if !defined(I_HATE_WINDOWS_REPLY_CODE) fstring dc_name; BOOL ret; + + if (lp_disable_netbios()) { + DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain)); + return False; + } /* * Due to the fact win WinNT *sucks* we must do a node status diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 95434d0ae4..dfa355a7ec 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -28,7 +28,7 @@ This implements the X/Open SMB password encryption It takes a password ('unix' string), a 8 byte "crypt key" and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24) +void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) { uchar p21[21]; @@ -66,9 +66,9 @@ void E_md4hash(const char *passwd, uchar p16[16]) } /** - * Creates the MD4 Hash of the users password in NT UNICODE. + * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. - * @param p16 return password hashed with md4, caller allocated 16 byte buffer + * @param p16 return password hashed with DES, caller allocated 16 byte buffer */ void E_deshash(const char *passwd, uchar p16[16]) @@ -77,7 +77,7 @@ void E_deshash(const char *passwd, uchar p16[16]) ZERO_STRUCT(dospwd); ZERO_STRUCTP(p16); - /* Password must be converted to DOS charset - null terminated. */ + /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); E_P16(dospwd, p16); @@ -175,7 +175,7 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p /* Does the NT MD4 hash then des encryption. */ -void SMBNTencrypt(const uchar *passwd, uchar *c8, uchar *p24) +void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) { uchar p21[21]; @@ -226,14 +226,14 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ void SMBOWFencrypt_ntv2(const uchar kr[16], const DATA_BLOB srv_chal, const DATA_BLOB cli_chal, - char resp_buf[16]) + uchar resp_buf[16]) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); hmac_md5_update(srv_chal.data, srv_chal.length, &ctx); hmac_md5_update(cli_chal.data, cli_chal.length, &ctx); - hmac_md5_final((unsigned char *)resp_buf, &ctx); + hmac_md5_final(resp_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); @@ -337,7 +337,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, SMB signing - setup the MAC key. ************************************************************/ -void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24]) +void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uchar resp[24]) { /* Get first 16 bytes. */ E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 3b77f7330e..fe6b673e39 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,7 +35,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? + result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { -- cgit From 4b1baa5a70964e94ecc4733a9f8cd3f318c758ea Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 2002 03:17:03 +0000 Subject: added a 'net ads lookup' command that does a CLDAP NetLogon query to a win2000 server. It does seem to work, and win200 sends us a valid reply, but we don't parse it yet. Maybe tomorrow :) (This used to be commit 6352508c54cee333ed7c0e3ebc372be7cd60ed62) --- source3/libsmb/asn1.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index b4ad3ad0b8..c8f832f3df 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -174,6 +174,16 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) return !data->has_error; } +/* write a BOOLEAN - hmm, I suspect this one is the correct one, and the + above boolean is bogus. Need to check */ +BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) +{ + asn1_push_tag(data, ASN1_BOOLEAN); + asn1_write_uint8(data, v); + asn1_pop_tag(data); + return !data->has_error; +} + /* check a BOOLEAN */ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) { -- cgit From e38148f78ca631dcbc8a09616c2c91e5ec64c670 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 2002 15:30:26 +0000 Subject: we now receive and parse the main cldap netlogon reply. we still need to parse the core of the structure (This used to be commit 6780ae25bf7ca291f612682dec7ee7ff44c24bef) --- source3/libsmb/asn1.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index c8f832f3df..358c23c146 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -254,15 +254,12 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) asn1_read_uint8(data, &b); if (b & 0x80) { int n = b & 0x7f; - if (n > 2) { - data->has_error = True; - return False; - } asn1_read_uint8(data, &b); nesting->taglen = b; - if (n == 2) { + while (n > 1) { asn1_read_uint8(data, &b); nesting->taglen = (nesting->taglen << 8) | b; + n--; } } else { nesting->taglen = b; -- cgit From 1040d27b14032cc609f1bffcb0e1c40622e8b536 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 19 Aug 2002 17:49:37 +0000 Subject: fixed memory corruption in cli_full_connection() (This used to be commit 7c2167182becbf72ba062230e911d55d337a4709) --- source3/libsmb/cliconnect.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 93cf3d95db..73846c4d43 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1162,8 +1162,7 @@ again: char *p; DEBUG(1,("session request to %s failed (%s)\n", called.name, cli_errstr(cli))); - cli_shutdown(cli); - if ((p=strchr(called.name, '.'))) { + if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) { *p = 0; goto again; } -- cgit From 03615599919f94c5ed56e9824343b02f4f3e0b71 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 20 Aug 2002 00:20:23 +0000 Subject: fix irix compiler error (This used to be commit 4df7983487545a432cfa8832eae1afbdf7866060) --- source3/libsmb/namecache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index fc09d8eac2..e69d462268 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -29,7 +29,7 @@ static TDB_CONTEXT *namecache_tdb; struct nc_value { time_t expiry; /* When entry expires */ int count; /* Number of addresses */ - struct in_addr ip_list[0]; /* Address list */ + struct in_addr *ip_list; /* Address list */ }; /* Initialise namecache system */ -- cgit From a08427ea6efafd378e8cf207277b00a86ffd4bdd Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 20 Aug 2002 12:38:43 +0000 Subject: cannot use casts in the DLIST_xxx macros (This used to be commit c9ffc416aeee2610fdc896a9d41dac182039a5f9) --- source3/libsmb/libsmb_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 34b818ee74..df02cf3718 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -89,7 +89,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, goto failed; } - DLIST_ADD(((struct smbc_server_cache *)context->server_cache), srvcache); + DLIST_ADD((context->server_cache), srvcache); return 0; failed: @@ -139,7 +139,7 @@ static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) if (server == srv->server) { /* remove this sucker */ - DLIST_REMOVE(((struct smbc_server_cache *)context->server_cache), srv); + DLIST_REMOVE(context->server_cache, srv); SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv->workgroup); -- cgit From d3aa76cef528a15571cade12ebdd10973f4ca579 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 21 Aug 2002 19:59:23 +0000 Subject: Patch from Paul Green to be more POSIX-compatible (This used to be commit addf29e6765393b25c35bd833d29e29e4581c233) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a47c956a55..07b1ff6b6f 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -94,7 +94,7 @@ uint32 unix_perms_to_wire(mode_t perms) ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0); #endif #ifdef S_ISUID - ret |= ((perms & S_ISVTX) ? UNIX_SET_UID : 0); + ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0); #endif return ret; } -- cgit From 39966b7e167736e34874fc0523298877490e0a65 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 21 Aug 2002 23:27:38 +0000 Subject: fix segfault (This used to be commit 982eadf73bb3932ec3ac89c6112a8bf79dbec127) --- source3/libsmb/namecache.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index e69d462268..88dbcf218d 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -29,7 +29,7 @@ static TDB_CONTEXT *namecache_tdb; struct nc_value { time_t expiry; /* When entry expires */ int count; /* Number of addresses */ - struct in_addr *ip_list; /* Address list */ + struct in_addr ip_list[1]; /* Address list */ }; /* Initialise namecache system */ @@ -94,14 +94,14 @@ static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, int size; size = sizeof(struct nc_value) + sizeof(struct in_addr) * - num_names; + (num_names-1); value = (struct nc_value *)malloc(size); value->expiry = expiry; value->count = num_names; - memcpy(value->ip_list, ip_list, num_names * sizeof(struct in_addr)); + memcpy(value->ip_list, ip_list, size); retval.dptr = (char *)value; retval.dsize = size; @@ -210,10 +210,10 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, /* Extract and return namelist */ *ip_list = (struct in_addr *)malloc( - sizeof(struct in_addr) * data->count); + sizeof(struct in_addr) * (data->count-1)); memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * - data->count); + (data->count-1)); *num_names = data->count; -- cgit From 2749f5e998a672e03ac7bbb932b1fd54b7f4a997 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 22 Aug 2002 00:51:00 +0000 Subject: A few fixes towards libsmbclient and rpcclient - get pointer types right and try to keep to functions inside libsmbclient. Andrew Bartlett (This used to be commit 340bc31fdb031d79fa87de27c2c46215dd8113a3) --- source3/libsmb/libsmbclient.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 0ffc1c1378..fa27f54340 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -180,14 +180,13 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, static int smbc_errno(SMBCCTX *context, struct cli_state *c) { - int ret; - + int ret = cli_errno(c); + if (cli_is_dos_error(c)) { uint8 eclass; uint32 ecode; cli_dos_error(c, &eclass, &ecode); - ret = cli_errno_from_dos(eclass, ecode); DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", (int)eclass, (int)ecode, (int)ecode, ret)); @@ -195,10 +194,9 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c) NTSTATUS status; status = cli_nt_error(c); - ret = cli_errno_from_nt(status); DEBUG(3,("smbc errno %s -> %d\n", - get_nt_error_msg(status), ret)); + nt_errstr(status), ret)); } return ret; -- cgit From 7c4d1ba0581dfd152a876f8726124938515410bd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 22 Aug 2002 02:51:32 +0000 Subject: fix a few segfaults (This used to be commit ccb02f7cfcec4a555cf7304816c739f4bf7b46f0) --- source3/libsmb/namecache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 88dbcf218d..f05f76a22b 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -101,7 +101,7 @@ static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, value->expiry = expiry; value->count = num_names; - memcpy(value->ip_list, ip_list, size); + memcpy(value->ip_list, ip_list, sizeof(*ip_list)); retval.dptr = (char *)value; retval.dsize = size; -- cgit From 8e089e8770722d218c76881e3de2138433e3504c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 Aug 2002 22:52:16 +0000 Subject: don't use spnego in the client unless enabled in smb.conf (This used to be commit c00388de6cf5d0527505bfe4edfe2f0269c5a4c8) --- source3/libsmb/clientgen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c9500ead5d..9ae3882301 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -234,7 +234,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - cli->use_spnego = True; + if (lp_use_spnego()) { + cli->use_spnego = True; + } /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 -- cgit From ba2fdbb4c841a917187b512b7021e9da287fe360 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 Aug 2002 22:53:00 +0000 Subject: a ASN.1 fix from anthony (This used to be commit 5ff687a839f805af56ae77cba94c466a0ff87ccc) --- source3/libsmb/asn1.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 358c23c146..b7cfca41fb 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -373,6 +373,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) { int len; + ZERO_STRUCTP(blob); if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; len = asn1_tag_remaining(data); *blob = data_blob(NULL, len); @@ -389,7 +390,8 @@ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) if (!asn1_start_tag(data, ASN1_INTEGER)) return False; while (asn1_tag_remaining(data)>0) { - *i = (*i << 8) + asn1_read_uint8(data, &b); + asn1_read_uint8(data, &b); + *i = (*i << 8) + b; } return asn1_end_tag(data); -- cgit From e6de7c24a5d60f0481eef9695780890e360802f9 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 22 Aug 2002 23:34:27 +0000 Subject: move where got_sig_term and reload_after_sighup are defined. populate cli structure with called name and calling name even for port 445 connects. (This used to be commit 123eee6206d9afb28c169540dc63824957b505f4) --- source3/libsmb/cliconnect.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 73846c4d43..7db377c25f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -938,15 +938,6 @@ BOOL cli_session_request(struct cli_state *cli, int len = 4; extern pstring user_socket_options; - /* 445 doesn't have session request */ - if (cli->port == 445) return True; - - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); - return False; - } - - /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); @@ -960,6 +951,15 @@ BOOL cli_session_request(struct cli_state *cli, name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); + /* 445 doesn't have session request */ + if (cli->port == 445) return True; + + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); + return False; + } + + /* send a session request (RFC 1002) */ /* setup the packet length * Remove four bytes from the length count, since the length * field in the NBT Session Service header counts the number -- cgit From 53fabdee019699d39648fadafa0963ecb04ba3aa Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Aug 2002 13:23:49 +0000 Subject: Don't take the sizeof(struct in_addr) * -1 (This used to be commit e13016bb42dbba675d6e7ee7e163543aad2e62c2) --- source3/libsmb/namecache.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index f05f76a22b..d985832613 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -93,8 +93,10 @@ static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, struct nc_value *value; int size; - size = sizeof(struct nc_value) + sizeof(struct in_addr) * - (num_names-1); + size = sizeof(struct nc_value); + + if (num_names > 0) + size += sizeof(struct in_addr) * (num_names-1); value = (struct nc_value *)malloc(size); -- cgit From 55315b4b4e0f25ab9d77228219b8a4f8ceee6b29 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Aug 2002 13:38:00 +0000 Subject: Moved calculation of secure channel type into a new function. (This used to be commit b8dba26978c281259e02b9d6ebacaa7cba4f7787) --- source3/libsmb/trust_passwd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index fe6b673e39..d500cb3ab7 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,8 +35,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); + result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", -- cgit From 6bca45020764ac36eee77518bc3727aaf5ebc268 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Aug 2002 15:01:08 +0000 Subject: Cope with negative cache dns entries better. (This used to be commit 3404023260a5d6fed5523eb378d4a1ad418302a0) --- source3/libsmb/namecache.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index d985832613..31341df86e 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -91,19 +91,20 @@ static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, { TDB_DATA retval; struct nc_value *value; - int size; - - size = sizeof(struct nc_value); + int size = sizeof(struct nc_value); if (num_names > 0) size += sizeof(struct in_addr) * (num_names-1); value = (struct nc_value *)malloc(size); - + + memset(value, 0, size); + value->expiry = expiry; value->count = num_names; - memcpy(value->ip_list, ip_list, sizeof(*ip_list)); + if (ip_list) + memcpy(value->ip_list, ip_list, sizeof(*ip_list)); retval.dptr = (char *)value; retval.dsize = size; -- cgit From f73039b2251a80020a0337da0263dffa83d380ad Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Aug 2002 21:36:45 +0000 Subject: Fix from kai to correctly decode ntlmssp flags. Andrew Bartlett (This used to be commit 2e74473551f0fce0384eacd31bc1a53ff3967464) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 16702c375b..bc4d0ca348 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -696,7 +696,7 @@ void debug_ntlmssp_flags(uint32 neg_flags) DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); -- cgit From 6b9de4f69f6d4f2cb7f28228c70e72837cc745ac Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Aug 2002 22:23:46 +0000 Subject: Use a function that actually exists for the keepalive send. Andrew Bartlett (This used to be commit 82e7212bbbeefce873291c2fdb3b04ae1e6c26d6) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index fa27f54340..3897851167 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -211,7 +211,7 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c) */ int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - if ( cli_send_keepalive(&server->cli) == False ) + if ( send_keepalive(server->cli.fd) == False ) return 1; /* connection is ok */ -- cgit From 2560c73026ced1917a04f0e670f51ebcc984bb86 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Aug 2002 03:08:37 +0000 Subject: Updates! - Don't print an uninitialised buffer in service.c - Change some charcnv.c functions to take smb_ucs2_t ** instead of void ** - Update NTLMv2 code to use dynamic buffers - Update experimental SMB signing code - still more work to do - Move sys_getgrouplist() to SAFE_FREE() and do a DEBUG() on initgroups() failure. Andrew Bartlett (This used to be commit de1964f7fa855022258a84556b266100b917444b) --- source3/libsmb/cliconnect.c | 74 +++++++++++++++++++++++++++---------------- source3/libsmb/clientgen.c | 7 +++- source3/libsmb/clireadwrite.c | 2 +- source3/libsmb/smbencrypt.c | 60 +++++++++++++++++++++++++++-------- 4 files changed, 100 insertions(+), 43 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7db377c25f..ded5a843f3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -237,6 +237,23 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, return True; } +static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 response[24]) +{ + uint8 zero_sig[8]; + ZERO_STRUCT(zero_sig); + if (memcmp(&cli->outbuf[smb_ss_field], zero_sig, 8) != 0) { + cli->sign_info.use_smb_signing = True; + cli_calculate_mac_key(cli, pass, response); + } +} + +static void set_temp_signing_on_cli(struct cli_state *cli) +{ + if (cli->sign_info.negotiated_smb_signing) { + cli->sign_info.temp_smb_signing = True; + } +} + /** do a NT1 NTLM/LM encrypted session setup @@ -256,7 +273,6 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, uchar pword[24]; uchar ntpword[24]; char *p; - BOOL tried_signing = False; if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { return False; @@ -268,12 +284,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt(pass,cli->secblob.data,pword); SMBNTencrypt(pass,cli->secblob.data,ntpword); - if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, pass, ntpword); - tried_signing = True; - } + + set_temp_signing_on_cli(cli); + } else { - /* pre-encrypted password supplied. Only used for security=server, can't do + /* pre-encrypted password supplied. Only used for + security=server, can't do signing becouse we don't have oringial key */ memcpy(pword, pass, 24); if (ntpasslen == 24) { @@ -307,22 +323,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + if (!cli_send_smb(cli)) { + return False; + } + if (!cli_receive_smb(cli)) { - if (tried_signing) { - /* We only use it if we have a successful non-guest connect */ - cli->sign_info.use_smb_signing = False; - } return False; } show_msg(cli->inbuf); - if (tried_signing && (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */)) { - /* We only use it if we have a successful non-guest connect */ - cli->sign_info.use_smb_signing = False; - } - if (cli_is_error(cli)) { return False; } @@ -337,6 +347,11 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, fstrcpy(cli->user_name, user); + if (passlen != 24) { + /* Have plaintext orginal */ + set_signing_on_cli(cli, pass, ntpword); + } + return True; } @@ -360,6 +375,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); + + set_temp_signing_on_cli(cli); + cli_setup_packet(cli); SCVAL(cli->outbuf,smb_vwv0,0xFF); @@ -375,8 +393,8 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + if (!cli_receive_smb(cli)) return blob2; @@ -451,7 +469,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, uint32 neg_flags; neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM; memset(sess_key, 0, 16); @@ -525,7 +543,13 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&auth); data_blob_free(&blob); - return !cli_is_error(cli); + if (cli_is_error(cli)) { + return False; + } + + set_signing_on_cli(cli, pass, nthash); + + return True; } /**************************************************************************** @@ -541,9 +565,6 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, int i; BOOL got_kerberos_mechanism = False; - /* spnego security cannot use SMB signing (for now). */ - cli->sign_info.use_smb_signing = False; - DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ @@ -643,6 +664,9 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_plaintext(cli, user, pass, workgroup); } + /* Indidicate signing */ + + /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { return cli_session_setup_spnego(cli, user, pass, workgroup); @@ -891,12 +915,8 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - /* A way to attempt to force SMB signing */ - if (getenv("CLI_FORCE_SMB_SIGNING")) + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) cli->sign_info.negotiated_smb_signing = True; - - if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) - cli->sign_info.negotiated_smb_signing = False; } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9ae3882301..560d391320 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -160,7 +160,8 @@ void cli_setup_packet(struct cli_state *cli) if (cli->use_spnego) { flags2 |= FLAGS2_EXTENDED_SECURITY; } - if (cli->sign_info.use_smb_signing) + if (cli->sign_info.use_smb_signing + || cli->sign_info.temp_smb_signing) flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } @@ -245,6 +246,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->force_dos_errors = True; } + /* A way to attempt to force SMB signing */ + if (getenv("CLI_FORCE_SMB_SIGNING")) + cli->sign_info.negotiated_smb_signing = True; + if (!cli->outbuf || !cli->inbuf) goto error; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 756a6cce2f..875df11dca 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -127,7 +127,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return total; } -#if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ +#if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */ /* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0 you must fix ensure you don't attempt to sign the packets - data diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index dfa355a7ec..db265c4bf7 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -116,39 +116,63 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) } /* Does both the NTLMv2 owfs of a user's password */ -void ntv2_owf_gen(const uchar owf[16], - const char *user_n, const char *domain_n, uchar kr_buf[16]) +BOOL ntv2_owf_gen(const uchar owf[16], + const char *user_in, const char *domain_in, uchar kr_buf[16]) { - pstring user_u; - pstring dom_u; + smb_ucs2_t *user; + smb_ucs2_t *domain; + + int user_byte_len; + int domain_byte_len; + HMACMD5Context ctx; - int user_l = strlen(user_n); - int domain_l = strlen(domain_n); + user_byte_len = push_ucs2_allocate(&user, user_in); + if (user_byte_len < 0) { + DEBUG(0, ("push_uss2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); + return False; + } - push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); - push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); + domain_byte_len = push_ucs2_allocate(&domain, domain_in); + if (domain_byte_len < 0) { + DEBUG(0, ("push_uss2_allocate() for domain returned %d (probably malloc() failure)\n", user_byte_len)); + return False; + } + + strupper_w(user); + strupper_w(domain); + + /* We don't want null termination */ + user_byte_len = user_byte_len - 2; + domain_byte_len = domain_byte_len - 2; + + SMB_ASSERT(user_byte_len >= 0); + SMB_ASSERT(domain_byte_len >= 0); hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update((const unsigned char *)user_u, user_l * 2, &ctx); - hmac_md5_update((const unsigned char *)dom_u, domain_l * 2, &ctx); + hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); + hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, user_u, user_l * 2); - dump_data(100, dom_u, domain_l * 2); + dump_data(100, (const char *)user, user_byte_len); + dump_data(100, (const char *)domain, domain_byte_len); dump_data(100, owf, 16); dump_data(100, kr_buf, 16); #endif + + SAFE_FREE(user); + SAFE_FREE(domain); + return True; } /* Does the des encryption from the NT or LM MD4 hash. */ void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) { uchar p21[21]; - - memset(p21,'\0',21); + + ZERO_STRUCT(p21); memcpy(p21, passwd, 16); E_P24(p21, c8, p24); @@ -362,6 +386,12 @@ void cli_caclulate_sign_mac(struct cli_state *cli) unsigned char calc_md5_mac[16]; struct MD5Context md5_ctx; + if (cli->sign_info.temp_smb_signing) { + memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + cli->sign_info.temp_smb_signing = False; + return; + } + if (!cli->sign_info.use_smb_signing) { return; } @@ -380,6 +410,8 @@ void cli_caclulate_sign_mac(struct cli_state *cli) MD5Final(calc_md5_mac, &md5_ctx); memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signitures...*/ cli->sign_info.send_seq_num++; cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; cli->sign_info.send_seq_num++; -- cgit From e32fdc10015ad57739c3db4ff476379274f09c77 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Aug 2002 03:59:01 +0000 Subject: Some fixes for SMB signing. I can now get Win2k to correctly respond with a security signiture, but I can't get it to accept ours. Andrew Bartlett (This used to be commit 7746de6a3c5798e321ed8300f763588fa3807964) --- source3/libsmb/cliconnect.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ded5a843f3..0d033c9b59 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -241,9 +241,19 @@ static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 respons { uint8 zero_sig[8]; ZERO_STRUCT(zero_sig); - if (memcmp(&cli->outbuf[smb_ss_field], zero_sig, 8) != 0) { + + DEBUG(5, ("Server returned security sig:\n")); + dump_data(5, &cli->inbuf[smb_ss_field], 8); + + if (cli->sign_info.use_smb_signing) { + DEBUG(5, ("smb signing already active on connection\n")); + } else if (memcmp(&cli->inbuf[smb_ss_field], zero_sig, 8) != 0) { + + DEBUG(3, ("smb signing enabled!\n")); cli->sign_info.use_smb_signing = True; cli_calculate_mac_key(cli, pass, response); + } else { + DEBUG(5, ("smb signing NOT enabled!\n")); } } @@ -273,6 +283,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, uchar pword[24]; uchar ntpword[24]; char *p; + BOOL have_plaintext = False; if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { return False; @@ -285,8 +296,8 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, SMBencrypt(pass,cli->secblob.data,pword); SMBNTencrypt(pass,cli->secblob.data,ntpword); + have_plaintext = True; set_temp_signing_on_cli(cli); - } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -347,7 +358,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, fstrcpy(cli->user_name, user); - if (passlen != 24) { + if (have_plaintext) { /* Have plaintext orginal */ set_signing_on_cli(cli, pass, ntpword); } -- cgit From c53bbb55f67aacdd30cff7fb46064ce009d7794f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 27 Aug 2002 12:43:15 +0000 Subject: merge from SAMBA_2_2 (This used to be commit b58ddacf73589870252eea52da68841e7294672d) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3897851167..44cba611d2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -378,7 +378,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, fstring remote_name; struct in_addr rem_ip; - if (!inet_aton(server, &rem_ip)) { + if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server)); errno = ENOENT; return NULL; -- cgit From b42229c2d8f505470b7b5c1e0d74cf36438d6de7 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 28 Aug 2002 00:17:11 +0000 Subject: Sync up namecache code with HEAD and APPLIANCE_HEAD. Rerun unit tests. (This used to be commit 41c2e7b162224a524a1bf4da012f383f2a6032d0) --- source3/libsmb/namecache.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 31341df86e..2252e8e59c 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -34,19 +34,19 @@ struct nc_value { /* Initialise namecache system */ -void namecache_enable(void) +BOOL namecache_enable(void) { /* Check if we have been here before, or name caching disabled by setting the name cache timeout to zero. */ if (done_namecache_init) - return; + return False; done_namecache_init = True; if (lp_name_cache_timeout() == 0) { DEBUG(5, ("namecache_init: disabling netbios name cache\n")); - return; + return False; } /* Open namecache tdb in read/write or readonly mode */ @@ -58,13 +58,15 @@ void namecache_enable(void) if (!namecache_tdb) { DEBUG(5, ("namecache_init: could not open %s\n", lock_path("namecache.tdb"))); - return; + return False; } DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d " "seconds\n", lp_name_cache_timeout())); enable_namecache = True; + + return True; } /* Return a key for a name and name type. The caller must free @@ -104,7 +106,7 @@ static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, value->count = num_names; if (ip_list) - memcpy(value->ip_list, ip_list, sizeof(*ip_list)); + memcpy(value->ip_list, ip_list, sizeof(struct in_addr) * num_names); retval.dptr = (char *)value; retval.dsize = size; @@ -163,6 +165,9 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, time_t now; int i; + *ip_list = NULL; + *num_names = 0; + if (!enable_namecache) return False; @@ -212,20 +217,23 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, /* Extract and return namelist */ - *ip_list = (struct in_addr *)malloc( - sizeof(struct in_addr) * (data->count-1)); - - memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * - (data->count-1)); + DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", + data->count, data->count == 1 ? "" : "es", name, name_type)); - *num_names = data->count; + if (data->count) { - DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", - *num_names, *num_names == 1 ? "" : "es", name, name_type)); + *ip_list = (struct in_addr *)malloc( + sizeof(struct in_addr) * data->count); + + memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * data->count); + + *num_names = data->count; + + for (i = 0; i < *num_names; i++) + DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), + i == (*num_names - 1) ? "" : ", ")); - for (i = 0; i < *num_names; i++) - DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), - i == (*num_names - 1) ? "" : ", ")); + } DEBUGADD(5, ("\n")); -- cgit From dcd029169424d8846c1fbb0b1527516a4a026b27 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 30 Aug 2002 06:59:57 +0000 Subject: convert the LDAP/SASL code to use GSS-SPNEGO if possible we now do this: - look for suported SASL mechanisms on the LDAP server - choose GSS-SPNEGO if possible - within GSS-SPNEGO choose KRB5 if we can do a kinit - otherwise use NTLMSSP This change also means that we no longer rely on having a gssapi library to do ADS. todo: - add TLS/SSL support over LDAP - change to using LDAP/SSL for password change in ADS (This used to be commit b04e91f660d3b26d23044075d4a7e707eb41462d) --- source3/libsmb/cliconnect.c | 13 +++++++++---- source3/libsmb/clikrb5.c | 8 +++++++- source3/libsmb/clispnego.c | 4 +--- 3 files changed, 17 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0d033c9b59..e9b2b7b32e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -446,7 +446,7 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(cli, principal); + negTokenTarg = spnego_gen_negTokenTarg(principal); if (!negTokenTarg.data) return False; @@ -572,14 +572,14 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, { char *principal; char *OIDs[ASN1_MAX_OIDS]; - uint8 guid[16]; int i; BOOL got_kerberos_mechanism = False; + DATA_BLOB blob; DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ - if (cli->secblob.length == 16) { + if (cli->secblob.length <= 16) { DEBUG(3,("server didn't supply a full spnego negprot\n")); goto ntlmssp; } @@ -588,11 +588,16 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, file_save("negprot.dat", cli->secblob.data, cli->secblob.length); #endif + /* there is 16 bytes of GUID before the real spnego packet starts */ + blob = data_blob(cli->secblob.data+16, cli->secblob.length-16); + /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ - if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principal)) { + if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + data_blob_free(&blob); return False; } + data_blob_free(&blob); /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 685c4a25e0..955a93285c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -20,6 +20,10 @@ #include "includes.h" +#ifndef ENCTYPE_ARCFOUR_HMAC +#define ENCTYPE_ARCFOUR_HMAC 0x0017 +#endif + #ifdef HAVE_KRB5 /* we can't use krb5_mk_req because w2k wants the service to be in a particular format @@ -94,7 +98,9 @@ DATA_BLOB krb5_get_ticket(char *principal) krb5_context context; krb5_auth_context auth_context = NULL; DATA_BLOB ret; - krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + krb5_enctype enc_types[] = {ENCTYPE_ARCFOUR_HMAC, + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; retval = krb5_init_context(&context); if (retval) { diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index bc4d0ca348..1eeae8b171 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -79,7 +79,6 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], OIDs (the mechanisms) and a principal name string */ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, - uint8 guid[16], char *OIDs[ASN1_MAX_OIDS], char **principal) { @@ -89,7 +88,6 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_load(&data, blob); - asn1_read(&data, guid, 16); asn1_start_tag(&data,ASN1_APPLICATION(0)); asn1_check_OID(&data,OID_SPNEGO); asn1_start_tag(&data,ASN1_CONTEXT(0)); @@ -279,7 +277,7 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principal) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; -- cgit From cfb5e91178eb8befdb00780a819f9c5cd3eee8e4 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 30 Aug 2002 10:46:59 +0000 Subject: added cli_net_auth_3 client code. changed cli_nt_setup_creds() to call cli_net_auth_2 or cli_net_auth_3 based on a switch. pass also the negociation flags all the way. all the places calling cli_nt_setup_creds() are still using cli_net_aut2(), it's just for future use and for rpcclient. in the future we will be able to call auth_2 or auth_3 as we want. J.F. (This used to be commit 4d38caca40f98d0584fefb9d66424a3db5b5789e) --- source3/libsmb/trust_passwd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index d500cb3ab7..4d7acd1988 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,7 +35,9 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash); + uint32 neg_flags = 0x000001ff; + + result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", -- cgit From 7aca67c3e90b55e590d8741d3c24bc37b45120b7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 31 Aug 2002 06:59:00 +0000 Subject: Add a bit of 'const' and move a lot of our 'repeditive' DEBUG() statements to 'DEBUGADD', so we don't repeat headers. (Makes them much easier to read). (Based on patch by kai) Andrew Bartlett (This used to be commit 9deada345c5f89f338530c4de62835cc1eeb3d0e) --- source3/libsmb/clispnego.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 1eeae8b171..fc25436d10 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -686,37 +686,39 @@ BOOL msrpc_parse(DATA_BLOB *blob, void debug_ntlmssp_flags(uint32 neg_flags) { + DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUG(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUG(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); + DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) - DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUG(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUG(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUG(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUG(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUG(4, (" NTLMSSP_NEGOTIATE_128\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUG(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); } -- cgit From 110954e8e1c8025831d2c7621ac4a21679e60a1e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 31 Aug 2002 08:51:38 +0000 Subject: Add a dash of static. (This used to be commit e3af3adac1a01842bc5242e68393196497a1d71c) --- source3/libsmb/clierror.c | 4 ++-- source3/libsmb/nterr.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 591c04db22..e1507c6048 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -156,7 +156,7 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) /* Return a UNIX errno from a dos error class, error number tuple */ -int cli_errno_from_dos(uint8 eclass, uint32 num) +static int cli_errno_from_dos(uint8 eclass, uint32 num) { if (eclass == ERRDOS) { switch (num) { @@ -205,7 +205,7 @@ static struct { {NT_STATUS(0), 0} }; -int cli_errno_from_nt(NTSTATUS status) +static int cli_errno_from_nt(NTSTATUS status) { int i; DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", NT_STATUS_V(status))); diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index e2da6318e1..02fd53fc05 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -28,7 +28,7 @@ typedef const struct NTSTATUS nt_errcode; } nt_err_code_struct; -nt_err_code_struct nt_errs[] = +static nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, -- cgit From 207455610418a32b428f1f267091e2ec7d245ece Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 3 Sep 2002 03:48:28 +0000 Subject: The session key in NTLMSSP AUTH blobs is actually an empty string. Also, the negotiate blob has two ASCI strings encoded in the same way that the UNICODE strings are, they are just in ASCII. The PARSER and Generator will have to deal with that. (This used to be commit aaa7a681ce4ee52edb23c73a53aeabb07fd5b7d8) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e9b2b7b32e..c441cf28a8 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -540,7 +540,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, workgroup, user, cli->calling.name, - sess_key, 16, + sess_key, 0, neg_flags); /* wrap it in SPNEGO */ -- cgit From bb30cd160b7d01b38fb6473d15a9056118d51a42 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 3 Sep 2002 03:53:50 +0000 Subject: Add type A to the small MSRPC generator ... (This used to be commit 7f8fd5f270af74dcb3fd18af74233f7db4d8f9a7) --- source3/libsmb/clispnego.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index fc25436d10..8376398e3f 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -471,6 +471,7 @@ DATA_BLOB spnego_gen_auth_response(void) U = unicode string (input is unix string) a = address (1 byte type, 1 byte length, unicode string, all inline) + A = ASCII string (pointer + length) Actually same as B B = data blob (pointer + length) b = data blob in header (pointer + length) d = word (4 bytes) @@ -500,6 +501,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, s = va_arg(ap, char *); data_size += (str_charnum(s) * 2) + 4; break; + case 'A': case 'B': b = va_arg(ap, uint8 *); head_size += 8; -- cgit From 629ad6941e95fef465059c248ea0d99a32be2a98 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 3 Sep 2002 04:10:58 +0000 Subject: Make sure that an NTLMSSP negotiate blob has the correct stuff in it! (This used to be commit b28267f52c0a5c175b067d7c2d10eca83c20e640) --- source3/libsmb/cliconnect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c441cf28a8..7ef9b2ab82 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -486,11 +486,12 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, memset(sess_key, 0, 16); /* generate the ntlmssp negotiate packet */ - msrpc_gen(&blob, "CddB", + msrpc_gen(&blob, "CddAA", "NTLMSSP", NTLMSSP_NEGOTIATE, neg_flags, - sess_key, 16); + workgroup, strlen(workgroup), + cli->calling.name, strlen(cli->calling.name)); /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenTarg(mechs, blob); -- cgit From fc15341b8265f57a2bdd9be8a06c83e1fd90497a Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 3 Sep 2002 06:34:40 +0000 Subject: Parse the NTLMSSP Challenge in cliconnect.c. This gets us closer ... Should have the challenge now. Need to check that it works. (This used to be commit 5784835db95baf62362d35d3beab5d534cc776e9) --- source3/libsmb/cliconnect.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7ef9b2ab82..cb3b4373dc 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -473,11 +473,12 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { const char *mechs[] = {OID_NTLMSSP, NULL}; - DATA_BLOB msg1; + DATA_BLOB msg1, struct_blob; DATA_BLOB blob, chal1, chal2, auth; uint8 challenge[8]; uint8 nthash[24], lmhash[24], sess_key[16]; - uint32 neg_flags; + uint32 neg_flags, chal_flags, ntlmssp_command, unkn1, unkn2; + pstring server_domain; /* FIX THIS, SHOULD be UCS2-LE */ neg_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | @@ -518,6 +519,31 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&blob); + /* + * Ok, chal1 and chal2 are actually two identical copies of + * the NTLMSSP Challenge BLOB, and they contain, encoded in them + * the challenge to use. + */ + + if (!msrpc_parse(&chal1, "CdUdbddB", + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + challenge, 8, + &unkn1, &unkn2, + struct_blob.data, &struct_blob.length)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return False; + } + + if (ntlmssp_command != NTLMSSP_CHALLENGE) { + DEBUG(0, ("NTLMSSP Response != NTLMSSP_CHALLENGE. Got %0X\n", + ntlmssp_command)); + return False; + } + + /* encrypt the password with the challenge */ memcpy(challenge, chal1.data + 24, 8); SMBencrypt(pass, challenge,lmhash); -- cgit From fd13038acff34acb9113afffd01af3e0fe90a6af Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 3 Sep 2002 17:36:00 +0000 Subject: Fix the client side NTLMSSP. It now works between smbclient and smbd! However, it does not work with Win2K over 445 with raw NTLMSSP! (This used to be commit 53e4975337be2cab3ee89f2f62e5659855365b73) --- source3/libsmb/cliconnect.c | 9 ++++++--- source3/libsmb/clispnego.c | 47 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cb3b4373dc..428167ebfa 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -486,16 +486,19 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, memset(sess_key, 0, 16); + DEBUG(10, ("sending NTLMSSP_NEGOTIATE\n")); + /* generate the ntlmssp negotiate packet */ msrpc_gen(&blob, "CddAA", "NTLMSSP", NTLMSSP_NEGOTIATE, neg_flags, workgroup, strlen(workgroup), - cli->calling.name, strlen(cli->calling.name)); - + cli->calling.name, strlen(cli->calling.name) + 1); + DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n", + neg_flags, workgroup, cli->calling.name)); /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenTarg(mechs, blob); + msg1 = gen_negTokenInit(OID_NTLMSSP, blob); data_blob_free(&blob); /* now send that blob on its way */ diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 8376398e3f..8aab0fdda9 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -73,6 +73,50 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], return ret; } +/* + Generate a negTokenInit as used by the client side ... It has a mechType + (OID), and a mechToken (a security blob) ... + + Really, we need to break out the NTLMSSP stuff as well, because it could be + raw in the packets! +*/ +DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OID(&data, OID); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} /* parse a negTokenInit packet giving a GUID, a list of supported @@ -553,7 +597,8 @@ BOOL msrpc_gen(DATA_BLOB *blob, } data_ofs += n*2; break; - + + case 'A': case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); -- cgit From a27923691ba8d1496c1eaaab2559a10e4f41d694 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 Sep 2002 19:18:12 +0000 Subject: Formatting tidyup and additon of cli_close_connection() before bugfix. Jeremy. (This used to be commit 3b71529c694b5b1093d99b7ef80835e72b1f8436) --- source3/libsmb/cliconnect.c | 115 ++++++++++++++++++-------------------------- source3/libsmb/clientgen.c | 104 ++++++++++++++++++++------------------- 2 files changed, 101 insertions(+), 118 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 428167ebfa..9ff4854998 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -50,14 +50,12 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, fstring pword; char *p; - if (passlen > sizeof(pword)-1) { + if (passlen > sizeof(pword)-1) return False; - } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { + if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) passlen = 0; - } if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ @@ -99,9 +97,8 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -118,17 +115,14 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) { uint32 capabilities = CAP_NT_SMBS; - if (!cli->force_dos_errors) { + if (!cli->force_dos_errors) capabilities |= CAP_STATUS32; - } - if (cli->use_level_II_oplocks) { + if (cli->use_level_II_oplocks) capabilities |= CAP_LEVEL_II_OPLOCKS; - } - if (cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) capabilities |= CAP_UNICODE; - } return capabilities; } @@ -167,9 +161,8 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -223,9 +216,8 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } cli->vuid = SVAL(cli->inbuf,smb_uid); p = smb_buf(cli->inbuf); @@ -259,20 +251,19 @@ static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 respons static void set_temp_signing_on_cli(struct cli_state *cli) { - if (cli->sign_info.negotiated_smb_signing) { + if (cli->sign_info.negotiated_smb_signing) cli->sign_info.temp_smb_signing = True; - } } -/** +/**************************************************************************** do a NT1 NTLM/LM encrypted session setup @param cli client state to create do session setup on @param user username @param pass *either* cleartext password (passlen !=24) or LM response. @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear @param workgroup The user's domain. -*/ +****************************************************************************/ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *pass, int passlen, @@ -285,9 +276,8 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *p; BOOL have_plaintext = False; - if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { + if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) return False; - } if (passlen != 24) { /* non encrypted password supplied. Ignore ntpass. */ @@ -303,11 +293,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, security=server, can't do signing becouse we don't have oringial key */ memcpy(pword, pass, 24); - if (ntpasslen == 24) { + if (ntpasslen == 24) memcpy(ntpword, ntpass, 24); - } else { + else ZERO_STRUCT(ntpword); - } } /* send a session setup command */ @@ -334,19 +323,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - if (!cli_send_smb(cli)) { + if (!cli_send_smb(cli)) return False; - } - if (!cli_receive_smb(cli)) { + if (!cli_receive_smb(cli)) return False; - } show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -433,7 +419,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return blob2; } - #ifdef HAVE_KRB5 /**************************************************************************** Do a spnego/kerberos encrypted session setup. @@ -472,7 +457,6 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { - const char *mechs[] = {OID_NTLMSSP, NULL}; DATA_BLOB msg1, struct_blob; DATA_BLOB blob, chal1, chal2, auth; uint8 challenge[8]; @@ -506,9 +490,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&msg1); - if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) return False; - } #if 0 file_save("chal.dat", blob.data, blob.length); @@ -541,9 +524,9 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, } if (ntlmssp_command != NTLMSSP_CHALLENGE) { - DEBUG(0, ("NTLMSSP Response != NTLMSSP_CHALLENGE. Got %0X\n", - ntlmssp_command)); - return False; + DEBUG(0, ("NTLMSSP Response != NTLMSSP_CHALLENGE. Got %0X\n", + ntlmssp_command)); + return False; } @@ -584,9 +567,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&auth); data_blob_free(&blob); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } set_signing_on_cli(cli, pass, nthash); @@ -687,38 +669,38 @@ BOOL cli_session_setup(struct cli_state *cli, flow a bit easier to understand (tridge) */ /* if its an older server then we have to use the older request format */ - if (cli->protocol < PROTOCOL_NT1) { + + if (cli->protocol < PROTOCOL_NT1) return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); - } /* if no user is supplied then we have to do an anonymous connection. passwords are ignored */ - if (!user || !*user) { + + if (!user || !*user) return cli_session_setup_guest(cli); - } /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) { + + if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) return cli_session_setup_plaintext(cli, user, "", workgroup); - } /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { + + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) return cli_session_setup_plaintext(cli, user, pass, workgroup); - } /* Indidicate signing */ - /* if the server supports extended security then use SPNEGO */ - if (cli->capabilities & CAP_EXTENDED_SECURITY) { + + if (cli->capabilities & CAP_EXTENDED_SECURITY) return cli_session_setup_spnego(cli, user, pass, workgroup); - } /* otherwise do a NT1 style session setup */ + return cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup); @@ -808,15 +790,13 @@ BOOL cli_send_tconX(struct cli_state *cli, if (!cli_receive_smb(cli)) return False; - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII); - if (strcasecmp(share,"IPC$")==0) { + if (strcasecmp(share,"IPC$")==0) fstrcpy(cli->dev, "IPC"); - } if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { @@ -856,9 +836,8 @@ void cli_negprot_send(struct cli_state *cli) char *p; int numprots; - if (cli->protocol < PROTOCOL_NT1) { + if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; - } memset(cli->outbuf,'\0',smb_size); @@ -897,9 +876,8 @@ BOOL cli_negprot(struct cli_state *cli) return False; } - if (cli->protocol < PROTOCOL_NT1) { + if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; - } memset(cli->outbuf,'\0',smb_size); @@ -986,9 +964,8 @@ BOOL cli_negprot(struct cli_state *cli) cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); /* a way to force ascii SMB */ - if (getenv("CLI_FORCE_ASCII")) { + if (getenv("CLI_FORCE_ASCII")) cli->capabilities &= ~CAP_UNICODE; - } return True; } @@ -1018,7 +995,8 @@ BOOL cli_session_request(struct cli_state *cli, len += name_len(p); /* 445 doesn't have session request */ - if (cli->port == 445) return True; + if (cli->port == 445) + return True; if (cli->sign_info.use_smb_signing) { DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); @@ -1132,7 +1110,8 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, cli->timeout); } - if (cli->fd != -1) cli->port = port; + if (cli->fd != -1) + cli->port = port; } if (cli->fd == -1) { DEBUG(1,("Error connecting to %s (%s)\n", @@ -1207,11 +1186,10 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return NT_STATUS_UNSUCCESSFUL; } - if (dest_ip) { + if (dest_ip) ip = *dest_ip; - } else { + else ZERO_STRUCT(ip); - } again: @@ -1239,11 +1217,10 @@ again: return NT_STATUS_UNSUCCESSFUL; } - if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) { + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) cli->use_spnego = False; - } else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { + else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) cli->use_kerberos = True; - } if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 560d391320..facf361a6b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -32,49 +32,48 @@ int cli_set_port(struct cli_state *cli, int port) } /**************************************************************************** - read an smb from a fd ignoring all keepalive packets. Note that the buffer - *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds - - This is exactly the same as receive_smb except that it never returns - a session keepalive packet (just as receive_smb used to do). - receive_smb was changed to return keepalives as the oplock processing means this call - should never go into a blocking read. + Read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. ****************************************************************************/ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) { - BOOL ret; - - for(;;) - { - ret = receive_smb(fd, buffer, timeout); - - if (!ret) - { - DEBUG(10,("client_receive_smb failed\n")); - show_msg(buffer); - return ret; - } - - /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) - break; - } - show_msg(buffer); - return ret; -} + BOOL ret; + + for(;;) { + ret = receive_smb(fd, buffer, timeout); + + if (!ret) { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != SMBkeepalive) + break; + } + show_msg(buffer); + return ret; +} /**************************************************************************** -recv an smb + Recv an smb. ****************************************************************************/ + BOOL cli_receive_smb(struct cli_state *cli) { BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) return False; + if (cli->fd == -1) + return False; again: ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); @@ -151,15 +150,12 @@ void cli_setup_packet(struct cli_state *cli) uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; - } - if (cli->capabilities & CAP_STATUS32) { + if (cli->capabilities & CAP_STATUS32) flags2 |= FLAGS2_32_BIT_ERROR_CODES; - } - if (cli->use_spnego) { + if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - } if (cli->sign_info.use_smb_signing || cli->sign_info.temp_smb_signing) flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; @@ -168,18 +164,18 @@ void cli_setup_packet(struct cli_state *cli) } /**************************************************************************** -setup the bcc length of the packet from a pointer to the end of the data + Setup the bcc length of the packet from a pointer to the end of the data. ****************************************************************************/ + void cli_setup_bcc(struct cli_state *cli, void *p) { set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); } - - /**************************************************************************** -initialise credentials of a client structure + Initialise credentials of a client structure. ****************************************************************************/ + void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ @@ -194,10 +190,10 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) cli->ntlmssp_flags,cli->ntlmssp_cli_flgs)); } - /**************************************************************************** -initialise a client structure + Initialise a client structure. ****************************************************************************/ + struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; @@ -280,11 +276,11 @@ struct cli_state *cli_initialise(struct cli_state *cli) } /**************************************************************************** -shutdown a client structure + Close a client connection and free the memory without destroying cli itself. ****************************************************************************/ -void cli_shutdown(struct cli_state *cli) + +void cli_close_connection(struct cli_state *cli) { - BOOL allocated; SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); @@ -295,25 +291,35 @@ void cli_shutdown(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); - allocated = cli->allocated; +} + +/**************************************************************************** + Shutdown a client structure. +****************************************************************************/ + +void cli_shutdown(struct cli_state *cli) +{ + BOOL allocated = cli->allocated; + cli_close_connection(cli); ZERO_STRUCTP(cli); if (allocated) { free(cli); } } - /**************************************************************************** -set socket options on a open connection + Set socket options on a open connection. ****************************************************************************/ + void cli_sockopt(struct cli_state *cli, char *options) { set_socket_options(cli->fd, options); } /**************************************************************************** -set the PID to use for smb messages. Return the old pid. + Set the PID to use for smb messages. Return the old pid. ****************************************************************************/ + uint16 cli_setpid(struct cli_state *cli, uint16 pid) { uint16 ret = cli->pid; -- cgit From 0d9cde27370e3c6cc6df28c7ee8a32aa57e3ce42 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 Sep 2002 19:19:20 +0000 Subject: Fix crashbug discovered by "Kim R. Pedersen" where cli struct was being deallocated in a called function. Jeremy. (This used to be commit e33e9defa657aa54594bb0c27f9be2f7b12aab1b) --- source3/libsmb/cliconnect.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9ff4854998..885463bd34 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1307,7 +1307,13 @@ with error %s.\n", desthost, cli_errstr(cli) )); return False; } - cli_shutdown(cli); + /* + * We need to close the connection here but can't call cli_shutdown as + * will free an allocated cli struct. cli_close_connection was invented + * for this purpose. JRA. Based on work by "Kim R. Pedersen" . + */ + + cli_close_connection(cli); if (!cli_initialise(cli) || !cli_connect(cli, desthost, pdest_ip) || -- cgit From f04ca060c2f30f4b5c01867b8db117e00912750c Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Tue, 3 Sep 2002 21:35:26 +0000 Subject: Fix the struct_blob. (This used to be commit ce152b33c8b08905ea863d47a620c90ca47c8566) --- source3/libsmb/cliconnect.c | 13 ++++++++----- source3/libsmb/clispnego.c | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 885463bd34..1f3635d6d7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -458,7 +458,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { DATA_BLOB msg1, struct_blob; - DATA_BLOB blob, chal1, chal2, auth; + DATA_BLOB blob, chal1, chal2, auth, challenge_blob; uint8 challenge[8]; uint8 nthash[24], lmhash[24], sess_key[16]; uint32 neg_flags, chal_flags, ntlmssp_command, unkn1, unkn2; @@ -516,9 +516,9 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, &ntlmssp_command, &server_domain, &chal_flags, - challenge, 8, + &challenge_blob, 8, &unkn1, &unkn2, - struct_blob.data, &struct_blob.length)) { + &struct_blob)) { DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); return False; } @@ -529,11 +529,14 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, return False; } + DEBUG(10, ("Challenge:\n")); + dump_data(10, challenge_blob.data, 8); - /* encrypt the password with the challenge */ - memcpy(challenge, chal1.data + 24, 8); + /* encrypt the password with the challenge which is in the blob */ + memcpy(challenge, challenge_blob.data, 8); SMBencrypt(pass, challenge,lmhash); SMBNTencrypt(pass, challenge,nthash); + data_blob_free(&challenge_blob); #if 0 file_save("nthash.dat", nthash, 24); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 8aab0fdda9..04ec6ed39e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -518,6 +518,7 @@ DATA_BLOB spnego_gen_auth_response(void) A = ASCII string (pointer + length) Actually same as B B = data blob (pointer + length) b = data blob in header (pointer + length) + D d = word (4 bytes) C = constant ascii string */ -- cgit From 65029365ba9e2df821a57173c7532e4cbc7b06e9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Sep 2002 10:58:42 +0000 Subject: don't use ENCTYPE_ARCFOUR_HMAC unless the kerberos lib supports it (This used to be commit 13dc9e37d2422c45ac5005dce26b349f88dbe505) --- source3/libsmb/clikrb5.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 955a93285c..1fc400edb0 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -20,10 +20,6 @@ #include "includes.h" -#ifndef ENCTYPE_ARCFOUR_HMAC -#define ENCTYPE_ARCFOUR_HMAC 0x0017 -#endif - #ifdef HAVE_KRB5 /* we can't use krb5_mk_req because w2k wants the service to be in a particular format @@ -98,7 +94,10 @@ DATA_BLOB krb5_get_ticket(char *principal) krb5_context context; krb5_auth_context auth_context = NULL; DATA_BLOB ret; - krb5_enctype enc_types[] = {ENCTYPE_ARCFOUR_HMAC, + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; -- cgit From 48c91e8b2a01628d03f1d2bdc49c32966d41c96c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Sep 2002 19:02:53 +0000 Subject: Merged Volkers (correct) fix from 2.2 for crash on unable to connect. Jeremy. (This used to be commit 05e2aba52f9b027bbab7c65cc02fd5c83d3c61aa) --- source3/libsmb/clientgen.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index facf361a6b..6b6a2acd3b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -212,9 +212,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) alloced_cli = True; } - if (cli->initialised) { - cli_shutdown(cli); - } + if (cli->initialised) + cli_close_connection(cli); ZERO_STRUCTP(cli); @@ -286,11 +285,14 @@ void cli_close_connection(struct cli_state *cli) data_blob_free(&cli->secblob); - if (cli->mem_ctx) + if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); + cli->mem_ctx = NULL; + } if (cli->fd != -1) close(cli->fd); + cli->fd = -1; } /**************************************************************************** -- cgit From df920a60b5f207149cbc9dcb63d406abb0d0490c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Sep 2002 01:58:51 +0000 Subject: Added final Steve French patch for "required" attributes with old dir listings. Added regression test in smbtorture (in HEAD) also. Jeremy. (This used to be commit 3c9d24d7c3bad2beb641880a97f0eda5cd3e4ec7) --- source3/libsmb/clilist.c | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 17a759f9e3..3eacc25380 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -22,13 +22,13 @@ #include "includes.h" - /**************************************************************************** -interpret a long filename structure - this is mostly guesses at the moment -The length of the structure is returned -The structure of a long filename depends on the info level. 260 is used -by NT and 2 is used by OS/2 + Interpret a long filename structure - this is mostly guesses at the moment. + The length of the structure is returned + The structure of a long filename depends on the info level. 260 is used + by NT and 2 is used by OS/2 ****************************************************************************/ + static int interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { @@ -41,8 +41,7 @@ static int interpret_long_filename(struct cli_state *cli, memcpy(finfo,&def_finfo,sizeof(*finfo)); - switch (level) - { + switch (level) { case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ @@ -126,16 +125,16 @@ static int interpret_long_filename(struct cli_state *cli, namelen, 0); return SVAL(base, 0); } - } + } DEBUG(1,("Unknown long filename format %d\n",level)); return(SVAL(p,0)); } - /**************************************************************************** - do a directory listing, calling fn on each file found - ****************************************************************************/ + Do a directory listing, calling fn on each file found. +****************************************************************************/ + int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { @@ -307,12 +306,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, return(total_received); } - - /**************************************************************************** -interpret a short filename structure -The length of the structure is returned + Interpret a short filename structure. + The length of the structure is returned. ****************************************************************************/ + static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { extern file_info def_finfo; @@ -334,10 +332,11 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /**************************************************************************** - do a directory listing, calling fn on each file found - this uses the old SMBsearch interface. It is needed for testing Samba, - but should otherwise not be used - ****************************************************************************/ + Do a directory listing, calling fn on each file found. + this uses the old SMBsearch interface. It is needed for testing Samba, + but should otherwise not be used. +****************************************************************************/ + int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { @@ -453,16 +452,15 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, return(num_received); } - /**************************************************************************** - do a directory listing, calling fn on each file found - this auto-switches between old and new style - ****************************************************************************/ + Do a directory listing, calling fn on each file found. + This auto-switches between old and new style. +****************************************************************************/ + int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { - if (cli->protocol <= PROTOCOL_LANMAN1) { + if (cli->protocol <= PROTOCOL_LANMAN1) return cli_list_old(cli, Mask, attribute, fn, state); - } return cli_list_new(cli, Mask, attribute, fn, state); } -- cgit From 66f90f97bf13d7f1b9aa18cc59ba1d15b2d8d4b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 11 Sep 2002 15:18:53 +0000 Subject: Merge the cli_shutdown change from 2_2. All except one call to attempt_netbios_... assumed that cli_shutdown was _not_ called on error anyway... Volker (This used to be commit f0c741594f0dad2da16b1d5692dd56a48b4157f1) --- source3/libsmb/cliconnect.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1f3635d6d7..6c5c5e0b0e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1306,7 +1306,6 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); return False; } @@ -1323,7 +1322,6 @@ with error %s.\n", desthost, cli_errstr(cli) )); !cli_session_request(cli, &calling, &smbservername)) { DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); return False; } } -- cgit From b33681fc0b8ef7b9fa91c154f7c3117afafa349e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 17 Sep 2002 12:12:50 +0000 Subject: Add clock skew handling to our kerberos code. This allows us to cope with the DC being out of sync with the local machine. (This used to be commit 0d28d769472ea3b98ae4c8757093dfd4499f6dd1) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clikrb5.c | 14 +++++++++++++- source3/libsmb/clispnego.c | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6c5c5e0b0e..298b1e52b6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -431,7 +431,7 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(principal); + negTokenTarg = spnego_gen_negTokenTarg(principal, 0); if (!negTokenTarg.data) return False; diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 1fc400edb0..22bfdc0463 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -64,6 +64,14 @@ static krb5_error_code krb5_mk_req2(krb5_context context, goto cleanup_creds; } + /* cope with the ticket being in the future due to clock skew */ + if ((unsigned)credsp->times.starttime > time(NULL)) { + time_t t = time(NULL); + int time_offset = (unsigned)credsp->times.starttime - t; + DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + krb5_set_real_time(context, t + time_offset + 1, 0); + } + in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); @@ -86,7 +94,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(char *principal) +DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) { krb5_error_code retval; krb5_data packet; @@ -108,6 +116,10 @@ DATA_BLOB krb5_get_ticket(char *principal) goto failed; } + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + if ((retval = krb5_cc_default(context, &ccdef))) { DEBUG(1,("krb5_cc_default failed (%s)\n", error_message(retval))); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 04ec6ed39e..55f49c5987 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -321,13 +321,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principal); + tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); -- cgit From 7e29a2ec1d7d86225cca4b02af28805a412da124 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 18 Sep 2002 01:40:13 +0000 Subject: Fixed compiler error when HAVE_KRB5 not defined. (This used to be commit 66c2e25079b348188abd48868300771b1e49fff3) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 22bfdc0463..e7143d065d 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -154,7 +154,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(char *principal) + DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); -- cgit From 8aaf8174bf1efef402d46489d56ae759a70341b8 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 22 Sep 2002 16:22:48 +0000 Subject: Small, long overdue, fix for libsmbclient. (This used to be commit 40aea3fe94b68ce284e2f21e57f086212936c049) --- source3/libsmb/clientgen.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6b6a2acd3b..793dd19644 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -328,3 +328,22 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) cli->pid = pid; return ret; } + +/**************************************************************************** +Send a keepalive packet to the server +****************************************************************************/ +BOOL cli_send_keepalive(struct cli_state *cli) +{ + if (cli->fd == -1) { + DEBUG(3, ("cli_send_keepalive: fd == -1\n")); + return False; + } + if (!send_keepalive(cli->fd)) { + close(cli->fd); + cli->fd = -1; + DEBUG(0,("Error sending keepalive packet to client.\n")); + return False; + } + return True; +} + -- cgit From af78eafa6cd8cf5e43c0c4104a3944855e35743f Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 23 Sep 2002 21:24:31 +0000 Subject: Don't uppercase the username and domain in a session setup. (This used to be commit 0ad19825df318030b1772404570cd993fe49e40a) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 298b1e52b6..62acccdfb7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -317,8 +317,8 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; memcpy(p,ntpword,ntpasslen); p += ntpasslen; - p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, user, -1, STR_TERMINATE); + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/libsmb/asn1.c | 21 +++- source3/libsmb/cliconnect.c | 279 +++++++++++++++++++++++++----------------- source3/libsmb/clientgen.c | 144 +++++++++++++--------- source3/libsmb/clierror.c | 4 +- source3/libsmb/clifile.c | 2 +- source3/libsmb/clikrb5.c | 23 +++- source3/libsmb/clilist.c | 48 ++++---- source3/libsmb/clireadwrite.c | 2 +- source3/libsmb/clispnego.c | 92 ++++++++++---- source3/libsmb/libsmb_cache.c | 4 +- source3/libsmb/libsmbclient.c | 12 +- source3/libsmb/namecache.c | 53 ++++---- source3/libsmb/nterr.c | 2 +- source3/libsmb/smbencrypt.c | 60 ++++++--- source3/libsmb/trust_passwd.c | 5 +- 15 files changed, 474 insertions(+), 277 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index b4ad3ad0b8..b7cfca41fb 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -174,6 +174,16 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) return !data->has_error; } +/* write a BOOLEAN - hmm, I suspect this one is the correct one, and the + above boolean is bogus. Need to check */ +BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) +{ + asn1_push_tag(data, ASN1_BOOLEAN); + asn1_write_uint8(data, v); + asn1_pop_tag(data); + return !data->has_error; +} + /* check a BOOLEAN */ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) { @@ -244,15 +254,12 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) asn1_read_uint8(data, &b); if (b & 0x80) { int n = b & 0x7f; - if (n > 2) { - data->has_error = True; - return False; - } asn1_read_uint8(data, &b); nesting->taglen = b; - if (n == 2) { + while (n > 1) { asn1_read_uint8(data, &b); nesting->taglen = (nesting->taglen << 8) | b; + n--; } } else { nesting->taglen = b; @@ -366,6 +373,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) { int len; + ZERO_STRUCTP(blob); if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; len = asn1_tag_remaining(data); *blob = data_blob(NULL, len); @@ -382,7 +390,8 @@ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) if (!asn1_start_tag(data, ASN1_INTEGER)) return False; while (asn1_tag_remaining(data)>0) { - *i = (*i << 8) + asn1_read_uint8(data, &b); + asn1_read_uint8(data, &b); + *i = (*i << 8) + b; } return asn1_end_tag(data); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 93cf3d95db..62acccdfb7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -50,14 +50,12 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, fstring pword; char *p; - if (passlen > sizeof(pword)-1) { + if (passlen > sizeof(pword)-1) return False; - } /* if in share level security then don't send a password now */ - if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) { + if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) passlen = 0; - } if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ @@ -99,9 +97,8 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -118,17 +115,14 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) { uint32 capabilities = CAP_NT_SMBS; - if (!cli->force_dos_errors) { + if (!cli->force_dos_errors) capabilities |= CAP_STATUS32; - } - if (cli->use_level_II_oplocks) { + if (cli->use_level_II_oplocks) capabilities |= CAP_LEVEL_II_OPLOCKS; - } - if (cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) capabilities |= CAP_UNICODE; - } return capabilities; } @@ -167,9 +161,8 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -223,9 +216,8 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } cli->vuid = SVAL(cli->inbuf,smb_uid); p = smb_buf(cli->inbuf); @@ -237,15 +229,41 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, return True; } +static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 response[24]) +{ + uint8 zero_sig[8]; + ZERO_STRUCT(zero_sig); + + DEBUG(5, ("Server returned security sig:\n")); + dump_data(5, &cli->inbuf[smb_ss_field], 8); -/** + if (cli->sign_info.use_smb_signing) { + DEBUG(5, ("smb signing already active on connection\n")); + } else if (memcmp(&cli->inbuf[smb_ss_field], zero_sig, 8) != 0) { + + DEBUG(3, ("smb signing enabled!\n")); + cli->sign_info.use_smb_signing = True; + cli_calculate_mac_key(cli, pass, response); + } else { + DEBUG(5, ("smb signing NOT enabled!\n")); + } +} + +static void set_temp_signing_on_cli(struct cli_state *cli) +{ + if (cli->sign_info.negotiated_smb_signing) + cli->sign_info.temp_smb_signing = True; +} + + +/**************************************************************************** do a NT1 NTLM/LM encrypted session setup @param cli client state to create do session setup on @param user username @param pass *either* cleartext password (passlen !=24) or LM response. @param ntpass NT response, implies ntpasslen >=24, implies pass is not clear @param workgroup The user's domain. -*/ +****************************************************************************/ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, char *pass, int passlen, @@ -256,11 +274,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, uchar pword[24]; uchar ntpword[24]; char *p; - BOOL tried_signing = False; + BOOL have_plaintext = False; - if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) { + if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) return False; - } if (passlen != 24) { /* non encrypted password supplied. Ignore ntpass. */ @@ -268,19 +285,18 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, ntpasslen = 24; SMBencrypt(pass,cli->secblob.data,pword); SMBNTencrypt(pass,cli->secblob.data,ntpword); - if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) { - cli_calculate_mac_key(cli, pass, ntpword); - tried_signing = True; - } + + have_plaintext = True; + set_temp_signing_on_cli(cli); } else { - /* pre-encrypted password supplied. Only used for security=server, can't do + /* pre-encrypted password supplied. Only used for + security=server, can't do signing becouse we don't have oringial key */ memcpy(pword, pass, 24); - if (ntpasslen == 24) { + if (ntpasslen == 24) memcpy(ntpword, ntpass, 24); - } else { + else ZERO_STRUCT(ntpword); - } } /* send a session setup command */ @@ -301,31 +317,22 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; memcpy(p,ntpword,ntpasslen); p += ntpasslen; - p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); - p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); + p += clistr_push(cli, p, user, -1, STR_TERMINATE); + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - if (tried_signing) { - /* We only use it if we have a successful non-guest connect */ - cli->sign_info.use_smb_signing = False; - } + if (!cli_send_smb(cli)) return False; - } - show_msg(cli->inbuf); + if (!cli_receive_smb(cli)) + return False; - if (tried_signing && (cli_is_error(cli) || SVAL(cli->inbuf,smb_vwv2) /* guest */)) { - /* We only use it if we have a successful non-guest connect */ - cli->sign_info.use_smb_signing = False; - } + show_msg(cli->inbuf); - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -337,6 +344,11 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, fstrcpy(cli->user_name, user); + if (have_plaintext) { + /* Have plaintext orginal */ + set_signing_on_cli(cli, pass, ntpword); + } + return True; } @@ -360,6 +372,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); + + set_temp_signing_on_cli(cli); + cli_setup_packet(cli); SCVAL(cli->outbuf,smb_vwv0,0xFF); @@ -375,8 +390,8 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + if (!cli_receive_smb(cli)) return blob2; @@ -404,7 +419,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return blob2; } - #ifdef HAVE_KRB5 /**************************************************************************** Do a spnego/kerberos encrypted session setup. @@ -417,7 +431,7 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(cli, principal); + negTokenTarg = spnego_gen_negTokenTarg(principal, 0); if (!negTokenTarg.data) return False; @@ -443,28 +457,32 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, char *pass, char *workgroup) { - const char *mechs[] = {OID_NTLMSSP, NULL}; - DATA_BLOB msg1; - DATA_BLOB blob, chal1, chal2, auth; + DATA_BLOB msg1, struct_blob; + DATA_BLOB blob, chal1, chal2, auth, challenge_blob; uint8 challenge[8]; uint8 nthash[24], lmhash[24], sess_key[16]; - uint32 neg_flags; + uint32 neg_flags, chal_flags, ntlmssp_command, unkn1, unkn2; + pstring server_domain; /* FIX THIS, SHOULD be UCS2-LE */ neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_LM_KEY | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM; memset(sess_key, 0, 16); + DEBUG(10, ("sending NTLMSSP_NEGOTIATE\n")); + /* generate the ntlmssp negotiate packet */ - msrpc_gen(&blob, "CddB", + msrpc_gen(&blob, "CddAA", "NTLMSSP", NTLMSSP_NEGOTIATE, neg_flags, - sess_key, 16); - + workgroup, strlen(workgroup), + cli->calling.name, strlen(cli->calling.name) + 1); + DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n", + neg_flags, workgroup, cli->calling.name)); /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenTarg(mechs, blob); + msg1 = gen_negTokenInit(OID_NTLMSSP, blob); data_blob_free(&blob); /* now send that blob on its way */ @@ -472,9 +490,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&msg1); - if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) return False; - } #if 0 file_save("chal.dat", blob.data, blob.length); @@ -488,10 +505,38 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&blob); - /* encrypt the password with the challenge */ - memcpy(challenge, chal1.data + 24, 8); + /* + * Ok, chal1 and chal2 are actually two identical copies of + * the NTLMSSP Challenge BLOB, and they contain, encoded in them + * the challenge to use. + */ + + if (!msrpc_parse(&chal1, "CdUdbddB", + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + &challenge_blob, 8, + &unkn1, &unkn2, + &struct_blob)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return False; + } + + if (ntlmssp_command != NTLMSSP_CHALLENGE) { + DEBUG(0, ("NTLMSSP Response != NTLMSSP_CHALLENGE. Got %0X\n", + ntlmssp_command)); + return False; + } + + DEBUG(10, ("Challenge:\n")); + dump_data(10, challenge_blob.data, 8); + + /* encrypt the password with the challenge which is in the blob */ + memcpy(challenge, challenge_blob.data, 8); SMBencrypt(pass, challenge,lmhash); SMBNTencrypt(pass, challenge,nthash); + data_blob_free(&challenge_blob); #if 0 file_save("nthash.dat", nthash, 24); @@ -511,7 +556,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, workgroup, user, cli->calling.name, - sess_key, 16, + sess_key, 0, neg_flags); /* wrap it in SPNEGO */ @@ -525,7 +570,12 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, data_blob_free(&auth); data_blob_free(&blob); - return !cli_is_error(cli); + if (cli_is_error(cli)) + return False; + + set_signing_on_cli(cli, pass, nthash); + + return True; } /**************************************************************************** @@ -537,17 +587,14 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, { char *principal; char *OIDs[ASN1_MAX_OIDS]; - uint8 guid[16]; int i; BOOL got_kerberos_mechanism = False; - - /* spnego security cannot use SMB signing (for now). */ - cli->sign_info.use_smb_signing = False; + DATA_BLOB blob; DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); /* the server might not even do spnego */ - if (cli->secblob.length == 16) { + if (cli->secblob.length <= 16) { DEBUG(3,("server didn't supply a full spnego negprot\n")); goto ntlmssp; } @@ -556,11 +603,16 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, file_save("negprot.dat", cli->secblob.data, cli->secblob.length); #endif + /* there is 16 bytes of GUID before the real spnego packet starts */ + blob = data_blob(cli->secblob.data+16, cli->secblob.length-16); + /* the server sent us the first part of the SPNEGO exchange in the negprot reply */ - if (!spnego_parse_negTokenInit(cli->secblob, guid, OIDs, &principal)) { + if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { + data_blob_free(&blob); return False; } + data_blob_free(&blob); /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { @@ -620,35 +672,38 @@ BOOL cli_session_setup(struct cli_state *cli, flow a bit easier to understand (tridge) */ /* if its an older server then we have to use the older request format */ - if (cli->protocol < PROTOCOL_NT1) { + + if (cli->protocol < PROTOCOL_NT1) return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); - } /* if no user is supplied then we have to do an anonymous connection. passwords are ignored */ - if (!user || !*user) { + + if (!user || !*user) return cli_session_setup_guest(cli); - } /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) { + + if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) return cli_session_setup_plaintext(cli, user, "", workgroup); - } /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { + + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) return cli_session_setup_plaintext(cli, user, pass, workgroup); - } + /* Indidicate signing */ + /* if the server supports extended security then use SPNEGO */ - if (cli->capabilities & CAP_EXTENDED_SECURITY) { + + if (cli->capabilities & CAP_EXTENDED_SECURITY) return cli_session_setup_spnego(cli, user, pass, workgroup); - } /* otherwise do a NT1 style session setup */ + return cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup); @@ -738,15 +793,13 @@ BOOL cli_send_tconX(struct cli_state *cli, if (!cli_receive_smb(cli)) return False; - if (cli_is_error(cli)) { + if (cli_is_error(cli)) return False; - } clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII); - if (strcasecmp(share,"IPC$")==0) { + if (strcasecmp(share,"IPC$")==0) fstrcpy(cli->dev, "IPC"); - } if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { @@ -786,9 +839,8 @@ void cli_negprot_send(struct cli_state *cli) char *p; int numprots; - if (cli->protocol < PROTOCOL_NT1) { + if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; - } memset(cli->outbuf,'\0',smb_size); @@ -827,9 +879,8 @@ BOOL cli_negprot(struct cli_state *cli) return False; } - if (cli->protocol < PROTOCOL_NT1) { + if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; - } memset(cli->outbuf,'\0',smb_size); @@ -891,12 +942,8 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - /* A way to attempt to force SMB signing */ - if (getenv("CLI_FORCE_SMB_SIGNING")) + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) cli->sign_info.negotiated_smb_signing = True; - - if (cli->sign_info.negotiated_smb_signing && !(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) - cli->sign_info.negotiated_smb_signing = False; } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; @@ -920,9 +967,8 @@ BOOL cli_negprot(struct cli_state *cli) cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); /* a way to force ascii SMB */ - if (getenv("CLI_FORCE_ASCII")) { + if (getenv("CLI_FORCE_ASCII")) cli->capabilities &= ~CAP_UNICODE; - } return True; } @@ -938,15 +984,6 @@ BOOL cli_session_request(struct cli_state *cli, int len = 4; extern pstring user_socket_options; - /* 445 doesn't have session request */ - if (cli->port == 445) return True; - - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); - return False; - } - - /* send a session request (RFC 1002) */ memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); @@ -960,6 +997,16 @@ BOOL cli_session_request(struct cli_state *cli, name_mangle(cli->calling.name, p, cli->calling.name_type); len += name_len(p); + /* 445 doesn't have session request */ + if (cli->port == 445) + return True; + + if (cli->sign_info.use_smb_signing) { + DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); + return False; + } + + /* send a session request (RFC 1002) */ /* setup the packet length * Remove four bytes from the length count, since the length * field in the NBT Session Service header counts the number @@ -1066,7 +1113,8 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, cli->timeout); } - if (cli->fd != -1) cli->port = port; + if (cli->fd != -1) + cli->port = port; } if (cli->fd == -1) { DEBUG(1,("Error connecting to %s (%s)\n", @@ -1141,11 +1189,10 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return NT_STATUS_UNSUCCESSFUL; } - if (dest_ip) { + if (dest_ip) ip = *dest_ip; - } else { + else ZERO_STRUCT(ip); - } again: @@ -1162,8 +1209,7 @@ again: char *p; DEBUG(1,("session request to %s failed (%s)\n", called.name, cli_errstr(cli))); - cli_shutdown(cli); - if ((p=strchr(called.name, '.'))) { + if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) { *p = 0; goto again; } @@ -1174,11 +1220,10 @@ again: return NT_STATUS_UNSUCCESSFUL; } - if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) { + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) cli->use_spnego = False; - } else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) { + else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) cli->use_kerberos = True; - } if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); @@ -1261,18 +1306,22 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ with error %s.\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); return False; } - cli_shutdown(cli); + /* + * We need to close the connection here but can't call cli_shutdown as + * will free an allocated cli struct. cli_close_connection was invented + * for this purpose. JRA. Based on work by "Kim R. Pedersen" . + */ + + cli_close_connection(cli); if (!cli_initialise(cli) || !cli_connect(cli, desthost, pdest_ip) || !cli_session_request(cli, &calling, &smbservername)) { DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); - cli_shutdown(cli); return False; } } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c9500ead5d..793dd19644 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -32,49 +32,48 @@ int cli_set_port(struct cli_state *cli, int port) } /**************************************************************************** - read an smb from a fd ignoring all keepalive packets. Note that the buffer - *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. - The timeout is in milliseconds - - This is exactly the same as receive_smb except that it never returns - a session keepalive packet (just as receive_smb used to do). - receive_smb was changed to return keepalives as the oplock processing means this call - should never go into a blocking read. + Read an smb from a fd ignoring all keepalive packets. Note that the buffer + *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + The timeout is in milliseconds + + This is exactly the same as receive_smb except that it never returns + a session keepalive packet (just as receive_smb used to do). + receive_smb was changed to return keepalives as the oplock processing means this call + should never go into a blocking read. ****************************************************************************/ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) { - BOOL ret; - - for(;;) - { - ret = receive_smb(fd, buffer, timeout); - - if (!ret) - { - DEBUG(10,("client_receive_smb failed\n")); - show_msg(buffer); - return ret; - } - - /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) - break; - } - show_msg(buffer); - return ret; -} + BOOL ret; + + for(;;) { + ret = receive_smb(fd, buffer, timeout); + if (!ret) { + DEBUG(10,("client_receive_smb failed\n")); + show_msg(buffer); + return ret; + } + + /* Ignore session keepalive packets. */ + if(CVAL(buffer,0) != SMBkeepalive) + break; + } + show_msg(buffer); + return ret; +} /**************************************************************************** -recv an smb + Recv an smb. ****************************************************************************/ + BOOL cli_receive_smb(struct cli_state *cli) { BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) return False; + if (cli->fd == -1) + return False; again: ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); @@ -151,34 +150,32 @@ void cli_setup_packet(struct cli_state *cli) uint16 flags2; SCVAL(cli->outbuf,smb_flg,0x8); flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli->capabilities & CAP_UNICODE) { + if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; - } - if (cli->capabilities & CAP_STATUS32) { + if (cli->capabilities & CAP_STATUS32) flags2 |= FLAGS2_32_BIT_ERROR_CODES; - } - if (cli->use_spnego) { + if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - } - if (cli->sign_info.use_smb_signing) + if (cli->sign_info.use_smb_signing + || cli->sign_info.temp_smb_signing) flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } /**************************************************************************** -setup the bcc length of the packet from a pointer to the end of the data + Setup the bcc length of the packet from a pointer to the end of the data. ****************************************************************************/ + void cli_setup_bcc(struct cli_state *cli, void *p) { set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); } - - /**************************************************************************** -initialise credentials of a client structure + Initialise credentials of a client structure. ****************************************************************************/ + void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ @@ -193,10 +190,10 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) cli->ntlmssp_flags,cli->ntlmssp_cli_flgs)); } - /**************************************************************************** -initialise a client structure + Initialise a client structure. ****************************************************************************/ + struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; @@ -215,9 +212,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) alloced_cli = True; } - if (cli->initialised) { - cli_shutdown(cli); - } + if (cli->initialised) + cli_close_connection(cli); ZERO_STRUCTP(cli); @@ -234,7 +230,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - cli->use_spnego = True; + if (lp_use_spnego()) { + cli->use_spnego = True; + } /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 @@ -243,6 +241,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->force_dos_errors = True; } + /* A way to attempt to force SMB signing */ + if (getenv("CLI_FORCE_SMB_SIGNING")) + cli->sign_info.negotiated_smb_signing = True; + if (!cli->outbuf || !cli->inbuf) goto error; @@ -273,43 +275,75 @@ struct cli_state *cli_initialise(struct cli_state *cli) } /**************************************************************************** -shutdown a client structure + Close a client connection and free the memory without destroying cli itself. ****************************************************************************/ -void cli_shutdown(struct cli_state *cli) + +void cli_close_connection(struct cli_state *cli) { - BOOL allocated; SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); data_blob_free(&cli->secblob); - if (cli->mem_ctx) + if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); + cli->mem_ctx = NULL; + } if (cli->fd != -1) close(cli->fd); - allocated = cli->allocated; + cli->fd = -1; +} + +/**************************************************************************** + Shutdown a client structure. +****************************************************************************/ + +void cli_shutdown(struct cli_state *cli) +{ + BOOL allocated = cli->allocated; + cli_close_connection(cli); ZERO_STRUCTP(cli); if (allocated) { free(cli); } } - /**************************************************************************** -set socket options on a open connection + Set socket options on a open connection. ****************************************************************************/ + void cli_sockopt(struct cli_state *cli, char *options) { set_socket_options(cli->fd, options); } /**************************************************************************** -set the PID to use for smb messages. Return the old pid. + Set the PID to use for smb messages. Return the old pid. ****************************************************************************/ + uint16 cli_setpid(struct cli_state *cli, uint16 pid) { uint16 ret = cli->pid; cli->pid = pid; return ret; } + +/**************************************************************************** +Send a keepalive packet to the server +****************************************************************************/ +BOOL cli_send_keepalive(struct cli_state *cli) +{ + if (cli->fd == -1) { + DEBUG(3, ("cli_send_keepalive: fd == -1\n")); + return False; + } + if (!send_keepalive(cli->fd)) { + close(cli->fd); + cli->fd = -1; + DEBUG(0,("Error sending keepalive packet to client.\n")); + return False; + } + return True; +} + diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 591c04db22..e1507c6048 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -156,7 +156,7 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) /* Return a UNIX errno from a dos error class, error number tuple */ -int cli_errno_from_dos(uint8 eclass, uint32 num) +static int cli_errno_from_dos(uint8 eclass, uint32 num) { if (eclass == ERRDOS) { switch (num) { @@ -205,7 +205,7 @@ static struct { {NT_STATUS(0), 0} }; -int cli_errno_from_nt(NTSTATUS status) +static int cli_errno_from_nt(NTSTATUS status) { int i; DEBUG(10,("cli_errno_from_nt: 32 bit codes: code=%08x\n", NT_STATUS_V(status))); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a47c956a55..07b1ff6b6f 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -94,7 +94,7 @@ uint32 unix_perms_to_wire(mode_t perms) ret |= ((perms & S_ISGID) ? UNIX_SET_GID : 0); #endif #ifdef S_ISUID - ret |= ((perms & S_ISVTX) ? UNIX_SET_UID : 0); + ret |= ((perms & S_ISUID) ? UNIX_SET_UID : 0); #endif return ret; } diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 685c4a25e0..e7143d065d 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -64,6 +64,14 @@ static krb5_error_code krb5_mk_req2(krb5_context context, goto cleanup_creds; } + /* cope with the ticket being in the future due to clock skew */ + if ((unsigned)credsp->times.starttime > time(NULL)) { + time_t t = time(NULL); + int time_offset = (unsigned)credsp->times.starttime - t; + DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + krb5_set_real_time(context, t + time_offset + 1, 0); + } + in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); @@ -86,7 +94,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(char *principal) +DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) { krb5_error_code retval; krb5_data packet; @@ -94,7 +102,12 @@ DATA_BLOB krb5_get_ticket(char *principal) krb5_context context; krb5_auth_context auth_context = NULL; DATA_BLOB ret; - krb5_enctype enc_types[] = {ENCTYPE_DES_CBC_MD5, ENCTYPE_NULL}; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_NULL}; retval = krb5_init_context(&context); if (retval) { @@ -103,6 +116,10 @@ DATA_BLOB krb5_get_ticket(char *principal) goto failed; } + if (time_offset != 0) { + krb5_set_real_time(context, time(NULL) + time_offset, 0); + } + if ((retval = krb5_cc_default(context, &ccdef))) { DEBUG(1,("krb5_cc_default failed (%s)\n", error_message(retval))); @@ -137,7 +154,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(char *principal) + DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 17a759f9e3..3eacc25380 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -22,13 +22,13 @@ #include "includes.h" - /**************************************************************************** -interpret a long filename structure - this is mostly guesses at the moment -The length of the structure is returned -The structure of a long filename depends on the info level. 260 is used -by NT and 2 is used by OS/2 + Interpret a long filename structure - this is mostly guesses at the moment. + The length of the structure is returned + The structure of a long filename depends on the info level. 260 is used + by NT and 2 is used by OS/2 ****************************************************************************/ + static int interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { @@ -41,8 +41,7 @@ static int interpret_long_filename(struct cli_state *cli, memcpy(finfo,&def_finfo,sizeof(*finfo)); - switch (level) - { + switch (level) { case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ @@ -126,16 +125,16 @@ static int interpret_long_filename(struct cli_state *cli, namelen, 0); return SVAL(base, 0); } - } + } DEBUG(1,("Unknown long filename format %d\n",level)); return(SVAL(p,0)); } - /**************************************************************************** - do a directory listing, calling fn on each file found - ****************************************************************************/ + Do a directory listing, calling fn on each file found. +****************************************************************************/ + int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { @@ -307,12 +306,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, return(total_received); } - - /**************************************************************************** -interpret a short filename structure -The length of the structure is returned + Interpret a short filename structure. + The length of the structure is returned. ****************************************************************************/ + static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { extern file_info def_finfo; @@ -334,10 +332,11 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /**************************************************************************** - do a directory listing, calling fn on each file found - this uses the old SMBsearch interface. It is needed for testing Samba, - but should otherwise not be used - ****************************************************************************/ + Do a directory listing, calling fn on each file found. + this uses the old SMBsearch interface. It is needed for testing Samba, + but should otherwise not be used. +****************************************************************************/ + int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { @@ -453,16 +452,15 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, return(num_received); } - /**************************************************************************** - do a directory listing, calling fn on each file found - this auto-switches between old and new style - ****************************************************************************/ + Do a directory listing, calling fn on each file found. + This auto-switches between old and new style. +****************************************************************************/ + int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { - if (cli->protocol <= PROTOCOL_LANMAN1) { + if (cli->protocol <= PROTOCOL_LANMAN1) return cli_list_old(cli, Mask, attribute, fn, state); - } return cli_list_new(cli, Mask, attribute, fn, state); } diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 756a6cce2f..875df11dca 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -127,7 +127,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return total; } -#if 0 /* relies on client_recieve_smb(), now a static in libsmb/clientgen.c */ +#if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */ /* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0 you must fix ensure you don't attempt to sign the packets - data diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 16702c375b..55f49c5987 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -73,13 +73,56 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], return ret; } +/* + Generate a negTokenInit as used by the client side ... It has a mechType + (OID), and a mechToken (a security blob) ... + + Really, we need to break out the NTLMSSP stuff as well, because it could be + raw in the packets! +*/ +DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OID(&data, OID); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} /* parse a negTokenInit packet giving a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, - uint8 guid[16], char *OIDs[ASN1_MAX_OIDS], char **principal) { @@ -89,7 +132,6 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_load(&data, blob); - asn1_read(&data, guid, 16); asn1_start_tag(&data,ASN1_APPLICATION(0)); asn1_check_OID(&data,OID_SPNEGO); asn1_start_tag(&data,ASN1_CONTEXT(0)); @@ -279,13 +321,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principal) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principal); + tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); @@ -473,8 +515,10 @@ DATA_BLOB spnego_gen_auth_response(void) U = unicode string (input is unix string) a = address (1 byte type, 1 byte length, unicode string, all inline) + A = ASCII string (pointer + length) Actually same as B B = data blob (pointer + length) b = data blob in header (pointer + length) + D d = word (4 bytes) C = constant ascii string */ @@ -502,6 +546,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, s = va_arg(ap, char *); data_size += (str_charnum(s) * 2) + 4; break; + case 'A': case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -553,7 +598,8 @@ BOOL msrpc_gen(DATA_BLOB *blob, } data_ofs += n*2; break; - + + case 'A': case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -688,37 +734,39 @@ BOOL msrpc_parse(DATA_BLOB *blob, void debug_ntlmssp_flags(uint32 neg_flags) { + DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUG(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUG(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUG(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUG(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUG(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUG(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUG(4, (" NTLMSSP_NEGOTIATE_128\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUG(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); } diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 34b818ee74..df02cf3718 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -89,7 +89,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, goto failed; } - DLIST_ADD(((struct smbc_server_cache *)context->server_cache), srvcache); + DLIST_ADD((context->server_cache), srvcache); return 0; failed: @@ -139,7 +139,7 @@ static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) if (server == srv->server) { /* remove this sucker */ - DLIST_REMOVE(((struct smbc_server_cache *)context->server_cache), srv); + DLIST_REMOVE(context->server_cache, srv); SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv->workgroup); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 0ffc1c1378..44cba611d2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -180,14 +180,13 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, static int smbc_errno(SMBCCTX *context, struct cli_state *c) { - int ret; - + int ret = cli_errno(c); + if (cli_is_dos_error(c)) { uint8 eclass; uint32 ecode; cli_dos_error(c, &eclass, &ecode); - ret = cli_errno_from_dos(eclass, ecode); DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", (int)eclass, (int)ecode, (int)ecode, ret)); @@ -195,10 +194,9 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c) NTSTATUS status; status = cli_nt_error(c); - ret = cli_errno_from_nt(status); DEBUG(3,("smbc errno %s -> %d\n", - get_nt_error_msg(status), ret)); + nt_errstr(status), ret)); } return ret; @@ -213,7 +211,7 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c) */ int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - if ( cli_send_keepalive(&server->cli) == False ) + if ( send_keepalive(server->cli.fd) == False ) return 1; /* connection is ok */ @@ -380,7 +378,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, fstring remote_name; struct in_addr rem_ip; - if (!inet_aton(server, &rem_ip)) { + if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server)); errno = ENOENT; return NULL; diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index fc09d8eac2..2252e8e59c 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -29,24 +29,24 @@ static TDB_CONTEXT *namecache_tdb; struct nc_value { time_t expiry; /* When entry expires */ int count; /* Number of addresses */ - struct in_addr ip_list[0]; /* Address list */ + struct in_addr ip_list[1]; /* Address list */ }; /* Initialise namecache system */ -void namecache_enable(void) +BOOL namecache_enable(void) { /* Check if we have been here before, or name caching disabled by setting the name cache timeout to zero. */ if (done_namecache_init) - return; + return False; done_namecache_init = True; if (lp_name_cache_timeout() == 0) { DEBUG(5, ("namecache_init: disabling netbios name cache\n")); - return; + return False; } /* Open namecache tdb in read/write or readonly mode */ @@ -58,13 +58,15 @@ void namecache_enable(void) if (!namecache_tdb) { DEBUG(5, ("namecache_init: could not open %s\n", lock_path("namecache.tdb"))); - return; + return False; } DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d " "seconds\n", lp_name_cache_timeout())); enable_namecache = True; + + return True; } /* Return a key for a name and name type. The caller must free @@ -91,17 +93,20 @@ static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, { TDB_DATA retval; struct nc_value *value; - int size; + int size = sizeof(struct nc_value); - size = sizeof(struct nc_value) + sizeof(struct in_addr) * - num_names; + if (num_names > 0) + size += sizeof(struct in_addr) * (num_names-1); value = (struct nc_value *)malloc(size); - + + memset(value, 0, size); + value->expiry = expiry; value->count = num_names; - memcpy(value->ip_list, ip_list, num_names * sizeof(struct in_addr)); + if (ip_list) + memcpy(value->ip_list, ip_list, sizeof(struct in_addr) * num_names); retval.dptr = (char *)value; retval.dsize = size; @@ -160,6 +165,9 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, time_t now; int i; + *ip_list = NULL; + *num_names = 0; + if (!enable_namecache) return False; @@ -209,20 +217,23 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, /* Extract and return namelist */ - *ip_list = (struct in_addr *)malloc( - sizeof(struct in_addr) * data->count); - - memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * - data->count); + DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", + data->count, data->count == 1 ? "" : "es", name, name_type)); - *num_names = data->count; + if (data->count) { - DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", - *num_names, *num_names == 1 ? "" : "es", name, name_type)); + *ip_list = (struct in_addr *)malloc( + sizeof(struct in_addr) * data->count); + + memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * data->count); + + *num_names = data->count; + + for (i = 0; i < *num_names; i++) + DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), + i == (*num_names - 1) ? "" : ", ")); - for (i = 0; i < *num_names; i++) - DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), - i == (*num_names - 1) ? "" : ", ")); + } DEBUGADD(5, ("\n")); diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index e2da6318e1..02fd53fc05 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -28,7 +28,7 @@ typedef const struct NTSTATUS nt_errcode; } nt_err_code_struct; -nt_err_code_struct nt_errs[] = +static nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index dfa355a7ec..db265c4bf7 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -116,39 +116,63 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) } /* Does both the NTLMv2 owfs of a user's password */ -void ntv2_owf_gen(const uchar owf[16], - const char *user_n, const char *domain_n, uchar kr_buf[16]) +BOOL ntv2_owf_gen(const uchar owf[16], + const char *user_in, const char *domain_in, uchar kr_buf[16]) { - pstring user_u; - pstring dom_u; + smb_ucs2_t *user; + smb_ucs2_t *domain; + + int user_byte_len; + int domain_byte_len; + HMACMD5Context ctx; - int user_l = strlen(user_n); - int domain_l = strlen(domain_n); + user_byte_len = push_ucs2_allocate(&user, user_in); + if (user_byte_len < 0) { + DEBUG(0, ("push_uss2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); + return False; + } - push_ucs2(NULL, user_u, user_n, (user_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); - push_ucs2(NULL, dom_u, domain_n, (domain_l+1)*2, STR_UNICODE|STR_NOALIGN|STR_TERMINATE|STR_UPPER); + domain_byte_len = push_ucs2_allocate(&domain, domain_in); + if (domain_byte_len < 0) { + DEBUG(0, ("push_uss2_allocate() for domain returned %d (probably malloc() failure)\n", user_byte_len)); + return False; + } + + strupper_w(user); + strupper_w(domain); + + /* We don't want null termination */ + user_byte_len = user_byte_len - 2; + domain_byte_len = domain_byte_len - 2; + + SMB_ASSERT(user_byte_len >= 0); + SMB_ASSERT(domain_byte_len >= 0); hmac_md5_init_limK_to_64(owf, 16, &ctx); - hmac_md5_update((const unsigned char *)user_u, user_l * 2, &ctx); - hmac_md5_update((const unsigned char *)dom_u, domain_l * 2, &ctx); + hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); + hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); hmac_md5_final(kr_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, user_u, user_l * 2); - dump_data(100, dom_u, domain_l * 2); + dump_data(100, (const char *)user, user_byte_len); + dump_data(100, (const char *)domain, domain_byte_len); dump_data(100, owf, 16); dump_data(100, kr_buf, 16); #endif + + SAFE_FREE(user); + SAFE_FREE(domain); + return True; } /* Does the des encryption from the NT or LM MD4 hash. */ void SMBOWFencrypt(const uchar passwd[16], const uchar *c8, uchar p24[24]) { uchar p21[21]; - - memset(p21,'\0',21); + + ZERO_STRUCT(p21); memcpy(p21, passwd, 16); E_P24(p21, c8, p24); @@ -362,6 +386,12 @@ void cli_caclulate_sign_mac(struct cli_state *cli) unsigned char calc_md5_mac[16]; struct MD5Context md5_ctx; + if (cli->sign_info.temp_smb_signing) { + memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + cli->sign_info.temp_smb_signing = False; + return; + } + if (!cli->sign_info.use_smb_signing) { return; } @@ -380,6 +410,8 @@ void cli_caclulate_sign_mac(struct cli_state *cli) MD5Final(calc_md5_mac, &md5_ctx); memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signitures...*/ cli->sign_info.send_seq_num++; cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; cli->sign_info.send_seq_num++; diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index fe6b673e39..4d7acd1988 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -35,8 +35,9 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ unsigned char new_trust_passwd_hash[16]) { NTSTATUS result; - result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ? - SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash); + uint32 neg_flags = 0x000001ff; + + result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", -- cgit From ef6f8197a3071996591f74f6d7b9d36dbcb19dc7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 26 Sep 2002 18:53:51 +0000 Subject: remove files not in HEAD (This used to be commit 9d9f7bbf87bf9a0e003e6da482615fe040d00852) --- source3/libsmb/cli_dfs.c | 245 ---- source3/libsmb/cli_lsarpc.c | 1168 ------------------- source3/libsmb/cli_netlogon.c | 664 ----------- source3/libsmb/cli_pipe_util.c | 82 -- source3/libsmb/cli_reg.c | 102 -- source3/libsmb/cli_samr.c | 1294 --------------------- source3/libsmb/cli_spoolss.c | 2156 ----------------------------------- source3/libsmb/cli_spoolss_notify.c | 223 ---- source3/libsmb/cli_srvsvc.c | 442 ------- source3/libsmb/cli_wkssvc.c | 93 -- 10 files changed, 6469 deletions(-) delete mode 100644 source3/libsmb/cli_dfs.c delete mode 100644 source3/libsmb/cli_lsarpc.c delete mode 100644 source3/libsmb/cli_netlogon.c delete mode 100644 source3/libsmb/cli_pipe_util.c delete mode 100644 source3/libsmb/cli_reg.c delete mode 100644 source3/libsmb/cli_samr.c delete mode 100644 source3/libsmb/cli_spoolss.c delete mode 100644 source3/libsmb/cli_spoolss_notify.c delete mode 100644 source3/libsmb/cli_srvsvc.c delete mode 100644 source3/libsmb/cli_wkssvc.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cli_dfs.c b/source3/libsmb/cli_dfs.c deleted file mode 100644 index 7fc27b9c3b..0000000000 --- a/source3/libsmb/cli_dfs.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Query DFS support */ - -NTSTATUS cli_dfs_exist(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL *dfs_exists) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_EXIST q; - DFS_R_DFS_EXIST r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_exist(&q); - - if (!dfs_io_q_dfs_exist("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_EXIST, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_exist("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - *dfs_exists = (r.status != 0); - - result = NT_STATUS_OK; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename, - char *comment, uint32 flags) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_ADD q; - DFS_R_DFS_ADD r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_add(&q, entrypath, servername, sharename, comment, - flags); - - if (!dfs_io_q_dfs_add("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_ADD, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_add("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_remove(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_REMOVE q; - DFS_R_DFS_REMOVE r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_remove(&q, entrypath, servername, sharename); - - if (!dfs_io_q_dfs_remove("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_REMOVE, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_remove("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -NTSTATUS cli_dfs_get_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *entrypath, char *servername, char *sharename, - uint32 info_level, DFS_INFO_CTR *ctr) - -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_GET_INFO q; - DFS_R_DFS_GET_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_get_info(&q, entrypath, servername, sharename, - info_level); - - if (!dfs_io_q_dfs_get_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_GET_INFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!dfs_io_r_dfs_get_info("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - *ctr = r.ctr; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enumerate dfs shares */ - -NTSTATUS cli_dfs_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 info_level, DFS_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - DFS_Q_DFS_ENUM q; - DFS_R_DFS_ENUM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_dfs_q_dfs_enum(&q, info_level, ctr); - - if (!dfs_io_q_dfs_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, DFS_ENUM, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!dfs_io_r_dfs_enum("", &r, &rbuf, 0)) { - goto done; - } - - /* Return result */ - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_lsarpc.c b/source3/libsmb/cli_lsarpc.c deleted file mode 100644 index 7dfee46fae..0000000000 --- a/source3/libsmb/cli_lsarpc.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - Copyright (C) Andrew Tridgell 1992-1997,2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, - Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000, - Copyright (C) Rafal Szczesniak 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** @defgroup lsa LSA - Local Security Architecture - * @ingroup rpc_client - * - * @{ - **/ - -/** - * @file cli_lsarpc.c - * - * RPC client routines for the LSA RPC pipe. LSA means "local - * security authority", which is half of a password database. - **/ - -/** Open a LSA policy handle - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_open_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL sec_qos, uint32 des_access, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPEN_POL q; - LSA_R_OPEN_POL r; - LSA_SEC_QOS qos; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0); - init_q_open_pol(&q, '\\', 0, des_access, &qos); - } else { - init_q_open_pol(&q, '\\', 0, des_access, NULL); - } - - /* Marshall data and send request */ - - if (!lsa_io_q_open_pol("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENPOLICY, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_pol("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *pol = r.pol; -#ifdef __INSURE__ - pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Open a LSA policy handle - * - * @param cli Handle on an initialised SMB connection - */ - -NTSTATUS cli_lsa_open_policy2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - BOOL sec_qos, uint32 des_access, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPEN_POL2 q; - LSA_R_OPEN_POL2 r; - LSA_SEC_QOS qos; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - if (sec_qos) { - init_lsa_sec_qos(&qos, 2, 1, 0); - init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access, - &qos); - } else { - init_q_open_pol2(&q, cli->srv_name_slash, 0, des_access, - NULL); - } - - /* Marshall data and send request */ - - if (!lsa_io_q_open_pol2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENPOLICY2, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_pol2("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *pol = r.pol; -#ifdef __INSURE__ - pol->marker = (char *)malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Close a LSA policy handle */ - -NTSTATUS cli_lsa_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_CLOSE q; - LSA_R_CLOSE r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_q_close(&q, pol); - - if (!lsa_io_q_close("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_CLOSE, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_close("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { -#ifdef __INSURE__ - SAFE_FREE(pol->marker); -#endif - *pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Lookup a list of sids */ - -NTSTATUS cli_lsa_lookup_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_sids, DOM_SID *sids, - char ***domains, char ***names, uint32 **types) -{ - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_SIDS q; - LSA_R_LOOKUP_SIDS r; - DOM_R_REF ref; - LSA_TRANS_NAME_ENUM t_names; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_lookup_sids(mem_ctx, &q, pol, num_sids, sids, 1); - - if (!lsa_io_q_lookup_sids("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_LOOKUPSIDS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - ZERO_STRUCT(ref); - ZERO_STRUCT(t_names); - - r.dom_ref = &ref; - r.names = &t_names; - - if (!lsa_io_r_lookup_sids("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - - /* An actual error occured */ - - goto done; - } - - /* Return output parameters */ - - if (r.mapped_count == 0) { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - if (!((*domains) = (char **)talloc(mem_ctx, sizeof(char *) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*names) = (char **)talloc(mem_ctx, sizeof(char *) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*types) = (uint32 *)talloc(mem_ctx, sizeof(uint32) * - num_sids))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < num_sids; i++) { - fstring name, dom_name; - uint32 dom_idx = t_names.name[i].domain_idx; - - /* Translate optimised name through domain index array */ - - if (dom_idx != 0xffffffff) { - - rpcstr_pull_unistr2_fstring( - dom_name, &ref.ref_dom[dom_idx].uni_dom_name); - rpcstr_pull_unistr2_fstring( - name, &t_names.uni_name[i]); - - (*names)[i] = talloc_strdup(mem_ctx, name); - (*domains)[i] = talloc_strdup(mem_ctx, dom_name); - (*types)[i] = t_names.name[i].sid_name_use; - - if (((*names)[i] == NULL) || ((*domains)[i] == NULL)) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - } else { - (*names)[i] = NULL; - (*types)[i] = SID_NAME_UNKNOWN; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Lookup a list of names */ - -NTSTATUS cli_lsa_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, int num_names, - const char **names, DOM_SID **sids, - uint32 **types) -{ - prs_struct qbuf, rbuf; - LSA_Q_LOOKUP_NAMES q; - LSA_R_LOOKUP_NAMES r; - DOM_R_REF ref; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_lookup_names(mem_ctx, &q, pol, num_names, names); - - if (!lsa_io_q_lookup_names("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_LOOKUPNAMES, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - ZERO_STRUCT(ref); - r.dom_ref = &ref; - - if (!lsa_io_r_lookup_names("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && NT_STATUS_V(result) != - NT_STATUS_V(STATUS_SOME_UNMAPPED)) { - - /* An actual error occured */ - - goto done; - } - - /* Return output parameters */ - - if (r.mapped_count == 0) { - result = NT_STATUS_NONE_MAPPED; - goto done; - } - - if (!((*sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * - num_names)))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*types = (uint32 *)talloc(mem_ctx, sizeof(uint32) * - num_names)))) { - DEBUG(0, ("cli_lsa_lookup_sids(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < num_names; i++) { - DOM_RID2 *t_rids = r.dom_rid; - uint32 dom_idx = t_rids[i].rid_idx; - uint32 dom_rid = t_rids[i].rid; - DOM_SID *sid = &(*sids)[i]; - - /* Translate optimised sid through domain index array */ - - if (dom_idx != 0xffffffff) { - - sid_copy(sid, &ref.ref_dom[dom_idx].ref_dom.sid); - - if (dom_rid != 0xffffffff) { - sid_append_rid(sid, dom_rid); - } - - (*types)[i] = t_rids[i].type; - } else { - ZERO_STRUCTP(sid); - (*types)[i] = SID_NAME_UNKNOWN; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Query info policy - * - * @param domain_sid - returned remote server's domain sid */ - -NTSTATUS cli_lsa_query_info_policy(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint16 info_class, - fstring domain_name, DOM_SID *domain_sid) -{ - prs_struct qbuf, rbuf; - LSA_Q_QUERY_INFO q; - LSA_R_QUERY_INFO r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_query(&q, pol, info_class); - - if (!lsa_io_q_query("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_QUERYINFOPOLICY, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_query("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - ZERO_STRUCTP(domain_sid); - domain_name[0] = '\0'; - - switch (info_class) { - - case 3: - if (r.dom.id3.buffer_dom_name != 0) { - unistr2_to_ascii(domain_name, - &r.dom.id3. - uni_domain_name, - sizeof (fstring) - 1); - } - - if (r.dom.id3.buffer_dom_sid != 0) { - *domain_sid = r.dom.id3.dom_sid.sid; - } - - break; - - case 5: - - if (r.dom.id5.buffer_dom_name != 0) { - unistr2_to_ascii(domain_name, &r.dom.id5. - uni_domain_name, - sizeof (fstring) - 1); - } - - if (r.dom.id5.buffer_dom_sid != 0) { - *domain_sid = r.dom.id5.dom_sid.sid; - } - - break; - - default: - DEBUG(3, ("unknown info class %d\n", info_class)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** - * Enumerate list of trusted domains - * - * @param cli client state (cli_state) structure of the connection - * @param mem_ctx memory context - * @param pol opened lsa policy handle - * @param enum_ctx enumeration context ie. index of first returned domain entry - * @param pref_num_domains preferred max number of entries returned in one response - * @param num_domains total number of trusted domains returned by response - * @param domain_names returned trusted domain names - * @param domain_sids returned trusted domain sids - * - * @return nt status code of response - **/ - -NTSTATUS cli_lsa_enum_trust_dom(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_ctx, - uint32 *pref_num_domains, uint32 *num_domains, - char ***domain_names, DOM_SID **domain_sids) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_TRUST_DOM q; - LSA_R_ENUM_TRUST_DOM r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_enum_trust_dom(&q, pol, *enum_ctx, *pref_num_domains); - - if (!lsa_io_q_enum_trust_dom("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUMTRUSTDOM, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_trust_dom("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) && - !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) { - - /* An actual error ocured */ - - goto done; - } - - /* Return output parameters */ - - if (r.num_domains) { - - /* Allocate memory for trusted domain names and sids */ - - *domain_names = (char **)talloc(mem_ctx, sizeof(char *) * - r.num_domains); - - if (!*domain_names) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - *domain_sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * - r.num_domains); - if (!domain_sids) { - DEBUG(0, ("cli_lsa_enum_trust_dom(): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Copy across names and sids */ - - for (i = 0; i < r.num_domains; i++) { - fstring tmp; - - unistr2_to_ascii(tmp, &r.uni_domain_name[i], - sizeof(tmp) - 1); - (*domain_names)[i] = talloc_strdup(mem_ctx, tmp); - sid_copy(&(*domain_sids)[i], &r.domain_sid[i].sid); - } - } - - *num_domains = r.num_domains; - *enum_ctx = r.enum_context; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate privileges*/ - -NTSTATUS cli_lsa_enum_privilege(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_context, uint32 pref_max_length, - uint32 *count, char ***privs_name, uint32 **privs_high, uint32 **privs_low) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_PRIVS q; - LSA_R_ENUM_PRIVS r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_q_enum_privs(&q, pol, *enum_context, pref_max_length); - - if (!lsa_io_q_enum_privs("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUM_PRIVS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_privs("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - *enum_context = r.enum_context; - *count = r.count; - - if (!((*privs_name = (char **)talloc(mem_ctx, sizeof(char *) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*privs_high = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!((*privs_low = (uint32 *)talloc(mem_ctx, sizeof(uint32) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privilege): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < r.count; i++) { - fstring name; - - rpcstr_pull_unistr2_fstring( name, &r.privs[i].name); - - (*privs_name)[i] = talloc_strdup(mem_ctx, name); - - (*privs_high)[i] = r.privs[i].luid_high; - (*privs_low)[i] = r.privs[i].luid_low; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Get privilege name */ - -NTSTATUS cli_lsa_get_dispname(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, char *name, uint16 lang_id, uint16 lang_id_sys, - fstring description, uint16 *lang_id_desc) -{ - prs_struct qbuf, rbuf; - LSA_Q_PRIV_GET_DISPNAME q; - LSA_R_PRIV_GET_DISPNAME r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_priv_get_dispname(&q, pol, name, lang_id, lang_id_sys); - - if (!lsa_io_q_priv_get_dispname("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_PRIV_GET_DISPNAME, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_priv_get_dispname("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - /* Return output parameters */ - - rpcstr_pull_unistr2_fstring(description , &r.desc); - *lang_id_desc = r.lang_id; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate list of SIDs */ - -NTSTATUS cli_lsa_enum_sids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *enum_ctx, uint32 pref_max_length, - uint32 *num_sids, DOM_SID **sids) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUM_ACCOUNTS q; - LSA_R_ENUM_ACCOUNTS r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_lsa_q_enum_accounts(&q, pol, *enum_ctx, pref_max_length); - - if (!lsa_io_q_enum_accounts("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUM_ACCOUNTS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_accounts("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.sids.num_entries==0) - goto done; - - /* Return output parameters */ - - *sids = (DOM_SID *)talloc(mem_ctx, sizeof(DOM_SID) * r.sids.num_entries); - if (!*sids) { - DEBUG(0, ("(cli_lsa_enum_sids): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Copy across names and sids */ - - for (i = 0; i < r.sids.num_entries; i++) { - sid_copy(&(*sids)[i], &r.sids.sid[i].sid); - } - - *num_sids= r.sids.num_entries; - *enum_ctx = r.enum_context; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Open a LSA user handle - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_open_account(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *dom_pol, DOM_SID *sid, uint32 des_access, - POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - LSA_Q_OPENACCOUNT q; - LSA_R_OPENACCOUNT r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_lsa_q_open_account(&q, dom_pol, sid, des_access); - - /* Marshall data and send request */ - - if (!lsa_io_q_open_account("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_OPENACCOUNT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_open_account("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *user_pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate user privileges - * - * @param cli Handle on an initialised SMB connection */ - -NTSTATUS cli_lsa_enum_privsaccount(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *count, LUID_ATTR **set) -{ - prs_struct qbuf, rbuf; - LSA_Q_ENUMPRIVSACCOUNT q; - LSA_R_ENUMPRIVSACCOUNT r; - NTSTATUS result; - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_lsa_q_enum_privsaccount(&q, pol); - - /* Marshall data and send request */ - - if (!lsa_io_q_enum_privsaccount("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, LSA_ENUMPRIVSACCOUNT, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!lsa_io_r_enum_privsaccount("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.count == 0) - goto done; - - if (!((*set = (LUID_ATTR *)talloc(mem_ctx, sizeof(LUID_ATTR) * r.count)))) { - DEBUG(0, ("(cli_lsa_enum_privsaccount): out of memory\n")); - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i=0; imem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_REQCHAL */ - - DEBUG(4,("new_cli_net_req_chal: LSA Request Challenge from %s to %s: %s\n", - global_myname, cli->desthost, credstr(clnt_chal->data))); - - /* store the parameters */ - init_q_req_chal(&q, cli->srv_name_slash, global_myname, clnt_chal); - - /* Marshall data and send request */ - - if (!net_io_q_req_chal("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_REQCHAL, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarhall response */ - - if (!net_io_r_req_chal("", &r, &rbuf, 0)) { - goto done; - } - - result = r.status; - - /* Return result */ - - if (NT_STATUS_IS_OK(result)) { - memcpy(srv_chal, r.srv_chal.data, sizeof(srv_chal->data)); - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/**************************************************************************** -LSA Authenticate 2 - -Send the client credential, receive back a server credential. -Ensure that the server credential returned matches the session key -encrypt of the server challenge originally received. JRA. -****************************************************************************/ - -NTSTATUS new_cli_net_auth2(struct cli_state *cli, - uint16 sec_chan, - uint32 neg_flags, DOM_CHAL *srv_chal) -{ - prs_struct qbuf, rbuf; - NET_Q_AUTH_2 q; - NET_R_AUTH_2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - extern pstring global_myname; - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); - prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_AUTH2 */ - - DEBUG(4,("new_cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", - cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, - credstr(cli->clnt_cred.challenge.data), neg_flags)); - - /* store the parameters */ - init_q_auth_2(&q, cli->srv_name_slash, cli->mach_acct, - sec_chan, global_myname, &cli->clnt_cred.challenge, - neg_flags); - - /* turn parameters into data stream */ - - if (!net_io_q_auth_2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_AUTH2, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_auth_2("", &r, &rbuf, 0)) { - goto done; - } - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - UTIME zerotime; - - /* - * Check the returned value using the initial - * server received challenge. - */ - - zerotime.time = 0; - if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, - zerotime) == 0) { - - /* - * Server replied with bad credential. Fail. - */ - DEBUG(0,("new_cli_net_auth2: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); - result = NT_STATUS_ACCESS_DENIED; - goto done; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Initialize domain session credentials */ - -NTSTATUS new_cli_nt_setup_creds(struct cli_state *cli, - uint16 sec_chan, - const unsigned char mach_pwd[16]) -{ - DOM_CHAL clnt_chal; - DOM_CHAL srv_chal; - UTIME zerotime; - NTSTATUS result; - - /******************* Request Challenge ********************/ - - generate_random_buffer(clnt_chal.data, 8, False); - - /* send a client challenge; receive a server challenge */ - result = new_cli_net_req_chal(cli, &clnt_chal, &srv_chal); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("new_cli_nt_setup_creds: request challenge failed\n")); - return result; - } - - /**************** Long-term Session key **************/ - - /* calculate the session key */ - cred_session_key(&clnt_chal, &srv_chal, mach_pwd, - cli->sess_key); - memset((char *)cli->sess_key+8, '\0', 8); - - /******************* Authenticate 2 ********************/ - - /* calculate auth-2 credentials */ - zerotime.time = 0; - cred_create(cli->sess_key, &clnt_chal, zerotime, - &cli->clnt_cred.challenge); - - /* - * Send client auth-2 challenge. - * Receive an auth-2 challenge response and check it. - */ - - result = new_cli_net_auth2(cli, sec_chan, 0x000001ff, - &srv_chal); - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", - nt_errstr(result))); - } - - return result; -} - -/* Logon Control 2 */ - -NTSTATUS cli_netlogon_logon_ctrl2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 query_level) -{ - prs_struct qbuf, rbuf; - NET_Q_LOGON_CTRL2 q; - NET_R_LOGON_CTRL2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_net_q_logon_ctrl2(&q, cli->srv_name_slash, query_level); - - /* Marshall data and send request */ - - if (!net_io_q_logon_ctrl2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_LOGON_CTRL2, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_logon_ctrl2("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/**************************************************************************** -Generate the next creds to use. Yuck - this is a cut&paste from another -file. They should be combined at some stage. )-: -****************************************************************************/ - -static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) -{ - /* - * Create the new client credentials. - */ - - cli->clnt_cred.timestamp.time = time(NULL); - - memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred)); - - /* Calculate the new credentials. */ - cred_create(cli->sess_key, &(cli->clnt_cred.challenge), - new_clnt_cred->timestamp, &(new_clnt_cred->challenge)); - -} - -/* Sam synchronisation */ - -NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds, - uint32 database_id, uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_SYNC q; - NET_R_SAM_SYNC r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2, - &clnt_creds, ret_creds, database_id); - - /* Marshall data and send request */ - - if (!net_io_q_sam_sync("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAM_SYNC, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_sam_sync("", cli->sess_key, &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - memcpy(ret_creds, &r.srv_creds, sizeof(*ret_creds)); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Sam synchronisation */ - -NTSTATUS cli_netlogon_sam_deltas(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 database_id, UINT64_S seqnum, - uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_DELTAS q; - NET_R_SAM_DELTAS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - init_net_q_sam_deltas(&q, cli->srv_name_slash, - cli->clnt_name_slash + 2, &clnt_creds, - database_id, seqnum); - - /* Marshall data and send request */ - - if (!net_io_q_sam_deltas("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAM_DELTAS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!net_io_r_sam_deltas("", cli->sess_key, &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Logon domain user */ - -NTSTATUS cli_netlogon_sam_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *username, char *password, - int logon_type) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds, dummy_rtn_creds; - extern pstring global_myname; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 user; - int validation_level = 3; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - q.validation_level = validation_level; - - memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); - dummy_rtn_creds.timestamp.time = time(NULL); - - ctr.switch_value = logon_type; - - switch (logon_type) { - case INTERACTIVE_LOGON_TYPE: { - unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; - - nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); - - init_id_info1(&ctr.auth.id1, lp_workgroup(), - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, cli->clnt_name_slash, - cli->sess_key, lm_owf_user_pwd, - nt_owf_user_pwd); - - break; - } - case NET_LOGON_TYPE: { - uint8 chal[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_response[24]; - - generate_random_buffer(chal, 8, False); - - SMBencrypt(password, chal, local_lm_response); - SMBNTencrypt(password, chal, local_nt_response); - - init_id_info2(&ctr.auth.id2, lp_workgroup(), - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, cli->clnt_name_slash, chal, - local_lm_response, 24, local_nt_response, 24); - break; - } - default: - DEBUG(0, ("switch value %d not supported\n", - ctr.switch_value)); - goto done; - } - - init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, - &clnt_creds, &dummy_rtn_creds, logon_type, - &ctr); - - /* Marshall data and send request */ - - if (!net_io_q_sam_logon("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.user = &user; - - if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { - goto done; - } - - /* Return results */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - - -/** - * Logon domain user with an 'network' SAM logon - * - * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller. - **/ - -NTSTATUS cli_netlogon_sam_network_logon(struct cli_state *cli, TALLOC_CTX *mem_ctx, - const char *username, const char *domain, const char *workstation, - const uint8 chal[8], - DATA_BLOB lm_response, DATA_BLOB nt_response, - NET_USER_INFO_3 *info3) - -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds, dummy_rtn_creds; - NET_ID_INFO_CTR ctr; - extern pstring global_myname; - int validation_level = 3; - char *workstation_name_slash; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - workstation_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", workstation); - - if (!workstation_name_slash) { - DEBUG(0, ("talloc_asprintf failed!\n")); - return NT_STATUS_NO_MEMORY; - } - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - gen_next_creds(cli, &clnt_creds); - - q.validation_level = validation_level; - - memset(&dummy_rtn_creds, '\0', sizeof(dummy_rtn_creds)); - dummy_rtn_creds.timestamp.time = time(NULL); - - ctr.switch_value = NET_LOGON_TYPE; - - init_id_info2(&ctr.auth.id2, domain, - 0, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, workstation_name_slash, (const uchar*)chal, - lm_response.data, lm_response.length, nt_response.data, nt_response.length); - - init_sam_info(&q.sam_id, cli->srv_name_slash, global_myname, - &clnt_creds, &dummy_rtn_creds, NET_LOGON_TYPE, - &ctr); - - /* Marshall data and send request */ - - if (!net_io_q_sam_logon("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, NET_SAMLOGON, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.user = info3; - - if (!net_io_r_sam_logon("", &r, &rbuf, 0)) { - goto done; - } - - /* Return results */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/*************************************************************************** -LSA Server Password Set. -****************************************************************************/ - -NTSTATUS cli_net_srv_pwset(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char* machine_name, uint8 hashed_mach_pwd[16]) -{ - prs_struct rbuf; - prs_struct qbuf; - DOM_CRED new_clnt_cred; - NET_Q_SRV_PWSET q_s; - uint16 sec_chan_type = 2; - NTSTATUS nt_status; - char *mach_acct; - - gen_next_creds( cli, &new_clnt_cred); - - prs_init(&qbuf , 1024, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* create and send a MSRPC command with api NET_SRV_PWSET */ - - mach_acct = talloc_asprintf(mem_ctx, "%s$", machine_name); - - if (!mach_acct) { - DEBUG(0,("talloc_asprintf failed!\n")); - nt_status = NT_STATUS_NO_MEMORY; - goto done; - } - - DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s clnt %s %x\n", - cli->srv_name_slash, mach_acct, sec_chan_type, machine_name, - credstr(new_clnt_cred.challenge.data), new_clnt_cred.timestamp.time)); - - /* store the parameters */ - init_q_srv_pwset(&q_s, cli->srv_name_slash, cli->sess_key, - mach_acct, sec_chan_type, machine_name, - &new_clnt_cred, (char *)hashed_mach_pwd); - - /* turn parameters into data stream */ - if(!net_io_q_srv_pwset("", &q_s, &qbuf, 0)) { - DEBUG(0,("cli_net_srv_pwset: Error : failed to marshall NET_Q_SRV_PWSET struct.\n")); - nt_status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* send the data on \PIPE\ */ - if (rpc_api_pipe_req(cli, NET_SRVPWSET, &qbuf, &rbuf)) - { - NET_R_SRV_PWSET r_s; - - if (!net_io_r_srv_pwset("", &r_s, &rbuf, 0)) { - nt_status = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - nt_status = r_s.status; - - if (!NT_STATUS_IS_OK(r_s.status)) - { - /* report error code */ - DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(nt_status))); - goto done; - } - - /* Update the credentials. */ - if (!clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &(r_s.srv_cred))) - { - /* - * Server replied with bad credential. Fail. - */ - DEBUG(0,("cli_net_srv_pwset: server %s replied with bad credential (bad machine \ -password ?).\n", cli->desthost )); - nt_status = NT_STATUS_UNSUCCESSFUL; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return nt_status; -} - diff --git a/source3/libsmb/cli_pipe_util.c b/source3/libsmb/cli_pipe_util.c deleted file mode 100644 index de1c832e44..0000000000 --- a/source3/libsmb/cli_pipe_util.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client utility functions - Copyright (C) Tim Potter 2001, - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** \defgroup rpc_client RPC Client routines - */ - -/* Opens a SMB connection to a named pipe */ - -struct cli_state *cli_pipe_initialise(struct cli_state *cli, char *system_name, - char *pipe_name, - struct ntuser_creds *creds) -{ - struct in_addr dest_ip; - struct nmb_name calling, called; - fstring dest_host; - extern pstring global_myname; - struct ntuser_creds anon; - - /* Initialise cli_state information */ - - if (!cli_initialise(cli)) { - return NULL; - } - - if (!creds) { - ZERO_STRUCT(anon); - anon.pwd.null_pwd = 1; - creds = &anon; - } - - cli_init_creds(cli, creds); - - /* Establish a SMB connection */ - - if (!resolve_srv_name(system_name, dest_host, &dest_ip)) { - return NULL; - } - - make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20); - make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0); - - if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling, - &called, "IPC$", "IPC", False, True)) { - return NULL; - } - - /* Open a NT session thingy */ - - if (!cli_nt_session_open(cli, pipe_name)) { - cli_shutdown(cli); - return NULL; - } - - return cli; -} - -/* Shut down a SMB connection to the SAMR pipe */ - -void cli_pipe_shutdown(struct cli_state *cli) -{ - if (cli->fd != -1) cli_ulogoff(cli); - cli_shutdown(cli); -} diff --git a/source3/libsmb/cli_reg.c b/source3/libsmb/cli_reg.c deleted file mode 100644 index aaf18882f7..0000000000 --- a/source3/libsmb/cli_reg.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC Pipe client - - Copyright (C) Andrew Tridgell 1992-1998, - Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - Copyright (C) Paul Ashton 1997-1998. - Copyright (C) Jeremy Allison 1999. - Copyright (C) Simo Sorce 2001 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Shutdown a server */ - -NTSTATUS cli_reg_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx, - const char *msg, uint32 timeout, uint16 flags) -{ - prs_struct qbuf; - prs_struct rbuf; - REG_Q_SHUTDOWN q_s; - REG_R_SHUTDOWN r_s; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - if (msg == NULL) return NT_STATUS_INVALID_PARAMETER; - - ZERO_STRUCT (q_s); - ZERO_STRUCT (r_s); - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_shutdown(&q_s, msg, timeout, flags); - - if (!reg_io_q_shutdown("", &q_s, &qbuf, 0) || - !rpc_api_pipe_req(cli, REG_SHUTDOWN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if(reg_io_r_shutdown("", &r_s, &rbuf, 0)) - result = r_s.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf); - - return result; -} - - -/* Abort a server shutdown */ - -NTSTATUS cli_reg_abort_shutdown(struct cli_state * cli, TALLOC_CTX *mem_ctx) -{ - prs_struct rbuf; - prs_struct qbuf; - REG_Q_ABORT_SHUTDOWN q_s; - REG_R_ABORT_SHUTDOWN r_s; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT (q_s); - ZERO_STRUCT (r_s); - - prs_init(&qbuf , MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_reg_q_abort_shutdown(&q_s); - - if (!reg_io_q_abort_shutdown("", &q_s, &qbuf, 0) || - !rpc_api_pipe_req(cli, REG_ABORT_SHUTDOWN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (reg_io_r_abort_shutdown("", &r_s, &rbuf, 0)) - result = r_s.status; - -done: - prs_mem_free(&rbuf); - prs_mem_free(&qbuf ); - - return result; -} diff --git a/source3/libsmb/cli_samr.c b/source3/libsmb/cli_samr.c deleted file mode 100644 index 91577b3325..0000000000 --- a/source3/libsmb/cli_samr.c +++ /dev/null @@ -1,1294 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - Copyright (C) Tim Potter 2000-2001, - Copyright (C) Andrew Tridgell 1992-1997,2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000, - Copyright (C) Paul Ashton 1997,2000, - Copyright (C) Elrond 2000. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* Connect to SAMR database */ - -NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 access_mask, POLICY_HND *connect_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CONNECT q; - SAMR_R_CONNECT r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_connect(&q, cli->desthost, access_mask); - - if (!samr_io_q_connect("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CONNECT, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_connect("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *connect_pol = r.connect_pol; -#ifdef __INSURE__ - connect_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Close SAMR handle */ - -NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CLOSE_HND q; - SAMR_R_CLOSE_HND r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_close_hnd(&q, connect_pol); - - if (!samr_io_q_close_hnd("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CLOSE_HND, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_close_hnd("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { -#ifdef __INSURE__ - SAFE_FREE(connect_pol->marker); -#endif - *connect_pol = r.pol; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a domain */ - -NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *connect_pol, uint32 access_mask, - const DOM_SID *domain_sid, POLICY_HND *domain_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_DOMAIN q; - SAMR_R_OPEN_DOMAIN r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid); - - if (!samr_io_q_open_domain("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_DOMAIN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_domain("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *domain_pol = r.domain_pol; -#ifdef __INSURE__ - domain_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a user */ - -NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 user_rid, POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_USER q; - SAMR_R_OPEN_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_user(&q, domain_pol, access_mask, user_rid); - - if (!samr_io_q_open_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_USER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_user("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *user_pol = r.user_pol; -#ifdef __INSURE__ - user_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on a group */ - -NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 group_rid, POLICY_HND *group_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_GROUP q; - SAMR_R_OPEN_GROUP r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_group(&q, domain_pol, access_mask, group_rid); - - if (!samr_io_q_open_group("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_GROUP, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_open_group("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *group_pol = r.pol; -#ifdef __INSURE__ - group_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user info */ - -NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - SAM_USERINFO_CTR **ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERINFO q; - SAMR_R_QUERY_USERINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_userinfo(&q, user_pol, switch_value); - - if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_userinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - *ctr = r.ctr; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query group info */ - -NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, uint32 info_level, - GROUP_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_GROUPINFO q; - SAMR_R_QUERY_GROUPINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_groupinfo(&q, group_pol, info_level); - - if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user groups */ - -NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint32 *num_groups, - DOM_GID **gid) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERGROUPS q; - SAMR_R_QUERY_USERGROUPS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_usergroups(&q, user_pol); - - if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_usergroups("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_groups = r.num_entries; - *gid = r.gid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user aliases */ - -NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint32 num_sids, DOM_SID2 *sid, - uint32 *num_aliases, uint32 **als_rids) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_USERALIASES q; - SAMR_R_QUERY_USERALIASES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - unsigned int ptr=1; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid); - - if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_useraliases("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_aliases = r.num_entries; - *als_rids = r.rid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user groups */ - -NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *group_pol, uint32 *num_mem, - uint32 **rid, uint32 **attr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_GROUPMEM q; - SAMR_R_QUERY_GROUPMEM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_groupmem(&q, group_pol); - - if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_query_groupmem("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *num_mem = r.num_entries; - *rid = r.rid; - *attr = r.attr; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enumerate domain groups */ - -NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, - uint32 size, struct acct_info **dom_groups, - uint32 *num_dom_groups) -{ - prs_struct qbuf, rbuf; - SAMR_Q_ENUM_DOM_GROUPS q; - SAMR_R_ENUM_DOM_GROUPS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 name_idx, i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_enum_dom_groups(&q, pol, *start_idx, size); - - if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) - goto done; - - *num_dom_groups = r.num_entries2; - - if (!((*dom_groups) = (struct acct_info *) - talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); - - name_idx = 0; - - for (i = 0; i < *num_dom_groups; i++) { - - (*dom_groups)[i].rid = r.sam[i].rid; - - if (r.sam[i].hdr_name.buffer) { - unistr2_to_ascii((*dom_groups)[i].acct_name, - &r.uni_grp_name[name_idx], - sizeof(fstring) - 1); - name_idx++; - } - - *start_idx = r.next_idx; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enumerate domain groups */ - -NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 *start_idx, - uint32 size, struct acct_info **dom_groups, - uint32 *num_dom_groups) -{ - prs_struct qbuf, rbuf; - SAMR_Q_ENUM_DOM_ALIASES q; - SAMR_R_ENUM_DOM_ALIASES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 name_idx, i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size); - - if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { - goto done; - } - - *num_dom_groups = r.num_entries2; - - if (!((*dom_groups) = (struct acct_info *) - talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - memset(*dom_groups, 0, sizeof(struct acct_info) * *num_dom_groups); - - name_idx = 0; - - for (i = 0; i < *num_dom_groups; i++) { - - (*dom_groups)[i].rid = r.sam[i].rid; - - if (r.sam[i].hdr_name.buffer) { - unistr2_to_ascii((*dom_groups)[i].acct_name, - &r.uni_grp_name[name_idx], - sizeof(fstring) - 1); - name_idx++; - } - - *start_idx = r.next_idx; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query alias members */ - -NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *alias_pol, uint32 *num_mem, - DOM_SID **sids) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_ALIASMEM q; - SAMR_R_QUERY_ALIASMEM r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_aliasmem(&q, alias_pol); - - if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - *num_mem = r.num_sids; - - if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - for (i = 0; i < *num_mem; i++) { - (*sids)[i] = r.sid[i].sid; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Open handle on an alias */ - -NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 access_mask, - uint32 alias_rid, POLICY_HND *alias_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_OPEN_ALIAS q; - SAMR_R_OPEN_ALIAS r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid); - - if (!samr_io_q_open_alias("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_open_alias("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Return output parameters */ - - if (NT_STATUS_IS_OK(result = r.status)) { - *alias_pol = r.pol; -#ifdef __INSURE__ - alias_pol->marker = malloc(1); -#endif - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query domain info */ - -NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint16 switch_value, - SAM_UNK_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_DOMAIN_INFO q; - SAMR_R_QUERY_DOMAIN_INFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_dom_info(&q, domain_pol, switch_value); - - if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query display info */ - -NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 *start_idx, - uint16 switch_value, uint32 *num_entries, - uint32 max_entries, SAM_DISPINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_DISPINFO q; - SAMR_R_QUERY_DISPINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_dispinfo(&q, domain_pol, switch_value, - *start_idx, max_entries); - - if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - if (!NT_STATUS_IS_OK(result) && - NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) { - goto done; - } - - *num_entries = r.num_entries; - *start_idx += r.num_entries; /* No next_idx in this structure! */ - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Lookup rids. Note that NT4 seems to crash if more than ~1000 rids are - looked up in one packet. */ - -NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 flags, - uint32 num_rids, uint32 *rids, - uint32 *num_names, char ***names, - uint32 **name_types) -{ - prs_struct qbuf, rbuf; - SAMR_Q_LOOKUP_RIDS q; - SAMR_R_LOOKUP_RIDS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - if (num_rids > 1000) { - DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if " - "more than ~1000 rids are looked up at once.\n")); - } - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags, - num_rids, rids); - - if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.num_names1 == 0) { - *num_names = 0; - *names = NULL; - goto done; - } - - *num_names = r.num_names1; - *names = talloc(mem_ctx, sizeof(char *) * r.num_names1); - *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1); - - for (i = 0; i < r.num_names1; i++) { - fstring tmp; - - unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1); - (*names)[i] = talloc_strdup(mem_ctx, tmp); - (*name_types)[i] = r.type[i]; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Lookup names */ - -NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, uint32 flags, - uint32 num_names, const char **names, - uint32 *num_rids, uint32 **rids, - uint32 **rid_types) -{ - prs_struct qbuf, rbuf; - SAMR_Q_LOOKUP_NAMES q; - SAMR_R_LOOKUP_NAMES r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - uint32 i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags, - num_names, names); - - if (!samr_io_q_lookup_names("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (r.num_rids1 == 0) { - *num_rids = 0; - goto done; - } - - *num_rids = r.num_rids1; - *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1); - *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1); - - for (i = 0; i < r.num_rids1; i++) { - (*rids)[i] = r.rids[i]; - (*rid_types)[i] = r.types[i]; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Create a domain user */ - -NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *domain_pol, const char *acct_name, - uint32 acb_info, uint32 unknown, - POLICY_HND *user_pol, uint32 *rid) -{ - prs_struct qbuf, rbuf; - SAMR_Q_CREATE_USER q; - SAMR_R_CREATE_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown); - - if (!samr_io_q_create_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_create_user("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - if (user_pol) - *user_pol = r.user_pol; - - if (rid) - *rid = r.user_rid; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set userinfo */ - -NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_SET_USERINFO q; - SAMR_R_SET_USERINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - q.ctr = ctr; - - init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, - ctr->info.id); - - if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set userinfo2 */ - -NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - uchar sess_key[16], SAM_USERINFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SAMR_Q_SET_USERINFO2 q; - SAMR_R_SET_USERINFO2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr); - - if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - if (!NT_STATUS_IS_OK(result = r.status)) { - goto done; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Delete domain user */ - -NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol) -{ - prs_struct qbuf, rbuf; - SAMR_Q_DELETE_DOM_USER q; - SAMR_R_DELETE_DOM_USER r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_delete_dom_user(&q, user_pol); - - if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Query user security object */ - -NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *user_pol, uint16 switch_value, - TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf) -{ - prs_struct qbuf, rbuf; - SAMR_Q_QUERY_SEC_OBJ q; - SAMR_R_QUERY_SEC_OBJ r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_query_sec_obj(&q, user_pol, switch_value); - - if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) { - goto done; - } - - /* Unmarshall response */ - - if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) { - goto done; - } - - /* Return output parameters */ - - result = r.status; - *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get domain password info */ - -NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint16 *unk_0, uint16 *unk_1, uint16 *unk_2) -{ - prs_struct qbuf, rbuf; - SAMR_Q_GET_DOM_PWINFO q; - SAMR_R_GET_DOM_PWINFO r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Marshall data and send request */ - - init_samr_q_get_dom_pwinfo(&q, cli->desthost); - - if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - if (unk_0) - *unk_0 = r.unk_0; - if (unk_1) - *unk_1 = r.unk_1; - if (unk_2) - *unk_2 = r.unk_2; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_spoolss.c b/source3/libsmb/cli_spoolss.c deleted file mode 100644 index 18e17758d6..0000000000 --- a/source3/libsmb/cli_spoolss.c +++ /dev/null @@ -1,2156 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - - Copyright (C) Gerald Carter 2001-2002, - Copyright (C) Tim Potter 2000-2002, - Copyright (C) Andrew Tridgell 1994-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean-Francois Micouleau 1999-2000. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** @defgroup spoolss SPOOLSS - NT printing routines - * @ingroup rpc_client - * - * @{ - **/ - -/********************************************************************** - Initialize a new spoolss buff for use by a client rpc -**********************************************************************/ -static void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx) -{ - buffer->ptr = (size != 0); - buffer->size = size; - buffer->string_at_end = size; - prs_init(&buffer->prs, size, ctx, MARSHALL); - buffer->struct_start = prs_offset(&buffer->prs); -} - -/********************************************************************* - Decode various spoolss rpc's and info levels - ********************************************************************/ - -/********************************************************************** -**********************************************************************/ -static void decode_printer_info_0(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 returned, PRINTER_INFO_0 **info) -{ - uint32 i; - PRINTER_INFO_0 *inf; - - inf=(PRINTER_INFO_0 *)talloc(mem_ctx, returned*sizeof(PRINTER_INFO_0)); - - buffer->prs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs, 0); - - for (i=0; iprs, 0); - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs.data_offset=0; - - for (i=0; iprs, 0); - - smb_io_driverdir_1("", buffer, inf, 0); - - *info=inf; -} - -/** Return a handle to the specified printer or print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param printername The name of the printer or print server to be - * opened in UNC format. - * - * @param datatype Specifies the default data type for the printer. - * - * @param access_required The access rights requested on the printer or - * print server. - * - * @param station The UNC name of the requesting workstation. - * - * @param username The name of the user requesting the open. - * - * @param pol Returned policy handle. - */ - -/********************************************************************************* - Win32 API - OpenPrinter() - ********************************************************************************/ - -WERROR cli_spoolss_open_printer_ex(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *printername, char *datatype, uint32 access_required, - char *station, char *username, POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_OPEN_PRINTER_EX q; - SPOOL_R_OPEN_PRINTER_EX r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_open_printer_ex(&q, printername, datatype, - access_required, station, username); - - /* Marshall data and send request */ - - if (!spoolss_io_q_open_printer_ex("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_OPENPRINTEREX, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_open_printer_ex("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *pol = r.handle; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Close a printer handle - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param pol Policy handle of printer or print server to close. - */ -/********************************************************************************* - Win32 API - ClosePrinter() - ********************************************************************************/ - -WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_CLOSEPRINTER q; - SPOOL_R_CLOSEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_closeprinter(&q, pol); - - /* Marshall data and send request */ - - if (!spoolss_io_q_closeprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_CLOSEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_closeprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *pol = r.handle; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Enumerate printers on a print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * - * @param flags Selected from PRINTER_ENUM_* flags. - * @param level Request information level. - * - * @param num_printers Pointer to number of printers returned. May be - * NULL. - * @param ctr Return structure for printer information. May - * be NULL. - */ -/********************************************************************************* - Win32 API - EnumPrinters() - ********************************************************************************/ - -WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 flags, uint32 level, - uint32 *num_printers, PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERS q; - SPOOL_R_ENUMPRINTERS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinters("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_enumprinters("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - if (num_printers) - *num_printers = r.returned; - - if (!ctr) - goto done; - - switch (level) { - case 0: - decode_printer_info_0(mem_ctx, r.buffer, r.returned, - &ctr->printers_0); - break; - case 1: - decode_printer_info_1(mem_ctx, r.buffer, r.returned, - &ctr->printers_1); - break; - case 2: - decode_printer_info_2(mem_ctx, r.buffer, r.returned, - &ctr->printers_2); - break; - case 3: - decode_printer_info_3(mem_ctx, r.buffer, r.returned, - &ctr->printers_3); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - EnumPorts() - ********************************************************************************/ -/** Enumerate printer ports on a print server. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * May be NULL. - * - * @param level Requested information level. - * - * @param num_ports Pointer to number of ports returned. May be NULL. - * @param ctr Pointer to structure holding port information. - * May be NULL. - */ - -WERROR cli_spoolss_enum_ports(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, int *num_ports, PORT_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPORTS q; - SPOOL_R_ENUMPORTS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_enumports(&q, server, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumports("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPORTS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_enumports("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(result)) - goto done; - - if (num_ports) - *num_ports = r.returned; - - if (!ctr) - goto done; - - switch (level) { - case 1: - decode_port_info_1(mem_ctx, r.buffer, r.returned, - &ctr->port.info_1); - break; - case 2: - decode_port_info_2(mem_ctx, r.buffer, r.returned, - &ctr->port.info_2); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinter() - ********************************************************************************/ - -WERROR cli_spoolss_getprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTER q; - SPOOL_R_GETPRINTER r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_getprinter(mem_ctx, &q, pol, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprinter("", &r, &rbuf, 0)) - goto done; - - if (needed) - *needed = r.needed; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) { - switch (level) { - case 0: - decode_printer_info_0(mem_ctx, r.buffer, 1, &ctr->printers_0); - break; - case 1: - decode_printer_info_1(mem_ctx, r.buffer, 1, &ctr->printers_1); - break; - case 2: - decode_printer_info_2(mem_ctx, r.buffer, 1, &ctr->printers_2); - break; - case 3: - decode_printer_info_3(mem_ctx, r.buffer, 1, &ctr->printers_3); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - SetPrinter() - ********************************************************************************/ -/** Set printer info - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param pol Policy handle on printer to set info. - * @param level Information level to set. - * @param ctr Pointer to structure holding printer information. - * @param command Specifies the action performed. See - * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/prntspol_13ua.asp - * for details. - * - */ - -WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 level, - PRINTER_INFO_CTR *ctr, uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTER q; - SPOOL_R_SETPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setprinter("", &r, &rbuf, 0)) - goto done; - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinterDriver() - ********************************************************************************/ -/** Get installed printer drivers for a given printer - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * - * @param pol Pointer to an open policy handle for the printer - * opened with cli_spoolss_open_printer_ex(). - * @param level Requested information level. - * @param env The print environment or archictecture. This is - * "Windows NT x86" for NT4. - * @param ctr Returned printer driver information. - */ - -WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *pol, uint32 level, - char *env, PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDRIVER2 q; - SPOOL_R_GETPRINTERDRIVER2 r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - fstrcpy (server, cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_getprinterdriver2(&q, pol, env, level, 2, 2, - &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdriver2 ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVER2, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_getprinterdriver2 ("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - result = r.status; - - /* Return output parameters */ - - if (!W_ERROR_IS_OK(result)) - goto done; - - if (!ctr) - goto done; - - switch (level) { - case 1: - decode_printer_driver_1(mem_ctx, r.buffer, 1, &ctr->info1); - break; - case 2: - decode_printer_driver_2(mem_ctx, r.buffer, 1, &ctr->info2); - break; - case 3: - decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - EnumPrinterDrivers() - ********************************************************************************/ -/********************************************************************** - * Get installed printer drivers for a given printer - */ -WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, char *env, - uint32 *num_drivers, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDRIVERS q; - SPOOL_R_ENUMPRINTERDRIVERS r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_enumprinterdrivers(&q, server, env, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinterdrivers ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ENUMPRINTERDRIVERS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumprinterdrivers ("", &r, &rbuf, 0)) - goto done; - - if (needed) - *needed = r.needed; - - if (num_drivers) - *num_drivers = r.returned; - - result = r.status; - - /* Return output parameters */ - - if (W_ERROR_IS_OK(result) && (r.returned != 0)) { - *num_drivers = r.returned; - - switch (level) { - case 1: - decode_printer_driver_1(mem_ctx, r.buffer, r.returned, &ctr->info1); - break; - case 2: - decode_printer_driver_2(mem_ctx, r.buffer, r.returned, &ctr->info2); - break; - case 3: - decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - - -/********************************************************************************* - Win32 API - GetPrinterDriverDirectory() - ********************************************************************************/ -/********************************************************************** - * Get installed printer drivers for a given printer - */ -WERROR cli_spoolss_getprinterdriverdir (struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - uint32 level, char *env, - DRIVER_DIRECTORY_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDRIVERDIR q; - SPOOL_R_GETPRINTERDRIVERDIR r; - NEW_BUFFER buffer; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_getprinterdriverdir(&q, server, env, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdriverdir ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_GETPRINTERDRIVERDIRECTORY, - &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (spoolss_io_r_getprinterdriverdir ("", &r, &rbuf, 0)) { - if (needed) - *needed = r.needed; - } - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) { - switch (level) { - case 1: - decode_printerdriverdir_1(mem_ctx, r.buffer, 1, - &ctr->info1); - break; - } - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - AddPrinterDriver() - ********************************************************************************/ -/********************************************************************** - * Install a printer driver - */ -WERROR cli_spoolss_addprinterdriver (struct cli_state *cli, - TALLOC_CTX *mem_ctx, uint32 level, - PRINTER_DRIVER_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTERDRIVER q; - SPOOL_R_ADDPRINTERDRIVER r; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_addprinterdriver (mem_ctx, &q, server, level, ctr); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTERDRIVER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addprinterdriver ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - AddPrinter() - ********************************************************************************/ -/********************************************************************** - * Install a printer - */ -WERROR cli_spoolss_addprinterex (struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 level, PRINTER_INFO_CTR*ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDPRINTEREX q; - SPOOL_R_ADDPRINTEREX r; - WERROR result = W_ERROR(ERRgeneral); - fstring server, - client, - user; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - slprintf (client, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (client); - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - fstrcpy (user, cli->user_name); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Write the request */ - - make_spoolss_q_addprinterex (mem_ctx, &q, server, client, user, - level, ctr); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addprinterex ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ADDPRINTEREX, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addprinterex ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - DeltePrinterDriver() - ********************************************************************************/ -/********************************************************************** - * Delete a Printer Driver from the server (does not remove - * the driver files - */ -WERROR cli_spoolss_deleteprinterdriver (struct cli_state *cli, - TALLOC_CTX *mem_ctx, char *arch, - char *driver) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEPRINTERDRIVER q; - SPOOL_R_DELETEPRINTERDRIVER r; - WERROR result = W_ERROR(ERRgeneral); - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - - /* Initialise input parameters */ - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - - /* Write the request */ - - make_spoolss_q_deleteprinterdriver(mem_ctx, &q, server, arch, driver); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteprinterdriver ("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli,SPOOLSS_DELETEPRINTERDRIVER , &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteprinterdriver ("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************************* - Win32 API - GetPrinterProcessorDirectory() - ********************************************************************************/ - -WERROR cli_spoolss_getprintprocessordirectory(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - char *name, char *environment, - fstring procdir) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTPROCESSORDIRECTORY q; - SPOOL_R_GETPRINTPROCESSORDIRECTORY r; - int level = 1; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_buffer(&buffer, offered, mem_ctx); - - make_spoolss_q_getprintprocessordirectory( - &q, name, environment, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprintprocessordirectory("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTPROCESSORDIRECTORY, - &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprintprocessordirectory("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (W_ERROR_IS_OK(result)) - fstrcpy(procdir, "Not implemented!"); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Add a form to a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param level Form info level to add - should always be 1. - * @param form A pointer to the form to be added. - * - */ - -WERROR cli_spoolss_addform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, uint32 level, FORM *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ADDFORM q; - SPOOL_R_ADDFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_addform(&q, handle, level, form); - - /* Marshall data and send request */ - - if (!spoolss_io_q_addform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ADDFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_addform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Set a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param level Form info level to set - should always be 1. - * @param form A pointer to the form to be set. - * - */ - -WERROR cli_spoolss_setform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, uint32 level, char *form_name, - FORM *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETFORM q; - SPOOL_R_SETFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setform(&q, handle, level, form_name, form); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Get a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param formname Name of the form to get - * @param level Form info level to get - should always be 1. - * - */ - -WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *handle, char *formname, uint32 level, - FORM_1 *form) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETFORM q; - SPOOL_R_GETFORM r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getform(&q, handle, formname, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (W_ERROR_IS_OK(result)) - smb_io_form_1("", r.buffer, form, 0); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** Delete a form on a printer. - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param handle Policy handle opened with cli_spoolss_open_printer_ex - * or cli_spoolss_addprinterex. - * @param form The name of the form to delete. - * - */ - -WERROR cli_spoolss_deleteform(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle, char *form_name) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEFORM q; - SPOOL_R_DELETEFORM r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_deleteform(&q, handle, form_name); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteform("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_DELETEFORM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteform("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -static void decode_forms_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_forms, FORM_1 **forms) -{ - int i; - - *forms = (FORM_1 *)talloc(mem_ctx, num_forms * sizeof(FORM_1)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_forms; i++) - smb_io_form_1("", buffer, &((*forms)[i]), 0); -} - -/** Enumerate forms - * - * @param cli Pointer to client state structure which is open - * on the SPOOLSS pipe. - * @param mem_ctx Pointer to an initialised talloc context. - * - * @param offered Buffer size offered in the request. - * @param needed Number of bytes needed to complete the request. - * may be NULL. - * or cli_spoolss_addprinterex. - * @param level Form info level to get - should always be 1. - * @param handle Open policy handle - * - */ - -WERROR cli_spoolss_enumforms(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *handle, int level, uint32 *num_forms, - FORM_1 **forms) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMFORMS q; - SPOOL_R_ENUMFORMS r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumforms(&q, handle, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumforms("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMFORMS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumforms("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (num_forms) - *num_forms = r.numofforms; - - decode_forms_1(mem_ctx, r.buffer, *num_forms, forms); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -static void decode_jobs_1(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_1 **jobs) -{ - uint32 i; - - *jobs = (JOB_INFO_1 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_1)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_jobs; i++) - smb_io_job_info_1("", buffer, &((*jobs)[i]), 0); -} - -static void decode_jobs_2(TALLOC_CTX *mem_ctx, NEW_BUFFER *buffer, - uint32 num_jobs, JOB_INFO_2 **jobs) -{ - uint32 i; - - *jobs = (JOB_INFO_2 *)talloc(mem_ctx, num_jobs * sizeof(JOB_INFO_2)); - buffer->prs.data_offset = 0; - - for (i = 0; i < num_jobs; i++) - smb_io_job_info_2("", buffer, &((*jobs)[i]), 0); -} - -/* Enumerate jobs */ - -WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 level, uint32 firstjob, - uint32 num_jobs, uint32 *returned, JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMJOBS q; - SPOOL_R_ENUMJOBS r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumjobs(&q, hnd, firstjob, num_jobs, level, &buffer, - offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumjobs("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMJOBS, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumjobs("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - *returned = r.returned; - - switch(level) { - case 1: - decode_jobs_1(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_1); - break; - case 2: - decode_jobs_2(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_2); - break; - default: - DEBUG(3, ("unsupported info level %d", level)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set job */ - -WERROR cli_spoolss_setjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 jobid, uint32 level, - uint32 command) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETJOB q; - SPOOL_R_SETJOB r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setjob(&q, hnd, jobid, level, command); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setjob("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETJOB, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setjob("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get job */ - -WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, uint32 jobid, uint32 level, - JOB_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETJOB q; - SPOOL_R_GETJOB r; - WERROR result = W_ERROR(ERRgeneral); - NEW_BUFFER buffer; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - init_buffer(&buffer, offered, mem_ctx); - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getjob(&q, hnd, jobid, level, &buffer, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getjob("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETJOB, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getjob("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - switch(level) { - case 1: - decode_jobs_1(mem_ctx, r.buffer, 1, ctr->job.job_info_1); - break; - case 2: - decode_jobs_2(mem_ctx, r.buffer, 1, ctr->job.job_info_2); - break; - default: - DEBUG(3, ("unsupported info level %d", level)); - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Startpageprinter. Sent to notify the spooler when a page is about to be - sent to a printer. */ - -WERROR cli_spoolss_startpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_STARTPAGEPRINTER q; - SPOOL_R_STARTPAGEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_startpageprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_startpageprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_STARTPAGEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_startpageprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Endpageprinter. Sent to notify the spooler when a page has finished - being sent to a printer. */ - -WERROR cli_spoolss_endpageprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENDPAGEPRINTER q; - SPOOL_R_ENDPAGEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_endpageprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_endpageprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENDPAGEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_endpageprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Startdocprinter. Sent to notify the spooler that a document is about - to be spooled for printing. */ - -WERROR cli_spoolss_startdocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *docname, - char *outputfile, char *datatype, - uint32 *jobid) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_STARTDOCPRINTER q; - SPOOL_R_STARTDOCPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - uint32 level = 1; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_startdocprinter(&q, hnd, level, docname, outputfile, - datatype); - - /* Marshall data and send request */ - - if (!spoolss_io_q_startdocprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_STARTDOCPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_startdocprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - if (W_ERROR_IS_OK(result)) - *jobid = r.jobid; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enddocprinter. Sent to notify the spooler that a document has finished - being spooled. */ - -WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENDDOCPRINTER q; - SPOOL_R_ENDDOCPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enddocprinter(&q, hnd); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enddocprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENDDOCPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enddocprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Get printer data */ - -WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 offered, uint32 *needed, - POLICY_HND *hnd, char *valuename, - uint32 *data_type, char **data, - uint32 *data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_GETPRINTERDATA q; - SPOOL_R_GETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_getprinterdata(&q, hnd, valuename, offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_getprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_getprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (needed) - *needed = r.needed; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - /* Return output parameters */ - - if (data_type) - *data_type = r.type; - - if (data) { - *data = (char *)talloc(mem_ctx, r.needed); - memcpy(*data, r.data, r.needed); - } - - if (data_size) - *data_size = r.needed; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Set printer data */ - -WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *value, - uint32 data_type, char *data, - uint32 data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_SETPRINTERDATA q; - SPOOL_R_SETPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size); - - /* Marshall data and send request */ - - if (!spoolss_io_q_setprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_setprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Enum printer data */ - -WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 ndx, - uint32 value_offered, uint32 data_offered, - uint32 *value_needed, uint32 *data_needed, - char **value, uint32 *data_type, char **data, - uint32 *data_size) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ENUMPRINTERDATA q; - SPOOL_R_ENUMPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_enumprinterdata(&q, hnd, ndx, value_offered, data_offered); - - /* Marshall data and send request */ - - if (!spoolss_io_q_enumprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_enumprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - /* Return data */ - - if (value_needed) - *value_needed = r.realvaluesize; - - if (data_needed) - *data_needed = r.realdatasize; - - if (data_type) - *data_type = r.type; - - if (value) { - fstring the_value; - - rpcstr_pull(the_value, r.value, sizeof(the_value), -1, - STR_TERMINATE); - - *value = talloc_strdup(mem_ctx, the_value); - } - - if (data) - *data = talloc_memdup(mem_ctx, r.data, r.realdatasize); - - if (data_size) - *data_size = r.realdatasize; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Write data to printer */ - -WERROR cli_spoolss_writeprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, uint32 data_size, char *data, - uint32 *num_written) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_WRITEPRINTER q; - SPOOL_R_WRITEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_writeprinter(&q, hnd, data_size, data); - - /* Marshall data and send request */ - - if (!spoolss_io_q_writeprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_WRITEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_writeprinter("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - if (num_written) - *num_written = r.buffer_written; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Delete printer data */ - -WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *valuename) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_DELETEPRINTERDATA q; - SPOOL_R_DELETEPRINTERDATA r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - make_spoolss_q_deleteprinterdata(&q, hnd, valuename); - - /* Marshall data and send request */ - - if (!spoolss_io_q_deleteprinterdata("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATA, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_deleteprinterdata("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(r.status)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/** @} **/ diff --git a/source3/libsmb/cli_spoolss_notify.c b/source3/libsmb/cli_spoolss_notify.c deleted file mode 100644 index 922b0fbb1d..0000000000 --- a/source3/libsmb/cli_spoolss_notify.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - Unix SMB/CIFS implementation. - RPC pipe client - - Copyright (C) Gerald Carter 2001-2002, - Copyright (C) Tim Potter 2000-2002, - Copyright (C) Andrew Tridgell 1994-2000, - Copyright (C) Luke Kenneth Casson Leighton 1996-2000, - Copyright (C) Jean-Francois Micouleau 1999-2000. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/* - * SPOOLSS Client RPC's used by servers as the notification - * back channel. - */ - -/* Send a ReplyOpenPrinter request. This rpc is made by the printer - server to the printer client in response to a rffpcnex request. - The rrfpcnex request names a printer and a handle (the printerlocal - value) and this rpc establishes a back-channel over which printer - notifications are performed. */ - -WERROR cli_spoolss_reply_open_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *printer, uint32 printerlocal, uint32 type, - POLICY_HND *handle) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLYOPENPRINTER q; - SPOOL_R_REPLYOPENPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_replyopenprinter(&q, printer, printerlocal, type); - - /* Marshall data and send request */ - - if (!spoolss_io_q_replyopenprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_REPLYOPENPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_replyopenprinter("", &r, &rbuf, 0)) - goto done; - - /* Return result */ - - memcpy(handle, &r.handle, sizeof(r.handle)); - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/* Close a back-channel notification connection */ - -WERROR cli_spoolss_reply_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *handle) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLYCLOSEPRINTER q; - SPOOL_R_REPLYCLOSEPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_reply_closeprinter(&q, handle); - - /* Marshall data and send request */ - - if (!spoolss_io_q_replycloseprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_REPLYCLOSEPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_replycloseprinter("", &r, &rbuf, 0)) - goto done; - - /* Return result */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************* - This SPOOLSS_ROUTERREPLYPRINTER function is used to send a change - notification event when the registration **did not** use - SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor. - Also see cli_spolss_reply_rrpcn() - *********************************************************************/ - -WERROR cli_spoolss_routerreplyprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 condition, uint32 change_id) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_ROUTERREPLYPRINTER q; - SPOOL_R_ROUTERREPLYPRINTER r; - WERROR result = W_ERROR(ERRgeneral); - - /* Initialise input parameters */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - make_spoolss_q_routerreplyprinter(&q, pol, condition, change_id); - - /* Marshall data and send request */ - - if (!spoolss_io_q_routerreplyprinter("", &q, &qbuf, 0) || - !rpc_api_pipe_req (cli, SPOOLSS_ROUTERREPLYPRINTER, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!spoolss_io_r_routerreplyprinter("", &r, &rbuf, 0)) - goto done; - - /* Return output parameters */ - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -/********************************************************************* - This SPOOLSS_REPLY_RRPCN function is used to send a change - notification event when the registration **did** use - SPOOL_NOTIFY_OPTION_TYPE structure to specify the events to monitor - Also see cli_spoolss_routereplyprinter() - *********************************************************************/ - -WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *pol, uint32 notify_data_len, - SPOOL_NOTIFY_INFO_DATA *notify_data, - uint32 change_low, uint32 change_high) -{ - prs_struct qbuf, rbuf; - SPOOL_Q_REPLY_RRPCN q; - SPOOL_R_REPLY_RRPCN r; - WERROR result = W_ERROR(ERRgeneral); - SPOOL_NOTIFY_INFO notify_info; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - ZERO_STRUCT(notify_info); - - /* Initialise input parameters */ - - notify_info.version = 0x2; - notify_info.flags = 0x00020000; /* ?? */ - notify_info.count = notify_data_len; - notify_info.data = notify_data; - - /* create and send a MSRPC command with api */ - /* store the parameters */ - - make_spoolss_q_reply_rrpcn(&q, pol, change_low, change_high, - ¬ify_info); - - /* Marshall data and send request */ - - if(!spoolss_io_q_reply_rrpcn("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SPOOLSS_RRPCN, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if(!spoolss_io_r_reply_rrpcn("", &r, &rbuf, 0)) - goto done; - - if (r.unknown0 == 0x00080000) - DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n")); - - result = r.status; - -done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} diff --git a/source3/libsmb/cli_srvsvc.c b/source3/libsmb/cli_srvsvc.c deleted file mode 100644 index 2dc12d726c..0000000000 --- a/source3/libsmb/cli_srvsvc.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Tim Potter 2001 - Copyright (C) Jim McDonough 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -NTSTATUS cli_srvsvc_net_srv_get_info(struct cli_state *cli, - TALLOC_CTX *mem_ctx, - uint32 switch_value, SRV_INFO_CTR *ctr) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SRV_GET_INFO q; - SRV_R_NET_SRV_GET_INFO r; - NTSTATUS result; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_srv_get_info(&q, cli->srv_name_slash, switch_value); - - /* Marshall data and send request */ - - if (!srv_io_q_net_srv_get_info("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SRV_GET_INFO, &qbuf, &rbuf)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - /* Unmarshall response */ - - r.ctr = ctr; - - if (!srv_io_r_net_srv_get_info("", &r, &rbuf, 0)) { - result = NT_STATUS_UNSUCCESSFUL; - goto done; - } - - result = werror_to_ntstatus(r.status); - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 info_level, SRV_SHARE_INFO_CTR *ctr, - int preferred_len, ENUM_HND *hnd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_ENUM q; - SRV_R_NET_SHARE_ENUM r; - WERROR result = W_ERROR(ERRgeneral); - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_share_enum( - &q, cli->srv_name_slash, info_level, preferred_len, hnd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_ENUM_ALL, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_enum("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - /* Oh yuck yuck yuck - we have to copy all the info out of the - SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a - prs_mem_free() it will all be invalidated. The various share - info structures suck badly too. This really is gross. */ - - ZERO_STRUCTP(ctr); - - ctr->info_level = info_level; - ctr->num_entries = r.ctr.num_entries; - - switch(info_level) { - case 1: - ctr->share.info1 = (SRV_SHARE_INFO_1 *)talloc( - mem_ctx, sizeof(SRV_SHARE_INFO_1) * ctr->num_entries); - - memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1)); - - for (i = 0; i < ctr->num_entries; i++) { - SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, - sizeof(SH_INFO_1)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname); - if (s) - init_unistr2(&info1->info_1_str.uni_netname, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark); - if (s) - init_unistr2(&info1->info_1_str.uni_remark, s, strlen(s) + 1); - - } - - break; - case 2: - ctr->share.info2 = (SRV_SHARE_INFO_2 *)talloc( - mem_ctx, sizeof(SRV_SHARE_INFO_2) * ctr->num_entries); - - memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2)); - - for (i = 0; i < ctr->num_entries; i++) { - SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, - sizeof(SH_INFO_2)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname); - if (s) - init_unistr2(&info2->info_2_str.uni_netname, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark); - if (s) - init_unistr2(&info2->info_2_str.uni_remark, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path); - if (s) - init_unistr2(&info2->info_2_str.uni_path, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd); - if (s) - init_unistr2(&info2->info_2_str.uni_passwd, s, strlen(s) + 1); - } - break; - } - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_del(struct cli_state *cli, TALLOC_CTX *mem_ctx, - const char *sharename) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_DEL q; - SRV_R_NET_SHARE_DEL r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_share_del(&q, cli->srv_name_slash, sharename); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_del("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_DEL, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_del("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_share_add(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *netname, uint32 type, char *remark, - uint32 perms, uint32 max_uses, uint32 num_uses, - char *path, char *passwd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_SHARE_ADD q; - SRV_R_NET_SHARE_ADD r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - init_srv_q_net_share_add(&q,cli->srv_name_slash, netname, type, remark, - perms, max_uses, num_uses, path, passwd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_share_add("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_SHARE_ADD, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_share_add("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_remote_tod(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *server, TIME_OF_DAY_INFO *tod) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_REMOTE_TOD q; - SRV_R_NET_REMOTE_TOD r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_remote_tod(&q, cli->srv_name_slash); - - /* Marshall data and send request */ - - if (!srv_io_q_net_remote_tod("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_REMOTE_TOD, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - r.tod = tod; - - if (!srv_io_r_net_remote_tod("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_file_enum(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_level, char *user_name, - SRV_FILE_INFO_CTR *ctr, int preferred_len, - ENUM_HND *hnd) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_FILE_ENUM q; - SRV_R_NET_FILE_ENUM r; - WERROR result = W_ERROR(ERRgeneral); - int i; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_file_enum(&q, cli->srv_name_slash, NULL, user_name, - file_level, ctr, preferred_len, hnd); - - /* Marshall data and send request */ - - if (!srv_io_q_net_file_enum("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_FILE_ENUM, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_file_enum("", &r, &rbuf, 0)) - goto done; - - result = r.status; - - if (!W_ERROR_IS_OK(result)) - goto done; - - /* copy the data over to the ctr */ - - ZERO_STRUCTP(ctr); - - ctr->switch_value = file_level; - - ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries; - - switch(file_level) { - case 3: - ctr->file.info3 = (SRV_FILE_INFO_3 *)talloc( - mem_ctx, sizeof(SRV_FILE_INFO_3) * ctr->num_entries); - - memset(ctr->file.info3, 0, - sizeof(SRV_FILE_INFO_3) * ctr->num_entries); - - for (i = 0; i < r.ctr.num_entries; i++) { - SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i]; - char *s; - - /* Copy pointer crap */ - - memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, - sizeof(FILE_INFO_3)); - - /* Duplicate strings */ - - s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name); - if (s) - init_unistr2(&info3->info_3_str.uni_path_name, s, strlen(s) + 1); - - s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name); - if (s) - init_unistr2(&info3->info_3_str.uni_user_name, s, strlen(s) + 1); - - } - - break; - } - - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - - return result; -} - -WERROR cli_srvsvc_net_file_close(struct cli_state *cli, TALLOC_CTX *mem_ctx, - uint32 file_id) -{ - prs_struct qbuf, rbuf; - SRV_Q_NET_FILE_CLOSE q; - SRV_R_NET_FILE_CLOSE r; - WERROR result = W_ERROR(ERRgeneral); - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise parse structures */ - - prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - /* Initialise input parameters */ - - init_srv_q_net_file_close(&q, cli->srv_name_slash, file_id); - - /* Marshall data and send request */ - - if (!srv_io_q_net_file_close("", &q, &qbuf, 0) || - !rpc_api_pipe_req(cli, SRV_NET_FILE_CLOSE, &qbuf, &rbuf)) - goto done; - - /* Unmarshall response */ - - if (!srv_io_r_net_file_close("", &r, &rbuf, 0)) - goto done; - - result = r.status; - done: - prs_mem_free(&qbuf); - prs_mem_free(&rbuf); - return result; -} diff --git a/source3/libsmb/cli_wkssvc.c b/source3/libsmb/cli_wkssvc.c deleted file mode 100644 index 97b948bf62..0000000000 --- a/source3/libsmb/cli_wkssvc.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - Unix SMB/CIFS implementation. - NT Domain Authentication SMB / MSRPC client - Copyright (C) Andrew Tridgell 1994-2000 - Copyright (C) Luke Kenneth Casson Leighton 1996-2000 - Copyright (C) Tim Potter 2001 - Copytight (C) Rafal Szczesniak 2002 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -/** - * WksQueryInfo rpc call (like query for server's capabilities) - * - * @param initialised client structure with \PIPE\wkssvc opened - * @param mem_ctx memory context assigned to this rpc binding - * @param wks100 WksQueryInfo structure - * - * @return NTSTATUS of rpc call - */ - -NTSTATUS cli_wks_query_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, - WKS_INFO_100 *wks100) -{ - prs_struct buf; - prs_struct rbuf; - WKS_Q_QUERY_INFO q_o; - WKS_R_QUERY_INFO r_o; - - if (cli == NULL || wks100 == NULL) - return NT_STATUS_UNSUCCESSFUL; - - /* init rpc parse structures */ - prs_init(&buf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - - DEBUG(4, ("WksQueryInfo\n")); - - /* init query structure with rpc call arguments */ - init_wks_q_query_info(&q_o, cli->desthost, 100); - - /* marshall data */ - if (!wks_io_q_query_info("", &q_o, &buf, 0)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - /* actual rpc call over \PIPE\wkssvc */ - if (!rpc_api_pipe_req(cli, WKS_QUERY_INFO, &buf, &rbuf)) { - prs_mem_free(&buf); - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - prs_mem_free(&buf); - - r_o.wks100 = wks100; - - /* get call results from response buffer */ - if (!wks_io_r_query_info("", &r_o, &rbuf, 0)) { - prs_mem_free(&rbuf); - return NT_STATUS_UNSUCCESSFUL; - } - - /* check returnet status code */ - if (NT_STATUS_IS_ERR(r_o.status)) { - /* report the error */ - DEBUG(0,("WKS_R_QUERY_INFO: %s\n", nt_errstr(r_o.status))); - prs_mem_free(&rbuf); - return r_o.status; - } - - /* do clean up */ - prs_mem_free(&rbuf); - - return NT_STATUS_OK; -} - -- cgit From 208b4be14b3b6ad7d76cae98c7bdd42c8af4f698 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 27 Sep 2002 16:51:22 +0000 Subject: Touching somebody else's code again... Sorry, Richard. smbclient would announce that it can send UNICODE, but would send the plain text password in ASCII. This confused Samba HEAD somewhat. This change has been tested against Samba HEAD of today and Samba 2.2.1a. I do not have any other servers that do plain text passwords. Anybody? Volker (This used to be commit c7de62d839634a85295d1a0ef5a48270ef30aa93) --- source3/libsmb/cliconnect.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 62acccdfb7..ebadafd5f0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -188,7 +188,14 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, int passlen; char *p; - passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII); + int push_flags = STR_TERMINATE; + + if (capabilities & CAP_UNICODE) + push_flags |= STR_UNICODE; + else + push_flags |= STR_ASCII; + + passlen = clistr_push(cli, pword, pass, sizeof(pword), push_flags); set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); @@ -202,7 +209,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, SSVAL(cli->outbuf,smb_vwv8,0); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, pword, -1, STR_TERMINATE); /* password */ + p += clistr_push(cli, p, pass, -1, push_flags); /* password */ SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ -- cgit From 9e0bd9be01a6337d75d54382b56dfe6a88bda47b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Sep 2002 12:14:17 +0000 Subject: Thanks to abartlet I looked at that function a bit closer. What did the first cli_push_string do? I suspect that it's a leftover from times when the password length was needed at some point. Volker (This used to be commit df906c156aea46524dedc28ee54f4e87711c7160) --- source3/libsmb/cliconnect.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ebadafd5f0..695c6506b5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -184,10 +184,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, char *pass, char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); - fstring pword; - int passlen; char *p; - int push_flags = STR_TERMINATE; if (capabilities & CAP_UNICODE) @@ -195,8 +192,6 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, else push_flags |= STR_ASCII; - passlen = clistr_push(cli, pword, pass, sizeof(pword), push_flags); - set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); -- cgit From ca772ac1f41cbcb620e534b8d2c916e0e3f16808 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Sep 2002 15:01:58 +0000 Subject: Ok, hopefully final fix for this one. abartlet told a bit about the history. Volker (This used to be commit d47aff38db23815a48e64718ecb6c957101ecdac) --- source3/libsmb/cliconnect.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 695c6506b5..3951e3c776 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -185,12 +185,6 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; - int push_flags = STR_TERMINATE; - - if (capabilities & CAP_UNICODE) - push_flags |= STR_UNICODE; - else - push_flags |= STR_ASCII; set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); @@ -204,7 +198,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, SSVAL(cli->outbuf,smb_vwv8,0); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, pass, -1, push_flags); /* password */ + p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ -- cgit From 6af2433ce6c8c1045bf97ba0d2c6f0bc6423be1e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 28 Sep 2002 20:06:41 +0000 Subject: Include ../include/libsmbclient.h instead of just libsmbclient.h - we don't want to include the globally installed libsmbclient.h - found by jht (This used to be commit a7a54fc2c8b26c92ab0e3499531919debca3fe64) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 44cba611d2..faa4191e6d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -23,7 +23,7 @@ #include "includes.h" -#include "libsmbclient.h" +#include "../include/libsmbclient.h" /* * Functions exported by libsmb_cache.c that we need here -- cgit From 10581a3cef1c5d6cfc66ec22482bb0dec6bb011b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 28 Sep 2002 20:09:30 +0000 Subject: Include ../include/libsmbclient.h instead of just libsmbclient.h - we don't want to include the globally installed libsmbclient.h - found by jht (This used to be commit e35a5da3a75c74ab066bff5e0f60d30deb008451) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 44cba611d2..faa4191e6d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -23,7 +23,7 @@ #include "includes.h" -#include "libsmbclient.h" +#include "../include/libsmbclient.h" /* * Functions exported by libsmb_cache.c that we need here -- cgit From cd2ab11b249306e7661a56e84b211c126949ec8d Mon Sep 17 00:00:00 2001 From: John Terpstra Date: Sat, 28 Sep 2002 20:44:23 +0000 Subject: Fixing path to libsmbclient.h so it never gets crossed with a system installed one. (This used to be commit cc878f43b9a91385ca3671f17a08253b8464c039) --- source3/libsmb/libsmb_cache.c | 2 +- source3/libsmb/libsmb_compat.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index df02cf3718..b1620042f3 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -27,7 +27,7 @@ * Define this to get the real SMBCFILE and SMBCSRV structures */ #define _SMBC_INTERNAL -#include "libsmbclient.h" +#include "../include/libsmbclient.h" /* * Structure we use if internal caching mechanism is used diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index dbfd860358..bba90c648e 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -28,7 +28,7 @@ * Define this to get the real SMBCFILE and SMBCSRV structures */ #define _SMBC_INTERNAL -#include "libsmbclient.h" +#include "../include/libsmbclient.h" struct smbc_compat_fdlist { SMBCFILE * file; -- cgit From f9789eb987f5cec9a9b5125815cb3de4ea88349b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 28 Sep 2002 21:42:51 +0000 Subject: Change libsmbclient.h -> ../include/libsmbclient.h in 3.0 as well (This used to be commit 5b451ce6f096d699a80c10f48bde5ee224e29ccf) --- source3/libsmb/libsmb_cache.c | 2 +- source3/libsmb/libsmb_compat.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index df02cf3718..b1620042f3 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -27,7 +27,7 @@ * Define this to get the real SMBCFILE and SMBCSRV structures */ #define _SMBC_INTERNAL -#include "libsmbclient.h" +#include "../include/libsmbclient.h" /* * Structure we use if internal caching mechanism is used diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index dbfd860358..bba90c648e 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -28,7 +28,7 @@ * Define this to get the real SMBCFILE and SMBCSRV structures */ #define _SMBC_INTERNAL -#include "libsmbclient.h" +#include "../include/libsmbclient.h" struct smbc_compat_fdlist { SMBCFILE * file; -- cgit From 68259be9d555257042e91e343324eb91f12a7185 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 01:33:05 +0000 Subject: Added error string for server timeout on client call. Jeremy. (This used to be commit abeebf33c132c4975ac5dadde57c22176ddc9fda) --- source3/libsmb/clientgen.c | 2 ++ source3/libsmb/clierror.c | 8 ++++++++ 2 files changed, 10 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 793dd19644..fff81545b1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -69,6 +69,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { + extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -100,6 +101,7 @@ BOOL cli_receive_smb(struct cli_state *cli) if (!ret) { close(cli->fd); cli->fd = -1; + cli->smb_read_erorr = smb_read_error; } return ret; diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index e1507c6048..fb88b66786 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -85,6 +85,14 @@ char *cli_errstr(struct cli_state *cli) return cli_error_message; } + /* Was it server timeout ? */ + if (cli->fd == -1 && cli->timeout > 0 && cli->smb_read_error == READ_TIMEOUT) { + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Call timed out: server did not respond after %d milliseconds", + cli->timeout); + return cli_error_message; + } + /* Case #1: RAP error */ if (cli->rap_error) { for (i = 0; rap_errmap[i].message != NULL; i++) { -- cgit From 5cec60b31b63821ebc35f0a3f02b96329a08387d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 01:41:20 +0000 Subject: Added error string for server timeout on client call. Jeremy. (This used to be commit 28d2eb934318818a3b0527e391987ea139dbf4a3) --- source3/libsmb/clientgen.c | 2 ++ source3/libsmb/clierror.c | 8 ++++++++ 2 files changed, 10 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 793dd19644..156de42836 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -69,6 +69,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { + extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -100,6 +101,7 @@ BOOL cli_receive_smb(struct cli_state *cli) if (!ret) { close(cli->fd); cli->fd = -1; + cli->smb_read_error = smb_read_error; } return ret; diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index e1507c6048..fb88b66786 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -85,6 +85,14 @@ char *cli_errstr(struct cli_state *cli) return cli_error_message; } + /* Was it server timeout ? */ + if (cli->fd == -1 && cli->timeout > 0 && cli->smb_read_error == READ_TIMEOUT) { + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Call timed out: server did not respond after %d milliseconds", + cli->timeout); + return cli_error_message; + } + /* Case #1: RAP error */ if (cli->rap_error) { for (i = 0; rap_errmap[i].message != NULL; i++) { -- cgit From 549f70f8eeb9ea416b8b54436597dd4fcc893918 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 01:43:09 +0000 Subject: Fixed typo. Jeremy. (This used to be commit e2d66c5d238a057175d9316b4491ca26066f34fe) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fff81545b1..156de42836 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -101,7 +101,7 @@ BOOL cli_receive_smb(struct cli_state *cli) if (!ret) { close(cli->fd); cli->fd = -1; - cli->smb_read_erorr = smb_read_error; + cli->smb_read_error = smb_read_error; } return ret; -- cgit From 3e2a384e765c0702fb34d2f2447bf653dabde185 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 02:11:26 +0000 Subject: Tidy up client error processing. Jeremy. (This used to be commit 983e6d137eaada5cea1235e0cf051bc314b6f9d8) --- source3/libsmb/clientgen.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 156de42836..4a102097ce 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,9 +22,10 @@ #include "includes.h" -/* - * Change the port number used to call on - */ +/**************************************************************************** + Change the port number used to call on. +****************************************************************************/ + int cli_set_port(struct cli_state *cli, int port) { cli->port = port; @@ -96,13 +97,13 @@ BOOL cli_receive_smb(struct cli_state *cli) } } - /* If the server is not responding, note that now */ + /* If the server is not responding, note that now */ - if (!ret) { - close(cli->fd); - cli->fd = -1; + if (!ret) { cli->smb_read_error = smb_read_error; - } + close(cli->fd); + cli->fd = -1; + } return ret; } @@ -130,7 +131,8 @@ BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { close(cli->fd); cli->fd = -1; - DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); + DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", + (int)len,(int)ret, strerror(errno) )); return False; } nwritten += ret; @@ -232,16 +234,14 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - if (lp_use_spnego()) { + if (lp_use_spnego()) cli->use_spnego = True; - } /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 ones. This intended only as a temporary hack. */ - if (getenv("CLI_FORCE_DOSERR")) { + if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - } /* A way to attempt to force SMB signing */ if (getenv("CLI_FORCE_SMB_SIGNING")) @@ -295,6 +295,7 @@ void cli_close_connection(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); cli->fd = -1; + cli->smb_read_error = 0; } /**************************************************************************** @@ -306,9 +307,8 @@ void cli_shutdown(struct cli_state *cli) BOOL allocated = cli->allocated; cli_close_connection(cli); ZERO_STRUCTP(cli); - if (allocated) { + if (allocated) free(cli); - } } /**************************************************************************** @@ -348,4 +348,3 @@ BOOL cli_send_keepalive(struct cli_state *cli) } return True; } - -- cgit From 88fad685d4c0e123ab0f85d8b081ae770569218e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 02:11:35 +0000 Subject: Tidy up client error processing. Jeremy. (This used to be commit aea64f1c300b1ec5ec1c5d637f456f025ec12821) --- source3/libsmb/clientgen.c | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 156de42836..4a102097ce 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,9 +22,10 @@ #include "includes.h" -/* - * Change the port number used to call on - */ +/**************************************************************************** + Change the port number used to call on. +****************************************************************************/ + int cli_set_port(struct cli_state *cli, int port) { cli->port = port; @@ -96,13 +97,13 @@ BOOL cli_receive_smb(struct cli_state *cli) } } - /* If the server is not responding, note that now */ + /* If the server is not responding, note that now */ - if (!ret) { - close(cli->fd); - cli->fd = -1; + if (!ret) { cli->smb_read_error = smb_read_error; - } + close(cli->fd); + cli->fd = -1; + } return ret; } @@ -130,7 +131,8 @@ BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { close(cli->fd); cli->fd = -1; - DEBUG(0,("Error writing %d bytes to client. %d\n", (int)len,(int)ret)); + DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", + (int)len,(int)ret, strerror(errno) )); return False; } nwritten += ret; @@ -232,16 +234,14 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - if (lp_use_spnego()) { + if (lp_use_spnego()) cli->use_spnego = True; - } /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 ones. This intended only as a temporary hack. */ - if (getenv("CLI_FORCE_DOSERR")) { + if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - } /* A way to attempt to force SMB signing */ if (getenv("CLI_FORCE_SMB_SIGNING")) @@ -295,6 +295,7 @@ void cli_close_connection(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); cli->fd = -1; + cli->smb_read_error = 0; } /**************************************************************************** @@ -306,9 +307,8 @@ void cli_shutdown(struct cli_state *cli) BOOL allocated = cli->allocated; cli_close_connection(cli); ZERO_STRUCTP(cli); - if (allocated) { + if (allocated) free(cli); - } } /**************************************************************************** @@ -348,4 +348,3 @@ BOOL cli_send_keepalive(struct cli_state *cli) } return True; } - -- cgit From 5567ef53cb65e6100825ea909d9c35e322e65293 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 06:50:25 +0000 Subject: Cope with rw errors and timeout to peer. Jeremy. (This used to be commit 736a7bab487d7e217eed452e2089adb6b4164ad5) --- source3/libsmb/clientgen.c | 5 +++-- source3/libsmb/clierror.c | 30 +++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4a102097ce..2236d8508d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -100,7 +100,7 @@ BOOL cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (!ret) { - cli->smb_read_error = smb_read_error; + cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; } @@ -131,6 +131,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { close(cli->fd); cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); return False; @@ -295,7 +296,7 @@ void cli_close_connection(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); cli->fd = -1; - cli->smb_read_error = 0; + cli->smb_rw_error = 0; } /**************************************************************************** diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index fb88b66786..f5281eb047 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -85,11 +85,31 @@ char *cli_errstr(struct cli_state *cli) return cli_error_message; } - /* Was it server timeout ? */ - if (cli->fd == -1 && cli->timeout > 0 && cli->smb_read_error == READ_TIMEOUT) { - slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Call timed out: server did not respond after %d milliseconds", - cli->timeout); + /* Was it server socket error ? */ + if (cli->fd == -1 && cli->smb_rw_error) { + switch(cli->smb_rw_error) { + case READ_TIMEOUT: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Call timed out: server did not respond after %d milliseconds", + cli->timeout); + break; + case READ_EOF: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Call returned zero bytes (EOF)\n" ); + break; + case READ_ERROR: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Read error: %s\n", strerror(errno) ); + break; + case WRITE_ERROR: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Write error: %s\n", strerror(errno) ); + break; + default: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Unknown error code %d\n", cli->smb_rw_error ); + break; + } return cli_error_message; } -- cgit From 8147df0b6b4674670e70b45c603e8323e5c61c33 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Oct 2002 06:50:38 +0000 Subject: Cope with rw errors and timeout to peer. Jeremy. (This used to be commit d8d351eb01ea7c84828dbc96224d7b13d643b558) --- source3/libsmb/clientgen.c | 5 +++-- source3/libsmb/clierror.c | 30 +++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4a102097ce..2236d8508d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -100,7 +100,7 @@ BOOL cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (!ret) { - cli->smb_read_error = smb_read_error; + cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; } @@ -131,6 +131,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (ret <= 0) { close(cli->fd); cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); return False; @@ -295,7 +296,7 @@ void cli_close_connection(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); cli->fd = -1; - cli->smb_read_error = 0; + cli->smb_rw_error = 0; } /**************************************************************************** diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index fb88b66786..f5281eb047 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -85,11 +85,31 @@ char *cli_errstr(struct cli_state *cli) return cli_error_message; } - /* Was it server timeout ? */ - if (cli->fd == -1 && cli->timeout > 0 && cli->smb_read_error == READ_TIMEOUT) { - slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Call timed out: server did not respond after %d milliseconds", - cli->timeout); + /* Was it server socket error ? */ + if (cli->fd == -1 && cli->smb_rw_error) { + switch(cli->smb_rw_error) { + case READ_TIMEOUT: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Call timed out: server did not respond after %d milliseconds", + cli->timeout); + break; + case READ_EOF: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Call returned zero bytes (EOF)\n" ); + break; + case READ_ERROR: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Read error: %s\n", strerror(errno) ); + break; + case WRITE_ERROR: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Write error: %s\n", strerror(errno) ); + break; + default: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Unknown error code %d\n", cli->smb_rw_error ); + break; + } return cli_error_message; } -- cgit From ad8a22e570c8970247dc76defc9be2b768bd102d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 1 Oct 2002 13:10:57 +0000 Subject: Updates from Samba HEAD: - Fix segfaults in the 'net ads' commands when no password is provided - Readd --with-ldapsam for 2.2 compatability. This conditionally compiles the old options, but the actual code is available on all ldap systems. - Fix shadow passwords (as per work with vl) - Fix sending plaintext passwords to unicode servers (again vl) - Add a bit of const to secrets.c functions - Fix some spelling and grammer by vance. - Document the -r option in smbgroupedit. There are more changes in HEAD, I'm only merging the changes I've been involved with. Andrew Bartlett (This used to be commit 83973c389355a5cc9ca74af467dfd8b5dabd2c8f) --- source3/libsmb/cliconnect.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 62acccdfb7..3951e3c776 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -184,12 +184,8 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, char *pass, char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); - fstring pword; - int passlen; char *p; - passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE|STR_ASCII); - set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -202,7 +198,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, SSVAL(cli->outbuf,smb_vwv8,0); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, pword, -1, STR_TERMINATE); /* password */ + p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ -- cgit From d2ea6d5ae759bd2c842b5836d778b5a52b8af477 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Oct 2002 19:11:36 +0000 Subject: merge of working dsrolegetprimdominfo() client code from APP_HEAD (This used to be commit f70caa25e4ee198151b915cf2bc0a26b2d0e243d) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3951e3c776..f005ac21f3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -344,7 +344,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* Have plaintext orginal */ set_signing_on_cli(cli, pass, ntpword); } - + return True; } -- cgit From 9c1b62c0fd06cc65853269db3c63b169daa90664 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 Oct 2002 19:33:41 +0000 Subject: merge of working dsrolegetprimdominfo() client code from APP_HEAD (This used to be commit 028477e35208e76fedbc7c743426fd9be94b7cf0) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3951e3c776..f005ac21f3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -344,7 +344,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, /* Have plaintext orginal */ set_signing_on_cli(cli, pass, ntpword); } - + return True; } -- cgit From ac71311ff2f74d602c14c24c0b03d6ef3e81afd1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Oct 2002 22:50:10 +0000 Subject: Added "unknown info level". Jeremy. (This used to be commit afecd1aa52b98f123b226ff172d5ef5768cbb44f) --- source3/libsmb/smberr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 84b3f507e6..724c8edd54 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -77,6 +77,7 @@ err_code_struct dos_msgs[] = { {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, {"ERRdiskfull",ERRdiskfull,"Disk full"}, {"ERRgeneral",ERRgeneral, "General failure"}, + {"ERRunknownlevel",ERRunknownlevel, "Unknown info level"}, {NULL,-1,NULL}}; /* Server Error Messages */ -- cgit From bb2dc1a6339c567f1802f5fa33e593bd7f73fbd3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Oct 2002 22:50:31 +0000 Subject: Added unknown info level. Jeremy. (This used to be commit 7634a58ec83ed7b40fe8ac95b0486b1ac00c59e4) --- source3/libsmb/smberr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 84b3f507e6..724c8edd54 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -77,6 +77,7 @@ err_code_struct dos_msgs[] = { {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, {"ERRdiskfull",ERRdiskfull,"Disk full"}, {"ERRgeneral",ERRgeneral, "General failure"}, + {"ERRunknownlevel",ERRunknownlevel, "Unknown info level"}, {NULL,-1,NULL}}; /* Server Error Messages */ -- cgit From 598ebaa2b3bb0ade6e07e0f520a966526142cb19 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Oct 2002 21:29:37 +0000 Subject: Added cli_set_timeout() call. Jeremy. (This used to be commit 94a5c589945ffd4719f7509c162cf994f7914312) --- source3/libsmb/clientgen.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2236d8508d..28480043b9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,6 +22,17 @@ #include "includes.h" +/**************************************************************************** + Change the timeout (in milliseconds). +****************************************************************************/ + +unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout) +{ + unsigned int old_timeout = cli->timeout; + cli->timeout = timeout; + return old_timeout; +} + /**************************************************************************** Change the port number used to call on. ****************************************************************************/ -- cgit From ebc7fd0a3c3cf7f199cf89f82f1457ddd2cf8686 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Oct 2002 21:30:06 +0000 Subject: Added cli_set_timeout() call. Jeremy. (This used to be commit 9225054179b6642ae8be790d35e6590aefa46dd3) --- source3/libsmb/clientgen.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2236d8508d..28480043b9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,6 +22,17 @@ #include "includes.h" +/**************************************************************************** + Change the timeout (in milliseconds). +****************************************************************************/ + +unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout) +{ + unsigned int old_timeout = cli->timeout; + cli->timeout = timeout; + return old_timeout; +} + /**************************************************************************** Change the port number used to call on. ****************************************************************************/ -- cgit From c53eb2ed540e79d6deae5f41e17febc5bf5dbf57 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Oct 2002 17:10:24 +0000 Subject: Added new error codes. Fix up connection code to retry in the same way that app-head does. Jeremy. (This used to be commit ec7953f20145799f6286a295472df4826bfdfb8f) --- source3/libsmb/cliconnect.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f005ac21f3..6a21121f43 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1153,6 +1153,7 @@ static void init_creds(struct ntuser_creds *creds, char* username, @param user Username, unix string @param domain User's domain @param password User's password, unencrypted unix string. + @param retry BOOL. Did this connection fail with a retryable error ? */ NTSTATUS cli_full_connection(struct cli_state **output_cli, @@ -1161,7 +1162,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr *dest_ip, int port, char *service, char *service_type, char *user, char *domain, - char *password, int flags) + char *password, int flags, + BOOL *retry) { struct ntuser_creds creds; NTSTATUS nt_status; @@ -1171,6 +1173,9 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr ip; extern pstring global_myname; + if (retry) + *retry = False; + if (!my_name) my_name = global_myname; @@ -1185,6 +1190,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return NT_STATUS_UNSUCCESSFUL; } + cli_set_timeout(cli, 10000); /* 10 seconds. */ + if (dest_ip) ip = *dest_ip; else @@ -1201,6 +1208,9 @@ again: return NT_STATUS_UNSUCCESSFUL; } + if (retry) + *retry = True; + if (!cli_session_request(cli, &calling, &called)) { char *p; DEBUG(1,("session request to %s failed (%s)\n", -- cgit From 389a16d9d5331ddc7ae61d3d4ef3a4ee48734d4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Oct 2002 17:10:29 +0000 Subject: Added new error codes. Fix up connection code to retry in the same way that app-head does. Jeremy. (This used to be commit b521abd86b10573ca8f9116907c81e6deb55f049) --- source3/libsmb/cliconnect.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f005ac21f3..6a21121f43 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1153,6 +1153,7 @@ static void init_creds(struct ntuser_creds *creds, char* username, @param user Username, unix string @param domain User's domain @param password User's password, unencrypted unix string. + @param retry BOOL. Did this connection fail with a retryable error ? */ NTSTATUS cli_full_connection(struct cli_state **output_cli, @@ -1161,7 +1162,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr *dest_ip, int port, char *service, char *service_type, char *user, char *domain, - char *password, int flags) + char *password, int flags, + BOOL *retry) { struct ntuser_creds creds; NTSTATUS nt_status; @@ -1171,6 +1173,9 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct in_addr ip; extern pstring global_myname; + if (retry) + *retry = False; + if (!my_name) my_name = global_myname; @@ -1185,6 +1190,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return NT_STATUS_UNSUCCESSFUL; } + cli_set_timeout(cli, 10000); /* 10 seconds. */ + if (dest_ip) ip = *dest_ip; else @@ -1201,6 +1208,9 @@ again: return NT_STATUS_UNSUCCESSFUL; } + if (retry) + *retry = True; + if (!cli_session_request(cli, &calling, &called)) { char *p; DEBUG(1,("session request to %s failed (%s)\n", -- cgit From dbfc2f42a2c4711f539364d3954b9b9c10dbddf5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 26 Oct 2002 00:59:21 +0000 Subject: Make sure that we always return False if the password change never returns. (A stuck 'unix passowrd sync' was gettting reported as 'success', causing all sorts of fun) Andrew Bartlett (This used to be commit b0d5745bb53b16e92160a6bdd2b984afb0e982ee) --- source3/libsmb/clirap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 2064e14954..b4924fd773 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -343,13 +343,17 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char return False; } - if (cli_receive_trans(cli,SMBtrans, + if (!cli_receive_trans(cli,SMBtrans, &rparam, &rprcnt, &rdata, &rdrcnt)) { - if (rparam) - cli->rap_error = SVAL(rparam,0); + DEBUG(0,("cli_oem_change_password: Failed to recieve reply to password change for user %s\n", + user )); + return False; } - + + if (rparam) + cli->rap_error = SVAL(rparam,0); + SAFE_FREE(rparam); SAFE_FREE(rdata); -- cgit From 35ac9d287f000c27dc864789b341bebe7acb4c74 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 26 Oct 2002 02:20:59 +0000 Subject: Try to catch up on the code I've put into HEAD that should be in 3.0: - vorlan's hosts allow with DNS names patch - use x_fileno() in debug.c, not the struct directly. - check for server timeout on password change (was reporting success) - better error/status loggin in both the pam_winbind client and winbindd_pam server code. - (pdb_ldap) don't set the ldap version twice - we do it on every bind anyway. (This used to be commit 9fa1863d8e7788eda83911ca2610754486b33069) --- source3/libsmb/clirap.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 2064e14954..b4924fd773 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -343,13 +343,17 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char return False; } - if (cli_receive_trans(cli,SMBtrans, + if (!cli_receive_trans(cli,SMBtrans, &rparam, &rprcnt, &rdata, &rdrcnt)) { - if (rparam) - cli->rap_error = SVAL(rparam,0); + DEBUG(0,("cli_oem_change_password: Failed to recieve reply to password change for user %s\n", + user )); + return False; } - + + if (rparam) + cli->rap_error = SVAL(rparam,0); + SAFE_FREE(rparam); SAFE_FREE(rdata); -- cgit From 689d510ef6b071ed220e41293c64a36ea79597b7 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 1 Nov 2002 05:06:19 +0000 Subject: Add more code to the profiles program and add Makefile.in support. (This used to be commit daefe52a56a7b977b8e561f8f668c42183de413b) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 28480043b9..fc3cdaffd8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -175,6 +175,7 @@ void cli_setup_packet(struct cli_state *cli) if (cli->sign_info.use_smb_signing || cli->sign_info.temp_smb_signing) flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + flags2 |= 0xc010; SSVAL(cli->outbuf,smb_flg2, flags2); } } -- cgit From 2eac34d4d93a4c5dbe8e895015000ef8635220cb Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 1 Nov 2002 05:29:11 +0000 Subject: Revert that stupid one line change. (This used to be commit 095af10ff2e549b82c646df5ed20cf05352a3994) --- source3/libsmb/clientgen.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fc3cdaffd8..28480043b9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -175,7 +175,6 @@ void cli_setup_packet(struct cli_state *cli) if (cli->sign_info.use_smb_signing || cli->sign_info.temp_smb_signing) flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - flags2 |= 0xc010; SSVAL(cli->outbuf,smb_flg2, flags2); } } -- cgit From 62144574998217ae322c9b0b63f0f746d59a89d6 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 4 Nov 2002 02:01:48 +0000 Subject: The fixes from Tom plus a minor update from me. (This used to be commit 6db6a48711f51ee6add32953506cd5db33939a1b) --- source3/libsmb/libsmb_compat.c | 8 +- source3/libsmb/libsmbclient.c | 169 ++++++++++++++++++++++++----------------- 2 files changed, 101 insertions(+), 76 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index bba90c648e..27b274953a 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -24,11 +24,7 @@ #include "includes.h" -/* - * Define this to get the real SMBCFILE and SMBCSRV structures - */ -#define _SMBC_INTERNAL -#include "../include/libsmbclient.h" +#include "../include/libsmb_internal.h" struct smbc_compat_fdlist { SMBCFILE * file; @@ -272,7 +268,7 @@ int smbc_open_print_job(const char *fname) return (int) file; } -int smbc_list_print_jobs(const char *purl, smbc_get_print_job_info fn) +int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn) { return statcont->list_print_jobs(statcont, purl, fn); } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index faa4191e6d..dd46749a5a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -23,7 +23,7 @@ #include "includes.h" -#include "../include/libsmbclient.h" +#include "../include/libsmb_internal.h" /* * Functions exported by libsmb_cache.c that we need here @@ -219,7 +219,7 @@ int smbc_check_server(SMBCCTX * context, SMBCSRV * server) } /* - * Remove a server from the list server_table if it's unused. + * Remove a server from the cached server list it's unused. * On success, 0 is returned. 1 is returned if the server could not be removed. * * Also useable outside libsmbclient @@ -229,11 +229,12 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) SMBCFILE * file; /* are we being fooled ? */ - if (!context || !context->_initialized || !srv) return 1; + if (!context || !context->internal || + !context->internal->_initialized || !srv) return 1; /* Check all open files/directories for a relation with this server */ - for (file = context->_files; file; file=file->next) { + for (file = context->internal->_files; file; file=file->next) { if (file->srv == srv) { /* Still used */ DEBUG(3, ("smbc_remove_usused_server: %p still used by %p.\n", @@ -242,7 +243,7 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) } } - DLIST_REMOVE(context->_servers, srv); + DLIST_REMOVE(context->internal->_servers, srv); cli_shutdown(&srv->cli); @@ -475,7 +476,8 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m SMBCFILE *file = NULL; int fd; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return NULL; @@ -542,7 +544,7 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m file->offset = 0; file->file = True; - DLIST_ADD(context->_files, file); + DLIST_ADD(context->internal->_files, file); return file; } @@ -573,7 +575,8 @@ static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return NULL; @@ -591,7 +594,8 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t { int ret; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -600,7 +604,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -641,14 +645,15 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ { int ret; - if (!context || context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -686,14 +691,15 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { SMBCSRV *srv; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -715,7 +721,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) * from the server cache if unused */ errno = smbc_errno(context, &file->srv->cli); srv = file->srv; - DLIST_REMOVE(context->_files, file); + DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); context->callbacks.remove_unused_server_fn(context, srv); @@ -737,7 +743,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) * from the server cache if unused */ errno = smbc_errno(context, &file->srv->cli); srv = file->srv; - DLIST_REMOVE(context->_files, file); + DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); context->callbacks.remove_unused_server_fn(context, srv); @@ -745,7 +751,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) return -1; } - DLIST_REMOVE(context->_files, file); + DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); @@ -762,7 +768,8 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, SMB_INO_T *ino) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -798,7 +805,8 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) pstring path; SMBCSRV *srv = NULL; - if (!context || context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -892,8 +900,10 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, pstring path1, path2; SMBCSRV *srv = NULL; - if (!ocontext || !ncontext || - !ocontext->_initialized || !ncontext->_initialized) { + if (!ocontext || !ncontext || + !ocontext->internal || !ncontext->internal || + !ocontext->internal->_initialized || + !ncontext->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -961,14 +971,15 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int { size_t size; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -1021,7 +1032,8 @@ static ino_t smbc_inode(SMBCCTX *context, const char *name) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -1089,7 +1101,8 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) uint16 mode = 0; SMB_INO_T ino = 0; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -1172,14 +1185,15 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) uint16 mode; SMB_INO_T ino = 0; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -1272,9 +1286,6 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint ZERO_STRUCTP(dirent); - ZERO_STRUCTP(dirent); - - if (dir->dir_list == NULL) { dir->dir_list = malloc(sizeof(struct smbc_dir_list)); @@ -1355,8 +1366,6 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ break; } - ZERO_STRUCTP(dir->dir_list); - } else dirent_type = dir->dir_type; @@ -1391,9 +1400,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; struct in_addr rem_ip; - int slot = 0; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return NULL; @@ -1489,7 +1498,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - ZERO_STRUCTP(dir->dir_end); dir->srv = srv; @@ -1669,7 +1677,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } - DLIST_ADD(context->_files, dir); + DLIST_ADD(context->internal->_files, dir); return dir; } @@ -1681,14 +1689,15 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!dir || !DLIST_CONTAINS(context->_files, dir)) { + if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; return -1; @@ -1697,7 +1706,7 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) smbc_remove_dir(dir); /* Clean it up */ - DLIST_REMOVE(context->_files, dir); + DLIST_REMOVE(context->internal->_files, dir); if (dir) { @@ -1720,14 +1729,15 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) /* Check that all is ok first ... */ - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return NULL; } - if (!dir || !DLIST_CONTAINS(context->_files, dir)) { + if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; return NULL; @@ -1756,12 +1766,12 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) /* Hmmm, do I even need to copy it? */ - memcpy(context->_dirent, dirent, dirent->dirlen); /* Copy the dirent */ - dirp = (struct smbc_dirent *)context->_dirent; + memcpy(context->internal->_dirent, dirent, dirent->dirlen); /* Copy the dirent */ + dirp = (struct smbc_dirent *)context->internal->_dirent; dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); dir->dir_next = dir->dir_next->next; - return (struct smbc_dirent *)context->_dirent; + return (struct smbc_dirent *)context->internal->_dirent; } } @@ -1778,14 +1788,15 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent /* Check that all is ok first ... */ - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!dir || !DLIST_CONTAINS(context->_files, dir)) { + if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; return -1; @@ -1864,7 +1875,8 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) fstring server, share, user, password, workgroup; pstring path; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -1950,7 +1962,8 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) fstring server, share, user, password, workgroup; pstring path; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2047,14 +2060,15 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!dir || !DLIST_CONTAINS(context->_files, dir)) { + if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; return -1; @@ -2111,7 +2125,8 @@ static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) struct smbc_dirent *dirent = (struct smbc_dirent *)offset; struct smbc_dir_list *list_ent = NULL; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2157,7 +2172,8 @@ static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) { - if (context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2179,7 +2195,8 @@ static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) fstring server, share, user, password; pstring path; - if (!context || context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return NULL; @@ -2216,8 +2233,8 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr int bytes, saverr, tot_bytes = 0; char buf[4096]; - if (!c_file || !c_file->_initialized || !c_print || - !c_print->_initialized) { + if (!c_file || !c_file->internal->_initialized || !c_print || + !c_print->internal->_initialized) { errno = EINVAL; return -1; @@ -2286,13 +2303,14 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr * Routine to list print jobs on a printer share ... */ -static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, void (*fn)(struct print_job_info *)) +static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn) { SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2322,7 +2340,7 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, void (* } - if (cli_print_queue(&srv->cli, fn) < 0) { + if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) { errno = smbc_errno(context, &srv->cli); return -1; @@ -2344,7 +2362,8 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id pstring path; int err; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2395,14 +2414,23 @@ SMBCCTX * smbc_new_context(void) { SMBCCTX * context; - context = malloc(sizeof(*context)); + context = malloc(sizeof(SMBCCTX)); if (!context) { errno = ENOMEM; return NULL; } - + ZERO_STRUCTP(context); + context->internal = malloc(sizeof(struct smbc_internal_data)); + if (!context->internal) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context->internal); + + /* ADD REASONABLE DEFAULTS */ context->debug = 0; context->timeout = 20000; /* 20 seconds */ @@ -2457,25 +2485,25 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) SMBCFILE * f; DEBUG(1,("Performing aggressive shutdown.\n")); - f = context->_files; + f = context->internal->_files; while (f) { context->close(context, f); f = f->next; } - context->_files = NULL; + context->internal->_files = NULL; /* First try to remove the servers the nice way. */ if (context->callbacks.purge_cached_fn(context)) { SMBCSRV * s; DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); - s = context->_servers; + s = context->internal->_servers; while (s) { cli_shutdown(&s->cli); context->callbacks.remove_cached_srv_fn(context, s); SAFE_FREE(s); s = s->next; } - context->_servers = NULL; + context->internal->_servers = NULL; } } else { @@ -2485,12 +2513,12 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) errno = EBUSY; return 1; } - if (context->_servers) { + if (context->internal->_servers) { DEBUG(1, ("Active servers in context, free_context failed.\n")); errno = EBUSY; return 1; } - if (context->_files) { + if (context->internal->_files) { DEBUG(1, ("Active files in context, free_context failed.\n")); errno = EBUSY; return 1; @@ -2503,6 +2531,7 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) SAFE_FREE(context->user); DEBUG(3, ("Context %p succesfully freed\n", context)); + SAFE_FREE(context->internal); SAFE_FREE(context); return 0; } @@ -2521,13 +2550,13 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) int pid; char *user = NULL, *home = NULL; - if (!context) { + if (!context || !context->internal) { errno = EBADF; return NULL; } /* Do not initialise the same client twice */ - if (context->_initialized) { + if (context->internal->_initialized) { return 0; } @@ -2634,7 +2663,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) * FIXME: Should we check the function pointers here? */ - context->_initialized = 1; + context->internal->_initialized = 1; return context; } -- cgit From ea24bb2da8f643e043dc3af3ed3f16388878b57b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Nov 2002 01:29:07 +0000 Subject: Merge of get_dc_list() api change. This was slightly more intrusive than the version in APPLIANCE so watch out for boogs. (This used to be commit 1e054e3db654801fbb5580211529cdfdea9ed686) --- source3/libsmb/namequery.c | 59 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 40a353fa8b..8fdf145625 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1206,54 +1206,87 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ } - /******************************************************** - Get the IP address list of the PDC/BDC's of a Domain. + Get the IP address list of the primary domain controller + for a domain. *********************************************************/ -BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count) +BOOL get_pdc_ip(const char *domain, struct in_addr *ip) { - int name_type = pdc_only ? 0x1B : 0x1C; + struct in_addr *ip_list; + int count; + + /* Look up #1B name */ + + if (!internal_resolve_name(domain, 0x1b, &ip_list, &count)) + return False; + + SMB_ASSERT(count == 1); + + *ip = ip_list[0]; + SAFE_FREE(ip_list); + + return True; +} +/******************************************************** + Get the IP address list of the domain controllers for + a domain. +*********************************************************/ + +BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) +{ /* * If it's our domain then * use the 'password server' parameter. */ - if (strequal(group, lp_workgroup())) { + if (strequal(domain, lp_workgroup())) { char *p; char *pserver = lp_passwordserver(); fstring name; int num_adresses = 0; struct in_addr *return_iplist = NULL; - if (! *pserver) - return internal_resolve_name(group, name_type, ip_list, count); + if (!*pserver) + return internal_resolve_name( + domain, 0x1C, ip_list, count); p = pserver; + while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) - return internal_resolve_name(group, name_type, ip_list, count); + return internal_resolve_name( + domain, 0x1C, ip_list, count); num_adresses++; } + if (num_adresses == 0) - return internal_resolve_name(group, name_type, ip_list, count); + return internal_resolve_name( + domain, 0x1C, ip_list, count); + + return_iplist = (struct in_addr *)malloc( + num_adresses * sizeof(struct in_addr)); - return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr)); - if(return_iplist == NULL) { + if (return_iplist == NULL) { DEBUG(3,("get_dc_list: malloc fail !\n")); return False; } + p = pserver; *count = 0; + while (next_token(&p,name,LIST_SEP,sizeof(name))) { struct in_addr name_ip; if (resolve_name( name, &name_ip, 0x20) == False) continue; return_iplist[(*count)++] = name_ip; } + *ip_list = return_iplist; + return (*count != 0); - } else - return internal_resolve_name(group, name_type, ip_list, count); + } + + return internal_resolve_name(domain, 0x1C, ip_list, count); } -- cgit From ab1cf8d1cf447e85063b43b65fa05c8b4bfde2a9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Nov 2002 05:14:15 +0000 Subject: Merge of get_dc_list() api change from HEAD. (This used to be commit 6ba7847ce2756fde94e530fd0bf2a055f3e27373) --- source3/libsmb/namequery.c | 59 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 46 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 40a353fa8b..8fdf145625 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1206,54 +1206,87 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... #endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ } - /******************************************************** - Get the IP address list of the PDC/BDC's of a Domain. + Get the IP address list of the primary domain controller + for a domain. *********************************************************/ -BOOL get_dc_list(BOOL pdc_only, const char *group, struct in_addr **ip_list, int *count) +BOOL get_pdc_ip(const char *domain, struct in_addr *ip) { - int name_type = pdc_only ? 0x1B : 0x1C; + struct in_addr *ip_list; + int count; + + /* Look up #1B name */ + + if (!internal_resolve_name(domain, 0x1b, &ip_list, &count)) + return False; + + SMB_ASSERT(count == 1); + + *ip = ip_list[0]; + SAFE_FREE(ip_list); + + return True; +} +/******************************************************** + Get the IP address list of the domain controllers for + a domain. +*********************************************************/ + +BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) +{ /* * If it's our domain then * use the 'password server' parameter. */ - if (strequal(group, lp_workgroup())) { + if (strequal(domain, lp_workgroup())) { char *p; char *pserver = lp_passwordserver(); fstring name; int num_adresses = 0; struct in_addr *return_iplist = NULL; - if (! *pserver) - return internal_resolve_name(group, name_type, ip_list, count); + if (!*pserver) + return internal_resolve_name( + domain, 0x1C, ip_list, count); p = pserver; + while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) - return internal_resolve_name(group, name_type, ip_list, count); + return internal_resolve_name( + domain, 0x1C, ip_list, count); num_adresses++; } + if (num_adresses == 0) - return internal_resolve_name(group, name_type, ip_list, count); + return internal_resolve_name( + domain, 0x1C, ip_list, count); + + return_iplist = (struct in_addr *)malloc( + num_adresses * sizeof(struct in_addr)); - return_iplist = (struct in_addr *)malloc(num_adresses * sizeof(struct in_addr)); - if(return_iplist == NULL) { + if (return_iplist == NULL) { DEBUG(3,("get_dc_list: malloc fail !\n")); return False; } + p = pserver; *count = 0; + while (next_token(&p,name,LIST_SEP,sizeof(name))) { struct in_addr name_ip; if (resolve_name( name, &name_ip, 0x20) == False) continue; return_iplist[(*count)++] = name_ip; } + *ip_list = return_iplist; + return (*count != 0); - } else - return internal_resolve_name(group, name_type, ip_list, count); + } + + return internal_resolve_name(domain, 0x1C, ip_list, count); } -- cgit From 47955b2f6cd10ac690705d322a8862c23f18072c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Nov 2002 02:38:42 +0000 Subject: Merge of scalable printing code fix... Needs testing. Also tidied up some of Richard's code (I don't think he uses the compiler flags -g -Wall -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual like I do :-) :-). Jeremy. (This used to be commit 10024ed06e9d91f24fdc78d59eef2f76bf395438) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6a21121f43..a404928a93 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1277,7 +1277,7 @@ again: Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. ****************************************************************************/ -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, +BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost, struct in_addr *pdest_ip) { struct nmb_name calling, called; -- cgit From 47035533781f49bd3cc1f4918c6b87c3904a02fe Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 8 Nov 2002 18:44:57 +0000 Subject: patches from Urban (This used to be commit da269a73edb7f637b1e1f8b3dafe677f46f66f85) --- source3/libsmb/cliconnect.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a404928a93..ee311932a7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -124,6 +124,9 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) if (cli->capabilities & CAP_UNICODE) capabilities |= CAP_UNICODE; + if (cli->capabilities & CAP_LARGE_FILES) + capabilities |= CAP_LARGE_FILES; + return capabilities; } -- cgit From 698fe3f07ab059fc2b0a3bac47e36748704fde6d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 8 Nov 2002 18:45:38 +0000 Subject: patches from Urban (This used to be commit 850b185a6e33fa924fa59cdd6316c9160ba65270) --- source3/libsmb/cliconnect.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6a21121f43..890dc4dc25 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -124,6 +124,9 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) if (cli->capabilities & CAP_UNICODE) capabilities |= CAP_UNICODE; + if (cli->capabilities & CAP_LARGE_FILES) + capabilities |= CAP_LARGE_FILES; + return capabilities; } -- cgit From c19598f2a6a3329e973e14e389e0577ebb914f3b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 8 Nov 2002 23:08:59 +0000 Subject: Merge from HEAD: - change auth_sam to use the initialisation flags to determine if the password attributes are set - add const to secrets.c, cliconnect.c - passdb: fix spelling in pdb_ldap, add group mapping back to smbpasswd - SAMR: add debugs to show what fails for group enum. Andrew Bartlett (This used to be commit 4e74d00b3634abf52aa24bfaa6dbe88202aa57a1) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 890dc4dc25..ee311932a7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1280,7 +1280,7 @@ again: Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. ****************************************************************************/ -BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost, +BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost, struct in_addr *pdest_ip) { struct nmb_name calling, called; -- cgit From 10968f47cf413d5471c7ca63394b376eac9eef40 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 10 Nov 2002 04:16:59 +0000 Subject: consolidate error mapping functions into a single file (This used to be commit 80086728f2b0d5d56a8ed9e427cba36898d68fc7) --- source3/libsmb/errormap.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index a35108c3de..7c28c7e8aa 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -3,6 +3,7 @@ * error mapping functions * Copyright (C) Andrew Tridgell 2001 * Copyright (C) Andrew Bartlett 2001 + * Copyright (C) Tim Potter 2000 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1482,3 +1483,57 @@ WERROR ntstatus_to_werror(NTSTATUS error) /* a lame guess */ return W_ERROR(NT_STATUS_V(error) & 0xffff); } + +/* Mapping between Unix, DOS and NT error numbers */ + +const struct unix_error_map unix_dos_nt_errmap[] = { + { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, + { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, + { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND }, + { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, + { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, + { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, + { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, + { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, + { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, + { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, +#ifdef EDQUOT + { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, +#endif +#ifdef ENOTEMPTY + { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, +#endif +#ifdef EXDEV + { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE }, +#endif +#ifdef EROFS + { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, +#endif +#ifdef ENAMETOOLONG + { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, +#endif + { 0, 0, 0, NT_STATUS_OK } +}; + +/********************************************************************* + Map an NT error code from a Unix error code. +*********************************************************************/ + +NTSTATUS map_nt_error_from_unix(int unix_error) +{ + int i = 0; + + if (unix_error == 0) + return NT_STATUS_OK; + + /* Look through list */ + while(unix_dos_nt_errmap[i].unix_error != 0) { + if (unix_dos_nt_errmap[i].unix_error == unix_error) + return unix_dos_nt_errmap[i].nt_error; + i++; + } + + /* Default return */ + return NT_STATUS_ACCESS_DENIED; +} -- cgit From 115f859a85cd31aff9935cbe9f9f7b43be303140 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 10 Nov 2002 04:34:03 +0000 Subject: sync with head was: consolidate alla error mapping functions in one file (This used to be commit 2c9e8b79d94e3276e9eb9bd676af0a68ee3908ff) --- source3/libsmb/errormap.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index a35108c3de..f310399616 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -3,6 +3,7 @@ * error mapping functions * Copyright (C) Andrew Tridgell 2001 * Copyright (C) Andrew Bartlett 2001 + * Copyright (C) Tim Potter 2000 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1482,3 +1483,58 @@ WERROR ntstatus_to_werror(NTSTATUS error) /* a lame guess */ return W_ERROR(NT_STATUS_V(error) & 0xffff); } + + +/* Mapping between Unix, DOS and NT error numbers */ + +const struct unix_error_map unix_dos_nt_errmap[] = { + { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, + { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, + { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND }, + { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, + { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, + { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, + { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, + { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, + { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, + { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, +#ifdef EDQUOT + { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, +#endif +#ifdef ENOTEMPTY + { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, +#endif +#ifdef EXDEV + { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE }, +#endif +#ifdef EROFS + { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, +#endif +#ifdef ENAMETOOLONG + { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, +#endif + { 0, 0, 0, NT_STATUS_OK } +}; + +/********************************************************************* + Map an NT error code from a Unix error code. +*********************************************************************/ + +NTSTATUS map_nt_error_from_unix(int unix_error) +{ + int i = 0; + + if (unix_error == 0) + return NT_STATUS_OK; + + /* Look through list */ + while(unix_dos_nt_errmap[i].unix_error != 0) { + if (unix_dos_nt_errmap[i].unix_error == unix_error) + return unix_dos_nt_errmap[i].nt_error; + i++; + } + + /* Default return */ + return NT_STATUS_ACCESS_DENIED; +} -- cgit From 250c9801197ea1c949bd94c1c891f81ab118b130 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:15:52 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit 82b8f749a36b42e22186297482aad2abb04fab8a) --- source3/libsmb/cliconnect.c | 51 +++++++++++++++++++++---------------------- source3/libsmb/namequery.c | 17 ++++++++------- source3/libsmb/nmblib.c | 31 +++++++++++++------------- source3/libsmb/passchange.c | 5 +---- source3/libsmb/pwd_cache.c | 14 ++---------- source3/libsmb/trust_passwd.c | 6 ++--- 6 files changed, 54 insertions(+), 70 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ee311932a7..584ad15174 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -44,8 +44,8 @@ static const struct { Do an old lanman2 style session setup. ****************************************************************************/ -static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, - char *pass, int passlen, const char *workgroup) +static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, + const char *pass, int passlen, const char *workgroup) { fstring pword; char *p; @@ -183,8 +183,8 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) Do a NT1 plaintext session setup. ****************************************************************************/ -static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, - char *pass, char *workgroup) +static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, + const char *pass, const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; @@ -228,7 +228,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, return True; } -static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 response[24]) +static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 response[24]) { uint8 zero_sig[8]; ZERO_STRUCT(zero_sig); @@ -264,10 +264,10 @@ static void set_temp_signing_on_cli(struct cli_state *cli) @param workgroup The user's domain. ****************************************************************************/ -static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) +static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, + const char *pass, int passlen, + const char *ntpass, int ntpasslen, + const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); uchar pword[24]; @@ -423,7 +423,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) Do a spnego/kerberos encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, char *workgroup) +static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; @@ -453,8 +453,8 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, - char *pass, char *workgroup) +static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, + const char *pass, const char *workgroup) { DATA_BLOB msg1, struct_blob; DATA_BLOB blob, chal1, chal2, auth, challenge_blob; @@ -581,8 +581,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, Do a spnego encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, - char *pass, char *workgroup) +static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, + const char *pass, const char *workgroup) { char *principal; char *OIDs[ASN1_MAX_OIDS]; @@ -646,10 +646,10 @@ ntlmssp: ****************************************************************************/ BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) + const char *user, + const char *pass, int passlen, + const char *ntpass, int ntpasslen, + const char *workgroup) { char *p; fstring user2; @@ -1130,8 +1130,8 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) Initialise client credentials for authenticated pipe access. ****************************************************************************/ -static void init_creds(struct ntuser_creds *creds, char* username, - char* domain, char* password) +static void init_creds(struct ntuser_creds *creds, const char* username, + const char* domain, const char* password) { ZERO_STRUCTP(creds); @@ -1163,9 +1163,9 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, struct in_addr *dest_ip, int port, - char *service, char *service_type, - char *user, char *domain, - char *password, int flags, + const char *service, const char *service_type, + const char *user, const char *domain, + const char *password, int flags, BOOL *retry) { struct ntuser_creds creds; @@ -1174,13 +1174,12 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct nmb_name called; struct cli_state *cli; struct in_addr ip; - extern pstring global_myname; if (retry) *retry = False; if (!my_name) - my_name = global_myname; + my_name = global_myname(); if (!(cli = cli_initialise(NULL))) return NT_STATUS_NO_MEMORY; @@ -1258,7 +1257,7 @@ again: if (service) { if (!cli_send_tconX(cli, service, service_type, - (char*)password, strlen(password)+1)) { + password, strlen(password)+1)) { DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); nt_status = cli_nt_error(cli); cli_shutdown(cli); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8fdf145625..5c3d942b90 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -471,7 +471,8 @@ BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa while(!x_feof(fp) && !x_ferror(fp)) { pstring ip,flags,extra; - char *ptr; + const char *ptr; + char *ptr1; int count = 0; *name_type = -1; @@ -524,20 +525,20 @@ BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa /* Extra feature. If the name ends in '#XX', where XX is a hex number, then only add that name type. */ - if((ptr = strchr_m(name, '#')) != NULL) + if((ptr1 = strchr_m(name, '#')) != NULL) { char *endptr; - ptr++; - *name_type = (int)strtol(ptr, &endptr, 16); + ptr1++; + *name_type = (int)strtol(ptr1, &endptr, 16); - if(!*ptr || (endptr == ptr)) + if(!*ptr1 || (endptr == ptr1)) { DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); continue; } - *(--ptr) = '\0'; /* Truncate at the '#' */ + *(--ptr1) = '\0'; /* Truncate at the '#' */ } return True; @@ -787,7 +788,7 @@ static BOOL internal_resolve_name(const char *name, int name_type, { pstring name_resolve_list; fstring tok; - char *ptr; + const char *ptr; BOOL allones = (strcmp(name,"255.255.255.255") == 0); BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); BOOL is_address = is_ipaddress(name); @@ -1242,7 +1243,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) */ if (strequal(domain, lp_workgroup())) { - char *p; + const char *p; char *pserver = lp_passwordserver(); fstring name; int num_adresses = 0; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ba0d8cee5d..43e32aebbd 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -28,14 +28,14 @@ static const struct opcode_names { char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { - {"Query", 0 }, - {"Registration", 5 }, - {"Release", 6 }, - {"WACK", 7 }, - {"Refresh", 8 }, - {"Refresh(altcode)", 9 }, - {"Multi-homed Registration", 15 }, - {0, -1 } + {"Query", 0 }, + {"Registration", 5 }, + {"Release", 6 }, + {"WACK", 7 }, + {"Refresh", 8 }, + {"Refresh(altcode)", 9 }, + {"Multi-homed Registration", 15 }, + {0, -1 } }; /**************************************************************************** @@ -814,15 +814,15 @@ static int build_dgram(char *buf,struct packet_struct *p) } /******************************************************************* - build a nmb name - *******************************************************************/ + Build a nmb name +*******************************************************************/ + void make_nmb_name( struct nmb_name *n, const char *name, int type) { - extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, global_scope, 63 ); + StrnCpy( n->scope, global_scope(), 63 ); strupper( n->scope ); } @@ -1180,7 +1180,6 @@ int name_mangle( char *In, char *Out, char name_type ) int len; char buf[20]; char *p = Out; - extern pstring global_scope; /* Safely copy the input string, In, into buf[]. */ (void)memset( buf, 0, 20 ); @@ -1204,9 +1203,9 @@ int name_mangle( char *In, char *Out, char name_type ) p[0] = '\0'; /* Add the scope string. */ - for( i = 0, len = 0; NULL != global_scope; i++, len++ ) + for( i = 0, len = 0; NULL != global_scope(); i++, len++ ) { - switch( global_scope[i] ) + switch( (global_scope())[i] ) { case '\0': p[0] = len; @@ -1219,7 +1218,7 @@ int name_mangle( char *In, char *Out, char name_type ) len = -1; break; default: - p[len+1] = global_scope[i]; + p[len+1] = (global_scope())[i]; break; } } diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index b96bdc95a1..41b6095520 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -20,9 +20,6 @@ #include "includes.h" - -extern pstring global_myname; - /************************************************************* change a password on a remote machine using IPC calls *************************************************************/ @@ -50,7 +47,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - make_nmb_name(&calling, global_myname , 0x0); + make_nmb_name(&calling, global_myname() , 0x0); make_nmb_name(&called , remote_machine, 0x20); if (!cli_session_request(&cli, &calling, &called)) { diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index fc0602507a..7ddcf853c4 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -41,7 +41,7 @@ static void pwd_init(struct pwd_info *pwd) Makes lm and nt hashed passwords. ****************************************************************************/ -static void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) +static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) { pstring dos_passwd; @@ -59,7 +59,7 @@ static void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) Stores a cleartext password. ****************************************************************************/ -void pwd_set_cleartext(struct pwd_info *pwd, char *clr) +void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) { pwd_init(pwd); push_ascii_fstring(pwd->password, clr); @@ -138,13 +138,3 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) if (nt_owf != NULL) memcpy(nt_owf, pwd->smb_nt_owf, 24); } - - - - - - - - - - diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 4d7acd1988..cf9fd58b13 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -20,8 +20,6 @@ #include "includes.h" -extern pstring global_myname; - /********************************************************* Change the domain password on the PDC. @@ -45,7 +43,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ return result; } - result = cli_net_srv_pwset(cli, mem_ctx, global_myname, new_trust_passwd_hash); + result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", @@ -99,7 +97,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx **********************************************************/ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *domain) + const char *domain) { unsigned char old_trust_passwd_hash[16]; char *up_domain; -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/libsmb/cliconnect.c | 51 +++++++++++++++++++++---------------------- source3/libsmb/namequery.c | 17 ++++++++------- source3/libsmb/nmblib.c | 31 +++++++++++++------------- source3/libsmb/passchange.c | 5 +---- source3/libsmb/pwd_cache.c | 14 ++---------- source3/libsmb/trust_passwd.c | 6 ++--- 6 files changed, 54 insertions(+), 70 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ee311932a7..584ad15174 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -44,8 +44,8 @@ static const struct { Do an old lanman2 style session setup. ****************************************************************************/ -static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user, - char *pass, int passlen, const char *workgroup) +static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, + const char *pass, int passlen, const char *workgroup) { fstring pword; char *p; @@ -183,8 +183,8 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) Do a NT1 plaintext session setup. ****************************************************************************/ -static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, - char *pass, char *workgroup) +static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, + const char *pass, const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; @@ -228,7 +228,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user, return True; } -static void set_signing_on_cli (struct cli_state *cli, char* pass, uint8 response[24]) +static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 response[24]) { uint8 zero_sig[8]; ZERO_STRUCT(zero_sig); @@ -264,10 +264,10 @@ static void set_temp_signing_on_cli(struct cli_state *cli) @param workgroup The user's domain. ****************************************************************************/ -static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) +static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, + const char *pass, int passlen, + const char *ntpass, int ntpasslen, + const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); uchar pword[24]; @@ -423,7 +423,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) Do a spnego/kerberos encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, char *workgroup) +static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; @@ -453,8 +453,8 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, char *principal, c Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, - char *pass, char *workgroup) +static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, + const char *pass, const char *workgroup) { DATA_BLOB msg1, struct_blob; DATA_BLOB blob, chal1, chal2, auth, challenge_blob; @@ -581,8 +581,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user, Do a spnego encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_spnego(struct cli_state *cli, char *user, - char *pass, char *workgroup) +static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, + const char *pass, const char *workgroup) { char *principal; char *OIDs[ASN1_MAX_OIDS]; @@ -646,10 +646,10 @@ ntlmssp: ****************************************************************************/ BOOL cli_session_setup(struct cli_state *cli, - char *user, - char *pass, int passlen, - char *ntpass, int ntpasslen, - char *workgroup) + const char *user, + const char *pass, int passlen, + const char *ntpass, int ntpasslen, + const char *workgroup) { char *p; fstring user2; @@ -1130,8 +1130,8 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) Initialise client credentials for authenticated pipe access. ****************************************************************************/ -static void init_creds(struct ntuser_creds *creds, char* username, - char* domain, char* password) +static void init_creds(struct ntuser_creds *creds, const char* username, + const char* domain, const char* password) { ZERO_STRUCTP(creds); @@ -1163,9 +1163,9 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, struct in_addr *dest_ip, int port, - char *service, char *service_type, - char *user, char *domain, - char *password, int flags, + const char *service, const char *service_type, + const char *user, const char *domain, + const char *password, int flags, BOOL *retry) { struct ntuser_creds creds; @@ -1174,13 +1174,12 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct nmb_name called; struct cli_state *cli; struct in_addr ip; - extern pstring global_myname; if (retry) *retry = False; if (!my_name) - my_name = global_myname; + my_name = global_myname(); if (!(cli = cli_initialise(NULL))) return NT_STATUS_NO_MEMORY; @@ -1258,7 +1257,7 @@ again: if (service) { if (!cli_send_tconX(cli, service, service_type, - (char*)password, strlen(password)+1)) { + password, strlen(password)+1)) { DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); nt_status = cli_nt_error(cli); cli_shutdown(cli); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8fdf145625..5c3d942b90 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -471,7 +471,8 @@ BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa while(!x_feof(fp) && !x_ferror(fp)) { pstring ip,flags,extra; - char *ptr; + const char *ptr; + char *ptr1; int count = 0; *name_type = -1; @@ -524,20 +525,20 @@ BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa /* Extra feature. If the name ends in '#XX', where XX is a hex number, then only add that name type. */ - if((ptr = strchr_m(name, '#')) != NULL) + if((ptr1 = strchr_m(name, '#')) != NULL) { char *endptr; - ptr++; - *name_type = (int)strtol(ptr, &endptr, 16); + ptr1++; + *name_type = (int)strtol(ptr1, &endptr, 16); - if(!*ptr || (endptr == ptr)) + if(!*ptr1 || (endptr == ptr1)) { DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); continue; } - *(--ptr) = '\0'; /* Truncate at the '#' */ + *(--ptr1) = '\0'; /* Truncate at the '#' */ } return True; @@ -787,7 +788,7 @@ static BOOL internal_resolve_name(const char *name, int name_type, { pstring name_resolve_list; fstring tok; - char *ptr; + const char *ptr; BOOL allones = (strcmp(name,"255.255.255.255") == 0); BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); BOOL is_address = is_ipaddress(name); @@ -1242,7 +1243,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) */ if (strequal(domain, lp_workgroup())) { - char *p; + const char *p; char *pserver = lp_passwordserver(); fstring name; int num_adresses = 0; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ba0d8cee5d..43e32aebbd 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -28,14 +28,14 @@ static const struct opcode_names { char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { - {"Query", 0 }, - {"Registration", 5 }, - {"Release", 6 }, - {"WACK", 7 }, - {"Refresh", 8 }, - {"Refresh(altcode)", 9 }, - {"Multi-homed Registration", 15 }, - {0, -1 } + {"Query", 0 }, + {"Registration", 5 }, + {"Release", 6 }, + {"WACK", 7 }, + {"Refresh", 8 }, + {"Refresh(altcode)", 9 }, + {"Multi-homed Registration", 15 }, + {0, -1 } }; /**************************************************************************** @@ -814,15 +814,15 @@ static int build_dgram(char *buf,struct packet_struct *p) } /******************************************************************* - build a nmb name - *******************************************************************/ + Build a nmb name +*******************************************************************/ + void make_nmb_name( struct nmb_name *n, const char *name, int type) { - extern pstring global_scope; memset( (char *)n, '\0', sizeof(struct nmb_name) ); push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, global_scope, 63 ); + StrnCpy( n->scope, global_scope(), 63 ); strupper( n->scope ); } @@ -1180,7 +1180,6 @@ int name_mangle( char *In, char *Out, char name_type ) int len; char buf[20]; char *p = Out; - extern pstring global_scope; /* Safely copy the input string, In, into buf[]. */ (void)memset( buf, 0, 20 ); @@ -1204,9 +1203,9 @@ int name_mangle( char *In, char *Out, char name_type ) p[0] = '\0'; /* Add the scope string. */ - for( i = 0, len = 0; NULL != global_scope; i++, len++ ) + for( i = 0, len = 0; NULL != global_scope(); i++, len++ ) { - switch( global_scope[i] ) + switch( (global_scope())[i] ) { case '\0': p[0] = len; @@ -1219,7 +1218,7 @@ int name_mangle( char *In, char *Out, char name_type ) len = -1; break; default: - p[len+1] = global_scope[i]; + p[len+1] = (global_scope())[i]; break; } } diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index b96bdc95a1..41b6095520 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -20,9 +20,6 @@ #include "includes.h" - -extern pstring global_myname; - /************************************************************* change a password on a remote machine using IPC calls *************************************************************/ @@ -50,7 +47,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - make_nmb_name(&calling, global_myname , 0x0); + make_nmb_name(&calling, global_myname() , 0x0); make_nmb_name(&called , remote_machine, 0x20); if (!cli_session_request(&cli, &calling, &called)) { diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index fc0602507a..7ddcf853c4 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -41,7 +41,7 @@ static void pwd_init(struct pwd_info *pwd) Makes lm and nt hashed passwords. ****************************************************************************/ -static void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) +static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) { pstring dos_passwd; @@ -59,7 +59,7 @@ static void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr) Stores a cleartext password. ****************************************************************************/ -void pwd_set_cleartext(struct pwd_info *pwd, char *clr) +void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) { pwd_init(pwd); push_ascii_fstring(pwd->password, clr); @@ -138,13 +138,3 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) if (nt_owf != NULL) memcpy(nt_owf, pwd->smb_nt_owf, 24); } - - - - - - - - - - diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index 4d7acd1988..cf9fd58b13 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -20,8 +20,6 @@ #include "includes.h" -extern pstring global_myname; - /********************************************************* Change the domain password on the PDC. @@ -45,7 +43,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ return result; } - result = cli_net_srv_pwset(cli, mem_ctx, global_myname, new_trust_passwd_hash); + result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", @@ -99,7 +97,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx **********************************************************/ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - char *domain) + const char *domain) { unsigned char old_trust_passwd_hash[16]; char *up_domain; -- cgit From 2b41c63b61687c2c7e1503c902d54bdf31b79bf3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 13 Nov 2002 06:38:33 +0000 Subject: Try to bring libsmbclient in line with the new global_myname stuff (This used to be commit e424b08050b44b1b52abd2af76b1b4dc8b100095) --- source3/libsmb/libsmbclient.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index dd46749a5a..edf582b34d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -46,7 +46,6 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { } extern BOOL in_client; -extern pstring global_myname; /* * Is the logging working / configfile read ? @@ -2625,8 +2624,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) * We try to get our netbios name from the config. If that fails we fall * back on constructing our netbios name from our hostname etc */ - if (global_myname) { - context->netbios_name = strdup(global_myname); + if (global_myname()) { + context->netbios_name = strdup(global_myname()); } else { /* -- cgit From 098c08ccabe164492d6a91372608f5feb0de0d47 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 13 Nov 2002 07:04:00 +0000 Subject: Merge from HEAD - make configure check for the location of Heimdal KRB5 on suse systems - fix libsmbclient for new global_myname() (This used to be commit 111b0405cf8c95da5c927f31e5db7fd51c590b1f) --- source3/libsmb/libsmbclient.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index faa4191e6d..a1fb380c37 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -46,7 +46,6 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { } extern BOOL in_client; -extern pstring global_myname; /* * Is the logging working / configfile read ? @@ -2596,8 +2595,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) * We try to get our netbios name from the config. If that fails we fall * back on constructing our netbios name from our hostname etc */ - if (global_myname) { - context->netbios_name = strdup(global_myname); + if (global_myname()) { + context->netbios_name = strdup(global_myname()); } else { /* -- cgit From 53c1b22adc500e7d6f9094cba6e5cb4226079d83 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 15 Nov 2002 17:56:46 +0000 Subject: fix segfault (This used to be commit 32ca3afa5486b1b04118e9f144bfdf4b3702d118) --- source3/libsmb/clikrb5.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e7143d065d..54a8a6ffe8 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -147,7 +147,9 @@ DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) return ret; failed: - krb5_free_context(context); + if ( context ) + krb5_free_context(context); + return data_blob(NULL, 0); } -- cgit From f2e3b68ce6db8b06f5ea4c8cc969cc1b8e4d9bd9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 15 Nov 2002 17:57:25 +0000 Subject: fix segfault (This used to be commit 36bcb312e95f46d196575ed3535679deeddd89b0) --- source3/libsmb/clikrb5.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e7143d065d..54a8a6ffe8 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -147,7 +147,9 @@ DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) return ret; failed: - krb5_free_context(context); + if ( context ) + krb5_free_context(context); + return data_blob(NULL, 0); } -- cgit From e955763315700af82b23bbfd2777cbecad47f7e7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 21 Nov 2002 00:10:28 +0000 Subject: merge get_friendly_nt_err_msg() from app_head (This used to be commit 3ea73f158ebfca0561d7928e5d6c0939c0734585) --- source3/libsmb/nterr.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 02fd53fc05..73d77b728a 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -539,6 +539,35 @@ static nt_err_code_struct nt_errs[] = { NULL, NT_STATUS(0) } }; +nt_err_code_struct nt_err_desc[] = +{ + { "Success", NT_STATUS_OK }, + { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, + { "Access denied", NT_STATUS_ACCESS_DENIED }, + { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, + { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, + { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, + { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, + { "Invalid account name", NT_STATUS_INVALID_ACCOUNT_NAME }, + { "User exists", NT_STATUS_USER_EXISTS }, + { "No such user", NT_STATUS_NO_SUCH_USER }, + { "Group exists", NT_STATUS_GROUP_EXISTS }, + { "No such group", NT_STATUS_NO_SUCH_GROUP }, + { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP }, + { "Wrong Password", NT_STATUS_WRONG_PASSWORD }, + { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD }, + { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION }, + { "Logon failure", NT_STATUS_LOGON_FAILURE }, + { "Account restruction", NT_STATUS_ACCOUNT_RESTRICTION }, + { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS }, + { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, + { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, + { "Account Disabled", NT_STATUS_ACCOUNT_DISABLED }, + { NULL, NT_STATUS(0) } +}; + + /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ @@ -560,6 +589,27 @@ char *nt_errstr(NTSTATUS nt_code) return msg; } +/************************************************************************ + Print friendler version fo NT error code + ***********************************************************************/ + +char *get_friendly_nt_error_msg(NTSTATUS nt_code) +{ + int idx = 0; + + while (nt_err_desc[idx].nt_errstr != NULL) { + if (NT_STATUS_V(nt_errs[idx].nt_errcode) == NT_STATUS_V(nt_code)) + { + return nt_errs[idx].nt_errstr; + } + idx++; + } + + /* fall back to NT_STATUS_XXX string */ + + return get_nt_error_msg(nt_code); +} + /***************************************************************************** returns an NT_STATUS constant as a string for inclusion in autogen C code *****************************************************************************/ -- cgit From 8713f45a06cf242749e2ccb460d0d15c682350bb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 21 Nov 2002 00:12:14 +0000 Subject: merge get_friendly_nt_err_msg() from app_head (This used to be commit af21e7738404f073fe2e22b282322e3facdfeb82) --- source3/libsmb/nterr.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 02fd53fc05..73d77b728a 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -539,6 +539,35 @@ static nt_err_code_struct nt_errs[] = { NULL, NT_STATUS(0) } }; +nt_err_code_struct nt_err_desc[] = +{ + { "Success", NT_STATUS_OK }, + { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, + { "Access denied", NT_STATUS_ACCESS_DENIED }, + { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, + { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, + { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, + { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, + { "Invalid account name", NT_STATUS_INVALID_ACCOUNT_NAME }, + { "User exists", NT_STATUS_USER_EXISTS }, + { "No such user", NT_STATUS_NO_SUCH_USER }, + { "Group exists", NT_STATUS_GROUP_EXISTS }, + { "No such group", NT_STATUS_NO_SUCH_GROUP }, + { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP }, + { "Wrong Password", NT_STATUS_WRONG_PASSWORD }, + { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD }, + { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION }, + { "Logon failure", NT_STATUS_LOGON_FAILURE }, + { "Account restruction", NT_STATUS_ACCOUNT_RESTRICTION }, + { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS }, + { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, + { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, + { "Account Disabled", NT_STATUS_ACCOUNT_DISABLED }, + { NULL, NT_STATUS(0) } +}; + + /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ @@ -560,6 +589,27 @@ char *nt_errstr(NTSTATUS nt_code) return msg; } +/************************************************************************ + Print friendler version fo NT error code + ***********************************************************************/ + +char *get_friendly_nt_error_msg(NTSTATUS nt_code) +{ + int idx = 0; + + while (nt_err_desc[idx].nt_errstr != NULL) { + if (NT_STATUS_V(nt_errs[idx].nt_errcode) == NT_STATUS_V(nt_code)) + { + return nt_errs[idx].nt_errstr; + } + idx++; + } + + /* fall back to NT_STATUS_XXX string */ + + return get_nt_error_msg(nt_code); +} + /***************************************************************************** returns an NT_STATUS constant as a string for inclusion in autogen C code *****************************************************************************/ -- cgit From 3e1846d0deeb49589aa69ca5af58d80a31d486a2 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 21 Nov 2002 00:58:50 +0000 Subject: get_nt_error_msg from APPLIANCE_HEAD is called nt_errstr in HEAD. This should fix the build. (This used to be commit 929874d2744509bba743d99b9c707e7626845fa0) --- source3/libsmb/nterr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 73d77b728a..89ad58b26f 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -607,7 +607,7 @@ char *get_friendly_nt_error_msg(NTSTATUS nt_code) /* fall back to NT_STATUS_XXX string */ - return get_nt_error_msg(nt_code); + return nt_errstr(nt_code); } /***************************************************************************** -- cgit From 5939005588f9e0518793cd85e1e78082cb90b11d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 21 Nov 2002 01:01:58 +0000 Subject: get_nt_error_msg from APPLIANCE_HEAD is called nt_errstr in HEAD. This should fix the build. (This used to be commit a89187ccc95cc54e39518413bd4fff92c7223108) --- source3/libsmb/nterr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 73d77b728a..89ad58b26f 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -607,7 +607,7 @@ char *get_friendly_nt_error_msg(NTSTATUS nt_code) /* fall back to NT_STATUS_XXX string */ - return get_nt_error_msg(nt_code); + return nt_errstr(nt_code); } /***************************************************************************** -- cgit From de474974ea25df7738dd175126e3f1de0df47ea6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 23 Nov 2002 02:52:36 +0000 Subject: Lots of fixes for error paths where tdb_fetch() data need freeing. Found via a post from Arcady Chernyak . Jeremy. (This used to be commit 5d5762d1787db4392d2dff16024097c638b2d494) --- source3/libsmb/namecache.c | 2 ++ source3/libsmb/netlogon_unigrp.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 2252e8e59c..ce4cbc048c 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -196,6 +196,7 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, tdb_delete(namecache_tdb, key); + SAFE_FREE(value.dptr); value = tdb_null; goto done; @@ -210,6 +211,7 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, tdb_delete(namecache_tdb, key); + SAFE_FREE(value.dptr); value = tdb_null; goto done; diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index 979ff52bd3..ea9e790b7d 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -129,7 +129,8 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, /* There is no cached universal groups in netlogon_unigrp.tdb */ /* for this user. */ - if (!data.dptr) return NULL; + if (!data.dptr) + return NULL; /* Transfer data to receiver's memory context */ group_count = IVAL(&((uint32*)data.dptr)[0],0); -- cgit From f023d6129b7bf0d972f2bb9ecc025d316e55c8ae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 23 Nov 2002 02:52:38 +0000 Subject: Lots of fixes for error paths where tdb_fetch() data need freeing. Found via a post from Arcady Chernyak . Jeremy. (This used to be commit 19f86f1f72aca924e9e320e20a175b5d21de45ad) --- source3/libsmb/namecache.c | 2 ++ source3/libsmb/netlogon_unigrp.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 2252e8e59c..ce4cbc048c 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -196,6 +196,7 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, tdb_delete(namecache_tdb, key); + SAFE_FREE(value.dptr); value = tdb_null; goto done; @@ -210,6 +211,7 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, tdb_delete(namecache_tdb, key); + SAFE_FREE(value.dptr); value = tdb_null; goto done; diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index 979ff52bd3..ea9e790b7d 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -129,7 +129,8 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, /* There is no cached universal groups in netlogon_unigrp.tdb */ /* for this user. */ - if (!data.dptr) return NULL; + if (!data.dptr) + return NULL; /* Transfer data to receiver's memory context */ group_count = IVAL(&((uint32*)data.dptr)[0],0); -- cgit From 191dff2d279dd8315f093e313d8c149e786eb19f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 23 Nov 2002 14:27:56 +0000 Subject: [merge from APP_HEAD] 90% fix for CR 1076. The password server parameter will no take things like password server = DC1 * which means to contact DC1 first and the go to auto lookup if it fails. jerry (This used to be commit c31a17889e3e4daf7c1e807038efc2c0fba78be3) --- source3/libsmb/namequery.c | 126 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 5c3d942b90..6190c872ee 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1235,19 +1235,24 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) a domain. *********************************************************/ -BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) +BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered) { - /* - * If it's our domain then - * use the 'password server' parameter. - */ + + *ordered = False; + + /* If it's our domain then use the 'password server' parameter. */ if (strequal(domain, lp_workgroup())) { - const char *p; - char *pserver = lp_passwordserver(); + char *p; + char *pserver = lp_passwordserver(); /* UNIX charset. */ fstring name; - int num_adresses = 0; + int num_addresses = 0; + int local_count, i, j; struct in_addr *return_iplist = NULL; + struct in_addr *auto_ip_list = NULL; + BOOL done_auto_lookup = False; + int auto_count = 0; + if (!*pserver) return internal_resolve_name( @@ -1255,19 +1260,31 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) p = pserver; + /* + * if '*' appears in the "password server" list then add + * an auto lookup to the list of manually configured + * DC's. If any DC is listed by name, then the list should be + * considered to be ordered + */ + while (next_token(&p,name,LIST_SEP,sizeof(name))) { - if (strequal(name, "*")) - return internal_resolve_name( - domain, 0x1C, ip_list, count); - num_adresses++; + if (strequal(name, "*")) { + if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) ) + num_addresses += auto_count; + done_auto_lookup = True; + DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); + } + else + num_addresses++; } - if (num_adresses == 0) - return internal_resolve_name( - domain, 0x1C, ip_list, count); + /* if we have no addresses and haven't done the auto lookup, then + just return the list of DC's */ + + if ( (num_addresses == 0) && !done_auto_lookup ) + return internal_resolve_name(domain, 0x1C, ip_list, count); - return_iplist = (struct in_addr *)malloc( - num_adresses * sizeof(struct in_addr)); + return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr)); if (return_iplist == NULL) { DEBUG(3,("get_dc_list: malloc fail !\n")); @@ -1275,19 +1292,84 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) } p = pserver; - *count = 0; + local_count = 0; - while (next_token(&p,name,LIST_SEP,sizeof(name))) { + /* fill in the return list now with real IP's */ + + while ( (local_count Date: Sat, 23 Nov 2002 14:52:34 +0000 Subject: [merge from APP_HEAD] 90% fix for CR 1076. The password server parameter will no take things like password server = DC1 * which means to contact DC1 first and the go to auto lookup if it fails. jerry (This used to be commit 016ef8b36b30846311a5321803298f8e28719244) --- source3/libsmb/namequery.c | 126 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 104 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 5c3d942b90..6190c872ee 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1235,19 +1235,24 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) a domain. *********************************************************/ -BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) +BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int *ordered) { - /* - * If it's our domain then - * use the 'password server' parameter. - */ + + *ordered = False; + + /* If it's our domain then use the 'password server' parameter. */ if (strequal(domain, lp_workgroup())) { - const char *p; - char *pserver = lp_passwordserver(); + char *p; + char *pserver = lp_passwordserver(); /* UNIX charset. */ fstring name; - int num_adresses = 0; + int num_addresses = 0; + int local_count, i, j; struct in_addr *return_iplist = NULL; + struct in_addr *auto_ip_list = NULL; + BOOL done_auto_lookup = False; + int auto_count = 0; + if (!*pserver) return internal_resolve_name( @@ -1255,19 +1260,31 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) p = pserver; + /* + * if '*' appears in the "password server" list then add + * an auto lookup to the list of manually configured + * DC's. If any DC is listed by name, then the list should be + * considered to be ordered + */ + while (next_token(&p,name,LIST_SEP,sizeof(name))) { - if (strequal(name, "*")) - return internal_resolve_name( - domain, 0x1C, ip_list, count); - num_adresses++; + if (strequal(name, "*")) { + if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count) ) + num_addresses += auto_count; + done_auto_lookup = True; + DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); + } + else + num_addresses++; } - if (num_adresses == 0) - return internal_resolve_name( - domain, 0x1C, ip_list, count); + /* if we have no addresses and haven't done the auto lookup, then + just return the list of DC's */ + + if ( (num_addresses == 0) && !done_auto_lookup ) + return internal_resolve_name(domain, 0x1C, ip_list, count); - return_iplist = (struct in_addr *)malloc( - num_adresses * sizeof(struct in_addr)); + return_iplist = (struct in_addr *)malloc(num_addresses * sizeof(struct in_addr)); if (return_iplist == NULL) { DEBUG(3,("get_dc_list: malloc fail !\n")); @@ -1275,19 +1292,84 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count) } p = pserver; - *count = 0; + local_count = 0; - while (next_token(&p,name,LIST_SEP,sizeof(name))) { + /* fill in the return list now with real IP's */ + + while ( (local_count Date: Tue, 26 Nov 2002 11:57:30 +0000 Subject: Having waited for *way* too long, this is mimir's namecache and trusted domain cache code. This uses gencache, mimir's new caching code that stores at text-based cache of various data. Mimir has done a *lot* of work on this patch, and it is finally time to get it in CVS. Andrew Bartlett (This used to be commit 47f3bfe9564e7f3aff60cefaefd599e0abb30a31) --- source3/libsmb/namecache.c | 325 +++++++++++++++++++--------------------- source3/libsmb/namequery.c | 10 +- source3/libsmb/trustdom_cache.c | 215 ++++++++++++++++++++++++++ 3 files changed, 372 insertions(+), 178 deletions(-) create mode 100644 source3/libsmb/trustdom_cache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index ce4cbc048c..40777011a1 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -1,9 +1,10 @@ /* Unix SMB/CIFS implementation. - NetBIOS name cache module. - - Copyright (C) Tim Potter, 2002 + NetBIOS name cache module on top of gencache mechanism. + + Copyright (C) Tim Potter 2002 + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,244 +23,224 @@ #include "includes.h" -static BOOL done_namecache_init; -static BOOL enable_namecache; -static TDB_CONTEXT *namecache_tdb; +#define NBTKEY_FMT "NBT/%s#%02X" -struct nc_value { - time_t expiry; /* When entry expires */ - int count; /* Number of addresses */ - struct in_addr ip_list[1]; /* Address list */ -}; -/* Initialise namecache system */ +/** + * Initialise namecache system. Function calls gencache + * initialisation function to perform necessary actions + * + * @return true upon successful initialisation of the cache or + * false on failure + **/ BOOL namecache_enable(void) { - /* Check if we have been here before, or name caching disabled - by setting the name cache timeout to zero. */ - - if (done_namecache_init) - return False; - - done_namecache_init = True; + /* + * Check if name caching disabled by setting the name cache + * timeout to zero. + */ if (lp_name_cache_timeout() == 0) { - DEBUG(5, ("namecache_init: disabling netbios name cache\n")); + DEBUG(5, ("namecache_enable: disabling netbios name cache\n")); return False; } - /* Open namecache tdb in read/write or readonly mode */ + /* Init namecache by calling gencache initialisation */ - namecache_tdb = tdb_open_log( - lock_path("namecache.tdb"), 0, - TDB_DEFAULT, O_RDWR | O_CREAT, 0644); - - if (!namecache_tdb) { - DEBUG(5, ("namecache_init: could not open %s\n", - lock_path("namecache.tdb"))); + if (!gencache_init()) { + DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n")); return False; } - DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d " + /* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */ + DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d " "seconds\n", lp_name_cache_timeout())); - enable_namecache = True; - return True; } -/* Return a key for a name and name type. The caller must free - retval.dptr when finished. */ -static TDB_DATA namecache_key(const char *name, int name_type) +/** + * Shutdown namecache. Routine calls gencache close function + * to safely close gencache file. + * + * @return true upon successful shutdown of the cache or + * false on failure + **/ + +BOOL namecache_shutdown(void) { - TDB_DATA retval; - char *keystr; - - asprintf(&keystr, "%s#%02X", strupper_static(name), name_type); - - retval.dsize = strlen(keystr) + 1; - retval.dptr = keystr; - - return retval; + if (!gencache_shutdown()) { + DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n")); + return False; + } + + DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n")); + return True; } -/* Return a data value for an IP list. The caller must free - retval.dptr when finished. */ - -static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, - time_t expiry) -{ - TDB_DATA retval; - struct nc_value *value; - int size = sizeof(struct nc_value); - if (num_names > 0) - size += sizeof(struct in_addr) * (num_names-1); +/** + * Generates a key for netbios name lookups on basis of + * netbios name and type. + * The caller must free returned key string when finished. + * + * @param name netbios name string (case insensitive) + * @param name_type netbios type of the name being looked up + * + * @return string consisted of uppercased name and appended + * type number + */ - value = (struct nc_value *)malloc(size); - - memset(value, 0, size); - - value->expiry = expiry; - value->count = num_names; - - if (ip_list) - memcpy(value->ip_list, ip_list, sizeof(struct in_addr) * num_names); - - retval.dptr = (char *)value; - retval.dsize = size; +static char* namecache_key(const char *name, int name_type) +{ + char *keystr; + asprintf(&keystr, NBTKEY_FMT, strupper_static(name), name_type); - return retval; + return keystr; } -/* Store a name in the name cache */ -void namecache_store(const char *name, int name_type, - int num_names, struct in_addr *ip_list) +/** + * Store a name(s) in the name cache + * + * @param name netbios names array + * @param name_type integer netbios name type + * @param num_names number of names being stored + * @param ip_list array of in_addr structures containing + * ip addresses being stored + **/ + +BOOL namecache_store(const char *name, int name_type, + int num_names, struct in_addr *ip_list) { - TDB_DATA key, value; time_t expiry; + char *key, *value_string; int i; - if (!enable_namecache) - return; + /* + * we use gecache call to avoid annoying debug messages about + * initialised namecache again and again... + */ + if (!gencache_init()) return False; DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", - num_names, num_names == 1 ? "": "es", name, name_type)); + num_names, num_names == 1 ? "": "es", name, name_type)); for (i = 0; i < num_names; i++) DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]), - i == (num_names - 1) ? "" : ", ")); + i == (num_names - 1) ? "" : ", ")); DEBUGADD(5, ("\n")); key = namecache_key(name, name_type); - /* Cache pdc location or dc lists for only a little while - otherwise if we lock on to a bad DC we can potentially be - out of action for the entire cache timeout time! */ + /* + * Cache pdc location or dc lists for only a little while + * otherwise if we lock on to a bad DC we can potentially be + * out of action for the entire cache timeout time! + */ - if (name_type != 0x1b || name_type != 0x1c) + if (name_type == 0x1b || name_type == 0x1c) expiry = time(NULL) + 10; else expiry = time(NULL) + lp_name_cache_timeout(); - value = namecache_value(ip_list, num_names, expiry); - - tdb_store(namecache_tdb, key, value, TDB_REPLACE); - - free(key.dptr); - free(value.dptr); + /* + * Generate string representation of ip addresses list + * First, store the number of ip addresses and then + * place each single ip + */ + ipstr_list_make(&value_string, ip_list, num_names); + + /* set the entry */ + return (gencache_set(key, value_string, expiry)); } -/* Look up a name in the name cache. Return a mallocated list of IP - addresses if the name is contained in the cache. */ + +/** + * Look up a name in the cache. + * + * @param name netbios name to look up for + * @param name_type netbios name type of @param name + * @param ip_list mallocated list of IP addresses if found in the cache, + * NULL otherwise + * @param num_names number of entries found + * + * @return true upon successful fetch or + * false if name isn't found in the cache or has expired + **/ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, - int *num_names) + int *num_names) { - TDB_DATA key, value; - struct nc_value *data; - time_t now; - int i; + char *key, *value; + time_t timeout; - *ip_list = NULL; *num_names = 0; - if (!enable_namecache) - return False; + /* exit now if null pointers were passed as they're required further */ + if (!ip_list || !num_names) return False; - /* Read value */ + if (!gencache_init()) + return False; + /* + * Use gencache interface - lookup the key + */ key = namecache_key(name, name_type); - value = tdb_fetch(namecache_tdb, key); - - if (!value.dptr) { - DEBUG(5, ("namecache_fetch: %s#%02x not found\n", - name, name_type)); - goto done; - } - - data = (struct nc_value *)value.dptr; - - /* Check expiry time */ - - now = time(NULL); - - if (now > data->expiry) { - - DEBUG(5, ("namecache_fetch: entry for %s#%02x expired\n", - name, name_type)); - - tdb_delete(namecache_tdb, key); - - SAFE_FREE(value.dptr); - value = tdb_null; - - goto done; - } - - if ((data->expiry - now) > lp_name_cache_timeout()) { - - /* Someone may have changed the system time on us */ - - DEBUG(5, ("namecache_fetch: entry for %s#%02x has bad expiry\n", - name, name_type)); - - tdb_delete(namecache_tdb, key); - - SAFE_FREE(value.dptr); - value = tdb_null; - - goto done; - } - - /* Extract and return namelist */ - - DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", - data->count, data->count == 1 ? "" : "es", name, name_type)); - - if (data->count) { - - *ip_list = (struct in_addr *)malloc( - sizeof(struct in_addr) * data->count); - - memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * data->count); - - *num_names = data->count; - - for (i = 0; i < *num_names; i++) - DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), - i == (*num_names - 1) ? "" : ", ")); - + if (!gencache_get(key, &value, &timeout)) { + DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); + SAFE_FREE(key); + return False; + } else { + DEBUG(5, ("name %s#%02X found.\n", name, name_type)); } + + /* + * Split up the stored value into the list of IP adresses + */ + *num_names = ipstr_list_parse(value, ip_list); + + SAFE_FREE(key); + SAFE_FREE(value); + return *num_names > 0; /* true only if some ip has been fetched */ +} - DEBUGADD(5, ("\n")); -done: - SAFE_FREE(key.dptr); - SAFE_FREE(value.dptr); +/** + * Delete single namecache entry. Look at the + * gencache_iterate definition. + * + **/ - return value.dsize > 0; +static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr) +{ + gencache_del(key); + DEBUG(5, ("Deleting entry %s\n", key)); } -/* Flush all names from the name cache */ + +/** + * Flush all names from the name cache. + * It's done by gencache_iterate() + * + * @return True upon successful deletion or + * False in case of an error + **/ void namecache_flush(void) { - int result; - - if (!namecache_tdb) + if (!gencache_init()) return; - result = tdb_traverse(namecache_tdb, tdb_traverse_delete_fn, NULL); - - if (result == -1) - DEBUG(5, ("namecache_flush: error deleting cache entries\n")); - else - DEBUG(5, ("namecache_flush: deleted %d cache entr%s\n", - result, result == 1 ? "y" : "ies")); + /* + * iterate through each NBT cache's entry and flush it + * by flush_netbios_name function + */ + gencache_iterate(flush_netbios_name, NULL, "NBT/*"); + DEBUG(5, ("Namecache flushed\n")); } + diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6190c872ee..1c5af8bff0 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -837,11 +837,6 @@ static BOOL internal_resolve_name(const char *name, int name_type, if (resolve_hosts(name, return_iplist, return_count)) { result = True; goto done; - } else { - - /* Store negative lookup result */ - - namecache_store(name, name_type, 0, NULL); } } } else if(strequal( tok, "lmhosts")) { @@ -916,7 +911,10 @@ static BOOL internal_resolve_name(const char *name, int name_type, } /* Save in name cache */ - + for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) + DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name, + name_type, inet_ntoa(*return_iplist[i]))); + namecache_store(name, name_type, *return_count, *return_iplist); /* Display some debugging info */ diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c new file mode 100644 index 0000000000..cddbb2daa6 --- /dev/null +++ b/source3/libsmb/trustdom_cache.c @@ -0,0 +1,215 @@ +/* + Unix SMB/CIFS implementation. + + Trusted domain names cache on top of gencache. + + Copyright (C) Rafal Szczesniak 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_ALL /* there's no proper class yet */ + +#define TDOMKEY_FMT "TDOM/%s" + + +/** + * @file trustdom_cache.c + * + * Implementation of trusted domain names cache useful when + * samba acts as domain member server. In such case, caching + * domain names currently trusted gives a performance gain + * because there's no need to query PDC each time we need + * list of trusted domains + **/ + + +/** + * Initialise trustdom name caching system. Call gencache + * initialisation routine to perform necessary activities. + * + * @return true upon successful cache initialisation or + * false if cache init failed + **/ + +BOOL trustdom_cache_enable(void) +{ + /* Init trustdom cache by calling gencache initialisation */ + if (!gencache_init()) { + DEBUG(2, ("trustdomcache_enable: Couldn't initialise trustdom cache on top of gencache.\n")); + return False; + } + + return True; +} + + +/** + * Shutdown trustdom name caching system. Calls gencache + * shutdown function. + * + * @return true upon successful cache close or + * false if it failed + **/ + +BOOL trustdom_cache_shutdown(void) +{ + /* Close trustdom cache by calling gencache shutdown */ + if (!gencache_shutdown()) { + DEBUG(2, ("trustdomcache_shutdown: Couldn't shutdown trustdom cache on top of gencache.\n")); + return False; + } + + return True; +} + + +/** + * Form up trustdom name key. It is based only + * on domain name now. + * + * @param name trusted domain name + * @return cache key for use in gencache mechanism + **/ + +static char* trustdom_cache_key(const char* name) +{ + char* keystr; + asprintf(&keystr, TDOMKEY_FMT, strupper_static(name)); + + return keystr; +} + + +/** + * Store trusted domain in gencache as the domain name (key) + * and ip address of domain controller (value) + * + * @param name trusted domain name + * @param alt_name alternative trusted domain name (used in ADS domains) + * @param sid trusted domain's SID + * @param timeout cache entry expiration time + * @return true upon successful value storing or + * false if store attempt failed + **/ + +BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, + time_t timeout) +{ + char *key, *alt_key; + fstring sid_string; + + /* + * we use gecache call to avoid annoying debug messages + * about initialised trustdom + */ + if (!gencache_init()) return False; + + DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n", + sid_string_static(sid), name)); + + key = trustdom_cache_key(name); + alt_key = alt_name ? trustdom_cache_key(alt_name) : NULL; + + /* Generate string representation domain SID */ + sid_to_string(sid_string, sid); + + /* + * try to put the names in the cache + */ + if (alt_key) { + return (gencache_set(alt_key, sid_string, timeout) + && gencache_set(key, sid_string, timeout)); + } + + return gencache_set(key, sid_string, timeout); +} + + +/** + * Fetch trusted domain's dc from the gencache. + * This routine can also be used to check whether given + * domain is currently trusted one. + * + * @param name trusted domain name + * @param sid trusted domain's SID to be returned + * @return true if entry is found or + * false if has expired/doesn't exist + **/ + +BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) +{ + char *key, *value; + time_t timeout; + + /* init the cache */ + if (!gencache_init()) return False; + + /* exit now if null pointers were passed as they're required further */ + if (!sid) return False; + + /* prepare a key and get the value */ + key = trustdom_cache_key(name); + + if (!gencache_get(key, &value, &timeout)) { + DEBUG(5, ("no entry for trusted domain %s found.\n", name)); + return False; + } else { + DEBUG(5, ("trusted domain %s found (%s)\n", name, value)); + } + + /* convert ip string representation into in_addr structure */ + if(! string_to_sid(sid, value)) { + sid = NULL; + return False; + } + + return True; +} + + +/** + * Delete single trustdom entry. Look at the + * gencache_iterate definition. + * + **/ + +static void flush_trustdom_name(const char* key, const char *value, time_t timeout, void* dptr) +{ + gencache_del(key); + DEBUG(5, ("Deleting entry %s\n", key)); +} + + +/** + * Flush all the trusted domains entries from the cache. + **/ + +void trustdom_cache_flush(void) +{ + if (!gencache_init()) + return; + + /* + * iterate through each TDOM cache's entry and flush it + * by flush_trustdom_name function + */ + gencache_iterate(flush_trustdom_name, NULL, trustdom_cache_key("*")); + DEBUG(5, ("Trusted domains cache flushed\n")); +} + -- cgit From 44c8c165462ee0a5e7050893c5379638691708cd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 26 Nov 2002 17:03:16 +0000 Subject: Fix bug in tdb_fetch tidyup. Jeremy. (This used to be commit 88d081e06428f02bcde8ceed8d86835c9222c3a9) --- source3/libsmb/namecache.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index ce4cbc048c..4304197a26 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -196,7 +196,6 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, tdb_delete(namecache_tdb, key); - SAFE_FREE(value.dptr); value = tdb_null; goto done; @@ -211,7 +210,6 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, tdb_delete(namecache_tdb, key); - SAFE_FREE(value.dptr); value = tdb_null; goto done; @@ -241,7 +239,7 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, done: SAFE_FREE(key.dptr); - SAFE_FREE(value.dptr); + SAFE_FREE(data); return value.dsize > 0; } -- cgit From edc4c1f643023b4c980a0b4518512e2cbeadce0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 26 Nov 2002 17:40:25 +0000 Subject: Ensure data is not used uninitialised. Jeremy. (This used to be commit 3c2d396aa8d674970b2cc043fd32d2648fcd004e) --- source3/libsmb/namecache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 4304197a26..724e0237d2 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -161,7 +161,7 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, int *num_names) { TDB_DATA key, value; - struct nc_value *data; + struct nc_value *data = NULL; time_t now; int i; -- cgit From e65e16fdf60819a45d03862579e69be3b11d9118 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Nov 2002 19:09:48 +0000 Subject: Test was reversed for ERRmoredata in cli_read. Jeremy. (This used to be commit 1a36ac60bef8de5368860478c268ba1671bb4825) --- source3/libsmb/clireadwrite.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 875df11dca..38e8aac42a 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -84,6 +84,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ errors. */ if (cli_is_error(cli)) { + BOOL recoverable_error = False; NTSTATUS status = NT_STATUS_OK; uint8 eclass = 0; uint32 ecode = 0; @@ -93,8 +94,17 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ else cli_dos_error(cli, &eclass, &ecode); + /* + * ERRDOS ERRmoredata or STATUS_MORE_ENRTIES is a + * recoverable error, plus we have valid data in the + * packet so don't error out here. + */ + if ((eclass == ERRDOS && ecode == ERRmoredata) || NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES)) + recoverable_error = True; + + if (!recoverable_error) return -1; } -- cgit From 296c93923c643fbbf1720af2f647f29aea708bd5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Nov 2002 19:11:46 +0000 Subject: Test was reversed for ERRmoredata in cli_read. Jeremy. (This used to be commit fff7f3cbe248982bcd70abb1da6624186bab42d2) --- source3/libsmb/clireadwrite.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 875df11dca..38e8aac42a 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -84,6 +84,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ errors. */ if (cli_is_error(cli)) { + BOOL recoverable_error = False; NTSTATUS status = NT_STATUS_OK; uint8 eclass = 0; uint32 ecode = 0; @@ -93,8 +94,17 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ else cli_dos_error(cli, &eclass, &ecode); + /* + * ERRDOS ERRmoredata or STATUS_MORE_ENRTIES is a + * recoverable error, plus we have valid data in the + * packet so don't error out here. + */ + if ((eclass == ERRDOS && ecode == ERRmoredata) || NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES)) + recoverable_error = True; + + if (!recoverable_error) return -1; } -- cgit From f3e3a56ea9085b186af24b0b4e911863fd9ceacc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 29 Nov 2002 02:58:59 +0000 Subject: Merge a bunch of trivial changes from HEAD. The difference remaining should actual functional differences between HEAD and 3.0. - Mostly reformatting - Removal of unecessary #include "smb.h" - Merge of dyn_DRIVERFILE removal - Silly bug fix for python code (This used to be commit d3998307adc50ba50defe610cb656c73799ae3b9) --- source3/libsmb/errormap.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index f310399616..7c28c7e8aa 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1484,7 +1484,6 @@ WERROR ntstatus_to_werror(NTSTATUS error) return W_ERROR(NT_STATUS_V(error) & 0xffff); } - /* Mapping between Unix, DOS and NT error numbers */ const struct unix_error_map unix_dos_nt_errmap[] = { -- cgit From d047db2807f8b8174cbb1cca9a835176056183cf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 1 Dec 2002 00:45:07 +0000 Subject: Fixup of ordered cleanup of get_dc_list - bug found by Dominik 'Aeneas' Schnitzer Jeremy. (This used to be commit 15185ac437a6a0f53711bef035879173dbb492c6) --- source3/libsmb/namequery.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6190c872ee..e6fe88f203 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1296,8 +1296,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * /* fill in the return list now with real IP's */ - while ( (local_count Date: Sun, 1 Dec 2002 00:46:50 +0000 Subject: Fixup of ordered cleanup of get_dc_list - bug found by Dominik 'Aeneas' Schnitzer Jeremy. (This used to be commit 7ba051a830a7dc96e3860a87643a3ac99cdf5836) --- source3/libsmb/namequery.c | 37 ++++++++++--------------------------- 1 file changed, 10 insertions(+), 27 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1c5af8bff0..6a59b73db2 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1294,8 +1294,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * /* fill in the return list now with real IP's */ - while ( (local_count Date: Sun, 1 Dec 2002 03:12:50 +0000 Subject: Dereference the correct thing here, so we don't segfault (This used to be commit ea18d02036b4e0502e5ecb057c9fe381709a07d8) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6a59b73db2..c781e98365 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -913,7 +913,7 @@ static BOOL internal_resolve_name(const char *name, int name_type, /* Save in name cache */ for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name, - name_type, inet_ntoa(*return_iplist[i]))); + name_type, inet_ntoa((*return_iplist)[i]))); namecache_store(name, name_type, *return_count, *return_iplist); -- cgit From db9686ff893c5a47249610e494a6bfad1168caf2 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 3 Dec 2002 20:00:31 +0000 Subject: use the new IVAL_TO_SMB_OFF_T for file_info size member dir now shows correct size on large files (This used to be commit ce7d421ba9cfa65e3ed404f18e8b3b4cf4730593) --- source3/libsmb/clilist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3eacc25380..1616d46bf1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -48,7 +48,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); + finfo->size = IVAL_TO_SMB_OFF_T(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); p += 27; @@ -69,7 +69,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); + finfo->size = IVAL_TO_SMB_OFF_T(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; @@ -104,7 +104,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = interpret_long_date(p); p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL(p,0); p += 8; + finfo->size = IVAL_TO_SMB_OFF_T(p,0); p += 8; p += 8; /* alloc size */ finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; @@ -322,7 +322,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /* this date is converted to GMT by make_unix_date */ finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; - finfo->size = IVAL(p,26); + finfo->size = IVAL_TO_SMB_OFF_T(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); -- cgit From e217ba0a701d668cc366c2d6f065094861ba0c36 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 3 Dec 2002 20:02:18 +0000 Subject: use the new IVAL_TO_SMB_OFF_T for file_info size member dir now shows correct size on large files (This used to be commit 172dccf55e972d4cc40b7e34ce433d49e738fba0) --- source3/libsmb/clilist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3eacc25380..1616d46bf1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -48,7 +48,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); + finfo->size = IVAL_TO_SMB_OFF_T(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); p += 27; @@ -69,7 +69,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); + finfo->size = IVAL_TO_SMB_OFF_T(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; @@ -104,7 +104,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = interpret_long_date(p); p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL(p,0); p += 8; + finfo->size = IVAL_TO_SMB_OFF_T(p,0); p += 8; p += 8; /* alloc size */ finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; @@ -322,7 +322,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /* this date is converted to GMT by make_unix_date */ finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; - finfo->size = IVAL(p,26); + finfo->size = IVAL_TO_SMB_OFF_T(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); -- cgit From 0694e965fbf75184a78ba8745b19b569e1ffe918 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Dec 2002 18:39:50 +0000 Subject: Doing janitorial duty for tpot - memory leak fix. Jeremy. (This used to be commit 7acf9594210f024e8d0c34259fcc990c6c76c838) --- source3/libsmb/namequery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e6fe88f203..98d9661567 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1316,6 +1316,8 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * } + SAFE_FREE(auto_ip_list); + /* need to remove duplicates in the list if we have any explicit password servers */ -- cgit From 64c967919145209a81863b425d3b66b636283c0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Dec 2002 18:40:01 +0000 Subject: Doing janitorial duty for tpot - memory leak fix. Jeremy. (This used to be commit c6da50def80e64226c7e5b310dce30d0490512cb) --- source3/libsmb/namequery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c781e98365..7aaa7d5908 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1314,6 +1314,8 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * } + SAFE_FREE(auto_ip_list); + /* need to remove duplicates in the list if we have any explicit password servers */ -- cgit From c73c3e1daa9449eb6abab182b2d41bb945ada8c9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 4 Dec 2002 19:00:29 +0000 Subject: [merge] remove assert(count ==1) for multi-homed PDCs; CR 1277 (This used to be commit 157b5ab198670c6999f22d6b49072fdebc84be0d) --- source3/libsmb/namequery.c | 204 +++++---------------------------------------- 1 file changed, 22 insertions(+), 182 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7aaa7d5908..f446453b9a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1001,7 +1001,6 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) BOOL lookup_dc_name(const char *srcname, const char *domain, struct in_addr *dc_ip, char *ret_name) { -#if !defined(I_HATE_WINDOWS_REPLY_CODE) fstring dc_name; BOOL ret; @@ -1025,184 +1024,6 @@ BOOL lookup_dc_name(const char *srcname, const char *domain, } return False; - -#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */ - -JRA - This code is broken with BDC rollover - we need to do a full -NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... - - int retries = 3; - int retry_time = 2000; - struct timeval tval; - struct packet_struct p; - struct dgram_packet *dgram = &p.packet.dgram; - char *ptr,*p2; - char tmp[4]; - int len; - struct sockaddr_in sock_name; - int sock_len = sizeof(sock_name); - const char *mailslot = NET_LOGON_MAILSLOT; - char *mailslot_name; - char buffer[1024]; - char *bufp; - int dgm_id = generate_trn_id(); - int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); - - if(sock == -1) - return False; - - /* Find out the transient UDP port we have been allocated. */ - if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) { - DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n", - strerror(errno))); - close(sock); - return False; - } - - /* - * Create the request data. - */ - - memset(buffer,'\0',sizeof(buffer)); - bufp = buffer; - SSVAL(bufp,0,QUERYFORPDC); - bufp += 2; - fstrcpy(bufp,srcname); - bufp += (strlen(bufp) + 1); - slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id); - mailslot_name = bufp; - bufp += (strlen(bufp) + 1); - bufp = ALIGN2(bufp, buffer); - bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE); - - SIVAL(bufp,0,1); - SSVAL(bufp,4,0xFFFF); - SSVAL(bufp,6,0xFFFF); - bufp += 8; - len = PTR_DIFF(bufp,buffer); - - memset((char *)&p,'\0',sizeof(p)); - - /* DIRECT GROUP or UNIQUE datagram. */ - dgram->header.msg_type = 0x10; - dgram->header.flags.node_type = M_NODE; - dgram->header.flags.first = True; - dgram->header.flags.more = False; - dgram->header.dgm_id = dgm_id; - dgram->header.source_ip = *iface_ip(*pdc_ip); - dgram->header.source_port = ntohs(sock_name.sin_port); - dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ - dgram->header.packet_offset = 0; - - make_nmb_name(&dgram->source_name,srcname,0); - make_nmb_name(&dgram->dest_name,domain,0x1C); - - ptr = &dgram->data[0]; - - /* Setup the smb part. */ - ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ - memcpy(tmp,ptr,4); - set_message(ptr,17,17 + len,True); - memcpy(ptr,tmp,4); - - CVAL(ptr,smb_com) = SMBtrans; - SSVAL(ptr,smb_vwv1,len); - SSVAL(ptr,smb_vwv11,len); - SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); - SSVAL(ptr,smb_vwv13,3); - SSVAL(ptr,smb_vwv14,1); - SSVAL(ptr,smb_vwv15,1); - SSVAL(ptr,smb_vwv16,2); - p2 = smb_buf(ptr); - pstrcpy(p2,mailslot); - p2 = skip_string(p2,1); - - memcpy(p2,buffer,len); - p2 += len; - - dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ - - p.ip = *pdc_ip; - p.port = DGRAM_PORT; - p.fd = sock; - p.timestamp = time(NULL); - p.packet_type = DGRAM_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) { - DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); - close(sock); - return False; - } - - retries--; - - while (1) { - struct timeval tval2; - struct packet_struct *p_ret; - - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!send_packet(&p)) { - DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); - close(sock); - return False; - } - GetTimeOfDay(&tval); - retries--; - } - - if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) { - struct dgram_packet *dgram2 = &p_ret->packet.dgram; - char *buf; - char *buf2; - - buf = &dgram2->data[0]; - buf -= 4; - - if (CVAL(buf,smb_com) != SMBtrans) { - DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int) - CVAL(buf,smb_com), (unsigned int)SMBtrans )); - free_packet(p_ret); - continue; - } - - len = SVAL(buf,smb_vwv11); - buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); - - if (len <= 0) { - DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len )); - free_packet(p_ret); - continue; - } - - DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n", - nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name), - inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len)); - - if(SVAL(buf2,0) != QUERYFORPDC_R) { - DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", - (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R )); - free_packet(p_ret); - continue; - } - - buf2 += 2; - /* Note this is safe as it is a bounded strcpy. */ - fstrcpy(ret_name, buf2); - ret_name[sizeof(fstring)-1] = '\0'; - close(sock); - free_packet(p_ret); - return True; - } - } - - close(sock); - return False; -#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ } /******************************************************** @@ -1214,15 +1035,34 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) { struct in_addr *ip_list; int count; + int i = 0; /* Look up #1B name */ if (!internal_resolve_name(domain, 0x1b, &ip_list, &count)) return False; - SMB_ASSERT(count == 1); + /* if we get more than 1 IP back we have to assume it is a + multi-homed PDC and not a mess up */ + + if ( count > 1 ) { + DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count)); + + /* look for a local net */ + for ( i=0; i Date: Wed, 4 Dec 2002 19:01:01 +0000 Subject: [merge] remove assert(count ==1) for multi-homed PDCs; CR 1277 (This used to be commit 18799c115b05d6662350509f6662dbfceb4b71f5) --- source3/libsmb/namequery.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 98d9661567..0f81ff3eab 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1216,15 +1216,34 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) { struct in_addr *ip_list; int count; + int i = 0; /* Look up #1B name */ if (!internal_resolve_name(domain, 0x1b, &ip_list, &count)) return False; - SMB_ASSERT(count == 1); + /* if we get more than 1 IP back we have to assume it is a + multi-homed PDC and not a mess up */ + + if ( count > 1 ) { + DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count)); + + /* look for a local net */ + for ( i=0; i Date: Wed, 4 Dec 2002 19:03:17 +0000 Subject: cleaning up some friendly error messages (This used to be commit 0f963685d9da1cd68cf922372c8ddaa769880f27) --- source3/libsmb/nterr.c | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 89ad58b26f..4bb21efaa7 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -542,28 +542,32 @@ static nt_err_code_struct nt_errs[] = nt_err_code_struct nt_err_desc[] = { { "Success", NT_STATUS_OK }, - { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, - { "Access denied", NT_STATUS_ACCESS_DENIED }, - { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, - { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, - { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, - { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, - { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, - { "Invalid account name", NT_STATUS_INVALID_ACCOUNT_NAME }, - { "User exists", NT_STATUS_USER_EXISTS }, - { "No such user", NT_STATUS_NO_SUCH_USER }, - { "Group exists", NT_STATUS_GROUP_EXISTS }, - { "No such group", NT_STATUS_NO_SUCH_GROUP }, - { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP }, - { "Wrong Password", NT_STATUS_WRONG_PASSWORD }, - { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD }, - { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION }, - { "Logon failure", NT_STATUS_LOGON_FAILURE }, - { "Account restruction", NT_STATUS_ACCOUNT_RESTRICTION }, - { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS }, - { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, - { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, - { "Account Disabled", NT_STATUS_ACCOUNT_DISABLED }, + { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, + { "Access denied", NT_STATUS_ACCESS_DENIED }, + { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, + { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, + { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, + { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, + { "Improperly formed account name", NT_STATUS_INVALID_ACCOUNT_NAME }, + { "User exists", NT_STATUS_USER_EXISTS }, + { "No such user", NT_STATUS_NO_SUCH_USER }, + { "Group exists", NT_STATUS_GROUP_EXISTS }, + { "No such group", NT_STATUS_NO_SUCH_GROUP }, + { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP }, + { "Wrong Password", NT_STATUS_WRONG_PASSWORD }, + { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD }, + { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION }, + { "Logon failure", NT_STATUS_LOGON_FAILURE }, + { "Account restriction", NT_STATUS_ACCOUNT_RESTRICTION }, + { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS }, + { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, + { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, + { "Account disabled", NT_STATUS_ACCOUNT_DISABLED }, + { "Unexpected information received", NT_STATUS_INVALID_PARAMETER }, + { "Memory allocation error", NT_STATUS_NO_MEMORY }, + { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, + { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, { NULL, NT_STATUS(0) } }; -- cgit From 2aaf0ea146b5b5dbe8b52efaaa806e6a3c9f8f0b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 4 Dec 2002 19:03:32 +0000 Subject: cleaning up some friendly error messages (This used to be commit f978387e789eeaf9b53a21231d4cdc7cf3ea6db3) --- source3/libsmb/nterr.c | 48 ++++++++++++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 89ad58b26f..4bb21efaa7 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -542,28 +542,32 @@ static nt_err_code_struct nt_errs[] = nt_err_code_struct nt_err_desc[] = { { "Success", NT_STATUS_OK }, - { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, - { "Access denied", NT_STATUS_ACCESS_DENIED }, - { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, - { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, - { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, - { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, - { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, - { "Invalid account name", NT_STATUS_INVALID_ACCOUNT_NAME }, - { "User exists", NT_STATUS_USER_EXISTS }, - { "No such user", NT_STATUS_NO_SUCH_USER }, - { "Group exists", NT_STATUS_GROUP_EXISTS }, - { "No such group", NT_STATUS_NO_SUCH_GROUP }, - { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP }, - { "Wrong Password", NT_STATUS_WRONG_PASSWORD }, - { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD }, - { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION }, - { "Logon failure", NT_STATUS_LOGON_FAILURE }, - { "Account restruction", NT_STATUS_ACCOUNT_RESTRICTION }, - { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS }, - { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, - { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, - { "Account Disabled", NT_STATUS_ACCOUNT_DISABLED }, + { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, + { "Access denied", NT_STATUS_ACCESS_DENIED }, + { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, + { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, + { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, + { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, + { "Improperly formed account name", NT_STATUS_INVALID_ACCOUNT_NAME }, + { "User exists", NT_STATUS_USER_EXISTS }, + { "No such user", NT_STATUS_NO_SUCH_USER }, + { "Group exists", NT_STATUS_GROUP_EXISTS }, + { "No such group", NT_STATUS_NO_SUCH_GROUP }, + { "Member not in group", NT_STATUS_MEMBER_NOT_IN_GROUP }, + { "Wrong Password", NT_STATUS_WRONG_PASSWORD }, + { "Ill formed password", NT_STATUS_ILL_FORMED_PASSWORD }, + { "Password restriction", NT_STATUS_PASSWORD_RESTRICTION }, + { "Logon failure", NT_STATUS_LOGON_FAILURE }, + { "Account restriction", NT_STATUS_ACCOUNT_RESTRICTION }, + { "Invalid logon hours", NT_STATUS_INVALID_LOGON_HOURS }, + { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, + { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, + { "Account disabled", NT_STATUS_ACCOUNT_DISABLED }, + { "Unexpected information received", NT_STATUS_INVALID_PARAMETER }, + { "Memory allocation error", NT_STATUS_NO_MEMORY }, + { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, + { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, { NULL, NT_STATUS(0) } }; -- cgit From 8c13b09b9d8dc8f4d7d3515f35dbd2fb58ff3e0e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Dec 2002 19:58:27 +0000 Subject: Ensure global_scope() returns "", not the NULL string. Froma tpot fix. Jeremy. (This used to be commit 7185b846e41da2bf7edaa7f3edeff1cc1486d28b) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 43e32aebbd..d38e2ff0ec 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1203,7 +1203,7 @@ int name_mangle( char *In, char *Out, char name_type ) p[0] = '\0'; /* Add the scope string. */ - for( i = 0, len = 0; NULL != global_scope(); i++, len++ ) + for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) { switch( (global_scope())[i] ) { -- cgit From ccdfed5587d4da1f2a4154ed151626d79765cc8f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 6 Dec 2002 19:59:04 +0000 Subject: Ensure global_scope() returns "", not the NULL string. Froma tpot fix. Jeremy. (This used to be commit 0ff254264e6e43399404595bc87b5bd889e17952) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 43e32aebbd..d38e2ff0ec 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1203,7 +1203,7 @@ int name_mangle( char *In, char *Out, char name_type ) p[0] = '\0'; /* Add the scope string. */ - for( i = 0, len = 0; NULL != global_scope(); i++, len++ ) + for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) { switch( (global_scope())[i] ) { -- cgit From 89ef861b4b7530a8a9a157b2e9e253a2e5716738 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Dec 2002 23:27:12 +0000 Subject: Fix client large file reporting. Jeremy (This used to be commit 185804ac945e717a5e3d3602e8118b35080f6251) --- source3/libsmb/clilist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 1616d46bf1..4a1737af49 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -48,7 +48,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL_TO_SMB_OFF_T(p,16); + finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); p += 27; @@ -69,7 +69,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL_TO_SMB_OFF_T(p,16); + finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; @@ -104,7 +104,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = interpret_long_date(p); p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL_TO_SMB_OFF_T(p,0); p += 8; + finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; p += 8; /* alloc size */ finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; @@ -322,7 +322,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /* this date is converted to GMT by make_unix_date */ finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; - finfo->size = IVAL_TO_SMB_OFF_T(p,26); + finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); -- cgit From 3fc4d88d99b8629e7e3f97d6e70254ef0865a5e5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Dec 2002 23:44:33 +0000 Subject: Fix client reporting of 64 bit files. Jeremy. (This used to be commit 8dcbfa4e770d74d4ce6faaf1a0597d07d0a5cc81) --- source3/libsmb/clilist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 1616d46bf1..4a1737af49 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -48,7 +48,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL_TO_SMB_OFF_T(p,16); + finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); p += 27; @@ -69,7 +69,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL_TO_SMB_OFF_T(p,16); + finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; @@ -104,7 +104,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = interpret_long_date(p); p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL_TO_SMB_OFF_T(p,0); p += 8; + finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; p += 8; /* alloc size */ finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; @@ -322,7 +322,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /* this date is converted to GMT by make_unix_date */ finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; - finfo->size = IVAL_TO_SMB_OFF_T(p,26); + finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); -- cgit From f2def025e277081ac86d68060fed3e10994eaa44 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Dec 2002 18:52:21 +0000 Subject: Fix write error returning EFBIG - found by Conrad. Jeremy. (This used to be commit e258887f508db3d2c923f393f0104e7cf1bd6545) --- source3/libsmb/errormap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 7c28c7e8aa..8bd29b55c0 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1512,6 +1512,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = { #endif #ifdef ENAMETOOLONG { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, +#endif +#ifdef EFBIG + { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, #endif { 0, 0, 0, NT_STATUS_OK } }; -- cgit From f7267c1235ae1b8c6a7324d508f5d435ff18de50 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Dec 2002 18:52:32 +0000 Subject: Fix write error returning EFBIG - found by Conrad. Jeremy. (This used to be commit 2d63fc7760634308cc280e4d745a6f7398f75d20) --- source3/libsmb/errormap.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 7c28c7e8aa..8bd29b55c0 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1512,6 +1512,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = { #endif #ifdef ENAMETOOLONG { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, +#endif +#ifdef EFBIG + { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, #endif { 0, 0, 0, NT_STATUS_OK } }; -- cgit From f6c4f25e4319b47ac6c8dbf67a4b1c513148384c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 12 Dec 2002 23:35:55 +0000 Subject: merge of get_dc_name()-like code from APP_HEAD; better support password server = DC1 * (This used to be commit 6b18ca9511ddcf1718f222af3f61491d1e5f3b60) --- source3/libsmb/namequery_dc.c | 104 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 source3/libsmb/namequery_dc.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c new file mode 100644 index 0000000000..ffc64139e9 --- /dev/null +++ b/source3/libsmb/namequery_dc.c @@ -0,0 +1,104 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon connection manager + + Copyright (C) Tim Potter 2001 + Copyright (C) Andrew Bartlett 2002 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" + + +/* + find the DC for a domain using methods appropriate for a RPC domain +*/ +BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) +{ + struct in_addr *ip_list = NULL, dc_ip, exclude_ip; + int count, i; + BOOL list_ordered; + BOOL use_pdc_only; + + zero_ip(&exclude_ip); + + use_pdc_only = must_use_pdc(domain); + + /* Lookup domain controller name */ + + if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) ) { + DEBUG(10,("rpc_find_dc: Atempting to lookup PDC to avoid sam sync delays\n")); + + if (name_status_find(domain, 0x1c, 0x20, dc_ip, srv_name)) { + goto done; + } + /* Didn't get name, remember not to talk to this DC. */ + exclude_ip = dc_ip; + } + + /* get a list of all domain controllers */ + + if (!get_dc_list( domain, &ip_list, &count, &list_ordered) ) { + DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); + return False; + } + + /* Remove the entry we've already failed with (should be the PDC). */ + + if ( use_pdc_only ) { + for (i = 0; i < count; i++) { + if (ip_equal( exclude_ip, ip_list[i])) + zero_ip(&ip_list[i]); + } + } + + /* Pick a nice close server, but only if the list was not ordered */ + if (!list_ordered && (count > 1) ) { + qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare); + } + + for (i = 0; i < count; i++) { + if (is_zero_ip(ip_list[i])) + continue; + + if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { + dc_ip = ip_list[i]; + goto done; + } + } + + + SAFE_FREE(ip_list); + + return False; +done: + /* We have the netbios name and IP address of a domain controller. + Ideally we should sent a SAMLOGON request to determine whether + the DC is alive and kicking. If we can catch a dead DC before + performing a cli_connect() we can avoid a 30-second timeout. */ + + DEBUG(3, ("rpc_find_dc: Returning DC %s (%s) for domain %s\n", srv_name, + inet_ntoa(dc_ip), domain)); + + *ip_out = dc_ip; + + SAFE_FREE(ip_list); + + return True; +} + -- cgit From 846b50cd417b392288727ecf948ba4df30a90e6e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 17 Dec 2002 22:53:56 +0000 Subject: app_head merge for get_friendly_nt_err() (This used to be commit 3ceff08eb75ecd70dcf10d033c7451d87b659c0b) --- source3/libsmb/nterr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 4bb21efaa7..e494995f86 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -602,9 +602,9 @@ char *get_friendly_nt_error_msg(NTSTATUS nt_code) int idx = 0; while (nt_err_desc[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_errs[idx].nt_errcode) == NT_STATUS_V(nt_code)) + if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) { - return nt_errs[idx].nt_errstr; + return nt_err_desc[idx].nt_errstr; } idx++; } -- cgit From 98b19b0e5ee9d4e3c4b6bb2279b743ba5669bcac Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 17 Dec 2002 22:55:49 +0000 Subject: app_head merge for get_friendly_nt_err() (This used to be commit 5b311250257b3c45879a85ac46d6b6aa316514bf) --- source3/libsmb/nterr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 4bb21efaa7..e494995f86 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -602,9 +602,9 @@ char *get_friendly_nt_error_msg(NTSTATUS nt_code) int idx = 0; while (nt_err_desc[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_errs[idx].nt_errcode) == NT_STATUS_V(nt_code)) + if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) { - return nt_errs[idx].nt_errstr; + return nt_err_desc[idx].nt_errstr; } idx++; } -- cgit From c52a34693d8bb007b246a365aa1ca7502156d9d2 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 19 Dec 2002 20:23:45 +0000 Subject: merge from 2.2 fix for smbclient large files (This used to be commit 723c4caf64c56b78052c52fec78c7143ec19e944) --- source3/libsmb/clireadwrite.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 38e8aac42a..7780c93cc4 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -29,10 +29,15 @@ Issue a single SMBread and don't wait for a reply. static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { + BOOL bigoffset = False; + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,10,0,True); + if ((SMB_BIG_UINT)offset >> 32) + bigoffset = True; + + set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); SCVAL(cli->outbuf,smb_com,SMBreadX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -45,6 +50,9 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); + if (bigoffset) + SIVAL(cli->outbuf,smb_vwv10,(offset>>32) & 0xffffffff); + return cli_send_smb(cli); } -- cgit From 41969738a4d5244b73864dd882d214ff8824365b Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Thu, 19 Dec 2002 20:26:44 +0000 Subject: merge from 2.2 fix for smbclient large files (This used to be commit 17f685fdbf5d36f82e3da0a09457f5e248b3f109) --- source3/libsmb/clireadwrite.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 38e8aac42a..7780c93cc4 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -29,10 +29,15 @@ Issue a single SMBread and don't wait for a reply. static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { + BOOL bigoffset = False; + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,10,0,True); + if ((SMB_BIG_UINT)offset >> 32) + bigoffset = True; + + set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); SCVAL(cli->outbuf,smb_com,SMBreadX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -45,6 +50,9 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv6,size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); + if (bigoffset) + SIVAL(cli->outbuf,smb_vwv10,(offset>>32) & 0xffffffff); + return cli_send_smb(cli); } -- cgit From 45a6532727888c710d537c6e1e03466af2a87881 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 20 Dec 2002 01:07:09 +0000 Subject: Fixed bug in debug statement when tconX fails. (This used to be commit a2159610b9d38cc7cfa7cb877ccee816cd2206b8) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 584ad15174..b758af41c4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1258,8 +1258,8 @@ again: if (service) { if (!cli_send_tconX(cli, service, service_type, password, strlen(password)+1)) { - DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); nt_status = cli_nt_error(cli); + DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); cli_shutdown(cli); if (NT_STATUS_IS_OK(nt_status)) { nt_status = NT_STATUS_UNSUCCESSFUL; -- cgit From ef8bd7c4f7ae8192ea05db070962ecf0ff3615f3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Dec 2002 20:21:31 +0000 Subject: Forward port the change to talloc_init() to make all talloc contexts named. Ensure we can query them. Jeremy. (This used to be commit 09a218a9f6fb0bd922940467bf8500eb4f1bcf84) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clisecdesc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 28480043b9..c843d49d27 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -262,7 +262,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (!cli->outbuf || !cli->inbuf) goto error; - if ((cli->mem_ctx = talloc_init_named("cli based talloc")) == NULL) + if ((cli->mem_ctx = talloc_init("cli based talloc")) == NULL) goto error; memset(cli->outbuf, 0, cli->bufsize); diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 5de67b1e05..7dd2747ff6 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -83,7 +83,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) prs_struct pd; BOOL ret = False; - if ((mem_ctx = talloc_init()) == NULL) { + if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) { DEBUG(0,("talloc_init failed.\n")); goto cleanup; } -- cgit From 7f23546730e49569d41a5edd0c47bb559c4f812d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Dec 2002 20:23:06 +0000 Subject: Forward port the change to talloc_init() to make all talloc contexts named. Ensure we can query them. Jeremy. (This used to be commit 842e08e52a665ae678eea239759bb2de1a0d7b33) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clisecdesc.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 28480043b9..c843d49d27 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -262,7 +262,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (!cli->outbuf || !cli->inbuf) goto error; - if ((cli->mem_ctx = talloc_init_named("cli based talloc")) == NULL) + if ((cli->mem_ctx = talloc_init("cli based talloc")) == NULL) goto error; memset(cli->outbuf, 0, cli->bufsize); diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 5de67b1e05..7dd2747ff6 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -83,7 +83,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) prs_struct pd; BOOL ret = False; - if ((mem_ctx = talloc_init()) == NULL) { + if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) { DEBUG(0,("talloc_init failed.\n")); goto cleanup; } -- cgit From 0fdf60f0512f1a4443e315d764d59636c2075fe7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Dec 2002 23:53:56 +0000 Subject: Finish adding strings to all talloc_init() calls. Jeremy. (This used to be commit 784d15761c3271bfd602866f8f9f880dac77671c) --- source3/libsmb/netlogon_unigrp.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index ea9e790b7d..fa2fe32f35 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -47,7 +47,7 @@ BOOL uni_group_cache_init(void) return (netlogon_unigrp_tdb != NULL); } -void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) +BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) { TDB_DATA key,data; fstring keystr; @@ -55,7 +55,7 @@ void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) if (!uni_group_cache_init()) { DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n")); - return; + return False; } /* Prepare key as DOMAIN-SID/USER-RID string */ @@ -70,7 +70,7 @@ void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) if(!data.dptr) { DEBUG(0,("uni_group_cache_store_netlogon: cannot allocate memory!\n")); talloc_destroy(mem_ctx); - return; + return False; } /* Store data in byteorder-independent format */ @@ -78,7 +78,9 @@ void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) for(i=1; i<=user->num_groups2; i++) { SIVAL(&((uint32*)data.dptr)[i],0,user->gids[i-1].g_rid); } - tdb_store(netlogon_unigrp_tdb, key, data, TDB_REPLACE); + if (tdb_store(netlogon_unigrp_tdb, key, data, TDB_REPLACE) == -1) + return False; + return True; } /* @@ -149,10 +151,9 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, } /* Shutdown netlogon_unigrp database */ -void uni_group_cache_shutdown(void) +BOOL uni_group_cache_shutdown(void) { - if(netlogon_unigrp_tdb) { - tdb_close(netlogon_unigrp_tdb); - } + if(netlogon_unigrp_tdb) + return (tdb_close(netlogon_unigrp_tdb) == 0); + return True; } - -- cgit From 98ac4503aca8f5a5a4268d89791e9a4491ce8645 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Dec 2002 23:54:10 +0000 Subject: Finish adding strings to all talloc_init() calls. Jeremy. (This used to be commit aa8439a49ec4b9f433745fefa1e769e45398f4df) --- source3/libsmb/netlogon_unigrp.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index ea9e790b7d..fa2fe32f35 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -47,7 +47,7 @@ BOOL uni_group_cache_init(void) return (netlogon_unigrp_tdb != NULL); } -void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) +BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) { TDB_DATA key,data; fstring keystr; @@ -55,7 +55,7 @@ void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) if (!uni_group_cache_init()) { DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n")); - return; + return False; } /* Prepare key as DOMAIN-SID/USER-RID string */ @@ -70,7 +70,7 @@ void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) if(!data.dptr) { DEBUG(0,("uni_group_cache_store_netlogon: cannot allocate memory!\n")); talloc_destroy(mem_ctx); - return; + return False; } /* Store data in byteorder-independent format */ @@ -78,7 +78,9 @@ void uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) for(i=1; i<=user->num_groups2; i++) { SIVAL(&((uint32*)data.dptr)[i],0,user->gids[i-1].g_rid); } - tdb_store(netlogon_unigrp_tdb, key, data, TDB_REPLACE); + if (tdb_store(netlogon_unigrp_tdb, key, data, TDB_REPLACE) == -1) + return False; + return True; } /* @@ -149,10 +151,9 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, } /* Shutdown netlogon_unigrp database */ -void uni_group_cache_shutdown(void) +BOOL uni_group_cache_shutdown(void) { - if(netlogon_unigrp_tdb) { - tdb_close(netlogon_unigrp_tdb); - } + if(netlogon_unigrp_tdb) + return (tdb_close(netlogon_unigrp_tdb) == 0); + return True; } - -- cgit From b68e6c99103fd0f1e8a25b2fafe14d7540b2ab10 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 30 Dec 2002 04:25:30 +0000 Subject: Port the fix to cli_setup_write to handle offsets greater than 32-bits from Samba 2.2.x ... (This used to be commit 4201038588bab8674b73371a5eac70a412c5dd6c) --- source3/libsmb/clireadwrite.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 7780c93cc4..187a40cade 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -252,6 +252,7 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 size_t size, int i) { char *p; + BOOL bigoffset = False; if (size > cli->bufsize) { cli->outbuf = realloc(cli->outbuf, size + 1024); @@ -264,7 +265,10 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - if (size > 0xFFFF) + if ((SMB_BIG_UINT)offset >> 32) + bigoffset = True; + + if (bigoffset) set_message(cli->outbuf,14,0,True); else set_message(cli->outbuf,12,0,True); @@ -277,14 +281,20 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_vwv2,fnum); SIVAL(cli->outbuf,smb_vwv3,offset); - SIVAL(cli->outbuf,smb_vwv5,(mode & 0x0008) ? 0xFFFFFFFF : 0); + SIVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv7,mode); + /* + * THe following is still wrong ... + */ SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1)); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + if (bigoffset) + SIVAL(cli->outbuf,smb_vwv12,(offset>>32) & 0xffffffff); p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); memcpy(p, buf, size); -- cgit From 266c1ece1242e9e7b32eede8d5e1d1c81a6eb619 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Dec 2002 06:12:13 +0000 Subject: Merge Richard's write > 4Gb fix. Jeremy. (This used to be commit 5431bae8944496f44d8cc6d2c4de86e9feb60f32) --- source3/libsmb/clireadwrite.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 7780c93cc4..187a40cade 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -252,6 +252,7 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 size_t size, int i) { char *p; + BOOL bigoffset = False; if (size > cli->bufsize) { cli->outbuf = realloc(cli->outbuf, size + 1024); @@ -264,7 +265,10 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - if (size > 0xFFFF) + if ((SMB_BIG_UINT)offset >> 32) + bigoffset = True; + + if (bigoffset) set_message(cli->outbuf,14,0,True); else set_message(cli->outbuf,12,0,True); @@ -277,14 +281,20 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SSVAL(cli->outbuf,smb_vwv2,fnum); SIVAL(cli->outbuf,smb_vwv3,offset); - SIVAL(cli->outbuf,smb_vwv5,(mode & 0x0008) ? 0xFFFFFFFF : 0); + SIVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv7,mode); + /* + * THe following is still wrong ... + */ SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1)); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + if (bigoffset) + SIVAL(cli->outbuf,smb_vwv12,(offset>>32) & 0xffffffff); p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); memcpy(p, buf, size); -- cgit From c105c12d122e599fe57dde8b2b73c52231f0c1d2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 1 Jan 2003 21:54:00 +0000 Subject: Document the size constraints on a write request. (This used to be commit 5d6c1810330b38e48355078b7a5d53e7b5076f74) --- source3/libsmb/clireadwrite.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 187a40cade..d35b0dfdfd 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -284,10 +284,13 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 SIVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv7,mode); + SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); /* - * THe following is still wrong ... + * According to CIFS-TR-1p00, this following field should only + * be set if CAP_LARGE_WRITEX is set. We should check this + * locally. However, this check might already have been + * done by our callers. */ - SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1)); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, -- cgit From 6d66fb308ab85bd9691d541764e683e6040cf724 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 2 Jan 2003 09:07:17 +0000 Subject: BIG patch... This patch makes Samba compile cleanly with -Wwrite-strings. - That is, all string literals are marked as 'const'. These strings are always read only, this just marks them as such for passing to other functions. What is most supprising is that I didn't need to change more than a few lines of code (all in 'net', which got a small cleanup of net.h and extern variables). The rest is just adding a lot of 'const'. As far as I can tell, I have not added any new warnings - apart from making all of tdbutil.c's function const (so they warn for adding that const string to struct). Andrew Bartlett (This used to be commit 92a777d0eaa4fb3a1c7835816f93c6bdd456816d) --- source3/libsmb/asn1.c | 2 +- source3/libsmb/clidgram.c | 4 ++-- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clierror.c | 6 +++--- source3/libsmb/clikrb5.c | 2 +- source3/libsmb/cliprint.c | 2 +- source3/libsmb/clirap.c | 6 +++--- source3/libsmb/clirap2.c | 2 +- source3/libsmb/clireadwrite.c | 5 +++-- source3/libsmb/doserr.c | 4 ++-- source3/libsmb/errormap.c | 6 +++--- source3/libsmb/nmblib.c | 8 ++++---- source3/libsmb/nterr.c | 8 ++++---- source3/libsmb/smberr.c | 12 ++++++------ source3/libsmb/unexpected.c | 4 ++-- 15 files changed, 37 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index b7cfca41fb..b967927871 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -338,7 +338,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) } /* check that the next object ID is correct */ -BOOL asn1_check_OID(ASN1_DATA *data, char *OID) +BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) { char *id; diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 8f4bdf7be6..5ab6bef87b 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -26,7 +26,7 @@ * cli_send_mailslot, send a mailslot for client code ... */ -int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, +int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot, char *buf, int len, const char *srcname, int src_type, const char *dstname, int dest_type, @@ -100,7 +100,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, /* * cli_get_response: Get a response ... */ -int cli_get_response(int dgram_sock, BOOL unique, char *mailslot, char *buf, int bufsiz) +int cli_get_response(int dgram_sock, BOOL unique, const char *mailslot, char *buf, int bufsiz) { struct packet_struct *packet; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c843d49d27..ed1286d627 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -327,7 +327,7 @@ void cli_shutdown(struct cli_state *cli) Set socket options on a open connection. ****************************************************************************/ -void cli_sockopt(struct cli_state *cli, char *options) +void cli_sockopt(struct cli_state *cli, const char *options) { set_socket_options(cli->fd, options); } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index f5281eb047..12a7b5dba1 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -33,7 +33,7 @@ static const struct { int err; - char *message; + const char *message; } rap_errmap[] = { {5, "RAP5: User has insufficient privilege" }, @@ -62,7 +62,7 @@ static const struct /**************************************************************************** return a description of an SMB error ****************************************************************************/ -static char *cli_smb_errstr(struct cli_state *cli) +static const char *cli_smb_errstr(struct cli_state *cli) { return smb_dos_errstr(cli->inbuf); } @@ -73,7 +73,7 @@ static char *cli_smb_errstr(struct cli_state *cli) in which case they can be safely ignored. ****************************************************************************/ -char *cli_errstr(struct cli_state *cli) +const char *cli_errstr(struct cli_state *cli) { static fstring cli_error_message; uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum; diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 54a8a6ffe8..a7b11d777e 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -94,7 +94,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) +DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) { krb5_error_code retval; krb5_data packet; diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 92fbf02e91..bfa33bc514 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -27,7 +27,7 @@ This function contains code to prevent core dumps if the server returns invalid data. *****************************************************************************/ -static char *fix_char_ptr(unsigned int datap, unsigned int converter, +static const char *fix_char_ptr(unsigned int datap, unsigned int converter, char *rdata, int rdrcnt) { if (datap == 0) { /* turn NULL pointers into zero length strings */ diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index b4924fd773..792a3e7aa0 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -26,7 +26,7 @@ /**************************************************************************** Call a remote api on an arbitrary pipe. takes param, data and setup buffers. ****************************************************************************/ -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, +BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, char *data, uint32 data_count, uint32 max_data_count, @@ -176,7 +176,7 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co char *sname = p; int type = SVAL(p,14); int comment_offset = IVAL(p,16) & 0xFFFF; - char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + const char *cmnt = comment_offset?(rdata+comment_offset-converter):""; pstring s1, s2; pull_ascii_pstring(s1, sname); @@ -253,7 +253,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, for (i = 0;i < count;i++, p += 26) { char *sname = p; int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; - char *cmnt = comment_offset?(rdata+comment_offset):""; + const char *cmnt = comment_offset?(rdata+comment_offset):""; pstring s1, s2; if (comment_offset < 0 || comment_offset > rdrcnt) continue; diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 9c3ec212d5..948e88061a 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -128,7 +128,7 @@ pull_ascii_pstring(s, off?(r+off-c):"");\ } while(0) -static char *make_header(char *param, uint16 apinum, char *reqfmt, char *datafmt) +static char *make_header(char *param, uint16 apinum, const char *reqfmt, const char *datafmt) { PUTWORD(param,apinum); if (reqfmt) diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index d35b0dfdfd..0715aa7f1a 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -248,7 +248,8 @@ ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, si issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, +static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, + uint16 mode, const char *buf, size_t size, int i) { char *p; @@ -319,7 +320,7 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size) + const char *buf, off_t offset, size_t size) { int bwritten = 0; int issued = 0; diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 02db625685..c9de4cf319 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -24,7 +24,7 @@ typedef const struct { - char *dos_errstr; + const char *dos_errstr; WERROR werror; } werror_code_struct; @@ -73,7 +73,7 @@ werror_code_struct dos_errs[] = /***************************************************************************** returns a DOS error message. not amazingly helpful, but better than a number. *****************************************************************************/ -char *dos_errstr(WERROR werror) +const char *dos_errstr(WERROR werror) { static pstring msg; int idx = 0; diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 8bd29b55c0..09340caccd 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -45,7 +45,7 @@ */ /* NT status -> dos error map */ -const static struct { +static const struct { uint8 dos_class; uint32 dos_code; NTSTATUS ntstatus; @@ -611,7 +611,7 @@ const static struct { /* dos -> nt status error map */ -const static struct { +static const struct { uint8 dos_class; uint32 dos_code; NTSTATUS ntstatus; @@ -866,7 +866,7 @@ const static struct { }; /* errmap NTSTATUS->Win32 */ -const static struct { +static const struct { NTSTATUS ntstatus; WERROR werror; } ntstatus_to_werror_map[] = { diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d38e2ff0ec..30ce5b6b10 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -25,7 +25,7 @@ int num_good_sends = 0; int num_good_receives = 0; static const struct opcode_names { - char *nmb_opcode_name; + const char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { {"Query", 0 }, @@ -57,7 +57,7 @@ static const char *lookup_opcode_name( int opcode ) /**************************************************************************** print out a res_rec structure ****************************************************************************/ -static void debug_nmb_res_rec(struct res_rec *res, char *hdr) +static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) { int i, j; @@ -1005,7 +1005,7 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) queue. The packet must be a reply packet and have the specified mailslot name The timeout is in milliseconds ***************************************************************************/ -struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) +struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) { struct packet_struct *p; @@ -1024,7 +1024,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) /**************************************************************************** see if a datagram has the right mailslot name ***************************************************************************/ -BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name) +BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) { struct dgram_packet *dgram = &p->packet.dgram; char *buf; diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index e494995f86..dbad05b91e 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -24,7 +24,7 @@ typedef const struct { - char *nt_errstr; + const char *nt_errstr; NTSTATUS nt_errcode; } nt_err_code_struct; @@ -575,7 +575,7 @@ nt_err_code_struct nt_err_desc[] = /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -char *nt_errstr(NTSTATUS nt_code) +const char *nt_errstr(NTSTATUS nt_code) { static pstring msg; int idx = 0; @@ -597,7 +597,7 @@ char *nt_errstr(NTSTATUS nt_code) Print friendler version fo NT error code ***********************************************************************/ -char *get_friendly_nt_error_msg(NTSTATUS nt_code) +const char *get_friendly_nt_error_msg(NTSTATUS nt_code) { int idx = 0; @@ -617,7 +617,7 @@ char *get_friendly_nt_error_msg(NTSTATUS nt_code) /***************************************************************************** returns an NT_STATUS constant as a string for inclusion in autogen C code *****************************************************************************/ -char *get_nt_error_c_code(NTSTATUS nt_code) +const char *get_nt_error_c_code(NTSTATUS nt_code) { static pstring out; int idx = 0; diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 724c8edd54..82efbdb689 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -37,9 +37,9 @@ typedef const struct { - char *name; + const char *name; int code; - char *message; + const char *message; } err_code_struct; /* Dos Error Messages */ @@ -142,7 +142,7 @@ err_code_struct hard_msgs[] = { const struct { int code; - char *class; + const char *class; err_code_struct *err_msgs; } err_classes[] = { {0,"SUCCESS",NULL}, @@ -160,7 +160,7 @@ const struct /**************************************************************************** return a SMB error name from a class and code ****************************************************************************/ -char *smb_dos_err_name(uint8 class, uint16 num) +const char *smb_dos_err_name(uint8 class, uint16 num) { static pstring ret; int i,j; @@ -184,7 +184,7 @@ char *smb_dos_err_name(uint8 class, uint16 num) /* Return a string for a DOS error */ -char *get_dos_error_msg(WERROR result) +const char *get_dos_error_msg(WERROR result) { uint16 errnum; @@ -196,7 +196,7 @@ char *get_dos_error_msg(WERROR result) /**************************************************************************** return a SMB error class name as a string. ****************************************************************************/ -char *smb_dos_err_class(uint8 class) +const char *smb_dos_err_class(uint8 class) { static pstring ret; int i; diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 4fc3914481..97d6071e71 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -110,7 +110,7 @@ void clear_unexpected(time_t t) static struct packet_struct *matched_packet; static int match_id; static enum packet_type match_type; -static char *match_name; +static const char *match_name; /**************************************************************************** tdb traversal fn to find a matching 137 packet @@ -144,7 +144,7 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void check for a particular packet in the unexpected packet queue **************************************************************************/ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, - char *mailslot_name) + const char *mailslot_name) { TDB_CONTEXT *tdb2; -- cgit From 94fec25c5fa1570a43370a105f2b86e2ed96c90b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 2 Jan 2003 09:40:10 +0000 Subject: One more const. Andrew, you seem to have krb5 :-) Volker (This used to be commit f5494f5ef6a14020bd31541b1f87d48111f60ad8) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index a7b11d777e..cca2a9cd3a 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -156,7 +156,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) + DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); -- cgit From fe0382f186afb212c8f39d73b4d7e28b0adb1a63 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 3 Jan 2003 04:32:23 +0000 Subject: Fixed some simple typos, including one that would have resulted in a DEBUG() message printing the wrong value. (This used to be commit 42a4e5b851aa7c9fd9dca5a6f8f42e5d91246c76) --- source3/libsmb/smbencrypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index db265c4bf7..42250fc19c 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -129,13 +129,13 @@ BOOL ntv2_owf_gen(const uchar owf[16], user_byte_len = push_ucs2_allocate(&user, user_in); if (user_byte_len < 0) { - DEBUG(0, ("push_uss2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); + DEBUG(0, ("push_ucs2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); return False; } domain_byte_len = push_ucs2_allocate(&domain, domain_in); if (domain_byte_len < 0) { - DEBUG(0, ("push_uss2_allocate() for domain returned %d (probably malloc() failure)\n", user_byte_len)); + DEBUG(0, ("push_ucs2_allocate() for domain returned %d (probably malloc() failure)\n", domain_byte_len)); return False; } -- cgit From 47a7f0cfb5006fb41239a6cd81cce5e35fde750a Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Fri, 3 Jan 2003 04:35:09 +0000 Subject: Fixed some simple typos, including one that would cause the wrong value to be printed in a DEBUG() message. (This used to be commit 96e9fa5f224966531fa8f9cf18cbc4bbb2fe60ed) --- source3/libsmb/smbencrypt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index db265c4bf7..42250fc19c 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -129,13 +129,13 @@ BOOL ntv2_owf_gen(const uchar owf[16], user_byte_len = push_ucs2_allocate(&user, user_in); if (user_byte_len < 0) { - DEBUG(0, ("push_uss2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); + DEBUG(0, ("push_ucs2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); return False; } domain_byte_len = push_ucs2_allocate(&domain, domain_in); if (domain_byte_len < 0) { - DEBUG(0, ("push_uss2_allocate() for domain returned %d (probably malloc() failure)\n", user_byte_len)); + DEBUG(0, ("push_ucs2_allocate() for domain returned %d (probably malloc() failure)\n", domain_byte_len)); return False; } -- cgit From 634c54310c92c48dd4eceec602e230a021bdcfc5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Jan 2003 08:28:12 +0000 Subject: Merge from HEAD - make Samba compile with -Wwrite-strings without additional warnings. (Adds a lot of const). Andrew Bartlett (This used to be commit 3a7458f9472432ef12c43008414925fd1ce8ea0c) --- source3/libsmb/asn1.c | 2 +- source3/libsmb/clidgram.c | 4 ++-- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clierror.c | 6 +++--- source3/libsmb/clikrb5.c | 2 +- source3/libsmb/cliprint.c | 2 +- source3/libsmb/clirap.c | 6 +++--- source3/libsmb/clirap2.c | 2 +- source3/libsmb/clireadwrite.c | 5 +++-- source3/libsmb/doserr.c | 4 ++-- source3/libsmb/errormap.c | 6 +++--- source3/libsmb/nmblib.c | 8 ++++---- source3/libsmb/nterr.c | 8 ++++---- source3/libsmb/smberr.c | 12 ++++++------ source3/libsmb/unexpected.c | 4 ++-- 15 files changed, 37 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index b7cfca41fb..b967927871 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -338,7 +338,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) } /* check that the next object ID is correct */ -BOOL asn1_check_OID(ASN1_DATA *data, char *OID) +BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) { char *id; diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 8f4bdf7be6..5ab6bef87b 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -26,7 +26,7 @@ * cli_send_mailslot, send a mailslot for client code ... */ -int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, +int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot, char *buf, int len, const char *srcname, int src_type, const char *dstname, int dest_type, @@ -100,7 +100,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, char *mailslot, /* * cli_get_response: Get a response ... */ -int cli_get_response(int dgram_sock, BOOL unique, char *mailslot, char *buf, int bufsiz) +int cli_get_response(int dgram_sock, BOOL unique, const char *mailslot, char *buf, int bufsiz) { struct packet_struct *packet; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c843d49d27..ed1286d627 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -327,7 +327,7 @@ void cli_shutdown(struct cli_state *cli) Set socket options on a open connection. ****************************************************************************/ -void cli_sockopt(struct cli_state *cli, char *options) +void cli_sockopt(struct cli_state *cli, const char *options) { set_socket_options(cli->fd, options); } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index f5281eb047..12a7b5dba1 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -33,7 +33,7 @@ static const struct { int err; - char *message; + const char *message; } rap_errmap[] = { {5, "RAP5: User has insufficient privilege" }, @@ -62,7 +62,7 @@ static const struct /**************************************************************************** return a description of an SMB error ****************************************************************************/ -static char *cli_smb_errstr(struct cli_state *cli) +static const char *cli_smb_errstr(struct cli_state *cli) { return smb_dos_errstr(cli->inbuf); } @@ -73,7 +73,7 @@ static char *cli_smb_errstr(struct cli_state *cli) in which case they can be safely ignored. ****************************************************************************/ -char *cli_errstr(struct cli_state *cli) +const char *cli_errstr(struct cli_state *cli) { static fstring cli_error_message; uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum; diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 54a8a6ffe8..a7b11d777e 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -94,7 +94,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) +DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) { krb5_error_code retval; krb5_data packet; diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 92fbf02e91..bfa33bc514 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -27,7 +27,7 @@ This function contains code to prevent core dumps if the server returns invalid data. *****************************************************************************/ -static char *fix_char_ptr(unsigned int datap, unsigned int converter, +static const char *fix_char_ptr(unsigned int datap, unsigned int converter, char *rdata, int rdrcnt) { if (datap == 0) { /* turn NULL pointers into zero length strings */ diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index b4924fd773..792a3e7aa0 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -26,7 +26,7 @@ /**************************************************************************** Call a remote api on an arbitrary pipe. takes param, data and setup buffers. ****************************************************************************/ -BOOL cli_api_pipe(struct cli_state *cli, char *pipe_name, +BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, char *data, uint32 data_count, uint32 max_data_count, @@ -176,7 +176,7 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co char *sname = p; int type = SVAL(p,14); int comment_offset = IVAL(p,16) & 0xFFFF; - char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + const char *cmnt = comment_offset?(rdata+comment_offset-converter):""; pstring s1, s2; pull_ascii_pstring(s1, sname); @@ -253,7 +253,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, for (i = 0;i < count;i++, p += 26) { char *sname = p; int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; - char *cmnt = comment_offset?(rdata+comment_offset):""; + const char *cmnt = comment_offset?(rdata+comment_offset):""; pstring s1, s2; if (comment_offset < 0 || comment_offset > rdrcnt) continue; diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 9c3ec212d5..948e88061a 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -128,7 +128,7 @@ pull_ascii_pstring(s, off?(r+off-c):"");\ } while(0) -static char *make_header(char *param, uint16 apinum, char *reqfmt, char *datafmt) +static char *make_header(char *param, uint16 apinum, const char *reqfmt, const char *datafmt) { PUTWORD(param,apinum); if (reqfmt) diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 187a40cade..fb013734ac 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -248,7 +248,8 @@ ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, si issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, char *buf, +static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, + uint16 mode, const char *buf, size_t size, int i) { char *p; @@ -316,7 +317,7 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1 ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, - char *buf, off_t offset, size_t size) + const char *buf, off_t offset, size_t size) { int bwritten = 0; int issued = 0; diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 02db625685..c9de4cf319 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -24,7 +24,7 @@ typedef const struct { - char *dos_errstr; + const char *dos_errstr; WERROR werror; } werror_code_struct; @@ -73,7 +73,7 @@ werror_code_struct dos_errs[] = /***************************************************************************** returns a DOS error message. not amazingly helpful, but better than a number. *****************************************************************************/ -char *dos_errstr(WERROR werror) +const char *dos_errstr(WERROR werror) { static pstring msg; int idx = 0; diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 8bd29b55c0..09340caccd 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -45,7 +45,7 @@ */ /* NT status -> dos error map */ -const static struct { +static const struct { uint8 dos_class; uint32 dos_code; NTSTATUS ntstatus; @@ -611,7 +611,7 @@ const static struct { /* dos -> nt status error map */ -const static struct { +static const struct { uint8 dos_class; uint32 dos_code; NTSTATUS ntstatus; @@ -866,7 +866,7 @@ const static struct { }; /* errmap NTSTATUS->Win32 */ -const static struct { +static const struct { NTSTATUS ntstatus; WERROR werror; } ntstatus_to_werror_map[] = { diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d38e2ff0ec..30ce5b6b10 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -25,7 +25,7 @@ int num_good_sends = 0; int num_good_receives = 0; static const struct opcode_names { - char *nmb_opcode_name; + const char *nmb_opcode_name; int opcode; } nmb_header_opcode_names[] = { {"Query", 0 }, @@ -57,7 +57,7 @@ static const char *lookup_opcode_name( int opcode ) /**************************************************************************** print out a res_rec structure ****************************************************************************/ -static void debug_nmb_res_rec(struct res_rec *res, char *hdr) +static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) { int i, j; @@ -1005,7 +1005,7 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) queue. The packet must be a reply packet and have the specified mailslot name The timeout is in milliseconds ***************************************************************************/ -struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) +struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) { struct packet_struct *p; @@ -1024,7 +1024,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t, char *mailslot_name) /**************************************************************************** see if a datagram has the right mailslot name ***************************************************************************/ -BOOL match_mailslot_name(struct packet_struct *p, char *mailslot_name) +BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) { struct dgram_packet *dgram = &p->packet.dgram; char *buf; diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index e494995f86..dbad05b91e 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -24,7 +24,7 @@ typedef const struct { - char *nt_errstr; + const char *nt_errstr; NTSTATUS nt_errcode; } nt_err_code_struct; @@ -575,7 +575,7 @@ nt_err_code_struct nt_err_desc[] = /***************************************************************************** returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ -char *nt_errstr(NTSTATUS nt_code) +const char *nt_errstr(NTSTATUS nt_code) { static pstring msg; int idx = 0; @@ -597,7 +597,7 @@ char *nt_errstr(NTSTATUS nt_code) Print friendler version fo NT error code ***********************************************************************/ -char *get_friendly_nt_error_msg(NTSTATUS nt_code) +const char *get_friendly_nt_error_msg(NTSTATUS nt_code) { int idx = 0; @@ -617,7 +617,7 @@ char *get_friendly_nt_error_msg(NTSTATUS nt_code) /***************************************************************************** returns an NT_STATUS constant as a string for inclusion in autogen C code *****************************************************************************/ -char *get_nt_error_c_code(NTSTATUS nt_code) +const char *get_nt_error_c_code(NTSTATUS nt_code) { static pstring out; int idx = 0; diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 724c8edd54..82efbdb689 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -37,9 +37,9 @@ typedef const struct { - char *name; + const char *name; int code; - char *message; + const char *message; } err_code_struct; /* Dos Error Messages */ @@ -142,7 +142,7 @@ err_code_struct hard_msgs[] = { const struct { int code; - char *class; + const char *class; err_code_struct *err_msgs; } err_classes[] = { {0,"SUCCESS",NULL}, @@ -160,7 +160,7 @@ const struct /**************************************************************************** return a SMB error name from a class and code ****************************************************************************/ -char *smb_dos_err_name(uint8 class, uint16 num) +const char *smb_dos_err_name(uint8 class, uint16 num) { static pstring ret; int i,j; @@ -184,7 +184,7 @@ char *smb_dos_err_name(uint8 class, uint16 num) /* Return a string for a DOS error */ -char *get_dos_error_msg(WERROR result) +const char *get_dos_error_msg(WERROR result) { uint16 errnum; @@ -196,7 +196,7 @@ char *get_dos_error_msg(WERROR result) /**************************************************************************** return a SMB error class name as a string. ****************************************************************************/ -char *smb_dos_err_class(uint8 class) +const char *smb_dos_err_class(uint8 class) { static pstring ret; int i; diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 4fc3914481..97d6071e71 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -110,7 +110,7 @@ void clear_unexpected(time_t t) static struct packet_struct *matched_packet; static int match_id; static enum packet_type match_type; -static char *match_name; +static const char *match_name; /**************************************************************************** tdb traversal fn to find a matching 137 packet @@ -144,7 +144,7 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void check for a particular packet in the unexpected packet queue **************************************************************************/ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, - char *mailslot_name) + const char *mailslot_name) { TDB_CONTEXT *tdb2; -- cgit From 863e9ca2c640ce7a94acf81cff7408edc6f64e01 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Jan 2003 08:48:15 +0000 Subject: Merge from HEAD - mimir's new gencache based namecache code. Andrew Bartlett (This used to be commit f79324f730c400342f445c931b0d75ff756d7cc7) --- source3/libsmb/namecache.c | 323 +++++++++++++++++++++------------------------ source3/libsmb/namequery.c | 10 +- 2 files changed, 157 insertions(+), 176 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 724e0237d2..40777011a1 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -1,9 +1,10 @@ /* Unix SMB/CIFS implementation. - NetBIOS name cache module. - - Copyright (C) Tim Potter, 2002 + NetBIOS name cache module on top of gencache mechanism. + + Copyright (C) Tim Potter 2002 + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -22,242 +23,224 @@ #include "includes.h" -static BOOL done_namecache_init; -static BOOL enable_namecache; -static TDB_CONTEXT *namecache_tdb; +#define NBTKEY_FMT "NBT/%s#%02X" -struct nc_value { - time_t expiry; /* When entry expires */ - int count; /* Number of addresses */ - struct in_addr ip_list[1]; /* Address list */ -}; -/* Initialise namecache system */ +/** + * Initialise namecache system. Function calls gencache + * initialisation function to perform necessary actions + * + * @return true upon successful initialisation of the cache or + * false on failure + **/ BOOL namecache_enable(void) { - /* Check if we have been here before, or name caching disabled - by setting the name cache timeout to zero. */ - - if (done_namecache_init) - return False; - - done_namecache_init = True; + /* + * Check if name caching disabled by setting the name cache + * timeout to zero. + */ if (lp_name_cache_timeout() == 0) { - DEBUG(5, ("namecache_init: disabling netbios name cache\n")); + DEBUG(5, ("namecache_enable: disabling netbios name cache\n")); return False; } - /* Open namecache tdb in read/write or readonly mode */ + /* Init namecache by calling gencache initialisation */ - namecache_tdb = tdb_open_log( - lock_path("namecache.tdb"), 0, - TDB_DEFAULT, O_RDWR | O_CREAT, 0644); - - if (!namecache_tdb) { - DEBUG(5, ("namecache_init: could not open %s\n", - lock_path("namecache.tdb"))); + if (!gencache_init()) { + DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n")); return False; } - DEBUG(5, ("namecache_init: enabling netbios namecache, timeout %d " + /* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */ + DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d " "seconds\n", lp_name_cache_timeout())); - enable_namecache = True; - return True; } -/* Return a key for a name and name type. The caller must free - retval.dptr when finished. */ -static TDB_DATA namecache_key(const char *name, int name_type) +/** + * Shutdown namecache. Routine calls gencache close function + * to safely close gencache file. + * + * @return true upon successful shutdown of the cache or + * false on failure + **/ + +BOOL namecache_shutdown(void) { - TDB_DATA retval; - char *keystr; - - asprintf(&keystr, "%s#%02X", strupper_static(name), name_type); - - retval.dsize = strlen(keystr) + 1; - retval.dptr = keystr; - - return retval; + if (!gencache_shutdown()) { + DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n")); + return False; + } + + DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n")); + return True; } -/* Return a data value for an IP list. The caller must free - retval.dptr when finished. */ - -static TDB_DATA namecache_value(struct in_addr *ip_list, int num_names, - time_t expiry) -{ - TDB_DATA retval; - struct nc_value *value; - int size = sizeof(struct nc_value); - if (num_names > 0) - size += sizeof(struct in_addr) * (num_names-1); +/** + * Generates a key for netbios name lookups on basis of + * netbios name and type. + * The caller must free returned key string when finished. + * + * @param name netbios name string (case insensitive) + * @param name_type netbios type of the name being looked up + * + * @return string consisted of uppercased name and appended + * type number + */ - value = (struct nc_value *)malloc(size); - - memset(value, 0, size); - - value->expiry = expiry; - value->count = num_names; - - if (ip_list) - memcpy(value->ip_list, ip_list, sizeof(struct in_addr) * num_names); - - retval.dptr = (char *)value; - retval.dsize = size; +static char* namecache_key(const char *name, int name_type) +{ + char *keystr; + asprintf(&keystr, NBTKEY_FMT, strupper_static(name), name_type); - return retval; + return keystr; } -/* Store a name in the name cache */ -void namecache_store(const char *name, int name_type, - int num_names, struct in_addr *ip_list) +/** + * Store a name(s) in the name cache + * + * @param name netbios names array + * @param name_type integer netbios name type + * @param num_names number of names being stored + * @param ip_list array of in_addr structures containing + * ip addresses being stored + **/ + +BOOL namecache_store(const char *name, int name_type, + int num_names, struct in_addr *ip_list) { - TDB_DATA key, value; time_t expiry; + char *key, *value_string; int i; - if (!enable_namecache) - return; + /* + * we use gecache call to avoid annoying debug messages about + * initialised namecache again and again... + */ + if (!gencache_init()) return False; DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", - num_names, num_names == 1 ? "": "es", name, name_type)); + num_names, num_names == 1 ? "": "es", name, name_type)); for (i = 0; i < num_names; i++) DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]), - i == (num_names - 1) ? "" : ", ")); + i == (num_names - 1) ? "" : ", ")); DEBUGADD(5, ("\n")); key = namecache_key(name, name_type); - /* Cache pdc location or dc lists for only a little while - otherwise if we lock on to a bad DC we can potentially be - out of action for the entire cache timeout time! */ + /* + * Cache pdc location or dc lists for only a little while + * otherwise if we lock on to a bad DC we can potentially be + * out of action for the entire cache timeout time! + */ - if (name_type != 0x1b || name_type != 0x1c) + if (name_type == 0x1b || name_type == 0x1c) expiry = time(NULL) + 10; else expiry = time(NULL) + lp_name_cache_timeout(); - value = namecache_value(ip_list, num_names, expiry); - - tdb_store(namecache_tdb, key, value, TDB_REPLACE); - - free(key.dptr); - free(value.dptr); + /* + * Generate string representation of ip addresses list + * First, store the number of ip addresses and then + * place each single ip + */ + ipstr_list_make(&value_string, ip_list, num_names); + + /* set the entry */ + return (gencache_set(key, value_string, expiry)); } -/* Look up a name in the name cache. Return a mallocated list of IP - addresses if the name is contained in the cache. */ + +/** + * Look up a name in the cache. + * + * @param name netbios name to look up for + * @param name_type netbios name type of @param name + * @param ip_list mallocated list of IP addresses if found in the cache, + * NULL otherwise + * @param num_names number of entries found + * + * @return true upon successful fetch or + * false if name isn't found in the cache or has expired + **/ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, - int *num_names) + int *num_names) { - TDB_DATA key, value; - struct nc_value *data = NULL; - time_t now; - int i; + char *key, *value; + time_t timeout; - *ip_list = NULL; *num_names = 0; - if (!enable_namecache) - return False; + /* exit now if null pointers were passed as they're required further */ + if (!ip_list || !num_names) return False; - /* Read value */ + if (!gencache_init()) + return False; + /* + * Use gencache interface - lookup the key + */ key = namecache_key(name, name_type); - value = tdb_fetch(namecache_tdb, key); - - if (!value.dptr) { - DEBUG(5, ("namecache_fetch: %s#%02x not found\n", - name, name_type)); - goto done; - } - - data = (struct nc_value *)value.dptr; - - /* Check expiry time */ - - now = time(NULL); - - if (now > data->expiry) { - - DEBUG(5, ("namecache_fetch: entry for %s#%02x expired\n", - name, name_type)); - - tdb_delete(namecache_tdb, key); - - value = tdb_null; - - goto done; - } - - if ((data->expiry - now) > lp_name_cache_timeout()) { - - /* Someone may have changed the system time on us */ - - DEBUG(5, ("namecache_fetch: entry for %s#%02x has bad expiry\n", - name, name_type)); - - tdb_delete(namecache_tdb, key); - - value = tdb_null; - - goto done; - } - - /* Extract and return namelist */ - - DEBUG(5, ("namecache_fetch: returning %d address%s for %s#%02x: ", - data->count, data->count == 1 ? "" : "es", name, name_type)); - - if (data->count) { - - *ip_list = (struct in_addr *)malloc( - sizeof(struct in_addr) * data->count); - - memcpy(*ip_list, data->ip_list, sizeof(struct in_addr) * data->count); - - *num_names = data->count; - - for (i = 0; i < *num_names; i++) - DEBUGADD(5, ("%s%s", inet_ntoa((*ip_list)[i]), - i == (*num_names - 1) ? "" : ", ")); - + if (!gencache_get(key, &value, &timeout)) { + DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); + SAFE_FREE(key); + return False; + } else { + DEBUG(5, ("name %s#%02X found.\n", name, name_type)); } + + /* + * Split up the stored value into the list of IP adresses + */ + *num_names = ipstr_list_parse(value, ip_list); + + SAFE_FREE(key); + SAFE_FREE(value); + return *num_names > 0; /* true only if some ip has been fetched */ +} - DEBUGADD(5, ("\n")); -done: - SAFE_FREE(key.dptr); - SAFE_FREE(data); +/** + * Delete single namecache entry. Look at the + * gencache_iterate definition. + * + **/ - return value.dsize > 0; +static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr) +{ + gencache_del(key); + DEBUG(5, ("Deleting entry %s\n", key)); } -/* Flush all names from the name cache */ + +/** + * Flush all names from the name cache. + * It's done by gencache_iterate() + * + * @return True upon successful deletion or + * False in case of an error + **/ void namecache_flush(void) { - int result; - - if (!namecache_tdb) + if (!gencache_init()) return; - result = tdb_traverse(namecache_tdb, tdb_traverse_delete_fn, NULL); - - if (result == -1) - DEBUG(5, ("namecache_flush: error deleting cache entries\n")); - else - DEBUG(5, ("namecache_flush: deleted %d cache entr%s\n", - result, result == 1 ? "y" : "ies")); + /* + * iterate through each NBT cache's entry and flush it + * by flush_netbios_name function + */ + gencache_iterate(flush_netbios_name, NULL, "NBT/*"); + DEBUG(5, ("Namecache flushed\n")); } + diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0f81ff3eab..342a2a2926 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -837,11 +837,6 @@ static BOOL internal_resolve_name(const char *name, int name_type, if (resolve_hosts(name, return_iplist, return_count)) { result = True; goto done; - } else { - - /* Store negative lookup result */ - - namecache_store(name, name_type, 0, NULL); } } } else if(strequal( tok, "lmhosts")) { @@ -916,7 +911,10 @@ static BOOL internal_resolve_name(const char *name, int name_type, } /* Save in name cache */ - + for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) + DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name, + name_type, inet_ntoa((*return_iplist)[i]))); + namecache_store(name, name_type, *return_count, *return_iplist); /* Display some debugging info */ -- cgit From 9de96c6f24cfa58db7a229c2a902406402cdf4f0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Jan 2003 09:01:19 +0000 Subject: Merge from HEAD - do an nt_errstr(nt_status) *after* assiging nt_status with the actual error value :-) Andrew Bartlett (This used to be commit 123ae99c7d51c62e9f765cd41018dcc1a70cdd22) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 584ad15174..b758af41c4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1258,8 +1258,8 @@ again: if (service) { if (!cli_send_tconX(cli, service, service_type, password, strlen(password)+1)) { - DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); nt_status = cli_nt_error(cli); + DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); cli_shutdown(cli); if (NT_STATUS_IS_OK(nt_status)) { nt_status = NT_STATUS_UNSUCCESSFUL; -- cgit From 48dc324cd1a477454ea2fb79a3711e031617a5b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 4 Jan 2003 09:06:46 +0000 Subject: Merge from HEAD - vl's fix to my const patch. Also update the 'not have_krb5' case. Andrew Bartlett (This used to be commit 8129529c4faec5ea630acf70b7514a3efc0fbdcf) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index a7b11d777e..cca2a9cd3a 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -156,7 +156,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(char *principal, time_t time_offset) + DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); -- cgit From 73b0a2bdf8b667a5ad70bb4bcc08409e8c9ef7aa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 11 Jan 2003 12:04:14 +0000 Subject: Fix a number of client-side fstring/pstring mixups. Andrew Bartlett (This used to be commit fe1cc779d5ea77e87dbc0e2edf7c34a354fee6e0) --- source3/libsmb/clilist.c | 8 +++++--- source3/libsmb/smbencrypt.c | 18 +++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4a1737af49..89ab5d6414 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -324,9 +324,11 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); - if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) - fstrcpy(finfo->short_name,finfo->name); - + if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { + strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1); + finfo->short_name[sizeof(finfo->short_name)-1] = '\0'; + } + return(DIR_STRUCT_SIZE); } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 42250fc19c..06871104a4 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -122,33 +122,33 @@ BOOL ntv2_owf_gen(const uchar owf[16], smb_ucs2_t *user; smb_ucs2_t *domain; - int user_byte_len; - int domain_byte_len; + size_t user_byte_len; + size_t domain_byte_len; HMACMD5Context ctx; user_byte_len = push_ucs2_allocate(&user, user_in); - if (user_byte_len < 0) { - DEBUG(0, ("push_ucs2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); + if (user_byte_len == (size_t)-1) { + DEBUG(0, ("push_uss2_allocate() for user returned -1 (probably malloc() failure)\n")); return False; } domain_byte_len = push_ucs2_allocate(&domain, domain_in); - if (domain_byte_len < 0) { - DEBUG(0, ("push_ucs2_allocate() for domain returned %d (probably malloc() failure)\n", domain_byte_len)); + if (domain_byte_len == (size_t)-1) { + DEBUG(0, ("push_uss2_allocate() for domain returned -1 (probably malloc() failure)\n")); return False; } strupper_w(user); strupper_w(domain); + SMB_ASSERT(user_byte_len >= 2); + SMB_ASSERT(domain_byte_len >= 2); + /* We don't want null termination */ user_byte_len = user_byte_len - 2; domain_byte_len = domain_byte_len - 2; - SMB_ASSERT(user_byte_len >= 0); - SMB_ASSERT(domain_byte_len >= 0); - hmac_md5_init_limK_to_64(owf, 16, &ctx); hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); -- cgit From 05f6c8dea105b34c6031fcd037d74eddc1eba869 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 13 Jan 2003 08:53:54 +0000 Subject: Don't force the DOS password into a 14 char space, as this would imply null termination - the password will not be null terminated before hashing if len >= 14. related to debian bug #157432 Andrew Bartlett (This used to be commit c6535836f2e48903aa89a18c11cbb37576fb4a20) --- source3/libsmb/smbencrypt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 06871104a4..a57a98e3ea 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -73,13 +73,14 @@ void E_md4hash(const char *passwd, uchar p16[16]) void E_deshash(const char *passwd, uchar p16[16]) { - uchar dospwd[15]; /* Password must not be > 14 chars long. */ + fstring dospwd; ZERO_STRUCT(dospwd); ZERO_STRUCTP(p16); /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16(dospwd, p16); ZERO_STRUCT(dospwd); -- cgit From e3293c7181525a069d2006c29792a1a805d93ee0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 13 Jan 2003 12:48:37 +0000 Subject: Updates to our NTLMSSP code: This tries to extract our server-side code out of sessetup.c, and into a more general lib. I hope this is only a temporay resting place - I indend to refactor it again into an auth-subsystem independent lib, using callbacks. Move some of our our NTLMSSP #defines into a new file, and add two that I found in the COMsource docs - we seem to have a double-up, but I've verified from traces that the NTLMSSP_TARGET_TYPE_{DOMAIN,SERVER} is real. This code also copes with ASCII clients - not that we will ever see any here, but I hope to use this for HTTP, were we can get them. Win2k authenticates fine under forced ASCII, btw. Tested with Win2k, NTLMv2 and Samba's smbclient. Andrew Bartlett (This used to be commit b6641badcbb2fb3bfec9d00a6466318203ea33e1) --- source3/libsmb/asn1.c | 2 +- source3/libsmb/cliconnect.c | 4 +-- source3/libsmb/clispnego.c | 61 +++++++++++++++++++++++++++++++++++---------- 3 files changed, 51 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index b967927871..333d157905 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -407,7 +407,7 @@ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) return !data->has_error && (v == b); } -/* check a enumarted value is correct */ +/* write an enumarted value to the stream */ BOOL asn1_write_enumerated(ASN1_DATA *data, uint8 v) { if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b758af41c4..cc3aaf92be 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -476,8 +476,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, "NTLMSSP", NTLMSSP_NEGOTIATE, neg_flags, - workgroup, strlen(workgroup), - cli->calling.name, strlen(cli->calling.name) + 1); + workgroup, + cli->calling.name); DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n", neg_flags, workgroup, cli->calling.name)); /* and wrap it in a SPNEGO wrapper */ diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 55f49c5987..6a5f6c00ae 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -485,7 +485,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) /* generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(void) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply) { ASN1_DATA data; DATA_BLOB ret; @@ -495,8 +495,13 @@ DATA_BLOB spnego_gen_auth_response(void) asn1_push_tag(&data, ASN1_CONTEXT(1)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_enumerated(&data, 0); + asn1_write_enumerated(&data, ntlmssp_reply->length ? 1 : 0); asn1_pop_tag(&data); + if (ntlmssp_reply->length) { + asn1_push_tag(&data,ASN1_CONTEXT(2)); + asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); + asn1_pop_tag(&data); + } asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -514,8 +519,9 @@ DATA_BLOB spnego_gen_auth_response(void) format specifiers are: U = unicode string (input is unix string) - a = address (1 byte type, 1 byte length, unicode string, all inline) - A = ASCII string (pointer + length) Actually same as B + a = address (input is BOOL unicode, char *unix_string) + (1 byte type, 1 byte length, unicode/ASCII string, all inline) + A = ASCII string (input is unix string) B = data blob (pointer + length) b = data blob in header (pointer + length) D @@ -531,6 +537,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, uint8 *b; int head_size=0, data_size=0; int head_ofs, data_ofs; + BOOL unicode; /* first scan the format to work out the header and body size */ va_start(ap, format); @@ -541,12 +548,21 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += str_charnum(s) * 2; break; + case 'A': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_ascii_charnum(s); + break; case 'a': + unicode = va_arg(ap, BOOL); n = va_arg(ap, int); s = va_arg(ap, char *); - data_size += (str_charnum(s) * 2) + 4; + if (unicode) { + data_size += (str_charnum(s) * 2) + 4; + } else { + data_size += (str_ascii_charnum(s)) + 4; + } break; - case 'A': case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -586,20 +602,39 @@ BOOL msrpc_gen(DATA_BLOB *blob, push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); data_ofs += n*2; break; + case 'A': + s = va_arg(ap, char *); + n = str_ascii_charnum(s); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + data_ofs += n; + break; case 'a': + unicode = va_arg(ap, BOOL); n = va_arg(ap, int); SSVAL(blob->data, data_ofs, n); data_ofs += 2; s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); + if (unicode) { + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + } else { + n = str_ascii_charnum(s); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n, + STR_ASCII|STR_NOALIGN); + } + data_ofs += n; } - data_ofs += n*2; break; - case 'A': case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); -- cgit From 16925589eb1f12ebe6e493774fd4306a827feb73 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 13 Jan 2003 20:04:40 +0000 Subject: Now that I am running config.developer, I decided to get rif of some warnings: 1. reboot in parse_reg and cli_reg was shadowing a definition on FreeBSD 4.3 from system includes. 2. Added a bit of const to places. 3. Made sure internal functions were declared where needed. (This used to be commit fd847aa93690eb72f0437a8d22c03b222eb2a016) --- source3/libsmb/libsmb_compat.c | 8 +- source3/libsmb/libsmbclient.c | 173 ++++++++++++++++++++++++----------------- 2 files changed, 103 insertions(+), 78 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index bba90c648e..27b274953a 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -24,11 +24,7 @@ #include "includes.h" -/* - * Define this to get the real SMBCFILE and SMBCSRV structures - */ -#define _SMBC_INTERNAL -#include "../include/libsmbclient.h" +#include "../include/libsmb_internal.h" struct smbc_compat_fdlist { SMBCFILE * file; @@ -272,7 +268,7 @@ int smbc_open_print_job(const char *fname) return (int) file; } -int smbc_list_print_jobs(const char *purl, smbc_get_print_job_info fn) +int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn) { return statcont->list_print_jobs(statcont, purl, fn); } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index a1fb380c37..5ceb36795a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -23,7 +23,7 @@ #include "includes.h" -#include "../include/libsmbclient.h" +#include "../include/libsmb_internal.h" /* * Functions exported by libsmb_cache.c that we need here @@ -70,7 +70,7 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, { static pstring s; pstring userinfo; - char *p; + const char *p; char *q, *r; int len; @@ -119,7 +119,7 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, r = strchr_m(p, '/'); if (q && (!r || q < r)) { pstring username, passwd, domain; - char *u = userinfo; + const char *u = userinfo; next_token(&p, userinfo, "@", sizeof(fstring)); @@ -218,7 +218,7 @@ int smbc_check_server(SMBCCTX * context, SMBCSRV * server) } /* - * Remove a server from the list server_table if it's unused. + * Remove a server from the cached server list it's unused. * On success, 0 is returned. 1 is returned if the server could not be removed. * * Also useable outside libsmbclient @@ -228,11 +228,12 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) SMBCFILE * file; /* are we being fooled ? */ - if (!context || !context->_initialized || !srv) return 1; + if (!context || !context->internal || + !context->internal->_initialized || !srv) return 1; /* Check all open files/directories for a relation with this server */ - for (file = context->_files; file; file=file->next) { + for (file = context->internal->_files; file; file=file->next) { if (file->srv == srv) { /* Still used */ DEBUG(3, ("smbc_remove_usused_server: %p still used by %p.\n", @@ -241,7 +242,7 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) } } - DLIST_REMOVE(context->_servers, srv); + DLIST_REMOVE(context->internal->_servers, srv); cli_shutdown(&srv->cli); @@ -474,7 +475,8 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m SMBCFILE *file = NULL; int fd; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return NULL; @@ -541,7 +543,7 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m file->offset = 0; file->file = True; - DLIST_ADD(context->_files, file); + DLIST_ADD(context->internal->_files, file); return file; } @@ -572,7 +574,8 @@ static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return NULL; @@ -590,7 +593,8 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t { int ret; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -599,7 +603,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -640,14 +644,15 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ { int ret; - if (!context || context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -685,14 +690,15 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { SMBCSRV *srv; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -714,7 +720,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) * from the server cache if unused */ errno = smbc_errno(context, &file->srv->cli); srv = file->srv; - DLIST_REMOVE(context->_files, file); + DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); context->callbacks.remove_unused_server_fn(context, srv); @@ -736,7 +742,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) * from the server cache if unused */ errno = smbc_errno(context, &file->srv->cli); srv = file->srv; - DLIST_REMOVE(context->_files, file); + DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); context->callbacks.remove_unused_server_fn(context, srv); @@ -744,7 +750,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) return -1; } - DLIST_REMOVE(context->_files, file); + DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); @@ -761,7 +767,8 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, SMB_INO_T *ino) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -797,7 +804,8 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) pstring path; SMBCSRV *srv = NULL; - if (!context || context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -891,8 +899,10 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, pstring path1, path2; SMBCSRV *srv = NULL; - if (!ocontext || !ncontext || - !ocontext->_initialized || !ncontext->_initialized) { + if (!ocontext || !ncontext || + !ocontext->internal || !ncontext->internal || + !ocontext->internal->_initialized || + !ncontext->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -960,14 +970,15 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int { size_t size; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -1020,7 +1031,8 @@ static ino_t smbc_inode(SMBCCTX *context, const char *name) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -1088,7 +1100,8 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) uint16 mode = 0; SMB_INO_T ino = 0; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ return -1; @@ -1171,14 +1184,15 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) uint16 mode; SMB_INO_T ino = 0; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!file || !DLIST_CONTAINS(context->_files, file)) { + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; return -1; @@ -1271,9 +1285,6 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint ZERO_STRUCTP(dirent); - ZERO_STRUCTP(dirent); - - if (dir->dir_list == NULL) { dir->dir_list = malloc(sizeof(struct smbc_dir_list)); @@ -1354,8 +1365,6 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ break; } - ZERO_STRUCTP(dir->dir_list); - } else dirent_type = dir->dir_type; @@ -1390,9 +1399,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; struct in_addr rem_ip; - int slot = 0; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return NULL; @@ -1488,7 +1497,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - ZERO_STRUCTP(dir->dir_end); dir->srv = srv; @@ -1668,7 +1676,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } - DLIST_ADD(context->_files, dir); + DLIST_ADD(context->internal->_files, dir); return dir; } @@ -1680,14 +1688,15 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!dir || !DLIST_CONTAINS(context->_files, dir)) { + if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; return -1; @@ -1696,7 +1705,7 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) smbc_remove_dir(dir); /* Clean it up */ - DLIST_REMOVE(context->_files, dir); + DLIST_REMOVE(context->internal->_files, dir); if (dir) { @@ -1719,14 +1728,15 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) /* Check that all is ok first ... */ - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return NULL; } - if (!dir || !DLIST_CONTAINS(context->_files, dir)) { + if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; return NULL; @@ -1755,12 +1765,12 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) /* Hmmm, do I even need to copy it? */ - memcpy(context->_dirent, dirent, dirent->dirlen); /* Copy the dirent */ - dirp = (struct smbc_dirent *)context->_dirent; + memcpy(context->internal->_dirent, dirent, dirent->dirlen); /* Copy the dirent */ + dirp = (struct smbc_dirent *)context->internal->_dirent; dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); dir->dir_next = dir->dir_next->next; - return (struct smbc_dirent *)context->_dirent; + return (struct smbc_dirent *)context->internal->_dirent; } } @@ -1777,14 +1787,15 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent /* Check that all is ok first ... */ - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!dir || !DLIST_CONTAINS(context->_files, dir)) { + if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; return -1; @@ -1863,7 +1874,8 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) fstring server, share, user, password, workgroup; pstring path; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -1949,7 +1961,8 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) fstring server, share, user, password, workgroup; pstring path; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2046,14 +2059,15 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; } - if (!dir || !DLIST_CONTAINS(context->_files, dir)) { + if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; return -1; @@ -2110,7 +2124,8 @@ static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) struct smbc_dirent *dirent = (struct smbc_dirent *)offset; struct smbc_dir_list *list_ent = NULL; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2156,7 +2171,8 @@ static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) { - if (context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2178,7 +2194,8 @@ static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) fstring server, share, user, password; pstring path; - if (!context || context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return NULL; @@ -2215,8 +2232,8 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr int bytes, saverr, tot_bytes = 0; char buf[4096]; - if (!c_file || !c_file->_initialized || !c_print || - !c_print->_initialized) { + if (!c_file || !c_file->internal->_initialized || !c_print || + !c_print->internal->_initialized) { errno = EINVAL; return -1; @@ -2285,13 +2302,14 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr * Routine to list print jobs on a printer share ... */ -static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, void (*fn)(struct print_job_info *)) +static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn) { SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2321,7 +2339,7 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, void (* } - if (cli_print_queue(&srv->cli, fn) < 0) { + if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) { errno = smbc_errno(context, &srv->cli); return -1; @@ -2343,7 +2361,8 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id pstring path; int err; - if (!context || !context->_initialized) { + if (!context || !context->internal || + !context->internal->_initialized) { errno = EINVAL; return -1; @@ -2394,14 +2413,23 @@ SMBCCTX * smbc_new_context(void) { SMBCCTX * context; - context = malloc(sizeof(*context)); + context = malloc(sizeof(SMBCCTX)); if (!context) { errno = ENOMEM; return NULL; } - + ZERO_STRUCTP(context); + context->internal = malloc(sizeof(struct smbc_internal_data)); + if (!context->internal) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context->internal); + + /* ADD REASONABLE DEFAULTS */ context->debug = 0; context->timeout = 20000; /* 20 seconds */ @@ -2456,25 +2484,25 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) SMBCFILE * f; DEBUG(1,("Performing aggressive shutdown.\n")); - f = context->_files; + f = context->internal->_files; while (f) { context->close(context, f); f = f->next; } - context->_files = NULL; + context->internal->_files = NULL; /* First try to remove the servers the nice way. */ if (context->callbacks.purge_cached_fn(context)) { SMBCSRV * s; DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); - s = context->_servers; + s = context->internal->_servers; while (s) { cli_shutdown(&s->cli); context->callbacks.remove_cached_srv_fn(context, s); SAFE_FREE(s); s = s->next; } - context->_servers = NULL; + context->internal->_servers = NULL; } } else { @@ -2484,12 +2512,12 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) errno = EBUSY; return 1; } - if (context->_servers) { + if (context->internal->_servers) { DEBUG(1, ("Active servers in context, free_context failed.\n")); errno = EBUSY; return 1; } - if (context->_files) { + if (context->internal->_files) { DEBUG(1, ("Active files in context, free_context failed.\n")); errno = EBUSY; return 1; @@ -2502,6 +2530,7 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) SAFE_FREE(context->user); DEBUG(3, ("Context %p succesfully freed\n", context)); + SAFE_FREE(context->internal); SAFE_FREE(context); return 0; } @@ -2520,13 +2549,13 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) int pid; char *user = NULL, *home = NULL; - if (!context) { + if (!context || !context->internal) { errno = EBADF; return NULL; } /* Do not initialise the same client twice */ - if (context->_initialized) { + if (context->internal->_initialized) { return 0; } @@ -2633,7 +2662,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) * FIXME: Should we check the function pointers here? */ - context->_initialized = 1; + context->internal->_initialized = 1; return context; } -- cgit From 5bbac9dd802cc7a5a5b8a3c6edc4f1cee90c9de7 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 13 Jan 2003 20:30:28 +0000 Subject: Make sure that those cleanups actually went in. (This used to be commit 9a38e378115a1c36d0cd7c41f4c5767c23b4eb3f) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index edf582b34d..5ceb36795a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -70,7 +70,7 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, { static pstring s; pstring userinfo; - char *p; + const char *p; char *q, *r; int len; @@ -119,7 +119,7 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, r = strchr_m(p, '/'); if (q && (!r || q < r)) { pstring username, passwd, domain; - char *u = userinfo; + const char *u = userinfo; next_token(&p, userinfo, "@", sizeof(fstring)); -- cgit From 6d030555a113ea8b6bfac51d90dce6cd76719caa Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Jan 2003 02:51:37 +0000 Subject: query_alt_name takes a forced unicode string in win2000. It is not null terminated. Thanks to Metze for finding this. (This used to be commit e4ce26332b8f876e25ff9baf06d4767a473e2676) --- source3/libsmb/clirap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 792a3e7aa0..f8f840abaa 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -727,7 +727,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin return NT_STATUS_INVALID_NETWORK_RESPONSE; } - clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, 0); + clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, STR_UNICODE); SAFE_FREE(rdata); SAFE_FREE(rparam); -- cgit From 42d9c734240574247cf3363a5d8ee67a17c668bc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Jan 2003 03:02:18 +0000 Subject: merge alt_name patch from head (This used to be commit 20ebdee36d5351731698bdef6602fc73a45b1651) --- source3/libsmb/clirap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 792a3e7aa0..f8f840abaa 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -727,7 +727,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin return NT_STATUS_INVALID_NETWORK_RESPONSE; } - clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, 0); + clistr_pull(cli, alt_name, rdata+4, sizeof(fstring), len, STR_UNICODE); SAFE_FREE(rdata); SAFE_FREE(rparam); -- cgit From d645041d6345ff2802dd2f06ebed1d8f456fee23 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 14 Jan 2003 08:26:54 +0000 Subject: Merge from HEAD: - remove useless #else - signed/unsigned fixes - use an fstring for LM hash buffer. Andrew Bartlett (This used to be commit c0fb53c31fd7341745d14640e761affc5dae5230) --- source3/libsmb/smbencrypt.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 42250fc19c..a57a98e3ea 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -73,13 +73,14 @@ void E_md4hash(const char *passwd, uchar p16[16]) void E_deshash(const char *passwd, uchar p16[16]) { - uchar dospwd[15]; /* Password must not be > 14 chars long. */ + fstring dospwd; ZERO_STRUCT(dospwd); ZERO_STRUCTP(p16); /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16(dospwd, p16); ZERO_STRUCT(dospwd); @@ -122,33 +123,33 @@ BOOL ntv2_owf_gen(const uchar owf[16], smb_ucs2_t *user; smb_ucs2_t *domain; - int user_byte_len; - int domain_byte_len; + size_t user_byte_len; + size_t domain_byte_len; HMACMD5Context ctx; user_byte_len = push_ucs2_allocate(&user, user_in); - if (user_byte_len < 0) { - DEBUG(0, ("push_ucs2_allocate() for user returned %d (probably malloc() failure)\n", user_byte_len)); + if (user_byte_len == (size_t)-1) { + DEBUG(0, ("push_uss2_allocate() for user returned -1 (probably malloc() failure)\n")); return False; } domain_byte_len = push_ucs2_allocate(&domain, domain_in); - if (domain_byte_len < 0) { - DEBUG(0, ("push_ucs2_allocate() for domain returned %d (probably malloc() failure)\n", domain_byte_len)); + if (domain_byte_len == (size_t)-1) { + DEBUG(0, ("push_uss2_allocate() for domain returned -1 (probably malloc() failure)\n")); return False; } strupper_w(user); strupper_w(domain); + SMB_ASSERT(user_byte_len >= 2); + SMB_ASSERT(domain_byte_len >= 2); + /* We don't want null termination */ user_byte_len = user_byte_len - 2; domain_byte_len = domain_byte_len - 2; - SMB_ASSERT(user_byte_len >= 0); - SMB_ASSERT(domain_byte_len >= 0); - hmac_md5_init_limK_to_64(owf, 16, &ctx); hmac_md5_update((const unsigned char *)user, user_byte_len, &ctx); hmac_md5_update((const unsigned char *)domain, domain_byte_len, &ctx); -- cgit From 58fe4d9c20203f6f55c8e995402e156becb91b3e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 15 Jan 2003 12:52:38 +0000 Subject: Refactor the NTLMSSP code again - this time we use function pointers to eliminate the dependency on the auth subsystem. The next step is to add the required code to 'ntlm_auth', for export to Squid etc. Andrew Bartlett (This used to be commit 9e48ab86da40e4c1cafa70c04fb9ebdcce23dfab) --- source3/libsmb/cliconnect.c | 3 +- source3/libsmb/ntlmssp.c | 278 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 source3/libsmb/ntlmssp.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cc3aaf92be..389b7a1733 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -465,7 +465,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, neg_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM; + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_REQUEST_TARGET; memset(sess_key, 0, 16); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c new file mode 100644 index 0000000000..4183f3e77a --- /dev/null +++ b/source3/libsmb/ntlmssp.c @@ -0,0 +1,278 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + handle NLTMSSP, server side + + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2001-2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/** + * Default challange generation code. + * + */ + + +static const uint8 *get_challenge(void *cookie) +{ + static uchar chal[8]; + generate_random_buffer(chal, sizeof(chal), False); + + return chal; +} + +NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + ZERO_STRUCTP(*ntlmssp_state); + + (*ntlmssp_state)->mem_ctx = mem_ctx; + (*ntlmssp_state)->get_challenge = get_challenge; + + (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_domain = lp_workgroup; + + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + + SAFE_FREE((*ntlmssp_state)->user); + SAFE_FREE((*ntlmssp_state)->domain); + SAFE_FREE((*ntlmssp_state)->workstation); + + talloc_destroy(mem_ctx); + *ntlmssp_state = NULL; + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, + DATA_BLOB request, DATA_BLOB *reply) +{ + uint32 ntlmssp_command; + + if (!msrpc_parse(&request, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + return NT_STATUS_LOGON_FAILURE; + } + + if (ntlmssp_command == NTLMSSP_NEGOTIATE) { + return ntlmssp_negotiate(ntlmssp_state, request, reply); + } else if (ntlmssp_command == NTLMSSP_AUTH) { + return ntlmssp_auth(ntlmssp_state, request, reply); + } else { + return NT_STATUS_LOGON_FAILURE; + } +} + +static const char *ntlmssp_target_name(NTLMSSP_STATE *ntlmssp_state, + uint32 neg_flags, uint32 *chal_flags) +{ + if (neg_flags & NTLMSSP_REQUEST_TARGET) { + *chal_flags |= NTLMSSP_CHAL_TARGET_INFO; + *chal_flags |= NTLMSSP_REQUEST_TARGET; + if (lp_server_role() == ROLE_STANDALONE) { + *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; + return ntlmssp_state->get_global_myname(); + } else { + *chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN; + return ntlmssp_state->get_domain(); + }; + } else { + return ""; + } +} + +NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, + DATA_BLOB request, DATA_BLOB *reply) +{ + DATA_BLOB struct_blob; + fstring dnsname, dnsdomname; + uint32 ntlmssp_command, neg_flags, chal_flags; + char *cliname=NULL, *domname=NULL; + const uint8 *cryptkey; + const char *target_name; + + /* parse the NTLMSSP packet */ +#if 0 + file_save("ntlmssp_negotiate.dat", request.data, request.length); +#endif + + if (!msrpc_parse(&request, "CddAA", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &cliname, + &domname)) { + return NT_STATUS_LOGON_FAILURE; + } + + SAFE_FREE(cliname); + SAFE_FREE(domname); + + debug_ntlmssp_flags(neg_flags); + + cryptkey = ntlmssp_state->get_challenge(ntlmssp_state->auth_context); + + /* Give them the challenge. For now, ignore neg_flags and just + return the flags we want. Obviously this is not correct */ + + chal_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM; + + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + chal_flags |= NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->unicode = True; + } else { + chal_flags |= NTLMSSP_NEGOTIATE_OEM; + } + + target_name = ntlmssp_target_name(ntlmssp_state, + neg_flags, &chal_flags); + + /* This should be a 'netbios domain -> DNS domain' mapping */ + dnsdomname[0] = '\0'; + get_mydomname(dnsdomname); + strlower(dnsdomname); + + dnsname[0] = '\0'; + get_myfullname(dnsname); + strlower(dnsname); + + if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) + { + const char *target_name_dns = ""; + if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) { + target_name_dns = dnsdomname; + } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) { + target_name_dns = dnsname; + } + + /* the numbers here are the string type flags */ + msrpc_gen(&struct_blob, "aaaaa", + ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN, target_name, + ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN_DNS, target_name_dns, + ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsdomname, + ntlmssp_state->unicode, 0, ""); + } else { + struct_blob = data_blob(NULL, 0); + } + + { + const char *gen_string; + if (ntlmssp_state->unicode) { + gen_string = "CdUdbddB"; + } else { + gen_string = "CdAdbddB"; + } + + msrpc_gen(reply, gen_string, + "NTLMSSP", + NTLMSSP_CHALLENGE, + target_name, + chal_flags, + cryptkey, 8, + 0, 0, + struct_blob.data, struct_blob.length); + } + + data_blob_free(&struct_blob); + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, + DATA_BLOB request, DATA_BLOB *reply) +{ + DATA_BLOB sess_key; + uint32 ntlmssp_command, neg_flags; + NTSTATUS nt_status; + + const char *parse_string; + + /* parse the NTLMSSP packet */ +#if 0 + file_save("ntlmssp_auth.dat", request.data, request.length); +#endif + + if (ntlmssp_state->unicode) { + parse_string = "CdBBUUUBd"; + } else { + parse_string = "CdBBAAABd"; + } + + data_blob_free(&ntlmssp_state->lm_resp); + data_blob_free(&ntlmssp_state->nt_resp); + + SAFE_FREE(ntlmssp_state->user); + SAFE_FREE(ntlmssp_state->domain); + SAFE_FREE(ntlmssp_state->workstation); + + /* now the NTLMSSP encoded auth hashes */ + if (!msrpc_parse(&request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &ntlmssp_state->domain, + &ntlmssp_state->user, + &ntlmssp_state->workstation, + &sess_key, + &neg_flags)) { + return NT_STATUS_LOGON_FAILURE; + } + + data_blob_free(&sess_key); + + DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%d len2=%d\n", + ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, ntlmssp_state->lm_resp.length, ntlmssp_state->nt_resp.length)); + +#if 0 + file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length); + file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); +#endif + + nt_status = ntlmssp_state->check_password(ntlmssp_state->auth_context); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + + *reply = data_blob(NULL, 0); + + return nt_status; +} -- cgit From 4242eda183393b0535ac8ef880b4f441c60137af Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 17:22:48 +0000 Subject: merging some rpcclient and net functionality from HEAD (This used to be commit 7a4c87484237308cb3ad0d671687da7e0f6e733b) --- source3/libsmb/asn1.c | 2 +- source3/libsmb/clilist.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index b967927871..333d157905 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -407,7 +407,7 @@ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) return !data->has_error && (v == b); } -/* check a enumarted value is correct */ +/* write an enumarted value to the stream */ BOOL asn1_write_enumerated(ASN1_DATA *data, uint8 v) { if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4a1737af49..bf10be887a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -324,8 +324,10 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); - if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) - fstrcpy(finfo->short_name,finfo->name); + if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { + strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1); + finfo->short_name[sizeof(finfo->short_name)-1] = '\0'; + } return(DIR_STRUCT_SIZE); } -- cgit From 5fb59502585c68d03bf016d6a4470f2519f941d7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 18:31:46 +0000 Subject: small merges from SAMBA_3_0; mostly typos, renames, etc... (This used to be commit 9ac196dad4893b0ceef13281a140be5d85391e6c) --- source3/libsmb/namequery.c | 179 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 179 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f446453b9a..342a2a2926 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1001,6 +1001,7 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) BOOL lookup_dc_name(const char *srcname, const char *domain, struct in_addr *dc_ip, char *ret_name) { +#if !defined(I_HATE_WINDOWS_REPLY_CODE) fstring dc_name; BOOL ret; @@ -1024,6 +1025,184 @@ BOOL lookup_dc_name(const char *srcname, const char *domain, } return False; + +#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */ + +JRA - This code is broken with BDC rollover - we need to do a full +NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... + + int retries = 3; + int retry_time = 2000; + struct timeval tval; + struct packet_struct p; + struct dgram_packet *dgram = &p.packet.dgram; + char *ptr,*p2; + char tmp[4]; + int len; + struct sockaddr_in sock_name; + int sock_len = sizeof(sock_name); + const char *mailslot = NET_LOGON_MAILSLOT; + char *mailslot_name; + char buffer[1024]; + char *bufp; + int dgm_id = generate_trn_id(); + int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); + + if(sock == -1) + return False; + + /* Find out the transient UDP port we have been allocated. */ + if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) { + DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n", + strerror(errno))); + close(sock); + return False; + } + + /* + * Create the request data. + */ + + memset(buffer,'\0',sizeof(buffer)); + bufp = buffer; + SSVAL(bufp,0,QUERYFORPDC); + bufp += 2; + fstrcpy(bufp,srcname); + bufp += (strlen(bufp) + 1); + slprintf(bufp, sizeof(fstring)-1, "\\MAILSLOT\\NET\\GETDC%d", dgm_id); + mailslot_name = bufp; + bufp += (strlen(bufp) + 1); + bufp = ALIGN2(bufp, buffer); + bufp += push_ucs2(NULL, bufp, srcname, sizeof(buffer) - (bufp - buffer), STR_TERMINATE); + + SIVAL(bufp,0,1); + SSVAL(bufp,4,0xFFFF); + SSVAL(bufp,6,0xFFFF); + bufp += 8; + len = PTR_DIFF(bufp,buffer); + + memset((char *)&p,'\0',sizeof(p)); + + /* DIRECT GROUP or UNIQUE datagram. */ + dgram->header.msg_type = 0x10; + dgram->header.flags.node_type = M_NODE; + dgram->header.flags.first = True; + dgram->header.flags.more = False; + dgram->header.dgm_id = dgm_id; + dgram->header.source_ip = *iface_ip(*pdc_ip); + dgram->header.source_port = ntohs(sock_name.sin_port); + dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ + dgram->header.packet_offset = 0; + + make_nmb_name(&dgram->source_name,srcname,0); + make_nmb_name(&dgram->dest_name,domain,0x1C); + + ptr = &dgram->data[0]; + + /* Setup the smb part. */ + ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ + memcpy(tmp,ptr,4); + set_message(ptr,17,17 + len,True); + memcpy(ptr,tmp,4); + + CVAL(ptr,smb_com) = SMBtrans; + SSVAL(ptr,smb_vwv1,len); + SSVAL(ptr,smb_vwv11,len); + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); + SSVAL(ptr,smb_vwv13,3); + SSVAL(ptr,smb_vwv14,1); + SSVAL(ptr,smb_vwv15,1); + SSVAL(ptr,smb_vwv16,2); + p2 = smb_buf(ptr); + pstrcpy(p2,mailslot); + p2 = skip_string(p2,1); + + memcpy(p2,buffer,len); + p2 += len; + + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ + + p.ip = *pdc_ip; + p.port = DGRAM_PORT; + p.fd = sock; + p.timestamp = time(NULL); + p.packet_type = DGRAM_PACKET; + + GetTimeOfDay(&tval); + + if (!send_packet(&p)) { + DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); + close(sock); + return False; + } + + retries--; + + while (1) { + struct timeval tval2; + struct packet_struct *p_ret; + + GetTimeOfDay(&tval2); + if (TvalDiff(&tval,&tval2) > retry_time) { + if (!retries) + break; + if (!send_packet(&p)) { + DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); + close(sock); + return False; + } + GetTimeOfDay(&tval); + retries--; + } + + if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) { + struct dgram_packet *dgram2 = &p_ret->packet.dgram; + char *buf; + char *buf2; + + buf = &dgram2->data[0]; + buf -= 4; + + if (CVAL(buf,smb_com) != SMBtrans) { + DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int) + CVAL(buf,smb_com), (unsigned int)SMBtrans )); + free_packet(p_ret); + continue; + } + + len = SVAL(buf,smb_vwv11); + buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); + + if (len <= 0) { + DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len )); + free_packet(p_ret); + continue; + } + + DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n", + nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name), + inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len)); + + if(SVAL(buf2,0) != QUERYFORPDC_R) { + DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", + (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R )); + free_packet(p_ret); + continue; + } + + buf2 += 2; + /* Note this is safe as it is a bounded strcpy. */ + fstrcpy(ret_name, buf2); + ret_name[sizeof(fstring)-1] = '\0'; + close(sock); + free_packet(p_ret); + return True; + } + } + + close(sock); + return False; +#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ } /******************************************************** -- cgit From 99cdb462083381c88689a4e698ca48b6ed4cf5ac Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 18:57:41 +0000 Subject: *lots of small merges form HEAD *sync up configure.in *don't build torture tools in make all *make sure to remove torture tools as part of make clean (This used to be commit 0fb724b3216eeeb97e61ff12755ca3a31bcad6ef) --- source3/libsmb/clilist.c | 2 +- source3/libsmb/clireadwrite.c | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index bf10be887a..89ab5d6414 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -328,7 +328,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1); finfo->short_name[sizeof(finfo->short_name)-1] = '\0'; } - + return(DIR_STRUCT_SIZE); } diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index fb013734ac..0715aa7f1a 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -285,10 +285,13 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, SIVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv7,mode); + SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); /* - * THe following is still wrong ... + * According to CIFS-TR-1p00, this following field should only + * be set if CAP_LARGE_WRITEX is set. We should check this + * locally. However, this check might already have been + * done by our callers. */ - SSVAL(cli->outbuf,smb_vwv8,(mode & 0x0008) ? size : 0); SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1)); SSVAL(cli->outbuf,smb_vwv10,size); SSVAL(cli->outbuf,smb_vwv11, -- cgit From d456bec06ef5f59e3b20907679a4f5783a3da45e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 15 Jan 2003 20:39:33 +0000 Subject: Missed auth_ntlmssp.c in last night's checkin. Also keep track of the current challenge in the NTLMSSP context. Andrew Bartlett (This used to be commit ba13e058d4533b1ffba723b9e98e95090ad63d85) --- source3/libsmb/ntlmssp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 4183f3e77a..21f3612034 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -65,6 +65,7 @@ NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + data_blob_free(&(*ntlmssp_state)->chal); data_blob_free(&(*ntlmssp_state)->lm_resp); data_blob_free(&(*ntlmssp_state)->nt_resp); @@ -146,6 +147,9 @@ NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, cryptkey = ntlmssp_state->get_challenge(ntlmssp_state->auth_context); + data_blob_free(&ntlmssp_state->chal); + ntlmssp_state->chal = data_blob(cryptkey, 8); + /* Give them the challenge. For now, ignore neg_flags and just return the flags we want. Obviously this is not correct */ -- cgit From 30ddea1f05a83cde1dc3ef72583ec7ba04d1d013 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 16 Jan 2003 04:40:07 +0000 Subject: (missed in last commit) Change the 'cookie' to be the ntlmssp_context, and use the 'auth_context' on that to store the cookie. Ensures that simple callbacks can 'just work'. Also make it clear that we are doing a pull_string into a pstring, not just any sized buffer. Andrew Bartlett (This used to be commit c7793f27188e658b7fc6336aa51d367eab36fc17) --- source3/libsmb/clispnego.c | 2 +- source3/libsmb/ntlmssp.c | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6a5f6c00ae..f4a414ef52 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -749,7 +749,7 @@ BOOL msrpc_parse(DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); - head_ofs += pull_string(NULL, p, blob->data+head_ofs, -1, + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), blob->length - head_ofs, STR_ASCII|STR_TERMINATE); if (strcmp(s, p) != 0) { diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 21f3612034..6837674736 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -29,7 +29,7 @@ */ -static const uint8 *get_challenge(void *cookie) +static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) { static uchar chal[8]; generate_random_buffer(chal, sizeof(chal), False); @@ -57,6 +57,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->get_global_myname = global_myname; (*ntlmssp_state)->get_domain = lp_workgroup; + (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ return NT_STATUS_OK; } @@ -82,10 +83,12 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, DATA_BLOB request, DATA_BLOB *reply) { uint32 ntlmssp_command; - + *reply = data_blob(NULL, 0); + if (!msrpc_parse(&request, "Cd", "NTLMSSP", &ntlmssp_command)) { + return NT_STATUS_LOGON_FAILURE; } @@ -104,7 +107,7 @@ static const char *ntlmssp_target_name(NTLMSSP_STATE *ntlmssp_state, if (neg_flags & NTLMSSP_REQUEST_TARGET) { *chal_flags |= NTLMSSP_CHAL_TARGET_INFO; *chal_flags |= NTLMSSP_REQUEST_TARGET; - if (lp_server_role() == ROLE_STANDALONE) { + if (ntlmssp_state->server_role == ROLE_STANDALONE) { *chal_flags |= NTLMSSP_TARGET_TYPE_SERVER; return ntlmssp_state->get_global_myname(); } else { @@ -145,7 +148,7 @@ NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, debug_ntlmssp_flags(neg_flags); - cryptkey = ntlmssp_state->get_challenge(ntlmssp_state->auth_context); + cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); data_blob_free(&ntlmssp_state->chal); ntlmssp_state->chal = data_blob(cryptkey, 8); @@ -270,7 +273,7 @@ NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); #endif - nt_status = ntlmssp_state->check_password(ntlmssp_state->auth_context); + nt_status = ntlmssp_state->check_password(ntlmssp_state); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; -- cgit From a45db02a82a42d6ac616c3a1efe73272ccbd69b5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 19 Jan 2003 22:25:34 +0000 Subject: Merge in more of the SuSE patches for Heimdal. These changes show how to add a function without an explicit #ifdef HEIMDAL which I'm trying to avoid. Jeremy. (This used to be commit 77aeb262ef7c7cd3d206afe2d5445caaca943dfd) --- source3/libsmb/clikrb5.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index cca2a9cd3a..20d0906e71 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 + Copyright (C) Luke Howard 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +22,34 @@ #include "includes.h" #ifdef HAVE_KRB5 + +#ifndef KRB5_SET_REAL_TIME +/* + * This function is not in the Heimdal mainline. + */ +krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) +{ + krb5_error_code ret; + int32_t sec, usec; + + ret = krb5_us_timeofday(context, &sec, &usec); + if (ret) + return ret; + + context->kdc_sec_offset = seconds - sec; + context->kdc_usec_offset = microseconds - usec; + + return 0; +} +#endif + +#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) +krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) +{ + return krb5_set_default_in_tkt_etypes(ctx, enc); +} +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From 812e093f026a3575f00633c8d4d63b8bdb8a1bcb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 19 Jan 2003 22:27:32 +0000 Subject: Merge in more of the SuSE patches for Heimdal. These changes show how to add a function without an explicit #ifdef HEIMDAL which I'm trying to avoid. Jeremy. (This used to be commit 92ecd0bf0fe2cc4f6c86ca48e6e458e726470a50) --- source3/libsmb/clikrb5.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index cca2a9cd3a..20d0906e71 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 + Copyright (C) Luke Howard 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +22,34 @@ #include "includes.h" #ifdef HAVE_KRB5 + +#ifndef KRB5_SET_REAL_TIME +/* + * This function is not in the Heimdal mainline. + */ +krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) +{ + krb5_error_code ret; + int32_t sec, usec; + + ret = krb5_us_timeofday(context, &sec, &usec); + if (ret) + return ret; + + context->kdc_sec_offset = seconds - sec; + context->kdc_usec_offset = microseconds - usec; + + return 0; +} +#endif + +#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) +krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) +{ + return krb5_set_default_in_tkt_etypes(ctx, enc); +} +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From ebe53e592a1e7ad855774786efae253bd226c656 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 20 Jan 2003 19:31:01 +0000 Subject: should be HAVE_KRB5_SET_REAL_TIME (HAVE_ was missing)...fix the build (This used to be commit aceaaad1c2efce41fe0e03655b0ca0583788d7ab) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 20d0906e71..8b89763c3f 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -23,7 +23,7 @@ #ifdef HAVE_KRB5 -#ifndef KRB5_SET_REAL_TIME +#ifndef HAVE_KRB5_SET_REAL_TIME /* * This function is not in the Heimdal mainline. */ -- cgit From 51d3f6175041a3bf2d292997f137f129aaca83fb Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 20 Jan 2003 19:37:11 +0000 Subject: should be HAVE_KRB5_SET_REAL_TIME (HAVE_ was missing)...fix the build (This used to be commit 9f1f3cb8bb3d7d9b4fb414b06ad10356f775bb28) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 20d0906e71..8b89763c3f 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -23,7 +23,7 @@ #ifdef HAVE_KRB5 -#ifndef KRB5_SET_REAL_TIME +#ifndef HAVE_KRB5_SET_REAL_TIME /* * This function is not in the Heimdal mainline. */ -- cgit From e97e51f5fd05e533d064ab8dd68a9039f4d44d0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 06:23:10 +0000 Subject: More fixes getting us closer to full Heimdal compile.... Jeremy. (This used to be commit 193cc4f4fc876c66e97ea6b82bae431d0247c1fa) --- source3/libsmb/clikrb5.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 8b89763c3f..b56de62730 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -50,6 +50,26 @@ krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype } #endif +#if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) +/* HEIMDAL */ +void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) +{ + pkaddr->addr_type = KRB5_ADDRESS_INET; + pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); +} +#elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) +/* MIT */ +void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) +{ + pkaddr->addrtype = ADDRTYPE_INET; + pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->contents = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); +} +#else +__ERROR__XX__UNKNOWN_ADDRTYPE +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From b0aadff2020886cbc2a35bf115e6c359ff28d870 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 06:23:49 +0000 Subject: More fixes getting us closer to full Heimdal compile.... Jeremy. (This used to be commit a7ee6ed64500a0d949849da6996b7dc837518f00) --- source3/libsmb/clikrb5.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 8b89763c3f..b56de62730 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -50,6 +50,26 @@ krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype } #endif +#if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) +/* HEIMDAL */ +void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) +{ + pkaddr->addr_type = KRB5_ADDRESS_INET; + pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); +} +#elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) +/* MIT */ +void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) +{ + pkaddr->addrtype = ADDRTYPE_INET; + pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->contents = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); +} +#else +__ERROR__XX__UNKNOWN_ADDRTYPE +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From 18c2948bc536552ed2949f8fe1d06a72b9cc66dd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 13:33:31 +0000 Subject: Fixup proto generation to not include krb5 specific symbols if no kerberos selected. Noticed by Metze. Jeremy. (This used to be commit 0c98f779f05431ac4d298c9f021fca85d16aebae) --- source3/libsmb/clikrb5.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index b56de62730..2047efd704 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -27,7 +27,7 @@ /* * This function is not in the Heimdal mainline. */ -krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) + krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) { krb5_error_code ret; int32_t sec, usec; @@ -44,7 +44,7 @@ krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_ #endif #if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) -krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) + krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) { return krb5_set_default_in_tkt_etypes(ctx, enc); } @@ -52,7 +52,7 @@ krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* HEIMDAL */ -void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) + void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) { pkaddr->addr_type = KRB5_ADDRESS_INET; pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); @@ -60,14 +60,14 @@ void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) } #elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ -void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) + void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) { pkaddr->addrtype = ADDRTYPE_INET; pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); pkaddr->contents = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); } #else -__ERROR__XX__UNKNOWN_ADDRTYPE + __ERROR__XX__UNKNOWN_ADDRTYPE #endif /* -- cgit From e0762fe08d42c0cea38989973447b7e258fe4754 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 13:33:36 +0000 Subject: Fixup proto generation to not include krb5 specific symbols if no kerberos selected. Noticed by Metze. Jeremy. (This used to be commit 1684719695acb7168115b032fc1ec672509239ea) --- source3/libsmb/clikrb5.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index b56de62730..2047efd704 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -27,7 +27,7 @@ /* * This function is not in the Heimdal mainline. */ -krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) + krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) { krb5_error_code ret; int32_t sec, usec; @@ -44,7 +44,7 @@ krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_ #endif #if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) -krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) + krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) { return krb5_set_default_in_tkt_etypes(ctx, enc); } @@ -52,7 +52,7 @@ krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* HEIMDAL */ -void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) + void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) { pkaddr->addr_type = KRB5_ADDRESS_INET; pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); @@ -60,14 +60,14 @@ void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) } #elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ -void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) + void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) { pkaddr->addrtype = ADDRTYPE_INET; pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); pkaddr->contents = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); } #else -__ERROR__XX__UNKNOWN_ADDRTYPE + __ERROR__XX__UNKNOWN_ADDRTYPE #endif /* -- cgit From e545fe3c0aa1901026d5d11fa48d084e4cecde40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Jan 2003 20:43:26 +0000 Subject: Get closer to Heimdal compile... Damn. HEAD has different code in kerberos_verify... Jeremy. (This used to be commit e8c4098da619a1429cc4c8251761333a7c0f3458) --- source3/libsmb/clikrb5.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2047efd704..c948431509 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -70,6 +70,54 @@ __ERROR__XX__UNKNOWN_ADDRTYPE #endif +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_data salt, + krb5_encrypt_block eblock; + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; + } + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + return krb5_string_to_key(context, &eblock, key, password, &salt); +} +#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_salt salt; + + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; + } + return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, + salt, key); +} +#else + __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) + krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setkey(context, auth_context, keyblock); +} +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From 72ae2c115944f56066aa8776f64edfc12e0e19c1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 22 Jan 2003 14:34:00 +0000 Subject: fix for CR 1603; provide description of NT_STATUS_PIPE_NOT_AVAILABLE (This used to be commit b063acd9062704be6352647dae2ad801ecacec75) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index dbad05b91e..6274680f60 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -568,6 +568,7 @@ nt_err_code_struct nt_err_desc[] = { "Memory allocation error", NT_STATUS_NO_MEMORY }, { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Named pipe note available", NT_STATUS_PIPE_NOT_AVAILABLE }, { NULL, NT_STATUS(0) } }; -- cgit From 069ac159429ea943a0f97747439b4293c5593b1d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 22 Jan 2003 14:37:50 +0000 Subject: fix for CR 1603; provide description of NT_STATUS_PIPE_NOT_AVAILABLE (This used to be commit fcf63df8bfae37680ad7af48c65af62abc4e0020) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index dbad05b91e..6274680f60 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -568,6 +568,7 @@ nt_err_code_struct nt_err_desc[] = { "Memory allocation error", NT_STATUS_NO_MEMORY }, { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Named pipe note available", NT_STATUS_PIPE_NOT_AVAILABLE }, { NULL, NT_STATUS(0) } }; -- cgit From c79eccad91705526c69ff6bca14060718138c570 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 22 Jan 2003 23:32:33 +0000 Subject: Merge of kerberos changes to make this branch build again! (This used to be commit 51b319f57f28e3993919d7f3db0251a724902332) --- source3/libsmb/clikrb5.c | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index c948431509..2047efd704 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -70,54 +70,6 @@ __ERROR__XX__UNKNOWN_ADDRTYPE #endif -#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) - int create_kerberos_key_from_string(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key) -{ - int ret; - krb5_data salt, - krb5_encrypt_block eblock; - - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return ret; - } - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - return krb5_string_to_key(context, &eblock, key, password, &salt); -} -#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) - int create_kerberos_key_from_string(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key) -{ - int ret; - krb5_salt salt; - - ret = krb5_get_pw_salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); - return ret; - } - return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, - salt, key); -} -#else - __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS -#endif - -#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) - krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, - krb5_auth_context auth_context, - krb5_keyblock *keyblock) -{ - return krb5_auth_con_setkey(context, auth_context, keyblock); -} -#endif - /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From 1c4eacafbafd11afa1992cd1f18a421d7737139c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 23 Jan 2003 00:21:00 +0000 Subject: Fixed typo. (This used to be commit 9b11ede90129fab8311344ce8621556fd6cff7dc) --- source3/libsmb/nterr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 6274680f60..551c6d66ce 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -568,7 +568,7 @@ nt_err_code_struct nt_err_desc[] = { "Memory allocation error", NT_STATUS_NO_MEMORY }, { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, - { "Named pipe note available", NT_STATUS_PIPE_NOT_AVAILABLE }, + { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE }, { NULL, NT_STATUS(0) } }; -- cgit From f354d6469ae8ed92cc02418b2b7018b7d9f8c1f1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 23 Jan 2003 00:21:22 +0000 Subject: Fixed typo. (This used to be commit 09d8a8e87fbb13928b863f659381dddb09592985) --- source3/libsmb/nterr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 6274680f60..551c6d66ce 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -568,7 +568,7 @@ nt_err_code_struct nt_err_desc[] = { "Memory allocation error", NT_STATUS_NO_MEMORY }, { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, - { "Named pipe note available", NT_STATUS_PIPE_NOT_AVAILABLE }, + { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE }, { NULL, NT_STATUS(0) } }; -- cgit From 6cf8ac019ec5022455de7ec80e798baf552e291f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Jan 2003 18:15:18 +0000 Subject: Thanks Meeester Potter, for reverting *all* my Heimdal changes because I mistyped a comma :-). Jeremy. (This used to be commit 04cc149c756c396012cfa321a74724b077302b95) --- source3/libsmb/clikrb5.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2047efd704..663f6a8454 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -70,6 +70,54 @@ __ERROR__XX__UNKNOWN_ADDRTYPE #endif +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_data salt; + krb5_encrypt_block eblock; + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; + } + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + return krb5_string_to_key(context, &eblock, key, password, &salt); +} +#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_salt salt; + + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; + } + return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, + salt, key); +} +#else + __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) + krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setkey(context, auth_context, keyblock); +} +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From 755e33ee3f25884096d3fa2ac4bd4cf64a794903 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Jan 2003 00:33:21 +0000 Subject: Get smbd to link with Heimdal. Still missing some client progs... Jeremy. (This used to be commit 85dda434763bbcea260c800599e4b6b73afcf174) --- source3/libsmb/clikrb5.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 663f6a8454..24a24c66a6 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -118,6 +118,28 @@ } #endif + void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + if (tkt->enc_part2) + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); +#else + if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) + *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, + tkt->ticket.authorization_data->val->ad_data.length); +#endif +} + + krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + return tkt->enc_part2->client; +#else + return tkt->client; +#endif +} + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From b1bce451411486525e72ec71c5fd37fc0b463add Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Jan 2003 03:31:33 +0000 Subject: Finally we compile with Heimdal as well as MIT ! Wonder if it works... :-). Jeremy. (This used to be commit 1b71786c161cd8ec4c3c0c6b178370ed50feeef4) --- source3/libsmb/clikrb5.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 24a24c66a6..203d9d874b 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -140,6 +140,58 @@ #endif } +#if !defined(HAVE_KRB5_LOCATE_KDC) + krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + krb5_krbhst_handle hnd; + krb5_krbhst_info *hinfo; + krb5_error_code rc; + int num_kdcs, i; + struct sockaddr *sa; + + *addr_pp = NULL; + *naddrs = 0; + + rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); + if (rc) { + DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); + return rc; + } + + for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) + ; + + krb5_krbhst_reset(ctx, hnd); + + if (!num_kdcs) { + DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); + krb5_krbhst_free(ctx, hnd); + return -1; + } + + sa = malloc( sizeof(struct sockaddr) * num_kdcs ); + if (!sa) { + DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); + krb5_krbhst_free(ctx, hnd); + naddrs = 0; + return -1; + } + + memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + + for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { + if (hinfo->ai->ai_family == AF_INET) + memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); + } + + krb5_krbhst_free(ctx, hnd); + + *naddrs = num_kdcs; + *addr_pp = sa; + return 0; +} +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From dc4bb3bed82773ab0a07eb72b3d21305cccb6ecf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Jan 2003 03:37:14 +0000 Subject: Factor out common code in the NTLMSSP/SPNEGO code. The idea here is to seperate, as much as possible, the SPNEGO layer from the NTLMSSP layer. This not only helps us with protocol correctness, but also should allow further mechinisms to be added with relitive ease. I indend to make the kerberos code use this shortly. I've never seen the 'zero length blob' form of the anonymous login, so I've removed that case. Andrew Bartlett (This used to be commit a8773c9f825539c5bc17e4200b16d7ebbe0b7620) --- source3/libsmb/clispnego.c | 67 +++++++++++++--------------------------------- source3/libsmb/ntlmssp.c | 4 --- 2 files changed, 18 insertions(+), 53 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index f4a414ef52..3e28baa417 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -386,51 +386,6 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, } -/* - generate a spnego NTLMSSP challenge packet given two security blobs - The second challenge is optional -*/ -BOOL spnego_gen_challenge(DATA_BLOB *blob, - DATA_BLOB *chal1, DATA_BLOB *chal2) -{ - ASN1_DATA data; - - ZERO_STRUCT(data); - - asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_push_tag(&data,ASN1_SEQUENCE(0)); - - asn1_push_tag(&data,ASN1_CONTEXT(0)); - asn1_write_enumerated(&data,1); - asn1_pop_tag(&data); - - asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); - asn1_pop_tag(&data); - - asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, chal1->data, chal1->length); - asn1_pop_tag(&data); - - /* the second challenge is optional (XP doesn't send it) */ - if (chal2) { - asn1_push_tag(&data,ASN1_CONTEXT(3)); - asn1_write_OctetString(&data, chal2->data, chal2->length); - asn1_pop_tag(&data); - } - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - if (data.has_error) { - return False; - } - - *blob = data_blob(data.data, data.length); - asn1_free(&data); - return True; -} - /* generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords */ @@ -485,23 +440,37 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) /* generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) { ASN1_DATA data; DATA_BLOB ret; + uint8 negResult; - memset(&data, 0, sizeof(data)); + if (NT_STATUS_IS_OK(nt_status)) { + negResult = SPNGEO_NEG_RESULT_ACCEPT; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + negResult = SPNGEO_NEG_RESULT_INCOMPLETE; + } else { + negResult = SPNGEO_NEG_RESULT_REJECT; + } + + ZERO_STRUCT(data); asn1_push_tag(&data, ASN1_CONTEXT(1)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_enumerated(&data, ntlmssp_reply->length ? 1 : 0); + asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (ntlmssp_reply->length) { + if (negResult == SPNGEO_NEG_RESULT_INCOMPLETE) { + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_write_OID(&data, OID_NTLMSSP); + asn1_pop_tag(&data); + asn1_push_tag(&data,ASN1_CONTEXT(2)); asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); asn1_pop_tag(&data); } + asn1_pop_tag(&data); asn1_pop_tag(&data); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 6837674736..5b608e0a7a 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -275,10 +275,6 @@ NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, nt_status = ntlmssp_state->check_password(ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { - return nt_status; - } - *reply = data_blob(NULL, 0); return nt_status; -- cgit From 1cba0a757970ffd8b81d61c88965010968ab3eff Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Jan 2003 12:07:02 +0000 Subject: Merge from HEAD: - NTLMSSP over SPENGO (sesssion-setup-and-x) cleanup and code refactor. - also consequential changes to the NTLMSSP and SPNEGO parsing functions - and the client code that uses the same functions - Add ntlm_auth, a NTLMSSP authentication interface for use by applications like Squid and Apache. - also consquential changes to use common code for base64 encode/decode. - Winbind changes to support ntlm_auth (I don't want this program to need to read smb.conf, instead getting all it's details over the pipe). - nmbd changes for fstrcat() instead of fstrcpy(). Andrew Bartlett (This used to be commit fbb46da79cf322570a7e3318100c304bbf33409e) --- source3/libsmb/cliconnect.c | 7 +-- source3/libsmb/clispnego.c | 124 +++++++++++++++++++++++--------------------- 2 files changed, 68 insertions(+), 63 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b758af41c4..389b7a1733 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -465,7 +465,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, neg_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM; + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_REQUEST_TARGET; memset(sess_key, 0, 16); @@ -476,8 +477,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, "NTLMSSP", NTLMSSP_NEGOTIATE, neg_flags, - workgroup, strlen(workgroup), - cli->calling.name, strlen(cli->calling.name) + 1); + workgroup, + cli->calling.name); DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n", neg_flags, workgroup, cli->calling.name)); /* and wrap it in a SPNEGO wrapper */ diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 55f49c5987..3e28baa417 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -386,51 +386,6 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, } -/* - generate a spnego NTLMSSP challenge packet given two security blobs - The second challenge is optional -*/ -BOOL spnego_gen_challenge(DATA_BLOB *blob, - DATA_BLOB *chal1, DATA_BLOB *chal2) -{ - ASN1_DATA data; - - ZERO_STRUCT(data); - - asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_push_tag(&data,ASN1_SEQUENCE(0)); - - asn1_push_tag(&data,ASN1_CONTEXT(0)); - asn1_write_enumerated(&data,1); - asn1_pop_tag(&data); - - asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); - asn1_pop_tag(&data); - - asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, chal1->data, chal1->length); - asn1_pop_tag(&data); - - /* the second challenge is optional (XP doesn't send it) */ - if (chal2) { - asn1_push_tag(&data,ASN1_CONTEXT(3)); - asn1_write_OctetString(&data, chal2->data, chal2->length); - asn1_pop_tag(&data); - } - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - if (data.has_error) { - return False; - } - - *blob = data_blob(data.data, data.length); - asn1_free(&data); - return True; -} - /* generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords */ @@ -485,18 +440,37 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) /* generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(void) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) { ASN1_DATA data; DATA_BLOB ret; + uint8 negResult; - memset(&data, 0, sizeof(data)); + if (NT_STATUS_IS_OK(nt_status)) { + negResult = SPNGEO_NEG_RESULT_ACCEPT; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + negResult = SPNGEO_NEG_RESULT_INCOMPLETE; + } else { + negResult = SPNGEO_NEG_RESULT_REJECT; + } + + ZERO_STRUCT(data); asn1_push_tag(&data, ASN1_CONTEXT(1)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_enumerated(&data, 0); + asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); + if (negResult == SPNGEO_NEG_RESULT_INCOMPLETE) { + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_write_OID(&data, OID_NTLMSSP); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(2)); + asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -514,8 +488,9 @@ DATA_BLOB spnego_gen_auth_response(void) format specifiers are: U = unicode string (input is unix string) - a = address (1 byte type, 1 byte length, unicode string, all inline) - A = ASCII string (pointer + length) Actually same as B + a = address (input is BOOL unicode, char *unix_string) + (1 byte type, 1 byte length, unicode/ASCII string, all inline) + A = ASCII string (input is unix string) B = data blob (pointer + length) b = data blob in header (pointer + length) D @@ -531,6 +506,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, uint8 *b; int head_size=0, data_size=0; int head_ofs, data_ofs; + BOOL unicode; /* first scan the format to work out the header and body size */ va_start(ap, format); @@ -541,12 +517,21 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += str_charnum(s) * 2; break; + case 'A': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_ascii_charnum(s); + break; case 'a': + unicode = va_arg(ap, BOOL); n = va_arg(ap, int); s = va_arg(ap, char *); - data_size += (str_charnum(s) * 2) + 4; + if (unicode) { + data_size += (str_charnum(s) * 2) + 4; + } else { + data_size += (str_ascii_charnum(s)) + 4; + } break; - case 'A': case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -586,20 +571,39 @@ BOOL msrpc_gen(DATA_BLOB *blob, push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); data_ofs += n*2; break; + case 'A': + s = va_arg(ap, char *); + n = str_ascii_charnum(s); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + data_ofs += n; + break; case 'a': + unicode = va_arg(ap, BOOL); n = va_arg(ap, int); SSVAL(blob->data, data_ofs, n); data_ofs += 2; s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); + if (unicode) { + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + } else { + n = str_ascii_charnum(s); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n, + STR_ASCII|STR_NOALIGN); + } + data_ofs += n; } - data_ofs += n*2; break; - case 'A': case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -714,7 +718,7 @@ BOOL msrpc_parse(DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); - head_ofs += pull_string(NULL, p, blob->data+head_ofs, -1, + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), blob->length - head_ofs, STR_ASCII|STR_TERMINATE); if (strcmp(s, p) != 0) { -- cgit From cf292aead6bdcced9deac62c50b25e83779d9741 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 30 Jan 2003 04:40:12 +0000 Subject: Sync of Heimdal kerberos stuff with HEAD. If this breaks I'm blaming the dog again. (This used to be commit 6f89ee2c9dc7f03e3dbe7aa734bf67c6a434d135) --- source3/libsmb/clikrb5.c | 122 ----------------------------------------------- 1 file changed, 122 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 203d9d874b..2047efd704 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -70,128 +70,6 @@ __ERROR__XX__UNKNOWN_ADDRTYPE #endif -#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) - int create_kerberos_key_from_string(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key) -{ - int ret; - krb5_data salt; - krb5_encrypt_block eblock; - - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return ret; - } - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); - return krb5_string_to_key(context, &eblock, key, password, &salt); -} -#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) - int create_kerberos_key_from_string(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key) -{ - int ret; - krb5_salt salt; - - ret = krb5_get_pw_salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); - return ret; - } - return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, - salt, key); -} -#else - __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS -#endif - -#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) - krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, - krb5_auth_context auth_context, - krb5_keyblock *keyblock) -{ - return krb5_auth_con_setkey(context, auth_context, keyblock); -} -#endif - - void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) -{ -#if defined(HAVE_KRB5_TKT_ENC_PART2) - if (tkt->enc_part2) - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); -#else - if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) - *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, - tkt->ticket.authorization_data->val->ad_data.length); -#endif -} - - krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) -{ -#if defined(HAVE_KRB5_TKT_ENC_PART2) - return tkt->enc_part2->client; -#else - return tkt->client; -#endif -} - -#if !defined(HAVE_KRB5_LOCATE_KDC) - krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) -{ - krb5_krbhst_handle hnd; - krb5_krbhst_info *hinfo; - krb5_error_code rc; - int num_kdcs, i; - struct sockaddr *sa; - - *addr_pp = NULL; - *naddrs = 0; - - rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); - if (rc) { - DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); - return rc; - } - - for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) - ; - - krb5_krbhst_reset(ctx, hnd); - - if (!num_kdcs) { - DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); - krb5_krbhst_free(ctx, hnd); - return -1; - } - - sa = malloc( sizeof(struct sockaddr) * num_kdcs ); - if (!sa) { - DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); - krb5_krbhst_free(ctx, hnd); - naddrs = 0; - return -1; - } - - memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); - - for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { - if (hinfo->ai->ai_family == AF_INET) - memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); - } - - krb5_krbhst_free(ctx, hnd); - - *naddrs = num_kdcs; - *addr_pp = sa; - return 0; -} -#endif - /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From f6fbf0c9dbe859603ed7bc5d08844dda195d3b98 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Jan 2003 18:01:03 +0000 Subject: Revert tpot's breakage of the Heimdal fixes. Jeremy. (This used to be commit 90336900ad2a6d50e1d42f7bc59fdc7c762187d3) --- source3/libsmb/clikrb5.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2047efd704..203d9d874b 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -70,6 +70,128 @@ __ERROR__XX__UNKNOWN_ADDRTYPE #endif +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_data salt; + krb5_encrypt_block eblock; + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; + } + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + return krb5_string_to_key(context, &eblock, key, password, &salt); +} +#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_salt salt; + + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; + } + return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, + salt, key); +} +#else + __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) + krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setkey(context, auth_context, keyblock); +} +#endif + + void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + if (tkt->enc_part2) + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); +#else + if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) + *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, + tkt->ticket.authorization_data->val->ad_data.length); +#endif +} + + krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + return tkt->enc_part2->client; +#else + return tkt->client; +#endif +} + +#if !defined(HAVE_KRB5_LOCATE_KDC) + krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + krb5_krbhst_handle hnd; + krb5_krbhst_info *hinfo; + krb5_error_code rc; + int num_kdcs, i; + struct sockaddr *sa; + + *addr_pp = NULL; + *naddrs = 0; + + rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); + if (rc) { + DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); + return rc; + } + + for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) + ; + + krb5_krbhst_reset(ctx, hnd); + + if (!num_kdcs) { + DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); + krb5_krbhst_free(ctx, hnd); + return -1; + } + + sa = malloc( sizeof(struct sockaddr) * num_kdcs ); + if (!sa) { + DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); + krb5_krbhst_free(ctx, hnd); + naddrs = 0; + return -1; + } + + memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + + for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { + if (hinfo->ai->ai_family == AF_INET) + memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); + } + + krb5_krbhst_free(ctx, hnd); + + *naddrs = num_kdcs; + *addr_pp = sa; + return 0; +} +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From 0414b4ac93e1920bcd76a2d7d3466d3986a9eda9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Jan 2003 18:01:23 +0000 Subject: Stop tpot from trampling over my Heimdal fixes by moving some of them to HEAD :-). Jeremy. (This used to be commit 1fec0f50ed0e750afec5cdf551fcd37ef4858e94) --- source3/libsmb/clikrb5.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2047efd704..203d9d874b 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -70,6 +70,128 @@ __ERROR__XX__UNKNOWN_ADDRTYPE #endif +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_data salt; + krb5_encrypt_block eblock; + + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; + } + krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + return krb5_string_to_key(context, &eblock, key, password, &salt); +} +#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) + int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key) +{ + int ret; + krb5_salt salt; + + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; + } + return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, + salt, key); +} +#else + __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) + krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, + krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setkey(context, auth_context, keyblock); +} +#endif + + void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + if (tkt->enc_part2) + *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, + tkt->enc_part2->authorization_data[0]->length); +#else + if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) + *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, + tkt->ticket.authorization_data->val->ad_data.length); +#endif +} + + krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + return tkt->enc_part2->client; +#else + return tkt->client; +#endif +} + +#if !defined(HAVE_KRB5_LOCATE_KDC) + krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + krb5_krbhst_handle hnd; + krb5_krbhst_info *hinfo; + krb5_error_code rc; + int num_kdcs, i; + struct sockaddr *sa; + + *addr_pp = NULL; + *naddrs = 0; + + rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); + if (rc) { + DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); + return rc; + } + + for ( num_kdcs = 0; (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); num_kdcs++) + ; + + krb5_krbhst_reset(ctx, hnd); + + if (!num_kdcs) { + DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); + krb5_krbhst_free(ctx, hnd); + return -1; + } + + sa = malloc( sizeof(struct sockaddr) * num_kdcs ); + if (!sa) { + DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); + krb5_krbhst_free(ctx, hnd); + naddrs = 0; + return -1; + } + + memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + + for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { + if (hinfo->ai->ai_family == AF_INET) + memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); + } + + krb5_krbhst_free(ctx, hnd); + + *naddrs = num_kdcs; + *addr_pp = sa; + return 0; +} +#endif + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -- cgit From 2f5d3e7a64a7f756aa289294050e57b34c6dfb17 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 1 Feb 2003 13:01:31 +0000 Subject: We now have client-side SMB signing support! This checking allows us to connect to Microsoft servers the use SMB signing, within a few restrictions: - I've not get the NTLMSSP stuff going - it appears to work, but if you break the sig - say by writing a zero in it - it still passes... - We don't currently verfiy the server's reply - It works against one of my test servers, but not the other... However, it provides an excellent basis to work from. Enable it with 'client signing' in your smb.conf. Doc to come (tomorrow) and this is not for 3.0, till we get it complete. The CIFS Spec is misleading - the session key (for NTLMv1 at least) is the standard session key, ie MD4(NT#). Thanks to jra for the early work on this. Andrew Bartlett (This used to be commit 1a2738937e3d80b378bd0ed33cd8d395fba2d3c3) --- source3/libsmb/cliconnect.c | 5 ++++- source3/libsmb/clientgen.c | 7 ++++--- source3/libsmb/smbencrypt.c | 11 +++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 389b7a1733..c13881bc21 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -942,7 +942,10 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) + cli->sign_info.negotiated_smb_signing = True; + + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) && cli->sign_info.allow_smb_signing) cli->sign_info.negotiated_smb_signing = True; } else if (cli->protocol >= PROTOCOL_LANMAN1) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ed1286d627..3d0bad6c99 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -249,15 +249,16 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (lp_use_spnego()) cli->use_spnego = True; + cli->capabilities = CAP_UNICODE | CAP_STATUS32; + /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 ones. This intended only as a temporary hack. */ if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - /* A way to attempt to force SMB signing */ - if (getenv("CLI_FORCE_SMB_SIGNING")) - cli->sign_info.negotiated_smb_signing = True; + if (lp_client_signing()) + cli->sign_info.allow_smb_signing = True; if (!cli->outbuf || !cli->inbuf) goto error; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index a57a98e3ea..022a57ef6a 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -362,10 +362,12 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, SMB signing - setup the MAC key. ************************************************************/ -void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uchar resp[24]) +void cli_calculate_mac_key(struct cli_state *cli, const char *plain_passwd, const uchar resp[24]) { - /* Get first 16 bytes. */ - E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); + uchar nt_hash[16]; + E_md4hash(plain_passwd, nt_hash); + + mdfour(&cli->sign_info.mac_key[0], nt_hash, sizeof(nt_hash)); memcpy(&cli->sign_info.mac_key[16],resp,24); cli->sign_info.mac_key_len = 40; cli->sign_info.use_smb_signing = True; @@ -375,7 +377,7 @@ void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uc cli->writebraw_supported = False; /* Reset the sequence number in case we had a previous (aborted) attempt */ - cli->sign_info.send_seq_num = 0; + cli->sign_info.send_seq_num = 2; } /*********************************************************** @@ -411,6 +413,7 @@ void cli_caclulate_sign_mac(struct cli_state *cli) MD5Final(calc_md5_mac, &md5_ctx); memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signitures...*/ cli->sign_info.send_seq_num++; -- cgit From ac2eeb7a8f49d389e024af82184b86e79bfd8976 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 2 Feb 2003 00:11:12 +0000 Subject: More signing updates - start checking that the server isn't being spoofed. Andrew Bartlett (This used to be commit b1c722e306533babeffeba9d8c7dcfa00e019423) --- source3/libsmb/clientgen.c | 5 ++++- source3/libsmb/smbencrypt.c | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3d0bad6c99..b35c7ea2ed 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -114,9 +114,12 @@ BOOL cli_receive_smb(struct cli_state *cli) cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; + return ret; } - return ret; + if (!cli_check_sign_mac(cli)) { + DEBUG(0, ("SMB Signiture verification failed on incoming packet!\n")); + }; } /**************************************************************************** diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 022a57ef6a..a30a48a020 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -5,6 +5,7 @@ Modified by Jeremy Allison 1995. Copyright (C) Jeremy Allison 1995-2000. Copyright (C) Luke Kennethc Casson Leighton 1996-2000. + Copyright (C) Andrew Bartlett 2002-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -420,3 +421,40 @@ void cli_caclulate_sign_mac(struct cli_state *cli) cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; cli->sign_info.send_seq_num++; } + +/*********************************************************** + SMB signing - check a MAC sent by server. +************************************************************/ + +BOOL cli_check_sign_mac(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + unsigned char server_sent_mac[8]; + struct MD5Context md5_ctx; + + if (cli->sign_info.temp_smb_signing) { + return True; + } + + if (!cli->sign_info.use_smb_signing) { + return True; + } + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + + SIVAL(cli->inbuf, smb_ss_field, cli->sign_info.reply_seq_num); + SIVAL(cli->inbuf, smb_ss_field + 4, 0); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + return (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); +} -- cgit From 809bb276adfbe71d2f7461c9f6ee4da68ab68d84 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 2 Feb 2003 11:11:24 +0000 Subject: Add some return values, and don't attempt signing for NTLMSSP yet (it uses a different algorithm). Andrew Bartlett (This used to be commit e6f87c7ee5c61f03f81159a8017d31f439c4454a) --- source3/libsmb/cliconnect.c | 4 +--- source3/libsmb/clientgen.c | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c13881bc21..ebe19b5143 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -464,7 +464,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, pstring server_domain; /* FIX THIS, SHOULD be UCS2-LE */ neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET; @@ -573,8 +573,6 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, if (cli_is_error(cli)) return False; - set_signing_on_cli(cli, pass, nthash); - return True; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b35c7ea2ed..ab051426ae 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -119,7 +119,9 @@ BOOL cli_receive_smb(struct cli_state *cli) if (!cli_check_sign_mac(cli)) { DEBUG(0, ("SMB Signiture verification failed on incoming packet!\n")); + return False; }; + return True; } /**************************************************************************** -- cgit From 868d169a4084c24924a419adc46a54f721aa2efd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Feb 2003 12:26:58 +0000 Subject: (only for HEAD at the moment). Add NTLMv2 support to our client, used when so configured ('client use NTLMv2 = yes') and only when 'client use spengo = no'. (A new option to allow the client and server ends to chose spnego seperatly). NTLMv2 signing doesn't yet work, and NTLMv2 is not done for NTLMSSP yet. Also some parinoia checks in our input parsing. Andrew Bartlett (This used to be commit 85e9c060eab59c7692198f14a447ad59f05af437) --- source3/libsmb/cliconnect.c | 138 +++++++++++++++++++++++++++++++++---------- source3/libsmb/clientgen.c | 4 +- source3/libsmb/clispnego.c | 3 +- source3/libsmb/ntlmssp.c | 139 ++++++++++++++++++++++---------------------- source3/libsmb/smbencrypt.c | 12 ++-- 5 files changed, 186 insertions(+), 110 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ebe19b5143..1c89423b7f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 - Copyright (C) Andrew Barteltt 2001-2002 + Copyright (C) Andrew Barteltt 2001-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,7 +45,7 @@ static const struct { ****************************************************************************/ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, - const char *pass, int passlen, const char *workgroup) + const char *pass, size_t passlen, const char *workgroup) { fstring pword; char *p; @@ -228,7 +228,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 response[24]) +static void set_signing_on_cli (struct cli_state *cli, uint8 user_session_key[16], DATA_BLOB response) { uint8 zero_sig[8]; ZERO_STRUCT(zero_sig); @@ -242,7 +242,7 @@ static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 r DEBUG(3, ("smb signing enabled!\n")); cli->sign_info.use_smb_signing = True; - cli_calculate_mac_key(cli, pass, response); + cli_calculate_mac_key(cli, user_session_key, response); } else { DEBUG(5, ("smb signing NOT enabled!\n")); } @@ -265,25 +265,90 @@ static void set_temp_signing_on_cli(struct cli_state *cli) ****************************************************************************/ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, - const char *pass, int passlen, - const char *ntpass, int ntpasslen, + const char *pass, size_t passlen, + const char *ntpass, size_t ntpasslen, const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); - uchar pword[24]; - uchar ntpword[24]; + DATA_BLOB lm_response = data_blob(NULL, 0); + DATA_BLOB nt_response = data_blob(NULL, 0); + uchar user_session_key[16]; char *p; BOOL have_plaintext = False; - if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) - return False; - if (passlen != 24) { - /* non encrypted password supplied. Ignore ntpass. */ - passlen = 24; - ntpasslen = 24; - SMBencrypt(pass,cli->secblob.data,pword); - SMBNTencrypt(pass,cli->secblob.data,ntpword); + uchar nt_hash[16]; + E_md4hash(pass, nt_hash); + + if (lp_client_ntlmv2_auth()) { + uchar ntlm_v2_hash[16]; + uchar ntlmv2_response[16]; + uchar lmv2_response[16]; + DATA_BLOB ntlmv2_client_data; + DATA_BLOB lmv2_client_data; + DATA_BLOB server_chal; + + /* We don't use the NT# directly. Instead we use it mashed up with + the username and domain. + This prevents username swapping during the auth exchange + */ + if (!ntv2_owf_gen(nt_hash, user, workgroup, ntlm_v2_hash)) { + return False; + } + + server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); + + /* NTLMv2 */ + + /* We also get to specify some random data */ + ntlmv2_client_data = data_blob(NULL, 20); + generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False); + memset(ntlmv2_client_data.data, 'A', ntlmv2_client_data.length); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response); + + /* put it into nt_response, for the code below to put into the packet */ + nt_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response)); + memcpy(nt_response.data, ntlmv2_response, sizeof(ntlmv2_response)); + /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */ + memcpy(nt_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); + data_blob_free(&ntlmv2_client_data); + + + /* LMv2 */ + + /* We also get to specify some random data, but only 8 bytes (24 byte total response) */ + lmv2_client_data = data_blob(NULL, 8); + generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False); + memset(lmv2_client_data.data, 'B', lmv2_client_data.length); + + /* Calculate response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, lmv2_client_data, lmv2_response); + + /* Calculate response */ + lm_response = data_blob(NULL, lmv2_client_data.length + sizeof(lmv2_response)); + memcpy(lm_response.data, lmv2_response, sizeof(lmv2_response)); + /* after the first 16 bytes is the 8 bytes of random data we made above */ + memcpy(lm_response.data + sizeof(lmv2_response), lmv2_client_data.data, lmv2_client_data.length); + data_blob_free(&lmv2_client_data); + + data_blob_free(&server_chal); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + SMBsesskeygen_ntv2(ntlm_v2_hash, ntlmv2_response, user_session_key); + + } else { + /* non encrypted password supplied. Ignore ntpass. */ + if (lp_client_lanman_auth()) { + lm_response = data_blob(NULL, 24); + SMBencrypt(pass,cli->secblob.data,lm_response.data); + } + + nt_response = data_blob(NULL, 24); + SMBNTencrypt(pass,cli->secblob.data,nt_response.data); + SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key); + } have_plaintext = True; set_temp_signing_on_cli(cli); @@ -291,11 +356,9 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, /* pre-encrypted password supplied. Only used for security=server, can't do signing becouse we don't have oringial key */ - memcpy(pword, pass, 24); - if (ntpasslen == 24) - memcpy(ntpword, ntpass, 24); - else - ZERO_STRUCT(ntpword); + + lm_response = data_blob(pass, passlen); + nt_response = data_blob(ntpass, ntpasslen); } /* send a session setup command */ @@ -310,28 +373,35 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - SSVAL(cli->outbuf,smb_vwv8,ntpasslen); + SSVAL(cli->outbuf,smb_vwv7,lm_response.length); + SSVAL(cli->outbuf,smb_vwv8,nt_response.length); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); p += passlen; - memcpy(p,ntpword,ntpasslen); p += ntpasslen; + if (lm_response.length) { + memcpy(p,lm_response.data, lm_response.length); p += lm_response.length; + } + if (nt_response.length) { + memcpy(p,nt_response.data, nt_response.length); p += nt_response.length; + } p += clistr_push(cli, p, user, -1, STR_TERMINATE); p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - if (!cli_send_smb(cli)) - return False; - - if (!cli_receive_smb(cli)) + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + data_blob_free(&lm_response); + data_blob_free(&nt_response); return False; + } show_msg(cli->inbuf); - if (cli_is_error(cli)) + if (cli_is_error(cli)) { + data_blob_free(&lm_response); + data_blob_free(&nt_response); return False; + } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -345,9 +415,11 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (have_plaintext) { /* Have plaintext orginal */ - set_signing_on_cli(cli, pass, ntpword); + set_signing_on_cli(cli, user_session_key, nt_response); } + data_blob_free(&lm_response); + data_blob_free(&nt_response); return True; } @@ -529,6 +601,10 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, return False; } + if (challenge_blob.length < 8) { + return False; + } + DEBUG(10, ("Challenge:\n")); dump_data(10, challenge_blob.data, 8); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ab051426ae..9598f4ac96 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -251,8 +251,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - if (lp_use_spnego()) - cli->use_spnego = True; + + cli->use_spnego = lp_client_use_spnego(); cli->capabilities = CAP_UNICODE | CAP_STATUS32; diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 3e28baa417..277bf4765f 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -709,7 +709,8 @@ BOOL msrpc_parse(DATA_BLOB *blob, case 'b': b = (DATA_BLOB *)va_arg(ap, void *); len1 = va_arg(ap, unsigned); - *b = data_blob(blob->data + head_ofs, len1); + *b = data_blob(blob->data + head_ofs, + MIN(len1, blob->length - head_ofs)); head_ofs += len1; break; case 'd': diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 5b608e0a7a..886f872764 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -37,71 +37,7 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) return chal; } -NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("NTLMSSP context"); - - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); - if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_start: talloc failed!\n")); - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - ZERO_STRUCTP(*ntlmssp_state); - - (*ntlmssp_state)->mem_ctx = mem_ctx; - (*ntlmssp_state)->get_challenge = get_challenge; - - (*ntlmssp_state)->get_global_myname = global_myname; - (*ntlmssp_state)->get_domain = lp_workgroup; - (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ - - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); - - SAFE_FREE((*ntlmssp_state)->user); - SAFE_FREE((*ntlmssp_state)->domain); - SAFE_FREE((*ntlmssp_state)->workstation); - - talloc_destroy(mem_ctx); - *ntlmssp_state = NULL; - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) -{ - uint32 ntlmssp_command; - *reply = data_blob(NULL, 0); - - if (!msrpc_parse(&request, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - - return NT_STATUS_LOGON_FAILURE; - } - - if (ntlmssp_command == NTLMSSP_NEGOTIATE) { - return ntlmssp_negotiate(ntlmssp_state, request, reply); - } else if (ntlmssp_command == NTLMSSP_AUTH) { - return ntlmssp_auth(ntlmssp_state, request, reply); - } else { - return NT_STATUS_LOGON_FAILURE; - } -} - -static const char *ntlmssp_target_name(NTLMSSP_STATE *ntlmssp_state, +static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, uint32 neg_flags, uint32 *chal_flags) { if (neg_flags & NTLMSSP_REQUEST_TARGET) { @@ -119,8 +55,8 @@ static const char *ntlmssp_target_name(NTLMSSP_STATE *ntlmssp_state, } } -NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) +static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB struct_blob; fstring dnsname, dnsdomname; @@ -222,8 +158,8 @@ NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, return NT_STATUS_MORE_PROCESSING_REQUIRED; } -NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) +static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB sess_key; uint32 ntlmssp_command, neg_flags; @@ -279,3 +215,68 @@ NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, return nt_status; } + +NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + ZERO_STRUCTP(*ntlmssp_state); + + (*ntlmssp_state)->mem_ctx = mem_ctx; + (*ntlmssp_state)->get_challenge = get_challenge; + + (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_domain = lp_workgroup; + (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ + + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + + SAFE_FREE((*ntlmssp_state)->user); + SAFE_FREE((*ntlmssp_state)->domain); + SAFE_FREE((*ntlmssp_state)->workstation); + + talloc_destroy(mem_ctx); + *ntlmssp_state = NULL; + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, + DATA_BLOB request, DATA_BLOB *reply) +{ + uint32 ntlmssp_command; + *reply = data_blob(NULL, 0); + + if (!msrpc_parse(&request, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + + return NT_STATUS_LOGON_FAILURE; + } + + if (ntlmssp_command == NTLMSSP_NEGOTIATE) { + return ntlmssp_server_negotiate(ntlmssp_state, request, reply); + } else if (ntlmssp_command == NTLMSSP_AUTH) { + return ntlmssp_server_auth(ntlmssp_state, request, reply); + } else { + return NT_STATUS_LOGON_FAILURE; + } +} + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index a30a48a020..34689b502c 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -363,19 +363,17 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, SMB signing - setup the MAC key. ************************************************************/ -void cli_calculate_mac_key(struct cli_state *cli, const char *plain_passwd, const uchar resp[24]) +void cli_calculate_mac_key(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) { - uchar nt_hash[16]; - E_md4hash(plain_passwd, nt_hash); - mdfour(&cli->sign_info.mac_key[0], nt_hash, sizeof(nt_hash)); - memcpy(&cli->sign_info.mac_key[16],resp,24); - cli->sign_info.mac_key_len = 40; + memcpy(&cli->sign_info.mac_key[0], user_session_key, 16); + memcpy(&cli->sign_info.mac_key[16],response.data, MIN(response.length, 40 - 16)); + cli->sign_info.mac_key_len = MIN(response.length + 16, 40); cli->sign_info.use_smb_signing = True; /* These calls are INCONPATIBLE with SMB signing */ cli->readbraw_supported = False; - cli->writebraw_supported = False; + cli->writebraw_supported = False; /* Reset the sequence number in case we had a previous (aborted) attempt */ cli->sign_info.send_seq_num = 2; -- cgit From bb9c66462233cffaf406bc8a00f3d14a4069a68f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Feb 2003 12:22:57 +0000 Subject: Clean up our NTLMv2 code by moving the grunt work into a helper function. Andrew Bartlett (This used to be commit 6789e237d7b070624ba09e7ed43680b838337b74) --- source3/libsmb/cliconnect.c | 48 +++++++-------------------------------------- source3/libsmb/smbencrypt.c | 27 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 41 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1c89423b7f..827a086df3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -282,12 +282,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (lp_client_ntlmv2_auth()) { uchar ntlm_v2_hash[16]; - uchar ntlmv2_response[16]; - uchar lmv2_response[16]; - DATA_BLOB ntlmv2_client_data; - DATA_BLOB lmv2_client_data; DATA_BLOB server_chal; + server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); + /* We don't use the NT# directly. Instead we use it mashed up with the username and domain. This prevents username swapping during the auth exchange @@ -295,48 +293,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (!ntv2_owf_gen(nt_hash, user, workgroup, ntlm_v2_hash)) { return False; } - - server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); - - /* NTLMv2 */ - - /* We also get to specify some random data */ - ntlmv2_client_data = data_blob(NULL, 20); - generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False); - memset(ntlmv2_client_data.data, 'A', ntlmv2_client_data.length); - - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response); - - /* put it into nt_response, for the code below to put into the packet */ - nt_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response)); - memcpy(nt_response.data, ntlmv2_response, sizeof(ntlmv2_response)); - /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */ - memcpy(nt_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); - data_blob_free(&ntlmv2_client_data); - + + nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); /* LMv2 */ - /* We also get to specify some random data, but only 8 bytes (24 byte total response) */ - lmv2_client_data = data_blob(NULL, 8); - generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False); - memset(lmv2_client_data.data, 'B', lmv2_client_data.length); - - /* Calculate response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, lmv2_client_data, lmv2_response); - - /* Calculate response */ - lm_response = data_blob(NULL, lmv2_client_data.length + sizeof(lmv2_response)); - memcpy(lm_response.data, lmv2_response, sizeof(lmv2_response)); - /* after the first 16 bytes is the 8 bytes of random data we made above */ - memcpy(lm_response.data + sizeof(lmv2_response), lmv2_client_data.data, lmv2_client_data.length); - data_blob_free(&lmv2_client_data); - - data_blob_free(&server_chal); + lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); /* The NTLMv2 calculations also provide a session key, for signing etc later */ - SMBsesskeygen_ntv2(ntlm_v2_hash, ntlmv2_response, user_session_key); + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response.data, user_session_key); } else { /* non encrypted password supplied. Ignore ntpass. */ diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 34689b502c..28a20e76af 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -295,6 +295,33 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } +DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], + DATA_BLOB server_chal, size_t client_chal_length) +{ + uchar ntlmv2_response[16]; + DATA_BLOB ntlmv2_client_data; + DATA_BLOB final_response; + + /* NTLMv2 */ + + /* We also get to specify some random data */ + ntlmv2_client_data = data_blob(NULL, client_chal_length); + generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response); + + /* put it into nt_response, for the code below to put into the packet */ + final_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response)); + memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); + /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */ + memcpy(final_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); + data_blob_free(&ntlmv2_client_data); + + return final_response; +} + + /*********************************************************** encode a password buffer. The caller gets to figure out what to put in it. -- cgit From 8e5585a20fe1ef7ebc6d37b40d65bf730ee93256 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 12 Feb 2003 16:43:47 +0000 Subject: adding more descriptions for nt status codes (This used to be commit dfceb0aab5d97df5b6b744143db254656398f0e9) --- source3/libsmb/nterr.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 551c6d66ce..e6047847ae 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -541,10 +541,11 @@ static nt_err_code_struct nt_errs[] = nt_err_code_struct nt_err_desc[] = { - { "Success", NT_STATUS_OK }, + { "Success", NT_STATUS_OK }, { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, { "Access denied", NT_STATUS_ACCESS_DENIED }, { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Must change password", NT_STATUS_PASSWORD_MUST_CHANGE }, { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, @@ -569,6 +570,70 @@ nt_err_code_struct nt_err_desc[] = { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE }, + { "Not implemented", NT_STATUS_NOT_IMPLEMENTED }, + { "Invalid information class", NT_STATUS_INVALID_INFO_CLASS }, + { "Information length mismatch", NT_STATUS_INFO_LENGTH_MISMATCH }, + { "Access violation", NT_STATUS_ACCESS_VIOLATION }, + { "Invalid handle", NT_STATUS_INVALID_HANDLE }, + { "Invalid parameter", NT_STATUS_INVALID_PARAMETER }, + { "No memory", NT_STATUS_NO_MEMORY }, + { "Buffer too small", NT_STATUS_BUFFER_TOO_SMALL }, + { "Revision mismatch", NT_STATUS_REVISION_MISMATCH }, + { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, + { "No such logon session", NT_STATUS_NO_SUCH_LOGON_SESSION }, + { "No such privilege", NT_STATUS_NO_SUCH_PRIVILEGE }, + { "Procedure not found", NT_STATUS_PROCEDURE_NOT_FOUND }, + { "Server disabled", NT_STATUS_SERVER_DISABLED }, + { "Invalid pipe state", NT_STATUS_INVALID_PIPE_STATE }, + { "Named pipe busy", NT_STATUS_PIPE_BUSY }, + { "Illegal function", NT_STATUS_ILLEGAL_FUNCTION }, + { "Named pipe dicconnected", NT_STATUS_PIPE_DISCONNECTED }, + { "Named pipe closing", NT_STATUS_PIPE_CLOSING }, + { "Remote host not listening", NT_STATUS_REMOTE_NOT_LISTENING }, + { "Duplicate name on network", NT_STATUS_DUPLICATE_NAME }, + { "Print queue is full", NT_STATUS_PRINT_QUEUE_FULL }, + { "No print spool space available", NT_STATUS_NO_SPOOL_SPACE }, + { "Too many names", NT_STATUS_TOO_MANY_NAMES }, + { "Too many sessions", NT_STATUS_TOO_MANY_SESSIONS }, + { "Invalid server state", NT_STATUS_INVALID_SERVER_STATE }, + { "Invalid domain state", NT_STATUS_INVALID_DOMAIN_STATE }, + { "Invalid domain role", NT_STATUS_INVALID_DOMAIN_ROLE }, + { "No such domain", NT_STATUS_NO_SUCH_DOMAIN }, + { "Domain exists", NT_STATUS_DOMAIN_EXISTS }, + { "Domain limit exceeded", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, + { "Bad logon session state", NT_STATUS_BAD_LOGON_SESSION_STATE }, + { "Logon session collision", NT_STATUS_LOGON_SESSION_COLLISION }, + { "Invalid logon type", NT_STATUS_INVALID_LOGON_TYPE }, + { "Cancelled", NT_STATUS_CANCELLED }, + { "Invalid computer name", NT_STATUS_INVALID_COMPUTER_NAME }, + { "Logon server conflict", NT_STATUS_LOGON_SERVER_CONFLICT }, + { "Time difference at domain controller", NT_STATUS_TIME_DIFFERENCE_AT_DC }, + { "Pipe broken", NT_STATUS_PIPE_BROKEN }, + { "Registry corrupt", NT_STATUS_REGISTRY_CORRUPT }, + { "Too many secrets", NT_STATUS_TOO_MANY_SECRETS }, + { "Too many SIDs", NT_STATUS_TOO_MANY_SIDS }, + { "Lanmanager cross encryption required", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, + { "Log file full", NT_STATUS_LOG_FILE_FULL }, + { "No trusted LSA secret", NT_STATUS_NO_TRUST_LSA_SECRET }, + { "No trusted SAM account", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, + { "Trusted domain failure", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, + { "Trust relationship failure", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, + { "Trust failure", NT_STATUS_TRUST_FAILURE }, + { "Netlogon service not started", NT_STATUS_NETLOGON_NOT_STARTED }, + { "Account expired", NT_STATUS_ACCOUNT_EXPIRED }, + { "Network credential conflict", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, + { "Remote session limit", NT_STATUS_REMOTE_SESSION_LIMIT }, + { "No logon interdomain trust account", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, + { "No logon workstation trust account", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, + { "No logon server trust account", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, + { "Domain trust inconsistent", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, + { "No user session key available", NT_STATUS_NO_USER_SESSION_KEY }, + { "User session deleted", NT_STATUS_USER_SESSION_DELETED }, + { "Insufficient server resources", NT_STATUS_INSUFF_SERVER_RESOURCES }, + { "Insufficient logon information", NT_STATUS_INSUFFICIENT_LOGON_INFO }, + + { "License quota exceeded", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, + { NULL, NT_STATUS(0) } }; -- cgit From 3bfd4406201593c1b5b7a97825bc514e700aea7a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 12 Feb 2003 16:44:13 +0000 Subject: adding more descriptions for nt status codes (This used to be commit 2fa33fcaee288f0607db9fc72d2f1cafdd6c5959) --- source3/libsmb/nterr.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 551c6d66ce..e6047847ae 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -541,10 +541,11 @@ static nt_err_code_struct nt_errs[] = nt_err_code_struct nt_err_desc[] = { - { "Success", NT_STATUS_OK }, + { "Success", NT_STATUS_OK }, { "Undetermined error", NT_STATUS_UNSUCCESSFUL }, { "Access denied", NT_STATUS_ACCESS_DENIED }, { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, + { "Must change password", NT_STATUS_PASSWORD_MUST_CHANGE }, { "Password is too short", NT_STATUS_PWD_TOO_SHORT }, { "Password is too recent", NT_STATUS_PWD_TOO_RECENT }, { "Password history conflict", NT_STATUS_PWD_HISTORY_CONFLICT }, @@ -569,6 +570,70 @@ nt_err_code_struct nt_err_desc[] = { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE }, + { "Not implemented", NT_STATUS_NOT_IMPLEMENTED }, + { "Invalid information class", NT_STATUS_INVALID_INFO_CLASS }, + { "Information length mismatch", NT_STATUS_INFO_LENGTH_MISMATCH }, + { "Access violation", NT_STATUS_ACCESS_VIOLATION }, + { "Invalid handle", NT_STATUS_INVALID_HANDLE }, + { "Invalid parameter", NT_STATUS_INVALID_PARAMETER }, + { "No memory", NT_STATUS_NO_MEMORY }, + { "Buffer too small", NT_STATUS_BUFFER_TOO_SMALL }, + { "Revision mismatch", NT_STATUS_REVISION_MISMATCH }, + { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, + { "No such logon session", NT_STATUS_NO_SUCH_LOGON_SESSION }, + { "No such privilege", NT_STATUS_NO_SUCH_PRIVILEGE }, + { "Procedure not found", NT_STATUS_PROCEDURE_NOT_FOUND }, + { "Server disabled", NT_STATUS_SERVER_DISABLED }, + { "Invalid pipe state", NT_STATUS_INVALID_PIPE_STATE }, + { "Named pipe busy", NT_STATUS_PIPE_BUSY }, + { "Illegal function", NT_STATUS_ILLEGAL_FUNCTION }, + { "Named pipe dicconnected", NT_STATUS_PIPE_DISCONNECTED }, + { "Named pipe closing", NT_STATUS_PIPE_CLOSING }, + { "Remote host not listening", NT_STATUS_REMOTE_NOT_LISTENING }, + { "Duplicate name on network", NT_STATUS_DUPLICATE_NAME }, + { "Print queue is full", NT_STATUS_PRINT_QUEUE_FULL }, + { "No print spool space available", NT_STATUS_NO_SPOOL_SPACE }, + { "Too many names", NT_STATUS_TOO_MANY_NAMES }, + { "Too many sessions", NT_STATUS_TOO_MANY_SESSIONS }, + { "Invalid server state", NT_STATUS_INVALID_SERVER_STATE }, + { "Invalid domain state", NT_STATUS_INVALID_DOMAIN_STATE }, + { "Invalid domain role", NT_STATUS_INVALID_DOMAIN_ROLE }, + { "No such domain", NT_STATUS_NO_SUCH_DOMAIN }, + { "Domain exists", NT_STATUS_DOMAIN_EXISTS }, + { "Domain limit exceeded", NT_STATUS_DOMAIN_LIMIT_EXCEEDED }, + { "Bad logon session state", NT_STATUS_BAD_LOGON_SESSION_STATE }, + { "Logon session collision", NT_STATUS_LOGON_SESSION_COLLISION }, + { "Invalid logon type", NT_STATUS_INVALID_LOGON_TYPE }, + { "Cancelled", NT_STATUS_CANCELLED }, + { "Invalid computer name", NT_STATUS_INVALID_COMPUTER_NAME }, + { "Logon server conflict", NT_STATUS_LOGON_SERVER_CONFLICT }, + { "Time difference at domain controller", NT_STATUS_TIME_DIFFERENCE_AT_DC }, + { "Pipe broken", NT_STATUS_PIPE_BROKEN }, + { "Registry corrupt", NT_STATUS_REGISTRY_CORRUPT }, + { "Too many secrets", NT_STATUS_TOO_MANY_SECRETS }, + { "Too many SIDs", NT_STATUS_TOO_MANY_SIDS }, + { "Lanmanager cross encryption required", NT_STATUS_LM_CROSS_ENCRYPTION_REQUIRED }, + { "Log file full", NT_STATUS_LOG_FILE_FULL }, + { "No trusted LSA secret", NT_STATUS_NO_TRUST_LSA_SECRET }, + { "No trusted SAM account", NT_STATUS_NO_TRUST_SAM_ACCOUNT }, + { "Trusted domain failure", NT_STATUS_TRUSTED_DOMAIN_FAILURE }, + { "Trust relationship failure", NT_STATUS_TRUSTED_RELATIONSHIP_FAILURE }, + { "Trust failure", NT_STATUS_TRUST_FAILURE }, + { "Netlogon service not started", NT_STATUS_NETLOGON_NOT_STARTED }, + { "Account expired", NT_STATUS_ACCOUNT_EXPIRED }, + { "Network credential conflict", NT_STATUS_NETWORK_CREDENTIAL_CONFLICT }, + { "Remote session limit", NT_STATUS_REMOTE_SESSION_LIMIT }, + { "No logon interdomain trust account", NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT }, + { "No logon workstation trust account", NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT }, + { "No logon server trust account", NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT }, + { "Domain trust inconsistent", NT_STATUS_DOMAIN_TRUST_INCONSISTENT }, + { "No user session key available", NT_STATUS_NO_USER_SESSION_KEY }, + { "User session deleted", NT_STATUS_USER_SESSION_DELETED }, + { "Insufficient server resources", NT_STATUS_INSUFF_SERVER_RESOURCES }, + { "Insufficient logon information", NT_STATUS_INSUFFICIENT_LOGON_INFO }, + + { "License quota exceeded", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, + { NULL, NT_STATUS(0) } }; -- cgit From ce306f8b08cc80d72e795e2795e1d71b5f43b93f Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Thu, 13 Feb 2003 21:40:35 +0000 Subject: A few typo fixes Andrew eventually let off to me. Rafal (This used to be commit 16a66cf17a544a214b7c5b483c81c7568a18a779) --- source3/libsmb/clispnego.c | 8 ++++---- source3/libsmb/ntlmssp.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 277bf4765f..eabddd1765 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -447,11 +447,11 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) uint8 negResult; if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNGEO_NEG_RESULT_ACCEPT; + negResult = SPNEGO_NEG_RESULT_ACCEPT; } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNGEO_NEG_RESULT_INCOMPLETE; + negResult = SPNEGO_NEG_RESULT_INCOMPLETE; } else { - negResult = SPNGEO_NEG_RESULT_REJECT; + negResult = SPNEGO_NEG_RESULT_REJECT; } ZERO_STRUCT(data); @@ -461,7 +461,7 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_push_tag(&data, ASN1_CONTEXT(0)); asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (negResult == SPNGEO_NEG_RESULT_INCOMPLETE) { + if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { asn1_push_tag(&data,ASN1_CONTEXT(1)); asn1_write_OID(&data, OID_NTLMSSP); asn1_pop_tag(&data); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 886f872764..969508a360 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -24,7 +24,7 @@ #include "includes.h" /** - * Default challange generation code. + * Default challenge generation code. * */ -- cgit From 938fd5652d24484dabecf908ea215fa29b80c77e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 14 Feb 2003 10:47:07 +0000 Subject: Further extract our NTLMv2 code into smbencrypt.c, prior to merge into our NTLMSSP client code. Andrew Bartlett (This used to be commit eaa8e7d1f82b30e7af14a0a58d7ca3eb66a06053) --- source3/libsmb/cliconnect.c | 52 +++++++++++++++++---------------------------- source3/libsmb/smbencrypt.c | 31 +++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 32 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 827a086df3..9c7b168431 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -272,39 +272,27 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, uint32 capabilities = cli_session_setup_capabilities(cli); DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); - uchar user_session_key[16]; + DATA_BLOB session_key = data_blob(NULL, 0); + BOOL ret = False; char *p; - BOOL have_plaintext = False; if (passlen != 24) { - uchar nt_hash[16]; - E_md4hash(pass, nt_hash); - if (lp_client_ntlmv2_auth()) { - uchar ntlm_v2_hash[16]; DATA_BLOB server_chal; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); - /* We don't use the NT# directly. Instead we use it mashed up with - the username and domain. - This prevents username swapping during the auth exchange - */ - if (!ntv2_owf_gen(nt_hash, user, workgroup, ntlm_v2_hash)) { + if (!SMBNTLMv2encrypt(user, workgroup, pass, server_chal, + &lm_response, &nt_response, &session_key)) { + data_blob_free(&server_chal); return False; } - - nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); - - /* LMv2 */ - - lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); - - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response.data, user_session_key); + data_blob_free(&server_chal); } else { + uchar nt_hash[16]; + E_md4hash(pass, nt_hash); + /* non encrypted password supplied. Ignore ntpass. */ if (lp_client_lanman_auth()) { lm_response = data_blob(NULL, 24); @@ -313,10 +301,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, nt_response = data_blob(NULL, 24); SMBNTencrypt(pass,cli->secblob.data,nt_response.data); - SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key); + session_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - have_plaintext = True; set_temp_signing_on_cli(cli); } else { /* pre-encrypted password supplied. Only used for @@ -356,17 +344,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, cli_setup_bcc(cli, p); if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { - data_blob_free(&lm_response); - data_blob_free(&nt_response); - return False; + ret = False; + goto end; } show_msg(cli->inbuf); if (cli_is_error(cli)) { - data_blob_free(&lm_response); - data_blob_free(&nt_response); - return False; + ret = False; + goto end; } /* use the returned vuid from now on */ @@ -379,13 +365,15 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, fstrcpy(cli->user_name, user); - if (have_plaintext) { + if (session_key.data) { /* Have plaintext orginal */ - set_signing_on_cli(cli, user_session_key, nt_response); + set_signing_on_cli(cli, session_key.data, nt_response); } - + +end: data_blob_free(&lm_response); data_blob_free(&nt_response); + data_blob_free(&session_key); return True; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 28a20e76af..aa9391325f 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -321,6 +321,37 @@ DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], return final_response; } +BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, + const DATA_BLOB server_chal, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *session_key) +{ + uchar nt_hash[16]; + uchar ntlm_v2_hash[16]; + E_md4hash(password, nt_hash); + + /* We don't use the NT# directly. Instead we use it mashed up with + the username and domain. + This prevents username swapping during the auth exchange + */ + if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) { + return False; + } + + *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); + + /* LMv2 */ + + *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); + + *session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, session_key->data); + + return True; +} /*********************************************************** encode a password buffer. The caller gets to figure out -- cgit From 8fc1f1aead6db996a6d96efdc5f81779afc9c8d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Feb 2003 22:55:46 +0000 Subject: Ensure that only parse_prs.c access internal members of the prs_struct. Needed to move to disk based i/o later. Jeremy. (This used to be commit a823fee5b41a5b6cd4ef05aa1f85f7725bd272a5) --- source3/libsmb/clisecdesc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 7dd2747ff6..20154dbeb2 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -54,8 +54,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, } prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL); - prs_append_data(&pd, rdata, rdata_count); - pd.data_offset = 0; + prs_copy_data_in(&pd, rdata, rdata_count); + prs_set_offset(&pd,0); if (!sec_io_desc("sd data", &psd, &pd, 1)) { DEBUG(1,("Failed to parse secdesc\n")); @@ -104,7 +104,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) 0, NULL, 0, 0, param, 8, 0, - pd.data_p, pd.data_offset, 0)) { + prs_data_p(&pd), prs_offset(&pd), 0)) { DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); goto cleanup; } -- cgit From 4cd6e31bd364270580f2907fbc5669bf29d09578 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Feb 2003 23:04:03 +0000 Subject: Ensure that only parse_prs.c access internal members of the prs_struct. Needed to move to disk based i/o later. Jeremy. (This used to be commit 4c3ee228fcdb089eaeead95e79532a9cf6cb0de6) --- source3/libsmb/clisecdesc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 7dd2747ff6..20154dbeb2 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -54,8 +54,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, } prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL); - prs_append_data(&pd, rdata, rdata_count); - pd.data_offset = 0; + prs_copy_data_in(&pd, rdata, rdata_count); + prs_set_offset(&pd,0); if (!sec_io_desc("sd data", &psd, &pd, 1)) { DEBUG(1,("Failed to parse secdesc\n")); @@ -104,7 +104,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) 0, NULL, 0, 0, param, 8, 0, - pd.data_p, pd.data_offset, 0)) { + prs_data_p(&pd), prs_offset(&pd), 0)) { DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); goto cleanup; } -- cgit From 3ca3e92376a95d91e1c46ec3055f192103fd409a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 14 Feb 2003 23:13:05 +0000 Subject: NTLMSSP parinoia - we really don't want to run over the end of our blob, and make sure we can never get an 'authenticate' packet without a challenge. Andrew Bartlett (This used to be commit 4d94f8e6912c1339515cd1f68d1b698e7c699626) --- source3/libsmb/clispnego.c | 41 +++++++++++++++++++++++++++++++++-------- source3/libsmb/ntlmssp.c | 19 +++++++++++++------ 2 files changed, 46 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index eabddd1765..54069fc637 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -636,6 +636,12 @@ BOOL msrpc_gen(DATA_BLOB *blob, } +/* a helpful macro to avoid running over the end of our blob */ +#define NEED_DATA(amount) \ +if (head_ofs + amount > blob->length) { \ + return False; \ +} + /* this is a tiny msrpc packet parser. This the the partner of msrpc_gen @@ -648,6 +654,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, d = word (4 bytes) C = constant ascii string */ + BOOL msrpc_parse(DATA_BLOB *blob, const char *format, ...) { @@ -665,19 +672,32 @@ BOOL msrpc_parse(DATA_BLOB *blob, for (i=0; format[i]; i++) { switch (format[i]) { case 'U': + NEED_DATA(8); len1 = SVAL(blob->data, head_ofs); head_ofs += 2; len2 = SVAL(blob->data, head_ofs); head_ofs += 2; ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + /* make sure its in the right format - be strict */ - if (len1 != len2 || (len1&1) || ptr + len1 > blob->length) { + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + if (len1 & 1) { + /* if odd length and unicode */ return False; } + ps = va_arg(ap, char **); - pull_string(NULL, p, blob->data + ptr, -1, len1, - STR_UNICODE|STR_NOALIGN); - (*ps) = strdup(p); + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_UNICODE|STR_NOALIGN); + (*ps) = strdup(p); + } else { + (*ps) = NULL; + } break; case 'A': + NEED_DATA(8); len1 = SVAL(blob->data, head_ofs); head_ofs += 2; len2 = SVAL(blob->data, head_ofs); head_ofs += 2; ptr = IVAL(blob->data, head_ofs); head_ofs += 4; @@ -686,16 +706,19 @@ BOOL msrpc_parse(DATA_BLOB *blob, if (len1 != len2 || ptr + len1 > blob->length) { return False; } + ps = va_arg(ap, char **); if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, -1, - len1, STR_ASCII|STR_NOALIGN); + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_ASCII|STR_NOALIGN); (*ps) = strdup(p); } else { (*ps) = NULL; } break; case 'B': + NEED_DATA(8); len1 = SVAL(blob->data, head_ofs); head_ofs += 2; len2 = SVAL(blob->data, head_ofs); head_ofs += 2; ptr = IVAL(blob->data, head_ofs); head_ofs += 4; @@ -709,12 +732,14 @@ BOOL msrpc_parse(DATA_BLOB *blob, case 'b': b = (DATA_BLOB *)va_arg(ap, void *); len1 = va_arg(ap, unsigned); - *b = data_blob(blob->data + head_ofs, - MIN(len1, blob->length - head_ofs)); + /* make sure its in the right format - be strict */ + NEED_DATA(len1); + *b = data_blob(blob->data + head_ofs, len1); head_ofs += len1; break; case 'd': v = va_arg(ap, uint32 *); + NEED_DATA(4); *v = IVAL(blob->data, head_ofs); head_ofs += 4; break; case 'C': diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 969508a360..48df7fc564 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -76,7 +76,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, &neg_flags, &cliname, &domname)) { - return NT_STATUS_LOGON_FAILURE; + return NT_STATUS_INVALID_PARAMETER; } SAFE_FREE(cliname); @@ -155,6 +155,8 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, data_blob_free(&struct_blob); + ntlmssp_state->expected_state = NTLMSSP_AUTH; + return NT_STATUS_MORE_PROCESSING_REQUIRED; } @@ -196,7 +198,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &ntlmssp_state->workstation, &sess_key, &neg_flags)) { - return NT_STATUS_LOGON_FAILURE; + return NT_STATUS_INVALID_PARAMETER; } data_blob_free(&sess_key); @@ -224,7 +226,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_start: talloc failed!\n")); + DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } @@ -238,6 +240,8 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->get_domain = lp_workgroup; (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ + (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; + return NT_STATUS_OK; } @@ -267,8 +271,11 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, if (!msrpc_parse(&request, "Cd", "NTLMSSP", &ntlmssp_command)) { - - return NT_STATUS_LOGON_FAILURE; + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command != ntlmssp_state->expected_state) { + return NT_STATUS_INVALID_PARAMETER; } if (ntlmssp_command == NTLMSSP_NEGOTIATE) { @@ -276,7 +283,7 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, } else if (ntlmssp_command == NTLMSSP_AUTH) { return ntlmssp_server_auth(ntlmssp_state, request, reply); } else { - return NT_STATUS_LOGON_FAILURE; + return NT_STATUS_INVALID_PARAMETER; } } -- cgit From 3b2693f1ae3b1e06d3015843d2933177fcb97a87 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Feb 2003 00:10:09 +0000 Subject: Move our NTLMSSP code into easily seperated peices, not relying on the whole of libsmb. Andrew Bartlett (This used to be commit b5ec7efa80478187124c1cfa8c7fcc4036506a37) --- source3/libsmb/clispnego.c | 322 ----------------------------------------- source3/libsmb/ntlmssp.c | 43 +++++- source3/libsmb/ntlmssp_parse.c | 303 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 345 insertions(+), 323 deletions(-) create mode 100644 source3/libsmb/ntlmssp_parse.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 54069fc637..91748c4c7a 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -478,325 +478,3 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_free(&data); return ret; } - -/* - this is a tiny msrpc packet generator. I am only using this to - avoid tying this code to a particular varient of our rpc code. This - generator is not general enough for all our rpc needs, its just - enough for the spnego/ntlmssp code - - format specifiers are: - - U = unicode string (input is unix string) - a = address (input is BOOL unicode, char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) - B = data blob (pointer + length) - b = data blob in header (pointer + length) - D - d = word (4 bytes) - C = constant ascii string - */ -BOOL msrpc_gen(DATA_BLOB *blob, - const char *format, ...) -{ - int i, n; - va_list ap; - char *s; - uint8 *b; - int head_size=0, data_size=0; - int head_ofs, data_ofs; - BOOL unicode; - - /* first scan the format to work out the header and body size */ - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_charnum(s) * 2; - break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_ascii_charnum(s); - break; - case 'a': - unicode = va_arg(ap, BOOL); - n = va_arg(ap, int); - s = va_arg(ap, char *); - if (unicode) { - data_size += (str_charnum(s) * 2) + 4; - } else { - data_size += (str_ascii_charnum(s)) + 4; - } - break; - case 'B': - b = va_arg(ap, uint8 *); - head_size += 8; - data_size += va_arg(ap, int); - break; - case 'b': - b = va_arg(ap, uint8 *); - head_size += va_arg(ap, int); - break; - case 'd': - n = va_arg(ap, int); - head_size += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_size += str_charnum(s) + 1; - break; - } - } - va_end(ap); - - /* allocate the space, then scan the format again to fill in the values */ - *blob = data_blob(NULL, head_size + data_size); - - head_ofs = 0; - data_ofs = head_size; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); - data_ofs += n*2; - break; - case 'A': - s = va_arg(ap, char *); - n = str_ascii_charnum(s); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); - data_ofs += n; - break; - case 'a': - unicode = va_arg(ap, BOOL); - n = va_arg(ap, int); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - s = va_arg(ap, char *); - if (unicode) { - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - } else { - n = str_ascii_charnum(s); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n, - STR_ASCII|STR_NOALIGN); - } - data_ofs += n; - } - break; - - case 'B': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - memcpy(blob->data+data_ofs, b, n); - data_ofs += n; - break; - case 'd': - n = va_arg(ap, int); - SIVAL(blob->data, head_ofs, n); head_ofs += 4; - break; - case 'b': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - memcpy(blob->data + head_ofs, b, n); - head_ofs += n; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, - STR_ASCII|STR_TERMINATE); - break; - } - } - va_end(ap); - - return True; -} - - -/* a helpful macro to avoid running over the end of our blob */ -#define NEED_DATA(amount) \ -if (head_ofs + amount > blob->length) { \ - return False; \ -} - -/* - this is a tiny msrpc packet parser. This the the partner of msrpc_gen - - format specifiers are: - - U = unicode string (output is unix string) - A = ascii string - B = data blob - b = data blob in header - d = word (4 bytes) - C = constant ascii string - */ - -BOOL msrpc_parse(DATA_BLOB *blob, - const char *format, ...) -{ - int i; - va_list ap; - char **ps, *s; - DATA_BLOB *b; - int head_ofs = 0; - uint16 len1, len2; - uint32 ptr; - uint32 *v; - pstring p; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - if (len1 & 1) { - /* if odd length and unicode */ - return False; - } - - ps = va_arg(ap, char **); - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_UNICODE|STR_NOALIGN); - (*ps) = strdup(p); - } else { - (*ps) = NULL; - } - break; - case 'A': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - - ps = va_arg(ap, char **); - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_ASCII|STR_NOALIGN); - (*ps) = strdup(p); - } else { - (*ps) = NULL; - } - break; - case 'B': - NEED_DATA(8); - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - b = (DATA_BLOB *)va_arg(ap, void *); - *b = data_blob(blob->data + ptr, len1); - break; - case 'b': - b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, unsigned); - /* make sure its in the right format - be strict */ - NEED_DATA(len1); - *b = data_blob(blob->data + head_ofs, len1); - head_ofs += len1; - break; - case 'd': - v = va_arg(ap, uint32 *); - NEED_DATA(4); - *v = IVAL(blob->data, head_ofs); head_ofs += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - return False; - } - break; - } - } - va_end(ap); - - return True; -} - -/** - * Print out the NTLMSSP flags for debugging - */ - -void debug_ntlmssp_flags(uint32 neg_flags) -{ - DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); - if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); - if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); -} - diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 48df7fc564..92a18d25c0 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -23,12 +23,53 @@ #include "includes.h" +/** + * Print out the NTLMSSP flags for debugging + */ + +void debug_ntlmssp_flags(uint32 neg_flags) +{ + DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); + + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_OEM) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + if (neg_flags & NTLMSSP_REQUEST_TARGET) + DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) + DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_128) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); +} + /** * Default challenge generation code. * */ - static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) { static uchar chal[8]; diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c new file mode 100644 index 0000000000..5f3132694e --- /dev/null +++ b/source3/libsmb/ntlmssp_parse.c @@ -0,0 +1,303 @@ +/* + Unix SMB/CIFS implementation. + simple kerberos5/SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Jim McDonough 2002 + Copyright (C) Andrew Bartlett 2002-2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +/* + this is a tiny msrpc packet generator. I am only using this to + avoid tying this code to a particular varient of our rpc code. This + generator is not general enough for all our rpc needs, its just + enough for the spnego/ntlmssp code + + format specifiers are: + + U = unicode string (input is unix string) + a = address (input is BOOL unicode, char *unix_string) + (1 byte type, 1 byte length, unicode/ASCII string, all inline) + A = ASCII string (input is unix string) + B = data blob (pointer + length) + b = data blob in header (pointer + length) + D + d = word (4 bytes) + C = constant ascii string + */ +BOOL msrpc_gen(DATA_BLOB *blob, + const char *format, ...) +{ + int i, n; + va_list ap; + char *s; + uint8 *b; + int head_size=0, data_size=0; + int head_ofs, data_ofs; + BOOL unicode; + + /* first scan the format to work out the header and body size */ + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_charnum(s) * 2; + break; + case 'A': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_ascii_charnum(s); + break; + case 'a': + unicode = va_arg(ap, BOOL); + n = va_arg(ap, int); + s = va_arg(ap, char *); + if (unicode) { + data_size += (str_charnum(s) * 2) + 4; + } else { + data_size += (str_ascii_charnum(s)) + 4; + } + break; + case 'B': + b = va_arg(ap, uint8 *); + head_size += 8; + data_size += va_arg(ap, int); + break; + case 'b': + b = va_arg(ap, uint8 *); + head_size += va_arg(ap, int); + break; + case 'd': + n = va_arg(ap, int); + head_size += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_size += str_charnum(s) + 1; + break; + } + } + va_end(ap); + + /* allocate the space, then scan the format again to fill in the values */ + *blob = data_blob(NULL, head_size + data_size); + + head_ofs = 0; + data_ofs = head_size; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); + data_ofs += n*2; + break; + case 'A': + s = va_arg(ap, char *); + n = str_ascii_charnum(s); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + data_ofs += n; + break; + case 'a': + unicode = va_arg(ap, BOOL); + n = va_arg(ap, int); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + s = va_arg(ap, char *); + if (unicode) { + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); + } + data_ofs += n*2; + } else { + n = str_ascii_charnum(s); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n, + STR_ASCII|STR_NOALIGN); + } + data_ofs += n; + } + break; + + case 'B': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + memcpy(blob->data+data_ofs, b, n); + data_ofs += n; + break; + case 'd': + n = va_arg(ap, int); + SIVAL(blob->data, head_ofs, n); head_ofs += 4; + break; + case 'b': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + memcpy(blob->data + head_ofs, b, n); + head_ofs += n; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, + STR_ASCII|STR_TERMINATE); + break; + } + } + va_end(ap); + + return True; +} + + +/* a helpful macro to avoid running over the end of our blob */ +#define NEED_DATA(amount) \ +if (head_ofs + amount > blob->length) { \ + return False; \ +} + +/* + this is a tiny msrpc packet parser. This the the partner of msrpc_gen + + format specifiers are: + + U = unicode string (output is unix string) + A = ascii string + B = data blob + b = data blob in header + d = word (4 bytes) + C = constant ascii string + */ + +BOOL msrpc_parse(DATA_BLOB *blob, + const char *format, ...) +{ + int i; + va_list ap; + char **ps, *s; + DATA_BLOB *b; + int head_ofs = 0; + uint16 len1, len2; + uint32 ptr; + uint32 *v; + pstring p; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + if (len1 & 1) { + /* if odd length and unicode */ + return False; + } + + ps = va_arg(ap, char **); + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_UNICODE|STR_NOALIGN); + (*ps) = strdup(p); + } else { + (*ps) = NULL; + } + break; + case 'A': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + + ps = va_arg(ap, char **); + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_ASCII|STR_NOALIGN); + (*ps) = strdup(p); + } else { + (*ps) = NULL; + } + break; + case 'B': + NEED_DATA(8); + len1 = SVAL(blob->data, head_ofs); head_ofs += 2; + len2 = SVAL(blob->data, head_ofs); head_ofs += 2; + ptr = IVAL(blob->data, head_ofs); head_ofs += 4; + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + b = (DATA_BLOB *)va_arg(ap, void *); + *b = data_blob(blob->data + ptr, len1); + break; + case 'b': + b = (DATA_BLOB *)va_arg(ap, void *); + len1 = va_arg(ap, unsigned); + /* make sure its in the right format - be strict */ + NEED_DATA(len1); + *b = data_blob(blob->data + head_ofs, len1); + head_ofs += len1; + break; + case 'd': + v = va_arg(ap, uint32 *); + NEED_DATA(4); + *v = IVAL(blob->data, head_ofs); head_ofs += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); + if (strcmp(s, p) != 0) { + return False; + } + break; + } + } + va_end(ap); + + return True; +} + -- cgit From e4202a9fe70785a0a5b47c90df696a880294d310 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Feb 2003 00:29:21 +0000 Subject: Antti Andreimann has done some changes to enable users w/o full administrative access on computer accounts to join a computer into AD domain. The patch and detailed changelog is available at: http://www.itcollege.ee/~aandreim/samba This is a list of changes in general: 1. When creating machine account do not fail if SD cannot be changed. setting SD is not mandatory and join will work perfectly without it. 2. Implement KPASSWD CHANGEPW protocol for changing trust password so machine account does not need to have reset password right for itself. 3. Command line utilities no longer interfere with user's existing kerberos ticket cache. 4. Command line utilities can do kerberos authentication even if username is specified (-U). Initial TGT will be requested in this case. I've modified the patch to share the kinit code, rather than copying it, and updated it to current CVS. The other change included in the original patch (local realms) has been left out for now. Andrew Bartlett (This used to be commit ce52f1c2ed4d3ddafe8ae6258c90b90fa434fe43) --- source3/libsmb/cliconnect.c | 22 ++++++++++++++++++++++ source3/libsmb/clikrb5.c | 2 +- 2 files changed, 23 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9c7b168431..90a7eca8e7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -445,6 +445,13 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) } #ifdef HAVE_KRB5 +/**************************************************************************** + Use in-memory credentials cache +****************************************************************************/ +static void use_in_memory_ccache() { + setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads_testjoin", 1); +} + /**************************************************************************** Do a spnego/kerberos encrypted session setup. ****************************************************************************/ @@ -656,6 +663,21 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, fstrcpy(cli->user_name, user); #ifdef HAVE_KRB5 + /* If password is set we reauthenticate to kerberos server + * and do not store results */ + + if (*pass) { + int ret; + + use_in_memory_ccache(); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */); + + if (ret){ + DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); + return False; + } + } + if (got_kerberos_mechanism && cli->use_kerberos) { return cli_session_setup_kerberos(cli, principal, workgroup); } diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 203d9d874b..e380d80bcc 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -278,6 +278,7 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) ENCTYPE_ARCFOUR_HMAC, #endif ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, ENCTYPE_NULL}; retval = krb5_init_context(&context); @@ -324,7 +325,6 @@ failed: return data_blob(NULL, 0); } - #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) -- cgit From 4aabc4cdfd7c50e37c29f253de4d08107e106a6a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Feb 2003 12:20:22 +0000 Subject: Move our NTLMSSP client code into ntlmssp.c. The intention is to provide a relitivly useful external lib from this code, and to remove the dupicate NTLMSSP code elsewhere in samba (RPC pipes, LDAP client). The code I've replaced this with in cliconnect.c is relitivly ugly, and I hope to replace it with a more general SPENGO layer at some later date. Andrew Bartlett (This used to be commit b2b66909ac2e251f8189e0696b6075dbf748521a) --- source3/libsmb/asn1.c | 21 ++- source3/libsmb/cliconnect.c | 179 +++++++++--------------- source3/libsmb/clispnego.c | 56 +++++++- source3/libsmb/errormap.c | 2 +- source3/libsmb/ntlmssp.c | 304 ++++++++++++++++++++++++++++++++++++++++- source3/libsmb/ntlmssp_parse.c | 6 +- 6 files changed, 440 insertions(+), 128 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 333d157905..09d4fbb6c9 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -240,7 +240,9 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) uint8 b; struct nesting *nesting; - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) + return False; + if (b != tag) { data->has_error = True; return False; @@ -251,13 +253,18 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) return False; } - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) { + return False; + } + if (b & 0x80) { int n = b & 0x7f; - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) + return False; nesting->taglen = b; while (n > 1) { - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) + return False; nesting->taglen = (nesting->taglen << 8) | b; n--; } @@ -404,7 +411,11 @@ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; asn1_read_uint8(data, &b); asn1_end_tag(data); - return !data->has_error && (v == b); + + if (v != b) + data->has_error = False; + + return !data->has_error; } /* write an enumarted value to the stream */ diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 90a7eca8e7..2b0b9abc9d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -385,11 +385,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; - DATA_BLOB blob2; + DATA_BLOB blob2 = data_blob(NULL, 0); uint32 len; - blob2 = data_blob(NULL, 0); - capabilities |= CAP_EXTENDED_SECURITY; /* send a session setup command */ @@ -449,7 +447,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) Use in-memory credentials cache ****************************************************************************/ static void use_in_memory_ccache() { - setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads_testjoin", 1); + setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); } /**************************************************************************** @@ -489,128 +487,83 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, const char *pass, const char *workgroup) { - DATA_BLOB msg1, struct_blob; - DATA_BLOB blob, chal1, chal2, auth, challenge_blob; - uint8 challenge[8]; - uint8 nthash[24], lmhash[24], sess_key[16]; - uint32 neg_flags, chal_flags, ntlmssp_command, unkn1, unkn2; - pstring server_domain; /* FIX THIS, SHOULD be UCS2-LE */ - - neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_REQUEST_TARGET; - - memset(sess_key, 0, 16); - - DEBUG(10, ("sending NTLMSSP_NEGOTIATE\n")); - - /* generate the ntlmssp negotiate packet */ - msrpc_gen(&blob, "CddAA", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - neg_flags, - workgroup, - cli->calling.name); - DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n", - neg_flags, workgroup, cli->calling.name)); - /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenInit(OID_NTLMSSP, blob); - data_blob_free(&blob); - - /* now send that blob on its way */ - blob = cli_session_setup_blob(cli, msg1); - - data_blob_free(&msg1); - - if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) - return False; - -#if 0 - file_save("chal.dat", blob.data, blob.length); -#endif + struct ntlmssp_client_state *ntlmssp_state; + NTSTATUS nt_status; + int turn = 1; + DATA_BLOB msg1; + DATA_BLOB blob; + DATA_BLOB blob_in = data_blob(NULL, 0); + DATA_BLOB blob_out; - /* the server gives us back two challenges */ - if (!spnego_parse_challenge(blob, &chal1, &chal2)) { - DEBUG(3,("Failed to parse challenges\n")); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return False; } - data_blob_free(&blob); - - /* - * Ok, chal1 and chal2 are actually two identical copies of - * the NTLMSSP Challenge BLOB, and they contain, encoded in them - * the challenge to use. - */ - - if (!msrpc_parse(&chal1, "CdUdbddB", - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8, - &unkn1, &unkn2, - &struct_blob)) { - DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); - return False; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { + return False; } - - if (ntlmssp_command != NTLMSSP_CHALLENGE) { - DEBUG(0, ("NTLMSSP Response != NTLMSSP_CHALLENGE. Got %0X\n", - ntlmssp_command)); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, workgroup))) { return False; } - - if (challenge_blob.length < 8) { + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { return False; } - DEBUG(10, ("Challenge:\n")); - dump_data(10, challenge_blob.data, 8); - - /* encrypt the password with the challenge which is in the blob */ - memcpy(challenge, challenge_blob.data, 8); - SMBencrypt(pass, challenge,lmhash); - SMBNTencrypt(pass, challenge,nthash); - data_blob_free(&challenge_blob); - -#if 0 - file_save("nthash.dat", nthash, 24); - file_save("lmhash.dat", lmhash, 24); - file_save("chal1.dat", chal1.data, chal1.length); -#endif - - data_blob_free(&chal1); - data_blob_free(&chal2); - - /* this generates the actual auth packet */ - msrpc_gen(&blob, "CdBBUUUBd", - "NTLMSSP", - NTLMSSP_AUTH, - lmhash, 24, - nthash, 24, - workgroup, - user, - cli->calling.name, - sess_key, 0, - neg_flags); - - /* wrap it in SPNEGO */ - auth = spnego_gen_auth(blob); - - data_blob_free(&blob); - - /* now send the auth packet and we should be done */ - blob = cli_session_setup_blob(cli, auth); - - data_blob_free(&auth); - data_blob_free(&blob); + ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(); + + do { + nt_status = ntlmssp_client_update(ntlmssp_state, + blob_in, &blob_out); + data_blob_free(&blob_in); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (turn == 1) { + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); + } else { + /* wrap it in SPNEGO */ + msg1 = spnego_gen_auth(blob_out); + } + + /* now send that blob on its way */ + blob = cli_session_setup_blob(cli, msg1); + data_blob_free(&msg1); + nt_status = cli_nt_error(cli); + } + + if (!blob.length) { + if (NT_STATUS_IS_OK(nt_status)) { + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } else if ((turn == 1) && + NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + /* the server might give us back two challenges */ + if (!spnego_parse_challenge(blob, &blob_in, + &tmp_blob)) { + DEBUG(3,("Failed to parse challenges\n")); + nt_status = NT_STATUS_INVALID_PARAMETER; + } + data_blob_free(&tmp_blob); + } else { + /* the server might give us back two challenges */ + if (!spnego_parse_auth_response(blob, nt_status, + &blob_in)) { + DEBUG(3,("Failed to parse auth response\n")); + if (NT_STATUS_IS_OK(nt_status) + || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) + nt_status = NT_STATUS_INVALID_PARAMETER; + } + } + data_blob_free(&blob); + data_blob_free(&blob_out); + turn++; + } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); - if (cli_is_error(cli)) + if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { return False; + } - return True; + return (NT_STATUS_IS_OK(nt_status)); } /**************************************************************************** diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 91748c4c7a..e93f1855dd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -345,7 +345,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) /* parse a spnego NTLMSSP challenge packet giving two security blobs */ -BOOL spnego_parse_challenge(DATA_BLOB blob, +BOOL spnego_parse_challenge(const DATA_BLOB blob, DATA_BLOB *chal1, DATA_BLOB *chal2) { BOOL ret; @@ -387,7 +387,7 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, /* - generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords + generate a SPNEGO auth packet. This will contain the encrypted passwords */ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) { @@ -412,7 +412,7 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) } /* - parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords + parse a SPNEGO auth packet. This contains the encrypted passwords */ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) { @@ -461,6 +461,7 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_push_tag(&data, ASN1_CONTEXT(0)); asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); + if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { asn1_push_tag(&data,ASN1_CONTEXT(1)); asn1_write_OID(&data, OID_NTLMSSP); @@ -478,3 +479,52 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_free(&data); return ret; } + +/* + parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords +*/ +BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, + DATA_BLOB *auth) +{ + ASN1_DATA data; + uint8 negResult; + + if (NT_STATUS_IS_OK(nt_status)) { + negResult = SPNEGO_NEG_RESULT_ACCEPT; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + negResult = SPNEGO_NEG_RESULT_INCOMPLETE; + } else { + negResult = SPNEGO_NEG_RESULT_REJECT; + } + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_check_enumerated(&data, negResult); + asn1_end_tag(&data); + + if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_check_OID(&data, OID_NTLMSSP); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_OctetString(&data, auth); + asn1_end_tag(&data); + } + + asn1_end_tag(&data); + asn1_end_tag(&data); + + if (data.has_error) { + DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data.ofs)); + asn1_free(&data); + data_blob_free(auth); + return False; + } + + asn1_free(&data); + return True; +} + diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 09340caccd..8ee5ee3d31 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1410,7 +1410,7 @@ static const struct { /***************************************************************************** convert a dos eclas/ecode to a NT status32 code *****************************************************************************/ -NTSTATUS dos_to_ntstatus(int eclass, int ecode) +NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode) { int i; if (eclass == 0 && ecode == 0) return NT_STATUS_OK; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 92a18d25c0..7992c1e84a 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -25,6 +25,7 @@ /** * Print out the NTLMSSP flags for debugging + * @param neg_flags The flags from the packet */ void debug_ntlmssp_flags(uint32 neg_flags) @@ -78,6 +79,16 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) return chal; } +/** + * Determine correct target name flags for reply, given server role + * and negoitated falgs + * + * @param ntlmssp_state NTLMSSP State + * @param neg_flags The flags from the packet + * @param chal_flags The flags to be set in the reply packet + * @return The 'target name' string. + */ + static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, uint32 neg_flags, uint32 *chal_flags) { @@ -96,8 +107,17 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, } } +/** + * Next state function for the Negotiate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. + */ + static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) + const DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB struct_blob; fstring dnsname, dnsdomname; @@ -201,8 +221,17 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_MORE_PROCESSING_REQUIRED; } +/** + * Next state function for the Authenticate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) + const DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB sess_key; uint32 ntlmssp_command, neg_flags; @@ -259,6 +288,12 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, return nt_status; } +/** + * Create an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, allocated by this funciton + */ + NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx; @@ -286,6 +321,12 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) return NT_STATUS_OK; } +/** + * End an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, free()ed by this funciton + */ + NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; @@ -303,8 +344,17 @@ NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) return NT_STATUS_OK; } +/** + * Next state function for the NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. + */ + NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) + const DATA_BLOB request, DATA_BLOB *reply) { uint32 ntlmssp_command; *reply = data_blob(NULL, 0); @@ -328,3 +378,251 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, } } +/********************************************************************* + Client side NTLMSSP +*********************************************************************/ + +/** + * Next state function for the Initial packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB. reply.data must be NULL + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request) +{ + if (ntlmssp_state->unicode) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + } + + /* generate the ntlmssp negotiate packet */ + msrpc_gen(next_request, "CddAA", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + ntlmssp_state->neg_flags, + ntlmssp_state->get_domain(), + ntlmssp_state->get_global_myname()); + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +/** + * Next state function for the Challenge Packet. Generate an auth packet. + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB. reply.data must be NULL + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_state, + const DATA_BLOB reply, DATA_BLOB *next_request) +{ + uint32 chal_flags, ntlmssp_command, unkn1, unkn2; + DATA_BLOB server_domain_blob; + DATA_BLOB challenge_blob; + DATA_BLOB struct_blob; + char *server_domain; + const char *chal_parse_string; + const char *auth_gen_string; + DATA_BLOB lm_response = data_blob(NULL, 0); + DATA_BLOB nt_response = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + uint8 datagram_sess_key[16]; + + ZERO_STRUCT(datagram_sess_key); + + if (!msrpc_parse(&reply, "CdBd", + "NTLMSSP", + &ntlmssp_command, + &server_domain_blob, + &chal_flags)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + data_blob_free(&server_domain_blob); + + if (chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { + chal_parse_string = "CdUdbddB"; + auth_gen_string = "CdBBUUUBd"; + ntlmssp_state->unicode = True; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; + } else if (chal_flags & NTLMSSP_NEGOTIATE_OEM) { + chal_parse_string = "CdAdbddB"; + auth_gen_string = "CdBBAAABd"; + ntlmssp_state->unicode = False; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + } else { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!msrpc_parse(&reply, chal_parse_string, + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + &challenge_blob, 8, + &unkn1, &unkn2, + &struct_blob)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + SAFE_FREE(server_domain); + data_blob_free(&struct_blob); + + if (challenge_blob.length != 8) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_state->use_ntlmv2) { + + /* TODO: if the remote server is standalone, then we should replace 'domain' + with the server name as supplied above */ + + if (!SMBNTLMv2encrypt(ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->password, challenge_blob, + &lm_response, &nt_response, &session_key)) { + data_blob_free(&challenge_blob); + return NT_STATUS_NO_MEMORY; + } + } else { + uchar nt_hash[16]; + E_md4hash(ntlmssp_state->password, nt_hash); + + /* non encrypted password supplied. Ignore ntpass. */ + if (lp_client_lanman_auth()) { + lm_response = data_blob(NULL, 24); + SMBencrypt(ntlmssp_state->password,challenge_blob.data, + lm_response.data); + } + + nt_response = data_blob(NULL, 24); + SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, + nt_response.data); + session_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + } + + data_blob_free(&challenge_blob); + + /* this generates the actual auth packet */ + if (!msrpc_gen(next_request, auth_gen_string, + "NTLMSSP", + NTLMSSP_AUTH, + lm_response.data, lm_response.length, + nt_response.data, nt_response.length, + ntlmssp_state->domain, + ntlmssp_state->user, + ntlmssp_state->get_global_myname(), + datagram_sess_key, 0, + ntlmssp_state->neg_flags)) { + + data_blob_free(&lm_response); + data_blob_free(&nt_response); + data_blob_free(&session_key); + return NT_STATUS_NO_MEMORY; + } + + data_blob_free(&lm_response); + data_blob_free(&nt_response); + + ntlmssp_state->session_key = session_key; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP Client context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + ZERO_STRUCTP(*ntlmssp_state); + + (*ntlmssp_state)->mem_ctx = mem_ctx; + + (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_domain = lp_workgroup; + + (*ntlmssp_state)->unicode = True; + + (*ntlmssp_state)->neg_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_REQUEST_TARGET; + + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + talloc_destroy(mem_ctx); + *ntlmssp_state = NULL; + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request) +{ + uint32 ntlmssp_command; + *next_request = data_blob(NULL, 0); + + if (!reply.length) { + return ntlmssp_client_initial(ntlmssp_state, reply, next_request); + } + + if (!msrpc_parse(&reply, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command == NTLMSSP_CHALLENGE) { + return ntlmssp_client_challenge(ntlmssp_state, reply, next_request); + } + return NT_STATUS_INVALID_PARAMETER; +} + +NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *user) +{ + ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); + if (!ntlmssp_state->user) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password) +{ + ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); + if (!ntlmssp_state->password) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_set_domain(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *domain) +{ + ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 5f3132694e..6644a3db71 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -181,7 +181,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, /* a helpful macro to avoid running over the end of our blob */ #define NEED_DATA(amount) \ -if (head_ofs + amount > blob->length) { \ +if ((head_ofs + amount) > blob->length) { \ return False; \ } @@ -198,14 +198,14 @@ if (head_ofs + amount > blob->length) { \ C = constant ascii string */ -BOOL msrpc_parse(DATA_BLOB *blob, +BOOL msrpc_parse(const DATA_BLOB *blob, const char *format, ...) { int i; va_list ap; char **ps, *s; DATA_BLOB *b; - int head_ofs = 0; + size_t head_ofs = 0; uint16 len1, len2; uint32 ptr; uint32 *v; -- cgit From 88a4d79e7b771ec8bcc903a7406e15cf4aeea248 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Feb 2003 21:41:01 +0000 Subject: Don't return NULL pointers for now. We should look into how to deal with NULL v "" strings, and the NTLMSSP code underneath properly at some stage. Andrew Bartlett (This used to be commit dc934412b0190ea75073cccddac45e74ebcd4a6b) --- source3/libsmb/ntlmssp_parse.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 6644a3db71..ac779a3906 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -234,9 +234,9 @@ BOOL msrpc_parse(const DATA_BLOB *blob, pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, STR_UNICODE|STR_NOALIGN); - (*ps) = strdup(p); + (*ps) = smb_xstrdup(p); } else { - (*ps) = NULL; + (*ps) = smb_xstrdup(""); } break; case 'A': @@ -255,9 +255,9 @@ BOOL msrpc_parse(const DATA_BLOB *blob, pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, STR_ASCII|STR_NOALIGN); - (*ps) = strdup(p); + (*ps) = smb_xstrdup(p); } else { - (*ps) = NULL; + (*ps) = smb_xstrdup(""); } break; case 'B': -- cgit From b7868582413a346a71997b23587450588d59b9d0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 16 Feb 2003 22:10:48 +0000 Subject: Add the 'session key' output of the NTLMSSP exchange to the cli struct, so it can be used for 'net rpc join'. Also fix a bug in our server-side NTLMSSP code - a client without any domain trust links to us may calculate the NTLMv2 response with "" as the domain. Andrew Bartlett (This used to be commit ddaa42423bc952e59b95362f5f5aa7cca10d1ad4) --- source3/libsmb/cliconnect.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2b0b9abc9d..487b184dd6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -248,6 +248,12 @@ static void set_signing_on_cli (struct cli_state *cli, uint8 user_session_key[16 } } +static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) +{ + memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); +} + + static void set_temp_signing_on_cli(struct cli_state *cli) { if (cli->sign_info.negotiated_smb_signing) @@ -367,6 +373,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (session_key.data) { /* Have plaintext orginal */ + set_cli_session_key(cli, session_key); set_signing_on_cli(cli, session_key.data, nt_response); } @@ -559,6 +566,10 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, turn++; } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); + if (NT_STATUS_IS_OK(nt_status)) { + set_cli_session_key(cli, ntlmssp_state->session_key); + } + if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { return False; } -- cgit From af249535bd8c17e38d5de05352d36747da67e551 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Feb 2003 12:20:20 +0000 Subject: Don't leak a session_key worth of memory at the end of the NTLMSSP auth. (This used to be commit ae9765b84de0fd6eff790b3bff26dd3d43ec2bd6) --- source3/libsmb/ntlmssp.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 7992c1e84a..e4398dad17 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -573,6 +573,7 @@ NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + data_blob_free(&(*ntlmssp_state)->session_key); talloc_destroy(mem_ctx); *ntlmssp_state = NULL; return NT_STATUS_OK; -- cgit From 3fe0de1fcf5ad6d86611e1cc655f9b0663d71da6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Feb 2003 21:19:00 +0000 Subject: Correctly check for inet_addr fail. Patch from gregor.7@osu.edu. Jeremy. (This used to be commit 01f6b2694532749807aff1c2e6f338dade2d9b09) --- source3/libsmb/namequery.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 342a2a2926..62b94761ad 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -809,8 +809,11 @@ static BOOL internal_resolve_name(const char *name, int name_type, } if(is_address) { /* if it's in the form of an IP address then get the lib to interpret it */ - (*return_iplist)->s_addr = inet_addr(name); - } else { + if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){ + DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); + return False; + } + } else { (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0; *return_count = 1; } -- cgit From 21e7ce38ab57bbc9186ec1c155f21f075594a915 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 17 Feb 2003 21:19:09 +0000 Subject: Correctly check for inet_addr fail. Patch from gregor.7@osu.edu. Jeremy. (This used to be commit fb3548e5080812c037c2c134504cc9af4ecbfedd) --- source3/libsmb/namequery.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 342a2a2926..62b94761ad 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -809,8 +809,11 @@ static BOOL internal_resolve_name(const char *name, int name_type, } if(is_address) { /* if it's in the form of an IP address then get the lib to interpret it */ - (*return_iplist)->s_addr = inet_addr(name); - } else { + if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){ + DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); + return False; + } + } else { (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0; *return_count = 1; } -- cgit From d08116ffcbe51c51c338f044e4f9389d3e4c10d5 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 18 Feb 2003 20:57:29 +0000 Subject: Sync w/HEAD - add DES_CBC_CRC encryption type (This used to be commit c7934f5cb56d54a90c9ffdbe2f7429a3c9227abe) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 203d9d874b..e380d80bcc 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -278,6 +278,7 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) ENCTYPE_ARCFOUR_HMAC, #endif ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, ENCTYPE_NULL}; retval = krb5_init_context(&context); @@ -324,7 +325,6 @@ failed: return data_blob(NULL, 0); } - #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) -- cgit From adfefcdcb6e9d8ea0458a11b6f684a5cf231c3ba Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 01:16:40 +0000 Subject: Try to get heimdal working with HEAD. - Provide generic functions for - get valid encryption types - free encryption types - Add encryption type parm to generic function create_kerberos_key_from_string() - Try to merge the two versions (between HEAD and SAMBA_3_0) of kerberos_verify.c I think this should work for both MIT and heimdal, in HEAD. If all goes smooth, I'll move it over to 3.0 soon... (This used to be commit 45e409fc8da9f26cf888e13d004392660d7c55d4) --- source3/libsmb/clikrb5.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e380d80bcc..c13f663381 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -74,7 +74,8 @@ int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, - krb5_keyblock *key) + krb5_keyblock *key, + krb5_enctype enctype) { int ret; krb5_data salt; @@ -85,14 +86,15 @@ DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); return ret; } - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + krb5_use_enctype(context, &eblock, enctype); return krb5_string_to_key(context, &eblock, key, password, &salt); } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, - krb5_keyblock *key) + krb5_keyblock *key, + krb5_enctype enctype) { int ret; krb5_salt salt; @@ -102,13 +104,41 @@ DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); return ret; } - return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, + return krb5_string_to_key_salt(context, enctype, password->data, salt, key); } #else __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS #endif +#if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_permitted_enctypes(context, enctypes); +} +#elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_default_in_tkt_etypes(context, enctypes); +} +#else + __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS +#endif + +#if defined(HAVE_KRB5_FREE_KTYPES) +void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes) +{ + return krb5_free_ktypes(context, enctypes); +} +#else +void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes) +{ + return free(enctypes); +} +#endif + #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, -- cgit From 3b541bdcfe14d30d961a5de20d382af179c381ee Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 03:19:30 +0000 Subject: Get non-krb systems to compile. How the heck do I keep something from being sucked into proto.h? (This used to be commit 7e84497882df5bf933ab7ae7fe9af3728393202c) --- source3/libsmb/clikrb5.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index c13f663381..2e07dfdb66 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -127,17 +127,18 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif -#if defined(HAVE_KRB5_FREE_KTYPES) -void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes) + /* the following is defined as krb5_error_code to keep it from + being sucked into proto.h */ +krb5_error_code free_kerberos_etypes(krb5_context context, + krb5_enctype *enctypes) { - return krb5_free_ktypes(context, enctypes); -} +#if defined(HAVE_KRB5_FREE_KTYPES) + krb5_free_ktypes(context, enctypes); #else -void free_kerberos_etypes(krb5_context context, krb5_enctype *enctypes) -{ - return free(enctypes); -} + SAFE_FREE(enctypes); #endif + return 0; +} #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, -- cgit From f145c2e350db43e401cd477eff89fdef136e7f6c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 10:12:14 +0000 Subject: Only do a kinit if we got told to use kerberos. Andrew Bartlett (This used to be commit 6af9ec50e010d171cf5287f40ec774e79e4a93fe) --- source3/libsmb/cliconnect.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 487b184dd6..c57f92eea9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -630,19 +630,19 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, /* If password is set we reauthenticate to kerberos server * and do not store results */ - if (*pass) { - int ret; - - use_in_memory_ccache(); - ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */); - - if (ret){ - DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); - return False; - } - } - if (got_kerberos_mechanism && cli->use_kerberos) { + if (*pass) { + int ret; + + use_in_memory_ccache(); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */); + + if (ret){ + DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); + return False; + } + } + return cli_session_setup_kerberos(cli, principal, workgroup); } #endif -- cgit From 231f7375590110046ed67b7b337ac2e12d257736 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 11:30:52 +0000 Subject: After a talloc_zero(), we don't need to ZERO_STRUCTP too.. (This used to be commit 4fe8066394143c64c79c052c00f0d747e872103a) --- source3/libsmb/ntlmssp.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e4398dad17..e1509f6b63 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -307,8 +307,6 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(*ntlmssp_state); - (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_challenge = get_challenge; @@ -552,8 +550,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(*ntlmssp_state); - (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_global_myname = global_myname; -- cgit From 251ea1e6776401005e302addd56a689c01924426 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 12:31:16 +0000 Subject: Merge minor library fixes from HEAD to 3.0. - setenv() replacement - mimir's ASN1/SPNEGO typo fixes - (size_t)-1 fixes for push_* returns - function argument signed/unsigned correction - ASN1 error handling (ensure we don't use initiailsed data) - extra net ads join error checking - allow 'set security discriptor' to fail - escape ldap strings in libads. - getgrouplist() correctness fixes (include primary gid) Andrew Bartlett (This used to be commit e9d6e2ea9a3dc01d3849b925c50702cda6ddf225) --- source3/libsmb/asn1.c | 21 ++++++++++++++++----- source3/libsmb/clispnego.c | 15 ++++++++------- source3/libsmb/errormap.c | 2 +- 3 files changed, 25 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 333d157905..09d4fbb6c9 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -240,7 +240,9 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) uint8 b; struct nesting *nesting; - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) + return False; + if (b != tag) { data->has_error = True; return False; @@ -251,13 +253,18 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) return False; } - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) { + return False; + } + if (b & 0x80) { int n = b & 0x7f; - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) + return False; nesting->taglen = b; while (n > 1) { - asn1_read_uint8(data, &b); + if (!asn1_read_uint8(data, &b)) + return False; nesting->taglen = (nesting->taglen << 8) | b; n--; } @@ -404,7 +411,11 @@ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; asn1_read_uint8(data, &b); asn1_end_tag(data); - return !data->has_error && (v == b); + + if (v != b) + data->has_error = False; + + return !data->has_error; } /* write an enumarted value to the stream */ diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 3e28baa417..41b5c3f990 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -345,7 +345,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) /* parse a spnego NTLMSSP challenge packet giving two security blobs */ -BOOL spnego_parse_challenge(DATA_BLOB blob, +BOOL spnego_parse_challenge(const DATA_BLOB blob, DATA_BLOB *chal1, DATA_BLOB *chal2) { BOOL ret; @@ -387,7 +387,7 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, /* - generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords + generate a SPNEGO auth packet. This will contain the encrypted passwords */ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) { @@ -412,7 +412,7 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) } /* - parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords + parse a SPNEGO auth packet. This contains the encrypted passwords */ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) { @@ -447,11 +447,11 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) uint8 negResult; if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNGEO_NEG_RESULT_ACCEPT; + negResult = SPNEGO_NEG_RESULT_ACCEPT; } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNGEO_NEG_RESULT_INCOMPLETE; + negResult = SPNEGO_NEG_RESULT_INCOMPLETE; } else { - negResult = SPNGEO_NEG_RESULT_REJECT; + negResult = SPNEGO_NEG_RESULT_REJECT; } ZERO_STRUCT(data); @@ -461,7 +461,8 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_push_tag(&data, ASN1_CONTEXT(0)); asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (negResult == SPNGEO_NEG_RESULT_INCOMPLETE) { + + if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { asn1_push_tag(&data,ASN1_CONTEXT(1)); asn1_write_OID(&data, OID_NTLMSSP); asn1_pop_tag(&data); diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 09340caccd..8ee5ee3d31 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1410,7 +1410,7 @@ static const struct { /***************************************************************************** convert a dos eclas/ecode to a NT status32 code *****************************************************************************/ -NTSTATUS dos_to_ntstatus(int eclass, int ecode) +NTSTATUS dos_to_ntstatus(uint8 eclass, uint32 ecode) { int i; if (eclass == 0 && ecode == 0) return NT_STATUS_OK; -- cgit From ffcee0c95e05f652f4eebf9b9d46bd51d059891b Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:22:46 +0000 Subject: Correct way to keep fucntion from proto.h (This used to be commit 762b072efb0d6801775a874494cb19ea3d61fa97) --- source3/libsmb/clikrb5.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2e07dfdb66..da120622ea 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -127,17 +127,14 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif - /* the following is defined as krb5_error_code to keep it from - being sucked into proto.h */ -krb5_error_code free_kerberos_etypes(krb5_context context, - krb5_enctype *enctypes) + void free_kerberos_etypes(krb5_context context, + krb5_enctype *enctypes) { #if defined(HAVE_KRB5_FREE_KTYPES) - krb5_free_ktypes(context, enctypes); + return krb5_free_ktypes(context, enctypes); #else - SAFE_FREE(enctypes); + return SAFE_FREE(enctypes); #endif - return 0; } #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) -- cgit From f15ed71fbba9d3762f4e8a1382b65d6291a2a065 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:46:15 +0000 Subject: Can't return SAFE_FREE...put on its own line. (This used to be commit 9f1a4809b503f050189d5f87a294b7d8675b1e95) --- source3/libsmb/clikrb5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index da120622ea..96e737166c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -133,7 +133,8 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, #if defined(HAVE_KRB5_FREE_KTYPES) return krb5_free_ktypes(context, enctypes); #else - return SAFE_FREE(enctypes); + SAFE_FREE(enctypes); + return; #endif } -- cgit From 83a11f7f0e4331602acefcb3324be6f35f1fef0e Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 19 Feb 2003 15:48:12 +0000 Subject: Sync with HEAD for verifying kerberos tickets. (This used to be commit 77e1178a888f0d380a5ef94911a8f07bf04a7ba3) --- source3/libsmb/clikrb5.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e380d80bcc..96e737166c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -74,7 +74,8 @@ int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, - krb5_keyblock *key) + krb5_keyblock *key, + krb5_enctype enctype) { int ret; krb5_data salt; @@ -85,14 +86,15 @@ DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); return ret; } - krb5_use_enctype(context, &eblock, ENCTYPE_DES_CBC_MD5); + krb5_use_enctype(context, &eblock, enctype); return krb5_string_to_key(context, &eblock, key, password, &salt); } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, - krb5_keyblock *key) + krb5_keyblock *key, + krb5_enctype enctype) { int ret; krb5_salt salt; @@ -102,13 +104,40 @@ DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); return ret; } - return krb5_string_to_key_salt(context, ENCTYPE_DES_CBC_MD5, password->data, + return krb5_string_to_key_salt(context, enctype, password->data, salt, key); } #else __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS #endif +#if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_permitted_enctypes(context, enctypes); +} +#elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) +krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_enctype **enctypes) +{ + return krb5_get_default_in_tkt_etypes(context, enctypes); +} +#else + __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS +#endif + + void free_kerberos_etypes(krb5_context context, + krb5_enctype *enctypes) +{ +#if defined(HAVE_KRB5_FREE_KTYPES) + return krb5_free_ktypes(context, enctypes); +#else + SAFE_FREE(enctypes); + return; +#endif +} + #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, -- cgit From e1c987abf2c716e26d2484a89e23507d1d2a9c5e Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 21 Feb 2003 05:07:51 +0000 Subject: Doesn't anyone run ./configure.developer anymore? (This used to be commit 09be123c6c1b67621eaf6c8ffb3016eccd375e5b) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c57f92eea9..901daf4b09 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -453,7 +453,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /**************************************************************************** Use in-memory credentials cache ****************************************************************************/ -static void use_in_memory_ccache() { +static void use_in_memory_ccache(void) { setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); } -- cgit From 23553b48e6bd21481ca32c4b3ee54fc1aded4174 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 21 Feb 2003 14:35:02 +0000 Subject: Fix IRIX build...void fn can't return another void fn (This used to be commit df3c7c9cbb275e9c35356b4f1cab1a741de6f500) --- source3/libsmb/clikrb5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 96e737166c..bef6998a49 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -131,7 +131,8 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype *enctypes) { #if defined(HAVE_KRB5_FREE_KTYPES) - return krb5_free_ktypes(context, enctypes); + krb5_free_ktypes(context, enctypes); + return; #else SAFE_FREE(enctypes); return; -- cgit From 217945cfc824ac0209738246d48ef2ece487f59b Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 21 Feb 2003 14:38:14 +0000 Subject: Fix IRIX build...void fn can't return another void fn (This used to be commit e0c1f9ef61a0ec4f06a0b0e257497943195b5297) --- source3/libsmb/clikrb5.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 96e737166c..bef6998a49 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -131,7 +131,8 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype *enctypes) { #if defined(HAVE_KRB5_FREE_KTYPES) - return krb5_free_ktypes(context, enctypes); + krb5_free_ktypes(context, enctypes); + return; #else SAFE_FREE(enctypes); return; -- cgit From d1221c9b6c369113a531063737890b58d89bf6fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:55:00 +0000 Subject: Merge from HEAD client-side authentication changes: - new kerberos code, allowing the account to change it's own password without special SD settings required - NTLMSSP client code, now seperated from cliconnect.c - NTLMv2 client code - SMB signing fixes Andrew Bartlett (This used to be commit 837680ca517982f2e5944730581a83012d4181ae) --- source3/libsmb/cliconnect.c | 313 ++++++++++++++-------------- source3/libsmb/clientgen.c | 18 +- source3/libsmb/clispnego.c | 321 ++++------------------------- source3/libsmb/ntlmssp.c | 488 +++++++++++++++++++++++++++++++++++++------- source3/libsmb/smbencrypt.c | 111 +++++++++- 5 files changed, 734 insertions(+), 517 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 389b7a1733..4962ffa3c9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 - Copyright (C) Andrew Barteltt 2001-2002 + Copyright (C) Andrew Bartlett 2001-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -45,7 +45,7 @@ static const struct { ****************************************************************************/ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, - const char *pass, int passlen, const char *workgroup) + const char *pass, size_t passlen, const char *workgroup) { fstring pword; char *p; @@ -228,7 +228,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 response[24]) +static void set_signing_on_cli (struct cli_state *cli, uint8 user_session_key[16], DATA_BLOB response) { uint8 zero_sig[8]; ZERO_STRUCT(zero_sig); @@ -242,12 +242,18 @@ static void set_signing_on_cli (struct cli_state *cli, const char* pass, uint8 r DEBUG(3, ("smb signing enabled!\n")); cli->sign_info.use_smb_signing = True; - cli_calculate_mac_key(cli, pass, response); + cli_calculate_mac_key(cli, user_session_key, response); } else { DEBUG(5, ("smb signing NOT enabled!\n")); } } +static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) +{ + memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); +} + + static void set_temp_signing_on_cli(struct cli_state *cli) { if (cli->sign_info.negotiated_smb_signing) @@ -265,37 +271,54 @@ static void set_temp_signing_on_cli(struct cli_state *cli) ****************************************************************************/ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, - const char *pass, int passlen, - const char *ntpass, int ntpasslen, + const char *pass, size_t passlen, + const char *ntpass, size_t ntpasslen, const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); - uchar pword[24]; - uchar ntpword[24]; + DATA_BLOB lm_response = data_blob(NULL, 0); + DATA_BLOB nt_response = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + BOOL ret = False; char *p; - BOOL have_plaintext = False; - - if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) - return False; if (passlen != 24) { - /* non encrypted password supplied. Ignore ntpass. */ - passlen = 24; - ntpasslen = 24; - SMBencrypt(pass,cli->secblob.data,pword); - SMBNTencrypt(pass,cli->secblob.data,ntpword); + if (lp_client_ntlmv2_auth()) { + DATA_BLOB server_chal; + + server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); + + if (!SMBNTLMv2encrypt(user, workgroup, pass, server_chal, + &lm_response, &nt_response, &session_key)) { + data_blob_free(&server_chal); + return False; + } + data_blob_free(&server_chal); + + } else { + uchar nt_hash[16]; + E_md4hash(pass, nt_hash); + + /* non encrypted password supplied. Ignore ntpass. */ + if (lp_client_lanman_auth()) { + lm_response = data_blob(NULL, 24); + SMBencrypt(pass,cli->secblob.data,lm_response.data); + } + + nt_response = data_blob(NULL, 24); + SMBNTencrypt(pass,cli->secblob.data,nt_response.data); + session_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + } - have_plaintext = True; set_temp_signing_on_cli(cli); } else { /* pre-encrypted password supplied. Only used for security=server, can't do signing becouse we don't have oringial key */ - memcpy(pword, pass, 24); - if (ntpasslen == 24) - memcpy(ntpword, ntpass, 24); - else - ZERO_STRUCT(ntpword); + + lm_response = data_blob(pass, passlen); + nt_response = data_blob(ntpass, ntpasslen); } /* send a session setup command */ @@ -310,28 +333,33 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,cli->pid); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); - SSVAL(cli->outbuf,smb_vwv8,ntpasslen); + SSVAL(cli->outbuf,smb_vwv7,lm_response.length); + SSVAL(cli->outbuf,smb_vwv8,nt_response.length); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); p += passlen; - memcpy(p,ntpword,ntpasslen); p += ntpasslen; + if (lm_response.length) { + memcpy(p,lm_response.data, lm_response.length); p += lm_response.length; + } + if (nt_response.length) { + memcpy(p,nt_response.data, nt_response.length); p += nt_response.length; + } p += clistr_push(cli, p, user, -1, STR_TERMINATE); p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - if (!cli_send_smb(cli)) - return False; - - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + ret = False; + goto end; + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + ret = False; + goto end; + } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -343,11 +371,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, fstrcpy(cli->user_name, user); - if (have_plaintext) { + if (session_key.data) { /* Have plaintext orginal */ - set_signing_on_cli(cli, pass, ntpword); + set_cli_session_key(cli, session_key); + set_signing_on_cli(cli, session_key.data, nt_response); } - + +end: + data_blob_free(&lm_response); + data_blob_free(&nt_response); + data_blob_free(&session_key); return True; } @@ -359,11 +392,9 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; - DATA_BLOB blob2; + DATA_BLOB blob2 = data_blob(NULL, 0); uint32 len; - blob2 = data_blob(NULL, 0); - capabilities |= CAP_EXTENDED_SECURITY; /* send a session setup command */ @@ -419,6 +450,13 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) } #ifdef HAVE_KRB5 +/**************************************************************************** + Use in-memory credentials cache +****************************************************************************/ +static void use_in_memory_ccache(void) { + setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); +} + /**************************************************************************** Do a spnego/kerberos encrypted session setup. ****************************************************************************/ @@ -456,126 +494,87 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, const char *pass, const char *workgroup) { - DATA_BLOB msg1, struct_blob; - DATA_BLOB blob, chal1, chal2, auth, challenge_blob; - uint8 challenge[8]; - uint8 nthash[24], lmhash[24], sess_key[16]; - uint32 neg_flags, chal_flags, ntlmssp_command, unkn1, unkn2; - pstring server_domain; /* FIX THIS, SHOULD be UCS2-LE */ - - neg_flags = NTLMSSP_NEGOTIATE_UNICODE | - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_REQUEST_TARGET; - - memset(sess_key, 0, 16); - - DEBUG(10, ("sending NTLMSSP_NEGOTIATE\n")); - - /* generate the ntlmssp negotiate packet */ - msrpc_gen(&blob, "CddAA", - "NTLMSSP", - NTLMSSP_NEGOTIATE, - neg_flags, - workgroup, - cli->calling.name); - DEBUG(10, ("neg_flags: %0X, workgroup: %s, calling name %s\n", - neg_flags, workgroup, cli->calling.name)); - /* and wrap it in a SPNEGO wrapper */ - msg1 = gen_negTokenInit(OID_NTLMSSP, blob); - data_blob_free(&blob); - - /* now send that blob on its way */ - blob = cli_session_setup_blob(cli, msg1); - - data_blob_free(&msg1); + struct ntlmssp_client_state *ntlmssp_state; + NTSTATUS nt_status; + int turn = 1; + DATA_BLOB msg1; + DATA_BLOB blob; + DATA_BLOB blob_in = data_blob(NULL, 0); + DATA_BLOB blob_out; - if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return False; + } -#if 0 - file_save("chal.dat", blob.data, blob.length); -#endif - - /* the server gives us back two challenges */ - if (!spnego_parse_challenge(blob, &chal1, &chal2)) { - DEBUG(3,("Failed to parse challenges\n")); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { return False; } - - data_blob_free(&blob); - - /* - * Ok, chal1 and chal2 are actually two identical copies of - * the NTLMSSP Challenge BLOB, and they contain, encoded in them - * the challenge to use. - */ - - if (!msrpc_parse(&chal1, "CdUdbddB", - "NTLMSSP", - &ntlmssp_command, - &server_domain, - &chal_flags, - &challenge_blob, 8, - &unkn1, &unkn2, - &struct_blob)) { - DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); - return False; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, workgroup))) { + return False; } - - if (ntlmssp_command != NTLMSSP_CHALLENGE) { - DEBUG(0, ("NTLMSSP Response != NTLMSSP_CHALLENGE. Got %0X\n", - ntlmssp_command)); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { return False; } - - DEBUG(10, ("Challenge:\n")); - dump_data(10, challenge_blob.data, 8); - - /* encrypt the password with the challenge which is in the blob */ - memcpy(challenge, challenge_blob.data, 8); - SMBencrypt(pass, challenge,lmhash); - SMBNTencrypt(pass, challenge,nthash); - data_blob_free(&challenge_blob); - -#if 0 - file_save("nthash.dat", nthash, 24); - file_save("lmhash.dat", lmhash, 24); - file_save("chal1.dat", chal1.data, chal1.length); -#endif - - data_blob_free(&chal1); - data_blob_free(&chal2); - /* this generates the actual auth packet */ - msrpc_gen(&blob, "CdBBUUUBd", - "NTLMSSP", - NTLMSSP_AUTH, - lmhash, 24, - nthash, 24, - workgroup, - user, - cli->calling.name, - sess_key, 0, - neg_flags); - - /* wrap it in SPNEGO */ - auth = spnego_gen_auth(blob); - - data_blob_free(&blob); - - /* now send the auth packet and we should be done */ - blob = cli_session_setup_blob(cli, auth); + ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(); + + do { + nt_status = ntlmssp_client_update(ntlmssp_state, + blob_in, &blob_out); + data_blob_free(&blob_in); + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (turn == 1) { + /* and wrap it in a SPNEGO wrapper */ + msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); + } else { + /* wrap it in SPNEGO */ + msg1 = spnego_gen_auth(blob_out); + } + + /* now send that blob on its way */ + blob = cli_session_setup_blob(cli, msg1); + data_blob_free(&msg1); + nt_status = cli_nt_error(cli); + } + + if (!blob.length) { + if (NT_STATUS_IS_OK(nt_status)) { + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } else if ((turn == 1) && + NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DATA_BLOB tmp_blob = data_blob(NULL, 0); + /* the server might give us back two challenges */ + if (!spnego_parse_challenge(blob, &blob_in, + &tmp_blob)) { + DEBUG(3,("Failed to parse challenges\n")); + nt_status = NT_STATUS_INVALID_PARAMETER; + } + data_blob_free(&tmp_blob); + } else { + /* the server might give us back two challenges */ + if (!spnego_parse_auth_response(blob, nt_status, + &blob_in)) { + DEBUG(3,("Failed to parse auth response\n")); + if (NT_STATUS_IS_OK(nt_status) + || NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) + nt_status = NT_STATUS_INVALID_PARAMETER; + } + } + data_blob_free(&blob); + data_blob_free(&blob_out); + turn++; + } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); - data_blob_free(&auth); - data_blob_free(&blob); + if (NT_STATUS_IS_OK(nt_status)) { + set_cli_session_key(cli, ntlmssp_state->session_key); + } - if (cli_is_error(cli)) + if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { return False; + } - set_signing_on_cli(cli, pass, nthash); - - return True; + return (NT_STATUS_IS_OK(nt_status)); } /**************************************************************************** @@ -628,7 +627,22 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, fstrcpy(cli->user_name, user); #ifdef HAVE_KRB5 + /* If password is set we reauthenticate to kerberos server + * and do not store results */ + if (got_kerberos_mechanism && cli->use_kerberos) { + if (*pass) { + int ret; + + use_in_memory_ccache(); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */); + + if (ret){ + DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); + return False; + } + } + return cli_session_setup_kerberos(cli, principal, workgroup); } #endif @@ -942,7 +956,10 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) + cli->sign_info.negotiated_smb_signing = True; + + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) && cli->sign_info.allow_smb_signing) cli->sign_info.negotiated_smb_signing = True; } else if (cli->protocol >= PROTOCOL_LANMAN1) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ed1286d627..9598f4ac96 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -114,9 +114,14 @@ BOOL cli_receive_smb(struct cli_state *cli) cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; + return ret; } - return ret; + if (!cli_check_sign_mac(cli)) { + DEBUG(0, ("SMB Signiture verification failed on incoming packet!\n")); + return False; + }; + return True; } /**************************************************************************** @@ -246,8 +251,10 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); cli->oplock_handler = cli_oplock_ack; - if (lp_use_spnego()) - cli->use_spnego = True; + + cli->use_spnego = lp_client_use_spnego(); + + cli->capabilities = CAP_UNICODE | CAP_STATUS32; /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 @@ -255,9 +262,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - /* A way to attempt to force SMB signing */ - if (getenv("CLI_FORCE_SMB_SIGNING")) - cli->sign_info.negotiated_smb_signing = True; + if (lp_client_signing()) + cli->sign_info.allow_smb_signing = True; if (!cli->outbuf || !cli->inbuf) goto error; diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 41b5c3f990..e93f1855dd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -481,297 +481,50 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) } /* - this is a tiny msrpc packet generator. I am only using this to - avoid tying this code to a particular varient of our rpc code. This - generator is not general enough for all our rpc needs, its just - enough for the spnego/ntlmssp code - - format specifiers are: - - U = unicode string (input is unix string) - a = address (input is BOOL unicode, char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) - B = data blob (pointer + length) - b = data blob in header (pointer + length) - D - d = word (4 bytes) - C = constant ascii string - */ -BOOL msrpc_gen(DATA_BLOB *blob, - const char *format, ...) + parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords +*/ +BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, + DATA_BLOB *auth) { - int i, n; - va_list ap; - char *s; - uint8 *b; - int head_size=0, data_size=0; - int head_ofs, data_ofs; - BOOL unicode; - - /* first scan the format to work out the header and body size */ - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_charnum(s) * 2; - break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_ascii_charnum(s); - break; - case 'a': - unicode = va_arg(ap, BOOL); - n = va_arg(ap, int); - s = va_arg(ap, char *); - if (unicode) { - data_size += (str_charnum(s) * 2) + 4; - } else { - data_size += (str_ascii_charnum(s)) + 4; - } - break; - case 'B': - b = va_arg(ap, uint8 *); - head_size += 8; - data_size += va_arg(ap, int); - break; - case 'b': - b = va_arg(ap, uint8 *); - head_size += va_arg(ap, int); - break; - case 'd': - n = va_arg(ap, int); - head_size += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_size += str_charnum(s) + 1; - break; - } - } - va_end(ap); - - /* allocate the space, then scan the format again to fill in the values */ - *blob = data_blob(NULL, head_size + data_size); - - head_ofs = 0; - data_ofs = head_size; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); - data_ofs += n*2; - break; - case 'A': - s = va_arg(ap, char *); - n = str_ascii_charnum(s); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); - data_ofs += n; - break; - case 'a': - unicode = va_arg(ap, BOOL); - n = va_arg(ap, int); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - s = va_arg(ap, char *); - if (unicode) { - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - } else { - n = str_ascii_charnum(s); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n, - STR_ASCII|STR_NOALIGN); - } - data_ofs += n; - } - break; - - case 'B': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - memcpy(blob->data+data_ofs, b, n); - data_ofs += n; - break; - case 'd': - n = va_arg(ap, int); - SIVAL(blob->data, head_ofs, n); head_ofs += 4; - break; - case 'b': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - memcpy(blob->data + head_ofs, b, n); - head_ofs += n; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, - STR_ASCII|STR_TERMINATE); - break; - } - } - va_end(ap); + ASN1_DATA data; + uint8 negResult; - return True; -} + if (NT_STATUS_IS_OK(nt_status)) { + negResult = SPNEGO_NEG_RESULT_ACCEPT; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + negResult = SPNEGO_NEG_RESULT_INCOMPLETE; + } else { + negResult = SPNEGO_NEG_RESULT_REJECT; + } + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_check_enumerated(&data, negResult); + asn1_end_tag(&data); -/* - this is a tiny msrpc packet parser. This the the partner of msrpc_gen - - format specifiers are: - - U = unicode string (output is unix string) - A = ascii string - B = data blob - b = data blob in header - d = word (4 bytes) - C = constant ascii string - */ -BOOL msrpc_parse(DATA_BLOB *blob, - const char *format, ...) -{ - int i; - va_list ap; - char **ps, *s; - DATA_BLOB *b; - int head_ofs = 0; - uint16 len1, len2; - uint32 ptr; - uint32 *v; - pstring p; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - /* make sure its in the right format - be strict */ - if (len1 != len2 || (len1&1) || ptr + len1 > blob->length) { - return False; - } - ps = va_arg(ap, char **); - pull_string(NULL, p, blob->data + ptr, -1, len1, - STR_UNICODE|STR_NOALIGN); - (*ps) = strdup(p); - break; - case 'A': - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - ps = va_arg(ap, char **); - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, -1, - len1, STR_ASCII|STR_NOALIGN); - (*ps) = strdup(p); - } else { - (*ps) = NULL; - } - break; - case 'B': - len1 = SVAL(blob->data, head_ofs); head_ofs += 2; - len2 = SVAL(blob->data, head_ofs); head_ofs += 2; - ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - b = (DATA_BLOB *)va_arg(ap, void *); - *b = data_blob(blob->data + ptr, len1); - break; - case 'b': - b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, unsigned); - *b = data_blob(blob->data + head_ofs, len1); - head_ofs += len1; - break; - case 'd': - v = va_arg(ap, uint32 *); - *v = IVAL(blob->data, head_ofs); head_ofs += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - return False; - } - break; - } + if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_check_OID(&data, OID_NTLMSSP); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_OctetString(&data, auth); + asn1_end_tag(&data); } - va_end(ap); - return True; -} + asn1_end_tag(&data); + asn1_end_tag(&data); -/** - * Print out the NTLMSSP flags for debugging - */ + if (data.has_error) { + DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data.ofs)); + asn1_free(&data); + data_blob_free(auth); + return False; + } -void debug_ntlmssp_flags(uint32 neg_flags) -{ - DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); - if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); - if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); + asn1_free(&data); + return True; } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 5b608e0a7a..e1509f6b63 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -24,11 +24,53 @@ #include "includes.h" /** - * Default challange generation code. + * Print out the NTLMSSP flags for debugging + * @param neg_flags The flags from the packet + */ + +void debug_ntlmssp_flags(uint32 neg_flags) +{ + DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); + + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_OEM) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + if (neg_flags & NTLMSSP_REQUEST_TARGET) + DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) + DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_128) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); +} + +/** + * Default challenge generation code. * */ - static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) { static uchar chal[8]; @@ -37,71 +79,17 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) return chal; } -NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx; - - mem_ctx = talloc_init("NTLMSSP context"); - - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); - if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_start: talloc failed!\n")); - talloc_destroy(mem_ctx); - return NT_STATUS_NO_MEMORY; - } - - ZERO_STRUCTP(*ntlmssp_state); - - (*ntlmssp_state)->mem_ctx = mem_ctx; - (*ntlmssp_state)->get_challenge = get_challenge; - - (*ntlmssp_state)->get_global_myname = global_myname; - (*ntlmssp_state)->get_domain = lp_workgroup; - (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ - - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); - - SAFE_FREE((*ntlmssp_state)->user); - SAFE_FREE((*ntlmssp_state)->domain); - SAFE_FREE((*ntlmssp_state)->workstation); - - talloc_destroy(mem_ctx); - *ntlmssp_state = NULL; - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) -{ - uint32 ntlmssp_command; - *reply = data_blob(NULL, 0); - - if (!msrpc_parse(&request, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - - return NT_STATUS_LOGON_FAILURE; - } - - if (ntlmssp_command == NTLMSSP_NEGOTIATE) { - return ntlmssp_negotiate(ntlmssp_state, request, reply); - } else if (ntlmssp_command == NTLMSSP_AUTH) { - return ntlmssp_auth(ntlmssp_state, request, reply); - } else { - return NT_STATUS_LOGON_FAILURE; - } -} +/** + * Determine correct target name flags for reply, given server role + * and negoitated falgs + * + * @param ntlmssp_state NTLMSSP State + * @param neg_flags The flags from the packet + * @param chal_flags The flags to be set in the reply packet + * @return The 'target name' string. + */ -static const char *ntlmssp_target_name(NTLMSSP_STATE *ntlmssp_state, +static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, uint32 neg_flags, uint32 *chal_flags) { if (neg_flags & NTLMSSP_REQUEST_TARGET) { @@ -119,8 +107,17 @@ static const char *ntlmssp_target_name(NTLMSSP_STATE *ntlmssp_state, } } -NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) +/** + * Next state function for the Negotiate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. + */ + +static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB struct_blob; fstring dnsname, dnsdomname; @@ -140,7 +137,7 @@ NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, &neg_flags, &cliname, &domname)) { - return NT_STATUS_LOGON_FAILURE; + return NT_STATUS_INVALID_PARAMETER; } SAFE_FREE(cliname); @@ -219,11 +216,22 @@ NTSTATUS ntlmssp_negotiate(NTLMSSP_STATE *ntlmssp_state, data_blob_free(&struct_blob); + ntlmssp_state->expected_state = NTLMSSP_AUTH; + return NT_STATUS_MORE_PROCESSING_REQUIRED; } -NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) +/** + * Next state function for the Authenticate packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB sess_key; uint32 ntlmssp_command, neg_flags; @@ -260,7 +268,7 @@ NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, &ntlmssp_state->workstation, &sess_key, &neg_flags)) { - return NT_STATUS_LOGON_FAILURE; + return NT_STATUS_INVALID_PARAMETER; } data_blob_free(&sess_key); @@ -279,3 +287,339 @@ NTSTATUS ntlmssp_auth(NTLMSSP_STATE *ntlmssp_state, return nt_status; } + +/** + * Create an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, allocated by this funciton + */ + +NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*ntlmssp_state)->mem_ctx = mem_ctx; + (*ntlmssp_state)->get_challenge = get_challenge; + + (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_domain = lp_workgroup; + (*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */ + + (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; + + return NT_STATUS_OK; +} + +/** + * End an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, free()ed by this funciton + */ + +NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + + SAFE_FREE((*ntlmssp_state)->user); + SAFE_FREE((*ntlmssp_state)->domain); + SAFE_FREE((*ntlmssp_state)->workstation); + + talloc_destroy(mem_ctx); + *ntlmssp_state = NULL; + return NT_STATUS_OK; +} + +/** + * Next state function for the NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. + */ + +NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply) +{ + uint32 ntlmssp_command; + *reply = data_blob(NULL, 0); + + if (!msrpc_parse(&request, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command != ntlmssp_state->expected_state) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command == NTLMSSP_NEGOTIATE) { + return ntlmssp_server_negotiate(ntlmssp_state, request, reply); + } else if (ntlmssp_command == NTLMSSP_AUTH) { + return ntlmssp_server_auth(ntlmssp_state, request, reply); + } else { + return NT_STATUS_INVALID_PARAMETER; + } +} + +/********************************************************************* + Client side NTLMSSP +*********************************************************************/ + +/** + * Next state function for the Initial packet + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB. reply.data must be NULL + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request) +{ + if (ntlmssp_state->unicode) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + } + + /* generate the ntlmssp negotiate packet */ + msrpc_gen(next_request, "CddAA", + "NTLMSSP", + NTLMSSP_NEGOTIATE, + ntlmssp_state->neg_flags, + ntlmssp_state->get_domain(), + ntlmssp_state->get_global_myname()); + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +/** + * Next state function for the Challenge Packet. Generate an auth packet. + * + * @param ntlmssp_state NTLMSSP State + * @param request The request, as a DATA_BLOB. reply.data must be NULL + * @param request The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors or NT_STATUS_OK. + */ + +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_state, + const DATA_BLOB reply, DATA_BLOB *next_request) +{ + uint32 chal_flags, ntlmssp_command, unkn1, unkn2; + DATA_BLOB server_domain_blob; + DATA_BLOB challenge_blob; + DATA_BLOB struct_blob; + char *server_domain; + const char *chal_parse_string; + const char *auth_gen_string; + DATA_BLOB lm_response = data_blob(NULL, 0); + DATA_BLOB nt_response = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + uint8 datagram_sess_key[16]; + + ZERO_STRUCT(datagram_sess_key); + + if (!msrpc_parse(&reply, "CdBd", + "NTLMSSP", + &ntlmssp_command, + &server_domain_blob, + &chal_flags)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + data_blob_free(&server_domain_blob); + + if (chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { + chal_parse_string = "CdUdbddB"; + auth_gen_string = "CdBBUUUBd"; + ntlmssp_state->unicode = True; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; + } else if (chal_flags & NTLMSSP_NEGOTIATE_OEM) { + chal_parse_string = "CdAdbddB"; + auth_gen_string = "CdBBAAABd"; + ntlmssp_state->unicode = False; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + } else { + return NT_STATUS_INVALID_PARAMETER; + } + + if (!msrpc_parse(&reply, chal_parse_string, + "NTLMSSP", + &ntlmssp_command, + &server_domain, + &chal_flags, + &challenge_blob, 8, + &unkn1, &unkn2, + &struct_blob)) { + DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + SAFE_FREE(server_domain); + data_blob_free(&struct_blob); + + if (challenge_blob.length != 8) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_state->use_ntlmv2) { + + /* TODO: if the remote server is standalone, then we should replace 'domain' + with the server name as supplied above */ + + if (!SMBNTLMv2encrypt(ntlmssp_state->user, + ntlmssp_state->domain, + ntlmssp_state->password, challenge_blob, + &lm_response, &nt_response, &session_key)) { + data_blob_free(&challenge_blob); + return NT_STATUS_NO_MEMORY; + } + } else { + uchar nt_hash[16]; + E_md4hash(ntlmssp_state->password, nt_hash); + + /* non encrypted password supplied. Ignore ntpass. */ + if (lp_client_lanman_auth()) { + lm_response = data_blob(NULL, 24); + SMBencrypt(ntlmssp_state->password,challenge_blob.data, + lm_response.data); + } + + nt_response = data_blob(NULL, 24); + SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, + nt_response.data); + session_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + } + + data_blob_free(&challenge_blob); + + /* this generates the actual auth packet */ + if (!msrpc_gen(next_request, auth_gen_string, + "NTLMSSP", + NTLMSSP_AUTH, + lm_response.data, lm_response.length, + nt_response.data, nt_response.length, + ntlmssp_state->domain, + ntlmssp_state->user, + ntlmssp_state->get_global_myname(), + datagram_sess_key, 0, + ntlmssp_state->neg_flags)) { + + data_blob_free(&lm_response); + data_blob_free(&nt_response); + data_blob_free(&session_key); + return NT_STATUS_NO_MEMORY; + } + + data_blob_free(&lm_response); + data_blob_free(&nt_response); + + ntlmssp_state->session_key = session_key; + + return NT_STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx; + + mem_ctx = talloc_init("NTLMSSP Client context"); + + *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + if (!*ntlmssp_state) { + DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + talloc_destroy(mem_ctx); + return NT_STATUS_NO_MEMORY; + } + + (*ntlmssp_state)->mem_ctx = mem_ctx; + + (*ntlmssp_state)->get_global_myname = global_myname; + (*ntlmssp_state)->get_domain = lp_workgroup; + + (*ntlmssp_state)->unicode = True; + + (*ntlmssp_state)->neg_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_REQUEST_TARGET; + + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + data_blob_free(&(*ntlmssp_state)->session_key); + talloc_destroy(mem_ctx); + *ntlmssp_state = NULL; + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request) +{ + uint32 ntlmssp_command; + *next_request = data_blob(NULL, 0); + + if (!reply.length) { + return ntlmssp_client_initial(ntlmssp_state, reply, next_request); + } + + if (!msrpc_parse(&reply, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + return NT_STATUS_INVALID_PARAMETER; + } + + if (ntlmssp_command == NTLMSSP_CHALLENGE) { + return ntlmssp_client_challenge(ntlmssp_state, reply, next_request); + } + return NT_STATUS_INVALID_PARAMETER; +} + +NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *user) +{ + ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); + if (!ntlmssp_state->user) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password) +{ + ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); + if (!ntlmssp_state->password) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_set_domain(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *domain) +{ + ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index a57a98e3ea..aa9391325f 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -5,6 +5,7 @@ Modified by Jeremy Allison 1995. Copyright (C) Jeremy Allison 1995-2000. Copyright (C) Luke Kennethc Casson Leighton 1996-2000. + Copyright (C) Andrew Bartlett 2002-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -294,6 +295,64 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } +DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], + DATA_BLOB server_chal, size_t client_chal_length) +{ + uchar ntlmv2_response[16]; + DATA_BLOB ntlmv2_client_data; + DATA_BLOB final_response; + + /* NTLMv2 */ + + /* We also get to specify some random data */ + ntlmv2_client_data = data_blob(NULL, client_chal_length); + generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response); + + /* put it into nt_response, for the code below to put into the packet */ + final_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response)); + memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); + /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */ + memcpy(final_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); + data_blob_free(&ntlmv2_client_data); + + return final_response; +} + +BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, + const DATA_BLOB server_chal, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *session_key) +{ + uchar nt_hash[16]; + uchar ntlm_v2_hash[16]; + E_md4hash(password, nt_hash); + + /* We don't use the NT# directly. Instead we use it mashed up with + the username and domain. + This prevents username swapping during the auth exchange + */ + if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) { + return False; + } + + *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); + + /* LMv2 */ + + *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); + + *session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, session_key->data); + + return True; +} + /*********************************************************** encode a password buffer. The caller gets to figure out what to put in it. @@ -362,20 +421,20 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, SMB signing - setup the MAC key. ************************************************************/ -void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uchar resp[24]) +void cli_calculate_mac_key(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) { - /* Get first 16 bytes. */ - E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]); - memcpy(&cli->sign_info.mac_key[16],resp,24); - cli->sign_info.mac_key_len = 40; + + memcpy(&cli->sign_info.mac_key[0], user_session_key, 16); + memcpy(&cli->sign_info.mac_key[16],response.data, MIN(response.length, 40 - 16)); + cli->sign_info.mac_key_len = MIN(response.length + 16, 40); cli->sign_info.use_smb_signing = True; /* These calls are INCONPATIBLE with SMB signing */ cli->readbraw_supported = False; - cli->writebraw_supported = False; + cli->writebraw_supported = False; /* Reset the sequence number in case we had a previous (aborted) attempt */ - cli->sign_info.send_seq_num = 0; + cli->sign_info.send_seq_num = 2; } /*********************************************************** @@ -411,9 +470,47 @@ void cli_caclulate_sign_mac(struct cli_state *cli) MD5Final(calc_md5_mac, &md5_ctx); memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signitures...*/ cli->sign_info.send_seq_num++; cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; cli->sign_info.send_seq_num++; } + +/*********************************************************** + SMB signing - check a MAC sent by server. +************************************************************/ + +BOOL cli_check_sign_mac(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + unsigned char server_sent_mac[8]; + struct MD5Context md5_ctx; + + if (cli->sign_info.temp_smb_signing) { + return True; + } + + if (!cli->sign_info.use_smb_signing) { + return True; + } + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + + SIVAL(cli->inbuf, smb_ss_field, cli->sign_info.reply_seq_num); + SIVAL(cli->inbuf, smb_ss_field + 4, 0); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + return (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); +} -- cgit From eb64538dba772a9846c05e2712839dbaa12c39a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 11:09:21 +0000 Subject: Patch from Luke Howard to add mutual kerberos authentication, and SMB session keys for kerberos authentication. Andrew Bartlett (This used to be commit 8b798f03dbbdd670ff9af4eb46f7b0845c611e0f) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clikrb5.c | 56 +++++++++++++++++++++++++++++++++++++-------- source3/libsmb/clispnego.c | 29 ++++++++++++----------- 3 files changed, 64 insertions(+), 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 901daf4b09..4962ffa3c9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 - Copyright (C) Andrew Barteltt 2001-2003 + Copyright (C) Andrew Bartlett 2001-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index bef6998a49..47dec1f171 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 - Copyright (C) Luke Howard 2002 + Copyright (C) Luke Howard 2002-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,16 @@ #ifdef HAVE_KRB5 +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE +#define KRB5_KEY_TYPE(k) ((k)->keytype) +#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) +#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) +#else +#define KRB5_KEY_TYPE(k) ((k)->enctype) +#define KRB5_KEY_LENGTH(k) ((k)->length) +#define KRB5_KEY_DATA(k) ((k)->contents) +#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ + #ifndef HAVE_KRB5_SET_REAL_TIME /* * This function is not in the Heimdal mainline. @@ -124,7 +134,7 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, return krb5_get_default_in_tkt_etypes(context, enctypes); } #else - __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS +#error UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif void free_kerberos_etypes(krb5_context context, @@ -305,12 +315,12 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) DATA_BLOB ret; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_DES_CBC_CRC, - ENCTYPE_NULL}; - + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_NULL}; + retval = krb5_init_context(&context); if (retval) { DEBUG(1,("krb5_init_context failed (%s)\n", @@ -355,11 +365,39 @@ failed: return data_blob(NULL, 0); } +BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + { + krb5_keyblock *skey; + BOOL ret = False; + + memset(session_key, 0, 16); + +#ifdef ENCTYPE_ARCFOUR_HMAC + if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { + if (KRB5_KEY_TYPE(skey) == + ENCTYPE_ARCFOUR_HMAC + && KRB5_KEY_LENGTH(skey) == 16) { + memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + ret = True; + } + krb5_free_keyblock(context, skey); + } +#endif /* ENCTYPE_ARCFOUR_HMAC */ + + return ret; + } #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); } + +BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context ac, uint8 session_key[16]) + { + DEBUG(0,("NO KERBEROS SUPPORT\n")); + memset(session_key, 0, 16); + return False; + } #endif diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e93f1855dd..dfa8f80146 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -3,6 +3,7 @@ simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 Copyright (C) Jim McDonough 2002 + Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -259,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; @@ -268,7 +269,8 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) asn1_push_tag(&data, ASN1_APPLICATION(0)); asn1_write_OID(&data, OID_KERBEROS5); - asn1_write_BOOLEAN(&data, 0); + + asn1_write(&data, tok_id, 2); asn1_write(&data, ticket.data, ticket.length); asn1_pop_tag(&data); @@ -286,7 +288,7 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) { BOOL ret; ASN1_DATA data; @@ -295,15 +297,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) asn1_load(&data, blob); asn1_start_tag(&data, ASN1_APPLICATION(0)); asn1_check_OID(&data, OID_KERBEROS5); - asn1_check_BOOLEAN(&data, 0); data_remaining = asn1_tag_remaining(&data); - if (data_remaining < 1) { + if (data_remaining < 3) { data.has_error = True; } else { - - *ticket = data_blob(data.data, data_remaining); + asn1_read(&data, tok_id, 2); + data_remaining -= 2; + *ticket = data_blob(NULL, data_remaining); asn1_read(&data, ticket->data, ticket->length); } @@ -330,7 +332,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt); + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); @@ -438,9 +440,10 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) } /* - generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. + generate a minimal SPNEGO response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, + const char *mechOID) { ASN1_DATA data; DATA_BLOB ret; @@ -462,13 +465,13 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + if (reply->data != NULL) { asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); + asn1_write_OID(&data, mechOID); asn1_pop_tag(&data); asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); + asn1_write_OctetString(&data, reply->data, reply->length); asn1_pop_tag(&data); } -- cgit From 79aaa35ea5e8c74ff7755ec650aca88cc7e4cf7e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 21:07:03 +0000 Subject: Clean up non-krb5 breakages from my modifications to luke howard's patch. Andrew Bartlett (This used to be commit 32fd0c49009e38022523cc5c14567dd55de08206) --- source3/libsmb/clikrb5.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 47dec1f171..6b0c7ddaf2 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -365,7 +365,7 @@ failed: return data_blob(NULL, 0); } -BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) { krb5_keyblock *skey; BOOL ret = False; @@ -394,10 +394,4 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) return data_blob(NULL, 0); } -BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context ac, uint8 session_key[16]) - { - DEBUG(0,("NO KERBEROS SUPPORT\n")); - memset(session_key, 0, 16); - return False; - } #endif -- cgit From 7d581bebd437cd66000a1cac4b74b1ec4408f672 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 25 Feb 2003 23:30:46 +0000 Subject: Fix unused variable warning when ENCTYPE_ARCFOUR_HMAC is not defined. (This used to be commit 92abafa62894a125c5a09fc92f5056e4d8b51089) --- source3/libsmb/clikrb5.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 6b0c7ddaf2..5edc56daa9 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -367,7 +367,9 @@ failed: BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) { +#ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; +#endif BOOL ret = False; memset(session_key, 0, 16); -- cgit From ca80787248bfe7fe8dff12486ba32520f6910341 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 26 Feb 2003 12:23:03 +0000 Subject: Netlogon-unigroup changes needed for the winbind RID-to-SID conversion. This changes the cache format, which will simply invalidate existing entries, leaving them dead in the cache. Andrew Bartlett (This used to be commit 3fc179362ea849db23490b971a9f64f943e7f7f8) --- source3/libsmb/netlogon_unigrp.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index fa2fe32f35..466410d800 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#define UNIGROUP_PREFIX "UNIGROUP" /* Handle for netlogon_unigrp.tdb database. It is used internally @@ -50,17 +51,22 @@ BOOL uni_group_cache_init(void) BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) { TDB_DATA key,data; - fstring keystr; - int i; + fstring keystr, sid_string; + DOM_SID user_sid; + unsigned int i; if (!uni_group_cache_init()) { DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n")); return False; } - /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s/%d", - sid_string_static(&user->dom_sid.sid), user->user_rid); + sid_copy(&user_sid, &user->dom_sid.sid); + sid_append_rid(&user_sid, user->user_rid); + + /* Prepare key as USER-SID string */ + slprintf(keystr, sizeof(keystr), "%s/%s", + UNIGROUP_PREFIX, + sid_to_string(sid_string, &user_sid)); key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -90,14 +96,15 @@ BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) and elements are array[0] ... array[num_elements-1] */ -uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, +DOM_SID **uni_group_cache_fetch(DOM_SID *domain, DOM_SID *user_sid, TALLOC_CTX *mem_ctx, uint32 *num_groups) { TDB_DATA key,data; fstring keystr; - uint32 *groups; + DOM_SID **groups; uint32 i; uint32 group_count; + fstring sid_string; if (!domain) { DEBUG(1,("uni_group_cache_fetch: expected non-null domain sid\n")); @@ -123,8 +130,9 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, *num_groups = 0; /* Fetch universal groups */ - slprintf(keystr, sizeof(keystr), "%s/%d", - sid_string_static(domain), user_rid); + slprintf(keystr, sizeof(keystr), "%s/%s", + UNIGROUP_PREFIX, + sid_to_string(sid_string, user_sid)); key.dptr = keystr; key.dsize = strlen(keystr) + 1; data = tdb_fetch(netlogon_unigrp_tdb, key); @@ -136,12 +144,17 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, /* Transfer data to receiver's memory context */ group_count = IVAL(&((uint32*)data.dptr)[0],0); - groups = talloc(mem_ctx, (group_count)*sizeof(uint32)); + groups = talloc(mem_ctx, (group_count)*sizeof(*groups)); if (groups) { for(i=0; i Date: Sat, 1 Mar 2003 01:07:18 +0000 Subject: the new DEVELOPER checks for string overflows have (as expected) broken a lot of stuff. These two macros are meant to make life easier when fixing these bugs. I'm guessing we will see more macros like this (eg. fstrcpy_base) (This used to be commit 50389c0cb2504d7941ec691af21d6a20ae5c5de7) --- source3/libsmb/clirap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index f8f840abaa..24108d40f3 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -221,10 +221,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - pstrcpy(p,"WrLehDz"); + pstrcpy_base(p,"WrLehDz", param); p = skip_string(p,1); - pstrcpy(p,"B16BBDz"); + pstrcpy_base(p,"B16BBDz", param); p = skip_string(p,1); SSVAL(p,0,uLevel); @@ -233,7 +233,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - p += push_pstring(p, workgroup); + p += push_pstring_base(p, workgroup, param); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ -- cgit From aa543f1345a2a10b65d6f3162f7db81b96db3d6a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Mar 2003 08:35:49 +0000 Subject: Add const (This used to be commit 251b91f46988053eccc53f814a23ed5ca787c852) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index dfa8f80146..53f7eb6e7d 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -260,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, uint8 tok_id[2]) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; -- cgit From 3042cfb7fabe25cc06e5cf6c49c2716c1112b6d2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 3 Mar 2003 17:43:33 +0000 Subject: Do my janitorial duties to encourage others to do so. Fix lingering large offset problems in smbtar etc. (This used to be commit c416eec2f2a38eebfcda5868999d474628037f1e) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 07b1ff6b6f..31d7ea5911 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -805,7 +805,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, + uint16 *attr, SMB_BIG_UINT *size, time_t *c_time, time_t *a_time, time_t *m_time) { memset(cli->outbuf,'\0',smb_size); -- cgit From e3fdd289f58505f258f9617e1b8618694703bea2 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 3 Mar 2003 23:00:22 +0000 Subject: More janitorial duties, fixing the BIG_UINT changes for large offsets. (This used to be commit 1af39523cc3b2313f3e8acd4f2e5338182ec0b13) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 07b1ff6b6f..31d7ea5911 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -805,7 +805,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, size_t *size, + uint16 *attr, SMB_BIG_UINT *size, time_t *c_time, time_t *a_time, time_t *m_time) { memset(cli->outbuf,'\0',smb_size); -- cgit From fe45e6d79a61df5f25e461603ff93c563da186b7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 00:54:07 +0000 Subject: Connectathon fix. W2K -> W2K over port 445 doing a tconX does the full \\server\share syntax, not just a "share" tconX syntax. This broke interop with a vendor. Jeremy. (This used to be commit 9d7ea5585c873156ede4b56e43a0d4d75077283a) --- source3/libsmb/cliconnect.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4962ffa3c9..49b0004ac2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -780,13 +780,8 @@ BOOL cli_send_tconX(struct cli_state *cli, } } - if (cli->port == 445) { - slprintf(fullshare, sizeof(fullshare)-1, - "%s", share); - } else { - slprintf(fullshare, sizeof(fullshare)-1, - "\\\\%s\\%s", cli->desthost, share); - } + slprintf(fullshare, sizeof(fullshare)-1, + "\\\\%s\\%s", cli->desthost, share); set_message(cli->outbuf,4, 0, True); SCVAL(cli->outbuf,smb_com,SMBtconX); -- cgit From 6f4aee34d9ba6c1e397192941e2c08cff2737455 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 00:54:16 +0000 Subject: Connectathon fix. W2K -> W2K over port 445 doing a tconX does the full \\server\share syntax, not just a "share" tconX syntax. This broke interop with a vendor. Jeremy. (This used to be commit 3cc2ace7718ac1162494b81fa21d4cc9de021d1c) --- source3/libsmb/cliconnect.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4962ffa3c9..49b0004ac2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -780,13 +780,8 @@ BOOL cli_send_tconX(struct cli_state *cli, } } - if (cli->port == 445) { - slprintf(fullshare, sizeof(fullshare)-1, - "%s", share); - } else { - slprintf(fullshare, sizeof(fullshare)-1, - "\\\\%s\\%s", cli->desthost, share); - } + slprintf(fullshare, sizeof(fullshare)-1, + "\\\\%s\\%s", cli->desthost, share); set_message(cli->outbuf,4, 0, True); SCVAL(cli->outbuf,smb_com,SMBtconX); -- cgit From d45fe965efbac17433b0de25f5a896803f59f388 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 01:30:15 +0000 Subject: Writable string const fixes. Jeremy. (This used to be commit c832e95c2f4daf175954a60f3c56420cf2f35b45) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 62b94761ad..18ce5e4bd9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1263,7 +1263,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * /* If it's our domain then use the 'password server' parameter. */ if (strequal(domain, lp_workgroup())) { - char *p; + const char *p; char *pserver = lp_passwordserver(); /* UNIX charset. */ fstring name; int num_addresses = 0; -- cgit From 1cdafbf17ebbcb1840cdb1bde3b49600406ed904 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Mar 2003 01:30:26 +0000 Subject: Writable string const fixes. Jeremy. (This used to be commit 60b0cfc8a5b6275d3460ebc6bf17d0f08e25b67e) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 62b94761ad..18ce5e4bd9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1263,7 +1263,7 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * /* If it's our domain then use the 'password server' parameter. */ if (strequal(domain, lp_workgroup())) { - char *p; + const char *p; char *pserver = lp_passwordserver(); /* UNIX charset. */ fstring name; int num_addresses = 0; -- cgit From bbf8961b284a877b5cfa4101e0fd677664a867f1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 8 Mar 2003 05:18:08 +0000 Subject: Make it clear that this is a fstrcpy(). (This used to be commit c2a266b7b661d319e13982bfdbc3a86e8502b8a4) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9598f4ac96..6ef7a7bd9c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -200,8 +200,8 @@ void cli_setup_bcc(struct cli_state *cli, void *p) void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ - safe_strcpy(cli->domain , usr->domain , sizeof(usr->domain )-1); - safe_strcpy(cli->user_name, usr->user_name, sizeof(usr->user_name)-1); + fstrcpy(cli->domain , usr->domain); + fstrcpy(cli->user_name, usr->user_name); memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); cli->ntlmssp_flags = usr->ntlmssp_flags; cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; -- cgit From 2ed7730f2d498a446dc7281e652d02a9dd2d94cf Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Mar 2003 09:23:09 +0000 Subject: Change the way we sign SMB packets, to a function pointer interface. The intention is to allow for NTLMSSP and kerberos signing of packets, but for now it's just what I call 'simple' signing. (aka SMB signing per the SNIA spec) Andrew Bartlett (This used to be commit b9cf95c3dc04a45de71fb16e85c1bfbae50e6d8f) --- source3/libsmb/cliconnect.c | 47 +------ source3/libsmb/clientgen.c | 8 +- source3/libsmb/smb_signing.c | 329 +++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smbencrypt.c | 100 +------------ 4 files changed, 338 insertions(+), 146 deletions(-) create mode 100644 source3/libsmb/smb_signing.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 49b0004ac2..589c7b36bb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -228,39 +228,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_signing_on_cli (struct cli_state *cli, uint8 user_session_key[16], DATA_BLOB response) -{ - uint8 zero_sig[8]; - ZERO_STRUCT(zero_sig); - - DEBUG(5, ("Server returned security sig:\n")); - dump_data(5, &cli->inbuf[smb_ss_field], 8); - - if (cli->sign_info.use_smb_signing) { - DEBUG(5, ("smb signing already active on connection\n")); - } else if (memcmp(&cli->inbuf[smb_ss_field], zero_sig, 8) != 0) { - - DEBUG(3, ("smb signing enabled!\n")); - cli->sign_info.use_smb_signing = True; - cli_calculate_mac_key(cli, user_session_key, response); - } else { - DEBUG(5, ("smb signing NOT enabled!\n")); - } -} - static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) { memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); } - -static void set_temp_signing_on_cli(struct cli_state *cli) -{ - if (cli->sign_info.negotiated_smb_signing) - cli->sign_info.temp_smb_signing = True; -} - - /**************************************************************************** do a NT1 NTLM/LM encrypted session setup @param cli client state to create do session setup on @@ -310,8 +282,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - - set_temp_signing_on_cli(cli); + cli_simple_set_signing(cli, session_key.data, nt_response); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -374,14 +345,14 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (session_key.data) { /* Have plaintext orginal */ set_cli_session_key(cli, session_key); - set_signing_on_cli(cli, session_key.data, nt_response); } + ret = True; end: data_blob_free(&lm_response); data_blob_free(&nt_response); data_blob_free(&session_key); - return True; + return ret; } /**************************************************************************** @@ -403,8 +374,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); - set_temp_signing_on_cli(cli); - cli_setup_packet(cli); SCVAL(cli->outbuf,smb_vwv0,0xFF); @@ -883,11 +852,6 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send negprot again, particularly after setting up SMB Signing\n")); - return False; - } - if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; @@ -1013,11 +977,6 @@ BOOL cli_session_request(struct cli_state *cli, if (cli->port == 445) return True; - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); - return False; - } - /* send a session request (RFC 1002) */ /* setup the packet length * Remove four bytes from the length count, since the length diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6ef7a7bd9c..3cae643c38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -177,9 +177,6 @@ void cli_setup_packet(struct cli_state *cli) flags2 |= FLAGS2_32_BIT_ERROR_CODES; if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - if (cli->sign_info.use_smb_signing - || cli->sign_info.temp_smb_signing) - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -262,6 +259,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; + /* initialise signing */ + cli_null_set_signing(cli); + if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; @@ -303,6 +303,7 @@ void cli_close_connection(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); + cli_free_signing_context(cli); data_blob_free(&cli->secblob); if (cli->mem_ctx) { @@ -314,6 +315,7 @@ void cli_close_connection(struct cli_state *cli) close(cli->fd); cli->fd = -1; cli->smb_rw_error = 0; + } /**************************************************************************** diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c new file mode 100644 index 0000000000..b3a6351893 --- /dev/null +++ b/source3/libsmb/smb_signing.c @@ -0,0 +1,329 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2002. + Copyright (C) Andrew Bartlett 2002-2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +struct smb_basic_signing_context { + DATA_BLOB mac_key; + uint32 send_seq_num; + uint32 reply_seq_num; +}; + +/*********************************************************** + SMB signing - Common code before we set a new signing implementation +************************************************************/ + +static BOOL set_smb_signing_common(struct cli_state *cli) +{ + if (cli->sign_info.doing_signing) { + return False; + } + + if (cli->sign_info.free_signing_context) + cli->sign_info.free_signing_context(cli); + + /* These calls are INCONPATIBLE with SMB signing */ + cli->readbraw_supported = False; + cli->writebraw_supported = False; + + return True; +} + +/*********************************************************** + SMB signing - Common code for 'real' implementations +************************************************************/ + +static BOOL set_smb_signing_real_common(struct cli_state *cli) +{ + if (cli->sign_info.mandetory_signing) { + DEBUG(5, ("Mandetory SMB signing enabled!\n")); + cli->sign_info.doing_signing = True; + } + + DEBUG(5, ("SMB signing enabled!\n")); + + return True; +} + +static void mark_packet_signed(struct cli_state *cli) +{ + uint16 flags2; + flags2 = SVAL(cli->outbuf,smb_flg2); + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + SSVAL(cli->outbuf,smb_flg2, flags2); +} + +/*********************************************************** + SMB signing - Simple implementation - calculate a MAC to send. +************************************************************/ + +static void cli_simple_sign_outgoing_message(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + struct MD5Context md5_ctx; + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + SIVAL(cli->outbuf, smb_ss_field, + data->send_seq_num); + SIVAL(cli->outbuf, smb_ss_field + 4, 0); + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, data->mac_key.data, + data->mac_key.length); + MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + DEBUG(10, ("sent SMB signiture of\n")); + dump_data(10, calc_md5_mac, 8); + + memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signitures...*/ + data->send_seq_num++; + data->reply_seq_num = data->send_seq_num; + data->send_seq_num++; +} + +/*********************************************************** + SMB signing - Simple implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_simple_check_incoming_message(struct cli_state *cli) +{ + BOOL good; + unsigned char calc_md5_mac[16]; + unsigned char server_sent_mac[8]; + struct MD5Context md5_ctx; + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + /* + * Firstly put the sequence number into the first 4 bytes. + * and zero out the next 4 bytes. + */ + + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + + DEBUG(10, ("got SMB signiture of\n")); + dump_data(10, server_sent_mac, 8); + + SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); + SIVAL(cli->inbuf, smb_ss_field + 4, 0); + + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + MD5Init(&md5_ctx); + MD5Update(&md5_ctx, data->mac_key.data, + data->mac_key.length); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Final(calc_md5_mac, &md5_ctx); + + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + + if (good && !cli->sign_info.doing_signing) { + cli->sign_info.doing_signing = True; + } + + if (!good) { + DEBUG(1, ("SMB signiture check failed!\n")); + } + + return good; +} + +/*********************************************************** + SMB signing - Simple implementation - free signing context +************************************************************/ + +static void cli_simple_free_signing_context(struct cli_state *cli) +{ + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + data_blob_free(&data->mac_key); + SAFE_FREE(cli->sign_info.signing_context); + + return; +} + +/*********************************************************** + SMB signing - Simple implementation - setup the MAC key. +************************************************************/ + +void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!set_smb_signing_common(cli)) { + return; + } + + if (!set_smb_signing_real_common(cli)) { + return; + } + + data = smb_xmalloc(sizeof(*data)); + cli->sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, MIN(response.length + 16, 40)); + + memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); + + /* Initialise the sequence number */ + data->send_seq_num = 0; + + cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; + cli->sign_info.free_signing_context = cli_simple_free_signing_context; +} + +/*********************************************************** + SMB signing - NULL implementation - calculate a MAC to send. +************************************************************/ + +static void cli_null_sign_outgoing_message(struct cli_state *cli) +{ + static uchar zeros[8]; + memcpy(&cli->outbuf[smb_ss_field], zeros, sizeof(zeros)); +} + +/*********************************************************** + SMB signing - NULL implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_null_check_incoming_message(struct cli_state *cli) +{ + return True; +} + +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ + +static void cli_null_free_signing_context(struct cli_state *cli) +{ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - setup the MAC key. +************************************************************/ + +void cli_null_set_signing(struct cli_state *cli) +{ + struct smb_basic_sign_data *data; + + if (!set_smb_signing_common(cli)) { + return; + } + + cli->sign_info.signing_context = NULL; + + cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_null_check_incoming_message; + cli->sign_info.free_signing_context = cli_null_free_signing_context; +} + +/*********************************************************** + SMB signing - TEMP implementation - calculate a MAC to send. +************************************************************/ + +static void cli_temp_sign_outgoing_message(struct cli_state *cli) +{ + memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + return; +} + +/*********************************************************** + SMB signing - TEMP implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_temp_check_incoming_message(struct cli_state *cli) +{ + return True; +} + +/*********************************************************** + SMB signing - TEMP implementation - free signing context +************************************************************/ + +static void cli_temp_free_signing_context(struct cli_state *cli) +{ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - setup the MAC key. +************************************************************/ + +void cli_temp_set_signing(struct cli_state *cli) +{ + if (!set_smb_signing_common(cli)) { + return; + } + + cli->sign_info.signing_context = NULL; + + cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; + cli->sign_info.free_signing_context = cli_temp_free_signing_context; +} + +/** + * Free the singing context + */ + +void cli_free_signing_context(struct cli_state *cli) +{ + if (cli->sign_info.free_signing_context) + cli->sign_info.free_signing_context(cli); + + cli_null_set_signing(cli); +} + +void cli_caclulate_sign_mac(struct cli_state *cli) +{ + cli->sign_info.sign_outgoing_message(cli); +} + +BOOL cli_check_sign_mac(struct cli_state *cli) +{ + BOOL good; + good = cli->sign_info.check_incoming_message(cli); + + if (!good) { + if (cli->sign_info.doing_signing) { + return False; + } else { + cli_free_signing_context(cli); + } + } + + return True; +} + diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index aa9391325f..28160d9609 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -295,7 +295,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], +static DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], DATA_BLOB server_chal, size_t client_chal_length) { uchar ntlmv2_response[16]; @@ -416,101 +416,3 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } - -/*********************************************************** - SMB signing - setup the MAC key. -************************************************************/ - -void cli_calculate_mac_key(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) -{ - - memcpy(&cli->sign_info.mac_key[0], user_session_key, 16); - memcpy(&cli->sign_info.mac_key[16],response.data, MIN(response.length, 40 - 16)); - cli->sign_info.mac_key_len = MIN(response.length + 16, 40); - cli->sign_info.use_smb_signing = True; - - /* These calls are INCONPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - - /* Reset the sequence number in case we had a previous (aborted) attempt */ - cli->sign_info.send_seq_num = 2; -} - -/*********************************************************** - SMB signing - calculate a MAC to send. -************************************************************/ - -void cli_caclulate_sign_mac(struct cli_state *cli) -{ - unsigned char calc_md5_mac[16]; - struct MD5Context md5_ctx; - - if (cli->sign_info.temp_smb_signing) { - memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); - cli->sign_info.temp_smb_signing = False; - return; - } - - if (!cli->sign_info.use_smb_signing) { - return; - } - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - */ - SIVAL(cli->outbuf, smb_ss_field, cli->sign_info.send_seq_num); - SIVAL(cli->outbuf, smb_ss_field + 4, 0); - - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ - MD5Init(&md5_ctx); - MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); - MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); - MD5Final(calc_md5_mac, &md5_ctx); - - memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signitures...*/ - cli->sign_info.send_seq_num++; - cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; - cli->sign_info.send_seq_num++; -} - -/*********************************************************** - SMB signing - check a MAC sent by server. -************************************************************/ - -BOOL cli_check_sign_mac(struct cli_state *cli) -{ - unsigned char calc_md5_mac[16]; - unsigned char server_sent_mac[8]; - struct MD5Context md5_ctx; - - if (cli->sign_info.temp_smb_signing) { - return True; - } - - if (!cli->sign_info.use_smb_signing) { - return True; - } - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - */ - - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - SIVAL(cli->inbuf, smb_ss_field, cli->sign_info.reply_seq_num); - SIVAL(cli->inbuf, smb_ss_field + 4, 0); - - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ - MD5Init(&md5_ctx); - MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); - MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); - MD5Final(calc_md5_mac, &md5_ctx); - - return (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); -} -- cgit From 2b6a6df0f65caccb31c78008539d24f8c4a2f72a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 9 Mar 2003 21:09:28 +0000 Subject: Try not to clobber the session request. (This used to be commit 05cffbee56f0556f550b4d14f3111bd7db972621) --- source3/libsmb/smb_signing.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index b3a6351893..581d18fef7 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -208,8 +208,10 @@ void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ static void cli_null_sign_outgoing_message(struct cli_state *cli) { - static uchar zeros[8]; - memcpy(&cli->outbuf[smb_ss_field], zeros, sizeof(zeros)); + /* we can't zero out the sig, as we might be trying to send a + session request - which is NBT-level, not SMB level and doesn't + have the feild */ + return; } /*********************************************************** @@ -295,7 +297,7 @@ void cli_temp_set_signing(struct cli_state *cli) } /** - * Free the singing context + * Free the singing context */ void cli_free_signing_context(struct cli_state *cli) @@ -306,11 +308,21 @@ void cli_free_signing_context(struct cli_state *cli) cli_null_set_signing(cli); } +/** + * Sign a packet with the current mechinism + */ + void cli_caclulate_sign_mac(struct cli_state *cli) { cli->sign_info.sign_outgoing_message(cli); } +/** + * Check a packet with the current mechinism + * @return False if we had an established signing connection + * which had a back checksum, True otherwise + */ + BOOL cli_check_sign_mac(struct cli_state *cli) { BOOL good; -- cgit From e9a94cd2c9cab4518603620259dae44b40d9049e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 10 Mar 2003 02:14:35 +0000 Subject: Further work on NTLMSSP-based SMB signing. Current status is that I cannnot get Win2k to send a valid signiture in it's session setup reply - which it will give to win2k clients. So, I need to look at becoming 'more like MS', but for now I'll get this code into the tree. It's actually based on the TNG cli_pipe_ntlmssp.c, as it was slightly easier to understand than our own (but only the utility functions remain in any way intact...). This includes the mysical 'NTLM2' code - I have no idea if it actually works. (I couldn't get TNG to use it for its pipes either). Andrew Bartlett (This used to be commit a034a5e381ba5612be21e2ba640d11f82cd945da) --- source3/libsmb/cliconnect.c | 47 ++++++++-- source3/libsmb/ntlmssp.c | 37 +++++--- source3/libsmb/ntlmssp_sign.c | 208 ++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smb_signing.c | 180 ++++++++++++++++++++++++++++++------ 4 files changed, 424 insertions(+), 48 deletions(-) create mode 100644 source3/libsmb/ntlmssp_sign.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 589c7b36bb..36b6f609f5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -356,15 +356,13 @@ end: } /**************************************************************************** - Send a extended security session setup blob, returning a reply blob. + Send a extended security session setup blob ****************************************************************************/ -static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; - DATA_BLOB blob2 = data_blob(NULL, 0); - uint32 len; capabilities |= CAP_EXTENDED_SECURITY; @@ -389,7 +387,18 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + return cli_send_smb(cli); +} + +/**************************************************************************** + Send a extended security session setup blob, returning a reply blob. +****************************************************************************/ + +static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) +{ + DATA_BLOB blob2 = data_blob(NULL, 0); + char *p; + size_t len; if (!cli_receive_smb(cli)) return blob2; @@ -418,6 +427,20 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return blob2; } +/**************************************************************************** + Send a extended security session setup blob, returning a reply blob. +****************************************************************************/ + +static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +{ + DATA_BLOB blob2 = data_blob(NULL, 0); + if (!cli_session_setup_blob_send(cli, blob)) { + return blob2; + } + + return cli_session_setup_blob_receive(cli); +} + #ifdef HAVE_KRB5 /**************************************************************************** Use in-memory credentials cache @@ -471,6 +494,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, DATA_BLOB blob_in = data_blob(NULL, 0); DATA_BLOB blob_out; + cli_temp_set_signing(cli); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return False; } @@ -501,8 +526,15 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } /* now send that blob on its way */ - blob = cli_session_setup_blob(cli, msg1); + if (!cli_session_setup_blob_send(cli, msg1)) { + return False; + } data_blob_free(&msg1); + + cli_ntlmssp_set_signing(cli, ntlmssp_state); + + blob = cli_session_setup_blob_receive(cli); + nt_status = cli_nt_error(cli); } @@ -539,6 +571,9 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, set_cli_session_key(cli, ntlmssp_state->session_key); } + /* we have a reference conter on ntlmssp_state, if we are signing + then the state will be kept by the signing engine */ + if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { return False; } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e1509f6b63..5722b8efcd 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -81,7 +81,7 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) /** * Determine correct target name flags for reply, given server role - * and negoitated falgs + * and negotiated flags * * @param ntlmssp_state NTLMSSP State * @param neg_flags The flags from the packet @@ -291,7 +291,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, /** * Create an NTLMSSP state machine * - * @param ntlmssp_state NTLMSSP State, allocated by this funciton + * @param ntlmssp_state NTLMSSP State, allocated by this function */ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) @@ -322,7 +322,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) /** * End an NTLMSSP state machine * - * @param ntlmssp_state NTLMSSP State, free()ed by this funciton + * @param ntlmssp_state NTLMSSP State, free()ed by this function */ NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) @@ -431,7 +431,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st DATA_BLOB session_key = data_blob(NULL, 0); uint8 datagram_sess_key[16]; - ZERO_STRUCT(datagram_sess_key); + generate_random_buffer(datagram_sess_key, sizeof(datagram_sess_key), False); if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -508,8 +508,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - - data_blob_free(&challenge_blob); /* this generates the actual auth packet */ if (!msrpc_gen(next_request, auth_gen_string, @@ -520,7 +518,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->get_global_myname(), - datagram_sess_key, 0, + datagram_sess_key, 16, ntlmssp_state->neg_flags)) { data_blob_free(&lm_response); @@ -529,9 +527,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_NO_MEMORY; } - data_blob_free(&lm_response); - data_blob_free(&nt_response); + data_blob_free(&ntlmssp_state->chal); + data_blob_free(&ntlmssp_state->lm_resp); + data_blob_free(&ntlmssp_state->nt_resp); + data_blob_free(&ntlmssp_state->session_key); + ntlmssp_state->chal = challenge_blob; + ntlmssp_state->lm_resp = lm_response; + ntlmssp_state->nt_resp = nt_response; ntlmssp_state->session_key = session_key; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -558,10 +561,12 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) (*ntlmssp_state)->unicode = True; (*ntlmssp_state)->neg_flags = - NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET; + (*ntlmssp_state)->ref_count = 1; + return NT_STATUS_OK; } @@ -569,8 +574,16 @@ NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - data_blob_free(&(*ntlmssp_state)->session_key); - talloc_destroy(mem_ctx); + (*ntlmssp_state)->ref_count--; + + if ((*ntlmssp_state)->ref_count == 0) { + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + data_blob_free(&(*ntlmssp_state)->session_key); + talloc_destroy(mem_ctx); + } + *ntlmssp_state = NULL; return NT_STATUS_OK; } diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c new file mode 100644 index 0000000000..f51d532319 --- /dev/null +++ b/source3/libsmb/ntlmssp_sign.c @@ -0,0 +1,208 @@ +/* + * Unix SMB/CIFS implementation. + * Version 3.0 + * NTLMSSP Signing routines + * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 + * Copyright (C) Andrew Bartlett 2003 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include "includes.h" + +#define CLI_SIGN "session key to client-to-server signing key magic constant" +#define CLI_SEAL "session key to client-to-server sealing key magic constant" +#define SRV_SIGN "session key to server-to-client signing key magic constant" +#define SRV_SEAL "session key to server-to-client sealing key magic constant" + +static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) +{ + unsigned char index_i = hash[256]; + unsigned char index_j = hash[257]; + int ind; + + for (ind = 0; ind < len; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += hash[index_i]; + + tc = hash[index_i]; + hash[index_i] = hash[index_j]; + hash[index_j] = tc; + + t = hash[index_i] + hash[index_j]; + data[ind] = data[ind] ^ hash[t]; + } + + hash[256] = index_i; + hash[257] = index_j; +} + +static void calc_hash(unsigned char *hash, const char *k2, int k2l) +{ + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + hash[ind] = (unsigned char)ind; + } + + for (ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (hash[ind] + k2[ind%k2l]); + + tc = hash[ind]; + hash[ind] = hash[j]; + hash[j] = tc; + } + + hash[256] = 0; + hash[257] = 0; +} + +static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], + const char encrypted_response[16], + const char *constant) +{ + struct MD5Context ctx3; + + MD5Init(&ctx3); + MD5Update(&ctx3, encrypted_response, 5); + MD5Update(&ctx3, constant, strlen(constant)); + MD5Final(digest, &ctx3); + + calc_hash(hash, digest, 16); +} + +static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + DATA_BLOB *sig) +{ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + HMACMD5Context ctx; + char seq_num[4]; + uchar digest[16]; + SIVAL(seq_num, 0, &ntlmssp_state->ntlmssp_seq_num); + + hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); + hmac_md5_update(seq_num, 4, &ctx); + hmac_md5_update(data, length, &ctx); + hmac_md5_final(digest, &ctx); + + if (!msrpc_gen(sig, "Bd", digest, sizeof(digest), ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, sig->data, sig->length); + } else { + uint32 crc; + crc = crc32_calc_buffer(data, length); + if (!msrpc_gen(sig, "ddd", 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data, sig->length); + } + return NT_STATUS_OK; +} + +NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + DATA_BLOB *sig) +{ + ntlmssp_state->ntlmssp_seq_num++; + return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, sig); +} + +/** + * Check the signature of an incoming packet + * @note caller *must* check that the signature is the size it expects + * + */ + +NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, + const uchar *data, size_t length, + const DATA_BLOB *sig) +{ + DATA_BLOB local_sig; + NTSTATUS nt_status; + + if (sig->length < 8) { + DEBUG(0, ("NTLMSSP packet check failed due to short signiture (%u bytes)!\n", + sig->length)); + } + + nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, + length, &local_sig); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); + return nt_status; + } + + if (memcmp(sig->data, local_sig.data, MIN(sig->length, local_sig.length)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); + return NT_STATUS_ACCESS_DENIED; + } +} + +/** + Initialise the state for NTLMSSP signing. +*/ +NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) +{ + unsigned char p24[24]; + unsigned char lm_hash[16]; + + if (!ntlmssp_state->lm_resp.data) { + /* can't sign or check signitures yet */ + return NT_STATUS_UNSUCCESSFUL; + } + + E_deshash(ntlmssp_state->password, lm_hash); + + NTLMSSPOWFencrypt(lm_hash, ntlmssp_state->lm_resp.data, p24); + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + { + calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, ntlmssp_state->cli_sign_const, p24, CLI_SIGN); + calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, ntlmssp_state->cli_seal_const, p24, CLI_SEAL); + calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, ntlmssp_state->srv_sign_const, p24, SRV_SIGN); + calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, ntlmssp_state->srv_seal_const, p24, SRV_SEAL); + } + else + { + char k2[8]; + memcpy(k2, p24, 5); + k2[5] = 0xe5; + k2[6] = 0x38; + k2[7] = 0xb0; + + calc_hash(ntlmssp_state->ntlmssp_hash, k2, 8); + } + + ntlmssp_state->ntlmssp_seq_num = 0; + + ZERO_STRUCT(lm_hash); + return NT_STATUS_OK; +} diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 581d18fef7..40359c5c8c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -33,6 +33,11 @@ struct smb_basic_signing_context { static BOOL set_smb_signing_common(struct cli_state *cli) { + if (!cli->sign_info.negotiated_smb_signing + && !cli->sign_info.mandetory_signing) { + return False; + } + if (cli->sign_info.doing_signing) { return False; } @@ -40,7 +45,7 @@ static BOOL set_smb_signing_common(struct cli_state *cli) if (cli->sign_info.free_signing_context) cli->sign_info.free_signing_context(cli); - /* These calls are INCONPATIBLE with SMB signing */ + /* These calls are INCOMPATIBLE with SMB signing */ cli->readbraw_supported = False; cli->writebraw_supported = False; @@ -54,7 +59,7 @@ static BOOL set_smb_signing_common(struct cli_state *cli) static BOOL set_smb_signing_real_common(struct cli_state *cli) { if (cli->sign_info.mandetory_signing) { - DEBUG(5, ("Mandetory SMB signing enabled!\n")); + DEBUG(5, ("Mandatory SMB signing enabled!\n")); cli->sign_info.doing_signing = True; } @@ -71,6 +76,28 @@ static void mark_packet_signed(struct cli_state *cli) SSVAL(cli->outbuf,smb_flg2, flags2); } +static BOOL signing_good(struct cli_state *cli, BOOL good) +{ + DEBUG(10, ("got SMB signature of\n")); + dump_data(10,&cli->outbuf[smb_ss_field] , 8); + + if (good && !cli->sign_info.doing_signing) { + cli->sign_info.doing_signing = True; + } + + if (!good) { + if (cli->sign_info.doing_signing) { + DEBUG(1, ("SMB signature check failed!\n")); + return False; + } else { + DEBUG(3, ("Server did not sign reply correctly\n")); + cli_free_signing_context(cli); + return False; + } + } + return True; +} + /*********************************************************** SMB signing - Simple implementation - calculate a MAC to send. ************************************************************/ @@ -99,7 +126,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); MD5Final(calc_md5_mac, &md5_ctx); - DEBUG(10, ("sent SMB signiture of\n")); + DEBUG(10, ("sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); @@ -130,7 +157,7 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - DEBUG(10, ("got SMB signiture of\n")); + DEBUG(10, ("got SMB signature of\n")); dump_data(10, server_sent_mac, 8); SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); @@ -145,15 +172,7 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - if (good && !cli->sign_info.doing_signing) { - cli->sign_info.doing_signing = True; - } - - if (!good) { - DEBUG(1, ("SMB signiture check failed!\n")); - } - - return good; + return signing_good(cli, good); } /*********************************************************** @@ -174,16 +193,16 @@ static void cli_simple_free_signing_context(struct cli_state *cli) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) { struct smb_basic_signing_context *data; if (!set_smb_signing_common(cli)) { - return; + return False; } if (!set_smb_signing_real_common(cli)) { - return; + return False; } data = smb_xmalloc(sizeof(*data)); @@ -194,12 +213,105 @@ void cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); - /* Initialise the sequence number */ + /* Initialize the sequence number */ data->send_seq_num = 0; cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; cli->sign_info.free_signing_context = cli_simple_free_signing_context; + + return True; +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - calculate a MAC to send. +************************************************************/ + +static void cli_ntlmssp_sign_outgoing_message(struct cli_state *cli) +{ + NTSTATUS nt_status; + DATA_BLOB sig; + NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + nt_status = ntlmssp_client_sign_packet(ntlmssp_state, cli->outbuf + 4, + smb_len(cli->outbuf), &sig); + + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(0, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); + return; + } + + DEBUG(10, ("sent SMB signature of\n")); + dump_data(10, sig.data, MIN(sig.length, 8)); + memcpy(&cli->outbuf[smb_ss_field], sig.data, MIN(sig.length, 8)); + + data_blob_free(&sig); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - check a MAC sent by server. +************************************************************/ + +static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli) +{ + BOOL good; + NTSTATUS nt_status; + DATA_BLOB sig = data_blob(&cli->outbuf[smb_ss_field], 8); + + NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; + + nt_status = ntlmssp_client_check_packet(ntlmssp_state, cli->outbuf + 4, + smb_len(cli->outbuf), &sig); + + data_blob_free(&sig); + + good = NT_STATUS_IS_OK(nt_status); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(5, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); + } + + return signing_good(cli, good); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - free signing context +************************************************************/ + +static void cli_ntlmssp_free_signing_context(struct cli_state *cli) +{ + ntlmssp_client_end((NTLMSSP_CLIENT_STATE **)&cli->sign_info.signing_context); +} + +/*********************************************************** + SMB signing - NTLMSSP implementation - setup the MAC key. +************************************************************/ + +BOOL cli_ntlmssp_set_signing(struct cli_state *cli, + NTLMSSP_CLIENT_STATE *ntlmssp_state) +{ + if (!set_smb_signing_common(cli)) { + return False; + } + + if (!NT_STATUS_IS_OK(ntlmssp_client_sign_init(ntlmssp_state))) { + return False; + } + + if (!set_smb_signing_real_common(cli)) { + return False; + } + + cli->sign_info.signing_context = ntlmssp_state; + ntlmssp_state->ref_count++; + + cli->sign_info.sign_outgoing_message = cli_ntlmssp_sign_outgoing_message; + cli->sign_info.check_incoming_message = cli_ntlmssp_check_incoming_message; + cli->sign_info.free_signing_context = cli_ntlmssp_free_signing_context; + + return True; } /*********************************************************** @@ -210,7 +322,7 @@ static void cli_null_sign_outgoing_message(struct cli_state *cli) { /* we can't zero out the sig, as we might be trying to send a session request - which is NBT-level, not SMB level and doesn't - have the feild */ + have the field */ return; } @@ -232,23 +344,24 @@ static void cli_null_free_signing_context(struct cli_state *cli) return; } -/*********************************************************** +/** SMB signing - NULL implementation - setup the MAC key. -************************************************************/ -void cli_null_set_signing(struct cli_state *cli) + @note Used as an initialisation only - it will not correctly + shut down a real signing mechinism +*/ + +BOOL cli_null_set_signing(struct cli_state *cli) { struct smb_basic_sign_data *data; - if (!set_smb_signing_common(cli)) { - return; - } - cli->sign_info.signing_context = NULL; cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_null_check_incoming_message; cli->sign_info.free_signing_context = cli_null_free_signing_context; + + return True; } /*********************************************************** @@ -257,7 +370,12 @@ void cli_null_set_signing(struct cli_state *cli) static void cli_temp_sign_outgoing_message(struct cli_state *cli) { - memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + /* I wonder what BSRSPYL stands for - but this is what MS + actually sends! */ + memcpy(&cli->outbuf[smb_ss_field], "BSRSPYL ", 8); return; } @@ -283,10 +401,10 @@ static void cli_temp_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. ************************************************************/ -void cli_temp_set_signing(struct cli_state *cli) +BOOL cli_temp_set_signing(struct cli_state *cli) { if (!set_smb_signing_common(cli)) { - return; + return False; } cli->sign_info.signing_context = NULL; @@ -294,6 +412,8 @@ void cli_temp_set_signing(struct cli_state *cli) cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; cli->sign_info.free_signing_context = cli_temp_free_signing_context; + + return True; } /** @@ -309,7 +429,7 @@ void cli_free_signing_context(struct cli_state *cli) } /** - * Sign a packet with the current mechinism + * Sign a packet with the current mechanism */ void cli_caclulate_sign_mac(struct cli_state *cli) @@ -318,7 +438,7 @@ void cli_caclulate_sign_mac(struct cli_state *cli) } /** - * Check a packet with the current mechinism + * Check a packet with the current mechanism * @return False if we had an established signing connection * which had a back checksum, True otherwise */ -- cgit From 8d563a985b1091b11554fb828700e57c18ac08fb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Mar 2003 16:54:57 +0000 Subject: strcpy_base from HEAD and trivial fix for smbclient -L Volker (This used to be commit 54c99ee1fbaf4541fb3fa10a9b764da1367af6d3) --- source3/libsmb/clirap.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index f8f840abaa..b6fbb3880a 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -85,19 +85,19 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) p = param; SSVAL(p,0,132); /* api number */ p += 2; - pstrcpy(p,"OOWb54WrLh"); + pstrcpy_base(p,"OOWb54WrLh",param); p = skip_string(p,1); - pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); + pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param); p = skip_string(p,1); SSVAL(p,0,1); p += 2; - pstrcpy(p,user); + pstrcpy_base(p,user,param); strupper(p); p += 21; p++; p += 15; p++; - pstrcpy(p, workstation); + pstrcpy_base(p, workstation, param); strupper(p); p += 16; SSVAL(p, 0, CLI_BUFFER_SIZE); @@ -145,9 +145,9 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co p = param; SSVAL(p,0,0); /* api number */ p += 2; - pstrcpy(p,"WrLeh"); + pstrcpy_base(p,"WrLeh",param); p = skip_string(p,1); - pstrcpy(p,"B13BWz"); + pstrcpy_base(p,"B13BWz",param); p = skip_string(p,1); SSVAL(p,0,1); /* @@ -221,10 +221,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - pstrcpy(p,"WrLehDz"); + pstrcpy_base(p,"WrLehDz",param); p = skip_string(p,1); - pstrcpy(p,"B16BBDz"); + pstrcpy_base(p,"B16BBDz",param); p = skip_string(p,1); SSVAL(p,0,uLevel); -- cgit From 06c4d9a8ff4373227ba6a418b8af627aaddbc4d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 10 Mar 2003 16:59:29 +0000 Subject: Some conversion to pstrcpy_base. Volker (This used to be commit 329911e43681b724cb0579aad77b4a658759d7ba) --- source3/libsmb/clirap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 24108d40f3..a1845b2e16 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -85,19 +85,19 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) p = param; SSVAL(p,0,132); /* api number */ p += 2; - pstrcpy(p,"OOWb54WrLh"); + pstrcpy_base(p,"OOWb54WrLh",param); p = skip_string(p,1); - pstrcpy(p,"WB21BWDWWDDDDDDDzzzD"); + pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param); p = skip_string(p,1); SSVAL(p,0,1); p += 2; - pstrcpy(p,user); + pstrcpy_base(p,user,param); strupper(p); p += 21; p++; p += 15; p++; - pstrcpy(p, workstation); + pstrcpy_base(p, workstation, param); strupper(p); p += 16; SSVAL(p, 0, CLI_BUFFER_SIZE); @@ -145,9 +145,9 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co p = param; SSVAL(p,0,0); /* api number */ p += 2; - pstrcpy(p,"WrLeh"); + pstrcpy_base(p,"WrLeh",param); p = skip_string(p,1); - pstrcpy(p,"B13BWz"); + pstrcpy_base(p,"B13BWz",param); p = skip_string(p,1); SSVAL(p,0,1); /* -- cgit From ddfed383a0791986c6d08fde67840e99424ebb1a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Mar 2003 22:24:12 +0000 Subject: Change size parameters from signed to unsigned to fix up warnings. Jeremy. (This used to be commit 2e9880ef7c259b67eb75edc8098b734c3b7b22c1) --- source3/libsmb/clifile.c | 12 +-- source3/libsmb/clilist.c | 2 +- source3/libsmb/clirap.c | 38 ++++---- source3/libsmb/clitrans.c | 233 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 190 insertions(+), 95 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 31d7ea5911..f61787abde 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -29,8 +29,8 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const char *fname_dst, BOOL hard_link) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; pstring data; @@ -123,8 +123,8 @@ BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; char data[100]; @@ -335,8 +335,8 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname) int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) { - int data_len = 1; - int param_len = 6; + unsigned int data_len = 1; + unsigned int param_len = 6; uint16 setup = TRANSACT2_SETFILEINFO; pstring param; unsigned char data; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 89ab5d6414..3884e4da82 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -154,7 +154,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - int param_len, data_len; + unsigned int param_len, data_len; uint16 setup; pstring param; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a1845b2e16..b38e7d5c23 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -41,8 +41,8 @@ BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, data, data_count, max_data_count); return (cli_receive_trans(cli, SMBtrans, - rparam, (int *)rparam_count, - rdata, (int *)rdata_count)); + rparam, (unsigned int *)rparam_count, + rdata, (unsigned int *)rdata_count)); } /**************************************************************************** @@ -51,8 +51,8 @@ call a remote api BOOL cli_api(struct cli_state *cli, char *param, int prcnt, int mprcnt, char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) + char **rparam, unsigned int *rprcnt, + char **rdata, unsigned int *rdrcnt) { cli_send_trans(cli,SMBtrans, PIPE_LANMAN, /* Name */ @@ -286,8 +286,8 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *p = param; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; - int data_len; - int param_len = 0; + unsigned int data_len; + unsigned int param_len = 0; char *rparam = NULL; char *rdata = NULL; int rprcnt, rdrcnt; @@ -368,9 +368,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint16 *mode) { - int data_len = 0; - int param_len = 0; - int rparam_len, rdata_len; + unsigned int data_len = 0; + unsigned int param_len = 0; + unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -449,8 +449,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *w_time, size_t *size, uint16 *mode, SMB_INO_T *ino) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -518,8 +518,8 @@ send a qfileinfo QUERY_FILE_NAME_INFO call BOOL cli_qfilename(struct cli_state *cli, int fnum, pstring name) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -563,8 +563,8 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -631,8 +631,8 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -677,8 +677,8 @@ send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call ****************************************************************************/ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3d862a1796..7e3357a8cc 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -24,18 +24,19 @@ /**************************************************************************** - send a SMB trans or trans2 request - ****************************************************************************/ + Send a SMB trans or trans2 request. +****************************************************************************/ + BOOL cli_send_trans(struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) + uint16 *setup, unsigned int lsetup, unsigned int msetup, + char *param, unsigned int lparam, unsigned int mparam, + char *data, unsigned int ldata, unsigned int mdata) { int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; + unsigned int this_ldata,this_lparam; + unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; char *p; int pipe_name_len=0; @@ -83,14 +84,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || - cli_is_error(cli)) { + if (!cli_receive_smb(cli) || cli_is_error(cli)) return(False); - } tot_data = this_ldata; tot_param = this_lparam; @@ -123,7 +123,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; tot_data += this_ldata; tot_param += this_lparam; @@ -133,17 +134,17 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, return(True); } - /**************************************************************************** - receive a SMB trans or trans2 response allocating the necessary memory - ****************************************************************************/ + Receive a SMB trans or trans2 response allocating the necessary memory. +****************************************************************************/ + BOOL cli_receive_trans(struct cli_state *cli,int trans, - char **param, int *param_len, - char **data, int *data_len) + char **param, unsigned int *param_len, + char **data, unsigned int *data_len) { - int total_data=0; - int total_param=0; - int this_data,this_param; + unsigned int total_data=0; + unsigned int total_param=0; + unsigned int this_data,this_param; NTSTATUS status; char *tdata; char *tparam; @@ -170,9 +171,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status)) { + if (NT_STATUS_IS_ERR(status)) return False; - } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -199,7 +199,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *param = tparam; } - while (1) { + for (;;) { this_data = SVAL(cli->inbuf,smb_drcnt); this_param = SVAL(cli->inbuf,smb_prcnt); @@ -209,21 +209,59 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, return False; } - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_drdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_prdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), - this_param); + if (this_data + *data_len < this_data || + this_data + *data_len < *data_len || + this_param + *param_len < this_param || + this_param + *param_len < *param_len) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) { + unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp); + unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff); + + if (data_offset_out > total_data || + data_offset_out + this_data > total_data || + data_offset_out + this_data < data_offset_out || + data_offset_out + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + if (data_offset_in > cli->bufsize || + data_offset_in + this_data > cli->bufsize || + data_offset_in + this_data < data_offset_in || + data_offset_in + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); + } + if (this_param) { + unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp); + unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff); + + if (param_offset_out > total_param || + param_offset_out + this_param > total_param || + param_offset_out + this_param < param_offset_out || + param_offset_out + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_trans\n")); + return False; + } + if (param_offset_in > cli->bufsize || + param_offset_in + this_param > cli->bufsize || + param_offset_in + this_param < param_offset_in || + param_offset_in + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_trans\n")); + return False; + } + + memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); + } *data_len += this_data; *param_len += this_param; - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - if (total_data <= *data_len && total_param <= *param_len) break; @@ -242,27 +280,35 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { return(False); } + + /* parse out the total lengths again - they can shrink! */ + if (SVAL(cli->inbuf,smb_tdrcnt) < total_data) + total_data = SVAL(cli->inbuf,smb_tdrcnt); + if (SVAL(cli->inbuf,smb_tprcnt) < total_param) + total_param = SVAL(cli->inbuf,smb_tprcnt); + + if (total_data <= *data_len && total_param <= *param_len) + break; + } return(True); } - - - /**************************************************************************** - send a SMB nttrans request - ****************************************************************************/ + Send a SMB nttrans request. +****************************************************************************/ + BOOL cli_send_nt_trans(struct cli_state *cli, int function, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) + uint16 *setup, unsigned int lsetup, unsigned int msetup, + char *param, unsigned int lparam, unsigned int mparam, + char *data, unsigned int ldata, unsigned int mdata) { - int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; + unsigned int i; + unsigned int this_ldata,this_lparam; + unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ @@ -301,14 +347,13 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || - cli_is_error(cli)) { + if (!cli_receive_smb(cli) || cli_is_error(cli)) return(False); - } tot_data = this_ldata; tot_param = this_lparam; @@ -340,7 +385,8 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; tot_data += this_ldata; tot_param += this_lparam; @@ -355,13 +401,14 @@ BOOL cli_send_nt_trans(struct cli_state *cli, /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ + BOOL cli_receive_nt_trans(struct cli_state *cli, - char **param, int *param_len, - char **data, int *data_len) + char **param, unsigned int *param_len, + char **data, unsigned int *data_len) { - int total_data=0; - int total_param=0; - int this_data,this_param; + unsigned int total_data=0; + unsigned int total_param=0; + unsigned int this_data,this_param; uint8 eclass; uint32 ecode; char *tdata; @@ -423,25 +470,65 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { - DEBUG(1,("Data overflow in cli_receive_trans\n")); + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + + if (this_data + *data_len < this_data || + this_data + *data_len < *data_len || + this_param + *param_len < this_param || + this_param + *param_len < *param_len) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); return False; } - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_ntr_DataDisplacement), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_DataOffset), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_ntr_ParameterDisplacement), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_ParameterOffset), - this_param); + if (this_data) { + unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement); + unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset); + + if (data_offset_out > total_data || + data_offset_out + this_data > total_data || + data_offset_out + this_data < data_offset_out || + data_offset_out + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + if (data_offset_in > cli->bufsize || + data_offset_in + this_data > cli->bufsize || + data_offset_in + this_data < data_offset_in || + data_offset_in + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + + memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); + } + + if (this_param) { + unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement); + unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset); + + if (param_offset_out > total_param || + param_offset_out + this_param > total_param || + param_offset_out + this_param < param_offset_out || + param_offset_out + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + return False; + } + if (param_offset_in > cli->bufsize || + param_offset_in + this_param > cli->bufsize || + param_offset_in + this_param < param_offset_in || + param_offset_in + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + return False; + } + + memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); + } + *data_len += this_data; *param_len += this_param; - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); - total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); - if (total_data <= *data_len && total_param <= *param_len) break; @@ -462,6 +549,14 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, !(eclass == ERRDOS && ecode == ERRmoredata)) return(False); } + /* parse out the total lengths again - they can shrink! */ + if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) + total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); + if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) + total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); + + if (total_data <= *data_len && total_param <= *param_len) + break; } return(True); -- cgit From dbe2858b862232ede390fe0088f82d1e826612f9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Mar 2003 00:51:05 +0000 Subject: Change size parameters from signed to unsigned to fix up warnings. Jeremy. (This used to be commit 33b11d5eb53bdeb9d279d221fd5c01579253e1c7) --- source3/libsmb/clifile.c | 12 +-- source3/libsmb/clilist.c | 2 +- source3/libsmb/clirap.c | 38 ++++---- source3/libsmb/clitrans.c | 233 ++++++++++++++++++++++++++++++++-------------- 4 files changed, 190 insertions(+), 95 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 31d7ea5911..f61787abde 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -29,8 +29,8 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const char *fname_dst, BOOL hard_link) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; pstring data; @@ -123,8 +123,8 @@ BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; char data[100]; @@ -335,8 +335,8 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname) int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) { - int data_len = 1; - int param_len = 6; + unsigned int data_len = 1; + unsigned int param_len = 6; uint16 setup = TRANSACT2_SETFILEINFO; pstring param; unsigned char data; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 89ab5d6414..3884e4da82 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -154,7 +154,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - int param_len, data_len; + unsigned int param_len, data_len; uint16 setup; pstring param; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index b6fbb3880a..069ee374fa 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -41,8 +41,8 @@ BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, data, data_count, max_data_count); return (cli_receive_trans(cli, SMBtrans, - rparam, (int *)rparam_count, - rdata, (int *)rdata_count)); + rparam, (unsigned int *)rparam_count, + rdata, (unsigned int *)rdata_count)); } /**************************************************************************** @@ -51,8 +51,8 @@ call a remote api BOOL cli_api(struct cli_state *cli, char *param, int prcnt, int mprcnt, char *data, int drcnt, int mdrcnt, - char **rparam, int *rprcnt, - char **rdata, int *rdrcnt) + char **rparam, unsigned int *rprcnt, + char **rdata, unsigned int *rdrcnt) { cli_send_trans(cli,SMBtrans, PIPE_LANMAN, /* Name */ @@ -286,8 +286,8 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *p = param; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; - int data_len; - int param_len = 0; + unsigned int data_len; + unsigned int param_len = 0; char *rparam = NULL; char *rdata = NULL; int rprcnt, rdrcnt; @@ -368,9 +368,9 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, size_t *size, uint16 *mode) { - int data_len = 0; - int param_len = 0; - int rparam_len, rdata_len; + unsigned int data_len = 0; + unsigned int param_len = 0; + unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -449,8 +449,8 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *w_time, size_t *size, uint16 *mode, SMB_INO_T *ino) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -518,8 +518,8 @@ send a qfileinfo QUERY_FILE_NAME_INFO call BOOL cli_qfilename(struct cli_state *cli, int fnum, pstring name) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -563,8 +563,8 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -631,8 +631,8 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; pstring param; char *rparam=NULL, *rdata=NULL; @@ -677,8 +677,8 @@ send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call ****************************************************************************/ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name) { - int data_len = 0; - int param_len = 0; + unsigned int data_len = 0; + unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; pstring param; char *rparam=NULL, *rdata=NULL; diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3d862a1796..7e3357a8cc 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -24,18 +24,19 @@ /**************************************************************************** - send a SMB trans or trans2 request - ****************************************************************************/ + Send a SMB trans or trans2 request. +****************************************************************************/ + BOOL cli_send_trans(struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) + uint16 *setup, unsigned int lsetup, unsigned int msetup, + char *param, unsigned int lparam, unsigned int mparam, + char *data, unsigned int ldata, unsigned int mdata) { int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; + unsigned int this_ldata,this_lparam; + unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; char *p; int pipe_name_len=0; @@ -83,14 +84,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || - cli_is_error(cli)) { + if (!cli_receive_smb(cli) || cli_is_error(cli)) return(False); - } tot_data = this_ldata; tot_param = this_lparam; @@ -123,7 +123,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; tot_data += this_ldata; tot_param += this_lparam; @@ -133,17 +134,17 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, return(True); } - /**************************************************************************** - receive a SMB trans or trans2 response allocating the necessary memory - ****************************************************************************/ + Receive a SMB trans or trans2 response allocating the necessary memory. +****************************************************************************/ + BOOL cli_receive_trans(struct cli_state *cli,int trans, - char **param, int *param_len, - char **data, int *data_len) + char **param, unsigned int *param_len, + char **data, unsigned int *data_len) { - int total_data=0; - int total_param=0; - int this_data,this_param; + unsigned int total_data=0; + unsigned int total_param=0; + unsigned int this_data,this_param; NTSTATUS status; char *tdata; char *tparam; @@ -170,9 +171,8 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status)) { + if (NT_STATUS_IS_ERR(status)) return False; - } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -199,7 +199,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *param = tparam; } - while (1) { + for (;;) { this_data = SVAL(cli->inbuf,smb_drcnt); this_param = SVAL(cli->inbuf,smb_prcnt); @@ -209,21 +209,59 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, return False; } - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_drdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_droff), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_prdisp), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_proff), - this_param); + if (this_data + *data_len < this_data || + this_data + *data_len < *data_len || + this_param + *param_len < this_param || + this_param + *param_len < *param_len) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + if (this_data) { + unsigned int data_offset_out = SVAL(cli->inbuf,smb_drdisp); + unsigned int data_offset_in = SVAL(cli->inbuf,smb_droff); + + if (data_offset_out > total_data || + data_offset_out + this_data > total_data || + data_offset_out + this_data < data_offset_out || + data_offset_out + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + if (data_offset_in > cli->bufsize || + data_offset_in + this_data > cli->bufsize || + data_offset_in + this_data < data_offset_in || + data_offset_in + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_trans\n")); + return False; + } + + memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); + } + if (this_param) { + unsigned int param_offset_out = SVAL(cli->inbuf,smb_prdisp); + unsigned int param_offset_in = SVAL(cli->inbuf,smb_proff); + + if (param_offset_out > total_param || + param_offset_out + this_param > total_param || + param_offset_out + this_param < param_offset_out || + param_offset_out + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_trans\n")); + return False; + } + if (param_offset_in > cli->bufsize || + param_offset_in + this_param > cli->bufsize || + param_offset_in + this_param < param_offset_in || + param_offset_in + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_trans\n")); + return False; + } + + memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); + } *data_len += this_data; *param_len += this_param; - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_tdrcnt); - total_param = SVAL(cli->inbuf,smb_tprcnt); - if (total_data <= *data_len && total_param <= *param_len) break; @@ -242,27 +280,35 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { return(False); } + + /* parse out the total lengths again - they can shrink! */ + if (SVAL(cli->inbuf,smb_tdrcnt) < total_data) + total_data = SVAL(cli->inbuf,smb_tdrcnt); + if (SVAL(cli->inbuf,smb_tprcnt) < total_param) + total_param = SVAL(cli->inbuf,smb_tprcnt); + + if (total_data <= *data_len && total_param <= *param_len) + break; + } return(True); } - - - /**************************************************************************** - send a SMB nttrans request - ****************************************************************************/ + Send a SMB nttrans request. +****************************************************************************/ + BOOL cli_send_nt_trans(struct cli_state *cli, int function, int flags, - uint16 *setup, int lsetup, int msetup, - char *param, int lparam, int mparam, - char *data, int ldata, int mdata) + uint16 *setup, unsigned int lsetup, unsigned int msetup, + char *param, unsigned int lparam, unsigned int mparam, + char *data, unsigned int ldata, unsigned int mdata) { - int i; - int this_ldata,this_lparam; - int tot_data=0,tot_param=0; + unsigned int i; + unsigned int this_ldata,this_lparam; + unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ @@ -301,14 +347,13 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || - cli_is_error(cli)) { + if (!cli_receive_smb(cli) || cli_is_error(cli)) return(False); - } tot_data = this_ldata; tot_param = this_lparam; @@ -340,7 +385,8 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_send_smb(cli); + if (!cli_send_smb(cli)) + return False; tot_data += this_ldata; tot_param += this_lparam; @@ -355,13 +401,14 @@ BOOL cli_send_nt_trans(struct cli_state *cli, /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ + BOOL cli_receive_nt_trans(struct cli_state *cli, - char **param, int *param_len, - char **data, int *data_len) + char **param, unsigned int *param_len, + char **data, unsigned int *data_len) { - int total_data=0; - int total_param=0; - int this_data,this_param; + unsigned int total_data=0; + unsigned int total_param=0; + unsigned int this_data,this_param; uint8 eclass; uint32 ecode; char *tdata; @@ -423,25 +470,65 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { - DEBUG(1,("Data overflow in cli_receive_trans\n")); + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + + if (this_data + *data_len < this_data || + this_data + *data_len < *data_len || + this_param + *param_len < this_param || + this_param + *param_len < *param_len) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); return False; } - if (this_data) - memcpy(*data + SVAL(cli->inbuf,smb_ntr_DataDisplacement), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_DataOffset), - this_data); - if (this_param) - memcpy(*param + SVAL(cli->inbuf,smb_ntr_ParameterDisplacement), - smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_ntr_ParameterOffset), - this_param); + if (this_data) { + unsigned int data_offset_out = SVAL(cli->inbuf,smb_ntr_DataDisplacement); + unsigned int data_offset_in = SVAL(cli->inbuf,smb_ntr_DataOffset); + + if (data_offset_out > total_data || + data_offset_out + this_data > total_data || + data_offset_out + this_data < data_offset_out || + data_offset_out + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + if (data_offset_in > cli->bufsize || + data_offset_in + this_data > cli->bufsize || + data_offset_in + this_data < data_offset_in || + data_offset_in + this_data < this_data) { + DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + return False; + } + + memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); + } + + if (this_param) { + unsigned int param_offset_out = SVAL(cli->inbuf,smb_ntr_ParameterDisplacement); + unsigned int param_offset_in = SVAL(cli->inbuf,smb_ntr_ParameterOffset); + + if (param_offset_out > total_param || + param_offset_out + this_param > total_param || + param_offset_out + this_param < param_offset_out || + param_offset_out + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + return False; + } + if (param_offset_in > cli->bufsize || + param_offset_in + this_param > cli->bufsize || + param_offset_in + this_param < param_offset_in || + param_offset_in + this_param < this_param) { + DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + return False; + } + + memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); + } + *data_len += this_data; *param_len += this_param; - /* parse out the total lengths again - they can shrink! */ - total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); - total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); - if (total_data <= *data_len && total_param <= *param_len) break; @@ -462,6 +549,14 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, !(eclass == ERRDOS && ecode == ERRmoredata)) return(False); } + /* parse out the total lengths again - they can shrink! */ + if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) + total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); + if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) + total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); + + if (total_data <= *data_len && total_param <= *param_len) + break; } return(True); -- cgit From 3b104f6e2dc56c5edcf0278e7e43d4993e7db368 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 13 Mar 2003 04:34:31 +0000 Subject: win2000 can take much longer than the specified time to respond to a lock - so to make the torture tests valid I give it a grace time of 10 seconds instead of 2 (This used to be commit c9c9e9eb26ec3042395637d14a6661d04a629ccc) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index f61787abde..8e84963c09 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -633,7 +633,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, cli_send_smb(cli); if (timeout != 0) { - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 10*1000); } if (!cli_receive_smb(cli)) { -- cgit From 5ca8254f747dd28ba1aba459d95f3567388bf5fb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Mar 2003 07:58:54 +0000 Subject: Merge from HEAD. 'win2000 can take much longer than the specified time to respond to a lock - so to make the torture tests valid I give it a grace time of 10 seconds instead of 2' Jeremy. (This used to be commit 41571a69e04838c00de7d4a528c59cd1e88919d0) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index f61787abde..8e84963c09 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -633,7 +633,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, cli_send_smb(cli); if (timeout != 0) { - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 2*1000); + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 10*1000); } if (!cli_receive_smb(cli)) { -- cgit From e37372f4d6e10204adf272f978524751420e890f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 14 Mar 2003 10:02:12 +0000 Subject: Found by metze with the clobber-region check - if it's a pstring, use pstrcpy(). Andrew Bartlett (This used to be commit f9c3c93f55cac774e576fd5975c0582e0b334d6a) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 8e84963c09..d86f36405d 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -948,7 +948,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) pstring path2; char *p; - safe_strcpy(path2,path,sizeof(pstring)); + pstrcpy(path2,path); trim_string(path2,NULL,"\\"); if (!*path2) *path2 = '\\'; -- cgit From 33c8a6779d490bd1aa722231a59a3b68343dbc17 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 14 Mar 2003 17:05:13 +0000 Subject: /tmp/newfun.msg (This used to be commit 3f4cb7b2c4d9b54b41bcc184ccfd00032e2b021b) --- source3/libsmb/trust_passwd.c | 116 ---------------------------- source3/libsmb/trusts_util.c | 174 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 174 insertions(+), 116 deletions(-) delete mode 100644 source3/libsmb/trust_passwd.c create mode 100644 source3/libsmb/trusts_util.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c deleted file mode 100644 index cf9fd58b13..0000000000 --- a/source3/libsmb/trust_passwd.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Routines to change trust account passwords. - * Copyright (C) Andrew Bartlett 2001. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -/********************************************************* - Change the domain password on the PDC. - - Just changes the password betwen the two values specified. - - Caller must have the cli connected to the netlogon pipe - already. -**********************************************************/ -static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, - unsigned char orig_trust_passwd_hash[16], - unsigned char new_trust_passwd_hash[16]) -{ - NTSTATUS result; - uint32 neg_flags = 0x000001ff; - - result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", - nt_errstr(result))); - return result; - } - - result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", - nt_errstr(result))); - } - return result; -} - -/********************************************************* - Change the domain password on the PDC. - Store the password ourselves, but use the supplied password - Caller must have already setup the connection to the NETLOGON pipe -**********************************************************/ - -NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - unsigned char orig_trust_passwd_hash[16]) -{ - unsigned char new_trust_passwd_hash[16]; - char *new_trust_passwd; - char *str; - NTSTATUS nt_status; - - /* Create a random machine account password */ - str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - new_trust_passwd = talloc_strdup(mem_ctx, str); - - E_md4hash(new_trust_passwd, new_trust_passwd_hash); - - nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, - new_trust_passwd_hash); - - if (NT_STATUS_IS_OK(nt_status)) { - DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", - timestring(False))); - /* - * Return the result of trying to write the new password - * back into the trust account file. - */ - if (!secrets_store_machine_password(new_trust_passwd)) { - nt_status = NT_STATUS_UNSUCCESSFUL; - } - } - - return nt_status; -} - -/********************************************************* - Change the domain password on the PDC. - Do most of the legwork ourselfs. Caller must have - already setup the connection to the NETLOGON pipe -**********************************************************/ - -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - const char *domain) -{ - unsigned char old_trust_passwd_hash[16]; - char *up_domain; - - up_domain = talloc_strdup(mem_ctx, domain); - - if (!secrets_fetch_trust_account_password(domain, - old_trust_passwd_hash, - NULL)) { - DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); - return NT_STATUS_UNSUCCESSFUL; - } - - return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); - -} diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c new file mode 100644 index 0000000000..055851f6b7 --- /dev/null +++ b/source3/libsmb/trusts_util.c @@ -0,0 +1,174 @@ +/* + * Unix SMB/CIFS implementation. + * Routines to operate on various trust relationships + * Copyright (C) Andrew Bartlett 2001 + * Copyright (C) Rafal Szczesniak 2003 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +/********************************************************* + Change the domain password on the PDC. + + Just changes the password betwen the two values specified. + + Caller must have the cli connected to the netlogon pipe + already. +**********************************************************/ +static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, + unsigned char orig_trust_passwd_hash[16], + unsigned char new_trust_passwd_hash[16]) +{ + NTSTATUS result; + uint32 neg_flags = 0x000001ff; + + result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", + nt_errstr(result))); + return result; + } + + result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", + nt_errstr(result))); + } + return result; +} + +/********************************************************* + Change the domain password on the PDC. + Store the password ourselves, but use the supplied password + Caller must have already setup the connection to the NETLOGON pipe +**********************************************************/ + +NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, + unsigned char orig_trust_passwd_hash[16]) +{ + unsigned char new_trust_passwd_hash[16]; + char *new_trust_passwd; + char *str; + NTSTATUS nt_status; + + /* Create a random machine account password */ + str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); + new_trust_passwd = talloc_strdup(mem_ctx, str); + + E_md4hash(new_trust_passwd, new_trust_passwd_hash); + + nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, + new_trust_passwd_hash); + + if (NT_STATUS_IS_OK(nt_status)) { + DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", + timestring(False))); + /* + * Return the result of trying to write the new password + * back into the trust account file. + */ + if (!secrets_store_machine_password(new_trust_passwd)) { + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } + + return nt_status; +} + +/********************************************************* + Change the domain password on the PDC. + Do most of the legwork ourselfs. Caller must have + already setup the connection to the NETLOGON pipe +**********************************************************/ + +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, + const char *domain) +{ + unsigned char old_trust_passwd_hash[16]; + char *up_domain; + + up_domain = talloc_strdup(mem_ctx, domain); + + if (!secrets_fetch_trust_account_password(domain, + old_trust_passwd_hash, + NULL)) { + DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); + return NT_STATUS_UNSUCCESSFUL; + } + + return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); + +} + + +/** + * Verify whether or not given domain is trusted. + * + * @param domain_name name of the domain to be verified + * @return true if domain is one of the trusted once or + * false if otherwise + **/ + +BOOL is_trusted_domain(const char* dom_name) +{ + int enum_ctx = 0; + const int trustdom_size = 10; + int num_domains, i; + TRUSTDOM **domains; + NTSTATUS result; + fstring trustdom_name; + DOM_SID trustdom_sid; + TALLOC_CTX *mem_ctx; + + /* + * Query the secrets db as an ultimate source of information + * about trusted domain names. This is PDC or BDC case. + */ + mem_ctx = talloc_init("is_trusted_domain"); + + do { + result = secrets_get_trusted_domains(mem_ctx, &enum_ctx, trustdom_size, + &num_domains, &domains); + /* compare each returned entry against incoming connection's domain */ + for (i = 0; i < num_domains; i++) { + pull_ucs2_fstring(trustdom_name, domains[i]->name); + if (strequal(trustdom_name, dom_name)) { + talloc_destroy(mem_ctx); + return True; + } + } + } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + + /* + * Query the trustdom_cache updated periodically. The only + * way for domain member server. + */ + if (trustdom_cache_enable() && + trustdom_cache_fetch(dom_name, &trustdom_sid)) { + trustdom_cache_shutdown(); + return True; + } + + /* + * if nothing's been found, then give up here, although + * the last resort might be to query the PDC. + */ + return False; +} + -- cgit From 9db9982cd34d36d8b23e94a4063761c8b6aa9e17 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Fri, 14 Mar 2003 17:20:13 +0000 Subject: We haven't implemented The Singing Contexts so far. Who knows what .NET server brings, though ...? ;-) Rafal (This used to be commit d81b0d26903004be6a99ac029dd531fd18947268) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 40359c5c8c..c3538ee9fd 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -417,7 +417,7 @@ BOOL cli_temp_set_signing(struct cli_state *cli) } /** - * Free the singing context + * Free the signing context */ void cli_free_signing_context(struct cli_state *cli) -- cgit From 6fe590983b5d4dca8cea82eaa8dfb7b3a13bc3d1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:43:37 +0000 Subject: Add const, and a signed/unsigned fix. (This used to be commit f07a93eaeba20f5704f43c7f02141adc564db136) --- source3/libsmb/clitrans.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 7e3357a8cc..3d3cd427d7 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -31,10 +31,10 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, - char *param, unsigned int lparam, unsigned int mparam, - char *data, unsigned int ldata, unsigned int mdata) + const char *param, unsigned int lparam, unsigned int mparam, + const char *data, unsigned int ldata, unsigned int mdata) { - int i; + unsigned int i; unsigned int this_ldata,this_lparam; unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; -- cgit From 16ec110b0f1fe45b598a04e171397d97c3cb5aef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:45:19 +0000 Subject: client-side smbpasswd fixes - use pstrcpy_base to avoid clobber_region bugs Andrew Bartlett (This used to be commit 7ab6559369b4e6ee3c5269d8cff04e5a39f6b493) --- source3/libsmb/clirap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index b38e7d5c23..224c37046c 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -281,7 +281,7 @@ Send a SamOEMChangePassword command BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password) { - char param[16+sizeof(fstring)]; + pstring param; char data[532]; char *p = param; unsigned char old_pw_hash[16]; @@ -300,11 +300,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; - pstrcpy(p, "zsT"); + pstrcpy_base(p, "zsT", param); p = skip_string(p,1); - pstrcpy(p, "B516B16"); + pstrcpy_base(p, "B516B16", param); p = skip_string(p,1); - pstrcpy(p,user); + pstrcpy_base(p,user, param); p = skip_string(p,1); SSVAL(p,0,532); p += 2; @@ -317,7 +317,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char */ E_deshash(old_password, old_pw_hash); - clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE|STR_ASCII); + clistr_push(cli, dos_new_password, new_password, sizeof(dos_new_password), STR_TERMINATE|STR_ASCII); if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) return False; @@ -685,7 +685,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin int count=8; char *p; BOOL ret; - int len; + unsigned int len; p = param; memset(p, 0, 6); -- cgit From dc7c505dec59329c5dde35763febab3547f6d642 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:46:05 +0000 Subject: Be parinoid, malloc an extra SAFETY_MARGIN on the client's inbuf and outbuf. Andrew Bartlett (This used to be commit 2effcae13f9dfbff40b34d32c7fd82118c3fd096) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3cae643c38..d969193089 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -245,8 +245,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize); - cli->inbuf = (char *)malloc(cli->bufsize); + cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); + cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->use_spnego = lp_client_use_spnego(); -- cgit From a4ba0496846924df4688cf3678940ec3b14e6376 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:46:43 +0000 Subject: Specify buffer sizes (This used to be commit aa12379b3fd9646199a8ff3f217ec7dfef1942a5) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 36b6f609f5..763878f9b3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -66,7 +66,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, memcpy(pword, pass, passlen); } else if (passlen > 0) { /* Plaintext mode needed, assume plaintext supplied. */ - passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); } /* send a session setup command */ @@ -778,7 +778,7 @@ BOOL cli_send_tconX(struct cli_state *cli, /* * Non-encrypted passwords - convert to DOS codepage before using. */ - passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); } else { memcpy(pword, pass, passlen); } -- cgit From eca1293fadf8774f016e18ca56ac200546ca70ba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 06:51:57 +0000 Subject: specify the size of these buffers (This used to be commit f6ea572cd57d4e655d387fe225a5d7122d587a9b) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3884e4da82..5bd1283ab7 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -178,7 +178,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; - p += clistr_push(cli, param+12, mask, -1, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; @@ -188,7 +188,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ p = param+12; - p += clistr_push(cli, param+12, mask, -1, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } -- cgit From 3b5bc93e9db4df6ded2eef7b32bda74328b04811 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 07:14:55 +0000 Subject: String handling parinoia fixes. This patch enables the compile-time checking of strings assable by means of sizeof(). (Original code had the configure check reversed). This is extended to all safe_strcpy() users, push_string and pull_string, as well as the cli and srv derivitives. There is an attempt to cap strings at the end of the cli buffer, and clobber_region() of the speified length (when not -1 :-). Becouse of the way they are declared, the 'overmalloc a string' users of safe_strcpy() have been changed to use overmalloc_safe_strcpy() (which skips some of the checks). This whole ball of mud worked fine, until I pulled out my 'fix' for our statcache. When jeremy fixes that, we should be able to get back to testing this stuff. This patch also includes a 'marker' of the last caller to clobber_region (ie, the function that called pstrcpy() that called clobber_region) to assist in debugging problems that may have smashed the stack. This is printed at smb_panic() time. (Original idea and patch by metze). It also removes some unsused functions, and #if 0's some others that are unused but probably should be used in the near future. For now, this patch gives us some confidence on one class of trivial parsing error in our code. Andrew Bartlett (This used to be commit 31f4827acc2a2f00399a5528fc83a0dae5cebaf4) --- source3/libsmb/clistr.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 3c9964368e..97a3fa6cc9 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -20,24 +20,38 @@ #include "includes.h" -int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags) +size_t clistr_push_fn(const char *function, unsigned int line, + struct cli_state *cli, void *dest, + const char *src, int dest_len, int flags) { - return push_string(cli->outbuf, dest, src, dest_len, flags); + size_t buf_used = PTR_DIFF(dest, cli->outbuf); + if (dest_len == -1) { + if (((ptrdiff_t)dest < (ptrdiff_t)cli->outbuf) || (buf_used > cli->bufsize)) { + DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n")); + return push_string_fn(function, line, cli->outbuf, dest, src, -1, flags); + } + return push_string_fn(function, line, cli->outbuf, dest, src, cli->bufsize - buf_used, flags); + } + + /* 'normal' push into size-specified buffer */ + return push_string_fn(function, line, cli->outbuf, dest, src, dest_len, flags); } -int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, - int flags) +size_t clistr_pull_fn(const char *function, unsigned int line, + struct cli_state *cli, char *dest, const void *src, + int dest_len, int src_len, + int flags) { - return pull_string(cli->inbuf, dest, src, dest_len, src_len, flags); + return pull_string_fn(function, line, cli->inbuf, dest, src, dest_len, src_len, flags); } -int clistr_align_out(struct cli_state *cli, const void *p, int flags) +size_t clistr_align_out(struct cli_state *cli, const void *p, int flags) { return align_string(cli->outbuf, p, flags); } -int clistr_align_in(struct cli_state *cli, const void *p, int flags) +size_t clistr_align_in(struct cli_state *cli, const void *p, int flags) { return align_string(cli->inbuf, p, flags); } -- cgit From 02704f973347f05af5ebcb0d4a494a6102199536 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2003 08:18:29 +0000 Subject: Minor fixes. - signed/unsigned - quieten warning about assignment as truth value - whitespace Andrew Bartlett (This used to be commit a13ce0df4b4a776fa635a1fb804dd00d195f58d0) --- source3/libsmb/trusts_util.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 055851f6b7..f7b2c2e3a6 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -152,9 +152,9 @@ BOOL is_trusted_domain(const char* dom_name) talloc_destroy(mem_ctx); return True; } - } + } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); - + /* * Query the trustdom_cache updated periodically. The only * way for domain member server. -- cgit From 0ab29d6186135bd66c4154b545ac8323232a6f2e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 04:42:57 +0000 Subject: Fix a memory leak - 'smbcontrol smbd pool-usage' is your freind! Andrew Bartlett (This used to be commit a12e8524997e329a4f4cd766d6371e384698795a) --- source3/libsmb/trusts_util.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index f7b2c2e3a6..b8f84ba890 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -155,6 +155,8 @@ BOOL is_trusted_domain(const char* dom_name) } } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + talloc_destroy(mem_ctx); + /* * Query the trustdom_cache updated periodically. The only * way for domain member server. -- cgit From cf9fcaa98ef7f11a660aad00a7628fd99dbaa950 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:40:37 +0000 Subject: pstrcpy_base merges for client-side smbpasswd. Andrew Bartlett (This used to be commit 980f2eb7c2efa1a2c83098aebecf0e25a05724cb) --- source3/libsmb/clirap.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 069ee374fa..224c37046c 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -221,10 +221,10 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - pstrcpy_base(p,"WrLehDz",param); + pstrcpy_base(p,"WrLehDz", param); p = skip_string(p,1); - pstrcpy_base(p,"B16BBDz",param); + pstrcpy_base(p,"B16BBDz", param); p = skip_string(p,1); SSVAL(p,0,uLevel); @@ -233,7 +233,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - p += push_pstring(p, workgroup); + p += push_pstring_base(p, workgroup, param); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ @@ -281,7 +281,7 @@ Send a SamOEMChangePassword command BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password) { - char param[16+sizeof(fstring)]; + pstring param; char data[532]; char *p = param; unsigned char old_pw_hash[16]; @@ -300,11 +300,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; - pstrcpy(p, "zsT"); + pstrcpy_base(p, "zsT", param); p = skip_string(p,1); - pstrcpy(p, "B516B16"); + pstrcpy_base(p, "B516B16", param); p = skip_string(p,1); - pstrcpy(p,user); + pstrcpy_base(p,user, param); p = skip_string(p,1); SSVAL(p,0,532); p += 2; @@ -317,7 +317,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char */ E_deshash(old_password, old_pw_hash); - clistr_push(cli, dos_new_password, new_password, -1, STR_TERMINATE|STR_ASCII); + clistr_push(cli, dos_new_password, new_password, sizeof(dos_new_password), STR_TERMINATE|STR_ASCII); if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) return False; @@ -685,7 +685,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin int count=8; char *p; BOOL ret; - int len; + unsigned int len; p = param; memset(p, 0, 6); -- cgit From ec458fa87e3ee858be39671f575e21a9350674b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:45:16 +0000 Subject: Merge from HEAD - sync up SessionSetup code to HEAD, including Luke Howard's session key and auth verifier patches. Andrew Bartlett (This used to be commit 3f9616a68a855acbae3f405c27ee2358fbe7ba2c) --- source3/libsmb/clikrb5.c | 52 ++++++++++++++++++++++++++++++++++++++-------- source3/libsmb/clispnego.c | 29 ++++++++++++++------------ 2 files changed, 59 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index bef6998a49..5edc56daa9 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 - Copyright (C) Luke Howard 2002 + Copyright (C) Luke Howard 2002-2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,6 +23,16 @@ #ifdef HAVE_KRB5 +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE +#define KRB5_KEY_TYPE(k) ((k)->keytype) +#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) +#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) +#else +#define KRB5_KEY_TYPE(k) ((k)->enctype) +#define KRB5_KEY_LENGTH(k) ((k)->length) +#define KRB5_KEY_DATA(k) ((k)->contents) +#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ + #ifndef HAVE_KRB5_SET_REAL_TIME /* * This function is not in the Heimdal mainline. @@ -124,7 +134,7 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, return krb5_get_default_in_tkt_etypes(context, enctypes); } #else - __ERROR_XX_UNKNOWN_GET_ENCTYPES_FUNCTIONS +#error UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif void free_kerberos_etypes(krb5_context context, @@ -305,12 +315,12 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) DATA_BLOB ret; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_DES_CBC_CRC, - ENCTYPE_NULL}; - + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_NULL}; + retval = krb5_init_context(&context); if (retval) { DEBUG(1,("krb5_init_context failed (%s)\n", @@ -355,11 +365,35 @@ failed: return data_blob(NULL, 0); } + BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + { +#ifdef ENCTYPE_ARCFOUR_HMAC + krb5_keyblock *skey; +#endif + BOOL ret = False; + + memset(session_key, 0, 16); + +#ifdef ENCTYPE_ARCFOUR_HMAC + if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { + if (KRB5_KEY_TYPE(skey) == + ENCTYPE_ARCFOUR_HMAC + && KRB5_KEY_LENGTH(skey) == 16) { + memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + ret = True; + } + krb5_free_keyblock(context, skey); + } +#endif /* ENCTYPE_ARCFOUR_HMAC */ + + return ret; + } #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ - DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); } + #endif diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e93f1855dd..53f7eb6e7d 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -3,6 +3,7 @@ simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 Copyright (C) Jim McDonough 2002 + Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -259,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; @@ -268,7 +269,8 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) asn1_push_tag(&data, ASN1_APPLICATION(0)); asn1_write_OID(&data, OID_KERBEROS5); - asn1_write_BOOLEAN(&data, 0); + + asn1_write(&data, tok_id, 2); asn1_write(&data, ticket.data, ticket.length); asn1_pop_tag(&data); @@ -286,7 +288,7 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) { BOOL ret; ASN1_DATA data; @@ -295,15 +297,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) asn1_load(&data, blob); asn1_start_tag(&data, ASN1_APPLICATION(0)); asn1_check_OID(&data, OID_KERBEROS5); - asn1_check_BOOLEAN(&data, 0); data_remaining = asn1_tag_remaining(&data); - if (data_remaining < 1) { + if (data_remaining < 3) { data.has_error = True; } else { - - *ticket = data_blob(data.data, data_remaining); + asn1_read(&data, tok_id, 2); + data_remaining -= 2; + *ticket = data_blob(NULL, data_remaining); asn1_read(&data, ticket->data, ticket->length); } @@ -330,7 +332,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt); + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); @@ -438,9 +440,10 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) } /* - generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. + generate a minimal SPNEGO response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, + const char *mechOID) { ASN1_DATA data; DATA_BLOB ret; @@ -462,13 +465,13 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + if (reply->data != NULL) { asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); + asn1_write_OID(&data, mechOID); asn1_pop_tag(&data); asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); + asn1_write_OctetString(&data, reply->data, reply->length); asn1_pop_tag(&data); } -- cgit From e88eab35bc03a2d108b27f2209ec4cfb395dcdba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 23:04:03 +0000 Subject: Merge from HEAD: signed/unsigned (mostly i counters) a little bit of const. Andrew Bartlett (This used to be commit 50f0ca752e5058c4051f42a9337361373ba1f727) --- source3/libsmb/clitrans.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 7e3357a8cc..3d3cd427d7 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -31,10 +31,10 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, - char *param, unsigned int lparam, unsigned int mparam, - char *data, unsigned int ldata, unsigned int mdata) + const char *param, unsigned int lparam, unsigned int mparam, + const char *data, unsigned int ldata, unsigned int mdata) { - int i; + unsigned int i; unsigned int this_ldata,this_lparam; unsigned int tot_data=0,tot_param=0; char *outdata,*outparam; -- cgit From d332200c254b4bbf27461a37f9655bf42faa2b3a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Mar 2003 01:48:11 +0000 Subject: Merge in the developer string options from HEAD. We need to ensure 3.0 is as stable as possible in the string department and some pain now will help later :-). Jeremy. (This used to be commit 86e3eddac698d90f4666b8492b4603a4efbbd67b) --- source3/libsmb/clistr.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 3c9964368e..97a3fa6cc9 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -20,24 +20,38 @@ #include "includes.h" -int clistr_push(struct cli_state *cli, void *dest, const char *src, int dest_len, int flags) +size_t clistr_push_fn(const char *function, unsigned int line, + struct cli_state *cli, void *dest, + const char *src, int dest_len, int flags) { - return push_string(cli->outbuf, dest, src, dest_len, flags); + size_t buf_used = PTR_DIFF(dest, cli->outbuf); + if (dest_len == -1) { + if (((ptrdiff_t)dest < (ptrdiff_t)cli->outbuf) || (buf_used > cli->bufsize)) { + DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n")); + return push_string_fn(function, line, cli->outbuf, dest, src, -1, flags); + } + return push_string_fn(function, line, cli->outbuf, dest, src, cli->bufsize - buf_used, flags); + } + + /* 'normal' push into size-specified buffer */ + return push_string_fn(function, line, cli->outbuf, dest, src, dest_len, flags); } -int clistr_pull(struct cli_state *cli, char *dest, const void *src, int dest_len, int src_len, - int flags) +size_t clistr_pull_fn(const char *function, unsigned int line, + struct cli_state *cli, char *dest, const void *src, + int dest_len, int src_len, + int flags) { - return pull_string(cli->inbuf, dest, src, dest_len, src_len, flags); + return pull_string_fn(function, line, cli->inbuf, dest, src, dest_len, src_len, flags); } -int clistr_align_out(struct cli_state *cli, const void *p, int flags) +size_t clistr_align_out(struct cli_state *cli, const void *p, int flags) { return align_string(cli->outbuf, p, flags); } -int clistr_align_in(struct cli_state *cli, const void *p, int flags) +size_t clistr_align_in(struct cli_state *cli, const void *p, int flags) { return align_string(cli->inbuf, p, flags); } -- cgit From d5ee9b2f480ddbda0b8f69409698d27c99384f9c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 18 Mar 2003 11:22:52 +0000 Subject: Jeremy merged across my string parinoia fixes, but forgot to enable them! :-) This patch catches up on the rest of the work - as much string checking as is possible is done at compile time, and the rest at runtime. Lots of code converted to pstrcpy() etc, and other code reworked to correctly call sizeof(). Andrew Bartlett (This used to be commit c5b604e2ee67d74241ae2fa07ae904647d35a2be) --- source3/libsmb/cliconnect.c | 4 ++-- source3/libsmb/clifile.c | 2 +- source3/libsmb/clilist.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 49b0004ac2..54a282e805 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -66,7 +66,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, memcpy(pword, pass, passlen); } else if (passlen > 0) { /* Plaintext mode needed, assume plaintext supplied. */ - passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); } /* send a session setup command */ @@ -774,7 +774,7 @@ BOOL cli_send_tconX(struct cli_state *cli, /* * Non-encrypted passwords - convert to DOS codepage before using. */ - passlen = clistr_push(cli, pword, pass, -1, STR_TERMINATE); + passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); } else { memcpy(pword, pass, passlen); } diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 8e84963c09..d86f36405d 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -948,7 +948,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) pstring path2; char *p; - safe_strcpy(path2,path,sizeof(pstring)); + pstrcpy(path2,path); trim_string(path2,NULL,"\\"); if (!*path2) *path2 = '\\'; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3884e4da82..5bd1283ab7 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -178,7 +178,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; - p += clistr_push(cli, param+12, mask, -1, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; @@ -188,7 +188,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ p = param+12; - p += clistr_push(cli, param+12, mask, -1, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } -- cgit From 972e492bed431d7a19f9b54727952293ce395660 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 18 Mar 2003 11:53:20 +0000 Subject: NTLMSSP updates from HEAD. Andrew Bartlett (This used to be commit f4ae028c2ad6ff8c7da3a6ef77a92762861144e1) --- source3/libsmb/ntlmssp.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e1509f6b63..5722b8efcd 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -81,7 +81,7 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) /** * Determine correct target name flags for reply, given server role - * and negoitated falgs + * and negotiated flags * * @param ntlmssp_state NTLMSSP State * @param neg_flags The flags from the packet @@ -291,7 +291,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, /** * Create an NTLMSSP state machine * - * @param ntlmssp_state NTLMSSP State, allocated by this funciton + * @param ntlmssp_state NTLMSSP State, allocated by this function */ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) @@ -322,7 +322,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) /** * End an NTLMSSP state machine * - * @param ntlmssp_state NTLMSSP State, free()ed by this funciton + * @param ntlmssp_state NTLMSSP State, free()ed by this function */ NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) @@ -431,7 +431,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st DATA_BLOB session_key = data_blob(NULL, 0); uint8 datagram_sess_key[16]; - ZERO_STRUCT(datagram_sess_key); + generate_random_buffer(datagram_sess_key, sizeof(datagram_sess_key), False); if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -508,8 +508,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - - data_blob_free(&challenge_blob); /* this generates the actual auth packet */ if (!msrpc_gen(next_request, auth_gen_string, @@ -520,7 +518,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->get_global_myname(), - datagram_sess_key, 0, + datagram_sess_key, 16, ntlmssp_state->neg_flags)) { data_blob_free(&lm_response); @@ -529,9 +527,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_NO_MEMORY; } - data_blob_free(&lm_response); - data_blob_free(&nt_response); + data_blob_free(&ntlmssp_state->chal); + data_blob_free(&ntlmssp_state->lm_resp); + data_blob_free(&ntlmssp_state->nt_resp); + data_blob_free(&ntlmssp_state->session_key); + ntlmssp_state->chal = challenge_blob; + ntlmssp_state->lm_resp = lm_response; + ntlmssp_state->nt_resp = nt_response; ntlmssp_state->session_key = session_key; return NT_STATUS_MORE_PROCESSING_REQUIRED; @@ -558,10 +561,12 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) (*ntlmssp_state)->unicode = True; (*ntlmssp_state)->neg_flags = - NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET; + (*ntlmssp_state)->ref_count = 1; + return NT_STATUS_OK; } @@ -569,8 +574,16 @@ NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - data_blob_free(&(*ntlmssp_state)->session_key); - talloc_destroy(mem_ctx); + (*ntlmssp_state)->ref_count--; + + if ((*ntlmssp_state)->ref_count == 0) { + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + data_blob_free(&(*ntlmssp_state)->session_key); + talloc_destroy(mem_ctx); + } + *ntlmssp_state = NULL; return NT_STATUS_OK; } -- cgit From 892599fb92b6158e86a3934c8f2045ee457f38e3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 18 Mar 2003 12:01:47 +0000 Subject: Merge from HEAD: A much better SMB signing module, that allows for mulitple signing algorithms and correctly backs down from signing when the server cannot sign the reply. This also attempts to enable SMB signing on NTLMSSP connections, but I don't know what NTLMSSP flags to set yet. This would allow 'client use signing' to be set by default, for server compatability. (A seperate option value should be provided for mandetory signing, which would not back down). Andrew Bartlett (This used to be commit 1c87be7a3d127201a6ab78d22d17c971af16b86b) --- source3/libsmb/cliconnect.c | 94 +++++++++++++++++++---------------------- source3/libsmb/clientgen.c | 12 +++--- source3/libsmb/smbencrypt.c | 100 +------------------------------------------- 3 files changed, 52 insertions(+), 154 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 54a282e805..763878f9b3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -228,39 +228,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_signing_on_cli (struct cli_state *cli, uint8 user_session_key[16], DATA_BLOB response) -{ - uint8 zero_sig[8]; - ZERO_STRUCT(zero_sig); - - DEBUG(5, ("Server returned security sig:\n")); - dump_data(5, &cli->inbuf[smb_ss_field], 8); - - if (cli->sign_info.use_smb_signing) { - DEBUG(5, ("smb signing already active on connection\n")); - } else if (memcmp(&cli->inbuf[smb_ss_field], zero_sig, 8) != 0) { - - DEBUG(3, ("smb signing enabled!\n")); - cli->sign_info.use_smb_signing = True; - cli_calculate_mac_key(cli, user_session_key, response); - } else { - DEBUG(5, ("smb signing NOT enabled!\n")); - } -} - static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) { memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); } - -static void set_temp_signing_on_cli(struct cli_state *cli) -{ - if (cli->sign_info.negotiated_smb_signing) - cli->sign_info.temp_smb_signing = True; -} - - /**************************************************************************** do a NT1 NTLM/LM encrypted session setup @param cli client state to create do session setup on @@ -310,8 +282,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - - set_temp_signing_on_cli(cli); + cli_simple_set_signing(cli, session_key.data, nt_response); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -374,26 +345,24 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (session_key.data) { /* Have plaintext orginal */ set_cli_session_key(cli, session_key); - set_signing_on_cli(cli, session_key.data, nt_response); } + ret = True; end: data_blob_free(&lm_response); data_blob_free(&nt_response); data_blob_free(&session_key); - return True; + return ret; } /**************************************************************************** - Send a extended security session setup blob, returning a reply blob. + Send a extended security session setup blob ****************************************************************************/ -static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; - DATA_BLOB blob2 = data_blob(NULL, 0); - uint32 len; capabilities |= CAP_EXTENDED_SECURITY; @@ -403,8 +372,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); - set_temp_signing_on_cli(cli); - cli_setup_packet(cli); SCVAL(cli->outbuf,smb_vwv0,0xFF); @@ -420,7 +387,18 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); + return cli_send_smb(cli); +} + +/**************************************************************************** + Send a extended security session setup blob, returning a reply blob. +****************************************************************************/ + +static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) +{ + DATA_BLOB blob2 = data_blob(NULL, 0); + char *p; + size_t len; if (!cli_receive_smb(cli)) return blob2; @@ -449,6 +427,20 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return blob2; } +/**************************************************************************** + Send a extended security session setup blob, returning a reply blob. +****************************************************************************/ + +static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +{ + DATA_BLOB blob2 = data_blob(NULL, 0); + if (!cli_session_setup_blob_send(cli, blob)) { + return blob2; + } + + return cli_session_setup_blob_receive(cli); +} + #ifdef HAVE_KRB5 /**************************************************************************** Use in-memory credentials cache @@ -502,6 +494,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, DATA_BLOB blob_in = data_blob(NULL, 0); DATA_BLOB blob_out; + cli_temp_set_signing(cli); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return False; } @@ -532,8 +526,15 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } /* now send that blob on its way */ - blob = cli_session_setup_blob(cli, msg1); + if (!cli_session_setup_blob_send(cli, msg1)) { + return False; + } data_blob_free(&msg1); + + cli_ntlmssp_set_signing(cli, ntlmssp_state); + + blob = cli_session_setup_blob_receive(cli); + nt_status = cli_nt_error(cli); } @@ -570,6 +571,9 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, set_cli_session_key(cli, ntlmssp_state->session_key); } + /* we have a reference conter on ntlmssp_state, if we are signing + then the state will be kept by the signing engine */ + if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { return False; } @@ -883,11 +887,6 @@ BOOL cli_negprot(struct cli_state *cli) int numprots; int plength; - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send negprot again, particularly after setting up SMB Signing\n")); - return False; - } - if (cli->protocol < PROTOCOL_NT1) cli->use_spnego = False; @@ -1013,11 +1012,6 @@ BOOL cli_session_request(struct cli_state *cli, if (cli->port == 445) return True; - if (cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot send session resquest again, particularly after setting up SMB Signing\n")); - return False; - } - /* send a session request (RFC 1002) */ /* setup the packet length * Remove four bytes from the length count, since the length diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9598f4ac96..3cae643c38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -177,9 +177,6 @@ void cli_setup_packet(struct cli_state *cli) flags2 |= FLAGS2_32_BIT_ERROR_CODES; if (cli->use_spnego) flags2 |= FLAGS2_EXTENDED_SECURITY; - if (cli->sign_info.use_smb_signing - || cli->sign_info.temp_smb_signing) - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; SSVAL(cli->outbuf,smb_flg2, flags2); } } @@ -200,8 +197,8 @@ void cli_setup_bcc(struct cli_state *cli, void *p) void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) { /* copy_nt_creds(&cli->usr, usr); */ - safe_strcpy(cli->domain , usr->domain , sizeof(usr->domain )-1); - safe_strcpy(cli->user_name, usr->user_name, sizeof(usr->user_name)-1); + fstrcpy(cli->domain , usr->domain); + fstrcpy(cli->user_name, usr->user_name); memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); cli->ntlmssp_flags = usr->ntlmssp_flags; cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; @@ -262,6 +259,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; + /* initialise signing */ + cli_null_set_signing(cli); + if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; @@ -303,6 +303,7 @@ void cli_close_connection(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); + cli_free_signing_context(cli); data_blob_free(&cli->secblob); if (cli->mem_ctx) { @@ -314,6 +315,7 @@ void cli_close_connection(struct cli_state *cli) close(cli->fd); cli->fd = -1; cli->smb_rw_error = 0; + } /**************************************************************************** diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index aa9391325f..28160d9609 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -295,7 +295,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], +static DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], DATA_BLOB server_chal, size_t client_chal_length) { uchar ntlmv2_response[16]; @@ -416,101 +416,3 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, return True; } - -/*********************************************************** - SMB signing - setup the MAC key. -************************************************************/ - -void cli_calculate_mac_key(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) -{ - - memcpy(&cli->sign_info.mac_key[0], user_session_key, 16); - memcpy(&cli->sign_info.mac_key[16],response.data, MIN(response.length, 40 - 16)); - cli->sign_info.mac_key_len = MIN(response.length + 16, 40); - cli->sign_info.use_smb_signing = True; - - /* These calls are INCONPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - - /* Reset the sequence number in case we had a previous (aborted) attempt */ - cli->sign_info.send_seq_num = 2; -} - -/*********************************************************** - SMB signing - calculate a MAC to send. -************************************************************/ - -void cli_caclulate_sign_mac(struct cli_state *cli) -{ - unsigned char calc_md5_mac[16]; - struct MD5Context md5_ctx; - - if (cli->sign_info.temp_smb_signing) { - memcpy(&cli->outbuf[smb_ss_field], "SignRequest", 8); - cli->sign_info.temp_smb_signing = False; - return; - } - - if (!cli->sign_info.use_smb_signing) { - return; - } - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - */ - SIVAL(cli->outbuf, smb_ss_field, cli->sign_info.send_seq_num); - SIVAL(cli->outbuf, smb_ss_field + 4, 0); - - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ - MD5Init(&md5_ctx); - MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); - MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); - MD5Final(calc_md5_mac, &md5_ctx); - - memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signitures...*/ - cli->sign_info.send_seq_num++; - cli->sign_info.reply_seq_num = cli->sign_info.send_seq_num; - cli->sign_info.send_seq_num++; -} - -/*********************************************************** - SMB signing - check a MAC sent by server. -************************************************************/ - -BOOL cli_check_sign_mac(struct cli_state *cli) -{ - unsigned char calc_md5_mac[16]; - unsigned char server_sent_mac[8]; - struct MD5Context md5_ctx; - - if (cli->sign_info.temp_smb_signing) { - return True; - } - - if (!cli->sign_info.use_smb_signing) { - return True; - } - - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - */ - - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - SIVAL(cli->inbuf, smb_ss_field, cli->sign_info.reply_seq_num); - SIVAL(cli->inbuf, smb_ss_field + 4, 0); - - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ - MD5Init(&md5_ctx); - MD5Update(&md5_ctx, cli->sign_info.mac_key, cli->sign_info.mac_key_len); - MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); - MD5Final(calc_md5_mac, &md5_ctx); - - return (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); -} -- cgit From ec2b31b7e31c4cdd9f187b329e4f26466ba9e748 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 18 Mar 2003 12:02:51 +0000 Subject: Parinoia fixes from HEAD - malloc() some extra room after the allocated buffer size. (This used to be commit 27ec538eca0905e1f749de4c49cc2555c5932d5c) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3cae643c38..d969193089 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -245,8 +245,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize); - cli->inbuf = (char *)malloc(cli->bufsize); + cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); + cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->use_spnego = lp_client_use_spnego(); -- cgit From 033187734893a11df004e03b6cdd8588d66f6ca6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Mar 2003 21:25:33 +0000 Subject: Removed unused var. Jeremy. (This used to be commit fb925a72a6323d96d8fae658c4271ca05e8256de) --- source3/libsmb/smb_signing.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c3538ee9fd..c713418e82 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -353,8 +353,6 @@ static void cli_null_free_signing_context(struct cli_state *cli) BOOL cli_null_set_signing(struct cli_state *cli) { - struct smb_basic_sign_data *data; - cli->sign_info.signing_context = NULL; cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; -- cgit From 72b0c07eae391c796c09161416baa34cd852dc03 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Mar 2003 21:25:35 +0000 Subject: Removed unused var. Jeremy. (This used to be commit f93c64b5ca1bc21f5fa89200034cd82dcbc0910b) --- source3/libsmb/smb_signing.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c3538ee9fd..c713418e82 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -353,8 +353,6 @@ static void cli_null_free_signing_context(struct cli_state *cli) BOOL cli_null_set_signing(struct cli_state *cli) { - struct smb_basic_sign_data *data; - cli->sign_info.signing_context = NULL; cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; -- cgit From c7e720c87bf1dae8ec4ca4bad47a7324c89b7c05 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Mar 2003 16:42:39 +0000 Subject: Patch from Samuel Thibault to convert messages from unix to dos charset. Works on 2000. sending messages to 9x needs to be fixed, but that didn't work anyway (This used to be commit ca066502a2a3dbdd8943d515c9c6d21e62d757b6) --- source3/libsmb/climessage.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 1587e6f4cd..5f6ce36133 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -65,6 +65,8 @@ send a message ****************************************************************************/ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) { + char *msgdos; + int lendos; char *p; memset(cli->outbuf,'\0',smb_size); @@ -77,9 +79,18 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) p = smb_buf(cli->outbuf); *p++ = 1; - SSVAL(p,0,len); p += 2; - memcpy(p,msg,len); - p += len; + + if ((lendos = convert_string_allocate(CH_UNIX, CH_DOS, msg,len, (void **) &msgdos)) < 0 || !msgdos) { + DEBUG(3,("Conversion failed, sending message in UNIX charset\n")); + SSVAL(p, 0, len); p += 2; + memcpy(p, msg, len); + p += len; + } else { + SSVAL(p, 0, lendos); p += 2; + memcpy(p, msgdos, lendos); + p += lendos; + SAFE_FREE(msgdos); + } cli_setup_bcc(cli, p); cli_send_smb(cli); -- cgit From 0b72dd8325bc5c78de56039942acc175d28042a7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Mar 2003 16:44:14 +0000 Subject: Patch from Samuel Thibault to convert messages from dos to unix charset when sending(and vice versa when receiving). (This used to be commit 5310447ec6e0df1c000e3ee14572f5b7fee31f28) --- source3/libsmb/climessage.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 1587e6f4cd..5f6ce36133 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -65,6 +65,8 @@ send a message ****************************************************************************/ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) { + char *msgdos; + int lendos; char *p; memset(cli->outbuf,'\0',smb_size); @@ -77,9 +79,18 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) p = smb_buf(cli->outbuf); *p++ = 1; - SSVAL(p,0,len); p += 2; - memcpy(p,msg,len); - p += len; + + if ((lendos = convert_string_allocate(CH_UNIX, CH_DOS, msg,len, (void **) &msgdos)) < 0 || !msgdos) { + DEBUG(3,("Conversion failed, sending message in UNIX charset\n")); + SSVAL(p, 0, len); p += 2; + memcpy(p, msg, len); + p += len; + } else { + SSVAL(p, 0, lendos); p += 2; + memcpy(p, msgdos, lendos); + p += lendos; + SAFE_FREE(msgdos); + } cli_setup_bcc(cli, p); cli_send_smb(cli); -- cgit From 940a114058de6488bc4212a006442fe2899a5f0a Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 21 Mar 2003 21:43:54 +0000 Subject: Add more mappings to the nterr->errno mapping table. It should be fairly complete now. (This used to be commit 72bb5615f3eef1c5b27716dfcabe4c8288729458) --- source3/libsmb/clierror.c | 78 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 75 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 12a7b5dba1..3889976070 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client error handling routines Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Jelmer Vernooij 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -220,16 +221,87 @@ static struct { int error; } nt_errno_map[] = { {NT_STATUS_ACCESS_VIOLATION, EACCES}, - {NT_STATUS_NO_SUCH_FILE, ENOENT}, - {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, {NT_STATUS_INVALID_HANDLE, EBADF}, - {NT_STATUS_NO_MEMORY, ENOMEM}, {NT_STATUS_ACCESS_DENIED, EACCES}, {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, {NT_STATUS_SHARING_VIOLATION, EBUSY}, {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, {NT_STATUS_PATH_NOT_COVERED, ENOENT}, + {NT_STATUS_UNSUCCESSFUL, EINVAL}, + {NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, + {NT_STATUS_IN_PAGE_ERROR, EFAULT}, + {NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, + {NT_STATUS_TIMER_NOT_CANCELED, ETIME}, + {NT_STATUS_INVALID_PARAMETER, EINVAL}, + {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, + {NT_STATUS_NO_SUCH_FILE, ENOENT}, + {NT_STATUS_END_OF_FILE, ENODATA}, + {NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM}, + {NT_STATUS_NONEXISTENT_SECTOR, ESPIPE}, + {NT_STATUS_NO_MEMORY, ENOMEM}, + {NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE}, + {NT_STATUS_NOT_MAPPED_VIEW, EINVAL}, + {NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE}, + {NT_STATUS_ACCESS_DENIED, EACCES}, + {NT_STATUS_BUFFER_TOO_SMALL, ENOBUFS}, + {NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, + {NT_STATUS_WRONG_PASSWORD, EACCES}, + {NT_STATUS_LOGON_FAILURE, EACCES}, + {NT_STATUS_INVALID_WORKSTATION, EACCES}, + {NT_STATUS_INVALID_LOGON_HOURS, EACCES}, + {NT_STATUS_PASSWORD_EXPIRED, EACCES}, + {NT_STATUS_ACCOUNT_DISABLED, EACCES}, + {NT_STATUS_DISK_FULL, ENOSPC}, + {NT_STATUS_INVALID_PIPE_STATE, EPIPE}, + {NT_STATUS_PIPE_BUSY, EPIPE}, + {NT_STATUS_PIPE_DISCONNECTED, EPIPE}, + {NT_STATUS_PIPE_NOT_AVAILABLE, ENOSYS}, + {NT_STATUS_FILE_IS_A_DIRECTORY, EISDIR}, + {NT_STATUS_NOT_SUPPORTED, ENOSYS}, + {NT_STATUS_NOT_A_DIRECTORY, ENOTDIR}, + {NT_STATUS_DIRECTORY_NOT_EMPTY, ENOTEMPTY}, + {NT_STATUS_NETWORK_UNREACHABLE, ENETUNREACH}, + {NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH}, + {NT_STATUS_CONNECTION_ABORTED, ECONNABORTED}, + {NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED}, + {NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, + {NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, + {NT_STATUS_TOO_MANY_LINKS, EMLINK}, + {NT_STATUS_NETWORK_BUSY, EBUSY}, + {NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, + {NT_STATUS_DLL_NOT_FOUND, ELIBACC}, + {NT_STATUS_PIPE_BROKEN, EPIPE}, + {NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED}, + {NT_STATUS_NETWORK_ACCESS_DENIED, EACCES}, + {NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE}, + {NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO}, + {NT_STATUS_NO_MEDIA, ENOMEDIUM}, + {NT_STATUS_FLOAT_OVERFLOW, ERANGE}, + {NT_STATUS_FLOAT_UNDERFLOW, ERANGE}, + {NT_STATUS_INTEGER_OVERFLOW, ERANGE}, + {NT_STATUS_MEDIA_WRITE_PROTECTED, EROFS}, + {NT_STATUS_PIPE_CONNECTED, EISCONN}, + {NT_STATUS_MEMORY_NOT_ALLOCATED, EFAULT}, + {NT_STATUS_FLOAT_INEXACT_RESULT, ERANGE}, + {NT_STATUS_ILL_FORMED_PASSWORD, EACCES}, + {NT_STATUS_PASSWORD_RESTRICTION, EACCES}, + {NT_STATUS_ACCOUNT_RESTRICTION, EACCES}, + {NT_STATUS_PORT_CONNECTION_REFUSED, ECONNREFUSED}, + {NT_STATUS_NAME_TOO_LONG, ENAMETOOLONG}, + {NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN}, + {NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED}, + {NT_STATUS_CONNECTION_RESET, ENETRESET}, + {NT_STATUS_IP_ADDRESS_CONFLICT1, ENOTUNIQ}, + {NT_STATUS_IP_ADDRESS_CONFLICT2, ENOTUNIQ}, + {NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE}, + {NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT}, + {NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE}, + {NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, + {NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, + {NT_STATUS_RETRY, EAGAIN}, + {NT_STATUS_NET_WRITE_FAULT, ECOMM}, + {NT_STATUS(0), 0} }; -- cgit From ab25a258c0c5486e513f0ab5e04c1923e9355a26 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 21 Mar 2003 22:31:25 +0000 Subject: Patch from colo (on IRC) to get libsmbclient building due to pstring/fstring issues. Also pick up these link failures at compile time (rather than runtime). Andrew Bartlett (This used to be commit 23c7342bc40daffbcd70ef04727cae2c2b2c366b) --- source3/libsmb/libsmbclient.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 5ceb36795a..440527cd9d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -492,9 +492,9 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -821,9 +821,9 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -920,11 +920,11 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, smbc_parse_path(ocontext, oname, server1, share1, path1, user1, password1); - if (user1[0] == (char)0) pstrcpy(user1, ocontext->user); + if (user1[0] == (char)0) fstrcpy(user1, ocontext->user); smbc_parse_path(ncontext, nname, server2, share2, path2, user2, password2); - if (user2[0] == (char)0) pstrcpy(user2, ncontext->user); + if (user2[0] == (char)0) fstrcpy(user2, ncontext->user); if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { @@ -936,7 +936,7 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, } - pstrcpy(workgroup, ocontext->workgroup); + fstrcpy(workgroup, ocontext->workgroup); /* HELP !!! Which workgroup should I use ? Or are they always the same -- Tom */ srv = smbc_server(ocontext, server1, share1, workgroup, user1, password1); if (!srv) { @@ -1119,9 +1119,9 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -1422,9 +1422,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); dir = malloc(sizeof(*dir)); @@ -1893,9 +1893,9 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -1980,9 +1980,9 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -2327,9 +2327,9 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_li smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -2380,9 +2380,9 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); -- cgit From 2da9a44ba014f74835aea95d50de8ab043d2b6c5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 21 Mar 2003 22:38:04 +0000 Subject: Clobber the 'SAFETY_MARGIN' in libsmb. Andrew Bartlett (This used to be commit 05a63bd17e4c35979b3864b0969b2bfd945335d9) --- source3/libsmb/clientgen.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d969193089..e067e92f8d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -259,9 +259,6 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - /* initialise signing */ - cli_null_set_signing(cli); - if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; @@ -274,6 +271,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); + /* just becouse we over-allocate, doesn't mean it's right to use it */ + clobber_region(__FUNCTION__, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); + clobber_region(__FUNCTION__, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); + + /* initialise signing */ + cli_null_set_signing(cli); + cli->nt_pipe_fnum = 0; cli->initialised = 1; -- cgit From 63894f2b5a5b11e946bbc1f53fee20d003862dc6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Mar 2003 09:27:42 +0000 Subject: Merge fixes to libsmbclient (fstring/pstring) from HEAD. Andrew Bartlett (This used to be commit 6bf04c41ed88528345f6bb19d48f5909753a8322) --- source3/libsmb/libsmbclient.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 5ceb36795a..440527cd9d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -492,9 +492,9 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -821,9 +821,9 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -920,11 +920,11 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, smbc_parse_path(ocontext, oname, server1, share1, path1, user1, password1); - if (user1[0] == (char)0) pstrcpy(user1, ocontext->user); + if (user1[0] == (char)0) fstrcpy(user1, ocontext->user); smbc_parse_path(ncontext, nname, server2, share2, path2, user2, password2); - if (user2[0] == (char)0) pstrcpy(user2, ncontext->user); + if (user2[0] == (char)0) fstrcpy(user2, ncontext->user); if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { @@ -936,7 +936,7 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, } - pstrcpy(workgroup, ocontext->workgroup); + fstrcpy(workgroup, ocontext->workgroup); /* HELP !!! Which workgroup should I use ? Or are they always the same -- Tom */ srv = smbc_server(ocontext, server1, share1, workgroup, user1, password1); if (!srv) { @@ -1119,9 +1119,9 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -1422,9 +1422,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); dir = malloc(sizeof(*dir)); @@ -1893,9 +1893,9 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -1980,9 +1980,9 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -2327,9 +2327,9 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_li smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); @@ -2380,9 +2380,9 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - if (user[0] == (char)0) pstrcpy(user, context->user); + if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); -- cgit From b33cee92ed7e6729291616778963037f0d2f2f30 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Mar 2003 10:53:20 +0000 Subject: Fix compile on IA64 by noting that this should be the integer, not a pointer to the integer for SIVAL(). (This used to be commit 5e20868fadc4e01ea09639bc57c51d1eb687f78c) --- source3/libsmb/ntlmssp_sign.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index f51d532319..8f6bd0c691 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -100,7 +100,7 @@ static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_stat HMACMD5Context ctx; char seq_num[4]; uchar digest[16]; - SIVAL(seq_num, 0, &ntlmssp_state->ntlmssp_seq_num); + SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); hmac_md5_update(seq_num, 4, &ctx); -- cgit From b508fdfc231b73d671b0c283e54532b9f14d7db6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Mar 2003 10:54:03 +0000 Subject: Fix compile on IA64 by noting that this should be the integer, not a pointer to the integer for SIVAL(). (This used to be commit e8b4b136669e7e415557956d698c66c254b28ec1) --- source3/libsmb/ntlmssp_sign.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index f51d532319..8f6bd0c691 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -100,7 +100,7 @@ static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_stat HMACMD5Context ctx; char seq_num[4]; uchar digest[16]; - SIVAL(seq_num, 0, &ntlmssp_state->ntlmssp_seq_num); + SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); hmac_md5_update(seq_num, 4, &ctx); -- cgit From a38e5e6850220fc1a0afa5097359c05458e1ae41 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Mar 2003 13:06:52 +0000 Subject: Small clenaup patches: - safe_string.h - don't assume that __FUNCTION__ is available - process.c - use new workaround from safe_string.h for the same - util.c - Show how many bytes we smb_panic()ed trying to smb_xmalloc() - gencache.c - Keep valgrind quiet by always null terminating. - clistr.c - Add copyright - srvstr.h - move srvstr_push into a .c file again, as a real function. - srvstr.c - revive, with 'safe' checked srvstr_push - loadparm.c - set a default for the display charset. Andrew Bartlett (This used to be commit a7eba37aadeb0b04cb1bd89deddb58be8aba825c) --- source3/libsmb/clistr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 97a3fa6cc9..c61445c073 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -2,7 +2,8 @@ Unix SMB/CIFS implementation. client string routines Copyright (C) Andrew Tridgell 2001 - + Copyright (C) Andrew Bartlett 2003 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or -- cgit From 1f499a79f5468e87d26b60ffe3aa375b91cadbef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Mar 2003 13:47:42 +0000 Subject: (merge from HEAD) Small clenaup patches: - safe_string.h - don't assume that __FUNCTION__ is available - process.c - use new workaround from safe_string.h for the same - util.c - Show how many bytes we smb_panic()ed trying to smb_xmalloc() - gencache.c - Keep valgrind quiet by always null terminating. - clistr.c - Add copyright - srvstr.h - move srvstr_push into a .c file again, as a real function. - srvstr.c - revive, with 'safe' checked srvstr_push - loadparm.c - set a default for the display charset. - connection.c - use safe_strcpy() Andrew Bartlett (This used to be commit c91e76bddbe1244ddc8d12b092eba875834029ac) --- source3/libsmb/clistr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 97a3fa6cc9..bba9fcf15a 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client string routines Copyright (C) Andrew Tridgell 2001 + Copyright (C) Andrew Bartlett 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 38794e945effa1b0626642ea1a80b74d9cf7e8f2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Mar 2003 19:39:31 +0000 Subject: Don't use errno's when they're not available (This used to be commit b757a4374832d76500a889e4785622320881018d) --- source3/libsmb/clierror.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 3889976070..4f80f274d9 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -232,12 +232,19 @@ static struct { {NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, {NT_STATUS_IN_PAGE_ERROR, EFAULT}, {NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, +#ifdef ETIME {NT_STATUS_TIMER_NOT_CANCELED, ETIME}, +#endif {NT_STATUS_INVALID_PARAMETER, EINVAL}, {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, {NT_STATUS_NO_SUCH_FILE, ENOENT}, +#ifdef ENODATA {NT_STATUS_END_OF_FILE, ENODATA}, +#endif +#ifdef ENOMEDIUM {NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM}, + {NT_STATUS_NO_MEDIA, ENOMEDIUM}, +#endif {NT_STATUS_NONEXISTENT_SECTOR, ESPIPE}, {NT_STATUS_NO_MEMORY, ENOMEM}, {NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE}, @@ -270,13 +277,16 @@ static struct { {NT_STATUS_TOO_MANY_LINKS, EMLINK}, {NT_STATUS_NETWORK_BUSY, EBUSY}, {NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, +#ifdef ELIBACC {NT_STATUS_DLL_NOT_FOUND, ELIBACC}, +#endif {NT_STATUS_PIPE_BROKEN, EPIPE}, {NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED}, {NT_STATUS_NETWORK_ACCESS_DENIED, EACCES}, {NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE}, +#ifdef EPROTO {NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO}, - {NT_STATUS_NO_MEDIA, ENOMEDIUM}, +#endif {NT_STATUS_FLOAT_OVERFLOW, ERANGE}, {NT_STATUS_FLOAT_UNDERFLOW, ERANGE}, {NT_STATUS_INTEGER_OVERFLOW, ERANGE}, @@ -292,15 +302,19 @@ static struct { {NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN}, {NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED}, {NT_STATUS_CONNECTION_RESET, ENETRESET}, +#ifdef ENOTUNIQ {NT_STATUS_IP_ADDRESS_CONFLICT1, ENOTUNIQ}, {NT_STATUS_IP_ADDRESS_CONFLICT2, ENOTUNIQ}, +#endif {NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE}, {NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT}, {NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE}, {NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, {NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, {NT_STATUS_RETRY, EAGAIN}, +#ifdef ECOMM {NT_STATUS_NET_WRITE_FAULT, ECOMM}, +#endif {NT_STATUS(0), 0} }; -- cgit From 4985533fd3ca47d6ee2ac293ceb810fa1857abd5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Mar 2003 20:49:55 +0000 Subject: Use FUNCTION_MACRO, not __FUNCTION__ (This used to be commit 6df38e250af1a8e7213ad66342c71c52ce118a12) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e067e92f8d..0da9a8932f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -272,8 +272,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->inbuf, 0, cli->bufsize); /* just becouse we over-allocate, doesn't mean it's right to use it */ - clobber_region(__FUNCTION__, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); - clobber_region(__FUNCTION__, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); + clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); + clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); /* initialise signing */ cli_null_set_signing(cli); -- cgit From dea7597767e690168e9485dfc2efabaab2dfb4cb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Mar 2003 22:04:58 +0000 Subject: Don't use EDQUOT on systems where it's not available (This used to be commit 2e1e5719f188a933e6b691fbd48037a0d29497e4) --- source3/libsmb/clierror.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 4f80f274d9..b66a6bcba8 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -231,7 +231,12 @@ static struct { {NT_STATUS_UNSUCCESSFUL, EINVAL}, {NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, {NT_STATUS_IN_PAGE_ERROR, EFAULT}, +#ifdef EDQUOT {NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, + {NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, + {NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, + {NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, +#endif #ifdef ETIME {NT_STATUS_TIMER_NOT_CANCELED, ETIME}, #endif @@ -252,7 +257,6 @@ static struct { {NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE}, {NT_STATUS_ACCESS_DENIED, EACCES}, {NT_STATUS_BUFFER_TOO_SMALL, ENOBUFS}, - {NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, {NT_STATUS_WRONG_PASSWORD, EACCES}, {NT_STATUS_LOGON_FAILURE, EACCES}, {NT_STATUS_INVALID_WORKSTATION, EACCES}, @@ -272,8 +276,6 @@ static struct { {NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH}, {NT_STATUS_CONNECTION_ABORTED, ECONNABORTED}, {NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED}, - {NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, - {NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, {NT_STATUS_TOO_MANY_LINKS, EMLINK}, {NT_STATUS_NETWORK_BUSY, EBUSY}, {NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, -- cgit From 1ce67b7672ab58afd76d0ad9cc0343e688c6770d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Mar 2003 23:25:09 +0000 Subject: Valgrind found a few memory leaks! Andrew Bartlett (This used to be commit fb680f610ceb9a0f350c99456cf7ab1a507543fe) --- source3/libsmb/namecache.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 40777011a1..d3541b7719 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -118,6 +118,7 @@ BOOL namecache_store(const char *name, int name_type, time_t expiry; char *key, *value_string; int i; + BOOL ret; /* * we use gecache call to avoid annoying debug messages about @@ -152,10 +153,17 @@ BOOL namecache_store(const char *name, int name_type, * First, store the number of ip addresses and then * place each single ip */ - ipstr_list_make(&value_string, ip_list, num_names); + if (!ipstr_list_make(&value_string, ip_list, num_names)) { + SAFE_FREE(key); + SAFE_FREE(value_string); + return False; + } /* set the entry */ - return (gencache_set(key, value_string, expiry)); + ret = gencache_set(key, value_string, expiry); + SAFE_FREE(key); + SAFE_FREE(value_string); + return ret; } -- cgit From 79f3265893a60c9109b02407d15d13f18925c751 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Mar 2003 23:32:50 +0000 Subject: (merge from HEAD) Valgrind found some memory leaks! (This used to be commit 8315b9c3119dde62aeb72ad5e20f63aee89abd0b) --- source3/libsmb/namecache.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 40777011a1..d3541b7719 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -118,6 +118,7 @@ BOOL namecache_store(const char *name, int name_type, time_t expiry; char *key, *value_string; int i; + BOOL ret; /* * we use gecache call to avoid annoying debug messages about @@ -152,10 +153,17 @@ BOOL namecache_store(const char *name, int name_type, * First, store the number of ip addresses and then * place each single ip */ - ipstr_list_make(&value_string, ip_list, num_names); + if (!ipstr_list_make(&value_string, ip_list, num_names)) { + SAFE_FREE(key); + SAFE_FREE(value_string); + return False; + } /* set the entry */ - return (gencache_set(key, value_string, expiry)); + ret = gencache_set(key, value_string, expiry); + SAFE_FREE(key); + SAFE_FREE(value_string); + return ret; } -- cgit From 1f5e93e2e7dccb16da3b733fffd401867b2ea3b9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 23 Mar 2003 13:03:25 +0000 Subject: NTLM Authentication: - Add a 'privileged' mode to Winbindd. This is achieved by means of a directory under lockdir, that the admin can change the group access for. - This mode is now required to access with 'CRAP' authentication feature. - This *will* break the current SQUID helper, so I've fixed up our ntlm_auth replacement: - Update our NTLMSSP code to cope with 'datagram' mode, where we don't get a challenge. - Use this to make our ntlm_auth utility suitable for use in current Squid 2.5 servers. - Tested - works for Win2k clients, but not Win9X at present. NTLMSSP updates are needed. - Now uses fgets(), not x_fgets() to cope with Squid environment (I think somthing to do with non-blocking stdin). - Add much more robust connection code to wb_common.c - it will not connect to a server of a different protocol version, and it will automatically try and reconnect to the 'privileged' pipe if possible. - This could help with 'privileged' idmap operations etc in future. - Add a generic HEX encode routine to util_str.c, - fix a small line of dodgy C in StrnCpy_fn() - Correctly pull our 'session key' out of the info3 from th the DC. This is used in both the auth code, and in for export over the winbind pipe to ntlm_auth. - Given the user's challenge/response and access to the privileged pipe, allow external access to the 'session key'. To be used for MSCHAPv2 integration. Andrew Bartlett (This used to be commit dcdc75ebd89f504a0f6e3a3bc5b43298858d276b) --- source3/libsmb/ntlmssp.c | 50 +++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 5722b8efcd..0cd1ac33ec 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -121,7 +121,8 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, { DATA_BLOB struct_blob; fstring dnsname, dnsdomname; - uint32 ntlmssp_command, neg_flags, chal_flags; + uint32 neg_flags = 0; + uint32 ntlmssp_command, chal_flags; char *cliname=NULL, *domname=NULL; const uint8 *cryptkey; const char *target_name; @@ -131,20 +132,24 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, file_save("ntlmssp_negotiate.dat", request.data, request.length); #endif - if (!msrpc_parse(&request, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname)) { - return NT_STATUS_INVALID_PARAMETER; + if (request.length) { + if (!msrpc_parse(&request, "CddAA", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &cliname, + &domname)) { + DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); + dump_data(2, request.data, request.length); + return NT_STATUS_INVALID_PARAMETER; + } + + SAFE_FREE(cliname); + SAFE_FREE(domname); + + debug_ntlmssp_flags(neg_flags); } - - SAFE_FREE(cliname); - SAFE_FREE(domname); - - debug_ntlmssp_flags(neg_flags); - + cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); data_blob_free(&ntlmssp_state->chal); @@ -268,6 +273,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &ntlmssp_state->workstation, &sess_key, &neg_flags)) { + DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); + dump_data(2, request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } @@ -357,13 +364,19 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, uint32 ntlmssp_command; *reply = data_blob(NULL, 0); - if (!msrpc_parse(&request, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_INVALID_PARAMETER; + if (request.length) { + if (!msrpc_parse(&request, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + return NT_STATUS_INVALID_PARAMETER; + } + } else { + /* 'datagram' mode - no neg packet */ + ntlmssp_command = NTLMSSP_NEGOTIATE; } if (ntlmssp_command != ntlmssp_state->expected_state) { + DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); return NT_STATUS_INVALID_PARAMETER; } @@ -372,6 +385,7 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, } else if (ntlmssp_command == NTLMSSP_AUTH) { return ntlmssp_server_auth(ntlmssp_state, request, reply); } else { + DEBUG(1, ("unknown NTLMSSP command %u\n", ntlmssp_command, ntlmssp_state->expected_state)); return NT_STATUS_INVALID_PARAMETER; } } -- cgit From 53beee9e5675a59c67d9ecfbaec50dca4ac01750 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Mar 2003 09:54:13 +0000 Subject: (merge from HEAD) NTLM Authentication: - Add a 'privileged' mode to Winbindd. This is achieved by means of a directory under lockdir, that the admin can change the group access for. - This mode is now required to access with 'CRAP' authentication feature. - This *will* break the current SQUID helper, so I've fixed up our ntlm_auth replacement: - Update our NTLMSSP code to cope with 'datagram' mode, where we don't get a challenge. - Use this to make our ntlm_auth utility suitable for use in current Squid 2.5 servers. - Tested - works for Win2k clients, but not Win9X at present. NTLMSSP updates are needed. - Now uses fgets(), not x_fgets() to cope with Squid environment (I think somthing to do with non-blocking stdin). - Add much more robust connection code to wb_common.c - it will not connect to a server of a different protocol version, and it will automatically try and reconnect to the 'privileged' pipe if possible. - This could help with 'privileged' idmap operations etc in future. - Add a generic HEX encode routine to util_str.c, - fix a small line of dodgy C in StrnCpy_fn() - Correctly pull our 'session key' out of the info3 from th the DC. This is used in both the auth code, and in for export over the winbind pipe to ntlm_auth. - Given the user's challenge/response and access to the privileged pipe, allow external access to the 'session key'. To be used for MSCHAPv2 integration. Andrew Bartlett (This used to be commit ec071ca3dcbd3881dc08e6a8d7ac2ff0bcd57664) --- source3/libsmb/ntlmssp.c | 50 +++++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 5722b8efcd..0cd1ac33ec 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -121,7 +121,8 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, { DATA_BLOB struct_blob; fstring dnsname, dnsdomname; - uint32 ntlmssp_command, neg_flags, chal_flags; + uint32 neg_flags = 0; + uint32 ntlmssp_command, chal_flags; char *cliname=NULL, *domname=NULL; const uint8 *cryptkey; const char *target_name; @@ -131,20 +132,24 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, file_save("ntlmssp_negotiate.dat", request.data, request.length); #endif - if (!msrpc_parse(&request, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname)) { - return NT_STATUS_INVALID_PARAMETER; + if (request.length) { + if (!msrpc_parse(&request, "CddAA", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &cliname, + &domname)) { + DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); + dump_data(2, request.data, request.length); + return NT_STATUS_INVALID_PARAMETER; + } + + SAFE_FREE(cliname); + SAFE_FREE(domname); + + debug_ntlmssp_flags(neg_flags); } - - SAFE_FREE(cliname); - SAFE_FREE(domname); - - debug_ntlmssp_flags(neg_flags); - + cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); data_blob_free(&ntlmssp_state->chal); @@ -268,6 +273,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &ntlmssp_state->workstation, &sess_key, &neg_flags)) { + DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); + dump_data(2, request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } @@ -357,13 +364,19 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, uint32 ntlmssp_command; *reply = data_blob(NULL, 0); - if (!msrpc_parse(&request, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_INVALID_PARAMETER; + if (request.length) { + if (!msrpc_parse(&request, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + return NT_STATUS_INVALID_PARAMETER; + } + } else { + /* 'datagram' mode - no neg packet */ + ntlmssp_command = NTLMSSP_NEGOTIATE; } if (ntlmssp_command != ntlmssp_state->expected_state) { + DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); return NT_STATUS_INVALID_PARAMETER; } @@ -372,6 +385,7 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, } else if (ntlmssp_command == NTLMSSP_AUTH) { return ntlmssp_server_auth(ntlmssp_state, request, reply); } else { + DEBUG(1, ("unknown NTLMSSP command %u\n", ntlmssp_command, ntlmssp_state->expected_state)); return NT_STATUS_INVALID_PARAMETER; } } -- cgit From a4d819e1e8a749f92c4e3fd39e8f025809e9d5c0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 24 Mar 2003 16:15:10 +0000 Subject: Add mapping for Bad Network Path (This used to be commit 1481cd9ecf1658312424c193d8cd3632766eb058) --- source3/libsmb/clierror.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index b66a6bcba8..cea736ef18 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -231,6 +231,7 @@ static struct { {NT_STATUS_UNSUCCESSFUL, EINVAL}, {NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, {NT_STATUS_IN_PAGE_ERROR, EFAULT}, + {NT_STATUS_BAD_NETWORK_NAME, ENOENT}, #ifdef EDQUOT {NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, {NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, -- cgit From c0efc3536f9b4dcb9978b198d4b143267948da36 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Mar 2003 10:29:22 +0000 Subject: Fix debug (thanks metze) Andrew Bartlett (This used to be commit 5562f1865c90e3f52a3178d9d9ded60909bbe5f0) --- source3/libsmb/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 0cd1ac33ec..d54655d17f 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -385,7 +385,7 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, } else if (ntlmssp_command == NTLMSSP_AUTH) { return ntlmssp_server_auth(ntlmssp_state, request, reply); } else { - DEBUG(1, ("unknown NTLMSSP command %u\n", ntlmssp_command, ntlmssp_state->expected_state)); + DEBUG(1, ("unknown NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); return NT_STATUS_INVALID_PARAMETER; } } -- cgit From 250b5f83e94619037063dc2996526d76974e8262 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 28 Mar 2003 21:07:44 +0000 Subject: Some fixes to URL syntax from coolo. (This used to be commit de49c3f48f85519b31e797730eca82cb979098dc) --- source3/libsmb/libsmbclient.c | 87 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 440527cd9d..916e388fe0 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -52,6 +52,82 @@ extern BOOL in_client; */ static int smbc_initialized = 0; +static int +hex2int( unsigned int _char ) +{ + if ( _char >= 'A' && _char <='F') + return _char - 'A' + 10; + if ( _char >= 'a' && _char <='f') + return _char - 'a' + 10; + if ( _char >= '0' && _char <='9') + return _char - '0'; + return -1; +} + +static void +decode_urlpart(char *segment) +{ + int old_length = strlen(segment); + int new_length = 0; + int new_length2 = 0; + int i = 0; + pstring new_segment; + char *new_usegment = 0; + + if ( !old_length ) { + return; + } + + /* make a copy of the old one */ + new_usegment = (char*)malloc( old_length * 3 + 1 ); + + while( i < old_length ) { + int bReencode = False; + unsigned char character = segment[ i++ ]; + if ((character <= ' ') || (character > 127)) + bReencode = True; + + new_usegment [ new_length2++ ] = character; + if (character == '%' ) { + int a = i+1 < old_length ? hex2int( segment[i] ) : -1; + int b = i+1 < old_length ? hex2int( segment[i+1] ) : -1; + if ((a == -1) || (b == -1)) { /* Only replace if sequence is valid */ + /* Contains stray %, make sure to re-encode! */ + bReencode = True; + } else { + /* Valid %xx sequence */ + character = a * 16 + b; /* Replace with value of %dd */ + if (!character) + break; /* Stop at %00 */ + + new_usegment [ new_length2++ ] = (unsigned char) segment[i++]; + new_usegment [ new_length2++ ] = (unsigned char) segment[i++]; + } + } + if (bReencode) { + unsigned int c = character / 16; + new_length2--; + new_usegment [ new_length2++ ] = '%'; + + c += (c > 9) ? ('A' - 10) : '0'; + new_usegment[ new_length2++ ] = c; + + c = character % 16; + c += (c > 9) ? ('A' - 10) : '0'; + new_usegment[ new_length2++ ] = c; + } + + new_segment [ new_length++ ] = character; + } + new_segment [ new_length ] = 0; + + /* this assumes (very safely) that removing %aa sequences + only shortens the string */ + strncpy(segment, new_segment, old_length); + + free(new_usegment); +} + /* * Function to parse a path and turn it into components * @@ -97,7 +173,7 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, p += 2; /* Skip the // or \\ */ if (*p == (char)0) - return 0; + goto decoding; if (*p == '/') { @@ -158,7 +234,7 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, } - if (*p == (char)0) return 0; /* That's it ... */ + if (*p == (char)0) goto decoding; /* That's it ... */ if (!next_token(&p, share, "/", sizeof(fstring))) { @@ -170,6 +246,13 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, all_string_sub(path, "/", "\\", 0); + decoding: + decode_urlpart(path); + decode_urlpart(server); + decode_urlpart(share); + decode_urlpart(user); + decode_urlpart(password); + return 0; } -- cgit From a6fad1ca7220160774148c1caeece45629d87ca6 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 28 Mar 2003 21:41:27 +0000 Subject: More patches from coolo. One of these functions needs to be moved elsewhere so other code can use it. (This used to be commit b988e16b7da824864cac6b69910ade27885e7f50) --- source3/libsmb/libsmbclient.c | 120 +++++++++++++++++++++++++++--------------- 1 file changed, 78 insertions(+), 42 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 916e388fe0..f74a0be7f3 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1475,9 +1475,47 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) } + +/* Return the IP address and workgroup of a master browser on the + network. */ + +static BOOL find_master_ip_bcast(pstring workgroup, struct in_addr *server_ip) +{ + struct in_addr *ip_list; + int i, count; + + /* Go looking for workgroups by broadcasting on the local network */ + + if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + return False; + } + + for (i = count-1; i < count; i++) { + static fstring name; + + DEBUG(0, ("name_status_find %d %s\n", i, inet_ntoa(ip_list[i]))); + + if (!name_status_find("*", 0, 0x1d, ip_list[i], name)) + continue; + + if (!find_master_ip(name, server_ip)) + continue; + + pstrcpy(workgroup, name); + + DEBUG(4, ("found master browser %s, %s\n", + name, inet_ntoa(ip_list[i]))); + + return True; + } + + return False; +} + static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { - fstring server, share, user, password, workgroup; + fstring server, share, user, password; + pstring workgroup; pstring path; SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; @@ -1486,28 +1524,31 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!context || !context->internal || !context->internal->_initialized) { + fprintf(stderr, "no valid context\n"); errno = EINVAL; return NULL; } if (!fname) { - + fprintf(stderr, "no valid fname\n"); errno = EINVAL; return NULL; } if (smbc_parse_path(context, fname, server, share, path, user, password)) { - + fprintf(stderr, "no valid path\n"); errno = EINVAL; return NULL; } + fprintf(stderr, "parsed path: fname='%s' server='%s' share='%s' path='%s'\n", fname, server, share, path); + if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); + pstrcpy(workgroup, context->workgroup); dir = malloc(sizeof(*dir)); @@ -1528,9 +1569,12 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) dir->dir_list = dir->dir_next = dir->dir_end = NULL; if (server[0] == (char)0) { + struct in_addr server_ip; + + fprintf(stderr, "empty server\n"); if (share[0] != (char)0 || path[0] != (char)0) { - + fprintf(stderr, "share %d path %d\n", share[0], path[0]); errno = EINVAL; if (dir) { SAFE_FREE(dir->fname); @@ -1544,48 +1588,40 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) /* first try to get the LMB for our workgroup, and if that fails, */ /* try the DMB */ - if (!(resolve_name(context->workgroup, &rem_ip, 0x1d) || - resolve_name(context->workgroup, &rem_ip, 0x1b))) { - - errno = EINVAL; /* Something wrong with smb.conf? */ - return NULL; + pstrcpy(workgroup, lp_workgroup()); - } - - dir->dir_type = SMBC_WORKGROUP; - - /* find the name of the server ... */ - - if (!name_status_find("*", 0, 0, rem_ip, server)) { - - DEBUG(0,("Could not get the name of local/domain master browser for server %s\n", server)); - errno = EINVAL; - return NULL; - - } - - /* - * Get a connection to IPC$ on the server if we do not already have one - */ - - srv = smbc_server(context, server, "IPC$", workgroup, user, password); - - if (!srv) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - + if (!find_master_ip(lp_workgroup(), &server_ip)) { + DEBUG(4, ("Unable to find master browser for workgroup %s\n", + workgroup)); + if (!find_master_ip_bcast(workgroup, &server_ip)) { + DEBUG(4, ("Unable to find master browser by " + "broadcast\n")); + errno = ENOENT; return NULL; - - } - + } + } + + /* + * Get a connection to IPC$ on the server if we do not already have one + */ + + srv = smbc_server(context, inet_ntoa(server_ip), "IPC$", workgroup, user, password); + + if (!srv) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; + } + dir->srv = srv; + dir->dir_type = SMBC_WORKGROUP; /* Now, list the stuff ... */ - if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn, + if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_fn, (void *)dir)) { if (dir) { @@ -2655,7 +2691,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) /* Do we still need this ? */ DEBUGLEVEL = 10; - setup_logging( "libsmbclient", False); + setup_logging( "libsmbclient", True); /* Here we would open the smb.conf file if needed ... */ -- cgit From dfcf1634bc84ff00f8241c326084a705989fb099 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 29 Mar 2003 12:44:42 +0000 Subject: added a simple test for the old SMBtcon interface (This used to be commit c95ae394c5dfe5e0fcc658119213b17bcb95fab5) --- source3/libsmb/cliconnect.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 763878f9b3..75dcd62c2f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -750,7 +750,6 @@ BOOL cli_ulogoff(struct cli_state *cli) /**************************************************************************** Send a tconX. ****************************************************************************/ - BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { @@ -1343,3 +1342,45 @@ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); return True; } + + + + + +/**************************************************************************** + Send an old style tcon. +****************************************************************************/ +NTSTATUS cli_raw_tcon(struct cli_state *cli, + const char *service, const char *pass, const char *dev, + uint16 *max_xmit, uint16 *tid) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 0, 0, True); + SCVAL(cli->outbuf,smb_com,SMBtcon); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN); + *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN); + *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN); + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } + + *max_xmit = SVAL(cli->inbuf, smb_vwv0); + *tid = SVAL(cli->inbuf, smb_vwv1); + + return NT_STATUS_OK; +} -- cgit From bcd9a08802f9f4f4b68741fb51574d3944cb4040 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Mar 2003 02:52:47 +0000 Subject: Don't modify the incoming packet when checking the signiture. Andrew Bartlett (This used to be commit 7064edf8534a6098fc4990bc516fcb45f4ff44bb) --- source3/libsmb/smb_signing.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c713418e82..9bbf7ef91c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -79,7 +79,7 @@ static void mark_packet_signed(struct cli_state *cli) static BOOL signing_good(struct cli_state *cli, BOOL good) { DEBUG(10, ("got SMB signature of\n")); - dump_data(10,&cli->outbuf[smb_ss_field] , 8); + dump_data(10,&cli->inbuf[smb_ss_field] , 8); if (good && !cli->sign_info.doing_signing) { cli->sign_info.doing_signing = True; @@ -147,31 +147,47 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) BOOL good; unsigned char calc_md5_mac[16]; unsigned char server_sent_mac[8]; + unsigned char sequence_buf[8]; struct MD5Context md5_ctx; struct smb_basic_signing_context *data = cli->sign_info.signing_context; + const size_t offset_end_of_sig = (smb_ss_field + 8); /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. */ - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - DEBUG(10, ("got SMB signature of\n")); - dump_data(10, server_sent_mac, 8); + SIVAL(sequence_buf, 0, data->reply_seq_num); + SIVAL(sequence_buf, 4, 0); - SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); - SIVAL(cli->inbuf, smb_ss_field + 4, 0); + if (smb_len(cli->inbuf) < (offset_end_of_sig - 4)) { + DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); + return False; + } + /* get a copy of the server-sent mac */ + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); - MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, + smb_len(cli->inbuf) - (offset_end_of_sig - 4)); MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + if (!good) { + DEBUG(5, ("BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); + } return signing_good(cli, good); } @@ -213,7 +229,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); - /* Initialize the sequence number */ + /* Initialise the sequence number */ data->send_seq_num = 0; cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; @@ -348,7 +364,7 @@ static void cli_null_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. @note Used as an initialisation only - it will not correctly - shut down a real signing mechinism + shut down a real signing mechanism */ BOOL cli_null_set_signing(struct cli_state *cli) -- cgit From 873284d90bb7f6f0862acf27544eadeee853972a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Mar 2003 02:58:33 +0000 Subject: Merge from HEAD - leave the SMB buffer untouched when checking it's SMB sig. Andrew Bartlett (This used to be commit 3d4c4b6cb3f4850f0801f140ea3dad2c8423ee52) --- source3/libsmb/smb_signing.c | 36 ++++++++++++++++++++++++++---------- 1 file changed, 26 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c713418e82..9bbf7ef91c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -79,7 +79,7 @@ static void mark_packet_signed(struct cli_state *cli) static BOOL signing_good(struct cli_state *cli, BOOL good) { DEBUG(10, ("got SMB signature of\n")); - dump_data(10,&cli->outbuf[smb_ss_field] , 8); + dump_data(10,&cli->inbuf[smb_ss_field] , 8); if (good && !cli->sign_info.doing_signing) { cli->sign_info.doing_signing = True; @@ -147,31 +147,47 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) BOOL good; unsigned char calc_md5_mac[16]; unsigned char server_sent_mac[8]; + unsigned char sequence_buf[8]; struct MD5Context md5_ctx; struct smb_basic_signing_context *data = cli->sign_info.signing_context; + const size_t offset_end_of_sig = (smb_ss_field + 8); /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. */ - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - DEBUG(10, ("got SMB signature of\n")); - dump_data(10, server_sent_mac, 8); + SIVAL(sequence_buf, 0, data->reply_seq_num); + SIVAL(sequence_buf, 4, 0); - SIVAL(cli->inbuf, smb_ss_field, data->reply_seq_num); - SIVAL(cli->inbuf, smb_ss_field + 4, 0); + if (smb_len(cli->inbuf) < (offset_end_of_sig - 4)) { + DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); + return False; + } + /* get a copy of the server-sent mac */ + memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); + /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ MD5Init(&md5_ctx); MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); - MD5Update(&md5_ctx, cli->inbuf + 4, smb_len(cli->inbuf)); + MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, + smb_len(cli->inbuf) - (offset_end_of_sig - 4)); MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + if (!good) { + DEBUG(5, ("BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); + } return signing_good(cli, good); } @@ -213,7 +229,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); - /* Initialize the sequence number */ + /* Initialise the sequence number */ data->send_seq_num = 0; cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; @@ -348,7 +364,7 @@ static void cli_null_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. @note Used as an initialisation only - it will not correctly - shut down a real signing mechinism + shut down a real signing mechanism */ BOOL cli_null_set_signing(struct cli_state *cli) -- cgit From cb830f05ae4ab5057209fb1b7c68bae450e78b22 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Mar 2003 09:45:44 +0000 Subject: added simple tests for SMBchkpath and SMBioctl (This used to be commit ca982a9f1d6485e2d388d4b2e9c13806736ad91e) --- source3/libsmb/clifile.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d86f36405d..4eb5efe193 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -942,7 +942,6 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) /**************************************************************************** Check for existance of a dir. ****************************************************************************/ - BOOL cli_chkpath(struct cli_state *cli, const char *path) { pstring path2; @@ -1049,3 +1048,34 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) return SVAL(cli->inbuf,smb_vwv0); } + + +/* + send a raw ioctl - used by the torture code +*/ +NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *blob) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 3, 0, True); + SCVAL(cli->outbuf,smb_com,SMBioctl); + cli_setup_packet(cli); + + SSVAL(cli->outbuf, smb_vwv0, fnum); + SSVAL(cli->outbuf, smb_vwv1, code>>16); + SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF)); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } + + *blob = data_blob(NULL, 0); + + return NT_STATUS_OK; +} -- cgit From 494f339ca8c726e1c91ce95c61eae2cb765c35b5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 2 Apr 2003 17:04:33 +0000 Subject: Add const (from a patch by Stephan Kulow ) (This used to be commit 8b5ad24231e5001e612c5fd4bbde2762caef5856) --- source3/libsmb/libsmb_cache.c | 8 ++++---- source3/libsmb/libsmbclient.c | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index b1620042f3..67dc686b48 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -50,8 +50,8 @@ struct smbc_server_cache { * This function is only used if the external cache is not enabled */ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, - char * server, char * share, - char * workgroup, char * username) + const char * server, const char * share, + const char * workgroup, const char * username) { struct smbc_server_cache * srvcache = NULL; @@ -108,8 +108,8 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, * returns server_fd on success, -1 on error (not found) * This function is only used if the external cache is not enabled */ -static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, char * server, - char * share, char * workgroup, char * user) +static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, + const char * share, const char * workgroup, const char * user) { struct smbc_server_cache * srv = NULL; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f74a0be7f3..1da55ed4bd 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -350,7 +350,7 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) */ SMBCSRV *smbc_server(SMBCCTX *context, - char *server, char *share, + const char *server, const char *share, char *workgroup, char *username, char *password) { @@ -358,7 +358,8 @@ SMBCSRV *smbc_server(SMBCCTX *context, int auth_called = 0; struct cli_state c; struct nmb_name called, calling; - char *p, *server_n = server; + char *p; + const char *server_n = server; fstring group; pstring ipenv; struct in_addr ip; @@ -1524,27 +1525,27 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!context || !context->internal || !context->internal->_initialized) { - fprintf(stderr, "no valid context\n"); + DEBUG(4, ("no valid context\n")); errno = EINVAL; return NULL; } if (!fname) { - fprintf(stderr, "no valid fname\n"); + DEBUG(4, ("no valid fname\n")); errno = EINVAL; return NULL; } if (smbc_parse_path(context, fname, server, share, path, user, password)) { - fprintf(stderr, "no valid path\n"); + DEBUG(4, ("no valid path\n")); errno = EINVAL; return NULL; } - fprintf(stderr, "parsed path: fname='%s' server='%s' share='%s' path='%s'\n", fname, server, share, path); + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s'\n", fname, server, share, path)); if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1571,10 +1572,10 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (server[0] == (char)0) { struct in_addr server_ip; - fprintf(stderr, "empty server\n"); + DEBUG(4, ("empty server\n")); if (share[0] != (char)0 || path[0] != (char)0) { - fprintf(stderr, "share %d path %d\n", share[0], path[0]); + DEBUG(4,("share %d path %d\n", share[0], path[0])); errno = EINVAL; if (dir) { SAFE_FREE(dir->fname); @@ -2759,7 +2760,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); } } - DEBUG(0,("Using netbios name %s.\n", context->netbios_name)); + DEBUG(1,("Using netbios name %s.\n", context->netbios_name)); if (!context->workgroup) { @@ -2771,7 +2772,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) context->workgroup = strdup("samba"); } } - DEBUG(0,("Using workgroup %s.\n", context->workgroup)); + DEBUG(1,("Using workgroup %s.\n", context->workgroup)); /* shortest timeout is 1 second */ if (context->timeout > 0 && context->timeout < 1000) -- cgit From 63f153c808312b806ff855906123bdc3d7f2a1cd Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 2 Apr 2003 18:32:31 +0000 Subject: Commit some more fixes for Coolo ... (This used to be commit e1a159c55fdeaa1620a3147105be4efd205560ba) --- source3/libsmb/clirap.c | 2 +- source3/libsmb/libsmbclient.c | 67 ++++++++++++++++--------------------------- 2 files changed, 25 insertions(+), 44 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 224c37046c..f05a65762b 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -233,7 +233,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - p += push_pstring_base(p, workgroup, param); + push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 1da55ed4bd..06885c55e0 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -351,8 +351,8 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) SMBCSRV *smbc_server(SMBCCTX *context, const char *server, const char *share, - char *workgroup, char *username, - char *password) + fstring workgroup, fstring username, + fstring password) { SMBCSRV *srv=NULL; int auth_called = 0; @@ -813,27 +813,6 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) } - if (!file->file) { - - return context->closedir(context, file); - - } - - if (!cli_close(&file->srv->cli, file->cli_fd)) { - DEBUG(3, ("cli_close failed on %s. purging server.\n", - file->fname)); - /* Deallocate slot and remove the server - * from the server cache if unused */ - errno = smbc_errno(context, &file->srv->cli); - srv = file->srv; - DLIST_REMOVE(context->internal->_files, file); - SAFE_FREE(file->fname); - SAFE_FREE(file); - context->callbacks.remove_unused_server_fn(context, srv); - - return -1; - } - DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); @@ -1087,12 +1066,16 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int case SEEK_END: if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, - NULL, NULL, NULL) && - !cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, - NULL)) { - + NULL, NULL, NULL)) + { + SMB_BIG_UINT b_size = size; + if (!cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &b_size, NULL, NULL, + NULL)) + { errno = EINVAL; return -1; + } else + size = b_size; } file->offset = size + offset; break; @@ -1290,12 +1273,15 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) } if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, - &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) && - !cli_getattrE(&file->srv->cli, file->cli_fd, - &mode, &size, &c_time, &a_time, &m_time)) { + &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) { + SMB_BIG_UINT b_size = size; + if (!cli_getattrE(&file->srv->cli, file->cli_fd, + &mode, &b_size, &c_time, &a_time, &m_time)) { errno = EINVAL; return -1; + } else + size = b_size; } @@ -1524,8 +1510,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!context || !context->internal || !context->internal->_initialized) { - - DEBUG(4, ("no valid context\n")); + DEBUG(4, ("no valid context\n")); errno = EINVAL; return NULL; @@ -1535,14 +1520,12 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) DEBUG(4, ("no valid fname\n")); errno = EINVAL; return NULL; - } if (smbc_parse_path(context, fname, server, share, path, user, password)) { - DEBUG(4, ("no valid path\n")); + DEBUG(4, ("no valid path\n")); errno = EINVAL; return NULL; - } DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s'\n", fname, server, share, path)); @@ -1571,9 +1554,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (server[0] == (char)0) { struct in_addr server_ip; - - DEBUG(4, ("empty server\n")); - + DEBUG(4, ("empty server\n")); if (share[0] != (char)0 || path[0] != (char)0) { DEBUG(4,("share %d path %d\n", share[0], path[0])); errno = EINVAL; @@ -1582,7 +1563,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SAFE_FREE(dir); } return NULL; - } /* We have server and share and path empty ... so list the workgroups */ @@ -1680,7 +1660,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) srv = smbc_server(context, buserver, "IPC$", workgroup, user, password); if (!srv) { - + DEBUG(0, ("got no contact to IPC$\n")); if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -2760,8 +2740,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); } } - DEBUG(1,("Using netbios name %s.\n", context->netbios_name)); - + + DEBUG(1, ("Using netbios name %s.\n", context->netbios_name)); if (!context->workgroup) { if (lp_workgroup()) { @@ -2772,7 +2752,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) context->workgroup = strdup("samba"); } } - DEBUG(1,("Using workgroup %s.\n", context->workgroup)); + + DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); /* shortest timeout is 1 second */ if (context->timeout > 0 && context->timeout < 1000) -- cgit From e9a20f741965e9fff1645045cc385ddc68fcbd39 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Wed, 2 Apr 2003 20:17:28 +0000 Subject: More of coolo's changes for UTF-8 and some minor fixes of mine. (This used to be commit 21a99fdec321c44e31b69589248ff8d1cb927577) --- source3/libsmb/libsmbclient.c | 54 +++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 06885c55e0..41a6755953 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -65,7 +65,7 @@ hex2int( unsigned int _char ) } static void -decode_urlpart(char *segment) +decode_urlpart(char *segment, size_t sizeof_segment) { int old_length = strlen(segment); int new_length = 0; @@ -121,9 +121,14 @@ decode_urlpart(char *segment) } new_segment [ new_length ] = 0; + free(new_usegment); + + /* realloc it with unix charset */ + pull_utf8_allocate((void**)&new_usegment, new_segment); + /* this assumes (very safely) that removing %aa sequences only shortens the string */ - strncpy(segment, new_segment, old_length); + strncpy(segment, new_usegment, sizeof_segment); free(new_usegment); } @@ -243,15 +248,15 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, } pstrcpy(path, p); - + all_string_sub(path, "/", "\\", 0); decoding: - decode_urlpart(path); - decode_urlpart(server); - decode_urlpart(share); - decode_urlpart(user); - decode_urlpart(password); + decode_urlpart(path, sizeof(pstring)); + decode_urlpart(server, sizeof(fstring)); + decode_urlpart(share, sizeof(fstring)); + decode_urlpart(user, sizeof(fstring)); + decode_urlpart(password, sizeof(fstring)); return 0; } @@ -1334,6 +1339,13 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint { struct smbc_dirent *dirent; int size; + char *u_name = NULL, *u_comment = NULL; + size_t u_name_len = 0, u_comment_len = 0; + + if (name) + u_name_len = push_utf8_allocate(&u_name, name); + if (comment) + u_comment_len = push_utf8_allocate(&u_comment, comment); /* * Allocate space for the dirent, which must be increased by the @@ -1341,8 +1353,7 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint * The null on the name is already accounted for. */ - size = sizeof(struct smbc_dirent) + (name?strlen(name):0) + - (comment?strlen(comment):0) + 1; + size = sizeof(struct smbc_dirent) + u_name_len + u_comment_len + 1; dirent = malloc(size); @@ -1391,14 +1402,17 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint dir->dir_end->dirent = dirent; dirent->smbc_type = type; - dirent->namelen = (name?strlen(name):0); - dirent->commentlen = (comment?strlen(comment):0); + dirent->namelen = u_name_len; + dirent->commentlen = u_comment_len; dirent->dirlen = size; - strncpy(dirent->name, (name?name:""), dirent->namelen + 1); + strncpy(dirent->name, (u_name?u_name:""), dirent->namelen + 1); dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); - strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); + strncpy(dirent->comment, (u_comment?u_comment:""), dirent->commentlen + 1); + + SAFE_FREE(u_comment); + SAFE_FREE(u_name); return 0; @@ -2158,6 +2172,7 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { + off_t ret_val; /* Squash warnings about cast */ if (!context || !context->internal || !context->internal->_initialized) { @@ -2181,7 +2196,11 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) } - return (off_t) dir->dir_next; + /* + * We return the pointer here as the offset + */ + ret_val = (int)dir->dir_next; + return ret_val; } @@ -2221,8 +2240,9 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) { - struct smbc_dirent *dirent = (struct smbc_dirent *)offset; - struct smbc_dir_list *list_ent = NULL; + long int l_offset = offset; /* Handle problems of size */ + struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; + struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; if (!context || !context->internal || !context->internal->_initialized) { -- cgit From 3643d94b4f01311a4cf068375da5cd728a150755 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Apr 2003 00:20:58 +0000 Subject: Fixup format warning. Jeremy. (This used to be commit 32dc4ddb04f4d3eecfdd542cb3495830067a2eed) --- source3/libsmb/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 0cd1ac33ec..b8ef3a80c2 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -385,7 +385,7 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, } else if (ntlmssp_command == NTLMSSP_AUTH) { return ntlmssp_server_auth(ntlmssp_state, request, reply); } else { - DEBUG(1, ("unknown NTLMSSP command %u\n", ntlmssp_command, ntlmssp_state->expected_state)); + DEBUG(1, ("unknown NTLMSSP command %u\n", ntlmssp_command)); return NT_STATUS_INVALID_PARAMETER; } } -- cgit From 3b592a76a12ede0e27dc71573b77a2616fd0093f Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 4 Apr 2003 21:15:20 +0000 Subject: Some castiness for Don McCall. (This used to be commit b03ac852a86cf9f436ad2b994e09fb08dd929674) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 41a6755953..acbde95b91 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2369,7 +2369,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr /* Try to open the file for reading ... */ - if ((fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { + if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); return -1; /* smbc_open sets errno */ @@ -2378,7 +2378,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr /* Now, try to open the printer file for writing */ - if ((fid2 = c_print->open_print_job(c_print, printq)) < 0) { + if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { saverr = errno; /* Save errno */ c_file->close(c_file, fid1); -- cgit From 15512544326aa29f8f9fc82bf28dc261288e9321 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 4 Apr 2003 22:16:50 +0000 Subject: Add some castiness for Don McCall. (This used to be commit 57c860b41b21bafc660f84070bfe9c8d90bc28a3) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 440527cd9d..92353d8c30 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2249,7 +2249,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr /* Try to open the file for reading ... */ - if ((fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { + if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); return -1; /* smbc_open sets errno */ @@ -2258,7 +2258,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr /* Now, try to open the printer file for writing */ - if ((fid2 = c_print->open_print_job(c_print, printq)) < 0) { + if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { saverr = errno; /* Save errno */ c_file->close(c_file, fid1); -- cgit From a59565bf3803c09e41559b2424baf812a1f49d33 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 4 Apr 2003 23:39:16 +0000 Subject: Some more good stuff from coolo. (This used to be commit 41b320ffc560117c0184999e30cc69723f40acbe) --- source3/libsmb/cliconnect.c | 71 +++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/libsmbclient.c | 65 ++++++++++++++------------------------- 2 files changed, 94 insertions(+), 42 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 75dcd62c2f..4bfa694e63 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1384,3 +1384,74 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, return NT_STATUS_OK; } + +/* Return a cli_state pointing at the IPC$ share for the given server */ + +struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, + struct user_auth_info *user_info) +{ + struct cli_state *cli; + pstring myname; + NTSTATUS nt_status; + + get_myname(myname); + + nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", + user_info->username, lp_workgroup(), user_info->password, + CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, NULL); + + if (NT_STATUS_IS_OK(nt_status)) { + return cli; + } else if (is_ipaddress(server)) { + /* windows 9* needs a correct NMB name for connections */ + fstring remote_name; + + if (name_status_find("*", 0, 0, *server_ip, remote_name)) { + cli = get_ipc_connect(remote_name, server_ip, user_info); + if (cli) + return cli; + } + } + return NULL; +} + +/* Return the IP address and workgroup of a master browser on the + network. */ + +struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) +{ + struct in_addr *ip_list; + struct cli_state *cli; + int i, count; + struct in_addr server_ip; + + /* Go looking for workgroups by broadcasting on the local network */ + + if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + return False; + } + + for (i = 0; i < count; i++) { + static fstring name; + + if (!name_status_find("*", 0, 0x1d, ip_list[i], name)) + continue; + + if (!find_master_ip(name, &server_ip)) + continue; + + pstrcpy(workgroup, name); + + DEBUG(4, ("found master browser %s, %s\n", + name, inet_ntoa(ip_list[i]))); + + cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); + + if (!cli) + continue; + + return cli; + } + + return NULL; +} diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index acbde95b91..c04736d8f5 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1476,43 +1476,6 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) } - -/* Return the IP address and workgroup of a master browser on the - network. */ - -static BOOL find_master_ip_bcast(pstring workgroup, struct in_addr *server_ip) -{ - struct in_addr *ip_list; - int i, count; - - /* Go looking for workgroups by broadcasting on the local network */ - - if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { - return False; - } - - for (i = count-1; i < count; i++) { - static fstring name; - - DEBUG(0, ("name_status_find %d %s\n", i, inet_ntoa(ip_list[i]))); - - if (!name_status_find("*", 0, 0x1d, ip_list[i], name)) - continue; - - if (!find_master_ip(name, server_ip)) - continue; - - pstrcpy(workgroup, name); - - DEBUG(4, ("found master browser %s, %s\n", - name, inet_ntoa(ip_list[i]))); - - return True; - } - - return False; -} - static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password; @@ -1568,9 +1531,8 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (server[0] == (char)0) { struct in_addr server_ip; - DEBUG(4, ("empty server\n")); if (share[0] != (char)0 || path[0] != (char)0) { - DEBUG(4,("share %d path %d\n", share[0], path[0])); + errno = EINVAL; if (dir) { SAFE_FREE(dir->fname); @@ -1585,22 +1547,41 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) pstrcpy(workgroup, lp_workgroup()); - if (!find_master_ip(lp_workgroup(), &server_ip)) { + if (!find_master_ip(workgroup, &server_ip)) { + struct user_auth_info u_info; + struct cli_state *cli; + DEBUG(4, ("Unable to find master browser for workgroup %s\n", workgroup)); - if (!find_master_ip_bcast(workgroup, &server_ip)) { + + /* find the name of the server ... */ + pstrcpy(u_info.username, user); + pstrcpy(u_info.password, password); + + if (!(cli = get_ipc_connect_master_ip_bcast(workgroup, &u_info))) { DEBUG(4, ("Unable to find master browser by " "broadcast\n")); errno = ENOENT; return NULL; } + + fstrcpy(server, cli->desthost); + + cli_shutdown(cli); + } else { + if (!name_status_find("*", 0, 0, server_ip, server)) { + errno = ENOENT; + return NULL; + } } + DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); + /* * Get a connection to IPC$ on the server if we do not already have one */ - srv = smbc_server(context, inet_ntoa(server_ip), "IPC$", workgroup, user, password); + srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { -- cgit From 35292596d8d57f76a6118127d7f3c71c6141170b Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 5 Apr 2003 19:41:33 +0000 Subject: Fix debug handling in libsmbclient.c. Also, PLEASE, PLEASE, PLEASE, do not include bashism and Cisms in shell scripts. (This used to be commit 7f6367aac8c5440e1d4e97b26571b205140488ae) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c04736d8f5..a0223568f1 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2670,8 +2670,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) if (!smbc_initialized) { /* Do some library wide intialisations the first time we get called */ - /* Do we still need this ? */ - DEBUGLEVEL = 10; + /* Set this to what the user wants */ + DEBUGLEVEL = context->debug; setup_logging( "libsmbclient", True); -- cgit From 88ed48d0f935db136318fafe6e541cf7cbaed5e2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 6 Apr 2003 13:08:07 +0000 Subject: SMB signing updates - this gets NTLMSSP signing workin to the point where I just need to get the verifiction code working - we get back a signiture from the server, and just can't verify it yet. This also brings the short-packet checks into common code, and breaks the connection if the server sends a signed reply, on an established connection, that fails the test. This breaks our read/write code at the moment, as we need to keep a list of outstanding packets. (signing is not enabled by default, unless the server demands it) Not for 3.0 till I fix the outstanding packet list. Andrew Barlett (This used to be commit 808d1fcf20153970d587cb631a08607beb09703a) --- source3/libsmb/clientgen.c | 5 ++++- source3/libsmb/ntlmssp_sign.c | 26 ++++++++++++++++++++++---- source3/libsmb/smb_signing.c | 17 +++++++++-------- 3 files changed, 35 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0da9a8932f..fe9453e6f2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -118,7 +118,10 @@ BOOL cli_receive_smb(struct cli_state *cli) } if (!cli_check_sign_mac(cli)) { - DEBUG(0, ("SMB Signiture verification failed on incoming packet!\n")); + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); + cli->smb_rw_error = READ_BAD_SIG; + close(cli->fd); + cli->fd = -1; return False; }; return True; diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 8f6bd0c691..5426263fb9 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -92,8 +92,14 @@ static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], calc_hash(hash, digest, 16); } +enum ntlmssp_direction { + NTLMSSP_SEND, + NTLMSSP_RECEIVE +}; + static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state, const uchar *data, size_t length, + enum ntlmssp_direction direction, DATA_BLOB *sig) { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -110,8 +116,14 @@ static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_stat if (!msrpc_gen(sig, "Bd", digest, sizeof(digest), ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } - - NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, sig->data, sig->length); + switch (direction) { + case NTLMSSP_SEND: + NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data, sig->length); + break; + case NTLMSSP_RECEIVE: + NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data, sig->length); + break; + } } else { uint32 crc; crc = crc32_calc_buffer(data, length); @@ -129,7 +141,7 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, DATA_BLOB *sig) { ntlmssp_state->ntlmssp_seq_num++; - return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, sig); + return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig); } /** @@ -151,7 +163,7 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, } nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, - length, &local_sig); + length, NTLMSSP_RECEIVE, &local_sig); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); @@ -161,6 +173,12 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, if (memcmp(sig->data, local_sig.data, MIN(sig->length, local_sig.length)) == 0) { return NT_STATUS_OK; } else { + DEBUG(5, ("BAD SIG: wanted signature of\n")); + dump_data(5, local_sig.data, local_sig.length); + + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, sig->data, sig->length); + DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); return NT_STATUS_ACCESS_DENIED; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 9bbf7ef91c..42c4d5574d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -160,11 +160,6 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) SIVAL(sequence_buf, 0, data->reply_seq_num); SIVAL(sequence_buf, 4, 0); - if (smb_len(cli->inbuf) < (offset_end_of_sig - 4)) { - DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); - return False; - } - /* get a copy of the server-sent mac */ memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); @@ -275,7 +270,7 @@ static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli) { BOOL good; NTSTATUS nt_status; - DATA_BLOB sig = data_blob(&cli->outbuf[smb_ss_field], 8); + DATA_BLOB sig = data_blob(&cli->inbuf[smb_ss_field], 8); NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; @@ -460,8 +455,14 @@ void cli_caclulate_sign_mac(struct cli_state *cli) BOOL cli_check_sign_mac(struct cli_state *cli) { BOOL good; - good = cli->sign_info.check_incoming_message(cli); - + + if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); + good = False; + } else { + good = cli->sign_info.check_incoming_message(cli); + } + if (!good) { if (cli->sign_info.doing_signing) { return False; -- cgit From ffe91a35261a26397e1c8155b5260d5e055fe349 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 6 Apr 2003 13:19:49 +0000 Subject: Clean up error messages on cli pipe disconnection, including adding the message for broken-due-to-bad-sig. Andrew Bartlett (This used to be commit b010b6c2dc400a97eb2ad038cd1fdb34bbde2ef0) --- source3/libsmb/clierror.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index cea736ef18..9ee181a90f 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -96,17 +96,21 @@ const char *cli_errstr(struct cli_state *cli) break; case READ_EOF: slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Call returned zero bytes (EOF)\n" ); + "Call returned zero bytes (EOF)" ); break; case READ_ERROR: slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Read error: %s\n", strerror(errno) ); + "Read error: %s", strerror(errno) ); break; case WRITE_ERROR: slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Write error: %s\n", strerror(errno) ); + "Write error: %s", strerror(errno) ); break; - default: + case READ_BAD_SIG: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Server packet had invalid SMB signiture!"); + break; + default: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Unknown error code %d\n", cli->smb_rw_error ); break; -- cgit From f4cc85c6c97e7a3e0b63eb4570ca24f1e950379a Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 6 Apr 2003 17:22:41 +0000 Subject: Fix the handling of smb.conf in libsmbclient. The right thing to do is to try for the user's local one in ~/.smbc/smb.conf, and if that fails, try the one in dyn_CONFIGFILE, and if that fails, keep going with the defaults but log a message. (This used to be commit 15fa48d19d178cf8bf214ea02f6c7a4c38890f71) --- source3/libsmb/libsmbclient.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index a0223568f1..69c4d8f7a7 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2688,13 +2688,16 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) if (!lp_load(conf, True, False, False)) { /* - * Hmmm, what the hell do we do here ... we could not parse the - * config file ... We must return an error ... and keep info around - * about why we failed + * Well, if that failed, try the dyn_CONFIGFILE + * Which points to the standard locn, and if that + * fails, silently ignore it and use the internal + * defaults ... */ - - errno = ENOENT; /* FIXME: Figure out the correct error response */ - return NULL; + + if (!lp_load(dyn_CONFIGFILE, True, False, False)) { + DEBUG(5, ("Could not load either config file: %s or %s\n", + conf, dyn_CONFIGFILE)); + } } reopen_logs(); /* Get logging working ... */ -- cgit From a48d89bb9d0092d9b2368d55fdd1e2350210c012 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 7 Apr 2003 07:37:46 +0000 Subject: Make this match head. (This used to be commit a718630961e713ca2bacc98ad0b7c2e996e20bf5) --- source3/libsmb/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index b8ef3a80c2..c179b98abf 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -385,7 +385,7 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, } else if (ntlmssp_command == NTLMSSP_AUTH) { return ntlmssp_server_auth(ntlmssp_state, request, reply); } else { - DEBUG(1, ("unknown NTLMSSP command %u\n", ntlmssp_command)); + DEBUG(1, ("unknown NTLMSSP command %u expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); return NT_STATUS_INVALID_PARAMETER; } } -- cgit From a8f7eaee5150e624316b14c04a8a9ec480b09dec Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 7 Apr 2003 09:35:35 +0000 Subject: Only warn about short packets if we are already 'doing signing'. Andrew Bartlett (This used to be commit 9656b8709128f24dd63094d504a6646f99933c57) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 42c4d5574d..4e9b895a1b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -457,7 +457,7 @@ BOOL cli_check_sign_mac(struct cli_state *cli) BOOL good; if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); + DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); good = False; } else { good = cli->sign_info.check_incoming_message(cli); -- cgit From 803e23f403bdb38d2523d73fd12083da486bca2f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 15:47:06 +0000 Subject: This is the netlogon schannel client code. Try a rpcclient -S pdc -U% -c "samlogon user password" and it should work with the schannel. Needs testing platforms different from NT4SP6. Volker (This used to be commit ecd0ee4d248e750168597ccf79c389513bb0f740) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fe9453e6f2..81cb61d757 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -282,6 +282,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli_null_set_signing(cli); cli->nt_pipe_fnum = 0; + cli->saved_netlogon_pipe_fnum = 0; cli->initialised = 1; cli->allocated = alloced_cli; -- cgit From 7238bf5f40e16360439e028fa7607a5a28e02965 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 9 Apr 2003 15:54:17 +0000 Subject: This is the netlogon schannel client code. Try a rpcclient -S pdc -U% -c "samlogon user password" and it should work with the schannel. Needs testing against platforms different from NT4SP6. Volker (This used to be commit eaef0d8aeff1aa5a067679be3f17e08d7434e1e8) --- source3/libsmb/clientgen.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d969193089..81b3bbcab5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -275,6 +275,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->inbuf, 0, cli->bufsize); cli->nt_pipe_fnum = 0; + cli->saved_netlogon_pipe_fnum = 0; cli->initialised = 1; cli->allocated = alloced_cli; -- cgit From 5b51fc4f065e9e68eefb530eb99ad8da9f4e5d28 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Apr 2003 23:32:00 +0000 Subject: smbcquota patch from metze (This used to be commit 74fab8f0d24004b1dfd5ce0fd7402895652f941f) --- source3/libsmb/clifile.c | 17 +- source3/libsmb/clifsinfo.c | 76 ++++++ source3/libsmb/cliquota.c | 633 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 719 insertions(+), 7 deletions(-) create mode 100644 source3/libsmb/clifsinfo.c create mode 100644 source3/libsmb/cliquota.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 4eb5efe193..b771e135f4 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -375,9 +375,11 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) Used in smbtorture. ****************************************************************************/ -int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess, +int cli_nt_create_full(struct cli_state *cli, const char *fname, + uint32 CreatFlags, uint32 DesiredAccess, uint32 FileAttributes, uint32 ShareAccess, - uint32 CreateDisposition, uint32 CreateOptions) + uint32 CreateDisposition, uint32 CreateOptions, + uint8 SecuityFlags) { char *p; int len; @@ -393,9 +395,9 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA SSVAL(cli->outbuf,smb_vwv0,0xFF); if (cli->use_oplocks) - SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); - else - SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); + CreatFlags |= (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); + + SIVAL(cli->outbuf,smb_ntcreate_Flags, CreatFlags); SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, FileAttributes); @@ -403,6 +405,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition); SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions); SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); + SCVAL(cli->outbuf,smb_ntcreate_SecurityFlags, SecuityFlags); p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ @@ -433,8 +436,8 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess) { - return cli_nt_create_full(cli, fname, DesiredAccess, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0); + return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0, 0x0); } /**************************************************************************** diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c new file mode 100644 index 0000000000..00fe189e9a --- /dev/null +++ b/source3/libsmb/clifsinfo.c @@ -0,0 +1,76 @@ +/* + Unix SMB/CIFS implementation. + FS info functions + Copyright (C) Stefan (metze) Metzmacher 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + + +BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) +{ + BOOL ret = False; + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + + if (!cli||!fs_attr) + smb_panic("cli_get_fs_attr_info() called with NULL Pionter!"); + + setup = TRANSACT2_QFSINFO; + + SSVAL(param,0,SMB_QUERY_FS_ATTRIBUTE_INFO); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + NULL, 0, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count < 12) { + goto cleanup; + } + + *fs_attr = IVAL(rdata,0); + + /* todo: but not yet needed + * return the other stuff + */ + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c new file mode 100644 index 0000000000..a56a6bd674 --- /dev/null +++ b/source3/libsmb/cliquota.c @@ -0,0 +1,633 @@ +/* + Unix SMB/CIFS implementation. + client quota functions + Copyright (C) Stefan (metze) Metzmacher 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +BOOL cli_get_quota_handle(struct cli_state *cli, int *quota_fnum) +{ + *quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA, + 0x00000016, DESIRED_ACCESS_PIPE, + 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE, + FILE_OPEN, 0x00000000, 0x03); + + if (*quota_fnum == (-1)) { + return False; + } + + return True; +} + +void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list) +{ + if (!qt_list) + return; + + if ((*qt_list)->mem_ctx) + talloc_destroy((*qt_list)->mem_ctx); + + (*qt_list) = NULL; + + return; +} + +static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt) +{ + int sid_len; + SMB_NTQUOTA_STRUCT qt; + + ZERO_STRUCT(qt); + + if (!rdata||!offset||!pqt) + smb_panic("parse_quota_record: called with NULL POINTER!\n"); + + if (rdata_count < 40) { + return False; + } + + /* offset to next quota record. + * 4 bytes IVAL(rdata,0) + * unused here... + */ + *offset = IVAL(rdata,0); + + /* sid len */ + sid_len = IVAL(rdata,4); + + if (rdata_count < 40+sid_len) { + return False; + } + + /* unknown 8 bytes in pdata + * maybe its the change time in NTTIME + */ + + /* the used space 8 bytes (SMB_BIG_UINT)*/ + qt.usedspace = (SMB_BIG_UINT)IVAL(rdata,16); +#ifdef LARGE_SMB_OFF_T + qt.usedspace |= (((SMB_BIG_UINT)IVAL(rdata,20)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,20) != 0)&& + ((qt.usedspace != 0xFFFFFFFF)|| + (IVAL(rdata,20)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + return False; + } +#endif /* LARGE_SMB_OFF_T */ + + /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ + qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24); +#ifdef LARGE_SMB_OFF_T + qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,28) != 0)&& + ((qt.softlim != 0xFFFFFFFF)|| + (IVAL(rdata,28)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + return False; + } +#endif /* LARGE_SMB_OFF_T */ + + /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ + qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32); +#ifdef LARGE_SMB_OFF_T + qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,36) != 0)&& + ((qt.hardlim != 0xFFFFFFFF)|| + (IVAL(rdata,36)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + return False; + } +#endif /* LARGE_SMB_OFF_T */ + + sid_parse(rdata+40,sid_len,&qt.sid); + + qt.qtype = SMB_USER_QUOTA_TYPE; + + *pqt = qt; + + return True; +} + +BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ + BOOL ret = False; + uint16 setup; + char params[16]; + unsigned int data_len; + char data[SID_MAX_SIZE+8]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + unsigned int sid_len; + unsigned int offset; + + if (!cli||!pqt) + smb_panic("cli_get_user_quota() called with NULL Pointer!"); + + setup = NT_TRANSACT_GET_USER_QUOTA; + + SSVAL(params, 0,quota_fnum); + SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_FOR_SID); + SIVAL(params, 4,0x00000024); + SIVAL(params, 8,0x00000000); + SIVAL(params,12,0x00000024); + + sid_len = sid_size(&pqt->sid); + data_len = sid_len+8; + SIVAL(data, 0, 0x00000000); + SIVAL(data, 4, sid_len); + sid_linearize(data+8, sid_len, &pqt->sid); + + if (!cli_send_nt_trans(cli, + NT_TRANSACT_GET_USER_QUOTA, + 0, + &setup, 1, 0, + params, 16, 4, + data, data_len, 112)) { + DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if ((rparam&&rdata)&&(rparam_count>=4&&rdata_count>=8)) { + ret = parse_user_quota_record(rdata, rdata_count, &offset, pqt); + } else { + DEBUG(0,("Got INVALID NT_TRANSACT_GET_USER_QUOTA reply.\n")); + ret = False; + } + + cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return ret; +} + +BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ + BOOL ret = False; + uint16 setup; + char params[2]; + char data[112]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + unsigned int sid_len; + memset(data,'\0',112); + + if (!cli||!pqt) + smb_panic("cli_set_user_quota() called with NULL Pointer!"); + + setup = NT_TRANSACT_SET_USER_QUOTA; + + SSVAL(params,0,quota_fnum); + + sid_len = sid_size(&pqt->sid); + SIVAL(data,0,0); + SIVAL(data,4,sid_len); + SBIG_UINT(data, 8,(SMB_BIG_UINT)0); + SBIG_UINT(data,16,pqt->usedspace); + SBIG_UINT(data,24,pqt->softlim); + SBIG_UINT(data,32,pqt->hardlim); + sid_linearize(data+40, sid_len, &pqt->sid); + + if (!cli_send_nt_trans(cli, + NT_TRANSACT_SET_USER_QUOTA, + 0, + &setup, 1, 0, + params, 2, 0, + data, 112, 0)) { + DEBUG(1,("Failed to send NT_TRANSACT_SET_USER_QUOTA\n")); + goto cleanup; + } + + + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("NT_TRANSACT_SET_USER_QUOTA failed\n")); + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return ret; +} + +BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list) +{ + BOOL ret = False; + uint16 setup; + char params[16]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + unsigned int offset; + const char *curdata = NULL; + unsigned int curdata_count = 0; + TALLOC_CTX *mem_ctx = NULL; + SMB_NTQUOTA_STRUCT qt; + SMB_NTQUOTA_LIST *tmp_list_ent; + + if (!cli||!pqt_list) + smb_panic("cli_list_user_quota() called with NULL Pointer!"); + + setup = NT_TRANSACT_GET_USER_QUOTA; + + SSVAL(params, 0,quota_fnum); + SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_START); + SIVAL(params, 4,0x00000000); + SIVAL(params, 8,0x00000000); + SIVAL(params,12,0x00000000); + + if (!cli_send_nt_trans(cli, + NT_TRANSACT_GET_USER_QUOTA, + 0, + &setup, 1, 0, + params, 16, 4, + NULL, 0, 2048)) { + DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count == 0) { + *pqt_list = NULL; + return True; + } + + if ((mem_ctx=talloc_init("SMB_USER_QUOTA_LIST"))==NULL) { + DEBUG(0,("talloc_init() failed\n")); + return (-1); + } + + offset = 1; + for (curdata=rdata,curdata_count=rdata_count; + ((curdata)&&(curdata_count>=8)&&(offset>0)); + curdata +=offset,curdata_count -= offset) { + ZERO_STRUCT(qt); + if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) { + DEBUG(1,("Failed to parse the quota record\n")); + goto cleanup; + } + + if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) { + DEBUG(0,("talloc_zero() failed\n")); + return (-1); + } + + if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) { + DEBUG(0,("talloc_zero() failed\n")); + return (-1); + } + + memcpy(tmp_list_ent->quotas,&qt,sizeof(qt)); + tmp_list_ent->mem_ctx = mem_ctx; + + DLIST_ADD((*pqt_list),tmp_list_ent); + } + + SSVAL(params, 2,TRANSACT_GET_USER_QUOTA_LIST_CONTINUE); + while(1) { + if (!cli_send_nt_trans(cli, + NT_TRANSACT_GET_USER_QUOTA, + 0, + &setup, 1, 0, + params, 16, 4, + NULL, 0, 2048)) { + DEBUG(1,("Failed to send NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + if (!cli_receive_nt_trans(cli, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + DEBUG(1,("Failed to recv NT_TRANSACT_GET_USER_QUOTA\n")); + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count == 0) { + break; + } + + offset = 1; + for (curdata=rdata,curdata_count=rdata_count; + ((curdata)&&(curdata_count>=8)&&(offset>0)); + curdata +=offset,curdata_count -= offset) { + ZERO_STRUCT(qt); + if (!parse_user_quota_record(curdata, curdata_count, &offset, &qt)) { + DEBUG(1,("Failed to parse the quota record\n")); + goto cleanup; + } + + if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) { + DEBUG(0,("talloc_zero() failed\n")); + talloc_destroy(mem_ctx); + goto cleanup; + } + + if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) { + DEBUG(0,("talloc_zero() failed\n")); + talloc_destroy(mem_ctx); + goto cleanup; + } + + memcpy(tmp_list_ent->quotas,&qt,sizeof(qt)); + tmp_list_ent->mem_ctx = mem_ctx; + + DLIST_ADD((*pqt_list),tmp_list_ent); + } + } + + + ret = True; + cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} + +BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ + BOOL ret = False; + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + SMB_NTQUOTA_STRUCT qt; + ZERO_STRUCT(qt); + + if (!cli||!pqt) + smb_panic("cli_get_fs_quota_info() called with NULL Pointer!"); + + setup = TRANSACT2_QFSINFO; + + SSVAL(param,0,SMB_FS_QUOTA_INFORMATION); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + NULL, 0, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count < 48) { + goto cleanup; + } + + /* unknown_1 24 NULL bytes in pdata*/ + + /* the soft quotas 8 bytes (SMB_BIG_UINT)*/ + qt.softlim = (SMB_BIG_UINT)IVAL(rdata,24); +#ifdef LARGE_SMB_OFF_T + qt.softlim |= (((SMB_BIG_UINT)IVAL(rdata,28)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,28) != 0)&& + ((qt.softlim != 0xFFFFFFFF)|| + (IVAL(rdata,28)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + goto cleanup; + } +#endif /* LARGE_SMB_OFF_T */ + + /* the hard quotas 8 bytes (SMB_BIG_UINT)*/ + qt.hardlim = (SMB_BIG_UINT)IVAL(rdata,32); +#ifdef LARGE_SMB_OFF_T + qt.hardlim |= (((SMB_BIG_UINT)IVAL(rdata,36)) << 32); +#else /* LARGE_SMB_OFF_T */ + if ((IVAL(rdata,36) != 0)&& + ((qt.hardlim != 0xFFFFFFFF)|| + (IVAL(rdata,36)!=0xFFFFFFFF)))) { + /* more than 32 bits? */ + goto cleanup; + } +#endif /* LARGE_SMB_OFF_T */ + + /* quota_flags 2 bytes **/ + qt.qflags = SVAL(rdata,40); + + qt.qtype = SMB_USER_FS_QUOTA_TYPE; + + *pqt = qt; + + ret = True; +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} + +BOOL cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +{ + BOOL ret = False; + uint16 setup; + char param[4]; + char data[48]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + SMB_NTQUOTA_STRUCT qt; + ZERO_STRUCT(qt); + memset(data,'\0',48); + + if (!cli||!pqt) + smb_panic("cli_set_fs_quota_info() called with NULL Pointer!"); + + setup = TRANSACT2_SETFSINFO; + + SSVAL(param,0,quota_fnum); + SSVAL(param,2,SMB_FS_QUOTA_INFORMATION); + + /* Unknown1 24 NULL bytes*/ + + /* Default Soft Quota 8 bytes */ + SBIG_UINT(data,24,pqt->softlim); + + /* Default Hard Quota 8 bytes */ + SBIG_UINT(data,32,pqt->hardlim); + + /* Quota flag 2 bytes */ + SSVAL(data,40,pqt->qflags); + + /* Unknown3 6 NULL bytes */ + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 4, 0, + data, 48, 0)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} + +static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric) +{ + static fstring buffer; + + memset(buffer,'\0',sizeof(buffer)); + + if (!_numeric&&special&&(val == SMB_NTQUOTAS_NO_LIMIT)) { + fstr_sprintf(buffer,"NO LIMIT"); + return buffer; + } +#if defined(HAVE_LONGLONG) + fstr_sprintf(buffer,"%llu",val); +#else + fstr_sprintf(buffer,"%lu",val); +#endif + return buffer; +} + +void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric)) +{ + if (!qt) + smb_panic("dump_ntquota() called with NULL pointer"); + + switch (qt->qtype) { + case SMB_USER_FS_QUOTA_TYPE: + { + d_printf("File System QUOTAS:\n"); + d_printf("Limits:\n"); + d_printf(" Default Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric)); + d_printf(" Default Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric)); + d_printf("Quota Flags:\n"); + d_printf(" Quotas Enabled: %s\n", + ((qt->qflags"AS_ENABLED)||(qt->qflags"AS_DENY_DISK))?"On":"Off"); + d_printf(" Deny Disk: %s\n",(qt->qflags"AS_DENY_DISK)?"On":"Off"); + d_printf(" Log Soft Limit: %s\n",(qt->qflags"AS_LOG_THRESHOLD)?"On":"Off"); + d_printf(" Log Hard Limit: %s\n",(qt->qflags"AS_LOG_LIMIT)?"On":"Off"); + } + break; + case SMB_USER_QUOTA_TYPE: + { + fstring username_str = {0}; + + if (_sidtostring) { + _sidtostring(username_str,&qt->sid,_numeric); + } else { + fstrcpy(username_str,sid_string_static(&qt->sid)); + } + + if (_verbose) { + d_printf("Quotas for User: %s\n",username_str); + d_printf("Used Space: %15s\n",quota_str_static(qt->usedspace,False,_numeric)); + d_printf("Soft Limit: %15s\n",quota_str_static(qt->softlim,True,_numeric)); + d_printf("Hard Limit: %15s\n",quota_str_static(qt->hardlim,True,_numeric)); + } else { + d_printf("%-30s: ",username_str); + d_printf("%15s/",quota_str_static(qt->usedspace,False,_numeric)); + d_printf("%15s/",quota_str_static(qt->softlim,True,_numeric)); + d_printf("%15s\n",quota_str_static(qt->hardlim,True,_numeric)); + } + } + break; + default: + d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype); + return; + } +} + +void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric)) +{ + SMB_NTQUOTA_LIST *cur; + + for (cur = *qtl;cur;cur = cur->next) { + if (cur->quotas) + dump_ntquota(cur->quotas,_verbose,_numeric,_sidtostring); + } +} -- cgit From e0cf81f1044eab1156dc30c06e7e788b640499f9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 14 Apr 2003 02:27:41 +0000 Subject: Whitespace syncup. (This used to be commit 93101a93dabe2dd7a6420e90acf82e0e08dce572) --- source3/libsmb/clistr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index bba9fcf15a..c61445c073 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -3,7 +3,7 @@ client string routines Copyright (C) Andrew Tridgell 2001 Copyright (C) Andrew Bartlett 2003 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or -- cgit From 19cda0035e5e056595ac9a96bfb3b029b76eb4d2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 14 Apr 2003 04:15:24 +0000 Subject: Merge cliconnect.c so smbtree builds. (This used to be commit 5df53e9d8a8b1861d9997a775cfd6d8fe472bdc4) --- source3/libsmb/cliconnect.c | 114 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 113 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 763878f9b3..4bfa694e63 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -750,7 +750,6 @@ BOOL cli_ulogoff(struct cli_state *cli) /**************************************************************************** Send a tconX. ****************************************************************************/ - BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { @@ -1343,3 +1342,116 @@ name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); return True; } + + + + + +/**************************************************************************** + Send an old style tcon. +****************************************************************************/ +NTSTATUS cli_raw_tcon(struct cli_state *cli, + const char *service, const char *pass, const char *dev, + uint16 *max_xmit, uint16 *tid) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 0, 0, True); + SCVAL(cli->outbuf,smb_com,SMBtcon); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; p += clistr_push(cli, p, service, -1, STR_TERMINATE | STR_NOALIGN); + *p++ = 4; p += clistr_push(cli, p, pass, -1, STR_TERMINATE | STR_NOALIGN); + *p++ = 4; p += clistr_push(cli, p, dev, -1, STR_TERMINATE | STR_NOALIGN); + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } + + *max_xmit = SVAL(cli->inbuf, smb_vwv0); + *tid = SVAL(cli->inbuf, smb_vwv1); + + return NT_STATUS_OK; +} + +/* Return a cli_state pointing at the IPC$ share for the given server */ + +struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, + struct user_auth_info *user_info) +{ + struct cli_state *cli; + pstring myname; + NTSTATUS nt_status; + + get_myname(myname); + + nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", + user_info->username, lp_workgroup(), user_info->password, + CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, NULL); + + if (NT_STATUS_IS_OK(nt_status)) { + return cli; + } else if (is_ipaddress(server)) { + /* windows 9* needs a correct NMB name for connections */ + fstring remote_name; + + if (name_status_find("*", 0, 0, *server_ip, remote_name)) { + cli = get_ipc_connect(remote_name, server_ip, user_info); + if (cli) + return cli; + } + } + return NULL; +} + +/* Return the IP address and workgroup of a master browser on the + network. */ + +struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) +{ + struct in_addr *ip_list; + struct cli_state *cli; + int i, count; + struct in_addr server_ip; + + /* Go looking for workgroups by broadcasting on the local network */ + + if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + return False; + } + + for (i = 0; i < count; i++) { + static fstring name; + + if (!name_status_find("*", 0, 0x1d, ip_list[i], name)) + continue; + + if (!find_master_ip(name, &server_ip)) + continue; + + pstrcpy(workgroup, name); + + DEBUG(4, ("found master browser %s, %s\n", + name, inet_ntoa(ip_list[i]))); + + cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); + + if (!cli) + continue; + + return cli; + } + + return NULL; +} -- cgit From 99fd07350510c07517ae5e05f5fb180cef56fc0e Mon Sep 17 00:00:00 2001 From: Paul Green Date: Mon, 14 Apr 2003 19:48:56 +0000 Subject: Rebalance parentheses in cliquota.c when LARGE_SMB_OFF_T is false. (This used to be commit bd69cbce93054548b6d1e3bac89032ff4f693423) --- source3/libsmb/cliquota.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index a56a6bd674..ed808aa1f5 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -85,7 +85,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,20) != 0)&& ((qt.usedspace != 0xFFFFFFFF)|| - (IVAL(rdata,20)!=0xFFFFFFFF)))) { + (IVAL(rdata,20)!=0xFFFFFFFF))) { /* more than 32 bits? */ return False; } @@ -98,7 +98,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,28) != 0)&& ((qt.softlim != 0xFFFFFFFF)|| - (IVAL(rdata,28)!=0xFFFFFFFF)))) { + (IVAL(rdata,28)!=0xFFFFFFFF))) { /* more than 32 bits? */ return False; } @@ -111,7 +111,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,36) != 0)&& ((qt.hardlim != 0xFFFFFFFF)|| - (IVAL(rdata,36)!=0xFFFFFFFF)))) { + (IVAL(rdata,36)!=0xFFFFFFFF))) { /* more than 32 bits? */ return False; } @@ -459,7 +459,7 @@ BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_ST #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,28) != 0)&& ((qt.softlim != 0xFFFFFFFF)|| - (IVAL(rdata,28)!=0xFFFFFFFF)))) { + (IVAL(rdata,28)!=0xFFFFFFFF))) { /* more than 32 bits? */ goto cleanup; } @@ -472,7 +472,7 @@ BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_ST #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,36) != 0)&& ((qt.hardlim != 0xFFFFFFFF)|| - (IVAL(rdata,36)!=0xFFFFFFFF)))) { + (IVAL(rdata,36)!=0xFFFFFFFF))) { /* more than 32 bits? */ goto cleanup; } -- cgit From e390ceda7619c87aa4eded300b28528760e7e23b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 15 Apr 2003 03:54:07 +0000 Subject: Add string message for WERR_SERVER_UNAVAILABLE. (This used to be commit 38efab087c86cab805c6b94c7455befaa9e94c5e) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index c9de4cf319..c6348568cf 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -67,6 +67,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, + { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { NULL, W_ERROR(0) } }; -- cgit From d0e19665e864468b8284d26af5ede0e24ee612f5 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 15 Apr 2003 06:55:42 +0000 Subject: Merge of server unavailable error string. (This used to be commit 21d7dba977037b83fc1d6d86b5d3d4cae6eb683d) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index c9de4cf319..c6348568cf 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -67,6 +67,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, + { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { NULL, W_ERROR(0) } }; -- cgit From a0e8344a8d1e8fbbde4cc4ca5a5722ee1e2c2bcf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 15 Apr 2003 14:42:06 +0000 Subject: Add some more NT to unix error code mappings (from HEAD) (This used to be commit 62dac3d6ebc72bec24f3c0df4c8d8e37029473e2) --- source3/libsmb/clierror.c | 95 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 12a7b5dba1..cea736ef18 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. client error handling routines Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Jelmer Vernooij 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -220,16 +221,104 @@ static struct { int error; } nt_errno_map[] = { {NT_STATUS_ACCESS_VIOLATION, EACCES}, - {NT_STATUS_NO_SUCH_FILE, ENOENT}, - {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, {NT_STATUS_INVALID_HANDLE, EBADF}, - {NT_STATUS_NO_MEMORY, ENOMEM}, {NT_STATUS_ACCESS_DENIED, EACCES}, {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, {NT_STATUS_SHARING_VIOLATION, EBUSY}, {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, {NT_STATUS_PATH_NOT_COVERED, ENOENT}, + {NT_STATUS_UNSUCCESSFUL, EINVAL}, + {NT_STATUS_NOT_IMPLEMENTED, ENOSYS}, + {NT_STATUS_IN_PAGE_ERROR, EFAULT}, + {NT_STATUS_BAD_NETWORK_NAME, ENOENT}, +#ifdef EDQUOT + {NT_STATUS_PAGEFILE_QUOTA, EDQUOT}, + {NT_STATUS_QUOTA_EXCEEDED, EDQUOT}, + {NT_STATUS_REGISTRY_QUOTA_LIMIT, EDQUOT}, + {NT_STATUS_LICENSE_QUOTA_EXCEEDED, EDQUOT}, +#endif +#ifdef ETIME + {NT_STATUS_TIMER_NOT_CANCELED, ETIME}, +#endif + {NT_STATUS_INVALID_PARAMETER, EINVAL}, + {NT_STATUS_NO_SUCH_DEVICE, ENODEV}, + {NT_STATUS_NO_SUCH_FILE, ENOENT}, +#ifdef ENODATA + {NT_STATUS_END_OF_FILE, ENODATA}, +#endif +#ifdef ENOMEDIUM + {NT_STATUS_NO_MEDIA_IN_DEVICE, ENOMEDIUM}, + {NT_STATUS_NO_MEDIA, ENOMEDIUM}, +#endif + {NT_STATUS_NONEXISTENT_SECTOR, ESPIPE}, + {NT_STATUS_NO_MEMORY, ENOMEM}, + {NT_STATUS_CONFLICTING_ADDRESSES, EADDRINUSE}, + {NT_STATUS_NOT_MAPPED_VIEW, EINVAL}, + {NT_STATUS_UNABLE_TO_FREE_VM, EADDRINUSE}, + {NT_STATUS_ACCESS_DENIED, EACCES}, + {NT_STATUS_BUFFER_TOO_SMALL, ENOBUFS}, + {NT_STATUS_WRONG_PASSWORD, EACCES}, + {NT_STATUS_LOGON_FAILURE, EACCES}, + {NT_STATUS_INVALID_WORKSTATION, EACCES}, + {NT_STATUS_INVALID_LOGON_HOURS, EACCES}, + {NT_STATUS_PASSWORD_EXPIRED, EACCES}, + {NT_STATUS_ACCOUNT_DISABLED, EACCES}, + {NT_STATUS_DISK_FULL, ENOSPC}, + {NT_STATUS_INVALID_PIPE_STATE, EPIPE}, + {NT_STATUS_PIPE_BUSY, EPIPE}, + {NT_STATUS_PIPE_DISCONNECTED, EPIPE}, + {NT_STATUS_PIPE_NOT_AVAILABLE, ENOSYS}, + {NT_STATUS_FILE_IS_A_DIRECTORY, EISDIR}, + {NT_STATUS_NOT_SUPPORTED, ENOSYS}, + {NT_STATUS_NOT_A_DIRECTORY, ENOTDIR}, + {NT_STATUS_DIRECTORY_NOT_EMPTY, ENOTEMPTY}, + {NT_STATUS_NETWORK_UNREACHABLE, ENETUNREACH}, + {NT_STATUS_HOST_UNREACHABLE, EHOSTUNREACH}, + {NT_STATUS_CONNECTION_ABORTED, ECONNABORTED}, + {NT_STATUS_CONNECTION_REFUSED, ECONNREFUSED}, + {NT_STATUS_TOO_MANY_LINKS, EMLINK}, + {NT_STATUS_NETWORK_BUSY, EBUSY}, + {NT_STATUS_DEVICE_DOES_NOT_EXIST, ENODEV}, +#ifdef ELIBACC + {NT_STATUS_DLL_NOT_FOUND, ELIBACC}, +#endif + {NT_STATUS_PIPE_BROKEN, EPIPE}, + {NT_STATUS_REMOTE_NOT_LISTENING, ECONNREFUSED}, + {NT_STATUS_NETWORK_ACCESS_DENIED, EACCES}, + {NT_STATUS_TOO_MANY_OPENED_FILES, EMFILE}, +#ifdef EPROTO + {NT_STATUS_DEVICE_PROTOCOL_ERROR, EPROTO}, +#endif + {NT_STATUS_FLOAT_OVERFLOW, ERANGE}, + {NT_STATUS_FLOAT_UNDERFLOW, ERANGE}, + {NT_STATUS_INTEGER_OVERFLOW, ERANGE}, + {NT_STATUS_MEDIA_WRITE_PROTECTED, EROFS}, + {NT_STATUS_PIPE_CONNECTED, EISCONN}, + {NT_STATUS_MEMORY_NOT_ALLOCATED, EFAULT}, + {NT_STATUS_FLOAT_INEXACT_RESULT, ERANGE}, + {NT_STATUS_ILL_FORMED_PASSWORD, EACCES}, + {NT_STATUS_PASSWORD_RESTRICTION, EACCES}, + {NT_STATUS_ACCOUNT_RESTRICTION, EACCES}, + {NT_STATUS_PORT_CONNECTION_REFUSED, ECONNREFUSED}, + {NT_STATUS_NAME_TOO_LONG, ENAMETOOLONG}, + {NT_STATUS_REMOTE_DISCONNECT, ESHUTDOWN}, + {NT_STATUS_CONNECTION_DISCONNECTED, ECONNABORTED}, + {NT_STATUS_CONNECTION_RESET, ENETRESET}, +#ifdef ENOTUNIQ + {NT_STATUS_IP_ADDRESS_CONFLICT1, ENOTUNIQ}, + {NT_STATUS_IP_ADDRESS_CONFLICT2, ENOTUNIQ}, +#endif + {NT_STATUS_PORT_MESSAGE_TOO_LONG, EMSGSIZE}, + {NT_STATUS_PROTOCOL_UNREACHABLE, ENOPROTOOPT}, + {NT_STATUS_ADDRESS_ALREADY_EXISTS, EADDRINUSE}, + {NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, + {NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, + {NT_STATUS_RETRY, EAGAIN}, +#ifdef ECOMM + {NT_STATUS_NET_WRITE_FAULT, ECOMM}, +#endif + {NT_STATUS(0), 0} }; -- cgit From d15cd357c702aaad4093f770d557b61a4e12f3a0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 15 Apr 2003 19:51:17 +0000 Subject: merge in metze' smbcquotas patch from HEAD (This used to be commit b6a77048886151435a4a5eeb9a04be44d397c504) --- source3/libsmb/clifile.c | 17 ++++++++++------- source3/libsmb/cliquota.c | 10 +++++----- 2 files changed, 15 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d86f36405d..1163b752b1 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -375,9 +375,11 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) Used in smbtorture. ****************************************************************************/ -int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredAccess, +int cli_nt_create_full(struct cli_state *cli, const char *fname, + uint32 CreatFlags, uint32 DesiredAccess, uint32 FileAttributes, uint32 ShareAccess, - uint32 CreateDisposition, uint32 CreateOptions) + uint32 CreateDisposition, uint32 CreateOptions, + uint8 SecuityFlags) { char *p; int len; @@ -393,9 +395,9 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA SSVAL(cli->outbuf,smb_vwv0,0xFF); if (cli->use_oplocks) - SIVAL(cli->outbuf,smb_ntcreate_Flags, REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); - else - SIVAL(cli->outbuf,smb_ntcreate_Flags, 0); + CreatFlags |= (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); + + SIVAL(cli->outbuf,smb_ntcreate_Flags, CreatFlags); SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); SIVAL(cli->outbuf,smb_ntcreate_FileAttributes, FileAttributes); @@ -403,6 +405,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition); SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions); SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); + SCVAL(cli->outbuf,smb_ntcreate_SecurityFlags, SecuityFlags); p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ @@ -433,8 +436,8 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 DesiredA int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess) { - return cli_nt_create_full(cli, fname, DesiredAccess, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0); + return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0, + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0, 0x0); } /**************************************************************************** diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index ed808aa1f5..a56a6bd674 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -85,7 +85,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,20) != 0)&& ((qt.usedspace != 0xFFFFFFFF)|| - (IVAL(rdata,20)!=0xFFFFFFFF))) { + (IVAL(rdata,20)!=0xFFFFFFFF)))) { /* more than 32 bits? */ return False; } @@ -98,7 +98,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,28) != 0)&& ((qt.softlim != 0xFFFFFFFF)|| - (IVAL(rdata,28)!=0xFFFFFFFF))) { + (IVAL(rdata,28)!=0xFFFFFFFF)))) { /* more than 32 bits? */ return False; } @@ -111,7 +111,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,36) != 0)&& ((qt.hardlim != 0xFFFFFFFF)|| - (IVAL(rdata,36)!=0xFFFFFFFF))) { + (IVAL(rdata,36)!=0xFFFFFFFF)))) { /* more than 32 bits? */ return False; } @@ -459,7 +459,7 @@ BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_ST #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,28) != 0)&& ((qt.softlim != 0xFFFFFFFF)|| - (IVAL(rdata,28)!=0xFFFFFFFF))) { + (IVAL(rdata,28)!=0xFFFFFFFF)))) { /* more than 32 bits? */ goto cleanup; } @@ -472,7 +472,7 @@ BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_ST #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,36) != 0)&& ((qt.hardlim != 0xFFFFFFFF)|| - (IVAL(rdata,36)!=0xFFFFFFFF))) { + (IVAL(rdata,36)!=0xFFFFFFFF)))) { /* more than 32 bits? */ goto cleanup; } -- cgit From 2cb0b91ed19c0fbbc3bfb1b5a35c6af2acf5b5d7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Apr 2003 10:20:14 +0000 Subject: Store the type of 'sec channel' that we establish to the DC. If we are a workstation, we have to use the workstation type, if we have a BDC account, we must use the BDC type - even if we are pretending to be a workstation at the moment. Also actually store and retreive the last change time, so we can do periodic password changes again (for RPC at least). And finally, a couple of minor fixes to 'net'. Andrew Bartlett (This used to be commit 6e6b7b79edae3efd0197651e9a8ce6775c001cf2) --- source3/libsmb/trusts_util.c | 65 ++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index b8f84ba890..d5a02bb625 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -31,12 +31,13 @@ **********************************************************/ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, unsigned char orig_trust_passwd_hash[16], - unsigned char new_trust_passwd_hash[16]) + unsigned char new_trust_passwd_hash[16], + uint32 sec_channel_type) { NTSTATUS result; uint32 neg_flags = 0x000001ff; - result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); + result = cli_nt_setup_creds(cli, sec_channel_type, orig_trust_passwd_hash, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", @@ -60,7 +61,9 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ **********************************************************/ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - unsigned char orig_trust_passwd_hash[16]) + const char *domain, + unsigned char orig_trust_passwd_hash[16], + uint32 sec_channel_type) { unsigned char new_trust_passwd_hash[16]; char *new_trust_passwd; @@ -74,7 +77,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx E_md4hash(new_trust_passwd, new_trust_passwd_hash); nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, - new_trust_passwd_hash); + new_trust_passwd_hash, sec_channel_type); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", @@ -83,7 +86,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx * Return the result of trying to write the new password * back into the trust account file. */ - if (!secrets_store_machine_password(new_trust_passwd)) { + if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) { nt_status = NT_STATUS_UNSUCCESSFUL; } } @@ -97,22 +100,26 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx already setup the connection to the NETLOGON pipe **********************************************************/ -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, + TALLOC_CTX *mem_ctx, const char *domain) { unsigned char old_trust_passwd_hash[16]; char *up_domain; - + uint32 sec_channel_type = 0; + up_domain = talloc_strdup(mem_ctx, domain); if (!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, - NULL)) { + NULL, &sec_channel_type)) { DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); return NT_STATUS_UNSUCCESSFUL; } - return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); + return trust_pw_change_and_store_it(cli, mem_ctx, domain, + old_trust_passwd_hash, + sec_channel_type); } @@ -127,35 +134,21 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *me BOOL is_trusted_domain(const char* dom_name) { - int enum_ctx = 0; - const int trustdom_size = 10; - int num_domains, i; - TRUSTDOM **domains; - NTSTATUS result; - fstring trustdom_name; DOM_SID trustdom_sid; - TALLOC_CTX *mem_ctx; - - /* - * Query the secrets db as an ultimate source of information - * about trusted domain names. This is PDC or BDC case. - */ - mem_ctx = talloc_init("is_trusted_domain"); - - do { - result = secrets_get_trusted_domains(mem_ctx, &enum_ctx, trustdom_size, - &num_domains, &domains); - /* compare each returned entry against incoming connection's domain */ - for (i = 0; i < num_domains; i++) { - pull_ucs2_fstring(trustdom_name, domains[i]->name); - if (strequal(trustdom_name, dom_name)) { - talloc_destroy(mem_ctx); - return True; - } - } - } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); + char *pass = NULL; + time_t lct; + BOOL ret; - talloc_destroy(mem_ctx); + if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) { + /* + * Query the secrets db as an ultimate source of information + * about trusted domain names. This is PDC or BDC case. + */ + ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct); + SAFE_FREE(pass); + if (ret) + return ret; + } /* * Query the trustdom_cache updated periodically. The only -- cgit From ddf662d11886189151dca188a2eb4f6bd602caa0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 16 Apr 2003 14:45:11 +0000 Subject: More merges from HEAD: - Stephan Kulow's changes (fixing warnings in libsmbclient) - VFS modules - Seperating libs (This used to be commit 6e9b7802335428c88ecf4e44a0e2395ac58e96b5) --- source3/libsmb/cliquota.c | 10 +- source3/libsmb/clirap.c | 2 +- source3/libsmb/libsmb_cache.c | 8 +- source3/libsmb/libsmbclient.c | 293 ++++++++++++++++++++++++++++-------------- 4 files changed, 209 insertions(+), 104 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index a56a6bd674..ed808aa1f5 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -85,7 +85,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,20) != 0)&& ((qt.usedspace != 0xFFFFFFFF)|| - (IVAL(rdata,20)!=0xFFFFFFFF)))) { + (IVAL(rdata,20)!=0xFFFFFFFF))) { /* more than 32 bits? */ return False; } @@ -98,7 +98,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,28) != 0)&& ((qt.softlim != 0xFFFFFFFF)|| - (IVAL(rdata,28)!=0xFFFFFFFF)))) { + (IVAL(rdata,28)!=0xFFFFFFFF))) { /* more than 32 bits? */ return False; } @@ -111,7 +111,7 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,36) != 0)&& ((qt.hardlim != 0xFFFFFFFF)|| - (IVAL(rdata,36)!=0xFFFFFFFF)))) { + (IVAL(rdata,36)!=0xFFFFFFFF))) { /* more than 32 bits? */ return False; } @@ -459,7 +459,7 @@ BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_ST #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,28) != 0)&& ((qt.softlim != 0xFFFFFFFF)|| - (IVAL(rdata,28)!=0xFFFFFFFF)))) { + (IVAL(rdata,28)!=0xFFFFFFFF))) { /* more than 32 bits? */ goto cleanup; } @@ -472,7 +472,7 @@ BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_ST #else /* LARGE_SMB_OFF_T */ if ((IVAL(rdata,36) != 0)&& ((qt.hardlim != 0xFFFFFFFF)|| - (IVAL(rdata,36)!=0xFFFFFFFF)))) { + (IVAL(rdata,36)!=0xFFFFFFFF))) { /* more than 32 bits? */ goto cleanup; } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 224c37046c..f05a65762b 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -233,7 +233,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - p += push_pstring_base(p, workgroup, param); + push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index b1620042f3..67dc686b48 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -50,8 +50,8 @@ struct smbc_server_cache { * This function is only used if the external cache is not enabled */ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, - char * server, char * share, - char * workgroup, char * username) + const char * server, const char * share, + const char * workgroup, const char * username) { struct smbc_server_cache * srvcache = NULL; @@ -108,8 +108,8 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, * returns server_fd on success, -1 on error (not found) * This function is only used if the external cache is not enabled */ -static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, char * server, - char * share, char * workgroup, char * user) +static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, + const char * share, const char * workgroup, const char * user) { struct smbc_server_cache * srv = NULL; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 92353d8c30..69c4d8f7a7 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -52,6 +52,87 @@ extern BOOL in_client; */ static int smbc_initialized = 0; +static int +hex2int( unsigned int _char ) +{ + if ( _char >= 'A' && _char <='F') + return _char - 'A' + 10; + if ( _char >= 'a' && _char <='f') + return _char - 'a' + 10; + if ( _char >= '0' && _char <='9') + return _char - '0'; + return -1; +} + +static void +decode_urlpart(char *segment, size_t sizeof_segment) +{ + int old_length = strlen(segment); + int new_length = 0; + int new_length2 = 0; + int i = 0; + pstring new_segment; + char *new_usegment = 0; + + if ( !old_length ) { + return; + } + + /* make a copy of the old one */ + new_usegment = (char*)malloc( old_length * 3 + 1 ); + + while( i < old_length ) { + int bReencode = False; + unsigned char character = segment[ i++ ]; + if ((character <= ' ') || (character > 127)) + bReencode = True; + + new_usegment [ new_length2++ ] = character; + if (character == '%' ) { + int a = i+1 < old_length ? hex2int( segment[i] ) : -1; + int b = i+1 < old_length ? hex2int( segment[i+1] ) : -1; + if ((a == -1) || (b == -1)) { /* Only replace if sequence is valid */ + /* Contains stray %, make sure to re-encode! */ + bReencode = True; + } else { + /* Valid %xx sequence */ + character = a * 16 + b; /* Replace with value of %dd */ + if (!character) + break; /* Stop at %00 */ + + new_usegment [ new_length2++ ] = (unsigned char) segment[i++]; + new_usegment [ new_length2++ ] = (unsigned char) segment[i++]; + } + } + if (bReencode) { + unsigned int c = character / 16; + new_length2--; + new_usegment [ new_length2++ ] = '%'; + + c += (c > 9) ? ('A' - 10) : '0'; + new_usegment[ new_length2++ ] = c; + + c = character % 16; + c += (c > 9) ? ('A' - 10) : '0'; + new_usegment[ new_length2++ ] = c; + } + + new_segment [ new_length++ ] = character; + } + new_segment [ new_length ] = 0; + + free(new_usegment); + + /* realloc it with unix charset */ + pull_utf8_allocate((void**)&new_usegment, new_segment); + + /* this assumes (very safely) that removing %aa sequences + only shortens the string */ + strncpy(segment, new_usegment, sizeof_segment); + + free(new_usegment); +} + /* * Function to parse a path and turn it into components * @@ -97,7 +178,7 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, p += 2; /* Skip the // or \\ */ if (*p == (char)0) - return 0; + goto decoding; if (*p == '/') { @@ -158,7 +239,7 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, } - if (*p == (char)0) return 0; /* That's it ... */ + if (*p == (char)0) goto decoding; /* That's it ... */ if (!next_token(&p, share, "/", sizeof(fstring))) { @@ -167,9 +248,16 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, } pstrcpy(path, p); - + all_string_sub(path, "/", "\\", 0); + decoding: + decode_urlpart(path, sizeof(pstring)); + decode_urlpart(server, sizeof(fstring)); + decode_urlpart(share, sizeof(fstring)); + decode_urlpart(user, sizeof(fstring)); + decode_urlpart(password, sizeof(fstring)); + return 0; } @@ -267,15 +355,16 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) */ SMBCSRV *smbc_server(SMBCCTX *context, - char *server, char *share, - char *workgroup, char *username, - char *password) + const char *server, const char *share, + fstring workgroup, fstring username, + fstring password) { SMBCSRV *srv=NULL; int auth_called = 0; struct cli_state c; struct nmb_name called, calling; - char *p, *server_n = server; + char *p; + const char *server_n = server; fstring group; pstring ipenv; struct in_addr ip; @@ -729,27 +818,6 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) } - if (!file->file) { - - return context->closedir(context, file); - - } - - if (!cli_close(&file->srv->cli, file->cli_fd)) { - DEBUG(3, ("cli_close failed on %s. purging server.\n", - file->fname)); - /* Deallocate slot and remove the server - * from the server cache if unused */ - errno = smbc_errno(context, &file->srv->cli); - srv = file->srv; - DLIST_REMOVE(context->internal->_files, file); - SAFE_FREE(file->fname); - SAFE_FREE(file); - context->callbacks.remove_unused_server_fn(context, srv); - - return -1; - } - DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); @@ -1003,12 +1071,16 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int case SEEK_END: if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, - NULL, NULL, NULL) && - !cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, - NULL)) { - + NULL, NULL, NULL)) + { + SMB_BIG_UINT b_size = size; + if (!cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &b_size, NULL, NULL, + NULL)) + { errno = EINVAL; return -1; + } else + size = b_size; } file->offset = size + offset; break; @@ -1206,12 +1278,15 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) } if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, - &mode, &size, &c_time, &a_time, &m_time, NULL, &ino) && - !cli_getattrE(&file->srv->cli, file->cli_fd, - &mode, &size, &c_time, &a_time, &m_time)) { + &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) { + SMB_BIG_UINT b_size = size; + if (!cli_getattrE(&file->srv->cli, file->cli_fd, + &mode, &b_size, &c_time, &a_time, &m_time)) { errno = EINVAL; return -1; + } else + size = b_size; } @@ -1264,6 +1339,13 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint { struct smbc_dirent *dirent; int size; + char *u_name = NULL, *u_comment = NULL; + size_t u_name_len = 0, u_comment_len = 0; + + if (name) + u_name_len = push_utf8_allocate(&u_name, name); + if (comment) + u_comment_len = push_utf8_allocate(&u_comment, comment); /* * Allocate space for the dirent, which must be increased by the @@ -1271,8 +1353,7 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint * The null on the name is already accounted for. */ - size = sizeof(struct smbc_dirent) + (name?strlen(name):0) + - (comment?strlen(comment):0) + 1; + size = sizeof(struct smbc_dirent) + u_name_len + u_comment_len + 1; dirent = malloc(size); @@ -1321,14 +1402,17 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint dir->dir_end->dirent = dirent; dirent->smbc_type = type; - dirent->namelen = (name?strlen(name):0); - dirent->commentlen = (comment?strlen(comment):0); + dirent->namelen = u_name_len; + dirent->commentlen = u_comment_len; dirent->dirlen = size; - strncpy(dirent->name, (name?name:""), dirent->namelen + 1); + strncpy(dirent->name, (u_name?u_name:""), dirent->namelen + 1); dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); - strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); + strncpy(dirent->comment, (u_comment?u_comment:""), dirent->commentlen + 1); + + SAFE_FREE(u_comment); + SAFE_FREE(u_name); return 0; @@ -1394,7 +1478,8 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { - fstring server, share, user, password, workgroup; + fstring server, share, user, password; + pstring workgroup; pstring path; SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; @@ -1402,29 +1487,29 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!context || !context->internal || !context->internal->_initialized) { - + DEBUG(4, ("no valid context\n")); errno = EINVAL; return NULL; } if (!fname) { - + DEBUG(4, ("no valid fname\n")); errno = EINVAL; return NULL; - } if (smbc_parse_path(context, fname, server, share, path, user, password)) { - + DEBUG(4, ("no valid path\n")); errno = EINVAL; return NULL; - } + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s'\n", fname, server, share, path)); + if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); + pstrcpy(workgroup, context->workgroup); dir = malloc(sizeof(*dir)); @@ -1445,64 +1530,74 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) dir->dir_list = dir->dir_next = dir->dir_end = NULL; if (server[0] == (char)0) { - + struct in_addr server_ip; if (share[0] != (char)0 || path[0] != (char)0) { - + errno = EINVAL; if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); } return NULL; - } /* We have server and share and path empty ... so list the workgroups */ /* first try to get the LMB for our workgroup, and if that fails, */ /* try the DMB */ - if (!(resolve_name(context->workgroup, &rem_ip, 0x1d) || - resolve_name(context->workgroup, &rem_ip, 0x1b))) { - - errno = EINVAL; /* Something wrong with smb.conf? */ - return NULL; - - } + pstrcpy(workgroup, lp_workgroup()); - dir->dir_type = SMBC_WORKGROUP; + if (!find_master_ip(workgroup, &server_ip)) { + struct user_auth_info u_info; + struct cli_state *cli; - /* find the name of the server ... */ + DEBUG(4, ("Unable to find master browser for workgroup %s\n", + workgroup)); - if (!name_status_find("*", 0, 0, rem_ip, server)) { + /* find the name of the server ... */ + pstrcpy(u_info.username, user); + pstrcpy(u_info.password, password); - DEBUG(0,("Could not get the name of local/domain master browser for server %s\n", server)); - errno = EINVAL; + if (!(cli = get_ipc_connect_master_ip_bcast(workgroup, &u_info))) { + DEBUG(4, ("Unable to find master browser by " + "broadcast\n")); + errno = ENOENT; return NULL; + } - } - - /* - * Get a connection to IPC$ on the server if we do not already have one - */ + fstrcpy(server, cli->desthost); - srv = smbc_server(context, server, "IPC$", workgroup, user, password); + cli_shutdown(cli); + } else { + if (!name_status_find("*", 0, 0, server_ip, server)) { + errno = ENOENT; + return NULL; + } + } - if (!srv) { + DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - - return NULL; + /* + * Get a connection to IPC$ on the server if we do not already have one + */ - } + srv = smbc_server(context, server, "IPC$", workgroup, user, password); + if (!srv) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; + } + dir->srv = srv; + dir->dir_type = SMBC_WORKGROUP; /* Now, list the stuff ... */ - if (!cli_NetServerEnum(&srv->cli, workgroup, 0x80000000, list_fn, + if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_fn, (void *)dir)) { if (dir) { @@ -1560,7 +1655,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) srv = smbc_server(context, buserver, "IPC$", workgroup, user, password); if (!srv) { - + DEBUG(0, ("got no contact to IPC$\n")); if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -2058,6 +2153,7 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { + off_t ret_val; /* Squash warnings about cast */ if (!context || !context->internal || !context->internal->_initialized) { @@ -2081,7 +2177,11 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) } - return (off_t) dir->dir_next; + /* + * We return the pointer here as the offset + */ + ret_val = (int)dir->dir_next; + return ret_val; } @@ -2121,8 +2221,9 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) { - struct smbc_dirent *dirent = (struct smbc_dirent *)offset; - struct smbc_dir_list *list_ent = NULL; + long int l_offset = offset; /* Handle problems of size */ + struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; + struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; if (!context || !context->internal || !context->internal->_initialized) { @@ -2569,10 +2670,10 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) if (!smbc_initialized) { /* Do some library wide intialisations the first time we get called */ - /* Do we still need this ? */ - DEBUGLEVEL = 10; + /* Set this to what the user wants */ + DEBUGLEVEL = context->debug; - setup_logging( "libsmbclient", False); + setup_logging( "libsmbclient", True); /* Here we would open the smb.conf file if needed ... */ @@ -2587,13 +2688,16 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) if (!lp_load(conf, True, False, False)) { /* - * Hmmm, what the hell do we do here ... we could not parse the - * config file ... We must return an error ... and keep info around - * about why we failed + * Well, if that failed, try the dyn_CONFIGFILE + * Which points to the standard locn, and if that + * fails, silently ignore it and use the internal + * defaults ... */ - - errno = ENOENT; /* FIXME: Figure out the correct error response */ - return NULL; + + if (!lp_load(dyn_CONFIGFILE, True, False, False)) { + DEBUG(5, ("Could not load either config file: %s or %s\n", + conf, dyn_CONFIGFILE)); + } } reopen_logs(); /* Get logging working ... */ @@ -2640,8 +2744,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); } } - DEBUG(0,("Using netbios name %s.\n", context->netbios_name)); - + + DEBUG(1, ("Using netbios name %s.\n", context->netbios_name)); if (!context->workgroup) { if (lp_workgroup()) { @@ -2652,7 +2756,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) context->workgroup = strdup("samba"); } } - DEBUG(0,("Using workgroup %s.\n", context->workgroup)); + + DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); /* shortest timeout is 1 second */ if (context->timeout > 0 && context->timeout < 1000) -- cgit From 8aa04b531e261dfc5f3ee4fa398ff5623376d843 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2003 08:13:29 +0000 Subject: Merge a trivial fix across from HEAD. Not that this would work now... Volker (This used to be commit 8c70f657cfb2f2b32fbaa31112d7953a3a6dc775) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 9bbf7ef91c..9b473fa736 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -275,7 +275,7 @@ static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli) { BOOL good; NTSTATUS nt_status; - DATA_BLOB sig = data_blob(&cli->outbuf[smb_ss_field], 8); + DATA_BLOB sig = data_blob(&cli->inbuf[smb_ss_field], 8); NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; -- cgit From 1e2147fc0f677914fb2e3168b4fd4d7ddb4b9867 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Apr 2003 13:00:39 +0000 Subject: Merge SMB signing, cli buffer clobber and NTLMSSP signing tweaks from HEAD. (This used to be commit c6c4f69b8ddc500890a65829e1b9fb7a3e9839e9) --- source3/libsmb/clientgen.c | 15 +++++++++++---- source3/libsmb/clierror.c | 12 ++++++++---- source3/libsmb/ntlmssp.c | 2 +- source3/libsmb/ntlmssp_sign.c | 26 ++++++++++++++++++++++---- source3/libsmb/smb_signing.c | 15 ++++++++------- 5 files changed, 50 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 81b3bbcab5..81cb61d757 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -118,7 +118,10 @@ BOOL cli_receive_smb(struct cli_state *cli) } if (!cli_check_sign_mac(cli)) { - DEBUG(0, ("SMB Signiture verification failed on incoming packet!\n")); + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); + cli->smb_rw_error = READ_BAD_SIG; + close(cli->fd); + cli->fd = -1; return False; }; return True; @@ -259,9 +262,6 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (getenv("CLI_FORCE_DOSERR")) cli->force_dos_errors = True; - /* initialise signing */ - cli_null_set_signing(cli); - if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; @@ -274,6 +274,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); + /* just becouse we over-allocate, doesn't mean it's right to use it */ + clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); + clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); + + /* initialise signing */ + cli_null_set_signing(cli); + cli->nt_pipe_fnum = 0; cli->saved_netlogon_pipe_fnum = 0; diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index cea736ef18..9ee181a90f 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -96,17 +96,21 @@ const char *cli_errstr(struct cli_state *cli) break; case READ_EOF: slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Call returned zero bytes (EOF)\n" ); + "Call returned zero bytes (EOF)" ); break; case READ_ERROR: slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Read error: %s\n", strerror(errno) ); + "Read error: %s", strerror(errno) ); break; case WRITE_ERROR: slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Write error: %s\n", strerror(errno) ); + "Write error: %s", strerror(errno) ); break; - default: + case READ_BAD_SIG: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Server packet had invalid SMB signiture!"); + break; + default: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Unknown error code %d\n", cli->smb_rw_error ); break; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index c179b98abf..d54655d17f 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -385,7 +385,7 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, } else if (ntlmssp_command == NTLMSSP_AUTH) { return ntlmssp_server_auth(ntlmssp_state, request, reply); } else { - DEBUG(1, ("unknown NTLMSSP command %u expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); + DEBUG(1, ("unknown NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); return NT_STATUS_INVALID_PARAMETER; } } diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 8f6bd0c691..86faf1f5e6 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -92,8 +92,14 @@ static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], calc_hash(hash, digest, 16); } +enum ntlmssp_direction { + NTLMSSP_SEND, + NTLMSSP_RECEIVE +}; + static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state, const uchar *data, size_t length, + enum ntlmssp_direction direction, DATA_BLOB *sig) { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -110,8 +116,14 @@ static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_stat if (!msrpc_gen(sig, "Bd", digest, sizeof(digest), ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } - - NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, sig->data, sig->length); + switch (direction) { + case NTLMSSP_SEND: + NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data, sig->length); + break; + case NTLMSSP_RECEIVE: + NTLMSSPcalc_ap(ntlmssp_state->srv_sign_hash, sig->data, sig->length); + break; + } } else { uint32 crc; crc = crc32_calc_buffer(data, length); @@ -129,7 +141,7 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, DATA_BLOB *sig) { ntlmssp_state->ntlmssp_seq_num++; - return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, sig); + return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig); } /** @@ -151,7 +163,7 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, } nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, - length, &local_sig); + length, NTLMSSP_RECEIVE, &local_sig); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); @@ -161,6 +173,12 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, if (memcmp(sig->data, local_sig.data, MIN(sig->length, local_sig.length)) == 0) { return NT_STATUS_OK; } else { + DEBUG(5, ("BAD SIG: wanted signature of\n")); + dump_data(5, local_sig.data, local_sig.length); + + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, sig->data, sig->length); + DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); return NT_STATUS_ACCESS_DENIED; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 9b473fa736..4e9b895a1b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -160,11 +160,6 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) SIVAL(sequence_buf, 0, data->reply_seq_num); SIVAL(sequence_buf, 4, 0); - if (smb_len(cli->inbuf) < (offset_end_of_sig - 4)) { - DEBUG(1, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); - return False; - } - /* get a copy of the server-sent mac */ memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); @@ -460,8 +455,14 @@ void cli_caclulate_sign_mac(struct cli_state *cli) BOOL cli_check_sign_mac(struct cli_state *cli) { BOOL good; - good = cli->sign_info.check_incoming_message(cli); - + + if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); + good = False; + } else { + good = cli->sign_info.check_incoming_message(cli); + } + if (!good) { if (cli->sign_info.doing_signing) { return False; -- cgit From f071020f5e49837154581c97c5af5f84d0e2de89 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 21 Apr 2003 14:09:03 +0000 Subject: Merge from HEAD - save the type of channel used to contact the DC. This allows us to join as a BDC, without appearing on the network as one until we have the database replicated, and the admin changes the configuration. This also change the SID retreval order from secrets.tdb, so we no longer require a 'net rpc getsid' - the sid fetch during the domain join is sufficient. Also minor fixes to 'net'. Andrew Bartlett (This used to be commit 876e00fd112e4aaf7519eec27f382eb99ec7562a) --- source3/libsmb/trust_passwd.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c index cf9fd58b13..0d015128a6 100644 --- a/source3/libsmb/trust_passwd.c +++ b/source3/libsmb/trust_passwd.c @@ -1,7 +1,7 @@ /* * Unix SMB/CIFS implementation. - * Routines to change trust account passwords. - * Copyright (C) Andrew Bartlett 2001. + * Routines to operate on various trust relationships + * Copyright (C) Andrew Bartlett 2001 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,12 +30,13 @@ **********************************************************/ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, unsigned char orig_trust_passwd_hash[16], - unsigned char new_trust_passwd_hash[16]) + unsigned char new_trust_passwd_hash[16], + uint32 sec_channel_type) { NTSTATUS result; uint32 neg_flags = 0x000001ff; - result = cli_nt_setup_creds(cli, get_sec_chan(), orig_trust_passwd_hash, &neg_flags, 2); + result = cli_nt_setup_creds(cli, sec_channel_type, orig_trust_passwd_hash, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", @@ -59,7 +60,9 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ **********************************************************/ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, - unsigned char orig_trust_passwd_hash[16]) + const char *domain, + unsigned char orig_trust_passwd_hash[16], + uint32 sec_channel_type) { unsigned char new_trust_passwd_hash[16]; char *new_trust_passwd; @@ -73,7 +76,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx E_md4hash(new_trust_passwd, new_trust_passwd_hash); nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, - new_trust_passwd_hash); + new_trust_passwd_hash, sec_channel_type); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", @@ -82,7 +85,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx * Return the result of trying to write the new password * back into the trust account file. */ - if (!secrets_store_machine_password(new_trust_passwd)) { + if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) { nt_status = NT_STATUS_UNSUCCESSFUL; } } @@ -96,21 +99,26 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx already setup the connection to the NETLOGON pipe **********************************************************/ -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, +NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, + TALLOC_CTX *mem_ctx, const char *domain) { unsigned char old_trust_passwd_hash[16]; char *up_domain; - + uint32 sec_channel_type = 0; + up_domain = talloc_strdup(mem_ctx, domain); if (!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, - NULL)) { + NULL, &sec_channel_type)) { DEBUG(0, ("could not fetch domain secrets for domain %s!\n", domain)); return NT_STATUS_UNSUCCESSFUL; } - return trust_pw_change_and_store_it(cli, mem_ctx, old_trust_passwd_hash); + return trust_pw_change_and_store_it(cli, mem_ctx, domain, + old_trust_passwd_hash, + sec_channel_type); -} +} + -- cgit From 2206df6b30c4992daa17257287390421cfc0662d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Apr 2003 08:12:34 +0000 Subject: Merge torture tests from HEAD - it looks like we had rather an incomplete merge last time. I hope this might fix a few failures on the build farm too. Andrew Bartlett (This used to be commit 0c837126923cc30fa60223a5a68d4f527971cc7b) --- source3/libsmb/clifile.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 1163b752b1..b771e135f4 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -945,7 +945,6 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) /**************************************************************************** Check for existance of a dir. ****************************************************************************/ - BOOL cli_chkpath(struct cli_state *cli, const char *path) { pstring path2; @@ -1052,3 +1051,34 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) return SVAL(cli->inbuf,smb_vwv0); } + + +/* + send a raw ioctl - used by the torture code +*/ +NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *blob) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 3, 0, True); + SCVAL(cli->outbuf,smb_com,SMBioctl); + cli_setup_packet(cli); + + SSVAL(cli->outbuf, smb_vwv0, fnum); + SSVAL(cli->outbuf, smb_vwv1, code>>16); + SSVAL(cli->outbuf, smb_vwv2, (code&0xFFFF)); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + } + + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } + + *blob = data_blob(NULL, 0); + + return NT_STATUS_OK; +} -- cgit From 2e9c2084a640fd9940bc3f17c42e9edc1f015152 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Apr 2003 09:26:07 +0000 Subject: Add a check to ensure that the server returns the correct device type, not just the correct error. This should help us avoid breaking NT4 IPC$ connections, for example. This has required that we don't overwrite the device type for IPC$ in our tcon&X code, but only smbwrapper even uses it, and a server that doesn't send a correct dev type breaks other things pretty badly. In any case, I'll 'fix' smbwrapper :-). Andrew Bartlett (This used to be commit a93057efcb6e639be05b7bdcb9729ed8f39f5f62) --- source3/libsmb/cliconnect.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4bfa694e63..9dddb6a163 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -810,9 +810,6 @@ BOOL cli_send_tconX(struct cli_state *cli, clistr_pull(cli, cli->dev, smb_buf(cli->inbuf), sizeof(fstring), -1, STR_TERMINATE|STR_ASCII); - if (strcasecmp(share,"IPC$")==0) - fstrcpy(cli->dev, "IPC"); - if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3) { /* almost certainly win95 - enable bug fixes */ -- cgit From 1a9394195d0c53c23b9377ce122f399fa914f58c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Apr 2003 11:54:56 +0000 Subject: Merge HEAD's winbind into 3.0. This includes the 'SIDs Rule' patch, mimir's trusted domains cacheing code, the winbind_idmap abstraction (not idmap proper, but the stuff that held up the winbind LDAP backend in HEAD). Andrew Bartlett (This used to be commit d4d5e6c2ee6383c6cceb5d449aa2ba6c83eb0666) --- source3/libsmb/netlogon_unigrp.c | 37 ++++++++---- source3/libsmb/trust_passwd.c | 124 --------------------------------------- 2 files changed, 25 insertions(+), 136 deletions(-) delete mode 100644 source3/libsmb/trust_passwd.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c index fa2fe32f35..466410d800 100644 --- a/source3/libsmb/netlogon_unigrp.c +++ b/source3/libsmb/netlogon_unigrp.c @@ -22,6 +22,7 @@ */ #include "includes.h" +#define UNIGROUP_PREFIX "UNIGROUP" /* Handle for netlogon_unigrp.tdb database. It is used internally @@ -50,17 +51,22 @@ BOOL uni_group_cache_init(void) BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) { TDB_DATA key,data; - fstring keystr; - int i; + fstring keystr, sid_string; + DOM_SID user_sid; + unsigned int i; if (!uni_group_cache_init()) { DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n")); return False; } - /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s/%d", - sid_string_static(&user->dom_sid.sid), user->user_rid); + sid_copy(&user_sid, &user->dom_sid.sid); + sid_append_rid(&user_sid, user->user_rid); + + /* Prepare key as USER-SID string */ + slprintf(keystr, sizeof(keystr), "%s/%s", + UNIGROUP_PREFIX, + sid_to_string(sid_string, &user_sid)); key.dptr = keystr; key.dsize = strlen(keystr) + 1; @@ -90,14 +96,15 @@ BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) and elements are array[0] ... array[num_elements-1] */ -uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, +DOM_SID **uni_group_cache_fetch(DOM_SID *domain, DOM_SID *user_sid, TALLOC_CTX *mem_ctx, uint32 *num_groups) { TDB_DATA key,data; fstring keystr; - uint32 *groups; + DOM_SID **groups; uint32 i; uint32 group_count; + fstring sid_string; if (!domain) { DEBUG(1,("uni_group_cache_fetch: expected non-null domain sid\n")); @@ -123,8 +130,9 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, *num_groups = 0; /* Fetch universal groups */ - slprintf(keystr, sizeof(keystr), "%s/%d", - sid_string_static(domain), user_rid); + slprintf(keystr, sizeof(keystr), "%s/%s", + UNIGROUP_PREFIX, + sid_to_string(sid_string, user_sid)); key.dptr = keystr; key.dsize = strlen(keystr) + 1; data = tdb_fetch(netlogon_unigrp_tdb, key); @@ -136,12 +144,17 @@ uint32* uni_group_cache_fetch(DOM_SID *domain, uint32 user_rid, /* Transfer data to receiver's memory context */ group_count = IVAL(&((uint32*)data.dptr)[0],0); - groups = talloc(mem_ctx, (group_count)*sizeof(uint32)); + groups = talloc(mem_ctx, (group_count)*sizeof(*groups)); if (groups) { for(i=0; i Date: Thu, 1 May 2003 02:51:49 +0000 Subject: Turn down some DEBUG()s and remove some duplicate code spotted by dfenwick. Andrew Bartlett (This used to be commit 542a8b1817d3930e03e08e16e9711cacceb6df61) --- source3/libsmb/trusts_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index d5a02bb625..6244c844f2 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -40,7 +40,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ result = cli_nt_setup_creds(cli, sec_channel_type, orig_trust_passwd_hash, &neg_flags, 2); if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("just_change_the_password: unable to setup creds (%s)!\n", + DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", nt_errstr(result))); return result; } -- cgit From 8b69f163359b7f917b13838cf7e88e7afb591bb0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 4 May 2003 01:05:39 +0000 Subject: Add doco to our SMB signing code. This should make it clearer what magic numbers refer to the magic numbers in the CIFS spec, and what bits and peices are being appended into the MD5 calculation where. Andrew Bartlett (This used to be commit 7f1c271cfb04f621e36f1acf60979652e82dc6f4) --- source3/libsmb/smb_signing.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4e9b895a1b..76e3eb8988 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -21,6 +21,15 @@ #include "includes.h" +/* the SNIA Technical Reference tells us that this is '40 or 44' bytes + long, but NTLM only uses 40, and we don't know what value to use for + NTLMv2 */ + +/* my guess is 64, and other evidence indicates we don't setup the + session key correctly, so that's why it's failing */ + +#define SIMPLE_SMB_SIGNING_MAC_KEY_LEN 64 + struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; @@ -111,6 +120,9 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. + * + * We put the sequence into the packet, becouse we are going + * to copy over it anyway. */ SIVAL(cli->outbuf, smb_ss_field, data->send_seq_num); @@ -132,7 +144,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); /* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signitures...*/ + Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; data->reply_seq_num = data->send_seq_num; data->send_seq_num++; @@ -155,6 +167,8 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. + * + * We do this here, to avoid modifying the packet. */ SIVAL(sequence_buf, 0, data->reply_seq_num); @@ -163,15 +177,28 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) /* get a copy of the server-sent mac */ memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + /* Calculate the 16 byte MAC - but don't alter the data in the + incoming packet. + + This makes for a bit for fussing about, but it's not too bad. + */ MD5Init(&md5_ctx); + + /* intialise with the key */ MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); + + /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); + + /* copy in the sequence number, instead of the signature */ MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); - + + /* copy in the rest of the packet in, skipping the signature */ MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, smb_len(cli->inbuf) - (offset_end_of_sig - 4)); + + /* caclulate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); @@ -219,10 +246,10 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data = smb_xmalloc(sizeof(*data)); cli->sign_info.signing_context = data; - data->mac_key = data_blob(NULL, MIN(response.length + 16, 40)); + data->mac_key = data_blob(NULL, MIN(response.length + 16, SIMPLE_SMB_SIGNING_MAC_KEY_LEN)); memcpy(&data->mac_key.data[0], user_session_key, 16); - memcpy(&data->mac_key.data[16],response.data, MIN(response.length, 40 - 16)); + memcpy(&data->mac_key.data[16],response.data, MIN(response.length, SIMPLE_SMB_SIGNING_MAC_KEY_LEN - 16)); /* Initialise the sequence number */ data->send_seq_num = 0; -- cgit From 423bd582f4f0f03ff086054060954e8e23cd02cd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 May 2003 05:15:54 +0000 Subject: Allow the NTLMv2 functions to spit out both possible varients on the session key, so we can test it in ntlm_auth. I suspect the 'lm' version doesn't exist, but it's easy to change back. Andrew Bartlett (This used to be commit 5efd95622c411f123660b6613b86c7a68bba68e8) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/ntlmssp.c | 2 +- source3/libsmb/smbencrypt.c | 34 +++++++++++++++++++++++----------- 3 files changed, 25 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9dddb6a163..982cbfff06 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -261,7 +261,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); if (!SMBNTLMv2encrypt(user, workgroup, pass, server_chal, - &lm_response, &nt_response, &session_key)) { + &lm_response, &nt_response, NULL, &session_key)) { data_blob_free(&server_chal); return False; } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index d54655d17f..356bb0c4fe 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -501,7 +501,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st if (!SMBNTLMv2encrypt(ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->password, challenge_blob, - &lm_response, &nt_response, &session_key)) { + &lm_response, &nt_response, NULL, &session_key)) { data_blob_free(&challenge_blob); return NT_STATUS_NO_MEMORY; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 28160d9609..bab18a07b1 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -76,10 +76,9 @@ void E_deshash(const char *passwd, uchar p16[16]) { fstring dospwd; ZERO_STRUCT(dospwd); - ZERO_STRUCTP(p16); /* Password must be converted to DOS charset - null terminated, uppercase. */ - push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); + push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16(dospwd, p16); @@ -324,7 +323,8 @@ static DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, const DATA_BLOB server_chal, DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *session_key) + DATA_BLOB *lm_session_key, + DATA_BLOB *nt_session_key) { uchar nt_hash[16]; uchar ntlm_v2_hash[16]; @@ -338,18 +338,30 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password return False; } - *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); + if (nt_response) { + *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); + if (nt_session_key) { + *nt_session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, nt_session_key->data); + } + } /* LMv2 */ - *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); - - *session_key = data_blob(NULL, 16); + if (lm_response) { + *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); + if (lm_session_key) { + *lm_session_key = data_blob(NULL, 16); + + /* The NTLMv2 calculations also provide a session key, for signing etc later */ + /* use only the first 16 bytes of nt_response for session key */ + SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data); + } + } - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, session_key->data); - return True; } -- cgit From 1af398b16913b9ae66ac66c4f65134dc4c8fb195 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 May 2003 02:00:58 +0000 Subject: Force ASCII for client messages. Patch from David Lee Jeremy. (This used to be commit f219e8309c7d17b332873e9283ab3c3796e7e799) --- source3/libsmb/climessage.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 5f6ce36133..2b1be75089 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -40,9 +40,9 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, username, -1, STR_TERMINATE); + p += clistr_push(cli, p, username, -1, STR_ASCII|STR_TERMINATE); *p++ = 4; - p += clistr_push(cli, p, host, -1, STR_TERMINATE); + p += clistr_push(cli, p, host, -1, STR_ASCII|STR_TERMINATE); cli_setup_bcc(cli, p); @@ -128,4 +128,3 @@ BOOL cli_message_end(struct cli_state *cli, int grp) return True; } - -- cgit From 2752f4a533a5546df794aa7c02f6765185ccc4cc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 7 May 2003 12:58:59 +0000 Subject: SMB Signing with NTLMv2 works! (well, under certain conditions :-) There is no length limit on the size of the authentication response added into the MD5 hash. (We had previously limited this to lengths like 40, 44 or 64 in attempts to make sense of what the SNIA spec tells us). Instead, the entire authentication response is added in. Currently, this only works on a Win2k domain members with a Samba PDC, becouse our NTLMv2 code currently fails against an Win2k PDC. However, this splits the problem in half - particularly as the NTLMv2 format is known, and even has an ethereal disector! (thanks tpot). Andrew Bartlett (This used to be commit 7645d3d28afbb8eea502c0e063df3afb3aa812f4) --- source3/libsmb/smb_signing.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 76e3eb8988..0f56cd15d9 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -21,15 +21,6 @@ #include "includes.h" -/* the SNIA Technical Reference tells us that this is '40 or 44' bytes - long, but NTLM only uses 40, and we don't know what value to use for - NTLMv2 */ - -/* my guess is 64, and other evidence indicates we don't setup the - session key correctly, so that's why it's failing */ - -#define SIMPLE_SMB_SIGNING_MAC_KEY_LEN 64 - struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; @@ -246,10 +237,10 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data = smb_xmalloc(sizeof(*data)); cli->sign_info.signing_context = data; - data->mac_key = data_blob(NULL, MIN(response.length + 16, SIMPLE_SMB_SIGNING_MAC_KEY_LEN)); + data->mac_key = data_blob(NULL, response.length + 16); memcpy(&data->mac_key.data[0], user_session_key, 16); - memcpy(&data->mac_key.data[16],response.data, MIN(response.length, SIMPLE_SMB_SIGNING_MAC_KEY_LEN - 16)); + memcpy(&data->mac_key.data[16],response.data, response.length); /* Initialise the sequence number */ data->send_seq_num = 0; -- cgit From d1da999e0a84939e372ebe590861376e2c0075b3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 May 2003 08:02:52 +0000 Subject: This puts real netlogon connection caching to winbind. This becomes important once we start doing schannel, as there would be a lot more roundtrips for the second PIPE open and bind. With this patch logging in to a member server is a matter of two (three if you count the ack...) packets between us and the DC. Volker (This used to be commit 5b3cb7725a974629d0bd8b707bc2940c36b8745e) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 18ce5e4bd9..2c5a92ff10 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -704,8 +704,8 @@ success: Resolve via "lmhosts" method. *********************************************************/ -static BOOL resolve_lmhosts(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) +BOOL resolve_lmhosts(const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) { /* * "lmhosts" means parse the local lmhosts file. -- cgit From 7f0740b7c044ebc2c0720c2eb28d4a748cb86875 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 8 May 2003 08:12:57 +0000 Subject: Revert a patch that somehow slipped in... Volker (This used to be commit 6cde3d4d655bbe1d81e68ec2ec7a23669ac82120) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2c5a92ff10..18ce5e4bd9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -704,8 +704,8 @@ success: Resolve via "lmhosts" method. *********************************************************/ -BOOL resolve_lmhosts(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) +static BOOL resolve_lmhosts(const char *name, int name_type, + struct in_addr **return_iplist, int *return_count) { /* * "lmhosts" means parse the local lmhosts file. -- cgit From d06f95ca78834403a602e4c1d64e13e059f3017e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 May 2003 14:42:20 +0000 Subject: Finally get NTLMv2 working on the client! With big thanks to tpot for the ethereal disector, and for the base code behind this, we now fully support NTLMv2 as a client. In particular, we support it with direct domain logons (tested with ntlm_auth --diagnostics), with 'old style' session setups, and with NTLMSSP. In fact, for NTLMSSP we recycle one of the parts of the server's reply directly... (we might need to parse for unicode issues later). In particular, a Win2k domain controller now supplies us with a session key for this password, which means that doman joins, and non-spnego SMB signing are now supported with NTLMv2! Andrew Bartlett (This used to be commit 9f6a26769d345d319ec167cd0e82a45e1207ed81) --- source3/libsmb/cliconnect.c | 15 ++++-- source3/libsmb/ntlmssp.c | 10 ++-- source3/libsmb/smbencrypt.c | 112 +++++++++++++++++++++++++++++++++----------- 3 files changed, 102 insertions(+), 35 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 982cbfff06..f58a458aba 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -257,14 +257,23 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (passlen != 24) { if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; - + DATA_BLOB names_blob; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); - if (!SMBNTLMv2encrypt(user, workgroup, pass, server_chal, - &lm_response, &nt_response, NULL, &session_key)) { + /* note that the 'workgroup' here is a best guess - we don't know + the server's domain at this point. The 'server name' is also + dodgy... + */ + names_blob = NTLMv2_generate_names_blob(cli->called.name, workgroup); + + if (!SMBNTLMv2encrypt(user, workgroup, pass, &server_chal, + &names_blob, + &lm_response, &nt_response, &session_key)) { + data_blob_free(&names_blob); data_blob_free(&server_chal); return False; } + data_blob_free(&names_blob); data_blob_free(&server_chal); } else { diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 356bb0c4fe..636e384e65 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -487,9 +487,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st } SAFE_FREE(server_domain); - data_blob_free(&struct_blob); - if (challenge_blob.length != 8) { + data_blob_free(&struct_blob); return NT_STATUS_INVALID_PARAMETER; } @@ -500,9 +499,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st if (!SMBNTLMv2encrypt(ntlmssp_state->user, ntlmssp_state->domain, - ntlmssp_state->password, challenge_blob, - &lm_response, &nt_response, NULL, &session_key)) { + ntlmssp_state->password, &challenge_blob, + &struct_blob, + &lm_response, &nt_response, &session_key)) { data_blob_free(&challenge_blob); + data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } } else { @@ -522,6 +523,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } + data_blob_free(&struct_blob); /* this generates the actual auth packet */ if (!msrpc_gen(next_request, auth_gen_string, diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index bab18a07b1..c1b3880299 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -249,21 +249,21 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ /* Does the md5 encryption from the NT hash for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], - const DATA_BLOB srv_chal, - const DATA_BLOB cli_chal, + const DATA_BLOB *srv_chal, + const DATA_BLOB *cli_chal, uchar resp_buf[16]) { HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); - hmac_md5_update(srv_chal.data, srv_chal.length, &ctx); - hmac_md5_update(cli_chal.data, cli_chal.length, &ctx); + hmac_md5_update(srv_chal->data, srv_chal->length, &ctx); + hmac_md5_update(cli_chal->data, cli_chal->length, &ctx); hmac_md5_final(resp_buf, &ctx); #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); - dump_data(100, srv_chal.data, srv_chal.length); - dump_data(100, cli_chal.data, cli_chal.length); + dump_data(100, srv_chal->data, srv_chal->length); + dump_data(100, cli_chal->data, cli_chal->length); dump_data(100, resp_buf, 16); #endif } @@ -294,36 +294,98 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -static DATA_BLOB NTLMv2_generate_response(uchar ntlm_v2_hash[16], - DATA_BLOB server_chal, size_t client_chal_length) +DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, + const char *domain) +{ + DATA_BLOB names_blob = data_blob(NULL, 0); + + msrpc_gen(&names_blob, "aaa", + True, NTLMSSP_NAME_TYPE_DOMAIN, domain, + True, NTLMSSP_NAME_TYPE_SERVER, hostname, + True, 0, ""); + return names_blob; +} + +static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) +{ + uchar client_chal[8]; + DATA_BLOB response = data_blob(NULL, 0); + char long_date[8]; + + generate_random_buffer(client_chal, sizeof(client_chal), False); + + put_long_date(long_date, time(NULL)); + + /* See http://www.ubiqx.org/cifs/SMB.html#SMB.8.5 */ + + msrpc_gen(&response, "ddbbdb", + 0x00000101, /* Header */ + 0, /* 'Reserved' */ + long_date, 8, /* Timestamp */ + client_chal, 8, /* client challenge */ + 0, /* Unknown */ + names_blob->data, names_blob->length); /* End of name list */ + + return response; +} + +static DATA_BLOB NTLMv2_generate_response(const uchar ntlm_v2_hash[16], + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob) { uchar ntlmv2_response[16]; DATA_BLOB ntlmv2_client_data; DATA_BLOB final_response; /* NTLMv2 */ + /* generate some data to pass into the response function - including + the hostname and domain name of the server */ + ntlmv2_client_data = NTLMv2_generate_client_data(names_blob); - /* We also get to specify some random data */ - ntlmv2_client_data = data_blob(NULL, client_chal_length); - generate_random_buffer(ntlmv2_client_data.data, ntlmv2_client_data.length, False); - /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, ntlmv2_client_data, ntlmv2_response); + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &ntlmv2_client_data, ntlmv2_response); - /* put it into nt_response, for the code below to put into the packet */ - final_response = data_blob(NULL, ntlmv2_client_data.length + sizeof(ntlmv2_response)); + final_response = data_blob(NULL, sizeof(ntlmv2_response) + ntlmv2_client_data.length); + memcpy(final_response.data, ntlmv2_response, sizeof(ntlmv2_response)); - /* after the first 16 bytes is the random data we generated above, so the server can verify us with it */ - memcpy(final_response.data + sizeof(ntlmv2_response), ntlmv2_client_data.data, ntlmv2_client_data.length); + + memcpy(final_response.data+sizeof(ntlmv2_response), + ntlmv2_client_data.data, ntlmv2_client_data.length); + data_blob_free(&ntlmv2_client_data); return final_response; } +static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16], + const DATA_BLOB *server_chal) +{ + uchar lmv2_response[16]; + DATA_BLOB lmv2_client_data = data_blob(NULL, 8); + DATA_BLOB final_response = data_blob(NULL, 24); + + /* LMv2 */ + /* client-supplied random data */ + generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False); + + /* Given that data, and the challenge from the server, generate a response */ + SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); + memcpy(final_response.data, lmv2_response, sizeof(lmv2_response)); + + /* after the first 16 bytes is the random data we generated above, + so the server can verify us with it */ + memcpy(final_response.data+sizeof(lmv2_response), + lmv2_client_data.data, lmv2_client_data.length); + + data_blob_free(&lmv2_client_data); + + return final_response; +} + BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, - const DATA_BLOB server_chal, + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *lm_session_key, DATA_BLOB *nt_session_key) { uchar nt_hash[16]; @@ -339,7 +401,8 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password } if (nt_response) { - *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 64 /* pick a number, > 8 */); + *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, + names_blob); if (nt_session_key) { *nt_session_key = data_blob(NULL, 16); @@ -352,14 +415,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password /* LMv2 */ if (lm_response) { - *lm_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, 8); - if (lm_session_key) { - *lm_session_key = data_blob(NULL, 16); - - /* The NTLMv2 calculations also provide a session key, for signing etc later */ - /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, lm_response->data, lm_session_key->data); - } + *lm_response = LMv2_generate_response(ntlm_v2_hash, server_chal); } return True; -- cgit From 1263c6e36c0a4608867259a651b0e8d1e6cc53f9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 10 May 2003 02:05:24 +0000 Subject: Fix from Tom.Lackemann@falconstor.com to correctly set the flags based on the security entries sent. Jeremy. (This used to be commit 45953d59f707b58e66b980512afc7f929d360ad5) --- source3/libsmb/clisecdesc.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 20154dbeb2..d86a9022a6 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -79,6 +79,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) char param[8]; char *rparam=NULL, *rdata=NULL; int rparam_count=0, rdata_count=0; + uint32 sec_info = 0; TALLOC_CTX *mem_ctx; prs_struct pd; BOOL ret = False; @@ -97,7 +98,14 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) } SIVAL(param, 0, fnum); - SSVAL(param, 4, 0x7); + + if (sd->off_dacl) + sec_info |= DACL_SECURITY_INFORMATION; + if (sd->off_owner_sid) + sec_info |= OWNER_SECURITY_INFORMATION; + if (sd->off_grp_sid) + sec_info |= GROUP_SECURITY_INFORMATION; + SSVAL(param, 4, sec_info); if (!cli_send_nt_trans(cli, NT_TRANSACT_SET_SECURITY_DESC, -- cgit From e8573c8fa928602fd979d5ac45c692e7464f0aad Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 12 May 2003 01:20:17 +0000 Subject: Add NT quota support. Patch from Stefan (metze) Metzemacher 1. Allows to change quota settings for shared mount points from Win2K and WinXP from Explorer properties tab 2. Disabled by default and when requested, will be probed and enabled only on Linux where it works 3. Was tested for approx. two weeks now on Linux by two independent QA teams, have not found any bugs so far Documentation to follow (This used to be commit 4bf022ce9e45be85609426762ba2644ac2031326) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index e6047847ae..166229ec6c 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -533,6 +533,7 @@ static nt_err_code_struct nt_errs[] = { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, + { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, -- cgit From 402fbc518a5489b33f1c5eafb8e6acb9ee5addbd Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 14 May 2003 00:46:43 +0000 Subject: spelling (This used to be commit 865c11275685c85124b506c9bbd2a8bde2e760b9) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 2 +- source3/libsmb/smb_signing.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f58a458aba..154a7cae58 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -295,7 +295,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, } else { /* pre-encrypted password supplied. Only used for security=server, can't do - signing becouse we don't have oringial key */ + signing because we don't have original key */ lm_response = data_blob(pass, passlen); nt_response = data_blob(ntpass, ntpasslen); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 81cb61d757..8d4e8a266c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -274,7 +274,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); - /* just becouse we over-allocate, doesn't mean it's right to use it */ + /* just because we over-allocate, doesn't mean it's right to use it */ clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 0f56cd15d9..eedf7f401f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -112,7 +112,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. * - * We put the sequence into the packet, becouse we are going + * We put the sequence into the packet, because we are going * to copy over it anyway. */ SIVAL(cli->outbuf, smb_ss_field, -- cgit From c52ee09afe06dce29118356078cc4c26b126afc6 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 21 May 2003 16:12:07 +0000 Subject: fix for UNICODE plaintext passwords (bug #59) and fix smbclient to send the unicode plain text password if negoitated (This used to be commit e7d635af80c844f17ff9f34c26c1e9c978951ce1) --- source3/libsmb/cliconnect.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 154a7cae58..8ebac7bae7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -188,6 +188,9 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; + fstring lanman; + + snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); @@ -201,12 +204,22 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, SSVAL(cli->outbuf,smb_vwv8,0); SIVAL(cli->outbuf,smb_vwv11,capabilities); p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ - SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); + + /* check wether to send the ASCII or UNICODE version of the password */ + + if ( (capabilities & CAP_UNICODE) == 0 ) { + p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ + SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); + } + else { + p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */ + SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))); + } + p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */ p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); - p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); + p += clistr_push(cli, p, lanman, -1, STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); -- cgit From 62f70d191077dd7bf41f7cdca00cb7b94607323c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 26 May 2003 19:47:53 +0000 Subject: Fix list of servers in 'smbclient -L' (debian bug #194553, patch by Heine Larsen) (This used to be commit e9df7d2820441c63c35e7b4fc5b3cc594053781c) --- source3/libsmb/clirap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index f05a65762b..9d4411797d 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -233,7 +233,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER); + p += push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER); if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ -- cgit From 4f276f969633f3c39e3ffc609b167930ff7fd42c Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 30 May 2003 20:11:34 +0000 Subject: More on bug 137: rename more of krb5_xxx functions to not start with krb5_ (This used to be commit 10f1da3f4a9680a039a2aa26301b97e31c06c38d) --- source3/libsmb/clikrb5.c | 28 ++++++++++++++-------------- source3/libsmb/clispnego.c | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5edc56daa9..df6043a618 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -235,12 +235,12 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ -static krb5_error_code krb5_mk_req2(krb5_context context, - krb5_auth_context *auth_context, - const krb5_flags ap_req_options, - const char *principal, - krb5_ccache ccache, - krb5_data *outbuf) +static krb5_error_code ads_krb5_mk_req(krb5_context context, + krb5_auth_context *auth_context, + const krb5_flags ap_req_options, + const char *principal, + krb5_ccache ccache, + krb5_data *outbuf) { krb5_error_code retval; krb5_principal server; @@ -305,7 +305,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) { krb5_error_code retval; krb5_data packet; @@ -344,11 +344,11 @@ DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) goto failed; } - if ((retval = krb5_mk_req2(context, - &auth_context, - 0, - principal, - ccdef, &packet))) { + if ((retval = ads_krb5_mk_req(context, + &auth_context, + 0, + principal, + ccdef, &packet))) { goto failed; } @@ -365,7 +365,7 @@ failed: return data_blob(NULL, 0); } - BOOL krb5_get_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) { #ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; @@ -390,7 +390,7 @@ failed: } #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -DATA_BLOB krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 53f7eb6e7d..bb48f57915 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -329,7 +329,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principal, time_offset); + tkt = cli_krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); -- cgit From 49d71c7e7b69662083d889966ca4600b5000f521 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 6 Jun 2003 05:31:30 +0000 Subject: fixed a pstrcpy() that is not on a pstring (This used to be commit f644b3d6d238e3c44d0358b44296a9360d16bb41) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 30ce5b6b10..b96111240f 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -295,7 +295,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) if (name->scope[0]) { /* XXXX this scope handling needs testing */ ret += strlen(name->scope) + 1; - pstrcpy(&buf[offset+1],name->scope); + safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); p = &buf[offset+1]; while ((p = strchr_m(p,'.'))) { -- cgit From 0d55e9c536779215a7e49b220041fdacde25d74a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 6 Jun 2003 14:11:14 +0000 Subject: merge from APP_HEAD. Push negative connection cache into rpc_find_dc(). Should probably be extended some more in 3.0 but this is what we have for the moment. (This used to be commit 0e23abf95cf7ba2d0a314a34bddb4d46de2a3cd1) --- source3/libsmb/namequery_dc.c | 155 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 148 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index ffc64139e9..e98b728963 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -25,15 +25,149 @@ #include "includes.h" -/* - find the DC for a domain using methods appropriate for a RPC domain -*/ +#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */ + +struct failed_connection_cache { + fstring domain_name; + fstring controller; + time_t lookup_time; + NTSTATUS nt_status; + struct failed_connection_cache *prev, *next; +}; + +static struct failed_connection_cache *failed_connection_cache; + +/********************************************************************** + Check for a previously failed connection +**********************************************************************/ + +static NTSTATUS check_negative_conn_cache( const char *domain, const char *server ) +{ + struct failed_connection_cache *fcc; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + /* can't check if we don't have strings */ + + if ( !domain || !server ) + return NT_STATUS_OK; + + for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { + + /* + * we have a match IFF the domain and server name matches + * (a) the domain matches, + * (b) the IP address matches (if we have one) + * (c) the server name (if specified) matches + */ + + if ( !strequal(domain, fcc->domain_name) || !strequal(server, fcc->controller) ) + continue; /* no match; check the next entry */ + + /* we have a match so see if it is still current */ + + if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT) + { + /* Cache entry has expired, delete it */ + + DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", + domain, server )); + + DLIST_REMOVE(failed_connection_cache, fcc); + SAFE_FREE(fcc); + + return NT_STATUS_OK; + } + + /* The timeout hasn't expired yet so return false */ + + DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n", + domain, server )); + + result = fcc->nt_status; + return result; + } + + /* end of function means no cache entry */ + return NT_STATUS_OK; +} + +/********************************************************************** + Add an entry to the failed conneciton cache +**********************************************************************/ + +void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) +{ + struct failed_connection_cache *fcc; + + SMB_ASSERT(!NT_STATUS_IS_OK(result)); + + /* Check we already aren't in the cache. We always have to have + a domain, but maybe not a specific DC name. */ + + for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { + if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) + { + DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n", + domain, server )); + return; + } + } + + /* Create negative lookup cache entry for this domain and controller */ + + if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) ) + { + DEBUG(0, ("malloc failed in add_failed_connection_entry!\n")); + return; + } + + ZERO_STRUCTP(fcc); + + fstrcpy( fcc->domain_name, domain ); + fstrcpy( fcc->controller, server ); + fcc->lookup_time = time(NULL); + fcc->nt_status = result; + + DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n", + domain, server )); + + DLIST_ADD(failed_connection_cache, fcc); +} + +/**************************************************************************** +****************************************************************************/ + +void flush_negative_conn_cache( void ) +{ + struct failed_connection_cache *fcc; + + fcc = failed_connection_cache; + + while (fcc) { + struct failed_connection_cache *fcc_next; + + fcc_next = fcc->next; + DLIST_REMOVE(failed_connection_cache, fcc); + free(fcc); + + fcc = fcc_next; + } + +} + +/**************************************************************************** + Utility function to return the name of a DC using RPC. The name is + guaranteed to be valid since we have already done a name_status_find on it + and we have checked our negative connection cache + ***************************************************************************/ + BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) { struct in_addr *ip_list = NULL, dc_ip, exclude_ip; int count, i; BOOL list_ordered; BOOL use_pdc_only; + NTSTATUS result; zero_ip(&exclude_ip); @@ -41,11 +175,15 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) /* Lookup domain controller name */ - if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) ) { + if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) ) + { DEBUG(10,("rpc_find_dc: Atempting to lookup PDC to avoid sam sync delays\n")); if (name_status_find(domain, 0x1c, 0x20, dc_ip, srv_name)) { - goto done; + /* makre we we haven't tried this on previously and failed */ + result = check_negative_conn_cache( domain, srv_name ); + if ( NT_STATUS_IS_OK(result) ) + goto done; } /* Didn't get name, remember not to talk to this DC. */ exclude_ip = dc_ip; @@ -77,8 +215,11 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) continue; if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { - dc_ip = ip_list[i]; - goto done; + result = check_negative_conn_cache( domain, srv_name ); + if ( NT_STATUS_IS_OK(result) ) { + dc_ip = ip_list[i]; + goto done; + } } } -- cgit From babab82d9a7f9de5409c8f53b0d66b7f8ffefd94 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 6 Jun 2003 23:09:39 +0000 Subject: applying David Lee's climessage patch to make sending messages more extendable (This used to be commit a5240adc4944342529702542e080c378d3883a09) --- source3/libsmb/climessage.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 2b1be75089..8ce8416487 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -26,12 +26,11 @@ /**************************************************************************** start a message sequence ****************************************************************************/ -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, - int *grp) +int cli_message_start_build(struct cli_state *cli, char *host, char *username) { char *p; - /* send a SMBsendstrt command */ + /* construct a SMBsendstrt command */ memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBsendstrt); @@ -45,6 +44,14 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, p += clistr_push(cli, p, host, -1, STR_ASCII|STR_TERMINATE); cli_setup_bcc(cli, p); + + return(PTR_DIFF(p, cli->outbuf)); +} + +BOOL cli_message_start(struct cli_state *cli, char *host, char *username, + int *grp) +{ + cli_message_start_build(cli, host, username); cli_send_smb(cli); @@ -63,7 +70,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username, /**************************************************************************** send a message ****************************************************************************/ -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) { char *msgdos; int lendos; @@ -93,6 +100,14 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) } cli_setup_bcc(cli, p); + + return(PTR_DIFF(p, cli->outbuf)); +} + +BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +{ + cli_message_text_build(cli, msg, len, grp); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -107,8 +122,10 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) /**************************************************************************** end a message ****************************************************************************/ -BOOL cli_message_end(struct cli_state *cli, int grp) +int cli_message_end_build(struct cli_state *cli, int grp) { + char *p; + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBsendend); @@ -117,7 +134,16 @@ BOOL cli_message_end(struct cli_state *cli, int grp) SSVAL(cli->outbuf,smb_vwv0,grp); cli_setup_packet(cli); - + + p = smb_buf(cli->outbuf); + + return(PTR_DIFF(p, cli->outbuf)); +} + +BOOL cli_message_end(struct cli_state *cli, int grp) +{ + cli_message_end_build(cli, grp); + cli_send_smb(cli); if (!cli_receive_smb(cli)) { -- cgit From 54f7cde1eb58921ca3fb08782bc72adaf5e93082 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Jun 2003 03:49:35 +0000 Subject: Rework our smb signing code again, this factors out some of the common MAC calcuation code, and now supports multiple outstanding packets. Fixes bug #40 Andrew Bartlett (This used to be commit dd33212f1ec08f46223d6de8e5ff3140ce367a9a) --- source3/libsmb/smb_signing.c | 163 +++++++++++++++++++++++++++++-------------- 1 file changed, 109 insertions(+), 54 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index eedf7f401f..fee2b66670 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -21,12 +21,50 @@ #include "includes.h" +/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ +struct outstanding_packet_lookup { + uint16 mid; + uint32 reply_seq_num; + struct outstanding_packet_lookup *prev, *next; +}; + struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; - uint32 reply_seq_num; + struct outstanding_packet_lookup *outstanding_packet_list; }; +static void store_sequence_for_reply(struct outstanding_packet_lookup **list, + uint16 mid, uint32 reply_seq_num) +{ + struct outstanding_packet_lookup *t; + struct outstanding_packet_lookup *tmp; + + t = smb_xmalloc(sizeof(*t)); + ZERO_STRUCTP(t); + + DLIST_ADD_END(*list, t, tmp); + t->mid = mid; + t->reply_seq_num = reply_seq_num; +} + +static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, + uint16 mid, uint32 *reply_seq_num) +{ + struct outstanding_packet_lookup *t; + + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + *reply_seq_num = t->reply_seq_num; + DLIST_REMOVE(*list, t); + return True; + } + } + DEBUG(0, ("Unexpected incoming packet, it's MID (%u) does not match" + " a MID in our outstanding list!\n", mid)); + return False; +} + /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ @@ -99,35 +137,67 @@ static BOOL signing_good(struct cli_state *cli, BOOL good) } /*********************************************************** - SMB signing - Simple implementation - calculate a MAC to send. + SMB signing - Simple implementation - calculate a MAC on the packet ************************************************************/ -static void cli_simple_sign_outgoing_message(struct cli_state *cli) +static void simple_packet_signature(struct smb_basic_signing_context *data, + const uchar *buf, uint32 seq_number, + unsigned char calc_md5_mac[16]) { - unsigned char calc_md5_mac[16]; + const size_t offset_end_of_sig = (smb_ss_field + 8); + unsigned char sequence_buf[8]; struct MD5Context md5_ctx; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; /* * Firstly put the sequence number into the first 4 bytes. * and zero out the next 4 bytes. * - * We put the sequence into the packet, because we are going - * to copy over it anyway. + * We do this here, to avoid modifying the packet. */ - SIVAL(cli->outbuf, smb_ss_field, - data->send_seq_num); - SIVAL(cli->outbuf, smb_ss_field + 4, 0); - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli); + SIVAL(sequence_buf, 0, seq_number); + SIVAL(sequence_buf, 4, 0); - /* Calculate the 16 byte MAC and place first 8 bytes into the field. */ + /* Calculate the 16 byte MAC - but don't alter the data in the + incoming packet. + + This makes for a bit for fussing about, but it's not too bad. + */ MD5Init(&md5_ctx); + + /* intialise with the key */ MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); - MD5Update(&md5_ctx, cli->outbuf + 4, smb_len(cli->outbuf)); + + /* copy in the first bit of the SMB header */ + MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); + + /* copy in the sequence number, instead of the signature */ + MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + + /* copy in the rest of the packet in, skipping the signature */ + MD5Update(&md5_ctx, buf + offset_end_of_sig, + smb_len(buf) - (offset_end_of_sig - 4)); + + /* caclulate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); +} + + +/*********************************************************** + SMB signing - Simple implementation - send the MAC. +************************************************************/ + +static void cli_simple_sign_outgoing_message(struct cli_state *cli) +{ + unsigned char calc_md5_mac[16]; + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(cli); + + simple_packet_signature(data, cli->outbuf, data->send_seq_num, + calc_md5_mac); DEBUG(10, ("sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); @@ -136,8 +206,11 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ + data->send_seq_num++; - data->reply_seq_num = data->send_seq_num; + store_sequence_for_reply(&data->outstanding_packet_list, + cli->mid, + data->send_seq_num); data->send_seq_num++; } @@ -148,50 +221,21 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) static BOOL cli_simple_check_incoming_message(struct cli_state *cli) { BOOL good; + uint32 reply_seq_number; unsigned char calc_md5_mac[16]; - unsigned char server_sent_mac[8]; - unsigned char sequence_buf[8]; - struct MD5Context md5_ctx; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; - const size_t offset_end_of_sig = (smb_ss_field + 8); + unsigned char *server_sent_mac; - /* - * Firstly put the sequence number into the first 4 bytes. - * and zero out the next 4 bytes. - * - * We do this here, to avoid modifying the packet. - */ - - SIVAL(sequence_buf, 0, data->reply_seq_num); - SIVAL(sequence_buf, 4, 0); - - /* get a copy of the server-sent mac */ - memcpy(server_sent_mac, &cli->inbuf[smb_ss_field], sizeof(server_sent_mac)); - - /* Calculate the 16 byte MAC - but don't alter the data in the - incoming packet. - - This makes for a bit for fussing about, but it's not too bad. - */ - MD5Init(&md5_ctx); - - /* intialise with the key */ - MD5Update(&md5_ctx, data->mac_key.data, - data->mac_key.length); - - /* copy in the first bit of the SMB header */ - MD5Update(&md5_ctx, cli->inbuf + 4, smb_ss_field - 4); - - /* copy in the sequence number, instead of the signature */ - MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf)); + struct smb_basic_signing_context *data = cli->sign_info.signing_context; - /* copy in the rest of the packet in, skipping the signature */ - MD5Update(&md5_ctx, cli->inbuf + offset_end_of_sig, - smb_len(cli->inbuf) - (offset_end_of_sig - 4)); + if (!get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(cli->inbuf, smb_mid), + &reply_seq_number)) { + return False; + } - /* caclulate the MD5 sig */ - MD5Final(calc_md5_mac, &md5_ctx); + simple_packet_signature(data, cli->inbuf, reply_seq_number, calc_md5_mac); + server_sent_mac = &cli->inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { @@ -211,6 +255,13 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) static void cli_simple_free_signing_context(struct cli_state *cli) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct outstanding_packet_lookup *list = data->outstanding_packet_list; + + while (list) { + struct outstanding_packet_lookup *old_head = list; + DLIST_REMOVE(list, list); + SAFE_FREE(old_head); + } data_blob_free(&data->mac_key); SAFE_FREE(cli->sign_info.signing_context); @@ -235,6 +286,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ } data = smb_xmalloc(sizeof(*data)); + cli->sign_info.signing_context = data; data->mac_key = data_blob(NULL, response.length + 16); @@ -245,6 +297,9 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ /* Initialise the sequence number */ data->send_seq_num = 0; + /* Initialise the list of outstanding packets */ + data->outstanding_packet_list = NULL; + cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; cli->sign_info.free_signing_context = cli_simple_free_signing_context; -- cgit From e4bc8f08c35aeff9aa430058a82a16a515ef474d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Jun 2003 12:49:31 +0000 Subject: Enforce 'client plaintext auth', 'client lanman auth' and 'client ntlmv2 auth'. (this now causes things like the LANMAN protocol and contacting servers with 'encrypt passwords = no' set to fail, if configured) 'client ntlmv2 auth' (a BOOL) forces both plaintext and lanman off, and is the most secure setting for compatible hosts. Perhaps we should change this to 'client minimum auth'? Andrew Bartlett (This used to be commit e1fb681e4c921456fde154b87687722a18ed4aac) --- source3/libsmb/cliconnect.c | 58 ++++++++++++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8ebac7bae7..ffacc3af9a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -293,14 +293,18 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, uchar nt_hash[16]; E_md4hash(pass, nt_hash); + nt_response = data_blob(NULL, 24); + SMBNTencrypt(pass,cli->secblob.data,nt_response.data); + /* non encrypted password supplied. Ignore ntpass. */ if (lp_client_lanman_auth()) { lm_response = data_blob(NULL, 24); - SMBencrypt(pass,cli->secblob.data,lm_response.data); + SMBencrypt(pass,cli->secblob.data, lm_response.data); + } else { + /* LM disabled, place NT# in LM feild instead */ + lm_response = data_blob(nt_response.data, nt_response.length); } - nt_response = data_blob(NULL, 24); - SMBNTencrypt(pass,cli->secblob.data,nt_response.data); session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } @@ -575,7 +579,6 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } data_blob_free(&tmp_blob); } else { - /* the server might give us back two challenges */ if (!spnego_parse_auth_response(blob, nt_status, &blob_in)) { DEBUG(3,("Failed to parse auth response\n")); @@ -713,8 +716,22 @@ BOOL cli_session_setup(struct cli_state *cli, /* if its an older server then we have to use the older request format */ - if (cli->protocol < PROTOCOL_NT1) + if (cli->protocol < PROTOCOL_NT1) { + if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) { + DEBUG(1, ("Server requested LM password but 'client lanman auth'" + " is disabled\n")); + return False; + } + + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && + !lp_client_plaintext_auth() && (*pass)) { + DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" + " is disabled\n")); + return False; + } + return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); + } /* if no user is supplied then we have to do an anonymous connection. passwords are ignored */ @@ -726,17 +743,21 @@ BOOL cli_session_setup(struct cli_state *cli, password at this point. The password is sent in the tree connect */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) + if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) return cli_session_setup_plaintext(cli, user, "", workgroup); /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ - if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { + if (!lp_client_plaintext_auth() && (*pass)) { + DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" + " is disabled\n")); + return False; + } return cli_session_setup_plaintext(cli, user, pass, workgroup); + } - /* Indidicate signing */ - /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) @@ -789,6 +810,12 @@ BOOL cli_send_tconX(struct cli_state *cli, } if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { + if (!lp_client_lanman_auth()) { + DEBUG(1, ("Server requested LANMAN password but 'client use lanman auth'" + " is disabled\n")); + return False; + } + /* * Non-encrypted passwords - convert to DOS codepage before encryption. */ @@ -796,10 +823,17 @@ BOOL cli_send_tconX(struct cli_state *cli, SMBencrypt(pass,cli->secblob.data,(uchar *)pword); } else { if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { + if (!lp_client_plaintext_auth() && (*pass)) { + DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" + " is disabled\n")); + return False; + } + /* * Non-encrypted passwords - convert to DOS codepage before using. */ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); + } else { memcpy(pword, pass, passlen); } @@ -1375,6 +1409,12 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, { char *p; + if (!lp_client_plaintext_auth() && (*pass)) { + DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" + " is disabled\n")); + return NT_STATUS_ACCESS_DENIED; + } + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); -- cgit From 46d106f2eb03e88b29e33e15d103b5e01ee3ff7e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Jun 2003 12:51:31 +0000 Subject: Fix some memory leaks and extra cache startups/shutdowns from the trusted domains lookup code. Andrew Bartlett (This used to be commit 0ec1b1207041a3b6050046ba6d7b466dd4fcf341) --- source3/libsmb/trustdom_cache.c | 5 ++++- source3/libsmb/trusts_util.c | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index cddbb2daa6..61b024da43 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -89,7 +89,7 @@ BOOL trustdom_cache_shutdown(void) static char* trustdom_cache_key(const char* name) { - char* keystr; + char* keystr = NULL; asprintf(&keystr, TDOMKEY_FMT, strupper_static(name)); return keystr; @@ -165,11 +165,14 @@ BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) /* prepare a key and get the value */ key = trustdom_cache_key(name); + if (!key) return False; if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for trusted domain %s found.\n", name)); + SAFE_FREE(key); return False; } else { + SAFE_FREE(key); DEBUG(5, ("trusted domain %s found (%s)\n", name, value)); } diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 6244c844f2..e0c5e79595 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -154,9 +154,7 @@ BOOL is_trusted_domain(const char* dom_name) * Query the trustdom_cache updated periodically. The only * way for domain member server. */ - if (trustdom_cache_enable() && - trustdom_cache_fetch(dom_name, &trustdom_sid)) { - trustdom_cache_shutdown(); + if (trustdom_cache_fetch(dom_name, &trustdom_sid)) { return True; } -- cgit From 1d008cd2cb2bf1821bca72328ef33aa76318e282 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jun 2003 03:48:09 +0000 Subject: use ZERO_STRUCT() instead of memset (This used to be commit 082084042307f5f7d532b28debdeac11753a05f9) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index df6043a618..fd5dd91325 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -255,7 +255,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, } /* obtain ticket & session key */ - memset((char *)&creds, 0, sizeof(creds)); + ZERO_STRUCT(creds); if ((retval = krb5_copy_principal(context, server, &creds.server))) { DEBUG(1,("krb5_copy_principal failed (%s)\n", error_message(retval))); -- cgit From d286e44209006e4176a3dd08d73f28a390d7922d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jun 2003 14:02:46 +0000 Subject: fixed libsmb code to set correct timeout in cli_state when waiting for a blocking lock (This used to be commit 3515476fe436132d4569ac9067ea6195ab087e77) --- source3/libsmb/clifile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index b771e135f4..f021076a46 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -600,8 +600,8 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, /**************************************************************************** Lock a file. + note that timeout is in units of 2 milliseconds ****************************************************************************/ - BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout, enum brl_type lock_type) { @@ -636,7 +636,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, cli_send_smb(cli); if (timeout != 0) { - cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout + 10*1000); + cli->timeout = (timeout == -1) ? 0x7FFFFFFF : (timeout*2 + 5*1000); } if (!cli_receive_smb(cli)) { -- cgit From 292a51eda152f5e1885f38f3a811e956560f33f0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Jun 2003 21:03:15 +0000 Subject: Forward port the app-head changes for dc name cache into 3.0. Jeremy. (This used to be commit 8bcc3116a22ce11b55a35f3363230f54bc5735fc) --- source3/libsmb/namecache.c | 83 +++++++++++++++++++++++++++++++++++++ source3/libsmb/namequery.c | 39 +++++++++++------- source3/libsmb/namequery_dc.c | 95 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 186 insertions(+), 31 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index d3541b7719..7a0eb5212a 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -143,10 +143,19 @@ BOOL namecache_store(const char *name, int name_type, * out of action for the entire cache timeout time! */ +#if 0 + /* + * I don't think we need to do this. We are + * checking at a higher level for failed DC + * connections. JRA. + */ + if (name_type == 0x1b || name_type == 0x1c) expiry = time(NULL) + 10; else expiry = time(NULL) + lp_name_cache_timeout(); +#endif + expiry = time(NULL) + lp_name_cache_timeout(); /* * Generate string representation of ip addresses list @@ -201,7 +210,9 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); + gencache_del(key); SAFE_FREE(key); + SAFE_FREE(value); return False; } else { DEBUG(5, ("name %s#%02X found.\n", name, name_type)); @@ -252,3 +263,75 @@ void namecache_flush(void) DEBUG(5, ("Namecache flushed\n")); } +/* Construct a name status record key. */ + +static char *namecache_status_record_key(const char *name, int name_type1, + int name_type2, struct in_addr keyip) +{ + char *keystr; + + asprintf(&keystr, "NBT/%s#%02X.%02X.%s", + strupper_static(name), name_type1, name_type2, inet_ntoa(keyip)); + return keystr; +} + +/* Store a name status record. */ + +BOOL namecache_status_store(const char *keyname, int keyname_type, + int name_type, struct in_addr keyip, + const char *srvname) +{ + char *key; + time_t expiry; + BOOL ret; + + if (!gencache_init()) + return False; + + key = namecache_status_record_key(keyname, keyname_type, name_type, keyip); + if (!key) + return False; + + expiry = time(NULL) + lp_name_cache_timeout(); + ret = gencache_set(key, srvname, expiry); + + if (ret) + DEBUG(5, ("namecache_status_store: entry %s -> %s\n", key, srvname )); + else + DEBUG(5, ("namecache_status_store: entry %s store failed.\n", key )); + + SAFE_FREE(key); + return ret; +} + +/* Fetch a name status record. */ + +BOOL namecache_status_fetch(const char *keyname, int keyname_type, + int name_type, struct in_addr keyip, char *srvname_out) +{ + char *key = NULL; + char *value = NULL; + time_t timeout; + + if (!gencache_init()) + return False; + + key = namecache_status_record_key(keyname, keyname_type, name_type, keyip); + if (!key) + return False; + + if (!gencache_get(key, &value, &timeout)) { + DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key)); + gencache_del(key); + SAFE_FREE(key); + SAFE_FREE(value); + return False; + } else { + DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", key, value )); + } + + strlcpy(srvname_out, value, 16); + SAFE_FREE(key); + SAFE_FREE(value); + return True; +} diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 18ce5e4bd9..7f343033d6 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -25,8 +25,9 @@ BOOL global_in_nmbd = False; /**************************************************************************** -generate a random trn_id + Generate a random trn_id. ****************************************************************************/ + static int generate_trn_id(void) { static int trn_id; @@ -40,10 +41,10 @@ static int generate_trn_id(void) return trn_id % (unsigned)0x7FFF; } - /**************************************************************************** - parse a node status response into an array of structures + Parse a node status response into an array of structures. ****************************************************************************/ + static struct node_status *parse_node_status(char *p, int *num_names) { struct node_status *ret; @@ -51,7 +52,8 @@ static struct node_status *parse_node_status(char *p, int *num_names) *num_names = CVAL(p,0); - if (*num_names == 0) return NULL; + if (*num_names == 0) + return NULL; ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names)); if (!ret) return NULL; @@ -71,9 +73,10 @@ static struct node_status *parse_node_status(char *p, int *num_names) /**************************************************************************** -do a NBT node status query on an open socket and return an array of -structures holding the returned names or NULL if the query failed + Do a NBT node status query on an open socket and return an array of + structures holding the returned names or NULL if the query failed. **************************************************************************/ + struct node_status *node_status_query(int fd,struct nmb_name *name, struct in_addr to_ip, int *num_names) { @@ -155,11 +158,9 @@ struct node_status *node_status_query(int fd,struct nmb_name *name, return NULL; } - /**************************************************************************** -find the first type XX name in a node status reply - used for finding -a servers name given its IP -return the matched name in *name + Find the first type XX name in a node status reply - used for finding + a servers name given its IP. Return the matched name in *name. **************************************************************************/ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name) @@ -178,6 +179,11 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, q_type, inet_ntoa(to_ip))); + /* Check the cache first. */ + + if (namecache_status_fetch(q_name, q_type, type, to_ip, name)) + return True; + sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); if (sock == -1) goto done; @@ -197,6 +203,10 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t goto done; pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE); + + /* Store the result in the cache. */ + namecache_status_store(q_name, q_type, type, to_ip, name); + result = True; done: @@ -205,17 +215,17 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not ")); if (result) - DEBUGADD(10, (", ip address is %s", inet_ntoa(to_ip))); + DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip))); DEBUG(10, ("\n")); return result; } - /* comparison function used by sort_ip_list */ + int ip_compare(struct in_addr *ip1, struct in_addr *ip2) { int max_bits1=0, max_bits2=0; @@ -248,6 +258,7 @@ int ip_compare(struct in_addr *ip1, struct in_addr *ip2) are at the top. This prevents the problem where a WINS server returns an IP that is not reachable from our subnet as the first match */ + static void sort_ip_list(struct in_addr *iplist, int count) { if (count <= 1) { @@ -257,13 +268,13 @@ static void sort_ip_list(struct in_addr *iplist, int count) qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); } - /**************************************************************************** Do a netbios name query to find someones IP. Returns an array of IP addresses or NULL if none. *count will be set to the number of addresses returned. *timed_out is set if we failed by timing out ****************************************************************************/ + struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse, struct in_addr to_ip, int *count, int *flags, @@ -611,6 +622,7 @@ BOOL name_resolve_bcast(const char *name, int name_type, /******************************************************** Resolve via "wins" method. *********************************************************/ + BOOL resolve_wins(const char *name, int name_type, struct in_addr **return_iplist, int *return_count) { @@ -1377,4 +1389,3 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * return internal_resolve_name(domain, 0x1C, ip_list, count); } - diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index e98b728963..c162e34027 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -156,12 +156,11 @@ void flush_negative_conn_cache( void ) } /**************************************************************************** - Utility function to return the name of a DC using RPC. The name is - guaranteed to be valid since we have already done a name_status_find on it - and we have checked our negative connection cache + Utility function to return the name of a DC. The name is guaranteed to be + valid since we have already done a name_status_find on it ***************************************************************************/ - -BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) + +BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) { struct in_addr *ip_list = NULL, dc_ip, exclude_ip; int count, i; @@ -177,10 +176,12 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) if ( use_pdc_only && get_pdc_ip(domain, &dc_ip) ) { - DEBUG(10,("rpc_find_dc: Atempting to lookup PDC to avoid sam sync delays\n")); + DEBUG(10,("get_dc_name: Atempting to lookup PDC to avoid sam sync delays\n")); - if (name_status_find(domain, 0x1c, 0x20, dc_ip, srv_name)) { - /* makre we we haven't tried this on previously and failed */ + /* check the connection cache and perform the node status + lookup only if the IP is not found to be bad */ + + if (name_status_find(domain, 0x1c, 0x20, dc_ip, srv_name) ) { result = check_negative_conn_cache( domain, srv_name ); if ( NT_STATUS_IS_OK(result) ) goto done; @@ -205,11 +206,71 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) } } - /* Pick a nice close server, but only if the list was not ordered */ - if (!list_ordered && (count > 1) ) { - qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare); + if ( !list_ordered ) + { + /* + * Pick a nice close server. Look for DC on local net + * (assuming we don't have a list of preferred DC's) + */ + + for (i = 0; i < count; i++) { + if (is_zero_ip(ip_list[i])) + continue; + + if ( !is_local_net(ip_list[i]) ) + continue; + + if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { + result = check_negative_conn_cache( domain, srv_name ); + if ( NT_STATUS_IS_OK(result) ) { + dc_ip = ip_list[i]; + goto done; + } + } + + zero_ip(&ip_list[i]); + } + + /* + * Try looking in the name status cache for an + * entry we already have. We know that already + * resolved ok. + */ + + for (i = 0; i < count; i++) { + if (is_zero_ip(ip_list[i])) + continue; + + if (namecache_status_fetch(domain, 0x1c, 0x20, + ip_list[i], srv_name)) { + result = check_negative_conn_cache( domain, srv_name ); + if ( NT_STATUS_IS_OK(result) ) { + dc_ip = ip_list[i]; + goto done; + } + } + } + + /* + * Secondly try and contact a random PDC/BDC. + */ + + i = (sys_random() % count); + + if ( !is_zero_ip(ip_list[i]) ) { + if ( name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { + result = check_negative_conn_cache( domain, srv_name ); + if ( NT_STATUS_IS_OK(result) ) { + dc_ip = ip_list[i]; + goto done; + } + } + zero_ip(&ip_list[i]); /* Tried and failed. */ + } } + /* Finally return first DC that we can contact */ + for (i = 0; i < count; i++) { if (is_zero_ip(ip_list[i])) continue; @@ -220,20 +281,21 @@ BOOL rpc_find_dc(const char *domain, fstring srv_name, struct in_addr *ip_out) dc_ip = ip_list[i]; goto done; } - } + } } - SAFE_FREE(ip_list); - return False; -done: + /* No-one to talk to )-: */ + return False; /* Boo-hoo */ + + done: /* We have the netbios name and IP address of a domain controller. Ideally we should sent a SAMLOGON request to determine whether the DC is alive and kicking. If we can catch a dead DC before performing a cli_connect() we can avoid a 30-second timeout. */ - DEBUG(3, ("rpc_find_dc: Returning DC %s (%s) for domain %s\n", srv_name, + DEBUG(3, ("get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name, inet_ntoa(dc_ip), domain)); *ip_out = dc_ip; @@ -242,4 +304,3 @@ done: return True; } - -- cgit From 93bcb9963bef53b91a0b16c6389cefdb7bea2b0e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 21 Jun 2003 04:05:01 +0000 Subject: merge of the netsamlogon caching code from APPLIANCE_HEAD This replaces the universal group caching code (was originally based on that code). Only applies to the the RPC code. One comment: domain local groups don't show up in 'getent group' that's easy to fix. Code has been tested against 2k domain but doesn't change anything with respect to NT4 domains. netsamlogon caching works pretty much like the universal group caching code did but has had much more testing and puts winbind mostly back in sync between branches. (This used to be commit aac01dc7bc95c20ee21c93f3581e2375d9a894e1) --- source3/libsmb/samlogon_cache.c | 238 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 source3/libsmb/samlogon_cache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c new file mode 100644 index 0000000000..7863ad7727 --- /dev/null +++ b/source3/libsmb/samlogon_cache.c @@ -0,0 +1,238 @@ +/* + Unix SMB/CIFS implementation. + Net_sam_logon info3 helpers + Copyright (C) Alexander Bokovoy 2002. + Copyright (C) Andrew Bartlett 2002. + Copyright (C) Gerald Carter 2003. + Copyright (C) Tim Potter 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#define NETSAMLOGON_TDB "netsamlogon_cache.tdb" + +static TDB_CONTEXT *netsamlogon_tdb = NULL; + +/*********************************************************************** + open the tdb + ***********************************************************************/ + +BOOL netsamlogon_cache_init(void) +{ + if (!netsamlogon_tdb) { + netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0, + TDB_DEFAULT, O_RDWR | O_CREAT, 0600); + } + + return (netsamlogon_tdb != NULL); +} + + +/*********************************************************************** + Shutdown samlogon_cache database +***********************************************************************/ + +BOOL netsamlogon_cache_shutdown(void) +{ + if(netsamlogon_tdb) + return (tdb_close(netsamlogon_tdb) == 0); + + return True; +} + +/*********************************************************************** + Clear cache getpwnam and getgroups entries from the winbindd cache +***********************************************************************/ +void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) +{ + fstring domain; + TDB_DATA key; + BOOL got_tdb = False; + + /* We may need to call this function from smbd which will not have + winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ + + if (!tdb) { + tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000, + TDB_DEFAULT, O_RDWR, 0600); + if (!tdb) { + DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n")); + return; + } + got_tdb = True; + } + + unistr2_to_ascii(domain, &user->uni_logon_dom, sizeof(domain) - 1); + + /* Clear U/DOMAIN/RID cache entry */ + + asprintf(&key.dptr, "U/%s/%d", domain, user->user_rid); + key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */ + + DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); + + tdb_delete(tdb, key); + + SAFE_FREE(key.dptr); + + /* Clear UG/DOMAIN/RID cache entry */ + + asprintf(&key.dptr, "UG/%s/%d", domain, user->user_rid); + key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */ + + DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); + + tdb_delete(tdb, key); + + SAFE_FREE(key.dptr); + + if (got_tdb) + tdb_close(tdb); +} + +/*********************************************************************** + Store a NET_USER_INFO_3 structure in a tdb for later user +***********************************************************************/ + +BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) +{ + TDB_DATA data; + fstring keystr; + prs_struct ps; + BOOL result = False; + DOM_SID user_sid; + time_t t = time(NULL); + + + if (!netsamlogon_cache_init()) { + DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); + return False; + } + + sid_copy( &user_sid, &user->dom_sid.sid ); + sid_append_rid( &user_sid, user->user_rid ); + + /* Prepare key as DOMAIN-SID/USER-RID string */ + slprintf(keystr, sizeof(keystr), "%s", sid_string_static(&user_sid)); + + DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); + + /* Prepare data */ + + prs_init( &ps,MAX_PDU_FRAG_LEN , mem_ctx, MARSHALL); + + if ( !prs_uint32( "timestamp", &ps, 0, (uint32*)&t ) ) + return False; + + if ( net_io_user_info3("", user, &ps, 0, 3) ) + { + data.dsize = prs_offset( &ps ); + data.dptr = prs_data_p( &ps ); + + if (tdb_store_by_string(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) + result = True; + + prs_mem_free( &ps ); + } + + return result; +} + +/*********************************************************************** + Retrieves a NET_USER_INFO_3 structure from a tdb. Caller must + free the user_info struct (malloc()'d memory) +***********************************************************************/ + +NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, DOM_SID *user_sid) +{ + NET_USER_INFO_3 *user = NULL; + TDB_DATA data, key; + prs_struct ps; + fstring keystr; + uint32 t; + + if (!netsamlogon_cache_init()) { + DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); + return False; + } + + /* Prepare key as DOMAIN-SID/USER-RID string */ + slprintf(keystr, sizeof(keystr), "%s", sid_string_static(user_sid)); + DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); + key.dptr = keystr; + key.dsize = strlen(keystr)+1; + data = tdb_fetch( netsamlogon_tdb, key ); + + if ( data.dptr ) { + + if ( (user = (NET_USER_INFO_3*)malloc(sizeof(NET_USER_INFO_3))) == NULL ) + return NULL; + + prs_init( &ps, 0, mem_ctx, UNMARSHALL ); + prs_give_memory( &ps, data.dptr, data.dsize, True ); + + if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) { + prs_mem_free( &ps ); + return False; + } + + if ( !net_io_user_info3("", user, &ps, 0, 3) ) { + SAFE_FREE( user ); + } + + prs_mem_free( &ps ); + +#if 0 /* The netsamlogon cache needs to hang around. Something about + this feels wrong, but it is the only way we can get all of the + groups. The old universal groups cache didn't expire either. + --jerry */ + { + time_t now = time(NULL); + uint32 time_diff; + + /* is the entry expired? */ + time_diff = now - t; + + if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) { + DEBUG(10,("netsamlogon_cache_get: cache entry expired \n")); + tdb_delete( netsamlogon_tdb, key ); + SAFE_FREE( user ); + } +#endif + } + + return user; +} + +BOOL netsamlogon_cache_have(DOM_SID *user_sid) +{ + TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); + NET_USER_INFO_3 *user = NULL; + BOOL result; + + if (!mem_ctx) + return False; + + user = netsamlogon_cache_get(mem_ctx, user_sid); + + result = (user != NULL); + + talloc_destroy(mem_ctx); + SAFE_FREE(user); + + return result; +} -- cgit From f36c96d59c79a51610bb5a1fc42ac62bd8d08401 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 23 Jun 2003 19:05:23 +0000 Subject: * s/get_dc_name/rpc_dc_name/g (revert a previous change) * move back to qsort() for sorting IP address in get_dc_list() * remove dc_name_cache in cm_get_dc_name() since it slowed things down more than it helped. I've made a note of where to add in the negative connection cache in the ads code. Will come back to that. * fix rpcclient to use PRINTER_ALL_ACCESS for set printer (instead of MAX_ALLOWED) * only enumerate domain local groups in our domain * simplify ldap search for seqnum in winbindd's rpc backend (This used to be commit f8cab8635b02b205b4031279cedd804c1fb22c5b) --- source3/libsmb/namequery.c | 11 +++++-- source3/libsmb/namequery_dc.c | 76 +++++-------------------------------------- 2 files changed, 18 insertions(+), 69 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 7f343033d6..3797f03979 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1379,10 +1379,17 @@ BOOL get_dc_list(const char *domain, struct in_addr **ip_list, int *count, int * } } + if ( DEBUGLEVEL >= 4 ) { + DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, + *ordered ? "":"un")); + DEBUG(4,("get_dc_list: ")); + for ( i=0; i 1) ) { + qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare); } - /* Finally return first DC that we can contact */ - for (i = 0; i < count; i++) { if (is_zero_ip(ip_list[i])) continue; @@ -281,8 +222,9 @@ BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) dc_ip = ip_list[i]; goto done; } - } + } } + SAFE_FREE(ip_list); @@ -295,7 +237,7 @@ BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) the DC is alive and kicking. If we can catch a dead DC before performing a cli_connect() we can avoid a 30-second timeout. */ - DEBUG(3, ("get_dc_name: Returning DC %s (%s) for domain %s\n", srv_name, + DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name, inet_ntoa(dc_ip), domain)); *ip_out = dc_ip; -- cgit From f51d769dd303027a3dbf46fc89a482933988e866 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Jun 2003 17:41:05 +0000 Subject: large change: *) consolidates the dc location routines again (dns and netbios) get_dc_list() or get_sorted_dc_list() is the authoritative means of locating DC's again. (also inludes a flag to get_dc_list() to define if this should be a DNS only lookup or not) (however, if you set "name resolve order = hosts wins" you could still get DNS queries for domain name IFF ldap_domain2hostlist() fails. The answer? Fix your DNS setup) *) enabled DOMAIN<0x1c> lookups to be funneled through resolve_hosts resulting in a call to ldap_domain2hostlist() if lp_security() == SEC_ADS *) enables name cache for winbind ADS backend *) enable the negative connection cache for winbind ADS backend *) removes some old dead code *) consolidates some duplicate code *) moves the internal_name_resolve() to use an IP/port pair to deal with SRV RR dns replies. The namecache code also supports the IP:port syntax now as well. *) removes 'ads server' and moves the functionality back into 'password server' (which can support "hostname:port" syntax now but works fine with defaults depending on the value of lp_security()) (This used to be commit d7f7fcda425bef380441509734eca33da943c091) --- source3/libsmb/cliconnect.c | 6 +- source3/libsmb/namecache.c | 44 +-- source3/libsmb/namequery.c | 698 ++++++++++++++++++++---------------------- source3/libsmb/namequery_dc.c | 155 +--------- 4 files changed, 353 insertions(+), 550 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ffacc3af9a..122cc56e45 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1479,7 +1479,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) { - struct in_addr *ip_list; + struct ip_service *ip_list; struct cli_state *cli; int i, count; struct in_addr server_ip; @@ -1493,7 +1493,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user for (i = 0; i < count; i++) { static fstring name; - if (!name_status_find("*", 0, 0x1d, ip_list[i], name)) + if (!name_status_find("*", 0, 0x1d, ip_list[i].ip, name)) continue; if (!find_master_ip(name, &server_ip)) @@ -1502,7 +1502,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user pstrcpy(workgroup, name); DEBUG(4, ("found master browser %s, %s\n", - name, inet_ntoa(ip_list[i]))); + name, inet_ntoa(ip_list[i].ip))); cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 7a0eb5212a..e3e7ac4e3c 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -113,7 +113,7 @@ static char* namecache_key(const char *name, int name_type) **/ BOOL namecache_store(const char *name, int name_type, - int num_names, struct in_addr *ip_list) + int num_names, struct ip_service *ip_list) { time_t expiry; char *key, *value_string; @@ -126,35 +126,18 @@ BOOL namecache_store(const char *name, int name_type, */ if (!gencache_init()) return False; - DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", - num_names, num_names == 1 ? "": "es", name, name_type)); - - for (i = 0; i < num_names; i++) - DEBUGADD(5, ("%s%s", inet_ntoa(ip_list[i]), - i == (num_names - 1) ? "" : ", ")); - - DEBUGADD(5, ("\n")); + if ( DEBUGLEVEL >= 5 ) { + DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", + num_names, num_names == 1 ? "": "es", name, name_type)); + for (i = 0; i < num_names; i++) + DEBUGADD(5, ("%s:%d%s", inet_ntoa(ip_list[i].ip), + ip_list[i].port, (i == (num_names - 1) ? "" : ","))); + + DEBUGADD(5, ("\n")); + } + key = namecache_key(name, name_type); - - /* - * Cache pdc location or dc lists for only a little while - * otherwise if we lock on to a bad DC we can potentially be - * out of action for the entire cache timeout time! - */ - -#if 0 - /* - * I don't think we need to do this. We are - * checking at a higher level for failed DC - * connections. JRA. - */ - - if (name_type == 0x1b || name_type == 0x1c) - expiry = time(NULL) + 10; - else - expiry = time(NULL) + lp_name_cache_timeout(); -#endif expiry = time(NULL) + lp_name_cache_timeout(); /* @@ -189,7 +172,7 @@ BOOL namecache_store(const char *name, int name_type, * false if name isn't found in the cache or has expired **/ -BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, +BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_list, int *num_names) { char *key, *value; @@ -224,7 +207,8 @@ BOOL namecache_fetch(const char *name, int name_type, struct in_addr **ip_list, *num_names = ipstr_list_parse(value, ip_list); SAFE_FREE(key); - SAFE_FREE(value); + SAFE_FREE(value); + return *num_names > 0; /* true only if some ip has been fetched */ } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 3797f03979..81c0c14437 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -205,7 +205,11 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE); /* Store the result in the cache. */ - namecache_status_store(q_name, q_type, type, to_ip, name); + /* but don't store an entry for 0x1c names here. Here we have + a single host and DOMAIN<0x1c> names should be a list of hosts */ + + if ( q_type != 0x1c ) + namecache_status_store(q_name, q_type, type, to_ip, name); result = True; @@ -253,6 +257,26 @@ int ip_compare(struct in_addr *ip1, struct in_addr *ip2) return max_bits2 - max_bits1; } +/******************************************************************* + compare 2 ldap IPs by nearness to our interfaces - used in qsort +*******************************************************************/ + +static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2) +{ + int result; + + if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 ) + return result; + + if ( ip1->port > ip2->port ) + return 1; + + if ( ip1->port < ip2->port ) + return -1; + + return 0; +} + /* sort an IP list so that names that are close to one of our interfaces are at the top. This prevents the problem where a WINS server returns an IP that @@ -268,6 +292,51 @@ static void sort_ip_list(struct in_addr *iplist, int count) qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); } +void sort_ip_list2(struct ip_service *iplist, int count) +{ + if (count <= 1) { + return; + } + + qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare); +} + +/********************************************************************** + Remove any duplicate address/port pairs in the list + *********************************************************************/ + +static int remove_duplicate_addrs2( struct ip_service *iplist, int count ) +{ + int i, j; + + DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n")); + + /* one loop to remove duplicates */ + for ( i=0; i if we are using ADS */ + if ( lp_security() != SEC_ADS ) + return False; + + DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n", + name)); + + if (ldap_domain2hostlist(name, &list) != LDAP_SUCCESS) + return False; + + count = count_chars(list, ' ') + 1; + if ( (*return_iplist = malloc(count * sizeof(struct ip_service))) == NULL ) { + DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count )); + return False; + } + + ptr = list; + while (next_token(&ptr, tok, " ", sizeof(tok))) { + unsigned port = LDAP_PORT; + char *p = strchr(tok, ':'); + if (p) { + *p = 0; + port = atoi(p+1); + } + (*return_iplist)[i].ip = *interpret_addr2(tok); + (*return_iplist)[i].port = port; + + /* make sure it is a valid IP. I considered checking the negative + connection cache, but this is the wrong place for it. Maybe only + as a hac. After think about it, if all of the IP addresses retuend + from DNS are dead, what hope does a netbios name lookup have? + The standard reason for falling back to netbios lookups is that + our DNS server doesn't know anything about the DC's -- jerry */ + + if ( is_zero_ip((*return_iplist)[i].ip) ) + continue; + + i++; + } + SAFE_FREE(list); + + *return_count = i; + + return True; + } +#endif /* HAVE_ADS */ *return_iplist = NULL; *return_count = 0; @@ -776,27 +941,33 @@ static BOOL resolve_hosts(const char *name, if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { struct in_addr return_ip; putip((char *)&return_ip,(char *)hp->h_addr); - *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); + *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service)); if(*return_iplist == NULL) { DEBUG(3,("resolve_hosts: malloc fail !\n")); return False; } - **return_iplist = return_ip; + (*return_iplist)->ip = return_ip; + (*return_iplist)->port = PORT_NONE; *return_count = 1; return True; } return False; } -/******************************************************** +/******************************************************************* Internal interface to resolve a name into an IP address. Use this function if the string is either an IP address, DNS or host name or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. -*********************************************************/ + + Added support for ip addr/port to support ADS ldap servers. + the only place we currently care about the port is in the + resolve_hosts() when looking up DC's via SRV RR entries in DNS +**********************************************************************/ static BOOL internal_resolve_name(const char *name, int name_type, - struct in_addr **return_iplist, int *return_count) + struct ip_service **return_iplist, + int *return_count, const char *resolve_order) { pstring name_resolve_list; fstring tok; @@ -805,7 +976,6 @@ static BOOL internal_resolve_name(const char *name, int name_type, BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); BOOL is_address = is_ipaddress(name); BOOL result = False; - struct in_addr *nodupes_iplist; int i; *return_iplist = NULL; @@ -814,42 +984,56 @@ static BOOL internal_resolve_name(const char *name, int name_type, DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); if (allzeros || allones || is_address) { - *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr)); - if(*return_iplist == NULL) { - DEBUG(3,("internal_resolve_name: malloc fail !\n")); + + if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) { + DEBUG(0,("internal_resolve_name: malloc fail !\n")); return False; } + if(is_address) { + /* ignore the port here */ + (*return_iplist)->port = PORT_NONE; + /* if it's in the form of an IP address then get the lib to interpret it */ - if (((*return_iplist)->s_addr = inet_addr(name)) == 0xFFFFFFFF ){ + if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){ DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); return False; } } else { - (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0; + (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0; *return_count = 1; } return True; } - /* Check netbios name cache */ + /* Check name cache */ if (namecache_fetch(name, name_type, return_iplist, return_count)) { - - /* This could be a negative response */ - - return (*return_count > 0); + /* This could be a negative response */ + return (*return_count > 0); } - pstrcpy(name_resolve_list, lp_name_resolve_order()); - ptr = name_resolve_list; - if (!ptr || !*ptr) + /* set the name resolution order */ + + if ( !resolve_order ) + pstrcpy(name_resolve_list, lp_name_resolve_order()); + else + pstrcpy(name_resolve_list, resolve_order); + + if ( !name_resolve_list[0] ) ptr = "host"; + else + ptr = name_resolve_list; + /* iterate through the name resolution backends */ + while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (name_type == 0x20) { - if (resolve_hosts(name, return_iplist, return_count)) { + /* deal with 0x20 & 0x1c names here. The latter will result + in a SRV record lookup for _ldap._tcp. if we are using + 'security = ads' */ + if ( name_type==0x20 || name_type == 0x1c ) { + if (resolve_hosts(name, name_type, return_iplist, return_count)) { result = True; goto done; } @@ -890,58 +1074,31 @@ static BOOL internal_resolve_name(const char *name, int name_type, controllers including the PDC in iplist[1..n]. Iterating over the iplist when the PDC is down will cause two sets of timeouts. */ - if (*return_count && (nodupes_iplist = (struct in_addr *) - malloc(sizeof(struct in_addr) * (*return_count)))) { - int nodupes_count = 0; - - /* Iterate over return_iplist looking for duplicates */ - - for (i = 0; i < *return_count; i++) { - BOOL is_dupe = False; - int j; - - for (j = i + 1; j < *return_count; j++) { - if (ip_equal((*return_iplist)[i], - (*return_iplist)[j])) { - is_dupe = True; - break; - } - } - - if (!is_dupe) { - - /* This one not a duplicate */ - - nodupes_iplist[nodupes_count] = (*return_iplist)[i]; - nodupes_count++; - } - } - - /* Switcheroo with original list */ - - free(*return_iplist); - - *return_iplist = nodupes_iplist; - *return_count = nodupes_count; + if ( *return_count ) { + *return_count = remove_duplicate_addrs2( *return_iplist, *return_count ); } /* Save in name cache */ - for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) - DEBUG(100, ("Storing name %s of type %d (ip: %s)\n", name, - name_type, inet_ntoa((*return_iplist)[i]))); - + if ( DEBUGLEVEL >= 100 ) { + for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) + DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name, + name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); + } + namecache_store(name, name_type, *return_count, *return_iplist); /* Display some debugging info */ - DEBUG(10, ("internal_resolve_name: returning %d addresses: ", - *return_count)); + if ( DEBUGLEVEL >= 10 ) { + DEBUG(10, ("internal_resolve_name: returning %d addresses: ", + *return_count)); - for (i = 0; i < *return_count; i++) - DEBUGADD(10, ("%s ", inet_ntoa((*return_iplist)[i]))); - - DEBUG(10, ("\n")); + for (i = 0; i < *return_count; i++) + DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); + DEBUG(10, ("\n")); + } + return result; } @@ -954,7 +1111,7 @@ static BOOL internal_resolve_name(const char *name, int name_type, BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) { - struct in_addr *ip_list = NULL; + struct ip_service *ip_list = NULL; int count = 0; if (is_ipaddress(name)) { @@ -962,20 +1119,23 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) return True; } - if (internal_resolve_name(name, name_type, &ip_list, &count)) { + if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) { int i; + /* only return valid addresses for TCP connections */ for (i=0; iheader.msg_type = 0x10; - dgram->header.flags.node_type = M_NODE; - dgram->header.flags.first = True; - dgram->header.flags.more = False; - dgram->header.dgm_id = dgm_id; - dgram->header.source_ip = *iface_ip(*pdc_ip); - dgram->header.source_port = ntohs(sock_name.sin_port); - dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ - dgram->header.packet_offset = 0; - - make_nmb_name(&dgram->source_name,srcname,0); - make_nmb_name(&dgram->dest_name,domain,0x1C); - - ptr = &dgram->data[0]; - - /* Setup the smb part. */ - ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ - memcpy(tmp,ptr,4); - set_message(ptr,17,17 + len,True); - memcpy(ptr,tmp,4); - - CVAL(ptr,smb_com) = SMBtrans; - SSVAL(ptr,smb_vwv1,len); - SSVAL(ptr,smb_vwv11,len); - SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); - SSVAL(ptr,smb_vwv13,3); - SSVAL(ptr,smb_vwv14,1); - SSVAL(ptr,smb_vwv15,1); - SSVAL(ptr,smb_vwv16,2); - p2 = smb_buf(ptr); - pstrcpy(p2,mailslot); - p2 = skip_string(p2,1); - - memcpy(p2,buffer,len); - p2 += len; - - dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ - - p.ip = *pdc_ip; - p.port = DGRAM_PORT; - p.fd = sock; - p.timestamp = time(NULL); - p.packet_type = DGRAM_PACKET; - - GetTimeOfDay(&tval); - - if (!send_packet(&p)) { - DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); - close(sock); - return False; - } - - retries--; - - while (1) { - struct timeval tval2; - struct packet_struct *p_ret; - - GetTimeOfDay(&tval2); - if (TvalDiff(&tval,&tval2) > retry_time) { - if (!retries) - break; - if (!send_packet(&p)) { - DEBUG(0,("lookup_pdc_name: send_packet failed.\n")); - close(sock); - return False; - } - GetTimeOfDay(&tval); - retries--; - } - - if ((p_ret = receive_dgram_packet(sock,90,mailslot_name))) { - struct dgram_packet *dgram2 = &p_ret->packet.dgram; - char *buf; - char *buf2; - - buf = &dgram2->data[0]; - buf -= 4; - - if (CVAL(buf,smb_com) != SMBtrans) { - DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int) - CVAL(buf,smb_com), (unsigned int)SMBtrans )); - free_packet(p_ret); - continue; - } - - len = SVAL(buf,smb_vwv11); - buf2 = smb_base(buf) + SVAL(buf,smb_vwv12); - - if (len <= 0) { - DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len )); - free_packet(p_ret); - continue; - } - - DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n", - nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name), - inet_ntoa(p_ret->ip), smb_buf(buf),SVAL(buf2,0),len)); - - if(SVAL(buf2,0) != QUERYFORPDC_R) { - DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n", - (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R )); - free_packet(p_ret); - continue; - } - - buf2 += 2; - /* Note this is safe as it is a bounded strcpy. */ - fstrcpy(ret_name, buf2); - ret_name[sizeof(fstring)-1] = '\0'; - close(sock); - free_packet(p_ret); - return True; - } - } - - close(sock); - return False; -#endif /* defined(I_HATE_WINDOWS_REPLY_CODE) */ -} - /******************************************************** Get the IP address list of the primary domain controller for a domain. @@ -1227,68 +1176,81 @@ NT GETDC call, UNICODE, NT domain SID and uncle tom cobbley and all... BOOL get_pdc_ip(const char *domain, struct in_addr *ip) { - struct in_addr *ip_list; + struct ip_service *ip_list; int count; - int i = 0; /* Look up #1B name */ - if (!internal_resolve_name(domain, 0x1b, &ip_list, &count)) + if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) return False; /* if we get more than 1 IP back we have to assume it is a multi-homed PDC and not a mess up */ - + if ( count > 1 ) { - DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count)); - - /* look for a local net */ - for ( i=0; i= 4 ) { DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, *ordered ? "":"un")); DEBUG(4,("get_dc_list: ")); for ( i=0; inext) { - - /* - * we have a match IFF the domain and server name matches - * (a) the domain matches, - * (b) the IP address matches (if we have one) - * (c) the server name (if specified) matches - */ - - if ( !strequal(domain, fcc->domain_name) || !strequal(server, fcc->controller) ) - continue; /* no match; check the next entry */ - - /* we have a match so see if it is still current */ - - if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT) - { - /* Cache entry has expired, delete it */ - - DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", - domain, server )); - - DLIST_REMOVE(failed_connection_cache, fcc); - SAFE_FREE(fcc); - - return NT_STATUS_OK; - } - - /* The timeout hasn't expired yet so return false */ - - DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n", - domain, server )); - - result = fcc->nt_status; - return result; - } - - /* end of function means no cache entry */ - return NT_STATUS_OK; -} - -/********************************************************************** - Add an entry to the failed conneciton cache -**********************************************************************/ - -void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) -{ - struct failed_connection_cache *fcc; - - SMB_ASSERT(!NT_STATUS_IS_OK(result)); - - /* Check we already aren't in the cache. We always have to have - a domain, but maybe not a specific DC name. */ - - for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { - if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) - { - DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n", - domain, server )); - return; - } - } - - /* Create negative lookup cache entry for this domain and controller */ - - if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) ) - { - DEBUG(0, ("malloc failed in add_failed_connection_entry!\n")); - return; - } - - ZERO_STRUCTP(fcc); - - fstrcpy( fcc->domain_name, domain ); - fstrcpy( fcc->controller, server ); - fcc->lookup_time = time(NULL); - fcc->nt_status = result; - - DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n", - domain, server )); - - DLIST_ADD(failed_connection_cache, fcc); -} - -/**************************************************************************** -****************************************************************************/ - -void flush_negative_conn_cache( void ) -{ - struct failed_connection_cache *fcc; - - fcc = failed_connection_cache; - - while (fcc) { - struct failed_connection_cache *fcc_next; - - fcc_next = fcc->next; - DLIST_REMOVE(failed_connection_cache, fcc); - free(fcc); - - fcc = fcc_next; - } - -} - /**************************************************************************** Utility function to return the name of a DC. The name is guaranteed to be valid since we have already done a name_status_find on it @@ -162,9 +31,9 @@ void flush_negative_conn_cache( void ) BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) { - struct in_addr *ip_list = NULL, dc_ip, exclude_ip; + struct ip_service *ip_list = NULL; + struct in_addr dc_ip, exclude_ip; int count, i; - BOOL list_ordered; BOOL use_pdc_only; NTSTATUS result; @@ -181,7 +50,7 @@ BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) /* check the connection cache and perform the node status lookup only if the IP is not found to be bad */ - if (name_status_find(domain, 0x1c, 0x20, dc_ip, srv_name) ) { + if (name_status_find(domain, 0x1b, 0x20, dc_ip, srv_name) ) { result = check_negative_conn_cache( domain, srv_name ); if ( NT_STATUS_IS_OK(result) ) goto done; @@ -192,7 +61,7 @@ BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) /* get a list of all domain controllers */ - if (!get_dc_list( domain, &ip_list, &count, &list_ordered) ) { + if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) { DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); return False; } @@ -201,25 +70,19 @@ BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) if ( use_pdc_only ) { for (i = 0; i < count; i++) { - if (ip_equal( exclude_ip, ip_list[i])) - zero_ip(&ip_list[i]); + if (ip_equal( exclude_ip, ip_list[i].ip)) + zero_ip(&ip_list[i].ip); } } - /* Pick a nice close server, but only if the list was not ordered */ - - if (!list_ordered && (count > 1) ) { - qsort(ip_list, count, sizeof(struct in_addr), QSORT_CAST ip_compare); - } - for (i = 0; i < count; i++) { - if (is_zero_ip(ip_list[i])) + if (is_zero_ip(ip_list[i].ip)) continue; - if (name_status_find(domain, 0x1c, 0x20, ip_list[i], srv_name)) { + if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) { result = check_negative_conn_cache( domain, srv_name ); if ( NT_STATUS_IS_OK(result) ) { - dc_ip = ip_list[i]; + dc_ip = ip_list[i].ip; goto done; } } -- cgit From 9e2f008bb99af8fd83136cbd8e5a785d5348276b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Jun 2003 18:08:00 +0000 Subject: forgot one file (This used to be commit ef978bd851431da373e005177504dbef2611cf4f) --- source3/libsmb/conncache.c | 158 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 source3/libsmb/conncache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c new file mode 100644 index 0000000000..ab0501b0be --- /dev/null +++ b/source3/libsmb/conncache.c @@ -0,0 +1,158 @@ +/* + Unix SMB/CIFS implementation. + + Winbind daemon connection manager + + Copyright (C) Tim Potter 2001 + Copyright (C) Andrew Bartlett 2002 + Copyright (C) Gerald (Jerry) Carter 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + + +#include "includes.h" + +#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */ + +#define CONNCACHE_ADDR 1 +#define CONNCACHE_NAME 2 + +/* cache entry contains either a server name **or** and IP address as + the key. This means that a server could have two entries (one for each key) */ + +struct failed_connection_cache { + fstring domain_name; + fstring controller; + time_t lookup_time; + NTSTATUS nt_status; + struct failed_connection_cache *prev, *next; +}; + +static struct failed_connection_cache *failed_connection_cache; + +/********************************************************************** + Check for a previously failed connection +**********************************************************************/ + +NTSTATUS check_negative_conn_cache( const char *domain, const char *server ) +{ + struct failed_connection_cache *fcc; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + + /* can't check if we don't have strings */ + + if ( !domain || !server ) + return NT_STATUS_OK; + + for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { + + if ( !(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller)) ) + continue; /* no match; check the next entry */ + + /* we have a match so see if it is still current */ + + if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT) + { + /* Cache entry has expired, delete it */ + + DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", + domain, server )); + + DLIST_REMOVE(failed_connection_cache, fcc); + SAFE_FREE(fcc); + + return NT_STATUS_OK; + } + + /* The timeout hasn't expired yet so return false */ + + DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n", + domain, server )); + + result = fcc->nt_status; + return result; + } + + /* end of function means no cache entry */ + return NT_STATUS_OK; +} + +/********************************************************************** + Add an entry to the failed conneciton cache (aither a name of dotted + decimal IP +**********************************************************************/ + +void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) +{ + struct failed_connection_cache *fcc; + + SMB_ASSERT(!NT_STATUS_IS_OK(result)); + + /* Check we already aren't in the cache. We always have to have + a domain, but maybe not a specific DC name. */ + + for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { + if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) + { + DEBUG(10, ("add_failed_connection_entry_byname: domain %s (%s) already tried and failed\n", + domain, server )); + return; + } + } + + /* Create negative lookup cache entry for this domain and controller */ + + if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) ) + { + DEBUG(0, ("malloc failed in add_failed_connection_entry!\n")); + return; + } + + ZERO_STRUCTP(fcc); + + fstrcpy( fcc->domain_name, domain ); + fstrcpy( fcc->controller, server ); + fcc->lookup_time = time(NULL); + fcc->nt_status = result; + + DEBUG(10,("add_failed_connection_entry_byname: added domain %s (%s) to failed conn cache\n", + domain, server )); + + DLIST_ADD(failed_connection_cache, fcc); +} + +/**************************************************************************** +****************************************************************************/ + +void flush_negative_conn_cache( void ) +{ + struct failed_connection_cache *fcc; + + fcc = failed_connection_cache; + + while (fcc) { + struct failed_connection_cache *fcc_next; + + fcc_next = fcc->next; + DLIST_REMOVE(failed_connection_cache, fcc); + free(fcc); + + fcc = fcc_next; + } + +} + + -- cgit From 72876b79c9b3f0ab3cda6de42d5c8995aadd687e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Jun 2003 19:00:15 +0000 Subject: * fix typos in a few debug statements * check negative connection cache before ads_try_connect() in ads_find_dc() (This used to be commit 2a76101a3a31f5fca2f444b25e3f0486f7ef406f) --- source3/libsmb/conncache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index ab0501b0be..da31e25a9c 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -107,7 +107,7 @@ void add_failed_connection_entry(const char *domain, const char *server, NTSTATU for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) { - DEBUG(10, ("add_failed_connection_entry_byname: domain %s (%s) already tried and failed\n", + DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n", domain, server )); return; } -- cgit From 7a4e38155deda998947f8ea3ef966c4c4fe0a055 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 26 Jun 2003 05:26:20 +0000 Subject: cleaning up more build issues. Tested "--with-ads=no --with-ldap=yes" and "--with-ads=yes && make everything" (This used to be commit 3e9e4bb7d1a2f5a95539f415aa101f033b67932a) --- source3/libsmb/cliconnect.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 122cc56e45..18125e26c3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -453,6 +453,8 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) return blob2; } +#ifdef HAVE_KRB5 + /**************************************************************************** Send a extended security session setup blob, returning a reply blob. ****************************************************************************/ @@ -467,7 +469,6 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) return cli_session_setup_blob_receive(cli); } -#ifdef HAVE_KRB5 /**************************************************************************** Use in-memory credentials cache ****************************************************************************/ @@ -503,7 +504,8 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi return !cli_is_error(cli); } -#endif +#endif /* HAVE_KRB5 */ + /**************************************************************************** Do a spnego/NTLMSSP encrypted session setup. -- cgit From d27029a8742c2dffd20d8f8637a80da1a402c43d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 30 Jun 2003 17:26:45 +0000 Subject: removing old code (This used to be commit 80df684b72f273f9efc0c00646f26d17f1b4bc70) --- source3/libsmb/netlogon_unigrp.c | 172 --------------------------------------- 1 file changed, 172 deletions(-) delete mode 100644 source3/libsmb/netlogon_unigrp.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/netlogon_unigrp.c b/source3/libsmb/netlogon_unigrp.c deleted file mode 100644 index 466410d800..0000000000 --- a/source3/libsmb/netlogon_unigrp.c +++ /dev/null @@ -1,172 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Universal groups helpers - Copyright (C) Alexander Bokovoy 2002. - Copyright (C) Andrew Bartlett 2002. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - - This work was sponsored by Optifacio Software Services, Inc. -*/ - -#include "includes.h" -#define UNIGROUP_PREFIX "UNIGROUP" - -/* - Handle for netlogon_unigrp.tdb database. It is used internally - in cli_store_uni_groups_*() and cli_fetch_uni_groups() - and is initialized on first call to cli_store_uni_groups_*() -*/ -static TDB_CONTEXT *netlogon_unigrp_tdb = NULL; - -/* - Store universal groups info into netlogon_unigrp.tdb for - later usage. We use 'domain_SID/user_rid' as key and - array of uint32 where array[0] is number of elements - and elements are array[1] ... array[array[0]] -*/ - -BOOL uni_group_cache_init(void) -{ - if (!netlogon_unigrp_tdb) { - netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0, - TDB_DEFAULT, O_RDWR | O_CREAT, 0644); - } - - return (netlogon_unigrp_tdb != NULL); -} - -BOOL uni_group_cache_store_netlogon(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) -{ - TDB_DATA key,data; - fstring keystr, sid_string; - DOM_SID user_sid; - unsigned int i; - - if (!uni_group_cache_init()) { - DEBUG(0,("uni_group_cache_store_netlogon: cannot open netlogon_unigrp.tdb for write!\n")); - return False; - } - - sid_copy(&user_sid, &user->dom_sid.sid); - sid_append_rid(&user_sid, user->user_rid); - - /* Prepare key as USER-SID string */ - slprintf(keystr, sizeof(keystr), "%s/%s", - UNIGROUP_PREFIX, - sid_to_string(sid_string, &user_sid)); - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - - /* Prepare data */ - data.dsize = (user->num_groups2+1)*sizeof(uint32); - data.dptr = talloc(mem_ctx, data.dsize); - if(!data.dptr) { - DEBUG(0,("uni_group_cache_store_netlogon: cannot allocate memory!\n")); - talloc_destroy(mem_ctx); - return False; - } - - /* Store data in byteorder-independent format */ - SIVAL(&((uint32*)data.dptr)[0],0,user->num_groups2); - for(i=1; i<=user->num_groups2; i++) { - SIVAL(&((uint32*)data.dptr)[i],0,user->gids[i-1].g_rid); - } - if (tdb_store(netlogon_unigrp_tdb, key, data, TDB_REPLACE) == -1) - return False; - return True; -} - -/* - Fetch universal groups info from netlogon_unigrp.tdb for given - domain sid and user rid and allocate it using given mem_ctx. - Universal groups are returned as array of uint32 elements - and elements are array[0] ... array[num_elements-1] - -*/ -DOM_SID **uni_group_cache_fetch(DOM_SID *domain, DOM_SID *user_sid, - TALLOC_CTX *mem_ctx, uint32 *num_groups) -{ - TDB_DATA key,data; - fstring keystr; - DOM_SID **groups; - uint32 i; - uint32 group_count; - fstring sid_string; - - if (!domain) { - DEBUG(1,("uni_group_cache_fetch: expected non-null domain sid\n")); - return NULL; - } - if (!mem_ctx) { - DEBUG(1,("uni_group_cache_fetch: expected non-null memory context\n")); - return NULL; - } - if (!num_groups) { - DEBUG(1,("uni_group_cache_fetch: expected non-null num_groups\n")); - return NULL; - } - if (!netlogon_unigrp_tdb) { - netlogon_unigrp_tdb = tdb_open_log(lock_path("netlogon_unigrp.tdb"), 0, - TDB_DEFAULT, O_RDWR, 0644); - } - if (!netlogon_unigrp_tdb) { - DEBUG(5,("uni_group_cache_fetch: cannot open netlogon_unigrp.tdb for read - normal if not created yet\n")); - return NULL; - } - - *num_groups = 0; - - /* Fetch universal groups */ - slprintf(keystr, sizeof(keystr), "%s/%s", - UNIGROUP_PREFIX, - sid_to_string(sid_string, user_sid)); - key.dptr = keystr; - key.dsize = strlen(keystr) + 1; - data = tdb_fetch(netlogon_unigrp_tdb, key); - - /* There is no cached universal groups in netlogon_unigrp.tdb */ - /* for this user. */ - if (!data.dptr) - return NULL; - - /* Transfer data to receiver's memory context */ - group_count = IVAL(&((uint32*)data.dptr)[0],0); - groups = talloc(mem_ctx, (group_count)*sizeof(*groups)); - if (groups) { - for(i=0; i Date: Mon, 30 Jun 2003 20:45:14 +0000 Subject: * cleanup more DC name resolution issues in check_*domain_security() * is_trusted_domain() is broken without winbind. Still working on this. * get_global_sam_name() should return the workgroup name unless we are a standalone server (verified by volker) * Get_Pwnam() should always fall back to the username (minus domain name) even if it is not our workgroup so that TRUSTEDOMAIN\user can logon if 'user' exists in the local list of accounts (on domain members w/o winbind) Tested using Samba PDC with trusts (running winbindd) and a Samba 3.0 domain member not running winbindd. notes: make_user_info_map() is slightly broken now due to the fact that is_trusted_domain() only works with winbindd. disabled checks temporarily until I can sort this out. (This used to be commit e1d6094d066d4c16ab73075caba40a1ae6c56b1e) --- source3/libsmb/namequery_dc.c | 71 ++++++++++++++++++++++++++++++++++++++++++- source3/libsmb/trusts_util.c | 10 +++++- 2 files changed, 79 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index fc383d9a6b..8bfb00b9ad 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -5,6 +5,7 @@ Copyright (C) Tim Potter 2001 Copyright (C) Andrew Bartlett 2002 + Copyright (C) Gerald Carter 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,12 +25,54 @@ #include "includes.h" +/************************************************************************** + Find the name and IP address for a server in he realm/domain + *************************************************************************/ + +static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_name) +{ + ADS_STRUCT *ads; + const char *realm = domain; + + if (strcasecmp(realm, lp_workgroup()) == 0) + realm = lp_realm(); + + ads = ads_init(realm, domain, NULL); + if (!ads) + return False; + + /* we don't need to bind, just connect */ + ads->auth.flags |= ADS_AUTH_NO_BIND; + + DEBUG(4,("ads_dc_name: domain=%s\n", domain)); + +#ifdef HAVE_ADS + /* a full ads_connect() is actually overkill, as we don't srictly need + to do the SASL auth in order to get the info we need, but libads + doesn't offer a better way right now */ + ads_connect(ads); +#endif + + if (!ads->config.realm) + return False; + + fstrcpy(srv_name, ads->config.ldap_server_name); + strupper(srv_name); + *dc_ip = ads->ldap_ip; + ads_destroy(&ads); + + DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n", + srv_name, inet_ntoa(*dc_ip))); + + return True; +} + /**************************************************************************** Utility function to return the name of a DC. The name is guaranteed to be valid since we have already done a name_status_find on it ***************************************************************************/ -BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) +static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) { struct ip_service *ip_list = NULL; struct in_addr dc_ip, exclude_ip; @@ -109,3 +152,29 @@ BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) return True; } + +/********************************************************************** + wrapper around ads and rpc methods of finds DC's +**********************************************************************/ + +BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) +{ + struct in_addr dc_ip; + BOOL ret; + + zero_ip(&dc_ip); + + ret = False; + if (lp_security() == SEC_ADS) + ret = ads_dc_name(domain, &dc_ip, srv_name); + + if (!ret) { + /* fall back on rpc methods if the ADS methods fail */ + ret = rpc_dc_name(domain, srv_name, &dc_ip); + } + + *ip_out = dc_ip; + + return ret; +} + diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index e0c5e79595..569b0521be 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -153,8 +153,16 @@ BOOL is_trusted_domain(const char* dom_name) /* * Query the trustdom_cache updated periodically. The only * way for domain member server. + * + * Sure...it's all fun and games until someone gets hurt... + * This call cannot work without winbindd running since it + * is the only process updating the cache currently. + * + * FIXME!!! make this always true for now until I figure + * out what to do --jerry */ - if (trustdom_cache_fetch(dom_name, &trustdom_sid)) { + + if (True || trustdom_cache_fetch(dom_name, &trustdom_sid)) { return True; } -- cgit From db6ce132e360a42ea6843c81429be194662fce39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 1 Jul 2003 03:49:41 +0000 Subject: * fix the trustdom_cache to work when winbindd is not running. smbd will update the trustdom_cache periodically after locking the timestamp key (This used to be commit 7bc4b65b91f98271089335cc301146d5f0c76c3a) --- source3/libsmb/trustdom_cache.c | 124 ++++++++++++++++++++++++++++++++++++++++ source3/libsmb/trusts_util.c | 100 +++++++++++++++++++++++++------- 2 files changed, 202 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 61b024da43..8378125088 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -26,6 +26,7 @@ #define DBGC_CLASS DBGC_ALL /* there's no proper class yet */ #define TDOMKEY_FMT "TDOM/%s" +#define TDOMTSKEY "TDOMCACHE/TIMESTAMP" /** @@ -186,6 +187,71 @@ BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) } +/******************************************************************* + fetch the timestamp from the last update +*******************************************************************/ + +uint32 trustdom_cache_fetch_timestamp( void ) +{ + char *value; + time_t timeout; + uint32 timestamp; + + /* init the cache */ + if (!gencache_init()) + return False; + + if (!gencache_get(TDOMTSKEY, &value, &timeout)) { + DEBUG(5, ("no timestamp for trusted domain cache located.\n")); + return 0; + } + + timestamp = atoi(value); + + return timestamp; +} + +/******************************************************************* + store the timestamp from the last update +*******************************************************************/ + +BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout ) +{ + fstring value; + + /* init the cache */ + if (!gencache_init()) + return False; + + snprintf(value, sizeof(value), "%d", t ); + + if (!gencache_set(TDOMTSKEY, value, timeout)) { + DEBUG(5, ("failed to set timestamp for trustdom_cache\n")); + return False; + } + + return True; +} + + +/******************************************************************* + lock the timestamp entry in the trustdom_cache +*******************************************************************/ + +BOOL trustdom_cache_lock_timestamp( void ) +{ + return gencache_lock_entry( TDOMTSKEY ) != -1; +} + +/******************************************************************* + unlock the timestamp entry in the trustdom_cache +*******************************************************************/ + +void trustdom_cache_unlock_timestamp( void ) +{ + gencache_unlock_entry( TDOMTSKEY ); +} + /** * Delete single trustdom entry. Look at the * gencache_iterate definition. @@ -216,3 +282,61 @@ void trustdom_cache_flush(void) DEBUG(5, ("Trusted domains cache flushed\n")); } +/******************************************************************** + update the trustdom_cache if needed +********************************************************************/ +#define TRUSTDOM_UPDATE_INTERVAL 600 + +void update_trustdom_cache( void ) +{ + char **domain_names; + DOM_SID *dom_sids; + uint32 num_domains; + uint32 last_check; + int time_diff; + TALLOC_CTX *mem_ctx = NULL; + time_t now = time(NULL); + int i; + + /* get the timestamp. We have to initialise it if the last timestamp == 0 */ + + if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 ) + trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL); + + time_diff = now - last_check; + + if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) { + DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n")); + return; + } + + /* lock the timestamp */ + if ( !trustdom_cache_lock_timestamp() ) + return; + + if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) { + DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n")); + goto done; + } + + /* get the domains and store them */ + + if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names, + &num_domains, &dom_sids) ) + { + for ( i=0; i Date: Tue, 1 Jul 2003 17:51:52 +0000 Subject: * fixed volker's wbinfo -a lockup again. This one was my fault. It was caused by the winbind_ping() call in is_trusted_domain() o if we are a DC then we check our own direct trust relationships we have to rely on winbindd to update the truatdom_cache o if we are a domain member, then we can update the trustdom_cache ourselves if winbindd is not there (This used to be commit 22dfcafb37f7109dc455f4fb6323a25ba4f097bc) --- source3/libsmb/trusts_util.c | 79 +++++++++++--------------------------------- 1 file changed, 19 insertions(+), 60 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 464a3324c1..77e63709aa 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -1,4 +1,4 @@ -/* +/* * Unix SMB/CIFS implementation. * Routines to operate on various trust relationships * Copyright (C) Andrew Bartlett 2001 @@ -127,8 +127,8 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, Enumerate the list of trusted domains from a DC *********************************************************************/ -BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, - char ***domain_names, uint32 *num_domains, +BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, + char ***domain_names, uint32 *num_domains, DOM_SID **sids ) { POLICY_HND pol; @@ -138,36 +138,36 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, uint32 enum_ctx = 0; struct cli_state *cli = NULL; BOOL retry; - + *domain_names = NULL; *num_domains = 0; *sids = NULL; - + /* lookup a DC first */ - + if ( !get_dc_name(domain, dc_name, &dc_ip) ) { DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n", domain)); return False; } - + /* setup the anonymous connection */ - - result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC", + + result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC", "", "", "", 0, &retry); if ( !NT_STATUS_IS_OK(result) ) goto done; - + /* open the LSARPC_PIPE */ - + if ( !cli_nt_session_open( cli, PI_LSARPC ) ) { result = NT_STATUS_UNSUCCESSFUL; goto done; } - + /* get a handle */ - - result = cli_lsa_open_policy(cli, mem_ctx, True, + + result = cli_lsa_open_policy(cli, mem_ctx, True, POLICY_VIEW_LOCAL_INFORMATION, &pol); if ( !NT_STATUS_IS_OK(result) ) goto done; @@ -176,56 +176,15 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx, num_domains, domain_names, sids); - if ( !NT_STATUS_IS_OK(result) ) + if ( !NT_STATUS_IS_OK(result) ) goto done; - -done: + +done: /* cleanup */ - + cli_nt_session_close( cli ); cli_shutdown( cli ); - - return NT_STATUS_IS_OK(result); -} - - -/** - * Verify whether or not given domain is trusted. - * - * @param domain_name name of the domain to be verified - * @return true if domain is one of the trusted once or - * false if otherwise - **/ - -BOOL is_trusted_domain(const char* dom_name) -{ - DOM_SID trustdom_sid; - char *pass = NULL; - time_t lct; - BOOL ret; - /* if we are a DC, then check for a direct trust relationships */ - - if (lp_server_role() == ROLE_DOMAIN_BDC || lp_server_role() == ROLE_DOMAIN_PDC) { - ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct); - SAFE_FREE(pass); - if (ret) - return True; - } - - /* if winbindd is not up then we need to update the trustdom_cache ourselves */ - - if ( !winbind_ping() ) - update_trustdom_cache(); - - /* now the trustdom cache should be available a DC could still - * have a transitive trust so fall back to the cache of trusted - * domains (like a domain member would use */ - - if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) { - return True; - } - - return False; + return NT_STATUS_IS_OK(result); } -- cgit From d304a61cc70af9bec3f630043f3e7e600352deea Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 3 Jul 2003 04:54:49 +0000 Subject: fix bug #190; WINS server was getting marked as dead when it was not. (This used to be commit fa354f3ceefe53bdfd4f543559041d337b75613f) --- source3/libsmb/namequery.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 81c0c14437..9875f77c72 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -516,7 +516,9 @@ struct in_addr *name_query(int fd,const char *name,int name_type, } } - if (timed_out) { + /* only set timed_out if we didn't fund what we where looking for*/ + + if ( !found && timed_out ) { *timed_out = True; } @@ -792,7 +794,10 @@ BOOL resolve_wins(const char *name, int name_type, ip_list = name_query(sock,name,name_type, False, True, wins_ip, return_count, &flags, &timed_out); - if ( !ip_list ) + + /* exit loop if we got a list of addresses */ + + if ( ip_list ) goto success; close(sock); @@ -1278,6 +1283,13 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, if ( (num_addresses == 0) && !done_auto_lookup ) return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder); + /* maybe we just failed? */ + + if ( num_addresses == 0 ) { + DEBUG(4,("get_dc_list: no servers found\n")); + return False; + } + if ( (return_iplist = (struct ip_service *) malloc(num_addresses * sizeof(struct ip_service))) == NULL ) { -- cgit From ce72beb2b558d86fb49063c6b1fa00e07952ce56 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Jul 2003 19:11:31 +0000 Subject: Removed strupper/strlower macros that automatically map to strupper_m/strlower_m. I really want people to think about when they're using multibyte strings. Jeremy. (This used to be commit ff222716a08af65d26ad842ce4c2841cc6540959) --- source3/libsmb/clirap.c | 4 ++-- source3/libsmb/clirap2.c | 4 ++-- source3/libsmb/namequery_dc.c | 2 +- source3/libsmb/nmblib.c | 2 +- source3/libsmb/ntlmssp.c | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 9d4411797d..a307ac6ccf 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -92,13 +92,13 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) SSVAL(p,0,1); p += 2; pstrcpy_base(p,user,param); - strupper(p); + strupper_m(p); p += 21; p++; p += 15; p++; pstrcpy_base(p, workstation, param); - strupper(p); + strupper_m(p); p += 16; SSVAL(p, 0, CLI_BUFFER_SIZE); p += 2; diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 948e88061a..669b33860d 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1396,11 +1396,11 @@ BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) PUTDWORD(p, 0); /* Null pointer */ PUTDWORD(p, 0); /* Null pointer */ fstrcpy(upperbuf, user); - strupper(upperbuf); + strupper_m(upperbuf); PUTSTRINGF(p, upperbuf, RAP_USERNAME_LEN); p++; /* strange format, but ok */ fstrcpy(upperbuf, workstation); - strupper(upperbuf); + strupper_m(upperbuf); PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN); PUTWORD(p, CLI_BUFFER_SIZE); PUTWORD(p, CLI_BUFFER_SIZE); diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 8bfb00b9ad..c9d45a7acc 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -57,7 +57,7 @@ static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_n return False; fstrcpy(srv_name, ads->config.ldap_server_name); - strupper(srv_name); + strupper_m(srv_name); *dc_ip = ads->ldap_ip; ads_destroy(&ads); diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b96111240f..157a2bb43c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -823,7 +823,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope(), 63 ); - strupper( n->scope ); + strupper_m( n->scope ); } /******************************************************************* diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 636e384e65..609b394560 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -175,11 +175,11 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; get_mydomname(dnsdomname); - strlower(dnsdomname); + strlower_m(dnsdomname); dnsname[0] = '\0'; get_myfullname(dnsname); - strlower(dnsname); + strlower_m(dnsname); if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { -- cgit From c674e411c7e7a5d56ef455dab5ecbea2eaa4883e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Jul 2003 20:37:01 +0000 Subject: i guess i'm the only one this ever annyoed... fix the confusion when we tdb_lock_bystring() but we retrieve an entry using tdb_fetch_by_string. It's now always tdb.*bystring() (This used to be commit 66359531b89368939f0e8f584a45844b5f2f99e7) --- source3/libsmb/samlogon_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 7863ad7727..72c10007bf 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -143,7 +143,7 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) data.dsize = prs_offset( &ps ); data.dptr = prs_data_p( &ps ); - if (tdb_store_by_string(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) + if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) result = True; prs_mem_free( &ps ); -- cgit From 31e6ed17a34dd922355bfe515909290947e87c54 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 14 Jul 2003 01:49:07 +0000 Subject: Delete obsolete comment. (This used to be commit 5416c51133297e866210ec0d8454e04c25541d91) --- source3/libsmb/ntlmssp.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 609b394560..4dc9d42659 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -190,7 +190,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, target_name_dns = dnsname; } - /* the numbers here are the string type flags */ msrpc_gen(&struct_blob, "aaaaa", ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN, target_name, ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), -- cgit From 456f51bcbe04ccbb37a27b6e115a851cc134adcd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Jul 2003 08:46:32 +0000 Subject: Jeremy requested that I get my NTLMSSP patch into CVS. He didn't request the schannel code, but I've included that anyway. :-) This patch revives the client-side NTLMSSP support for RPC named pipes in Samba, and cleans up the client and server schannel code. The use of the new code is enabled by the 'sign', 'seal' and 'schannel' commands in rpcclient. The aim was to prove that our separate NTLMSSP client library actually implements NTLMSSP signing and sealing as per Microsoft's NTLMv1 implementation, in the hope that knowing this will assist us in correctly implementing NTLMSSP signing for SMB packets. (Still not yet functional) This patch replaces the NTLMSSP implementation in rpc_client/cli_pipe.c with calls to libsmb/ntlmssp.c. In the process, we have gained the ability to use the more secure NT password, and the ability to sign-only, instead of having to seal the pipe connection. (Previously we were limited to sealing, and could only use the LM-password derived key). Our new client-side NTLMSSP code also needed alteration to cope with our comparatively simple server-side implementation. A future step is to replace it with calls to the same NTLMSSP library. Also included in this patch is the schannel 'sign only' patch I submitted to the team earlier. While not enabled (and not functional, at this stage) the work in this patch makes the code paths *much* easier to follow. I have also included similar hooks in rpccleint to allow the use of schannel on *any* pipe. rpcclient now defaults to not using schannel (or any other extra per-pipe authenticiation) for any connection. The 'schannel' command enables schannel for all pipes until disabled. This code is also much more secure than the previous code, as changes to our cli_pipe routines ensure that the authentication footer cannot be removed by an attacker, and more error states are correctly handled. (The same needs to be done to our server) Andrew Bartlett (This used to be commit 5472ddc9eaf4e79c5b2e1c8ee8c7f190dc285f19) --- source3/libsmb/cliconnect.c | 6 ++ source3/libsmb/clientgen.c | 42 ++++++++- source3/libsmb/ntlmssp.c | 107 ++++++++++++++++++--- source3/libsmb/ntlmssp_parse.c | 75 ++++++++------- source3/libsmb/ntlmssp_sign.c | 206 +++++++++++++++++++++++++++++++++-------- source3/libsmb/pwd_cache.c | 14 +-- source3/libsmb/smbencrypt.c | 31 +++++++ 7 files changed, 385 insertions(+), 96 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 18125e26c3..cdd80b7f0c 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -540,6 +540,12 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(); + if (cli->sign_info.negotiated_smb_signing + || cli->sign_info.mandetory_signing) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + } + do { nt_status = ntlmssp_client_update(ntlmssp_state, blob_in, &blob_out); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8d4e8a266c..93fa94c1db 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -203,12 +203,9 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) fstrcpy(cli->domain , usr->domain); fstrcpy(cli->user_name, usr->user_name); memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); - cli->ntlmssp_flags = usr->ntlmssp_flags; - cli->ntlmssp_cli_flgs = usr != NULL ? usr->ntlmssp_flags : 0; - DEBUG(10,("cli_init_creds: user %s domain %s flgs: %x\nntlmssp_cli_flgs:%x\n", - cli->user_name, cli->domain, - cli->ntlmssp_flags,cli->ntlmssp_cli_flgs)); + DEBUG(10,("cli_init_creds: user %s domain %s\n", + cli->user_name, cli->domain)); } /**************************************************************************** @@ -287,6 +284,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->initialised = 1; cli->allocated = alloced_cli; + cli->pipe_idx = -1; + return cli; /* Clean up after malloc() error */ @@ -302,18 +301,51 @@ struct cli_state *cli_initialise(struct cli_state *cli) return NULL; } +/**************************************************************************** +close the session +****************************************************************************/ + +void cli_nt_session_close(struct cli_state *cli) +{ + if (cli->ntlmssp_pipe_state) { + ntlmssp_client_end(&cli->ntlmssp_pipe_state); + } + + cli_close(cli, cli->nt_pipe_fnum); + cli->nt_pipe_fnum = 0; + cli->pipe_idx = -1; +} + +/**************************************************************************** +close the NETLOGON session holding the session key for NETSEC +****************************************************************************/ + +void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) +{ + if (cli->saved_netlogon_pipe_fnum != 0) { + cli_close(cli, cli->saved_netlogon_pipe_fnum); + cli->saved_netlogon_pipe_fnum = 0; + } +} + /**************************************************************************** Close a client connection and free the memory without destroying cli itself. ****************************************************************************/ void cli_close_connection(struct cli_state *cli) { + cli_nt_session_close(cli); + cli_nt_netlogon_netsec_session_close(cli); + SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); cli_free_signing_context(cli); data_blob_free(&cli->secblob); + if (cli->ntlmssp_pipe_state) + ntlmssp_client_end(&cli->ntlmssp_pipe_state); + if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); cli->mem_ctx = NULL; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 4dc9d42659..66dc6e08eb 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -409,6 +409,10 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; } + if (ntlmssp_state->use_ntlmv2) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; + } + /* generate the ntlmssp negotiate packet */ msrpc_gen(next_request, "CddAA", "NTLMSSP", @@ -435,7 +439,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st uint32 chal_flags, ntlmssp_command, unkn1, unkn2; DATA_BLOB server_domain_blob; DATA_BLOB challenge_blob; - DATA_BLOB struct_blob; + DATA_BLOB struct_blob = data_blob(NULL, 0); char *server_domain; const char *chal_parse_string; const char *auth_gen_string; @@ -443,28 +447,48 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); uint8 datagram_sess_key[16]; + size_t datagram_sess_key_len; +#if 0 /* until we know what flag to tigger it on */ generate_random_buffer(datagram_sess_key, sizeof(datagram_sess_key), False); + datagram_sess_key_len = sizeof(datagram_sess_key); +#else + ZERO_STRUCT(datagram_sess_key); + datagram_sess_key_len = 0; +#endif if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", &ntlmssp_command, &server_domain_blob, &chal_flags)) { - DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); + dump_data(2, reply.data, reply.length); + return NT_STATUS_INVALID_PARAMETER; } data_blob_free(&server_domain_blob); + DEBUG(3, ("Got challenge flags:\n")); + debug_ntlmssp_flags(chal_flags); + if (chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { - chal_parse_string = "CdUdbddB"; + if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { + chal_parse_string = "CdUdbddB"; + } else { + chal_parse_string = "CdUdbdd"; + } auth_gen_string = "CdBBUUUBd"; ntlmssp_state->unicode = True; ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; } else if (chal_flags & NTLMSSP_NEGOTIATE_OEM) { - chal_parse_string = "CdAdbddB"; + if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { + chal_parse_string = "CdAdbddB"; + } else { + chal_parse_string = "CdAdbdd"; + } auth_gen_string = "CdBBAAABd"; ntlmssp_state->unicode = False; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; @@ -473,6 +497,25 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_INVALID_PARAMETER; } + if (chal_flags & NTLMSSP_NEGOTIATE_LM_KEY && lp_client_lanman_auth()) { + /* server forcing us to use LM */ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; + ntlmssp_state->use_ntlmv2 = False; + } else { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + + if (!(chal_flags & NTLMSSP_NEGOTIATE_NTLM2)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + } + + if (!(chal_flags & NTLMSSP_NEGOTIATE_128)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; + } + + DEBUG(3, ("NTLMSSP: Set final flags:\n")); + debug_ntlmssp_flags(ntlmssp_state->neg_flags); + if (!msrpc_parse(&reply, chal_parse_string, "NTLMSSP", &ntlmssp_command, @@ -481,7 +524,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st &challenge_blob, 8, &unkn1, &unkn2, &struct_blob)) { - DEBUG(0, ("Failed to parse the NTLMSSP Challenge\n")); + DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); + dump_data(2, reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } @@ -493,6 +537,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st if (ntlmssp_state->use_ntlmv2) { + if (!struct_blob.length) { + /* be lazy, match win2k - we can't do NTLMv2 without it */ + return NT_STATUS_INVALID_PARAMETER; + } + /* TODO: if the remote server is standalone, then we should replace 'domain' with the server name as supplied above */ @@ -506,10 +555,12 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_NO_MEMORY; } } else { + uchar lm_hash[16]; uchar nt_hash[16]; + E_deshash(ntlmssp_state->password, lm_hash); E_md4hash(ntlmssp_state->password, nt_hash); - /* non encrypted password supplied. Ignore ntpass. */ + /* lanman auth is insecure, it may be disabled */ if (lp_client_lanman_auth()) { lm_response = data_blob(NULL, 24); SMBencrypt(ntlmssp_state->password,challenge_blob.data, @@ -519,8 +570,15 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st nt_response = data_blob(NULL, 24); SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, nt_response.data); + session_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + && lp_client_lanman_auth()) { + SMBsesskeygen_lmv1(lm_hash, lm_response.data, + session_key.data); + } else { + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + } } data_blob_free(&struct_blob); @@ -533,7 +591,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->get_global_myname(), - datagram_sess_key, 16, + datagram_sess_key, datagram_sess_key_len, ntlmssp_state->neg_flags)) { data_blob_free(&lm_response); @@ -575,6 +633,8 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) (*ntlmssp_state)->unicode = True; + (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth(); + (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | @@ -596,6 +656,7 @@ NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) data_blob_free(&(*ntlmssp_state)->lm_resp); data_blob_free(&(*ntlmssp_state)->nt_resp); data_blob_free(&(*ntlmssp_state)->session_key); + data_blob_free(&(*ntlmssp_state)->stored_response); talloc_destroy(mem_ctx); } @@ -606,12 +667,18 @@ NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, DATA_BLOB reply, DATA_BLOB *next_request) { + NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; uint32 ntlmssp_command; *next_request = data_blob(NULL, 0); if (!reply.length) { - return ntlmssp_client_initial(ntlmssp_state, reply, next_request); - } + /* If there is a cached reply, use it - otherwise this is the first packet */ + if (!ntlmssp_state->stored_response.length) { + return ntlmssp_client_initial(ntlmssp_state, reply, next_request); + } + + reply = ntlmssp_state->stored_response; + } if (!msrpc_parse(&reply, "Cd", "NTLMSSP", @@ -620,9 +687,12 @@ NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, } if (ntlmssp_command == NTLMSSP_CHALLENGE) { - return ntlmssp_client_challenge(ntlmssp_state, reply, next_request); + nt_status = ntlmssp_client_challenge(ntlmssp_state, reply, next_request); } - return NT_STATUS_INVALID_PARAMETER; + if (ntlmssp_state->stored_response.length) { + data_blob_free(&ntlmssp_state->stored_response); + } + return nt_status; } NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *user) @@ -651,3 +721,16 @@ NTSTATUS ntlmssp_set_domain(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *dom } return NT_STATUS_OK; } + +/** + * Store a DATA_BLOB containing an NTLMSSP response, for use later. + * This 'keeps' the data blob - the caller must *not* free it. + */ + +NTSTATUS ntlmssp_client_store_response(NTLMSSP_CLIENT_STATE *ntlmssp_state, + DATA_BLOB response) +{ + data_blob_free(&ntlmssp_state->stored_response); + ntlmssp_state->stored_response = response; + return NT_STATUS_OK; +} diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index ac779a3906..f53afcdcd0 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -220,23 +220,27 @@ BOOL msrpc_parse(const DATA_BLOB *blob, len2 = SVAL(blob->data, head_ofs); head_ofs += 2; ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - if (len1 & 1) { - /* if odd length and unicode */ - return False; - } - ps = va_arg(ap, char **); - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_UNICODE|STR_NOALIGN); - (*ps) = smb_xstrdup(p); + if (len1 == 0 && len2 == 0) { + *ps = smb_xstrdup(""); } else { - (*ps) = smb_xstrdup(""); + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + if (len1 & 1) { + /* if odd length and unicode */ + return False; + } + + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_UNICODE|STR_NOALIGN); + (*ps) = smb_xstrdup(p); + } else { + (*ps) = smb_xstrdup(""); + } } break; case 'A': @@ -245,19 +249,23 @@ BOOL msrpc_parse(const DATA_BLOB *blob, len2 = SVAL(blob->data, head_ofs); head_ofs += 2; ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } - ps = va_arg(ap, char **); - if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_ASCII|STR_NOALIGN); - (*ps) = smb_xstrdup(p); + /* make sure its in the right format - be strict */ + if (len1 == 0 && len2 == 0) { + *ps = smb_xstrdup(""); } else { - (*ps) = smb_xstrdup(""); + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + + if (0 < len1) { + pull_string(NULL, p, blob->data + ptr, sizeof(p), + len1, + STR_ASCII|STR_NOALIGN); + (*ps) = smb_xstrdup(p); + } else { + (*ps) = smb_xstrdup(""); + } } break; case 'B': @@ -265,12 +273,17 @@ BOOL msrpc_parse(const DATA_BLOB *blob, len1 = SVAL(blob->data, head_ofs); head_ofs += 2; len2 = SVAL(blob->data, head_ofs); head_ofs += 2; ptr = IVAL(blob->data, head_ofs); head_ofs += 4; - /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { - return False; - } + b = (DATA_BLOB *)va_arg(ap, void *); - *b = data_blob(blob->data + ptr, len1); + if (len1 == 0 && len2 == 0) { + *b = data_blob(NULL, 0); + } else { + /* make sure its in the right format - be strict */ + if (len1 != len2 || ptr + len1 > blob->length) { + return False; + } + *b = data_blob(blob->data + ptr, len1); + } break; case 'b': b = (DATA_BLOB *)va_arg(ap, void *); diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 86faf1f5e6..748c008963 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -79,13 +79,18 @@ static void calc_hash(unsigned char *hash, const char *k2, int k2l) } static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], - const char encrypted_response[16], + DATA_BLOB session_key, const char *constant) { struct MD5Context ctx3; + /* NOTE: This code is currently complate fantasy - it's + got more in common with reality than the previous code + (the LM session key is not the right thing to use) but + it still needs work */ + MD5Init(&ctx3); - MD5Update(&ctx3, encrypted_response, 5); + MD5Update(&ctx3, session_key.data, session_key.length); MD5Update(&ctx3, constant, strlen(constant)); MD5Final(digest, &ctx3); @@ -113,25 +118,28 @@ static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_stat hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); - if (!msrpc_gen(sig, "Bd", digest, sizeof(digest), ntlmssp_state->ntlmssp_seq_num)) { + if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */ + , ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } switch (direction) { case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data, sig->length); + NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data+4, sig->length-4); break; case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->srv_sign_hash, sig->data, sig->length); + NTLMSSPcalc_ap(ntlmssp_state->srv_sign_hash, sig->data+4, sig->length-4); break; } } else { uint32 crc; crc = crc32_calc_buffer(data, length); - if (!msrpc_gen(sig, "ddd", 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data, sig->length); + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); } return NT_STATUS_OK; } @@ -140,8 +148,11 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, const uchar *data, size_t length, DATA_BLOB *sig) { + NTSTATUS nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + + /* increment counter on send */ ntlmssp_state->ntlmssp_seq_num++; - return ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + return nt_status; } /** @@ -151,8 +162,8 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, */ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - const uchar *data, size_t length, - const DATA_BLOB *sig) + const uchar *data, size_t length, + const DATA_BLOB *sig) { DATA_BLOB local_sig; NTSTATUS nt_status; @@ -170,9 +181,7 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, return nt_status; } - if (memcmp(sig->data, local_sig.data, MIN(sig->length, local_sig.length)) == 0) { - return NT_STATUS_OK; - } else { + if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) { DEBUG(5, ("BAD SIG: wanted signature of\n")); dump_data(5, local_sig.data, local_sig.length); @@ -182,6 +191,97 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); return NT_STATUS_ACCESS_DENIED; } + + /* increment counter on recieive */ + ntlmssp_state->ntlmssp_seq_num++; + + return NT_STATUS_OK; +} + + +/** + * Seal data with the NTLMSSP algorithm + * + */ + +NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, + uchar *data, size_t length, + DATA_BLOB *sig) +{ + DEBUG(10,("ntlmssp_client_seal_data: seal\n")); + dump_data_pw("ntlmssp clear data\n", data, length); + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + HMACMD5Context ctx; + char seq_num[4]; + uchar digest[16]; + SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); + + hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); + hmac_md5_update(seq_num, 4, &ctx); + hmac_md5_update(data, length, &ctx); + hmac_md5_final(digest, &ctx); + + if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */ + , ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + dump_data_pw("ntlmssp client sealing hash:\n", + ntlmssp_state->cli_seal_hash, + sizeof(ntlmssp_state->cli_seal_hash)); + NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, data, length); + dump_data_pw("ntlmssp client signing hash:\n", + ntlmssp_state->cli_sign_hash, + sizeof(ntlmssp_state->cli_sign_hash)); + NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data+4, sig->length-4); + } else { + uint32 crc; + crc = crc32_calc_buffer(data, length); + if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + return NT_STATUS_NO_MEMORY; + } + + /* The order of these two operations matters - we must first seal the packet, + then seal the sequence number - this is becouse the ntlmssp_hash is not + constant, but is is rather updated with each iteration */ + + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); + + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + } + dump_data_pw("ntlmssp sealed data\n", data, length); + + /* increment counter on send */ + ntlmssp_state->ntlmssp_seq_num++; + + return NT_STATUS_OK; +} + +/** + * Unseal data with the NTLMSSP algorithm + * + */ + +NTSTATUS ntlmssp_client_unseal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, + uchar *data, size_t length, + DATA_BLOB *sig) +{ + DEBUG(10,("ntlmssp_client_unseal_data: seal\n")); + dump_data_pw("ntlmssp sealed data\n", data, length); + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + NTLMSSPcalc_ap(ntlmssp_state->srv_seal_hash, data, length); + } else { + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); + } + dump_data_pw("ntlmssp clear data\n", data, length); + + return ntlmssp_client_check_packet(ntlmssp_state, data, length, sig); } /** @@ -190,37 +290,69 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) { unsigned char p24[24]; - unsigned char lm_hash[16]; + ZERO_STRUCT(p24); + + DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); + debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (!ntlmssp_state->lm_resp.data) { - /* can't sign or check signitures yet */ - return NT_STATUS_UNSUCCESSFUL; - } - - E_deshash(ntlmssp_state->password, lm_hash); - - NTLMSSPOWFencrypt(lm_hash, ntlmssp_state->lm_resp.data, p24); - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, ntlmssp_state->cli_sign_const, p24, CLI_SIGN); - calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, ntlmssp_state->cli_seal_const, p24, CLI_SEAL); - calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, ntlmssp_state->srv_sign_const, p24, SRV_SIGN); - calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, ntlmssp_state->srv_seal_const, p24, SRV_SEAL); - } - else - { - char k2[8]; - memcpy(k2, p24, 5); - k2[5] = 0xe5; - k2[6] = 0x38; - k2[7] = 0xb0; + + calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, + ntlmssp_state->cli_sign_const, + ntlmssp_state->session_key, CLI_SIGN); + dump_data_pw("NTLMSSP client sign hash:\n", + ntlmssp_state->cli_sign_hash, + sizeof(ntlmssp_state->cli_sign_hash)); + + calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, + ntlmssp_state->cli_seal_const, + ntlmssp_state->session_key, CLI_SEAL); + dump_data_pw("NTLMSSP client sesl hash:\n", + ntlmssp_state->cli_seal_hash, + sizeof(ntlmssp_state->cli_seal_hash)); + + calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, + ntlmssp_state->srv_sign_const, + ntlmssp_state->session_key, SRV_SIGN); + dump_data_pw("NTLMSSP server sign hash:\n", + ntlmssp_state->srv_sign_hash, + sizeof(ntlmssp_state->srv_sign_hash)); + + calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, + ntlmssp_state->srv_seal_const, + ntlmssp_state->session_key, SRV_SEAL); + dump_data_pw("NTLMSSP server seal hash:\n", + ntlmssp_state->cli_sign_hash, + sizeof(ntlmssp_state->cli_sign_hash)); + } + else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { + /* can't sign or check signitures yet */ + DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n")); + return NT_STATUS_UNSUCCESSFUL; + } + + DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n")); + + calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 8); + dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); + } else { + if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) { + /* can't sign or check signitures yet */ + DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n")); + return NT_STATUS_UNSUCCESSFUL; + } - calc_hash(ntlmssp_state->ntlmssp_hash, k2, 8); + DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n")); + + calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 16); + dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, + sizeof(ntlmssp_state->ntlmssp_hash)); } ntlmssp_state->ntlmssp_seq_num = 0; - ZERO_STRUCT(lm_hash); return NT_STATUS_OK; } diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 7ddcf853c4..f45832d7d7 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -43,15 +43,10 @@ static void pwd_init(struct pwd_info *pwd) static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) { - pstring dos_passwd; - pwd_init(pwd); - push_ascii_pstring(dos_passwd, clr); - - nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); pwd->null_pwd = False; - pwd->cleartext = False; pwd->crypted = False; } @@ -61,12 +56,9 @@ static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) { - pwd_init(pwd); - push_ascii_fstring(pwd->password, clr); - pwd->cleartext = True; - pwd->null_pwd = False; - pwd->crypted = False; pwd_make_lm_nt_16(pwd, clr); + fstrcpy(pwd->password, clr); + pwd->cleartext = True; } /**************************************************************************** diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index c1b3880299..7a1a2d7d18 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -271,6 +271,8 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], void SMBsesskeygen_ntv2(const uchar kr[16], const uchar * nt_resp, uint8 sess_key[16]) { + /* a very nice, 128 bit, variable session key */ + HMACMD5Context ctx; hmac_md5_init_limK_to_64(kr, 16, &ctx); @@ -286,6 +288,9 @@ void SMBsesskeygen_ntv2(const uchar kr[16], void SMBsesskeygen_ntv1(const uchar kr[16], const uchar * nt_resp, uint8 sess_key[16]) { + /* yes, this session key does not change - yes, this + is a problem - but it is 128 bits */ + mdfour((unsigned char *)sess_key, kr, 16); #ifdef DEBUG_PASSWORD @@ -294,6 +299,32 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } +void SMBsesskeygen_lmv1(const uchar lm_hash[16], + const uchar lm_resp[24], /* only uses 8 */ + uint8 sess_key[16]) +{ + /* Calculate the LM session key (effective length 40 bits, + but changes with each session) */ + + uchar p24[24]; + uchar partial_lm_hash[16]; + + memcpy(partial_lm_hash, lm_hash, 8); + memset(partial_lm_hash + 8, 0xbd, 8); + + SMBOWFencrypt(lm_hash, lm_resp, p24); + + memcpy(sess_key, p24, 16); + sess_key[5] = 0xe5; + sess_key[6] = 0x38; + sess_key[7] = 0xb0; + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_lmv1:\n")); + dump_data(100, sess_key, 16); +#endif +} + DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, const char *domain) { -- cgit From 236702e15c26432fd09888658fd66f318d03e3f5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 14 Jul 2003 10:38:23 +0000 Subject: Fix SMB signing when using NTLMSSP... It's so simple now I know how it works - and it has nothing to do with NTLMSSP (it's just a slightly different use of the old algorithm). :-). Note: This is actually less secure then the non-NTLMSSP code, as there is no per-session random data included for NTLM logins. (NTLMv2 is better, fortunetly). Andrew Bartlett (This used to be commit 95ec8317d4c6817d192bcd52eec44a22286e10ee) --- source3/libsmb/cliconnect.c | 7 +++- source3/libsmb/smb_signing.c | 94 ++------------------------------------------ 2 files changed, 8 insertions(+), 93 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cdd80b7f0c..8c02c4fdfe 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -551,6 +551,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DATA_BLOB null = data_blob(NULL, 0); if (turn == 1) { /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); @@ -559,14 +560,16 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, msg1 = spnego_gen_auth(blob_out); } + cli_simple_set_signing(cli, + ntlmssp_state->session_key.data, + null); + /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { return False; } data_blob_free(&msg1); - cli_ntlmssp_set_signing(cli, ntlmssp_state); - blob = cli_session_setup_blob_receive(cli); nt_status = cli_nt_error(cli); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index fee2b66670..c15604c91c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -277,6 +277,9 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ { struct smb_basic_signing_context *data; + if (!user_session_key) + return False; + if (!set_smb_signing_common(cli)) { return False; } @@ -307,97 +310,6 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return True; } -/*********************************************************** - SMB signing - NTLMSSP implementation - calculate a MAC to send. -************************************************************/ - -static void cli_ntlmssp_sign_outgoing_message(struct cli_state *cli) -{ - NTSTATUS nt_status; - DATA_BLOB sig; - NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; - - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli); - - nt_status = ntlmssp_client_sign_packet(ntlmssp_state, cli->outbuf + 4, - smb_len(cli->outbuf), &sig); - - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(0, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); - return; - } - - DEBUG(10, ("sent SMB signature of\n")); - dump_data(10, sig.data, MIN(sig.length, 8)); - memcpy(&cli->outbuf[smb_ss_field], sig.data, MIN(sig.length, 8)); - - data_blob_free(&sig); -} - -/*********************************************************** - SMB signing - NTLMSSP implementation - check a MAC sent by server. -************************************************************/ - -static BOOL cli_ntlmssp_check_incoming_message(struct cli_state *cli) -{ - BOOL good; - NTSTATUS nt_status; - DATA_BLOB sig = data_blob(&cli->inbuf[smb_ss_field], 8); - - NTLMSSP_CLIENT_STATE *ntlmssp_state = cli->sign_info.signing_context; - - nt_status = ntlmssp_client_check_packet(ntlmssp_state, cli->outbuf + 4, - smb_len(cli->outbuf), &sig); - - data_blob_free(&sig); - - good = NT_STATUS_IS_OK(nt_status); - if (!NT_STATUS_IS_OK(nt_status)) { - DEBUG(5, ("NTLMSSP signing failed with %s\n", nt_errstr(nt_status))); - } - - return signing_good(cli, good); -} - -/*********************************************************** - SMB signing - NTLMSSP implementation - free signing context -************************************************************/ - -static void cli_ntlmssp_free_signing_context(struct cli_state *cli) -{ - ntlmssp_client_end((NTLMSSP_CLIENT_STATE **)&cli->sign_info.signing_context); -} - -/*********************************************************** - SMB signing - NTLMSSP implementation - setup the MAC key. -************************************************************/ - -BOOL cli_ntlmssp_set_signing(struct cli_state *cli, - NTLMSSP_CLIENT_STATE *ntlmssp_state) -{ - if (!set_smb_signing_common(cli)) { - return False; - } - - if (!NT_STATUS_IS_OK(ntlmssp_client_sign_init(ntlmssp_state))) { - return False; - } - - if (!set_smb_signing_real_common(cli)) { - return False; - } - - cli->sign_info.signing_context = ntlmssp_state; - ntlmssp_state->ref_count++; - - cli->sign_info.sign_outgoing_message = cli_ntlmssp_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_ntlmssp_check_incoming_message; - cli->sign_info.free_signing_context = cli_ntlmssp_free_signing_context; - - return True; -} - /*********************************************************** SMB signing - NULL implementation - calculate a MAC to send. ************************************************************/ -- cgit From 39de3249b0676a65cfbce23484d964f1e3334baa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jul 2003 22:26:47 +0000 Subject: Add a cli_ prefix to a few functions to ensure everything that takes a struct cli_state is so marked. Jeremy (This used to be commit 0b8724ed65799f94f2af5d1dbb9ba20f1bac53a7) --- source3/libsmb/smb_signing.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c15604c91c..466f32cb92 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -69,7 +69,7 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, SMB signing - Common code before we set a new signing implementation ************************************************************/ -static BOOL set_smb_signing_common(struct cli_state *cli) +static BOOL cli_set_smb_signing_common(struct cli_state *cli) { if (!cli->sign_info.negotiated_smb_signing && !cli->sign_info.mandetory_signing) { @@ -94,7 +94,7 @@ static BOOL set_smb_signing_common(struct cli_state *cli) SMB signing - Common code for 'real' implementations ************************************************************/ -static BOOL set_smb_signing_real_common(struct cli_state *cli) +static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) { if (cli->sign_info.mandetory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); @@ -106,7 +106,7 @@ static BOOL set_smb_signing_real_common(struct cli_state *cli) return True; } -static void mark_packet_signed(struct cli_state *cli) +static void cli_mark_packet_signed(struct cli_state *cli) { uint16 flags2; flags2 = SVAL(cli->outbuf,smb_flg2); @@ -114,7 +114,7 @@ static void mark_packet_signed(struct cli_state *cli) SSVAL(cli->outbuf,smb_flg2, flags2); } -static BOOL signing_good(struct cli_state *cli, BOOL good) +static BOOL cli_signing_good(struct cli_state *cli, BOOL good) { DEBUG(10, ("got SMB signature of\n")); dump_data(10,&cli->inbuf[smb_ss_field] , 8); @@ -194,7 +194,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) struct smb_basic_signing_context *data = cli->sign_info.signing_context; /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli); + cli_mark_packet_signed(cli); simple_packet_signature(data, cli->outbuf, data->send_seq_num, calc_md5_mac); @@ -245,7 +245,7 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) DEBUG(5, ("BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); } - return signing_good(cli, good); + return cli_signing_good(cli, good); } /*********************************************************** @@ -280,11 +280,11 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ if (!user_session_key) return False; - if (!set_smb_signing_common(cli)) { + if (!cli_set_smb_signing_common(cli)) { return False; } - if (!set_smb_signing_real_common(cli)) { + if (!cli_set_smb_signing_real_common(cli)) { return False; } @@ -365,7 +365,7 @@ BOOL cli_null_set_signing(struct cli_state *cli) static void cli_temp_sign_outgoing_message(struct cli_state *cli) { /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli); + cli_mark_packet_signed(cli); /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ @@ -397,7 +397,7 @@ static void cli_temp_free_signing_context(struct cli_state *cli) BOOL cli_temp_set_signing(struct cli_state *cli) { - if (!set_smb_signing_common(cli)) { + if (!cli_set_smb_signing_common(cli)) { return False; } -- cgit From c44a9d25a2bfff9d5ebede80f30e13e41aca797c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jul 2003 23:05:57 +0000 Subject: Added the "required" keyword to the "client signing" parameter to force it on. Fail if missmatch. Small format tidyups in smbd/sesssetup.c. Preparing to add signing on server side. Jeremy. (This used to be commit c390b3e4cd68cfc233ddf14d139e25d40f050f27) --- source3/libsmb/cliconnect.c | 16 ++++++++++++++-- source3/libsmb/clientgen.c | 3 +++ source3/libsmb/smb_signing.c | 5 ++--- 3 files changed, 19 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8c02c4fdfe..fa9af19bf5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -541,7 +541,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(); if (cli->sign_info.negotiated_smb_signing - || cli->sign_info.mandetory_signing) { + || cli->sign_info.mandatory_signing) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } @@ -1013,12 +1013,24 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) + if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) { + /* Fail if signing is mandatory and we don't want to support it. */ + if (!lp_client_signing()) { + DEBUG(1,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); + return False; + } cli->sign_info.negotiated_smb_signing = True; + } if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) && cli->sign_info.allow_smb_signing) cli->sign_info.negotiated_smb_signing = True; + /* Fail if signing is mandatory and the server doesn't support it. */ + if (cli->sign_info.mandatory_signing && !(cli->sign_info.negotiated_smb_signing)) { + DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); + return False; + } + } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 93fa94c1db..58c5ad8cd3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -261,6 +261,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) if (lp_client_signing()) cli->sign_info.allow_smb_signing = True; + + if (lp_client_signing() == Required) + cli->sign_info.mandatory_signing = True; if (!cli->outbuf || !cli->inbuf) goto error; diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 466f32cb92..d4f77bf07c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -72,7 +72,7 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, static BOOL cli_set_smb_signing_common(struct cli_state *cli) { if (!cli->sign_info.negotiated_smb_signing - && !cli->sign_info.mandetory_signing) { + && !cli->sign_info.mandatory_signing) { return False; } @@ -96,7 +96,7 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) { - if (cli->sign_info.mandetory_signing) { + if (cli->sign_info.mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); cli->sign_info.doing_signing = True; } @@ -458,4 +458,3 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } - -- cgit From 2ff85e2f0a25697970e80beb4d58d81f05bcf800 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 16 Jul 2003 02:51:28 +0000 Subject: fix typo in debug log (This used to be commit 074da426708555de082d0c2e5ae3a5cddaadcdf4) --- source3/libsmb/conncache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index da31e25a9c..e6604617d6 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -128,7 +128,7 @@ void add_failed_connection_entry(const char *domain, const char *server, NTSTATU fcc->lookup_time = time(NULL); fcc->nt_status = result; - DEBUG(10,("add_failed_connection_entry_byname: added domain %s (%s) to failed conn cache\n", + DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n", domain, server )); DLIST_ADD(failed_connection_cache, fcc); -- cgit From aed434ea9baf430bf7513ca3fb1f7b2f01792341 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 16 Jul 2003 05:51:10 +0000 Subject: Spelling. (This used to be commit 2750418752e491c5e87f0f2adf253291e31ee4c2) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clierror.c | 2 +- source3/libsmb/ntlmssp_sign.c | 14 +++++++------- source3/libsmb/smb_signing.c | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index fa9af19bf5..0dcc9e2845 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -301,7 +301,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, lm_response = data_blob(NULL, 24); SMBencrypt(pass,cli->secblob.data, lm_response.data); } else { - /* LM disabled, place NT# in LM feild instead */ + /* LM disabled, place NT# in LM field instead */ lm_response = data_blob(nt_response.data, nt_response.length); } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 58c5ad8cd3..cd9edb1cc9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -141,7 +141,7 @@ BOOL cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return False; - cli_caclulate_sign_mac(cli); + cli_calculate_sign_mac(cli); len = smb_len(cli->outbuf) + 4; diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 9ee181a90f..656671823c 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -108,7 +108,7 @@ const char *cli_errstr(struct cli_state *cli) break; case READ_BAD_SIG: slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Server packet had invalid SMB signiture!"); + "Server packet had invalid SMB signature!"); break; default: slprintf(cli_error_message, sizeof(cli_error_message) - 1, diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 748c008963..ecaef808c9 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -102,7 +102,7 @@ enum ntlmssp_direction { NTLMSSP_RECEIVE }; -static NTSTATUS ntlmssp_make_packet_signiture(NTLMSSP_CLIENT_STATE *ntlmssp_state, +static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_state, const uchar *data, size_t length, enum ntlmssp_direction direction, DATA_BLOB *sig) @@ -148,7 +148,7 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, const uchar *data, size_t length, DATA_BLOB *sig) { - NTSTATUS nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); /* increment counter on send */ ntlmssp_state->ntlmssp_seq_num++; @@ -169,11 +169,11 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, NTSTATUS nt_status; if (sig->length < 8) { - DEBUG(0, ("NTLMSSP packet check failed due to short signiture (%u bytes)!\n", + DEBUG(0, ("NTLMSSP packet check failed due to short signature (%u bytes)!\n", sig->length)); } - nt_status = ntlmssp_make_packet_signiture(ntlmssp_state, data, + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_RECEIVE, &local_sig); if (!NT_STATUS_IS_OK(nt_status)) { @@ -188,7 +188,7 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, DEBUG(5, ("BAD SIG: got signature of\n")); dump_data(5, sig->data, sig->length); - DEBUG(0, ("NTLMSSP packet check failed due to invalid signiture!\n")); + DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n")); return NT_STATUS_ACCESS_DENIED; } @@ -328,7 +328,7 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { - /* can't sign or check signitures yet */ + /* can't sign or check signatures yet */ DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n")); return NT_STATUS_UNSUCCESSFUL; } @@ -340,7 +340,7 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) sizeof(ntlmssp_state->ntlmssp_hash)); } else { if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) { - /* can't sign or check signitures yet */ + /* can't sign or check signatures yet */ DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n")); return NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d4f77bf07c..df17362f08 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -179,7 +179,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Update(&md5_ctx, buf + offset_end_of_sig, smb_len(buf) - (offset_end_of_sig - 4)); - /* caclulate the MD5 sig */ + /* calculate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); } @@ -426,7 +426,7 @@ void cli_free_signing_context(struct cli_state *cli) * Sign a packet with the current mechanism */ -void cli_caclulate_sign_mac(struct cli_state *cli) +void cli_calculate_sign_mac(struct cli_state *cli) { cli->sign_info.sign_outgoing_message(cli); } -- cgit From 8c38bb75b74ef7a4f40a5490102c77ab7d5fa0ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jul 2003 19:17:33 +0000 Subject: Add krb5_princ_component to Heimdal. Remove cli_ from mark packet signed. Jeremy. (This used to be commit dd46f8b22d6e8411081a1279e1cd32929e40370b) --- source3/libsmb/clikrb5.c | 13 +++++++++++++ source3/libsmb/smb_signing.c | 10 +++++----- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index fd5dd91325..ba8ba11368 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -388,6 +388,19 @@ failed: return ret; } + + +#if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) + const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) +{ + static krb5_data kdata; + + kdata.data = krb5_principal_get_comp_string(context, principal, i); + kdata.length = strlen(kdata.data); + return &kdata; +} +#endif + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index df17362f08..f4ee6c00e0 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -106,12 +106,12 @@ static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) return True; } -static void cli_mark_packet_signed(struct cli_state *cli) +static void mark_packet_signed(char *outbuf) { uint16 flags2; - flags2 = SVAL(cli->outbuf,smb_flg2); + flags2 = SVAL(outbuf,smb_flg2); flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - SSVAL(cli->outbuf,smb_flg2, flags2); + SSVAL(outbuf,smb_flg2, flags2); } static BOOL cli_signing_good(struct cli_state *cli, BOOL good) @@ -194,7 +194,7 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) struct smb_basic_signing_context *data = cli->sign_info.signing_context; /* mark the packet as signed - BEFORE we sign it...*/ - cli_mark_packet_signed(cli); + mark_packet_signed(cli->outbuf); simple_packet_signature(data, cli->outbuf, data->send_seq_num, calc_md5_mac); @@ -365,7 +365,7 @@ BOOL cli_null_set_signing(struct cli_state *cli) static void cli_temp_sign_outgoing_message(struct cli_state *cli) { /* mark the packet as signed - BEFORE we sign it...*/ - cli_mark_packet_signed(cli); + mark_packet_signed(cli->outbuf); /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ -- cgit From 4fbbaff415dbb8f1d06b6213e394860bf07a6b6d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jul 2003 21:06:21 +0000 Subject: Add API framework for server SMB signing. Jeremy. (This used to be commit 61fc9a7b2eafdf8cbed1f8d9aae016b828c91a08) --- source3/libsmb/smb_signing.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index f4ee6c00e0..e18d1ed42a 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -458,3 +458,24 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } + +/*********************************************************** + SMB signing - server API's. +************************************************************/ + +void srv_enable_signing(void) +{ +} + +void srv_disable_signing(void) +{ +} + +BOOL srv_check_sign_mac(char *buf) +{ + return True; +} + +void srv_calculate_sign_mac(char *buf) +{ +} -- cgit From 6ab5e14494ed6b579658f4fe3410759582d909cd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jul 2003 22:57:56 +0000 Subject: Refactor signing code to remove most dependencies on 'struct cli'. Ensure a server can't do a downgrade attack if client signing is mandatory. Add a lp_server_signing() function and a 'server signing' parameter that will act as the client one does. Jeremy (This used to be commit 203e4bf0bfb66fd9239e9a0656438a71280113cb) --- source3/libsmb/cliconnect.c | 5 ++ source3/libsmb/smb_signing.c | 205 ++++++++++++++++++++++++------------------- 2 files changed, 118 insertions(+), 92 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0dcc9e2845..49430616b3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -989,6 +989,11 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; + if ((cli->protocol < PROTOCOL_NT1) && (lp_client_signing() == Required)) { + DEBUG(1,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); + return False; + } + if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index e18d1ed42a..683a382369 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -81,7 +81,7 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) } if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(cli); + cli->sign_info.free_signing_context(&cli->sign_info); /* These calls are INCOMPATIBLE with SMB signing */ cli->readbraw_supported = False; @@ -94,11 +94,11 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) SMB signing - Common code for 'real' implementations ************************************************************/ -static BOOL cli_set_smb_signing_real_common(struct cli_state *cli) +static BOOL set_smb_signing_real_common(struct smb_sign_info *si) { - if (cli->sign_info.mandatory_signing) { + if (si->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); - cli->sign_info.doing_signing = True; + si->doing_signing = True; } DEBUG(5, ("SMB signing enabled!\n")); @@ -114,22 +114,85 @@ static void mark_packet_signed(char *outbuf) SSVAL(outbuf,smb_flg2, flags2); } -static BOOL cli_signing_good(struct cli_state *cli, BOOL good) +/*********************************************************** + SMB signing - NULL implementation - calculate a MAC to send. +************************************************************/ + +static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + /* we can't zero out the sig, as we might be trying to send a + session request - which is NBT-level, not SMB level and doesn't + have the field */ + return; +} + +/*********************************************************** + SMB signing - NULL implementation - check a MAC sent by server. +************************************************************/ + +static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si) +{ + return True; +} + +/*********************************************************** + SMB signing - NULL implementation - free signing context +************************************************************/ + +static void null_free_signing_context(struct smb_sign_info *si) +{ + return; +} + +/** + SMB signing - NULL implementation - setup the MAC key. + + @note Used as an initialisation only - it will not correctly + shut down a real signing mechanism +*/ + +static BOOL null_set_signing(struct smb_sign_info *si) +{ + si->signing_context = NULL; + + si->sign_outgoing_message = null_sign_outgoing_message; + si->check_incoming_message = null_check_incoming_message; + si->free_signing_context = null_free_signing_context; + + return True; +} + +/** + * Free the signing context + */ + +static void free_signing_context(struct smb_sign_info *si) +{ + if (si->free_signing_context) { + si->free_signing_context(si); + si->signing_context = NULL; + } + + null_set_signing(si); +} + + +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) { DEBUG(10, ("got SMB signature of\n")); - dump_data(10,&cli->inbuf[smb_ss_field] , 8); + dump_data(10,&inbuf[smb_ss_field] , 8); - if (good && !cli->sign_info.doing_signing) { - cli->sign_info.doing_signing = True; + if (good && !si->doing_signing) { + si->doing_signing = True; } if (!good) { - if (cli->sign_info.doing_signing) { + if (si->doing_signing) { DEBUG(1, ("SMB signature check failed!\n")); return False; } else { DEBUG(3, ("Server did not sign reply correctly\n")); - cli_free_signing_context(cli); + free_signing_context(si); return False; } } @@ -188,28 +251,27 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, SMB signing - Simple implementation - send the MAC. ************************************************************/ -static void cli_simple_sign_outgoing_message(struct cli_state *cli) +static void cli_simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli->outbuf); + mark_packet_signed(outbuf); - simple_packet_signature(data, cli->outbuf, data->send_seq_num, - calc_md5_mac); + simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); DEBUG(10, ("sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); - memcpy(&cli->outbuf[smb_ss_field], calc_md5_mac, 8); + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, - cli->mid, + SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; } @@ -218,24 +280,24 @@ static void cli_simple_sign_outgoing_message(struct cli_state *cli) SMB signing - Simple implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_simple_check_incoming_message(struct cli_state *cli) +static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(cli->inbuf, smb_mid), + SVAL(inbuf, smb_mid), &reply_seq_number)) { return False; } - simple_packet_signature(data, cli->inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); - server_sent_mac = &cli->inbuf[smb_ss_field]; + server_sent_mac = &inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { @@ -245,16 +307,16 @@ static BOOL cli_simple_check_incoming_message(struct cli_state *cli) DEBUG(5, ("BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); } - return cli_signing_good(cli, good); + return signing_good(inbuf, si, good); } /*********************************************************** SMB signing - Simple implementation - free signing context ************************************************************/ -static void cli_simple_free_signing_context(struct cli_state *cli) +static void cli_simple_free_signing_context(struct smb_sign_info *si) { - struct smb_basic_signing_context *data = cli->sign_info.signing_context; + struct smb_basic_signing_context *data = si->signing_context; struct outstanding_packet_lookup *list = data->outstanding_packet_list; while (list) { @@ -264,7 +326,7 @@ static void cli_simple_free_signing_context(struct cli_state *cli) } data_blob_free(&data->mac_key); - SAFE_FREE(cli->sign_info.signing_context); + SAFE_FREE(si->signing_context); return; } @@ -284,7 +346,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return False; } - if (!cli_set_smb_signing_real_common(cli)) { + if (!set_smb_signing_real_common(&cli->sign_info)) { return False; } @@ -310,66 +372,18 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return True; } -/*********************************************************** - SMB signing - NULL implementation - calculate a MAC to send. -************************************************************/ - -static void cli_null_sign_outgoing_message(struct cli_state *cli) -{ - /* we can't zero out the sig, as we might be trying to send a - session request - which is NBT-level, not SMB level and doesn't - have the field */ - return; -} - -/*********************************************************** - SMB signing - NULL implementation - check a MAC sent by server. -************************************************************/ - -static BOOL cli_null_check_incoming_message(struct cli_state *cli) -{ - return True; -} - -/*********************************************************** - SMB signing - NULL implementation - free signing context -************************************************************/ - -static void cli_null_free_signing_context(struct cli_state *cli) -{ - return; -} - -/** - SMB signing - NULL implementation - setup the MAC key. - - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism -*/ - -BOOL cli_null_set_signing(struct cli_state *cli) -{ - cli->sign_info.signing_context = NULL; - - cli->sign_info.sign_outgoing_message = cli_null_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_null_check_incoming_message; - cli->sign_info.free_signing_context = cli_null_free_signing_context; - - return True; -} - /*********************************************************** SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ -static void cli_temp_sign_outgoing_message(struct cli_state *cli) +static void cli_temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(cli->outbuf); + mark_packet_signed(outbuf); /* I wonder what BSRSPYL stands for - but this is what MS actually sends! */ - memcpy(&cli->outbuf[smb_ss_field], "BSRSPYL ", 8); + memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8); return; } @@ -377,7 +391,7 @@ static void cli_temp_sign_outgoing_message(struct cli_state *cli) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_temp_check_incoming_message(struct cli_state *cli) +static BOOL cli_temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) { return True; } @@ -386,7 +400,7 @@ static BOOL cli_temp_check_incoming_message(struct cli_state *cli) SMB signing - TEMP implementation - free signing context ************************************************************/ -static void cli_temp_free_signing_context(struct cli_state *cli) +static void cli_temp_free_signing_context(struct smb_sign_info *si) { return; } @@ -395,6 +409,15 @@ static void cli_temp_free_signing_context(struct cli_state *cli) SMB signing - NULL implementation - setup the MAC key. ************************************************************/ +BOOL cli_null_set_signing(struct cli_state *cli) +{ + return null_set_signing(&cli->sign_info); +} + +/*********************************************************** + SMB signing - temp implementation - setup the MAC key. +************************************************************/ + BOOL cli_temp_set_signing(struct cli_state *cli) { if (!cli_set_smb_signing_common(cli)) { @@ -410,16 +433,9 @@ BOOL cli_temp_set_signing(struct cli_state *cli) return True; } -/** - * Free the signing context - */ - -void cli_free_signing_context(struct cli_state *cli) +void cli_free_signing_context(struct cli_state *cli) { - if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(cli); - - cli_null_set_signing(cli); + free_signing_context(&cli->sign_info); } /** @@ -428,7 +444,7 @@ void cli_free_signing_context(struct cli_state *cli) void cli_calculate_sign_mac(struct cli_state *cli) { - cli->sign_info.sign_outgoing_message(cli); + cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); } /** @@ -445,14 +461,14 @@ BOOL cli_check_sign_mac(struct cli_state *cli) DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); good = False; } else { - good = cli->sign_info.check_incoming_message(cli); + good = cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info); } if (!good) { if (cli->sign_info.doing_signing) { return False; } else { - cli_free_signing_context(cli); + free_signing_context(&cli->sign_info); } } @@ -479,3 +495,8 @@ BOOL srv_check_sign_mac(char *buf) void srv_calculate_sign_mac(char *buf) { } + +BOOL allow_sendfile(void) +{ + return True; +} -- cgit From f1b6cd794dd5de853c4b068361a326160a3d0384 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Jul 2003 00:48:21 +0000 Subject: Putting the framework for server signing in place. Ensure we don't use sendfile when signing (I need to add this for readbraw/writebraw too...). Jeremy. (This used to be commit f2e84f1ba67b13ff29e24a38099b559d9033a680) --- source3/libsmb/smb_signing.c | 72 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 683a382369..8e3a4ff8d8 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -479,24 +479,86 @@ BOOL cli_check_sign_mac(struct cli_state *cli) SMB signing - server API's. ************************************************************/ +static struct smb_sign_info srv_sign_info = { + null_sign_outgoing_message, + null_check_incoming_message, + null_free_signing_context, + NULL, + False, + False, + False, + False +}; + +/*********************************************************** + Turn on signing after sending an oplock break. +************************************************************/ + void srv_enable_signing(void) { + srv_sign_info.doing_signing = True; } +/*********************************************************** + Turn off signing before sending an oplock break. +************************************************************/ + void srv_disable_signing(void) { + srv_sign_info.doing_signing = False; } -BOOL srv_check_sign_mac(char *buf) +/*********************************************************** + Called to validate an incoming packet from the client. +************************************************************/ + +BOOL srv_check_sign_mac(char *inbuf) { - return True; + if (!srv_sign_info.doing_signing) + return True; + + /* Check if it's a session keepalive. */ + if(CVAL(inbuf,0) == SMBkeepalive) + return True; + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_check_sign_mac: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf) )); + return False; + } + + return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); } -void srv_calculate_sign_mac(char *buf) +/*********************************************************** + Called to sign an outgoing packet to the client. +************************************************************/ + +void srv_calculate_sign_mac(char *outbuf) { + if (!srv_sign_info.doing_signing) + return; + + /* Check if it's a session keepalive. */ + /* JRA Paranioa test - do we ever generate these in the server ? */ + if(CVAL(outbuf,0) == SMBkeepalive) + return; + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_calculate_sign_mac: Logic error. Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + + srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } -BOOL allow_sendfile(void) +/*********************************************************** + Returns whether signing is active. We can't use sendfile or raw + reads/writes if it is. +************************************************************/ + +BOOL srv_signing_active(void) { - return True; + return srv_sign_info.doing_signing; } -- cgit From 583fc850781148b15f8fe20d9567ca840fb722d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Jul 2003 00:58:14 +0000 Subject: Correctly toggle the signing state to what it was previosly when sending an oplock break. Jeremy. (This used to be commit 9515de83a864250c417cf490b7be714c8e1e127e) --- source3/libsmb/smb_signing.c | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8e3a4ff8d8..23611f3e3b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -491,21 +491,14 @@ static struct smb_sign_info srv_sign_info = { }; /*********************************************************** - Turn on signing after sending an oplock break. + Turn signing off or on for oplock break code. ************************************************************/ -void srv_enable_signing(void) +BOOL srv_oplock_set_signing(BOOL onoff) { - srv_sign_info.doing_signing = True; -} - -/*********************************************************** - Turn off signing before sending an oplock break. -************************************************************/ - -void srv_disable_signing(void) -{ - srv_sign_info.doing_signing = False; + BOOL ret = srv_sign_info.doing_signing; + srv_sign_info.doing_signing = onoff; + return ret; } /*********************************************************** -- cgit From 814e987c6241601fb03335b2ba9a633d65cc5e23 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jul 2003 00:53:34 +0000 Subject: Signing so far... the client code fails on a SMBtrans2 secondary transaction I think (my changes haven't affected this I believe). Initial support on the server side for smbclient. Still doesn't work for w2k clients I think... Work in progress..... (don't change). Jeremy. (This used to be commit e5714edc233424c2f74edb6d658f32f8e0ec9275) --- source3/libsmb/smb_signing.c | 164 ++++++++++++++++++++++++++++++------------- 1 file changed, 114 insertions(+), 50 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 23611f3e3b..2612ed2367 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -57,6 +57,7 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; DLIST_REMOVE(*list, t); + SAFE_FREE(t); return True; } } @@ -179,7 +180,7 @@ static void free_signing_context(struct smb_sign_info *si) static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) { - DEBUG(10, ("got SMB signature of\n")); + DEBUG(10, ("signing_good: got SMB signature of\n")); dump_data(10,&inbuf[smb_ss_field] , 8); if (good && !si->doing_signing) { @@ -251,17 +252,27 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, SMB signing - Simple implementation - send the MAC. ************************************************************/ -static void cli_simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; + if (!si->doing_signing) + return; + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("simple_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); - DEBUG(10, ("sent SMB signature of\n")); + DEBUG(10, ("simple_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -270,17 +281,19 @@ static void cli_simple_sign_outgoing_message(char *outbuf, struct smb_sign_info Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; +#if 1 /* JRATEST */ store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; +#endif /* JRATEST */ } /*********************************************************** SMB signing - Simple implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; @@ -289,11 +302,24 @@ static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info struct smb_basic_signing_context *data = si->signing_context; + if (!si->doing_signing) + return True; + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("simple_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + return False; + } + +#if 1 /* JRATEST */ if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { return False; } +#else /* JRATEST */ + reply_seq_number = data->send_seq_num; + data->send_seq_num++; +#endif /* JRATEST */ simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -301,10 +327,10 @@ static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { - DEBUG(5, ("BAD SIG: wanted SMB signature of\n")); + DEBUG(5, ("simple_check_incoming_message: BAD SIG: wanted SMB signature of\n")); dump_data(5, calc_md5_mac, 8); - DEBUG(5, ("BAD SIG: got SMB signature of\n")); + DEBUG(5, ("simple_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); } return signing_good(inbuf, si, good); @@ -314,7 +340,7 @@ static BOOL cli_simple_check_incoming_message(char *inbuf, struct smb_sign_info SMB signing - Simple implementation - free signing context ************************************************************/ -static void cli_simple_free_signing_context(struct smb_sign_info *si) +static void simple_free_signing_context(struct smb_sign_info *si) { struct smb_basic_signing_context *data = si->signing_context; struct outstanding_packet_lookup *list = data->outstanding_packet_list; @@ -357,7 +383,8 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data->mac_key = data_blob(NULL, response.length + 16); memcpy(&data->mac_key.data[0], user_session_key, 16); - memcpy(&data->mac_key.data[16],response.data, response.length); + if (response.length) + memcpy(&data->mac_key.data[16],response.data, response.length); /* Initialise the sequence number */ data->send_seq_num = 0; @@ -365,9 +392,9 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; - cli->sign_info.sign_outgoing_message = cli_simple_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_simple_check_incoming_message; - cli->sign_info.free_signing_context = cli_simple_free_signing_context; + cli->sign_info.sign_outgoing_message = simple_sign_outgoing_message; + cli->sign_info.check_incoming_message = simple_check_incoming_message; + cli->sign_info.free_signing_context = simple_free_signing_context; return True; } @@ -376,7 +403,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ -static void cli_temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); @@ -391,7 +418,7 @@ static void cli_temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *s SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL cli_temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) { return True; } @@ -400,7 +427,7 @@ static BOOL cli_temp_check_incoming_message(char *inbuf, struct smb_sign_info *s SMB signing - TEMP implementation - free signing context ************************************************************/ -static void cli_temp_free_signing_context(struct smb_sign_info *si) +static void temp_free_signing_context(struct smb_sign_info *si) { return; } @@ -426,9 +453,9 @@ BOOL cli_temp_set_signing(struct cli_state *cli) cli->sign_info.signing_context = NULL; - cli->sign_info.sign_outgoing_message = cli_temp_sign_outgoing_message; - cli->sign_info.check_incoming_message = cli_temp_check_incoming_message; - cli->sign_info.free_signing_context = cli_temp_free_signing_context; + cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; + cli->sign_info.check_incoming_message = temp_check_incoming_message; + cli->sign_info.free_signing_context = temp_free_signing_context; return True; } @@ -450,28 +477,15 @@ void cli_calculate_sign_mac(struct cli_state *cli) /** * Check a packet with the current mechanism * @return False if we had an established signing connection - * which had a back checksum, True otherwise + * which had a bad checksum, True otherwise. */ BOOL cli_check_sign_mac(struct cli_state *cli) { - BOOL good; - - if (smb_len(cli->inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(cli->sign_info.doing_signing ? 1 : 10, ("Can't check signature on short packet! smb_len = %u\n", smb_len(cli->inbuf))); - good = False; - } else { - good = cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info); - } - - if (!good) { - if (cli->sign_info.doing_signing) { - return False; - } else { - free_signing_context(&cli->sign_info); - } + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) { + free_signing_context(&cli->sign_info); + return False; } - return True; } @@ -507,18 +521,10 @@ BOOL srv_oplock_set_signing(BOOL onoff) BOOL srv_check_sign_mac(char *inbuf) { - if (!srv_sign_info.doing_signing) - return True; - /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) return True; - if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_check_sign_mac: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf) )); - return False; - } - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); } @@ -536,22 +542,80 @@ void srv_calculate_sign_mac(char *outbuf) if(CVAL(outbuf,0) == SMBkeepalive) return; - /* JRA Paranioa test - we should be able to get rid of this... */ - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_calculate_sign_mac: Logic error. Can't check signature on short packet! smb_len = %u\n", - smb_len(outbuf) )); - abort(); - } - srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } +/*********************************************************** + Called by server negprot when signing has been negotiated. +************************************************************/ + +void srv_set_signing_negotiated(void) +{ + srv_sign_info.allow_smb_signing = True; + srv_sign_info.negotiated_smb_signing = True; + if (lp_server_signing() == Required) + srv_sign_info.mandatory_signing = True; + + srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message; + srv_sign_info.check_incoming_message = temp_check_incoming_message; + srv_sign_info.free_signing_context = temp_free_signing_context; +} + /*********************************************************** Returns whether signing is active. We can't use sendfile or raw reads/writes if it is. ************************************************************/ -BOOL srv_signing_active(void) +BOOL srv_is_signing_active(void) { return srv_sign_info.doing_signing; } + +/*********************************************************** + Turn on signing from this packet onwards. +************************************************************/ + +void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) +{ + struct smb_basic_signing_context *data; + + if (!user_session_key) + return; + + if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { + DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n", + (unsigned int)srv_sign_info.negotiated_smb_signing, + (unsigned int)srv_sign_info.mandatory_signing )); + return; + } + + /* Once we've turned on, ignore any more sessionsetups. */ + if (srv_sign_info.doing_signing) { + return; + } + + if (srv_sign_info.free_signing_context) + srv_sign_info.free_signing_context(&srv_sign_info); + + srv_sign_info.doing_signing = True; + + data = smb_xmalloc(sizeof(*data)); + + srv_sign_info.signing_context = data; + + data->mac_key = data_blob(NULL, response.length + 16); + + memcpy(&data->mac_key.data[0], user_session_key, 16); + if (response.length) + memcpy(&data->mac_key.data[16],response.data, response.length); + + /* Initialise the sequence number */ + data->send_seq_num = 0; + + /* Initialise the list of outstanding packets */ + data->outstanding_packet_list = NULL; + + srv_sign_info.sign_outgoing_message = simple_sign_outgoing_message; + srv_sign_info.check_incoming_message = simple_check_incoming_message; + srv_sign_info.free_signing_context = simple_free_signing_context; +} -- cgit From e79e26eb0002cc664ceaff62bc587ac4f3d62073 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jul 2003 06:04:20 +0000 Subject: Don't check in two places for signing turned off... Jeremy. (This used to be commit f4b02e52e25556e5b101d493e2e6404563bf96dd) --- source3/libsmb/smb_signing.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 2612ed2367..19450a9536 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -534,9 +534,6 @@ BOOL srv_check_sign_mac(char *inbuf) void srv_calculate_sign_mac(char *outbuf) { - if (!srv_sign_info.doing_signing) - return; - /* Check if it's a session keepalive. */ /* JRA Paranioa test - do we ever generate these in the server ? */ if(CVAL(outbuf,0) == SMBkeepalive) -- cgit From 490fcdd199aed91a6e982911bd1ff5019b340b4d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 23 Jul 2003 10:09:29 +0000 Subject: fixed segv in calls to pstrcpy() in cliprint.c (This used to be commit 36bc2b99b4fec2c14f8471d89381b2d6c2f9d339) --- source3/libsmb/cliprint.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index bfa33bc514..f302c045a5 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -65,16 +65,16 @@ int cli_print_queue(struct cli_state *cli, p = param; SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ p += 2; - pstrcpy(p,"zWrLeh"); /* parameter description? */ + pstrcpy_base(p,"zWrLeh", param); /* parameter description? */ p = skip_string(p,1); - pstrcpy(p,"WWzWWDDzz"); /* returned data format */ + pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */ p = skip_string(p,1); - pstrcpy(p,cli->share); /* name of queue */ + pstrcpy_base(p,cli->share, param); /* name of queue */ p = skip_string(p,1); SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ SSVAL(p,2,1000); /* size of bytes of returned data buffer */ p += 4; - pstrcpy(p,""); /* subformat */ + pstrcpy_base(p,"", param); /* subformat */ p = skip_string(p,1); DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); @@ -133,9 +133,9 @@ int cli_printjob_del(struct cli_state *cli, int job) p = param; SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; - pstrcpy(p,"W"); + pstrcpy_base(p,"W", param); p = skip_string(p,1); - pstrcpy(p,""); + pstrcpy_base(p,"", param); p = skip_string(p,1); SSVAL(p,0,job); p += 2; -- cgit From 3a5dc7c2ecacecf7dd0cfd71ff1bb298d70b391b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Jul 2003 12:33:59 +0000 Subject: convert snprintf() calls using pstrings & fstrings to pstr_sprintf() and fstr_sprintf() to try to standardize. lots of snprintf() calls were using len-1; some were using len. At least this helps to be consistent. (This used to be commit 9f835b85dd38cbe655eb19021ff763f31886ac00) --- source3/libsmb/asn1.c | 6 +++--- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/trustdom_cache.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 09d4fbb6c9..576491dd3b 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -322,9 +322,9 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); oid[0] = 0; - snprintf(el, sizeof(el), "%u", b/40); + fstr_sprintf(el, "%u", b/40); pstrcat(oid, el); - snprintf(el, sizeof(el), " %u", b%40); + fstr_sprintf(el, " %u", b%40); pstrcat(oid, el); while (asn1_tag_remaining(data) > 0) { @@ -333,7 +333,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); } while (!data->has_error && b & 0x80); - snprintf(el, sizeof(el), " %u", v); + fstr_sprintf(el, " %u", v); pstrcat(oid, el); } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 49430616b3..2188db2a62 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -190,7 +190,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, char *p; fstring lanman; - snprintf( lanman, sizeof(lanman), "Samba %s", VERSION ); + fstr_sprintf( lanman, "Samba %s", VERSION ); set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 8378125088..0128d08006 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -223,7 +223,7 @@ BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout ) if (!gencache_init()) return False; - snprintf(value, sizeof(value), "%d", t ); + fstr_sprintf(value, "%d", t ); if (!gencache_set(TDOMTSKEY, value, timeout)) { DEBUG(5, ("failed to set timestamp for trustdom_cache\n")); -- cgit From 79e2d7c24ebc06a485d8a26c1e58c684237ef533 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jul 2003 04:25:37 +0000 Subject: Server side NTLM signing works - until the first async packet. Working on this next.... Jeremy. (This used to be commit eff74a1fcc597497a4c70589a44c1b70e93ab549) --- source3/libsmb/smb_signing.c | 136 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 114 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 19450a9536..36c4147af8 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. SMB Signing Code - Copyright (C) Jeremy Allison 2002. + Copyright (C) Jeremy Allison 2003. Copyright (C) Andrew Bartlett 2002-2003 This program is free software; you can redistribute it and/or modify @@ -219,6 +219,8 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, * We do this here, to avoid modifying the packet. */ + DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number )); + SIVAL(sequence_buf, 0, seq_number); SIVAL(sequence_buf, 4, 0); @@ -249,10 +251,10 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, /*********************************************************** - SMB signing - Simple implementation - send the MAC. + SMB signing - Client implementation - send the MAC. ************************************************************/ -static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; @@ -262,7 +264,7 @@ static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* JRA Paranioa test - we should be able to get rid of this... */ if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("simple_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", smb_len(outbuf) )); abort(); } @@ -272,7 +274,7 @@ static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); - DEBUG(10, ("simple_sign_outgoing_message: sent SMB signature of\n")); + DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -281,19 +283,17 @@ static void simple_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) Uncomment this to test if the remote server actually verifies signatures...*/ data->send_seq_num++; -#if 1 /* JRATEST */ store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; -#endif /* JRATEST */ } /*********************************************************** - SMB signing - Simple implementation - check a MAC sent by server. + SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; @@ -306,20 +306,15 @@ static BOOL simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) return True; if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("simple_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); return False; } -#if 1 /* JRATEST */ if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { return False; } -#else /* JRATEST */ - reply_seq_number = data->send_seq_num; - data->send_seq_num++; -#endif /* JRATEST */ simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -327,10 +322,10 @@ static BOOL simple_check_incoming_message(char *inbuf, struct smb_sign_info *si) good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { - DEBUG(5, ("simple_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); dump_data(5, calc_md5_mac, 8); - DEBUG(5, ("simple_check_incoming_message: BAD SIG: got SMB signature of\n")); + DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); } return signing_good(inbuf, si, good); @@ -383,8 +378,17 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ data->mac_key = data_blob(NULL, response.length + 16); memcpy(&data->mac_key.data[0], user_session_key, 16); - if (response.length) + + DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); + dump_data(10, user_session_key, 16); + + if (response.length) { memcpy(&data->mac_key.data[16],response.data, response.length); + DEBUG(10, ("cli_simple_set_signing: response_data\n")); + dump_data(10, response.data, response.length); + } else { + DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); + } /* Initialise the sequence number */ data->send_seq_num = 0; @@ -392,8 +396,8 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; - cli->sign_info.sign_outgoing_message = simple_sign_outgoing_message; - cli->sign_info.check_incoming_message = simple_check_incoming_message; + cli->sign_info.sign_outgoing_message = client_sign_outgoing_message; + cli->sign_info.check_incoming_message = client_check_incoming_message; cli->sign_info.free_signing_context = simple_free_signing_context; return True; @@ -489,6 +493,94 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } +/*********************************************************** + SMB signing - Server implementation - send the MAC. +************************************************************/ + +static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +{ + unsigned char calc_md5_mac[16]; + struct smb_basic_signing_context *data = si->signing_context; + + if (!si->doing_signing) + return; + + /* JRA Paranioa test - we should be able to get rid of this... */ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf) )); + abort(); + } + + /* mark the packet as signed - BEFORE we sign it...*/ + mark_packet_signed(outbuf); + + simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); + + DEBUG(10, ("srv_sign_outgoing_message: sent SMB signature of\n")); + dump_data(10, calc_md5_mac, 8); + + memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); + +/* cli->outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signatures...*/ + + data->send_seq_num++; +#if 0 /* JRATEST */ + store_sequence_for_reply(&data->outstanding_packet_list, + SVAL(outbuf,smb_mid), + data->send_seq_num); + data->send_seq_num++; +#endif /* JRATEST */ +} + +/*********************************************************** + SMB signing - Server implementation - check a MAC sent by server. +************************************************************/ + +static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) +{ + BOOL good; + uint32 reply_seq_number; + unsigned char calc_md5_mac[16]; + unsigned char *server_sent_mac; + + struct smb_basic_signing_context *data = si->signing_context; + + if (!si->doing_signing) + return True; + + if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { + DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + return False; + } + +#if 0 /* JRATEST */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(inbuf, smb_mid), + &reply_seq_number)) { + return False; + } +#else /* JRATEST */ + reply_seq_number = data->send_seq_num; + data->send_seq_num++; +#endif /* JRATEST */ + + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + + server_sent_mac = &inbuf[smb_ss_field]; + good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + + if (!good) { + DEBUG(5, ("srv_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); + + DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); + dump_data(5, server_sent_mac, 8); + } + return signing_good(inbuf, si, good); +} + /*********************************************************** SMB signing - server API's. ************************************************************/ @@ -612,7 +704,7 @@ void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; - srv_sign_info.sign_outgoing_message = simple_sign_outgoing_message; - srv_sign_info.check_incoming_message = simple_check_incoming_message; + srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message; + srv_sign_info.check_incoming_message = srv_check_incoming_message; srv_sign_info.free_signing_context = simple_free_signing_context; } -- cgit From 08634e26e45d3dd935727e43587a137c72417cd3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jul 2003 06:19:37 +0000 Subject: SMB signing is now working with change notify. Need to fix the disconnect when bad signature received, plus check the oplock breaks.... Jermey. (This used to be commit dd83931a00ec0a2c4b78b939c54bc101ec82312f) --- source3/libsmb/smb_signing.c | 46 +++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 36c4147af8..1fe3f99c8a 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -61,8 +61,6 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return True; } } - DEBUG(0, ("Unexpected incoming packet, it's MID (%u) does not match" - " a MID in our outstanding list!\n", mid)); return False; } @@ -501,6 +499,8 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; + uint32 send_seq_number = data->send_seq_num; + BOOL was_deferred_packet; if (!si->doing_signing) return; @@ -515,7 +515,12 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); - simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); + /* See if this is a reply for a deferred packet. */ + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(outbuf, smb_mid), + &send_seq_number); + + simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); DEBUG(10, ("srv_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); @@ -525,13 +530,8 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - data->send_seq_num++; -#if 0 /* JRATEST */ - store_sequence_for_reply(&data->outstanding_packet_list, - SVAL(outbuf,smb_mid), - data->send_seq_num); - data->send_seq_num++; -#endif /* JRATEST */ + if (!was_deferred_packet) + data->send_seq_num++; } /*********************************************************** @@ -555,16 +555,8 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } -#if 0 /* JRATEST */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(inbuf, smb_mid), - &reply_seq_number)) { - return False; - } -#else /* JRATEST */ reply_seq_number = data->send_seq_num; data->send_seq_num++; -#endif /* JRATEST */ simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -634,6 +626,24 @@ void srv_calculate_sign_mac(char *outbuf) srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } +/*********************************************************** + Called by server to defer an outgoing packet. +************************************************************/ + +void srv_defer_sign_response(uint16 mid) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + store_sequence_for_reply(&data->outstanding_packet_list, + mid, data->send_seq_num); + data->send_seq_num++; +} + /*********************************************************** Called by server negprot when signing has been negotiated. ************************************************************/ -- cgit From ceb68ee051e97afb1cb08e6f458e23e8f475504e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jul 2003 19:05:32 +0000 Subject: Fix packet signing with asynchronous oplock breaks. Removed bad error message due to w2k bug. I think this code is now working.... Need more testing of course but works on all the obvious cases I can think of. Jeremy. (This used to be commit a6e537f6611cc1357fffea0b69901fba7c9ad6ea) --- source3/libsmb/smb_signing.c | 72 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 67 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 1fe3f99c8a..4a98b84826 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -187,7 +187,12 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) if (!good) { if (si->doing_signing) { - DEBUG(1, ("SMB signature check failed!\n")); + struct smb_basic_signing_context *data = si->signing_context; + + /* W2K sends a bad first signature but the sign engine is on.... JRA. */ + if (data->send_seq_num > 1) + DEBUG(1, ("SMB signature check failed!\n")); + return False; } else { DEBUG(3, ("Server did not sign reply correctly\n")); @@ -491,6 +496,21 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } +static BOOL outgoing_packet_is_oplock_break(char *outbuf) +{ + if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + return False; + } + + if (CVAL(outbuf,smb_com) != SMBlockingX) + return False; + + if (CVAL(outbuf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) + return False; + + return True; +} + /*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ @@ -502,12 +522,32 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) uint32 send_seq_number = data->send_seq_num; BOOL was_deferred_packet; - if (!si->doing_signing) + if (!si->doing_signing) { + if (si->allow_smb_signing && si->negotiated_smb_signing) { + uint16 mid = SVAL(outbuf, smb_mid); + + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, + mid, &send_seq_number); + if (!was_deferred_packet) { + /* + * Is this an outgoing oplock break ? If so, store the + * mid in the outstanding list. + */ + + if (outgoing_packet_is_oplock_break(outbuf)) { + store_sequence_for_reply(&data->outstanding_packet_list, + mid, data->send_seq_num); + } + + data->send_seq_num++; + } + } return; + } /* JRA Paranioa test - we should be able to get rid of this... */ if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", + DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n", smb_len(outbuf) )); abort(); } @@ -555,8 +595,13 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } - reply_seq_number = data->send_seq_num; - data->send_seq_num++; + /* Oplock break requests store an outgoing mid in the packet list. */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, + SVAL(inbuf, smb_mid), + &reply_seq_number)) { + reply_seq_number = data->send_seq_num; + data->send_seq_num++; + } simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -564,11 +609,28 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { + DEBUG(5, ("srv_check_incoming_message: BAD SIG: wanted SMB signature of\n")); dump_data(5, calc_md5_mac, 8); DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); + +#if 0 /* JRATEST */ + { + int i; + reply_seq_number -= 5; + for (i = 0; i < 10; i++, reply_seq_number++) { + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n", + reply_seq_number )); + break; + } + } + } +#endif /* JRATEST */ + } return signing_good(inbuf, si, good); } -- cgit From 77373f1f8e3b2f61e9bbcd9fadfb83257d390cf2 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 24 Jul 2003 23:46:27 +0000 Subject: More printf fixes - size_t is long on some architectures. (This used to be commit ba4d334b822248d8ab929c9568533431603d967e) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/ntlmssp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2188db2a62..71e80b5dbe 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -630,7 +630,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, BOOL got_kerberos_mechanism = False; DATA_BLOB blob; - DEBUG(2,("Doing spnego session setup (blob length=%d)\n", cli->secblob.length)); + DEBUG(2,("Doing spnego session setup (blob length=%l)\n", cli->secblob.length)); /* the server might not even do spnego */ if (cli->secblob.length <= 16) { diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 66dc6e08eb..175e952f86 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -279,7 +279,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&sess_key); - DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%d len2=%d\n", + DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%l len2=%l\n", ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, ntlmssp_state->lm_resp.length, ntlmssp_state->nt_resp.length)); #if 0 -- cgit From 7d833de662b83f026b54a236588da27dd8899630 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 25 Jul 2003 04:24:40 +0000 Subject: More printf portability fixes. Got caught out by some gcc'isms last time. )-: (This used to be commit 59dae1da66a5eb7e128263bd578f167d8746e9f0) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/ntlmssp.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 71e80b5dbe..eceeb96309 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -630,7 +630,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, BOOL got_kerberos_mechanism = False; DATA_BLOB blob; - DEBUG(2,("Doing spnego session setup (blob length=%l)\n", cli->secblob.length)); + DEBUG(2,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); /* the server might not even do spnego */ if (cli->secblob.length <= 16) { diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 175e952f86..a50ae9b70f 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -279,8 +279,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&sess_key); - DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%l len2=%l\n", - ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, ntlmssp_state->lm_resp.length, ntlmssp_state->nt_resp.length)); + DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", + ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); #if 0 file_save("nthash1.dat", &ntlmssp_state->nt_resp.data, &ntlmssp_state->nt_resp.length); -- cgit From 4632786cfb193dd80ce04206912297186e871814 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Jul 2003 23:15:30 +0000 Subject: W00t! Client smb signing is now working correctly with krb5 and w2k server. Server code *should* also work (I'll check shortly). May be the odd memory leak. Problem was we (a) weren't setting signing on in the client krb5 sessionsetup code (b) we need to ask for a subkey... (c). The client and server need to ask for local and remote subkeys respectively. Thanks to Paul Nelson @ Thursby for some sage advice on this :-). Jeremy. (This used to be commit 3f9e3b60709df5ab755045a093e642510d4cde00) --- source3/libsmb/cliconnect.c | 16 +++++++++++----- source3/libsmb/clikrb5.c | 23 +++++++++++++++-------- source3/libsmb/clispnego.c | 6 +++--- source3/libsmb/smb_signing.c | 15 +++++++++++++++ 4 files changed, 44 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index eceeb96309..8873c1fdc8 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -472,6 +472,7 @@ static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) /**************************************************************************** Use in-memory credentials cache ****************************************************************************/ + static void use_in_memory_ccache(void) { setenv(KRB5_ENV_CCNAME, "MEMORY:cliconnect", 1); } @@ -483,18 +484,23 @@ static void use_in_memory_ccache(void) { static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; - + unsigned char session_key_krb5[16]; + DATA_BLOB null_blob = data_blob(NULL, 0); + DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(principal, 0); + negTokenTarg = spnego_gen_negTokenTarg(principal, 0, session_key_krb5); - if (!negTokenTarg.data) return False; + if (!negTokenTarg.data) + return False; #if 0 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif + cli_simple_set_signing(cli, session_key_krb5, null_blob); + blob2 = cli_session_setup_blob(cli, negTokenTarg); /* we don't need this blob for kerberos */ @@ -551,7 +557,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DATA_BLOB null = data_blob(NULL, 0); + DATA_BLOB null_blob = data_blob(NULL, 0); if (turn == 1) { /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); @@ -562,7 +568,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, cli_simple_set_signing(cli, ntlmssp_state->session_key.data, - null); + null_blob); /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index ba8ba11368..beac8cb2c1 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -305,7 +305,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16]) { krb5_error_code retval; krb5_data packet; @@ -345,13 +345,15 @@ DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) } if ((retval = ads_krb5_mk_req(context, - &auth_context, - 0, - principal, - ccdef, &packet))) { + &auth_context, + AP_OPTS_USE_SUBKEY, + principal, + ccdef, &packet))) { goto failed; } + get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); + ret = data_blob(packet.data, packet.length); /* Hmm, heimdal dooesn't have this - what's the correct call? */ /* krb5_free_data_contents(context, &packet); */ @@ -365,17 +367,22 @@ failed: return data_blob(NULL, 0); } - BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16]) + BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote) { #ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; #endif BOOL ret = False; + krb5_error_code err; memset(session_key, 0, 16); #ifdef ENCTYPE_ARCFOUR_HMAC - if (krb5_auth_con_getremotesubkey(context, auth_context, &skey) == 0 && skey != NULL) { + if (remote) + err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); + else + err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); + if (err == 0 && skey != NULL) { if (KRB5_KEY_TYPE(skey) == ENCTYPE_ARCFOUR_HMAC && KRB5_KEY_LENGTH(skey) == 16) { @@ -403,7 +410,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16]) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index bb48f57915..fbf8323679 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -323,13 +323,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16]) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; - /* get a kerberos ticket for the service */ - tkt = cli_krb5_get_ticket(principal, time_offset); + /* get a kerberos ticket for the service and extract the session key */ + tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4a98b84826..977d5e3905 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -330,6 +330,21 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); +#if 0 /* JRATEST */ + { + int i; + reply_seq_number -= 5; + for (i = 0; i < 10; i++, reply_seq_number++) { + simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n", + reply_seq_number )); + break; + } + } + } +#endif /* JRATEST */ + } return signing_good(inbuf, si, good); } -- cgit From 455bb6de903ca3950d965b29190c09f116d91889 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 27 Jul 2003 02:28:25 +0000 Subject: Some small fixes to our charset conversion code: - Treat the NMB names in the 'session request' packet as 'ASCII'. This means that we do not get invalid multibyte from the wire, even if we truncate in the conversion. (Otherwise we panic when we try to strupper_m it). - Remove acnv_uxu2(), as it was duplicated by push_ucs2_allocate() - Remove acnv_dosu2(), as it is not used. - In push_ucs2(), with the STR_UPPER flag, do the case conversion *after* the UCS2 conversion, when it we know that the length can't change. Also faster, as we don't need to do another 2 UCS2 conversions. Andrew Bartlett (This used to be commit 912035af1178424583d0bf887a391a0cac2acd87) --- source3/libsmb/nmblib.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 157a2bb43c..7e97dbf43a 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1129,12 +1129,14 @@ char *dns_to_netbios_name(char *dns_name) /**************************************************************************** -interpret the weird netbios "name". Return the name type +interpret the weird netbios "name" into a unix fstring. Return the name type ****************************************************************************/ -static int name_interpret(char *in,char *out) +static int name_interpret(char *in, fstring name) { int ret; int len = (*in++) / 2; + fstring out_string; + char *out = out_string; *out=0; @@ -1165,6 +1167,8 @@ static int name_interpret(char *in,char *out) in += len; } #endif + pull_ascii(name, out, sizeof(fstring), sizeof(out), STR_TERMINATE); + return(ret); } @@ -1245,9 +1249,9 @@ static char *name_ptr(char *buf,int ofs) } /**************************************************************************** -extract a netbios name from a buf +extract a netbios name from a buf (into a unix string) ****************************************************************************/ -int name_extract(char *buf,int ofs,char *name) +int name_extract(char *buf,int ofs, fstring name) { char *p = name_ptr(buf,ofs); int d = PTR_DIFF(p,buf+ofs); -- cgit From 1478bcd847cfe0fe8374f403f20761675d944413 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 27 Jul 2003 03:29:40 +0000 Subject: Try again to fix up 'session request' name exchange. This time we actualy get the names... Andrew Bartlett (This used to be commit 7c9e204f7eb15139532f2cc522ed87d0ac34d118) --- source3/libsmb/nmblib.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7e97dbf43a..6ee05f0104 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1152,8 +1152,8 @@ static int name_interpret(char *in, fstring name) in += 2; out++; } - *out = 0; ret = out[-1]; + out[-1] = 0; #ifdef NETBIOS_SCOPE /* Handle any scope names */ @@ -1167,7 +1167,7 @@ static int name_interpret(char *in, fstring name) in += len; } #endif - pull_ascii(name, out, sizeof(fstring), sizeof(out), STR_TERMINATE); + pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE); return(ret); } @@ -1249,7 +1249,7 @@ static char *name_ptr(char *buf,int ofs) } /**************************************************************************** -extract a netbios name from a buf (into a unix string) +extract a netbios name from a buf (into a unix string) return name type ****************************************************************************/ int name_extract(char *buf,int ofs, fstring name) { -- cgit From 5e2235843ed98afafc9309067dea651196a62b5f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 27 Jul 2003 10:25:44 +0000 Subject: Fix comment (This used to be commit 2c395a3904395c2743df9c3035459c6f3866232d) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 977d5e3905..305a741ef1 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -230,7 +230,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, /* Calculate the 16 byte MAC - but don't alter the data in the incoming packet. - This makes for a bit for fussing about, but it's not too bad. + This makes for a bit of fussing about, but it's not too bad. */ MD5Init(&md5_ctx); -- cgit From 7730b658a10c60e0c30c0d16aa4ff2da0a99ac10 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Jul 2003 15:00:38 +0000 Subject: This adds gss-spnego to ntlm_auth. It contains some new spnego support from Jim McDonough. It is to enable cyrus sasl to provide the gss-spnego support. For a preliminary patch to cyrus sasl see http://samba.sernet.de/cyrus-gss-spnego.diff Volker (This used to be commit 45cef8f66e46abe4a25fd2b803a7d1051c1c6602) --- source3/libsmb/spnego.c | 292 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 source3/libsmb/spnego.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c new file mode 100644 index 0000000000..078191ffba --- /dev/null +++ b/source3/libsmb/spnego.c @@ -0,0 +1,292 @@ +/* + Unix SMB/CIFS implementation. + + RFC2478 Compliant SPNEGO implementation + + Copyright (C) Jim McDonough 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) +{ + ZERO_STRUCTP(token); + + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { + int i; + + switch (asn1->data[asn1->ofs]) { + /* Read mechTypes */ + case ASN1_CONTEXT(0): + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + token->mechTypes = malloc(sizeof(*token->mechTypes)); + for (i = 0; !asn1->has_error && + 0 < asn1_tag_remaining(asn1); i++) { + token->mechTypes = + realloc(token->mechTypes, (i + 1) * + sizeof(*token->mechTypes)); + asn1_read_OID(asn1, token->mechTypes + i); + } + token->mechTypes[i] = NULL; + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + break; + /* Read reqFlags */ + case ASN1_CONTEXT(1): + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_read_Integer(asn1, &token->reqFlags); + token->reqFlags |= SPNEGO_REQ_FLAG; + asn1_end_tag(asn1); + break; + /* Read mechToken */ + case ASN1_CONTEXT(2): + asn1_start_tag(asn1, ASN1_CONTEXT(2)); + asn1_read_OctetString(asn1, &token->mechToken); + asn1_end_tag(asn1); + break; + /* Read mecListMIC */ + case ASN1_CONTEXT(3): + asn1_start_tag(asn1, ASN1_CONTEXT(3)); + if (!asn1_read_OctetString(asn1, &token->mechListMIC)) { + char *mechListMIC; + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_read_GeneralString(asn1, &mechListMIC); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + token->mechListMIC = + data_blob(mechListMIC, strlen(mechListMIC)); + SAFE_FREE(mechListMIC); + } + asn1_end_tag(asn1); + break; + default: + asn1->has_error = True; + break; + } + } + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + + return !asn1->has_error; +} + +static BOOL write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) +{ + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + + /* Write mechTypes */ + if (token->mechTypes && *token->mechTypes) { + int i; + + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + for (i = 0; token->mechTypes[i]; i++) { + asn1_write_OID(asn1, token->mechTypes[i]); + } + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + } + + /* write reqFlags */ + if (token->reqFlags & SPNEGO_REQ_FLAG) { + int flags = token->reqFlags & ~SPNEGO_REQ_FLAG; + + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_write_Integer(asn1, flags); + asn1_pop_tag(asn1); + } + + /* write mechToken */ + if (token->mechToken.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(2)); + asn1_write_OctetString(asn1, token->mechToken.data, + token->mechToken.length); + asn1_pop_tag(asn1); + } + + /* write mechListMIC */ + if (token->mechListMIC.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(3)); + asn1_write_OctetString(asn1, token->mechListMIC.data, + token->mechListMIC.length); + asn1_pop_tag(asn1); + } + + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + return !asn1->has_error; +} + +static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) +{ + ZERO_STRUCTP(token); + + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_start_tag(asn1, ASN1_SEQUENCE(0)); + + while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { + switch (asn1->data[asn1->ofs]) { + case ASN1_CONTEXT(0): + /* this is listed as being non-optional by RFC2478 but + Windows doesn't always send it... */ + asn1_start_tag(asn1, ASN1_CONTEXT(0)); + asn1_start_tag(asn1, ASN1_ENUMERATED); + asn1_read_uint8(asn1, &token->negResult); + asn1_end_tag(asn1); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(1): + asn1_start_tag(asn1, ASN1_CONTEXT(1)); + asn1_read_OID(asn1, &token->supportedMech); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(2): + asn1_start_tag(asn1, ASN1_CONTEXT(2)); + asn1_read_OctetString(asn1, &token->responseToken); + asn1_end_tag(asn1); + break; + case ASN1_CONTEXT(3): + asn1_start_tag(asn1, ASN1_CONTEXT(3)); + asn1_read_OctetString(asn1, &token->mechListMIC); + asn1_end_tag(asn1); + break; + default: + asn1->has_error = True; + break; + } + } + + asn1_end_tag(asn1); + asn1_end_tag(asn1); + + return !asn1->has_error; +} + +static BOOL write_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) +{ + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_write_enumerated(asn1, token->negResult); + asn1_pop_tag(asn1); + + if (token->supportedMech) { + asn1_push_tag(asn1, ASN1_CONTEXT(1)); + asn1_write_OID(asn1, token->supportedMech); + asn1_pop_tag(asn1); + } + + if (token->responseToken.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(2)); + asn1_write_OctetString(asn1, token->responseToken.data, + token->responseToken.length); + asn1_pop_tag(asn1); + } + + if (token->mechListMIC.data) { + asn1_push_tag(asn1, ASN1_CONTEXT(3)); + asn1_write_OctetString(asn1, token->mechListMIC.data, + token->mechListMIC.length); + asn1_pop_tag(asn1); + } + + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + return !asn1->has_error; +} + +ssize_t read_spnego_data(DATA_BLOB data, SPNEGO_DATA *token) +{ + ASN1_DATA asn1; + ssize_t ret = -1; + + ZERO_STRUCTP(token); + ZERO_STRUCT(asn1); + asn1_load(&asn1, data); + + switch (asn1.data[asn1.ofs]) { + case ASN1_APPLICATION(0): + asn1_start_tag(&asn1, ASN1_APPLICATION(0)); + asn1_check_OID(&asn1, OID_SPNEGO); + if (read_negTokenInit(&asn1, &token->negTokenInit)) { + token->type = SPNEGO_NEG_TOKEN_INIT; + } + asn1_end_tag(&asn1); + break; + case ASN1_CONTEXT(1): + if (read_negTokenTarg(&asn1, &token->negTokenTarg)) { + token->type = SPNEGO_NEG_TOKEN_TARG; + } + break; + default: + break; + } + + if (!asn1.has_error) ret = asn1.ofs; + asn1_free(&asn1); + + return ret; +} + +ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego) +{ + ASN1_DATA asn1; + ssize_t ret = -1; + + ZERO_STRUCT(asn1); + + switch (spnego->type) { + case SPNEGO_NEG_TOKEN_INIT: + asn1_push_tag(&asn1, ASN1_APPLICATION(0)); + asn1_write_OID(&asn1, OID_SPNEGO); + write_negTokenInit(&asn1, &spnego->negTokenInit); + asn1_pop_tag(&asn1); + break; + case SPNEGO_NEG_TOKEN_TARG: + write_negTokenTarg(&asn1, &spnego->negTokenTarg); + break; + default: + asn1.has_error = True; + break; + } + + if (!asn1.has_error) { + *blob = data_blob(asn1.data, asn1.length); + ret = asn1.ofs; + } + asn1_free(&asn1); + + return ret; +} + -- cgit From 5ab2b1e9219a99b8e3b01a977e0703e76b57debb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 18:57:37 +0000 Subject: Eliminate valgrind error when client gets bad sig on list. Some reformatting. Jeremy. (This used to be commit b8f6b836468b3a0ae75977dc65cae8400f74734c) --- source3/libsmb/clierror.c | 3 +++ source3/libsmb/clilist.c | 34 ++++++++++++++++++++++------------ 2 files changed, 25 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 656671823c..c27e1955e2 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -371,6 +371,9 @@ BOOL cli_is_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; + if (cli->fd == -1 && cli->smb_rw_error != 0) + return True; + if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { /* Return error is error bits are set */ rcls = IVAL(cli->inbuf, smb_rcls); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 5bd1283ab7..608d740f83 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -101,13 +101,20 @@ static int interpret_long_filename(struct cli_state *cli, cheap to calculate, I suppose, as no DST tables will be needed */ - finfo->ctime = interpret_long_date(p); p += 8; - finfo->atime = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; + finfo->ctime = interpret_long_date(p); + p += 8; + finfo->atime = interpret_long_date(p); + p += 8; + finfo->mtime = interpret_long_date(p); + p += 8; + p += 8; + finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); + p += 8; p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); p += 4; - namelen = IVAL(p,0); p += 4; + finfo->mode = CVAL(p,0); + p += 4; + namelen = IVAL(p,0); + p += 4; p += 4; /* EA size */ slen = SVAL(p, 0); p += 2; @@ -214,7 +221,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, uint8 eclass; uint32 ecode; cli_dos_error(cli, &eclass, &ecode); - if (eclass != ERRSRV || ecode != ERRerror) break; + if (eclass != ERRSRV || ecode != ERRerror) + break; msleep(100); continue; } @@ -222,7 +230,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (cli_is_error(cli) || !rdata || !rparam) break; - if (total_received == -1) total_received = 0; + if (total_received == -1) + total_received = 0; /* parse out some important return info */ p = rparam; @@ -245,8 +254,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* we might need the lastname for continuations */ if (ff_lastname > 0) { - switch(info_level) - { + switch(info_level) { case 260: clistr_pull(cli, mask, p+ff_lastname, sizeof(mask), @@ -270,8 +278,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (!tdl) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); break; + } else { + dirlist = tdl; } - else dirlist = tdl; /* put in a length for the last entry, to ensure we can chain entries into the next packet */ @@ -291,7 +300,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, DEBUG(3,("received %d entries (eos=%d)\n", ff_searchcount,ff_eos)); - if (ff_searchcount > 0) loop_count = 0; + if (ff_searchcount > 0) + loop_count = 0; First = False; } -- cgit From 9c49c4694885a0b173ac982877fc64385e4855b7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 19:00:52 +0000 Subject: Fix bug we discovered in W2K client signing on secondary trans2 packets. Use W2K parameters. tpot please re-test smbclient with your problem directory. Jeremy. (This used to be commit 677d3a3c4ca0b67148e5e56fa876773a067679bd) --- source3/libsmb/clilist.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 608d740f83..2b56582700 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -145,7 +145,7 @@ static int interpret_long_filename(struct cli_state *cli, int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { - int max_matches = 512; + int max_matches = 1366; /* Match W2k - was 512. */ int info_level; char *p, *p2; pstring mask; @@ -207,7 +207,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, 0, - cli->max_xmit /* data, length, max */ + MIN(16384,cli->max_xmit) /* data, length, max. W2K server signing + has a bug unless this matches what W2K uses. */ )) { break; } -- cgit From 29ca70cd34d3ba927ea1a9915ebd247f64965bd5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 23:49:29 +0000 Subject: Add a command line option (-S on|off|required) to enable signing on client connections. Overrides smb.conf parameter if set. Jeremy. (This used to be commit 879309671df6b530e0bff69559422a417da4a307) --- source3/libsmb/cliconnect.c | 9 ++++++--- source3/libsmb/clientgen.c | 21 +++++++++++++++++++++ source3/libsmb/trusts_util.c | 2 +- 3 files changed, 28 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8873c1fdc8..94fe04a480 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -995,7 +995,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if ((cli->protocol < PROTOCOL_NT1) && (lp_client_signing() == Required)) { + if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) { DEBUG(1,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); return False; } @@ -1026,7 +1026,7 @@ BOOL cli_negprot(struct cli_state *cli) if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) { /* Fail if signing is mandatory and we don't want to support it. */ - if (!lp_client_signing()) { + if (!cli->sign_info.allow_smb_signing) { DEBUG(1,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); return False; } @@ -1259,6 +1259,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *service, const char *service_type, const char *user, const char *domain, const char *password, int flags, + int signing_state, BOOL *retry) { struct ntuser_creds creds; @@ -1321,6 +1322,8 @@ again: return NT_STATUS_UNSUCCESSFUL; } + cli_setup_signing_state(cli, signing_state); + if (flags & CLI_FULL_CONNECTION_DONT_SPNEGO) cli->use_spnego = False; else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) @@ -1491,7 +1494,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", user_info->username, lp_workgroup(), user_info->password, - CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, NULL); + CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return cli; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cd9edb1cc9..cdda2eb224 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -208,6 +208,27 @@ void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) cli->user_name, cli->domain)); } +/**************************************************************************** + Set the signing state (used from the command line). +****************************************************************************/ + +void cli_setup_signing_state(struct cli_state *cli, int signing_state) +{ + if (signing_state == Undefined) + return; + + if (signing_state == False) { + cli->sign_info.allow_smb_signing = False; + cli->sign_info.mandatory_signing = False; + return; + } + + cli->sign_info.allow_smb_signing = True; + + if (signing_state == Required) + cli->sign_info.mandatory_signing = True; +} + /**************************************************************************** Initialise a client structure. ****************************************************************************/ diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 77e63709aa..610f4b3c03 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -154,7 +154,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* setup the anonymous connection */ result = cli_full_connection( &cli, global_myname(), dc_name, &dc_ip, 0, "IPC$", "IPC", - "", "", "", 0, &retry); + "", "", "", 0, Undefined, &retry); if ( !NT_STATUS_IS_OK(result) ) goto done; -- cgit From aa7f82c5cc751915192a8641dc87c837a61e29fb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Jul 2003 00:30:01 +0000 Subject: Turn the 'doing_signing' variable on - fix bug where it was only being set on when signing was mandatory. Jeremy. (This used to be commit 7c58673a103195435ca75ebb2684880d1f7242d3) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 305a741ef1..3feffe4c96 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -97,9 +97,9 @@ static BOOL set_smb_signing_real_common(struct smb_sign_info *si) { if (si->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); - si->doing_signing = True; } + si->doing_signing = True; DEBUG(5, ("SMB signing enabled!\n")); return True; -- cgit From 2f81ccefa2dcd04da444280924cacac266adfc7a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 31 Jul 2003 10:23:13 +0000 Subject: This fixes an error I must have made when playing with spnego.c found by aliguori: NegTokenInit.mechListMIC is an Octet String. Second: add a free_spnego_data function. Both thanks to aliguori. Volker (This used to be commit 6c252440fba33eb69827d5515a95fbb3e8e9a653) --- source3/libsmb/spnego.c | 49 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 078191ffba..267e2f24ff 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -71,18 +71,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) /* Read mecListMIC */ case ASN1_CONTEXT(3): asn1_start_tag(asn1, ASN1_CONTEXT(3)); - if (!asn1_read_OctetString(asn1, &token->mechListMIC)) { - char *mechListMIC; - asn1_push_tag(asn1, ASN1_SEQUENCE(0)); - asn1_push_tag(asn1, ASN1_CONTEXT(0)); - asn1_read_GeneralString(asn1, &mechListMIC); - asn1_pop_tag(asn1); - asn1_pop_tag(asn1); - - token->mechListMIC = - data_blob(mechListMIC, strlen(mechListMIC)); - SAFE_FREE(mechListMIC); - } + asn1_read_OctetString(asn1, &token->mechListMIC); asn1_end_tag(asn1); break; default: @@ -156,8 +145,6 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) while (!asn1->has_error && 0 < asn1_tag_remaining(asn1)) { switch (asn1->data[asn1->ofs]) { case ASN1_CONTEXT(0): - /* this is listed as being non-optional by RFC2478 but - Windows doesn't always send it... */ asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_ENUMERATED); asn1_read_uint8(asn1, &token->negResult); @@ -290,3 +277,37 @@ ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego) return ret; } +BOOL free_spnego_data(SPNEGO_DATA *spnego) +{ + BOOL ret = True; + + if (!spnego) goto out; + + switch(spnego->type) { + case SPNEGO_NEG_TOKEN_INIT: + if (spnego->negTokenInit.mechTypes) { + int i; + for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { + free(spnego->negTokenInit.mechTypes[i]); + } + free(spnego->negTokenInit.mechTypes); + } + data_blob_free(&spnego->negTokenInit.mechToken); + data_blob_free(&spnego->negTokenInit.mechListMIC); + break; + case SPNEGO_NEG_TOKEN_TARG: + if (spnego->negTokenTarg.supportedMech) { + free(spnego->negTokenTarg.supportedMech); + } + data_blob_free(&spnego->negTokenTarg.responseToken); + data_blob_free(&spnego->negTokenTarg.mechListMIC); + break; + default: + ret = False; + break; + } + ZERO_STRUCTP(spnego); +out: + return ret; +} + -- cgit From c13fac26c50b510a936567adc2206b6390d6edee Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 31 Jul 2003 15:53:59 +0000 Subject: Fix off-by-one found by valgrind. Volker (This used to be commit bc39c9b57fa6258674e1ee44b3446f25bf63661e) --- source3/libsmb/spnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 267e2f24ff..8cf2413a21 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -46,7 +46,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = - realloc(token->mechTypes, (i + 1) * + realloc(token->mechTypes, (i + 2) * sizeof(*token->mechTypes)); asn1_read_OID(asn1, token->mechTypes + i); } -- cgit From ef915c8eaf1d8335aa331d3b2376c40e3a63de22 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 1 Aug 2003 06:10:30 +0000 Subject: Final fix for the bug tridge found. Only push locks onto a blocking lock queue if the posix lock failed with EACCES or EAGAIN (this means another lock conflicts). Else return an error and don't queue the request. Jeremy. (This used to be commit 43fbc18fdc184bf29c15186c16bc99fb208de963) --- source3/libsmb/errormap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 8ee5ee3d31..3d99e3d5e5 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1498,6 +1498,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, + { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY }, #ifdef EDQUOT { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, #endif -- cgit From 9f2e6167d22cc06fa94495574fc29d6bcbb1dd8a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Aug 2003 15:21:20 +0000 Subject: Update my copyrights according to my agreement with IBM (This used to be commit c9b209be2b17c2e4677cc30b46b1074f48878f43) --- source3/libsmb/clispnego.c | 2 +- source3/libsmb/ntlmssp_parse.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index fbf8323679..b0570b09b6 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough 2002 Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index f53afcdcd0..3c6da349e4 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough 2002 Copyright (C) Andrew Bartlett 2002-2003 This program is free software; you can redistribute it and/or modify -- cgit From 2443f7ffa20a683eabb792182cb0206402ad8059 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 00:29:45 +0000 Subject: Correct fix (removed the earlier band-aid) for what I thought was a signing bug with w2k. Turns out that when we're doing a trans/trans2/nttrans call the MID and send_sequence_number and reply_sequence_number must remain constant. This was something we got very wrong in earlier versions of Samba. I can now get a directory listing from WINNT\SYSTEM32 with the older earlier parameters for clilist.c This still needs to be fixed for the server side of Samba, client appears to be working happily now (I'm doing a signed smbtar download of an entire W2K3 image to test this :-). Jeremy. (This used to be commit 2093a3130d4087d0659b497eebd580e7a66e5aa3) --- source3/libsmb/clientgen.c | 4 +++ source3/libsmb/clilist.c | 12 ++++++-- source3/libsmb/clitrans.c | 18 ++++++++++++ source3/libsmb/smb_signing.c | 67 ++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 97 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cdda2eb224..bc5f1462cc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -157,6 +157,10 @@ BOOL cli_send_smb(struct cli_state *cli) } nwritten += ret; } + /* Increment the mid so we can tell between responses. */ + cli->mid++; + if (!cli->mid) + cli->mid++; return True; } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2b56582700..7822987ada 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -145,7 +145,11 @@ static int interpret_long_filename(struct cli_state *cli, int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { +#if 0 int max_matches = 1366; /* Match W2k - was 512. */ +#else + int max_matches = 512; +#endif int info_level; char *p, *p2; pstring mask; @@ -207,8 +211,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, 0, - MIN(16384,cli->max_xmit) /* data, length, max. W2K server signing - has a bug unless this matches what W2K uses. */ +#if 0 + /* w2k value. */ + MIN(16384,cli->max_xmit) /* data, length, max. */ +#else + cli->max_xmit /* data, length, max. */ +#endif )) { break; } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3d3cd427d7..49897d0bb0 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -40,6 +40,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, char *outdata,*outparam; char *p; int pipe_name_len=0; + uint16 mid; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); @@ -49,6 +50,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, SCVAL(cli->outbuf,smb_com,trans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); + mid = cli->mid; if (pipe_name) { pipe_name_len = clistr_push(cli, smb_buf(cli->outbuf), pipe_name, -1, STR_TERMINATE); @@ -84,6 +86,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); + + cli_signing_trans_start(cli); if (!cli_send_smb(cli)) return False; @@ -122,6 +126,10 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); + /* Ensure this packet has the same MID as + * the primary. Important in signing. JRA. */ + cli->mid = mid; + show_msg(cli->outbuf); if (!cli_send_smb(cli)) return False; @@ -292,6 +300,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, } + cli_signing_trans_stop(cli); return(True); } @@ -309,6 +318,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, unsigned int i; unsigned int this_ldata,this_lparam; unsigned int tot_data=0,tot_param=0; + uint16 mid; char *outdata,*outparam; this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */ @@ -319,6 +329,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, SCVAL(cli->outbuf,smb_com,SMBnttrans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); + mid = cli->mid; outparam = smb_buf(cli->outbuf)+3; outdata = outparam+this_lparam; @@ -347,6 +358,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); + cli_signing_trans_start(cli); if (!cli_send_smb(cli)) return False; @@ -384,7 +396,12 @@ BOOL cli_send_nt_trans(struct cli_state *cli, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); + /* Ensure this packet has the same MID as + * the primary. Important in signing. JRA. */ + cli->mid = mid; + show_msg(cli->outbuf); + if (!cli_send_smb(cli)) return False; @@ -559,5 +576,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, break; } + cli_signing_trans_stop(cli); return(True); } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 3feffe4c96..81e25cb67c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -28,9 +28,17 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; }; +/* Store the data for an ongoing trans/trans2/nttrans operation. */ +struct trans_info_context { + uint16 mid; + uint32 send_seq_num; + uint32 reply_seq_num; +}; + struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; + struct trans_info_context *trans_info; struct outstanding_packet_lookup *outstanding_packet_list; }; @@ -261,6 +269,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; + uint32 send_seq_num; if (!si->doing_signing) return; @@ -275,7 +284,12 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); - simple_packet_signature(data, outbuf, data->send_seq_num, calc_md5_mac); + if (data->trans_info) + send_seq_num = data->trans_info->send_seq_num; + else + send_seq_num = data->send_seq_num; + + simple_packet_signature(data, outbuf, send_seq_num, calc_md5_mac); DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); @@ -285,6 +299,9 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ + if (data->trans_info) + return; + data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), @@ -313,9 +330,13 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } - if (!get_sequence_for_reply(&data->outstanding_packet_list, + if (data->trans_info) { + reply_seq_number = data->trans_info->reply_seq_num; + } else if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { + DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", + (unsigned int) SVAL(inbuf, smb_mid) )); return False; } @@ -365,6 +386,10 @@ static void simple_free_signing_context(struct smb_sign_info *si) } data_blob_free(&data->mac_key); + + if (data->trans_info) + SAFE_FREE(data->trans_info); + SAFE_FREE(si->signing_context); return; @@ -390,6 +415,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ } data = smb_xmalloc(sizeof(*data)); + memset(data, '\0', sizeof(*data)); cli->sign_info.signing_context = data; @@ -421,6 +447,42 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ return True; } +/*********************************************************** + Tell client code we are in a multiple trans reply state. +************************************************************/ + +void cli_signing_trans_start(struct cli_state *cli) +{ + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + if (!cli->sign_info.doing_signing) + return; + + data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + ZERO_STRUCTP(data->trans_info); + + data->trans_info->send_seq_num = data->send_seq_num; + data->trans_info->mid = SVAL(cli->outbuf,smb_mid); + data->trans_info->reply_seq_num = data->send_seq_num+1; +} + +/*********************************************************** + Tell client code we are out of a multiple trans reply state. +************************************************************/ + +void cli_signing_trans_stop(struct cli_state *cli) +{ + struct smb_basic_signing_context *data = cli->sign_info.signing_context; + + if (!cli->sign_info.doing_signing) + return; + + if (data->trans_info) + SAFE_FREE(data->trans_info); + + data->send_seq_num += 2; +} + /*********************************************************** SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ @@ -776,6 +838,7 @@ void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) srv_sign_info.doing_signing = True; data = smb_xmalloc(sizeof(*data)); + memset(data, '\0', sizeof(*data)); srv_sign_info.signing_context = data; -- cgit From 760e58cf807e099b450c83fbdb8d393d53b9dca3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 03:06:07 +0000 Subject: Add the same signing code to the server. Ensure we use identical session numbers and MIDs when in trans/trans2/nttrans code. Jeremy. (This used to be commit 901544b29b4d815709b3dbad3012f1d2c419d904) --- source3/libsmb/smb_signing.c | 76 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 81e25cb67c..d4c50a71f0 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -477,8 +477,8 @@ void cli_signing_trans_stop(struct cli_state *cli) if (!cli->sign_info.doing_signing) return; - if (data->trans_info) - SAFE_FREE(data->trans_info); + SAFE_FREE(data->trans_info); + data->trans_info = NULL; data->send_seq_num += 2; } @@ -598,10 +598,11 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) struct smb_basic_signing_context *data = si->signing_context; uint32 send_seq_number = data->send_seq_num; BOOL was_deferred_packet; + uint16 mid; if (!si->doing_signing) { if (si->allow_smb_signing && si->negotiated_smb_signing) { - uint16 mid = SVAL(outbuf, smb_mid); + mid = SVAL(outbuf, smb_mid); was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); @@ -632,10 +633,13 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); + mid = SVAL(outbuf, smb_mid); + /* See if this is a reply for a deferred packet. */ - was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(outbuf, smb_mid), - &send_seq_number); + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); + + if (data->trans_info && (data->trans_info->mid == mid)) + send_seq_number = data->trans_info->send_seq_num; simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); @@ -647,7 +651,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - if (!was_deferred_packet) + if (!was_deferred_packet && !data->trans_info) data->send_seq_num++; } @@ -661,6 +665,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) uint32 reply_seq_number; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; + uint mid; struct smb_basic_signing_context *data = si->signing_context; @@ -672,12 +677,16 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } + mid = SVAL(inbuf, smb_mid); + /* Oplock break requests store an outgoing mid in the packet list. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(inbuf, smb_mid), - &reply_seq_number)) { - reply_seq_number = data->send_seq_num; - data->send_seq_num++; + if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number)) { + if (data->trans_info && (data->trans_info->mid == mid)) { + reply_seq_number = data->trans_info->reply_seq_num; + } else { + reply_seq_number = data->send_seq_num; + data->send_seq_num++; + } } simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -809,6 +818,49 @@ BOOL srv_is_signing_active(void) return srv_sign_info.doing_signing; } +/*********************************************************** + Tell server code we are in a multiple trans reply state. +************************************************************/ + +void srv_signing_trans_start(uint16 mid) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + ZERO_STRUCTP(data->trans_info); + + data->trans_info->reply_seq_num = data->send_seq_num-1; + data->trans_info->mid = mid; + data->trans_info->send_seq_num = data->send_seq_num; + + /* Increment now in case we need to send a non-trans + * reply in the middle of the trans stream. */ + data->send_seq_num++; +} + +/*********************************************************** + Tell server code we are out of a multiple trans reply state. +************************************************************/ + +void srv_signing_trans_stop(void) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + SAFE_FREE(data->trans_info); + data->trans_info = NULL; +} + + /*********************************************************** Turn on signing from this packet onwards. ************************************************************/ -- cgit From a202afb881e3f9db5f79d7cd93c64a49f128ba70 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 03:12:39 +0000 Subject: Leave the packet sequence checkers enabled whilst I track down a smbclient -> smbd sequence number problem. Jeremy. (This used to be commit 844898dbd8e99837ef1621aa73024714aa819ce4) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d4c50a71f0..5fc44eb953 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -351,7 +351,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); -#if 0 /* JRATEST */ +#if 1 /* JRATEST */ { int i; reply_seq_number -= 5; @@ -702,7 +702,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); dump_data(5, server_sent_mac, 8); -#if 0 /* JRATEST */ +#if 1 /* JRATEST */ { int i; reply_seq_number -= 5; -- cgit From 099bd33a9999718e6cfe6cb387c8845805b67284 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 07:07:38 +0000 Subject: More fixes for client and server side signing. Ensure sequence numbers are updated correctly on returning an error for server trans streams. Ensure we turn off client trans streams on error. Jeremy. (This used to be commit 3a789cb7f01115c37404e5a696de363287cb0e5f) --- source3/libsmb/clitrans.c | 78 ++++++++++++++++++++++++++++++++++---------- source3/libsmb/smb_signing.c | 57 +++++++++++++++++++++++--------- 2 files changed, 103 insertions(+), 32 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 49897d0bb0..e6771ac688 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -88,13 +88,17 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); cli_signing_trans_start(cli); - if (!cli_send_smb(cli)) + if (!cli_send_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || cli_is_error(cli)) + if (!cli_receive_smb(cli) || cli_is_error(cli)) { + cli_signing_trans_stop(cli); return(False); + } tot_data = this_ldata; tot_param = this_lparam; @@ -131,8 +135,10 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, cli->mid = mid; show_msg(cli->outbuf); - if (!cli_send_smb(cli)) + if (!cli_send_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } tot_data += this_ldata; tot_param += this_lparam; @@ -159,8 +165,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *data_len = *param_len = 0; - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } show_msg(cli->inbuf); @@ -169,6 +177,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); + cli_signing_trans_stop(cli); return(False); } @@ -179,8 +188,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status)) + if (NT_STATUS_IS_ERR(status)) { + cli_signing_trans_stop(cli); return False; + } /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_tdrcnt); @@ -191,6 +202,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, tdata = Realloc(*data,total_data); if (!tdata) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); + cli_signing_trans_stop(cli); return False; } else @@ -201,6 +213,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, tparam = Realloc(*param,total_param); if (!tparam) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); + cli_signing_trans_stop(cli); return False; } else @@ -214,6 +227,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -222,6 +236,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -234,6 +249,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } if (data_offset_in > cli->bufsize || @@ -241,6 +257,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -255,6 +272,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } if (param_offset_in > cli->bufsize || @@ -262,6 +280,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -273,8 +292,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (total_data <= *data_len && total_param <= *param_len) break; - if (!cli_receive_smb(cli)) - return False; + if (!cli_receive_smb(cli)) { + cli_signing_trans_stop(cli); + return False; + } show_msg(cli->inbuf); @@ -283,9 +304,11 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); + cli_signing_trans_stop(cli); return(False); } if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { + cli_signing_trans_stop(cli); return(False); } @@ -359,13 +382,17 @@ BOOL cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); cli_signing_trans_start(cli); - if (!cli_send_smb(cli)) + if (!cli_send_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ - if (!cli_receive_smb(cli) || cli_is_error(cli)) + if (!cli_receive_smb(cli) || cli_is_error(cli)) { + cli_signing_trans_stop(cli); return(False); + } tot_data = this_ldata; tot_param = this_lparam; @@ -402,8 +429,10 @@ BOOL cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); - if (!cli_send_smb(cli)) + if (!cli_send_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } tot_data += this_ldata; tot_param += this_lparam; @@ -413,8 +442,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli, return(True); } - - /**************************************************************************** receive a SMB nttrans response allocating the necessary memory ****************************************************************************/ @@ -433,8 +460,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, *data_len = *param_len = 0; - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } show_msg(cli->inbuf); @@ -442,6 +471,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); + cli_signing_trans_stop(cli); return(False); } @@ -452,8 +482,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, */ if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) + if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + cli_signing_trans_stop(cli); return(False); + } } /* parse out the lengths */ @@ -465,6 +497,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, tdata = Realloc(*data,total_data); if (!tdata) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); + cli_signing_trans_stop(cli); return False; } else { *data = tdata; @@ -475,6 +508,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, tparam = Realloc(*param,total_param); if (!tparam) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); + cli_signing_trans_stop(cli); return False; } else { *param = tparam; @@ -488,6 +522,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -496,6 +531,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -508,6 +544,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } if (data_offset_in > cli->bufsize || @@ -515,6 +552,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -530,6 +568,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } if (param_offset_in > cli->bufsize || @@ -537,6 +576,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); + cli_signing_trans_stop(cli); return False; } @@ -549,8 +589,10 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (total_data <= *data_len && total_param <= *param_len) break; - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { + cli_signing_trans_stop(cli); return False; + } show_msg(cli->inbuf); @@ -558,13 +600,15 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); + cli_signing_trans_stop(cli); return(False); } if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if(cli->nt_pipe_fnum == 0 || - !(eclass == ERRDOS && ecode == ERRmoredata)) + if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + cli_signing_trans_stop(cli); return(False); + } } /* parse out the total lengths again - they can shrink! */ if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 5fc44eb953..a62b5a4cdf 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -186,9 +186,6 @@ static void free_signing_context(struct smb_sign_info *si) static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) { - DEBUG(10, ("signing_good: got SMB signature of\n")); - dump_data(10,&inbuf[smb_ss_field] , 8); - if (good && !si->doing_signing) { si->doing_signing = True; } @@ -199,11 +196,11 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) /* W2K sends a bad first signature but the sign engine is on.... JRA. */ if (data->send_seq_num > 1) - DEBUG(1, ("SMB signature check failed!\n")); + DEBUG(1, ("signing_good: SMB signature check failed!\n")); return False; } else { - DEBUG(3, ("Server did not sign reply correctly\n")); + DEBUG(3, ("signing_good: Peer did not sign reply correctly\n")); free_signing_context(si); return False; } @@ -366,6 +363,9 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) } #endif /* JRATEST */ + } else { + DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good); } @@ -455,7 +455,7 @@ void cli_signing_trans_start(struct cli_state *cli) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; - if (!cli->sign_info.doing_signing) + if (!cli->sign_info.doing_signing || !data) return; data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); @@ -464,6 +464,13 @@ void cli_signing_trans_start(struct cli_state *cli) data->trans_info->send_seq_num = data->send_seq_num; data->trans_info->mid = SVAL(cli->outbuf,smb_mid); data->trans_info->reply_seq_num = data->send_seq_num+1; + + DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); } /*********************************************************** @@ -474,7 +481,7 @@ void cli_signing_trans_stop(struct cli_state *cli) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; - if (!cli->sign_info.doing_signing) + if (!cli->sign_info.doing_signing || !data) return; SAFE_FREE(data->trans_info); @@ -638,12 +645,15 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* See if this is a reply for a deferred packet. */ was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); - if (data->trans_info && (data->trans_info->mid == mid)) + if (data->trans_info && (data->trans_info->mid == mid)) { + /* This is a reply in a trans stream. Use the sequence + * number associated with the stream mid. */ send_seq_number = data->trans_info->send_seq_num; + } simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); - DEBUG(10, ("srv_sign_outgoing_message: sent SMB signature of\n")); + DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -651,8 +661,16 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - if (!was_deferred_packet && !data->trans_info) - data->send_seq_num++; + if (!was_deferred_packet) { + if (!data->trans_info) { + /* Always increment if not in a trans stream. */ + data->send_seq_num++; + } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { + /* Increment if this is the first reply in a trans stream or a + * packet that doesn't belong to this stream (different mid). */ + data->send_seq_num++; + } + } } /*********************************************************** @@ -717,6 +735,9 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } #endif /* JRATEST */ + } else { + DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good); } @@ -830,6 +851,8 @@ void srv_signing_trans_start(uint16 mid) return; data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return; data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); ZERO_STRUCTP(data->trans_info); @@ -838,9 +861,12 @@ void srv_signing_trans_start(uint16 mid) data->trans_info->mid = mid; data->trans_info->send_seq_num = data->send_seq_num; - /* Increment now in case we need to send a non-trans - * reply in the middle of the trans stream. */ - data->send_seq_num++; + DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); } /*********************************************************** @@ -855,12 +881,13 @@ void srv_signing_trans_stop(void) return; data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data || !data->trans_info) + return; SAFE_FREE(data->trans_info); data->trans_info = NULL; } - /*********************************************************** Turn on signing from this packet onwards. ************************************************************/ -- cgit From 9482f14b2cb6df0672853c1ba758152ff634ecea Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 08:38:34 +0000 Subject: Only look for mid sign records on incoming packets for oplock break replies. Otherwise we find spurious mid sign records on reply_ntcancel calls (they cancel by mid). That took a *lot* of tracking down. I still need to remove the mid records from the sign state on reply_ntcancel to avoid leaking memory.... Jeremy. (This used to be commit 270bf20fe3e226ab5cfc689bd20ed4c22b2fa7e6) --- source3/libsmb/smb_signing.c | 48 ++++++++++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index a62b5a4cdf..c3fc3306fe 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -54,6 +54,8 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; + DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", + (unsigned int)reply_seq_num, (unsigned int)mid )); } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, @@ -64,6 +66,8 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, for (t = *list; t; t = t->next) { if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; + DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", + (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); DLIST_REMOVE(*list, t); SAFE_FREE(t); return True; @@ -580,16 +584,12 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } -static BOOL outgoing_packet_is_oplock_break(char *outbuf) +static BOOL packet_is_oplock_break(char *buf) { - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { + if (CVAL(buf,smb_com) != SMBlockingX) return False; - } - if (CVAL(outbuf,smb_com) != SMBlockingX) - return False; - - if (CVAL(outbuf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) + if (CVAL(buf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) return False; return True; @@ -604,7 +604,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; uint32 send_seq_number = data->send_seq_num; - BOOL was_deferred_packet; + BOOL was_deferred_packet = False; uint16 mid; if (!si->doing_signing) { @@ -619,7 +619,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) * mid in the outstanding list. */ - if (outgoing_packet_is_oplock_break(outbuf)) { + if (packet_is_oplock_break(outbuf)) { store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num); } @@ -680,13 +680,12 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; - uint32 reply_seq_number; + struct smb_basic_signing_context *data = si->signing_context; + uint32 reply_seq_number = data->send_seq_num; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; uint mid; - struct smb_basic_signing_context *data = si->signing_context; - if (!si->doing_signing) return True; @@ -697,14 +696,16 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) mid = SVAL(inbuf, smb_mid); - /* Oplock break requests store an outgoing mid in the packet list. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number)) { - if (data->trans_info && (data->trans_info->mid == mid)) { - reply_seq_number = data->trans_info->reply_seq_num; - } else { - reply_seq_number = data->send_seq_num; - data->send_seq_num++; - } + /* Is this part of a trans stream ? */ + if (data->trans_info && (data->trans_info->mid == mid)) { + /* If so we don't increment the sequence. */ + reply_seq_number = data->trans_info->reply_seq_num; + } else { + /* We always increment the sequence number. */ + data->send_seq_num++; + /* Oplock break requests store an outgoing mid in the packet list. */ + if (packet_is_oplock_break(inbuf)) + get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number); } simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); @@ -884,6 +885,13 @@ void srv_signing_trans_stop(void) if (!data || !data->trans_info) return; + DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); + SAFE_FREE(data->trans_info); data->trans_info = NULL; } -- cgit From b925d197f5c1829f7bb8c18de2557c0ccc2d94a9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 08:48:01 +0000 Subject: Ensure we don't leak any sign records on cancel of pending requests. Jeremy. (This used to be commit 9a8ffc239c0f1aada713de7e9e007066738d8874) --- source3/libsmb/smb_signing.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c3fc3306fe..4167452953 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -809,11 +809,38 @@ void srv_defer_sign_response(uint16 mid) data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return; + store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num); data->send_seq_num++; } +/*********************************************************** + Called to remove sequence records when a deferred packet is + cancelled by mid. This should never find one.... +************************************************************/ + +void srv_cancel_sign_response(uint16 mid) +{ + struct smb_basic_signing_context *data; + uint32 dummy_seq; + + if (!srv_sign_info.doing_signing) + return; + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + + if (!data) + return; + + DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); + + while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) + ; +} + /*********************************************************** Called by server negprot when signing has been negotiated. ************************************************************/ -- cgit From a8646708e3b5bfe7838db7fe1f9f9974170d1f9e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 3 Aug 2003 07:12:46 +0000 Subject: Fix oplock break detection code on incoming oplock break responses. This fixes signing for oplocks. Jeremy. (This used to be commit 69c56ee8bce122839a8fec4e59198f84b0757166) --- source3/libsmb/smb_signing.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4167452953..174e29fa52 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -188,7 +188,7 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq) { if (good && !si->doing_signing) { si->doing_signing = True; @@ -200,7 +200,8 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good) /* W2K sends a bad first signature but the sign engine is on.... JRA. */ if (data->send_seq_num > 1) - DEBUG(1, ("signing_good: SMB signature check failed!\n")); + DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n", + (unsigned int)seq )); return False; } else { @@ -318,6 +319,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) { BOOL good; uint32 reply_seq_number; + uint32 saved_seq; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; @@ -341,6 +343,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) return False; } + saved_seq = reply_seq_number; simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); server_sent_mac = &inbuf[smb_ss_field]; @@ -371,7 +374,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, server_sent_mac, 8); } - return signing_good(inbuf, si, good); + return signing_good(inbuf, si, good, saved_seq); } /*********************************************************** @@ -589,9 +592,10 @@ static BOOL packet_is_oplock_break(char *buf) if (CVAL(buf,smb_com) != SMBlockingX) return False; - if (CVAL(buf,smb_vwv3) != LOCKING_ANDX_OPLOCK_RELEASE) + if (!(CVAL(buf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) return False; + DEBUG(10,("packet_is_oplock_break = True !\n")); return True; } @@ -682,6 +686,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) BOOL good; struct smb_basic_signing_context *data = si->signing_context; uint32 reply_seq_number = data->send_seq_num; + uint32 saved_seq; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; uint mid; @@ -708,6 +713,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number); } + saved_seq = reply_seq_number; simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); server_sent_mac = &inbuf[smb_ss_field]; @@ -715,10 +721,12 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) if (!good) { - DEBUG(5, ("srv_check_incoming_message: BAD SIG: wanted SMB signature of\n")); + DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", + (unsigned int)saved_seq)); dump_data(5, calc_md5_mac, 8); - DEBUG(5, ("srv_check_incoming_message: BAD SIG: got SMB signature of\n")); + DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + (unsigned int)saved_seq)); dump_data(5, server_sent_mac, 8); #if 1 /* JRATEST */ @@ -740,7 +748,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, server_sent_mac, 8); } - return signing_good(inbuf, si, good); + return signing_good(inbuf, si, good, saved_seq); } /*********************************************************** -- cgit From 05540b48f0dc6209bb67db62ba6d7a1f9c33b4de Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 4 Aug 2003 06:16:03 +0000 Subject: Fix unused variable warning. (This used to be commit 73d02e3a2b0f9e84ab6d8685e4ad6a03ef9249b2) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index beac8cb2c1..3fe6d6457a 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -371,9 +371,9 @@ failed: { #ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; + krb5_error_code err; #endif BOOL ret = False; - krb5_error_code err; memset(session_key, 0, 16); -- cgit From a4954bd3d28bc9ffcd33d4ceef71ba1a31723eb6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Aug 2003 13:10:43 +0000 Subject: Changes to make gss-spnego ntlmssp client work against W2k AD. Now I know where the mechListMIC changes came from: Ethereal ;-) Volker (This used to be commit 4e9eed1273035d09ac3b427b9711327ba8c6ebfc) --- source3/libsmb/spnego.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 8cf2413a21..0b2dec7ef8 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -71,7 +71,23 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) /* Read mecListMIC */ case ASN1_CONTEXT(3): asn1_start_tag(asn1, ASN1_CONTEXT(3)); - asn1_read_OctetString(asn1, &token->mechListMIC); + if (asn1->data[asn1->ofs] == ASN1_OCTET_STRING) { + asn1_read_OctetString(asn1, + &token->mechListMIC); + } else { + /* RFC 2478 says we have an Octet String here, + but W2k sends something different... */ + char *mechListMIC; + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_read_GeneralString(asn1, &mechListMIC); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + + token->mechListMIC = + data_blob(mechListMIC, strlen(mechListMIC)); + SAFE_FREE(mechListMIC); + } asn1_end_tag(asn1); break; default: -- cgit From 110abf10d208769bf6bcfc0604874cb1bed0406a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Aug 2003 02:59:52 +0000 Subject: Turns out I had my packet sequences wrong for oplock break code. I was storing the mid of the oplock break - I should have been storing the mid from the open. There are thus 2 types of deferred packet sequence returns - ones that increment the sequence number (returns from oplock causing opens) and ones that don't (change notify returns etc). Running with signing forced on does lead to some interesting tests :-). Jeremy. (This used to be commit 85907f02cec566502d9e4adabbd414020a26064d) --- source3/libsmb/smb_signing.c | 65 +++++++++++++------------------------------- 1 file changed, 19 insertions(+), 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 174e29fa52..4b12f36eba 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,6 +25,7 @@ struct outstanding_packet_lookup { uint16 mid; uint32 reply_seq_num; + BOOL deferred_packet; struct outstanding_packet_lookup *prev, *next; }; @@ -43,7 +44,7 @@ struct smb_basic_signing_context { }; static void store_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 reply_seq_num) + uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt) { struct outstanding_packet_lookup *t; struct outstanding_packet_lookup *tmp; @@ -54,19 +55,25 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; - DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", + t->deferred_packet = deferred_pkt; + + DEBUG(10,("store_sequence_for_reply: stored %sseq = %u mid = %u\n", + deferred_pkt ? "deferred " : "", (unsigned int)reply_seq_num, (unsigned int)mid )); } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 *reply_seq_num) + uint16 mid, uint32 *reply_seq_num, BOOL *def) { struct outstanding_packet_lookup *t; for (t = *list; t; t = t->next) { if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; - DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", + if (def) + *def = t->deferred_packet; + DEBUG(10,("get_sequence_for_reply: found %sseq = %u mid = %u\n", + (t->deferred_packet) ? "deferred " : "", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); DLIST_REMOVE(*list, t); SAFE_FREE(t); @@ -307,7 +314,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), - data->send_seq_num); + data->send_seq_num, False); data->send_seq_num++; } @@ -337,7 +344,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) reply_seq_number = data->trans_info->reply_seq_num; } else if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), - &reply_seq_number)) { + &reply_seq_number, NULL)) { DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", (unsigned int) SVAL(inbuf, smb_mid) )); return False; @@ -587,18 +594,6 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } -static BOOL packet_is_oplock_break(char *buf) -{ - if (CVAL(buf,smb_com) != SMBlockingX) - return False; - - if (!(CVAL(buf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) - return False; - - DEBUG(10,("packet_is_oplock_break = True !\n")); - return True; -} - /*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ @@ -612,25 +607,6 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) uint16 mid; if (!si->doing_signing) { - if (si->allow_smb_signing && si->negotiated_smb_signing) { - mid = SVAL(outbuf, smb_mid); - - was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, - mid, &send_seq_number); - if (!was_deferred_packet) { - /* - * Is this an outgoing oplock break ? If so, store the - * mid in the outstanding list. - */ - - if (packet_is_oplock_break(outbuf)) { - store_sequence_for_reply(&data->outstanding_packet_list, - mid, data->send_seq_num); - } - - data->send_seq_num++; - } - } return; } @@ -647,7 +623,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) mid = SVAL(outbuf, smb_mid); /* See if this is a reply for a deferred packet. */ - was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); + get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number, &was_deferred_packet); if (data->trans_info && (data->trans_info->mid == mid)) { /* This is a reply in a trans stream. Use the sequence @@ -666,7 +642,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) Uncomment this to test if the remote server actually verifies signatures...*/ if (!was_deferred_packet) { - if (!data->trans_info) { + if (!data->trans_info) { /* Always increment if not in a trans stream. */ data->send_seq_num++; } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { @@ -674,7 +650,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) * packet that doesn't belong to this stream (different mid). */ data->send_seq_num++; } - } + } } /*********************************************************** @@ -708,9 +684,6 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { /* We always increment the sequence number. */ data->send_seq_num++; - /* Oplock break requests store an outgoing mid in the packet list. */ - if (packet_is_oplock_break(inbuf)) - get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_number); } saved_seq = reply_seq_number; @@ -808,7 +781,7 @@ void srv_calculate_sign_mac(char *outbuf) Called by server to defer an outgoing packet. ************************************************************/ -void srv_defer_sign_response(uint16 mid) +void srv_defer_sign_response(uint16 mid, BOOL deferred_packet) { struct smb_basic_signing_context *data; @@ -821,7 +794,7 @@ void srv_defer_sign_response(uint16 mid) return; store_sequence_for_reply(&data->outstanding_packet_list, - mid, data->send_seq_num); + mid, data->send_seq_num, deferred_packet); data->send_seq_num++; } @@ -845,7 +818,7 @@ void srv_cancel_sign_response(uint16 mid) DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); - while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) + while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL)) ; } -- cgit From 3bbe9c0869ea8653f684afa9a1345f6fa2f80b4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Aug 2003 05:36:08 +0000 Subject: An oplock break reply from the client causes the sequence number to be updated by 2 if there is no open reply outstanding, else by one.... Yes - this makes no sense.... Jeremy. (This used to be commit b43ce1ff6109f6422a621329ceb713b42df40040) --- source3/libsmb/smb_signing.c | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4b12f36eba..afacfc7a93 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -83,6 +83,22 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return False; } +/*********************************************************** + A reply is pending if there is a non-deferred packet on the queue. +************************************************************/ + +static BOOL is_reply_pending(struct outstanding_packet_lookup *list) +{ + for (; list; list = list->next) { + if (!list->deferred_packet) { + DEBUG(10,("is_reply_pending: True.\n")); + return True; + } + } + DEBUG(10,("is_reply_pending: False.\n")); + return False; +} + /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ @@ -653,6 +669,22 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) } } +/*********************************************************** + Is an incoming packet an oplock break reply ? +************************************************************/ + +static BOOL is_oplock_break(char *inbuf) +{ + if (CVAL(inbuf,smb_com) != SMBlockingX) + return False; + + if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) + return False; + + DEBUG(10,("is_oplock_break: Packet is oplock break\n")); + return True; +} + /*********************************************************** SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ @@ -684,6 +716,13 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { /* We always increment the sequence number. */ data->send_seq_num++; + + /* If we get an asynchronous oplock break reply and there + * isn't a reply pending we need to re-sync the sequence + * number. + */ + if (is_oplock_break(inbuf) && !is_reply_pending(data->outstanding_packet_list)) + data->send_seq_num++; } saved_seq = reply_seq_number; @@ -718,7 +757,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) #endif /* JRATEST */ } else { - DEBUG(10, ("srv_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); -- cgit From 38b3ee6467230955ec94c820f3740eab89534d8c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Aug 2003 17:08:35 +0000 Subject: RPC fix from Ronan Waide . Tested with rpcecho. Jeremy. (This used to be commit 68590b9e2266cf76b46a68cca0acaa47733811fe) --- source3/libsmb/clireadwrite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 0715aa7f1a..8eac7d07d8 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -326,7 +326,7 @@ ssize_t cli_write(struct cli_state *cli, int issued = 0; int received = 0; int mpx = MAX(cli->max_mux-1, 1); - int block = (cli->max_xmit - (smb_size+32)) & ~1023; + int block = cli->max_xmit - (smb_size+32); int blocks = (size + (block-1)) / block; while (received < blocks) { -- cgit From 4b5257b5b09d2490b2f4dc48e2181fde2a67cb5f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 8 Aug 2003 23:53:13 +0000 Subject: fix 2 bugs: 1) don't ask trusted DC's for a list of trusted domains. This causes us to treat non-transitive ones as if they were transitive. Not needed anyways 2) Fix dc lookup bug where we would always try to use DNS to resolve the DC's for a domain (even if it was a trusted NT4 domain). (This used to be commit 4d3acce5066d3adf53ee8fbaa627c42523b3cbc3) --- source3/libsmb/namequery_dc.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index c9d45a7acc..a596f00ddb 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -161,18 +161,28 @@ BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) { struct in_addr dc_ip; BOOL ret; + BOOL our_domain = False; zero_ip(&dc_ip); ret = False; - if (lp_security() == SEC_ADS) + + if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), domain) ) + our_domain = True; + + /* always try to obey what the admin specified in smb.conf. + If it is not our domain, assume that domain names with periods + in them are realm names */ + + if ( (our_domain && lp_security()==SEC_ADS) || strchr_m(domain, '.') ) { ret = ads_dc_name(domain, &dc_ip, srv_name); - + } + if (!ret) { /* fall back on rpc methods if the ADS methods fail */ ret = rpc_dc_name(domain, srv_name, &dc_ip); } - + *ip_out = dc_ip; return ret; -- cgit From 94bbd5c93a777ad1a6b3951358306e29e6277251 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 10 Aug 2003 20:18:05 +0000 Subject: Store the server domain from the ntlmssp challenge in the client struct to be able to ask a LMB for the servers in its workgroup. Against W2k this only works on port 139.... Volker (This used to be commit 62b04d7776852098dd768268500f36c3a362f688) --- source3/libsmb/cliconnect.c | 1 + source3/libsmb/ntlmssp.c | 3 +++ 2 files changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 94fe04a480..a1a207d197 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -610,6 +610,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); if (NT_STATUS_IS_OK(nt_status)) { + fstrcpy(cli->server_domain, ntlmssp_state->server_domain); set_cli_session_key(cli, ntlmssp_state->session_key); } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index a50ae9b70f..e76ad75e6e 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -529,6 +529,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_INVALID_PARAMETER; } + ntlmssp_state->server_domain = talloc_strdup(ntlmssp_state->mem_ctx, + server_domain); + SAFE_FREE(server_domain); if (challenge_blob.length != 8) { data_blob_free(&struct_blob); -- cgit From 76ecaa347ebffe0a713afe8d7fcdfdadc4cce6d5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 11 Aug 2003 20:40:39 +0000 Subject: Fix a segfault in ntlm_auth when we can't find a domain or hostname. Volker (This used to be commit 49c4f8a764a2b9e266c33f018515e6a742cfc8b0) --- source3/libsmb/ntlmssp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e76ad75e6e..37f5510c65 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -174,11 +174,13 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; - get_mydomname(dnsdomname); + if (!get_mydomname(dnsdomname)) + return NT_STATUS_INVALID_PARAMETER; strlower_m(dnsdomname); dnsname[0] = '\0'; - get_myfullname(dnsname); + if (!get_myfullname(dnsname)) + return NT_STATUS_INVALID_PARAMETER; strlower_m(dnsname); if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) -- cgit From 6932617c50f0cd084b7d8ad4f976d7ac33394c01 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 11 Aug 2003 20:51:47 +0000 Subject: Revert the latest fix. Need to investigate further. Volker (This used to be commit 447f130619ad7aaab351c2b46d3e57eaf31a9454) --- source3/libsmb/ntlmssp.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 37f5510c65..e76ad75e6e 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -174,13 +174,11 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; - if (!get_mydomname(dnsdomname)) - return NT_STATUS_INVALID_PARAMETER; + get_mydomname(dnsdomname); strlower_m(dnsdomname); dnsname[0] = '\0'; - if (!get_myfullname(dnsname)) - return NT_STATUS_INVALID_PARAMETER; + get_myfullname(dnsname); strlower_m(dnsname); if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) -- cgit From 494ea488210eae8206dce69ebbff977fe37f8f83 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 11 Aug 2003 21:00:13 +0000 Subject: I think this is the one to check... Volker (This used to be commit f6d853d36a37dd854a410717af2f7eaf9457eeb5) --- source3/libsmb/ntlmssp.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e76ad75e6e..a314aa15db 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -172,6 +172,9 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, target_name = ntlmssp_target_name(ntlmssp_state, neg_flags, &chal_flags); + if (target_name == NULL) + return NT_STATUS_INVALID_PARAMETER; + /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; get_mydomname(dnsdomname); -- cgit From 102de75a7ca4055dee21610061429e100cfc5699 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 11 Aug 2003 21:44:19 +0000 Subject: Fallback to not using NTLMv2 is extended security not supported. Jeremy. (This used to be commit ba075ff03af06dfc2f4bcb952508bbc4a6967d85) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a1a207d197..1f06ebf66f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -268,7 +268,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, char *p; if (passlen != 24) { - if (lp_client_ntlmv2_auth()) { + if ((cli->capabilities & CAP_EXTENDED_SECURITY) && lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); -- cgit From 46e0d25b7f3e570daffe73bad5d883f617ea291e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 12 Aug 2003 01:15:23 +0000 Subject: Fix client autonegotiate signing. Jeremy. (This used to be commit a4d2dd1d40f6b1322e69d430023aa89dac86fda3) --- source3/libsmb/cliconnect.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1f06ebf66f..82d6fc7cef 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1025,22 +1025,27 @@ BOOL cli_negprot(struct cli_state *cli) smb_buflen(cli->inbuf)-8, STR_UNICODE|STR_NOALIGN); } - if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)) { - /* Fail if signing is mandatory and we don't want to support it. */ + /* + * As signing is slow we only turn it on if either the client or + * the server require it. JRA. + */ + + if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { + /* Fail if server says signing is mandatory and we don't want to support it. */ if (!cli->sign_info.allow_smb_signing) { DEBUG(1,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); return False; } cli->sign_info.negotiated_smb_signing = True; - } - - if ((cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) && cli->sign_info.allow_smb_signing) + cli->sign_info.mandatory_signing = True; + } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) { + /* Fail if client says signing is mandatory and the server doesn't support it. */ + if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { + DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); + return False; + } cli->sign_info.negotiated_smb_signing = True; - - /* Fail if signing is mandatory and the server doesn't support it. */ - if (cli->sign_info.mandatory_signing && !(cli->sign_info.negotiated_smb_signing)) { - DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); - return False; + cli->sign_info.mandatory_signing = True; } } else if (cli->protocol >= PROTOCOL_LANMAN1) { -- cgit From 3b8485d047492788925b530e9e622a61c66f2dbd Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 12 Aug 2003 05:53:43 +0000 Subject: As described in http://davenport.sourceforge.net/ntlm.html add NTLM2 authentication. NTLM2 is a version of NTLM, that involves both a client and server challenge, and the creating of a new (presuable more secure) session key. Unfortunetly this is not quite the same as NTLMv2, and we don't know how to get the session key. I suggest looking very closely at what MSCHAPv2, and other MS auth protocols do... Andrew Bartlett (This used to be commit d4a5f4fdf97b707b44a0787267e1e4388d1b5388) --- source3/libsmb/ntlmssp.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index a314aa15db..47e283dc51 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -23,6 +23,12 @@ #include "includes.h" +#if 0 +/* we currently do not know how to get the right session key for this, so + we cannot enable it by default... :-( */ +#define USE_NTLM2 1 +#endif + /** * Print out the NTLMSSP flags for debugging * @param neg_flags The flags from the packet @@ -415,6 +421,10 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat if (ntlmssp_state->use_ntlmv2) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } + +#ifdef USE_NTLM2 + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; +#endif /* generate the ntlmssp negotiate packet */ msrpc_gen(next_request, "CddAA", @@ -560,7 +570,34 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } +#ifdef USE_NTLM2 + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + struct MD5Context md5_session_nonce_ctx; + uchar nt_hash[16]; + uchar session_nonce[16]; + E_md4hash(ntlmssp_state->password, nt_hash); + + generate_random_buffer(lm_response.data, 8, False); + memset(lm_response.data+8, 0, 16); + + MD5Init(&md5_session_nonce_ctx); + MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); + MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); + MD5Final(session_nonce, &md5_session_nonce_ctx); + + nt_response = data_blob(NULL, 24); + SMBNTencrypt(ntlmssp_state->password, + challenge_blob.data, + nt_response.data); + + /* This is *NOT* the correct session key algorithm - just + fill in the bytes with something... */ + session_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); +#endif } else { + + uchar lm_hash[16]; uchar nt_hash[16]; E_deshash(ntlmssp_state->password, lm_hash); @@ -571,15 +608,15 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st lm_response = data_blob(NULL, 24); SMBencrypt(ntlmssp_state->password,challenge_blob.data, lm_response.data); - } + } nt_response = data_blob(NULL, 24); SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, nt_response.data); - + session_key = data_blob(NULL, 16); if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - && lp_client_lanman_auth()) { + && lp_client_lanman_auth()) { SMBsesskeygen_lmv1(lm_hash, lm_response.data, session_key.data); } else { -- cgit From ea403855075b75150b81e51e96774c95b92f369a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Aug 2003 20:26:24 +0000 Subject: Only close anything that is not fid 0. Was very confusing in ethereal... Volker (This used to be commit 9f453f27be7eeb792b57d5c60284bb5efc84b408) --- source3/libsmb/clientgen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bc5f1462cc..308ce31fd0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -339,7 +339,9 @@ void cli_nt_session_close(struct cli_state *cli) ntlmssp_client_end(&cli->ntlmssp_pipe_state); } - cli_close(cli, cli->nt_pipe_fnum); + if (cli->nt_pipe_fnum != 0) + cli_close(cli, cli->nt_pipe_fnum); + cli->nt_pipe_fnum = 0; cli->pipe_idx = -1; } -- cgit From d7ec3205e9f8202c47931d7362a18ab2a36c60ea Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Aug 2003 20:27:18 +0000 Subject: Don't wrap up anything that is not there. Otherwise upper layers can not figure that we got no ticket. Volker (This used to be commit 2a724a7a873c08f14644427766bfd48908ddb501) --- source3/libsmb/clispnego.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index b0570b09b6..63076a1a1c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -331,6 +331,9 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsign /* get a kerberos ticket for the service and extract the session key */ tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5); + if (tkt.data == NULL) + return tkt; + /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); -- cgit From 172766eea7a374e910ea91c857fcce45996783a2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 14 Aug 2003 01:08:00 +0000 Subject: Change Samba to always use extended security for it's guest logins, (ie, NTLMSSP with "" username, NULL password), and add --machine-pass (-P) to all of Samba's clients. When connecting to an Active Directory DC, you must initiate the CIFS level session setup with Kerberos, not a guest login. If you don't, your machine account is demoted to NT4. Andrew Bartlett (This used to be commit 3547cb3def45a90f99f67829a533eac1ccba5e77) --- source3/libsmb/cliconnect.c | 72 +++++++++--------------------------------- source3/libsmb/clikrb5.c | 12 +++---- source3/libsmb/ntlmssp.c | 14 +++++--- source3/libsmb/ntlmssp_parse.c | 3 +- source3/libsmb/smbencrypt.c | 2 +- 5 files changed, 33 insertions(+), 70 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 82d6fc7cef..010aa4d1bb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -130,55 +130,6 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) return capabilities; } -/**************************************************************************** - Do a NT1 guest session setup. -****************************************************************************/ - -static BOOL cli_session_setup_guest(struct cli_state *cli) -{ - char *p; - uint32 capabilities = cli_session_setup_capabilities(cli); - - set_message(cli->outbuf,13,0,True); - SCVAL(cli->outbuf,smb_com,SMBsesssetupX); - cli_setup_packet(cli); - - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); - SSVAL(cli->outbuf,smb_vwv3,2); - SSVAL(cli->outbuf,smb_vwv4,cli->pid); - SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,0); - SSVAL(cli->outbuf,smb_vwv8,0); - SIVAL(cli->outbuf,smb_vwv11,capabilities); - p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */ - p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */ - p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); - p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); - cli_setup_bcc(cli, p); - - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; - - show_msg(cli->inbuf); - - if (cli_is_error(cli)) - return False; - - cli->vuid = SVAL(cli->inbuf,smb_uid); - - p = smb_buf(cli->inbuf); - p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); - p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); - p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); - - fstrcpy(cli->user_name, ""); - - return True; -} - /**************************************************************************** Do a NT1 plaintext session setup. ****************************************************************************/ @@ -267,7 +218,9 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, BOOL ret = False; char *p; - if (passlen != 24) { + if (passlen == 0) { + /* do nothing - guest login */ + } else if (passlen != 24) { if ((cli->capabilities & CAP_EXTENDED_SECURITY) && lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; @@ -678,7 +631,7 @@ static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, * and do not store results */ if (got_kerberos_mechanism && cli->use_kerberos) { - if (*pass) { + if (pass && *pass) { int ret; use_in_memory_ccache(); @@ -751,12 +704,6 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); } - /* if no user is supplied then we have to do an anonymous connection. - passwords are ignored */ - - if (!user || !*user) - return cli_session_setup_guest(cli); - /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ @@ -764,6 +711,17 @@ BOOL cli_session_setup(struct cli_state *cli, if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) return cli_session_setup_plaintext(cli, user, "", workgroup); + /* if no user is supplied then we have to do an anonymous connection. + passwords are ignored */ + + if (!user || !*user) { + user = ""; + pass = NULL; + ntpass = NULL; + passlen = 0; + ntpasslen = 0; + } + /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 3fe6d6457a..a18852a691 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -369,29 +369,27 @@ failed: BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote) { -#ifdef ENCTYPE_ARCFOUR_HMAC krb5_keyblock *skey; krb5_error_code err; -#endif BOOL ret = False; memset(session_key, 0, 16); -#ifdef ENCTYPE_ARCFOUR_HMAC if (remote) err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); else err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); if (err == 0 && skey != NULL) { - if (KRB5_KEY_TYPE(skey) == - ENCTYPE_ARCFOUR_HMAC - && KRB5_KEY_LENGTH(skey) == 16) { + DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); + if (KRB5_KEY_LENGTH(skey) == 16) { memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + dump_data_pw("KRB5 Session Key:\n", session_key, 16); ret = True; } krb5_free_keyblock(context, skey); + } else { + DEBUG(10, ("KRB5 error getting session key %d\n", err)); } -#endif /* ENCTYPE_ARCFOUR_HMAC */ return ret; } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 47e283dc51..43c3464bd2 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -551,7 +551,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_INVALID_PARAMETER; } - if (ntlmssp_state->use_ntlmv2) { + if (!ntlmssp_state->password) { + /* do nothing - blobs are zero length */ + } else if (ntlmssp_state->use_ntlmv2) { if (!struct_blob.length) { /* be lazy, match win2k - we can't do NTLMv2 without it */ @@ -749,9 +751,13 @@ NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *u NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password) { - ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); - if (!ntlmssp_state->password) { - return NT_STATUS_NO_MEMORY; + if (!password) { + ntlmssp_state->password = NULL; + } else { + ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); + if (!ntlmssp_state->password) { + return NT_STATUS_NO_MEMORY; + } } return NT_STATUS_OK; } diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 3c6da349e4..60cb4ab04a 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -153,7 +153,8 @@ BOOL msrpc_gen(DATA_BLOB *blob, SSVAL(blob->data, head_ofs, n); head_ofs += 2; SSVAL(blob->data, head_ofs, n); head_ofs += 2; SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - memcpy(blob->data+data_ofs, b, n); + if (n && b) /* don't follow null pointers... */ + memcpy(blob->data+data_ofs, b, n); data_ofs += n; break; case 'd': diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 7a1a2d7d18..ada6a423f2 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -247,7 +247,7 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[ return True; } -/* Does the md5 encryption from the NT hash for NTLMv2. */ +/* Does the md5 encryption from the Key Response for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], const DATA_BLOB *srv_chal, const DATA_BLOB *cli_chal, -- cgit From 062f89bc2833bf49f873a7fd5c2624babd702db0 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 01:42:30 +0000 Subject: get rid of some sompiler warnings on IRIX (This used to be commit a6a39c61e8228c8b3b7552ab3c61ec3a6a639143) --- source3/libsmb/clikrb5.c | 2 +- source3/libsmb/cliprint.c | 5 ++-- source3/libsmb/clirap.c | 10 +++---- source3/libsmb/clirap2.c | 63 ++++++++++++++++++++++++------------------- source3/libsmb/clisecdesc.c | 4 +-- source3/libsmb/ntlmssp.c | 8 +++--- source3/libsmb/ntlmssp_sign.c | 24 ++++++++--------- 7 files changed, 63 insertions(+), 53 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index a18852a691..7e1801f555 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -74,7 +74,7 @@ { pkaddr->addrtype = ADDRTYPE_INET; pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); - pkaddr->contents = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); } #else __ERROR__XX__UNKNOWN_ADDRTYPE diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index f302c045a5..2fb0e59aca 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -55,7 +55,7 @@ int cli_print_queue(struct cli_state *cli, char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt, rprcnt; + unsigned int rdrcnt, rprcnt; pstring param; int result_code=0; int i = -1; @@ -125,7 +125,8 @@ int cli_printjob_del(struct cli_state *cli, int job) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt, ret = -1; + unsigned int rdrcnt,rprcnt; + int ret = -1; pstring param; memset(param,'\0',sizeof(param)); diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a307ac6ccf..79ad38fc8c 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -76,7 +76,7 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; pstring param; memset(param, 0, sizeof(param)); @@ -137,7 +137,7 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; pstring param; int count = -1; @@ -211,7 +211,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, { char *rparam = NULL; char *rdata = NULL; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; char *p; pstring param; int uLevel = 1; @@ -256,7 +256,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, const char *cmnt = comment_offset?(rdata+comment_offset):""; pstring s1, s2; - if (comment_offset < 0 || comment_offset > rdrcnt) continue; + if (comment_offset < 0 || comment_offset > (int)rdrcnt) continue; stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; @@ -290,7 +290,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char unsigned int param_len = 0; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; pstring dos_new_password; if (strlen(user) >= sizeof(fstring)-1) { diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 669b33860d..12a3d63aff 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -153,7 +153,8 @@ int cli_NetGroupDelete(struct cli_state *cli, const char *group_name ) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt, res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupDel_REQ) /* parm string */ +1 /* no ret string */ @@ -204,7 +205,8 @@ int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt,res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupAdd_REQ) /* req string */ +sizeof(RAP_GROUP_INFO_L1) /* return string */ @@ -272,7 +274,7 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res = -1; @@ -332,7 +334,8 @@ int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const ch char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt,res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupDelUser_REQ) /* parm string */ +1 /* no ret string */ @@ -390,7 +393,8 @@ int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const ch char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt,res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupAddUser_REQ) /* parm string */ +1 /* no ret string */ @@ -446,7 +450,7 @@ int cli_NetGroupGetUsers(struct cli_state * cli, const char *group_name, void (* char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; int res = -1; char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupGetUsers_REQ)/* parm string */ @@ -501,7 +505,7 @@ int cli_NetUserGetGroups(struct cli_state * cli, const char *user_name, void (*f char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; int res = -1; char param[WORDSIZE /* api number */ +sizeof(RAP_NetUserGetGroups_REQ)/* parm string */ @@ -560,7 +564,8 @@ int cli_NetUserDelete(struct cli_state *cli, const char * user_name ) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt, res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupDel_REQ) /* parm string */ +1 /* no ret string */ @@ -614,7 +619,8 @@ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo ) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt,res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_NetUserAdd2_REQ) /* req string */ +sizeof(RAP_USER_INFO_L1) /* data string */ @@ -702,7 +708,7 @@ int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res = -1; @@ -770,7 +776,7 @@ int cli_NetFileClose(struct cli_state *cli, uint32 file_id ) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; char param[WORDSIZE /* api number */ +sizeof(RAP_WFileClose2_REQ) /* req string */ +1 /* no ret string */ @@ -816,7 +822,8 @@ int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const c char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt, res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_WFileGetInfo2_REQ) /* req string */ +sizeof(RAP_FILE_INFO_L3) /* return string */ @@ -893,7 +900,7 @@ int cli_NetFileEnum(struct cli_state *cli, char * user, char * base_path, void ( char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; char param[WORDSIZE /* api number */ +sizeof(RAP_WFileEnum2_REQ) /* req string */ +sizeof(RAP_FILE_INFO_L3) /* return string */ @@ -965,7 +972,8 @@ int cli_NetShareAdd(struct cli_state *cli, RAP_SHARE_INFO_2 * sinfo ) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt,res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_WShareAdd_REQ) /* req string */ +sizeof(RAP_SHARE_INFO_L2) /* return string */ @@ -1035,7 +1043,8 @@ int cli_NetShareDelete(struct cli_state *cli, const char * share_name ) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt, res; + unsigned int rdrcnt,rprcnt; + int res; char param[WORDSIZE /* api number */ +sizeof(RAP_WShareDel_REQ) /* req string */ +1 /* no ret string */ @@ -1097,7 +1106,7 @@ BOOL cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) { char *rparam = NULL; char *rdata = NULL; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; char *p; char param[WORDSIZE /* api number */ +sizeof(RAP_NetServerEnum2_REQ) /* req string */ @@ -1177,7 +1186,7 @@ BOOL cli_get_server_domain(struct cli_state *cli) { char *rparam = NULL; char *rdata = NULL; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; char *p; char param[WORDSIZE /* api number */ +sizeof(RAP_WWkstaGetInfo_REQ) /* req string */ @@ -1242,7 +1251,7 @@ BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype) { char *rparam = NULL; char *rdata = NULL; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; char *p; char param[WORDSIZE /* api number */ +sizeof(RAP_WserverGetInfo_REQ) /* req string */ @@ -1309,7 +1318,7 @@ BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 sty { char *rparam = NULL; char *rdata = NULL; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; char *p; char param[WORDSIZE /* api number */ +sizeof(RAP_NetServerEnum2_REQ) /* req string */ @@ -1378,7 +1387,7 @@ BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) char *rparam = NULL; char *rdata = NULL; char *p; - int rdrcnt,rprcnt; + unsigned int rdrcnt,rprcnt; char param[WORDSIZE /* api number */ +sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string */ +sizeof(RAP_USER_LOGOFF_INFO_L1) /* return string */ @@ -1436,7 +1445,7 @@ int cli_NetPrintQEnum(struct cli_state *cli, char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res = -1; @@ -1540,7 +1549,7 @@ int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res = -1; @@ -1639,7 +1648,7 @@ int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const ch char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res = -1; @@ -1708,7 +1717,7 @@ int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res = -1; memset(param, '\0', sizeof(param)); @@ -1784,7 +1793,7 @@ int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void ( char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res = -1; @@ -1858,7 +1867,7 @@ int cli_NetSessionDel(struct cli_state *cli, const char *workstation) char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res; memset(param, '\0', sizeof(param)); @@ -1903,7 +1912,7 @@ int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*f char *p; char *rparam = NULL; char *rdata = NULL; - int rprcnt, rdrcnt; + unsigned int rprcnt, rdrcnt; int res = -1; memset(param, '\0', sizeof(param)); diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index d86a9022a6..548cd6ec18 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -28,7 +28,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, { char param[8]; char *rparam=NULL, *rdata=NULL; - int rparam_count=0, rdata_count=0; + unsigned int rparam_count=0, rdata_count=0; prs_struct pd; SEC_DESC *psd = NULL; @@ -78,7 +78,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) { char param[8]; char *rparam=NULL, *rdata=NULL; - int rparam_count=0, rdata_count=0; + unsigned int rparam_count=0, rdata_count=0; uint32 sec_info = 0; TALLOC_CTX *mem_ctx; prs_struct pd; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 43c3464bd2..e4d4acd29b 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -146,7 +146,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, &cliname, &domname)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); - dump_data(2, request.data, request.length); + dump_data(2, (const char *)request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } @@ -282,7 +282,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &sess_key, &neg_flags)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); - dump_data(2, request.data, request.length); + dump_data(2, (const char *)request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } @@ -476,7 +476,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st &server_domain_blob, &chal_flags)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); - dump_data(2, reply.data, reply.length); + dump_data(2, (const char *)reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } @@ -538,7 +538,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st &unkn1, &unkn2, &struct_blob)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); - dump_data(2, reply.data, reply.length); + dump_data(2, (const char *)reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index ecaef808c9..ff2f97c2e8 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -91,8 +91,8 @@ static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], MD5Init(&ctx3); MD5Update(&ctx3, session_key.data, session_key.length); - MD5Update(&ctx3, constant, strlen(constant)); - MD5Final(digest, &ctx3); + MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)); + MD5Final((unsigned char *)digest, &ctx3); calc_hash(hash, digest, 16); } @@ -113,8 +113,8 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); - hmac_md5_update(seq_num, 4, &ctx); + hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx); + hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -132,7 +132,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat } } else { uint32 crc; - crc = crc32_calc_buffer(data, length); + crc = crc32_calc_buffer((const char *)data, length); if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } @@ -183,10 +183,10 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) { DEBUG(5, ("BAD SIG: wanted signature of\n")); - dump_data(5, local_sig.data, local_sig.length); + dump_data(5, (const char *)local_sig.data, local_sig.length); DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, sig->data, sig->length); + dump_data(5, (const char *)(sig->data), sig->length); DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n")); return NT_STATUS_ACCESS_DENIED; @@ -216,8 +216,8 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64(ntlmssp_state->cli_sign_const, 16, &ctx); - hmac_md5_update(seq_num, 4, &ctx); + hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx); + hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -236,7 +236,7 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data+4, sig->length-4); } else { uint32 crc; - crc = crc32_calc_buffer(data, length); + crc = crc32_calc_buffer((const char *)data, length); if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } @@ -335,7 +335,7 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n")); - calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 8); + calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 8); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } else { @@ -347,7 +347,7 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n")); - calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 16); + calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } -- cgit From c9aa836204eb722890cbd4d64248ff7ef1a50e60 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 15 Aug 2003 01:46:09 +0000 Subject: Fix memleaks. Currently I'm compiling against MIT Kerberos 1.2.8. Anthony, you said you have a heimdal installation available. Could you please compile this stuff with krb and check it with valgrind? Thanks, Volker (This used to be commit d8ab44685994b302bb46eed9001c72c194d13dc8) --- source3/libsmb/clikrb5.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 7e1801f555..1fccc04a01 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -97,7 +97,9 @@ return ret; } krb5_use_enctype(context, &eblock, enctype); - return krb5_string_to_key(context, &eblock, key, password, &salt); + ret = krb5_string_to_key(context, &eblock, key, password, &salt); + SAFE_FREE(salt.data); + return ret; } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) int create_kerberos_key_from_string(krb5_context context, -- cgit From 4ad85bf48e9a48835b081b966e49ddc7160f4567 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 15 Aug 2003 02:57:59 +0000 Subject: Add the gss-spnego kerberos server side to ntml_auth. This uses the same ads_verify_ticket routine that smbd uses, so in the current state we have to be have the host password in secrets.tdb instead of the keytab. This means we have to be an ADS member, but it's a start. Volker (This used to be commit dc2d2ad467927affbd1461df75f77f07ddfbc3b1) --- source3/libsmb/spnego.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 0b2dec7ef8..50caf7b4c0 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -140,8 +140,22 @@ static BOOL write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) /* write mechListMIC */ if (token->mechListMIC.data) { asn1_push_tag(asn1, ASN1_CONTEXT(3)); +#if 0 + /* This is what RFC 2478 says ... */ asn1_write_OctetString(asn1, token->mechListMIC.data, token->mechListMIC.length); +#else + /* ... but unfortunately this is what Windows + sends/expects */ + asn1_push_tag(asn1, ASN1_SEQUENCE(0)); + asn1_push_tag(asn1, ASN1_CONTEXT(0)); + asn1_push_tag(asn1, ASN1_GENERAL_STRING); + asn1_write(asn1, token->mechListMIC.data, + token->mechListMIC.length); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); + asn1_pop_tag(asn1); +#endif asn1_pop_tag(asn1); } -- cgit From aa39cc37dab9c4f8c3295d872bb8cc143890b378 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 15 Aug 2003 04:42:05 +0000 Subject: get rid of more compiler warnings (This used to be commit 398bd14fc6e2f8ab2f34211270e179b8928a6669) --- source3/libsmb/smb_signing.c | 36 ++++++++++++++++++------------------ source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index afacfc7a93..08ff655a3f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -314,10 +314,10 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) else send_seq_num = data->send_seq_num; - simple_packet_signature(data, outbuf, send_seq_num, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_num, calc_md5_mac); DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); - dump_data(10, calc_md5_mac, 8); + dump_data(10, (const char *)calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -367,23 +367,23 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) } saved_seq = reply_seq_number; - simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - server_sent_mac = &inbuf[smb_ss_field]; + server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); - dump_data(5, calc_md5_mac, 8); + dump_data(5, (const char *)calc_md5_mac, 8); DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); - dump_data(5, server_sent_mac, 8); + dump_data(5, (const char *)server_sent_mac, 8); #if 1 /* JRATEST */ { int i; reply_seq_number -= 5; for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n", reply_seq_number )); @@ -395,7 +395,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(10, server_sent_mac, 8); + dump_data(10, (const char *)server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); } @@ -454,12 +454,12 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ memcpy(&data->mac_key.data[0], user_session_key, 16); DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, user_session_key, 16); + dump_data(10, (const char *)user_session_key, 16); if (response.length) { memcpy(&data->mac_key.data[16],response.data, response.length); DEBUG(10, ("cli_simple_set_signing: response_data\n")); - dump_data(10, response.data, response.length); + dump_data(10, (const char *)response.data, response.length); } else { DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); } @@ -647,10 +647,10 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) send_seq_number = data->trans_info->send_seq_num; } - simple_packet_signature(data, outbuf, send_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); - dump_data(10, calc_md5_mac, 8); + dump_data(10, (const char *)calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -726,27 +726,27 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } saved_seq = reply_seq_number; - simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - server_sent_mac = &inbuf[smb_ss_field]; + server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); if (!good) { DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", (unsigned int)saved_seq)); - dump_data(5, calc_md5_mac, 8); + dump_data(5, (const char *)calc_md5_mac, 8); DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", (unsigned int)saved_seq)); - dump_data(5, server_sent_mac, 8); + dump_data(5, (const char *)server_sent_mac, 8); #if 1 /* JRATEST */ { int i; reply_seq_number -= 5; for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, inbuf, reply_seq_number, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n", reply_seq_number )); @@ -758,7 +758,7 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) } else { DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); - dump_data(10, server_sent_mac, 8); + dump_data(10, (const char *)server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ada6a423f2..ec31bb5dba 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -81,7 +81,7 @@ void E_deshash(const char *passwd, uchar p16[16]) push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); /* Only the fisrt 14 chars are considered, password need not be null terminated. */ - E_P16(dospwd, p16); + E_P16((const unsigned char *)dospwd, p16); ZERO_STRUCT(dospwd); } -- cgit From 83e576c09f7f08406cb3f360a13537e536ce5547 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2003 17:47:44 +0000 Subject: Break up 'cli_full_connection' to allow for the session setups to be done elsewhere in the code. This will allow us to try kerberos, then another user then guest in the winbindd code. Also, re-introduce the seperate, NT1 'guest' session setup code, as I found some problems with doing guest under NTLMSSP. Andrew Bartlett (This used to be commit 33109fefe7d306a97ac48a75e3e67c166daff4ea) --- source3/libsmb/cliconnect.c | 149 +++++++++++++++++++++++++++++++++----------- 1 file changed, 114 insertions(+), 35 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 010aa4d1bb..ca492e0a1c 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -130,6 +130,55 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) return capabilities; } +/**************************************************************************** + Do a NT1 guest session setup. +****************************************************************************/ + +static BOOL cli_session_setup_guest(struct cli_state *cli) +{ + char *p; + uint32 capabilities = cli_session_setup_capabilities(cli); + + set_message(cli->outbuf,13,0,True); + SCVAL(cli->outbuf,smb_com,SMBsesssetupX); + cli_setup_packet(cli); + + SCVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE); + SSVAL(cli->outbuf,smb_vwv3,2); + SSVAL(cli->outbuf,smb_vwv4,cli->pid); + SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); + SSVAL(cli->outbuf,smb_vwv7,0); + SSVAL(cli->outbuf,smb_vwv8,0); + SIVAL(cli->outbuf,smb_vwv11,capabilities); + p = smb_buf(cli->outbuf); + p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* username */ + p += clistr_push(cli, p, "", -1, STR_TERMINATE); /* workgroup */ + p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); + p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + show_msg(cli->inbuf); + + if (cli_is_error(cli)) + return False; + + cli->vuid = SVAL(cli->inbuf,smb_uid); + + p = smb_buf(cli->inbuf); + p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); + p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); + + fstrcpy(cli->user_name, ""); + + return True; +} + /**************************************************************************** Do a NT1 plaintext session setup. ****************************************************************************/ @@ -198,7 +247,8 @@ static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) } /**************************************************************************** - do a NT1 NTLM/LM encrypted session setup + do a NT1 NTLM/LM encrypted session setup - for when extended security + is not negotiated. @param cli client state to create do session setup on @param user username @param pass *either* cleartext password (passlen !=24) or LM response. @@ -221,7 +271,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (passlen == 0) { /* do nothing - guest login */ } else if (passlen != 24) { - if ((cli->capabilities & CAP_EXTENDED_SECURITY) && lp_client_ntlmv2_auth()) { + /* if client ntlmv2 auth is set, then don't use it on a + connection without extended security. This isn't a very + good check, but it is a start */ + if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); @@ -573,7 +626,7 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { return False; } - + return (NT_STATUS_IS_OK(nt_status)); } @@ -581,8 +634,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, Do a spnego encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) +BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, + const char *pass, const char *workgroup) { char *principal; char *OIDs[ASN1_MAX_OIDS]; @@ -704,6 +757,12 @@ BOOL cli_session_setup(struct cli_state *cli, return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); } + /* if no user is supplied then we have to do an anonymous connection. + passwords are ignored */ + + if (!user || !*user) + return cli_session_setup_guest(cli); + /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ @@ -711,17 +770,6 @@ BOOL cli_session_setup(struct cli_state *cli, if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) return cli_session_setup_plaintext(cli, user, "", workgroup); - /* if no user is supplied then we have to do an anonymous connection. - passwords are ignored */ - - if (!user || !*user) { - user = ""; - pass = NULL; - ntpass = NULL; - passlen = 0; - ntpasslen = 0; - } - /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ @@ -1187,7 +1235,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) Initialise client credentials for authenticated pipe access. ****************************************************************************/ -static void init_creds(struct ntuser_creds *creds, const char* username, +void init_creds(struct ntuser_creds *creds, const char* username, const char* domain, const char* password) { ZERO_STRUCTP(creds); @@ -1203,30 +1251,21 @@ static void init_creds(struct ntuser_creds *creds, const char* username, } /** - establishes a connection right up to doing tconX, password specified. + establishes a connection to after the negprot. @param output_cli A fully initialised cli structure, non-null only on success @param dest_host The netbios name of the remote host @param dest_ip (optional) The the destination IP, NULL for name based lookup @param port (optional) The destination port (0 for default) - @param service (optional) The share to make the connection to. Should be 'unqualified' in any way. - @param service_type The 'type' of serivice. - @param user Username, unix string - @param domain User's domain - @param password User's password, unencrypted unix string. @param retry BOOL. Did this connection fail with a retryable error ? -*/ -NTSTATUS cli_full_connection(struct cli_state **output_cli, - const char *my_name, - const char *dest_host, - struct in_addr *dest_ip, int port, - const char *service, const char *service_type, - const char *user, const char *domain, - const char *password, int flags, - int signing_state, - BOOL *retry) +*/ +NTSTATUS cli_start_connection(struct cli_state **output_cli, + const char *my_name, + const char *dest_host, + struct in_addr *dest_ip, int port, + int signing_state, int flags, + BOOL *retry) { - struct ntuser_creds creds; NTSTATUS nt_status; struct nmb_name calling; struct nmb_name called; @@ -1259,7 +1298,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, again: - DEBUG(3,("Connecting to host=%s share=%s\n", dest_host, service)); + DEBUG(3,("Connecting to host=%s\n", dest_host)); if (!cli_connect(cli, dest_host, &ip)) { DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n", @@ -1300,6 +1339,46 @@ again: return nt_status; } + *output_cli = cli; + return NT_STATUS_OK; +} + + +/** + establishes a connection right up to doing tconX, password specified. + @param output_cli A fully initialised cli structure, non-null only on success + @param dest_host The netbios name of the remote host + @param dest_ip (optional) The the destination IP, NULL for name based lookup + @param port (optional) The destination port (0 for default) + @param service (optional) The share to make the connection to. Should be 'unqualified' in any way. + @param service_type The 'type' of serivice. + @param user Username, unix string + @param domain User's domain + @param password User's password, unencrypted unix string. + @param retry BOOL. Did this connection fail with a retryable error ? +*/ + +NTSTATUS cli_full_connection(struct cli_state **output_cli, + const char *my_name, + const char *dest_host, + struct in_addr *dest_ip, int port, + const char *service, const char *service_type, + const char *user, const char *domain, + const char *password, int flags, + int signing_state, + BOOL *retry) +{ + struct ntuser_creds creds; + NTSTATUS nt_status; + struct cli_state *cli = NULL; + + nt_status = cli_start_connection(&cli, my_name, dest_host, + dest_ip, port, signing_state, flags, retry); + + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + if (!cli_session_setup(cli, user, password, strlen(password)+1, password, strlen(password)+1, domain)) { -- cgit From f1be3a5c5defc2df94550b90b7dd2ed4ab0cb1f2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2003 22:47:10 +0000 Subject: - Make 'net' use a single funciton for setting the 'use machine account' code. - Make winbindd try to use kerberos for connections to DCs, so that it can access RA=2 servers, particularly for netlogon. - Make rpcclient follow the new flags for the NETLOGON pipe - Make all the code that uses schannel use the centralised functions for doing so. Andrew Bartlett (This used to be commit 96b4187963cedcfe158ff02868929b8cf81c6ebf) --- source3/libsmb/trusts_util.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 610f4b3c03..4e02b29f92 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -35,16 +35,15 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ uint32 sec_channel_type) { NTSTATUS result; - uint32 neg_flags = 0x000001ff; - result = cli_nt_setup_creds(cli, sec_channel_type, orig_trust_passwd_hash, &neg_flags, 2); - - if (!NT_STATUS_IS_OK(result)) { + /* ensure that schannel uses the right domain */ + fstrcpy(cli->domain, lp_workgroup()); + if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, sec_channel_type, orig_trust_passwd_hash))) { DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", nt_errstr(result))); return result; } - + result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { -- cgit From 8bfe26b62db2e671b143d93a5428f8fb64a9df05 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 20 Aug 2003 17:13:38 +0000 Subject: metze's autogenerate patch for version.h (This used to be commit ae452e51b02672a56adf18aa7a7e365eeaba9272) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ca492e0a1c..bb0712d989 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -190,7 +190,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, char *p; fstring lanman; - fstr_sprintf( lanman, "Samba %s", VERSION ); + fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); -- cgit From ecddae8bf012c6b9dc4e99c788c14adde64baba8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Aug 2003 22:06:19 +0000 Subject: Attempt to fix the charcnv issues causing nmbd to crash. If we get a failed conversion simply copy as is. Also fixed the horrid malloc-twice-copy code in the convert alloc path. Jeremy. (This used to be commit cfde7477fd12caef943a9422b52174438092a135) --- source3/libsmb/climessage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 8ce8416487..035088212c 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -87,7 +87,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) p = smb_buf(cli->outbuf); *p++ = 1; - if ((lendos = convert_string_allocate(CH_UNIX, CH_DOS, msg,len, (void **) &msgdos)) < 0 || !msgdos) { + if ((lendos = convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **) &msgdos)) < 0 || !msgdos) { DEBUG(3,("Conversion failed, sending message in UNIX charset\n")); SSVAL(p, 0, len); p += 2; memcpy(p, msg, len); -- cgit From 647a048ad085c74ebbddb1957b690f3cb9ced178 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 22 Aug 2003 00:26:37 +0000 Subject: Ensure nmb_namestr() converts back from CH_DOS to CH_UNIX. Jeremy. (This used to be commit eb792727437c74417f5ef7614b300ab84f06fdaf) --- source3/libsmb/nmblib.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 6ee05f0104..b833a2f5df 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -310,21 +310,24 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) } /******************************************************************* - useful for debugging messages - ******************************************************************/ + Useful for debugging messages. +******************************************************************/ + char *nmb_namestr(struct nmb_name *n) { - static int i=0; - static fstring ret[4]; - char *p = ret[i]; - - if (!n->scope[0]) - slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type); - else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope); - - i = (i+1)%4; - return(p); + static int i=0; + static fstring ret[4]; + fstring name; + char *p = ret[i]; + + pull_ascii_fstring(name, n->name); + if (!n->scope[0]) + slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type); + else + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope); + + i = (i+1)%4; + return(p); } /******************************************************************* -- cgit From ac5665f2046d9cf079e6eeddd6dc92b720ddc69f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 22 Aug 2003 14:24:38 +0000 Subject: revert abartet's change that removed the check for CAP_EXTENDED_SECURITY when decidiing whether or not use ntlmv2 in client connections (This used to be commit 6e82c9fdf9c1db6feec319b4550b07cbfad4defb) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index bb0712d989..63db6b1aea 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -274,7 +274,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, /* if client ntlmv2 auth is set, then don't use it on a connection without extended security. This isn't a very good check, but it is a start */ - if (lp_client_ntlmv2_auth()) { + if ((cli->capabilities & CAP_EXTENDED_SECURITY) && lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); @@ -357,7 +357,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, goto end; } - show_msg(cli->inbuf); + /* show_msg(cli->inbuf); */ if (cli_is_error(cli)) { ret = False; -- cgit From 5dfeda00028c1d22428736a85140dec6f46ff94c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 22 Aug 2003 21:41:50 +0000 Subject: Use correct size (17 not 16) when doing a push_ascii(). Ensure that wins hook is called with unix charset. Jeremy. (This used to be commit ecb80573870103de7b3f332fb53bf6b952f25ee7) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b833a2f5df..23eac9ad7c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -823,7 +823,7 @@ static int build_dgram(char *buf,struct packet_struct *p) void make_nmb_name( struct nmb_name *n, const char *name, int type) { memset( (char *)n, '\0', sizeof(struct nmb_name) ); - push_ascii(n->name, name, 16, STR_TERMINATE|STR_UPPER); + push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; StrnCpy( n->scope, global_scope(), 63 ); strupper_m( n->scope ); -- cgit From 9fdc1363bec6ae9a0a0f9a37130b98a92ebe8ce2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Aug 2003 01:25:01 +0000 Subject: Fix the character set handling properly in nmbd. Also fix bug where iconv wasn't re-initialised on reading of "charset" parameters. This caused workgroup name to be set incorrectly if it contained an extended character. Jeremy. (This used to be commit 84ae44678a6c59c999bc1023fdd9b7ad87f4ec18) --- source3/libsmb/nmblib.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 23eac9ad7c..ff38245435 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -825,8 +825,7 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) memset( (char *)n, '\0', sizeof(struct nmb_name) ); push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER); n->name_type = (unsigned int)type & 0xFF; - StrnCpy( n->scope, global_scope(), 63 ); - strupper_m( n->scope ); + push_ascii(n->scope, global_scope(), 64, STR_TERMINATE); } /******************************************************************* -- cgit From 245fbf7efbc42530c81d5aac66681bb892c97557 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Sep 2003 01:12:39 +0000 Subject: Used cachegrind to track down some bottlenecks. Removed calls to clobber_region when not compiling with developer as they were hiding speed problems. Added fast path to convert_string() when dealing with ascii -> ascii, ucs2-le to ascii and ascii to ucs2-le with values <= 0x7F. This gives a speedup of 22% on my nbench tests. Next I will do this on convert_string_allocate. Jeremy. (This used to be commit ef140d15ea0d76a3e7cdcadbfd3e917c210a9411) --- source3/libsmb/clientgen.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 308ce31fd0..0a134f715d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -299,9 +299,12 @@ struct cli_state *cli_initialise(struct cli_state *cli) memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); + +#if defined(DEVELOPER) /* just because we over-allocate, doesn't mean it's right to use it */ clobber_region(FUNCTION_MACRO, __LINE__, cli->outbuf+cli->bufsize, SAFETY_MARGIN); clobber_region(FUNCTION_MACRO, __LINE__, cli->inbuf+cli->bufsize, SAFETY_MARGIN); +#endif /* initialise signing */ cli_null_set_signing(cli); -- cgit From 94f59f54921174fc156fade575ca114d331b1bd8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Sep 2003 19:59:55 +0000 Subject: More tuning from cachegrind. Change most trim_string() calls to trim_char(0, as that's what they do. Fix string_replace() to fast-path ascii. Jeremy. (This used to be commit f35e9a8b909d3c74be47083ccc4a4e91a14938db) --- source3/libsmb/clifile.c | 5 +++-- source3/libsmb/namequery.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index f021076a46..c7f0cdb84b 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -951,8 +951,9 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) char *p; pstrcpy(path2,path); - trim_string(path2,NULL,"\\"); - if (!*path2) *path2 = '\\'; + trim_char(path2,'\0','\\'); + if (!*path2) + *path2 = '\\'; memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 9875f77c72..1de7413711 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -61,7 +61,7 @@ static struct node_status *parse_node_status(char *p, int *num_names) p++; for (i=0;i< *num_names;i++) { StrnCpy(ret[i].name,p,15); - trim_string(ret[i].name,NULL," "); + trim_char(ret[i].name,'\0',' '); ret[i].type = CVAL(p,15); ret[i].flags = p[16]; p += 18; -- cgit From c913fc058113b3a3a193f7b98459679945afcf03 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 6 Sep 2003 19:23:24 +0000 Subject: address bug #359. Andrew B's patch for implementing client portion of NTLMv2 key exchange. Also revert the default for 'client ntlmv2 auth' to no. This caused no ends of grief in different cases. And based on abartlet's mail.... > All I care about at this point is that we use NTLMv2 > in our client code when connecting to a server that > supports it. There is *no* way to tell this. The server can't tell us, because it doesn't know what it's DC supports. The DC can't tell us, because it doesn't know what the trusted DC supports. One DC might be Win2k, and the PDC could be an older NT4. (This used to be commit fe585d49cc3df0d71314ff43d3271d276d7d4503) --- source3/libsmb/cliconnect.c | 5 +--- source3/libsmb/ntlmssp.c | 63 ++++++++++++++++++++++++++------------------- 2 files changed, 37 insertions(+), 31 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 63db6b1aea..48bcb61f92 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -271,10 +271,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (passlen == 0) { /* do nothing - guest login */ } else if (passlen != 24) { - /* if client ntlmv2 auth is set, then don't use it on a - connection without extended security. This isn't a very - good check, but it is a start */ - if ((cli->capabilities & CAP_EXTENDED_SECURITY) && lp_client_ntlmv2_auth()) { + if (lp_client_ntlmv2_auth()) { DATA_BLOB server_chal; DATA_BLOB names_blob; server_chal = data_blob(cli->secblob.data, MIN(cli->secblob.length, 8)); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e4d4acd29b..42bf18d1d2 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -23,12 +23,6 @@ #include "includes.h" -#if 0 -/* we currently do not know how to get the right session key for this, so - we cannot enable it by default... :-( */ -#define USE_NTLM2 1 -#endif - /** * Print out the NTLMSSP flags for debugging * @param neg_flags The flags from the packet @@ -422,9 +416,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } -#ifdef USE_NTLM2 ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; -#endif /* generate the ntlmssp negotiate packet */ msrpc_gen(next_request, "CddAA", @@ -459,16 +451,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); - uint8 datagram_sess_key[16]; - size_t datagram_sess_key_len; - -#if 0 /* until we know what flag to tigger it on */ - generate_random_buffer(datagram_sess_key, sizeof(datagram_sess_key), False); - datagram_sess_key_len = sizeof(datagram_sess_key); -#else - ZERO_STRUCT(datagram_sess_key); - datagram_sess_key_len = 0; -#endif + DATA_BLOB encrypted_session_key = data_blob(NULL, 0); if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -502,7 +485,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st } else { chal_parse_string = "CdAdbdd"; } + auth_gen_string = "CdBBAAABd"; + ntlmssp_state->unicode = False; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; @@ -526,6 +511,10 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; } + if (!(chal_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; + } + DEBUG(3, ("NTLMSSP: Set final flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); @@ -572,31 +561,35 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st data_blob_free(&struct_blob); return NT_STATUS_NO_MEMORY; } -#ifdef USE_NTLM2 } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { struct MD5Context md5_session_nonce_ctx; uchar nt_hash[16]; uchar session_nonce[16]; + uchar session_nonce_hash[16]; + uchar nt_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); + lm_response = data_blob(NULL, 24); generate_random_buffer(lm_response.data, 8, False); memset(lm_response.data+8, 0, 16); - + + memcpy(session_nonce, challenge_blob.data, 8); + memcpy(&session_nonce[8], lm_response.data, 8); + MD5Init(&md5_session_nonce_ctx); MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); - MD5Final(session_nonce, &md5_session_nonce_ctx); + MD5Final(session_nonce_hash, &md5_session_nonce_ctx); nt_response = data_blob(NULL, 24); SMBNTencrypt(ntlmssp_state->password, - challenge_blob.data, + session_nonce_hash, nt_response.data); - /* This is *NOT* the correct session key algorithm - just - fill in the bytes with something... */ session_key = data_blob(NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); -#endif + + SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key); + hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data); } else { @@ -627,6 +620,18 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st } data_blob_free(&struct_blob); + /* Key exchange encryptes a new client-generated session key with + the password-derived key */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + uint8 client_session_key[16]; + + generate_random_buffer(client_session_key, sizeof(client_session_key), False); + encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); + SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); + data_blob_free(&session_key); + session_key = data_blob(client_session_key, sizeof(client_session_key)); + } + /* this generates the actual auth packet */ if (!msrpc_gen(next_request, auth_gen_string, "NTLMSSP", @@ -636,7 +641,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->get_global_myname(), - datagram_sess_key, datagram_sess_key_len, + encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags)) { data_blob_free(&lm_response); @@ -645,6 +650,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st return NT_STATUS_NO_MEMORY; } + data_blob_free(&encrypted_session_key); + data_blob_free(&ntlmssp_state->chal); data_blob_free(&ntlmssp_state->lm_resp); data_blob_free(&ntlmssp_state->nt_resp); @@ -683,6 +690,8 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_NTLM2 | + NTLMSSP_NEGOTIATE_KEY_EXCH | NTLMSSP_REQUEST_TARGET; (*ntlmssp_state)->ref_count = 1; -- cgit From 1555cacd7c7814571ed8bb91a0d3a722cf7dc30b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 16 Sep 2003 01:27:46 +0000 Subject: Fix #442 which Alexander considered a showstopper. Allow us to join mixed mode domains. Jeremy. (This used to be commit c816aacefb6621533194a374251835f186ca838f) --- source3/libsmb/cliconnect.c | 8 -------- source3/libsmb/ntlmssp.c | 6 ++++++ 2 files changed, 6 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 48bcb61f92..b5f7b97ae8 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -547,14 +547,6 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, return False; } - ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(); - - if (cli->sign_info.negotiated_smb_signing - || cli->sign_info.mandatory_signing) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; - } - do { nt_status = ntlmssp_client_update(ntlmssp_state, blob_in, &blob_out); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 42bf18d1d2..c51b599b04 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -692,6 +692,12 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | + /* + * We need to set this to allow a later SetPassword + * via the SAMR pipe to succeed. Strange.... We could + * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. + * */ + NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_REQUEST_TARGET; (*ntlmssp_state)->ref_count = 1; -- cgit From eb268003f4282849bc03dae4f6fc27a9bec852ba Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 16 Sep 2003 03:54:42 +0000 Subject: Applied Steve Langasek's patch for bug #450. (This used to be commit e3cb0cd0d60d90a76e5f74d5bda702148584ab30) --- source3/libsmb/trusts_util.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 4e02b29f92..c18641bc84 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -180,9 +180,10 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, done: /* cleanup */ - - cli_nt_session_close( cli ); - cli_shutdown( cli ); + if (cli) { + cli_nt_session_close( cli ); + cli_shutdown( cli ); + } return NT_STATUS_IS_OK(result); } -- cgit From 52f63783bcc42cc4a1351ad9176d24a73a26c5eb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 8 Oct 2003 23:21:36 +0000 Subject: Fixup error code returns from Samba4 tester. Ensure invalid paths are validated the same way. Jeremy. (This used to be commit 6ad2f0ba27566ab3928ccbbbb3c3a64b09ca139c) --- source3/libsmb/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 3d99e3d5e5..4d9a717e1c 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1490,7 +1490,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND }, + { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY }, { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, -- cgit From ec890d5c0fcb0ac9b3680d3c930614c726535d0a Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 14 Oct 2003 03:56:42 +0000 Subject: Enclose usage of st_blksize and st_blocks struct stat members in #ifdef HAVE_STAT_ST_BLKSIZE and #ifdef HAVE_STAT_ST_BLOCKS, respectively. Fixes bug 550 reported by Joachim Schmitz . (This used to be commit 18adfdbe0c6ed79ba8ac07956b1e7abc226556c3) --- source3/libsmb/libsmbclient.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 69c4d8f7a7..4eb7f49760 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1139,8 +1139,12 @@ int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; st->st_size = size; +#ifdef HAVE_STAT_ST_BLKSIZE st->st_blksize = 512; +#endif +#ifdef HAVE_STAT_ST_BLOCKS st->st_blocks = (size+511)/512; +#endif st->st_uid = getuid(); st->st_gid = getgid(); -- cgit From 1269d231132b414958a16b9a3544917e15b81f57 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Oct 2003 17:01:03 +0000 Subject: Enable us to see what sequence number we were expecting when we fail a sign (should help track down out of sequence bugs). Jeremy. (This used to be commit 6e21261fe40698b2ee46c802bd1c044a909f8e5d) --- source3/libsmb/smb_signing.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 08ff655a3f..8a4401ef19 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -385,8 +385,8 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) for (i = 0; i < 10; i++, reply_seq_number++) { simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches.\n", - reply_seq_number )); + DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ +We were expecting seq %u\n", reply_seq_number, saved_seq )); break; } } @@ -748,8 +748,8 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) for (i = 0; i < 10; i++, reply_seq_number++) { simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches.\n", - reply_seq_number )); + DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \ +We were expecting seq %u\n", reply_seq_number, saved_seq )); break; } } -- cgit From df81637076fed4173d8900816c3ee3dfddc960a5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 20 Oct 2003 08:41:32 +0000 Subject: We are doing NT error codes now.... If we have an NT error, report that back the same way we handle the DOS error. Although I don't see why BUFFER_TOO_SMALL should not be handled as an error, simply copy the logic. This is only called from smbcacls and smbcquotas. Volker (This used to be commit 169f4dfee08e8de05e729fd48209df91cf8ba255) --- source3/libsmb/clitrans.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index e6771ac688..92c1cc99ee 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -488,6 +488,17 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, } } + /* + * Likewise for NT_STATUS_BUFFER_TOO_SMALL + */ + if (cli_is_nt_error(cli)) { + if (!NT_STATUS_EQUAL(cli_nt_error(cli), + NT_STATUS_BUFFER_TOO_SMALL)) { + cli_signing_trans_stop(cli); + return(False); + } + } + /* parse out the lengths */ total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); -- cgit From 3fe18a46a33cc1c0a0ecfefc61618356d7746a15 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Oct 2003 17:40:58 +0000 Subject: Fix signing miss-sequence noticed by Stefan Metzmacher Jeremy. (This used to be commit 63f331564396e7a4f16dce95bb98d3b6c4b75351) --- source3/libsmb/smb_signing.c | 73 ++++++++++++++++---------------------------- 1 file changed, 27 insertions(+), 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8a4401ef19..91509f0fb8 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,7 +25,6 @@ struct outstanding_packet_lookup { uint16 mid; uint32 reply_seq_num; - BOOL deferred_packet; struct outstanding_packet_lookup *prev, *next; }; @@ -44,7 +43,7 @@ struct smb_basic_signing_context { }; static void store_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 reply_seq_num, BOOL deferred_pkt) + uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; struct outstanding_packet_lookup *tmp; @@ -55,25 +54,20 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; - t->deferred_packet = deferred_pkt; - DEBUG(10,("store_sequence_for_reply: stored %sseq = %u mid = %u\n", - deferred_pkt ? "deferred " : "", + DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", (unsigned int)reply_seq_num, (unsigned int)mid )); } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 *reply_seq_num, BOOL *def) + uint16 mid, uint32 *reply_seq_num) { struct outstanding_packet_lookup *t; for (t = *list; t; t = t->next) { if (t->mid == mid) { *reply_seq_num = t->reply_seq_num; - if (def) - *def = t->deferred_packet; - DEBUG(10,("get_sequence_for_reply: found %sseq = %u mid = %u\n", - (t->deferred_packet) ? "deferred " : "", + DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); DLIST_REMOVE(*list, t); SAFE_FREE(t); @@ -83,22 +77,6 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return False; } -/*********************************************************** - A reply is pending if there is a non-deferred packet on the queue. -************************************************************/ - -static BOOL is_reply_pending(struct outstanding_packet_lookup *list) -{ - for (; list; list = list->next) { - if (!list->deferred_packet) { - DEBUG(10,("is_reply_pending: True.\n")); - return True; - } - } - DEBUG(10,("is_reply_pending: False.\n")); - return False; -} - /*********************************************************** SMB signing - Common code before we set a new signing implementation ************************************************************/ @@ -329,8 +307,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) data->send_seq_num++; store_sequence_for_reply(&data->outstanding_packet_list, - SVAL(outbuf,smb_mid), - data->send_seq_num, False); + SVAL(outbuf,smb_mid), data->send_seq_num); data->send_seq_num++; } @@ -359,8 +336,7 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) if (data->trans_info) { reply_seq_number = data->trans_info->reply_seq_num; } else if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(inbuf, smb_mid), - &reply_seq_number, NULL)) { + SVAL(inbuf, smb_mid), &reply_seq_number)) { DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", (unsigned int) SVAL(inbuf, smb_mid) )); return False; @@ -639,7 +615,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) mid = SVAL(outbuf, smb_mid); /* See if this is a reply for a deferred packet. */ - get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number, &was_deferred_packet); + was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); if (data->trans_info && (data->trans_info->mid == mid)) { /* This is a reply in a trans stream. Use the sequence @@ -655,18 +631,21 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); /* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signatures...*/ + Uncomment this to test if the remote client actually verifies signatures...*/ - if (!was_deferred_packet) { - if (!data->trans_info) { - /* Always increment if not in a trans stream. */ - data->send_seq_num++; - } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { - /* Increment if this is the first reply in a trans stream or a - * packet that doesn't belong to this stream (different mid). */ - data->send_seq_num++; - } - } + /* Don't mess with the sequence number for a deferred packet. */ + if (was_deferred_packet) { + return; + } + + if (!data->trans_info) { + /* Always increment if not in a trans stream. */ + data->send_seq_num++; + } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { + /* Increment if this is the first reply in a trans stream or a + * packet that doesn't belong to this stream (different mid). */ + data->send_seq_num++; + } } /*********************************************************** @@ -721,8 +700,10 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) * isn't a reply pending we need to re-sync the sequence * number. */ - if (is_oplock_break(inbuf) && !is_reply_pending(data->outstanding_packet_list)) + if (is_oplock_break(inbuf)) { + DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data->send_seq_num)); data->send_seq_num++; + } } saved_seq = reply_seq_number; @@ -820,7 +801,7 @@ void srv_calculate_sign_mac(char *outbuf) Called by server to defer an outgoing packet. ************************************************************/ -void srv_defer_sign_response(uint16 mid, BOOL deferred_packet) +void srv_defer_sign_response(uint16 mid) { struct smb_basic_signing_context *data; @@ -833,7 +814,7 @@ void srv_defer_sign_response(uint16 mid, BOOL deferred_packet) return; store_sequence_for_reply(&data->outstanding_packet_list, - mid, data->send_seq_num, deferred_packet); + mid, data->send_seq_num); data->send_seq_num++; } @@ -857,7 +838,7 @@ void srv_cancel_sign_response(uint16 mid) DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); - while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq,NULL)) + while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) ; } -- cgit From f589164ed94d79161d0798296c325b81c5eadbc7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Oct 2003 21:19:00 +0000 Subject: Patch from Stefan Metzmacher to fix signing problems when reverse connecting back to a client for printer notify. Jeremy. (This used to be commit 06aa434c3fdb139e3f3143d19413556945cbcd4f) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0a134f715d..9b54acf775 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -59,7 +59,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL ret; for(;;) { - ret = receive_smb(fd, buffer, timeout); + ret = receive_smb_raw(fd, buffer, timeout); if (!ret) { DEBUG(10,("client_receive_smb failed\n")); -- cgit From 5114dee2716f9703f2eee07a891d77a15f4b6a82 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Oct 2003 23:14:41 +0000 Subject: Fix for bug #64, Win9x Nexus tools not working against Samba3.0. Missing map in errormap for ERROR_MORE_DATA -> ERRDOS, ERRmoredata. Jeremy. (This used to be commit 7eaae388b35cb3d20cdd968b00d65c88fcee5878) --- source3/libsmb/errormap.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 4d9a717e1c..116d2cefe1 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -98,6 +98,10 @@ static const struct { */ {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {ERRDOS, 111, NT_STATUS_BUFFER_TOO_SMALL}, +/* + * Not an official error, as only bit 0x80000000, not bits 0xC0000000 are set. + */ + {ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW}, {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, {ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, -- cgit From bb0598faf58679a7ad26a1caab8eadb154a07ae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Oct 2003 23:38:20 +0000 Subject: Put strcasecmp/strncasecmp on the banned list (except for needed calls in iconv.c and nsswitch/). Using them means you're not thinking about multibyte at all and I really want to discourage that. Jeremy. (This used to be commit d7e35dfb9283d560d0ed2ab231f36ed92767dace) --- source3/libsmb/namequery_dc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index a596f00ddb..df7f856cd7 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -34,7 +34,7 @@ static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_n ADS_STRUCT *ads; const char *realm = domain; - if (strcasecmp(realm, lp_workgroup()) == 0) + if (strequal(realm, lp_workgroup())) realm = lp_realm(); ads = ads_init(realm, domain, NULL); -- cgit From e78cf62248f842069c97da914c0dfc2d5c27e997 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 23 Oct 2003 13:45:48 +0000 Subject: According to Ethereal we have a 32-Bit quantity here. And with SSVAL valgrind reports an unitialized read which is obviously correct. And I hate valgrind errors ;-) Volker (This used to be commit e5dbf2441c2ce7e7cb62f2538786e38bb8c8bdd9) --- source3/libsmb/clisecdesc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 548cd6ec18..2989966f4d 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -33,7 +33,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, SEC_DESC *psd = NULL; SIVAL(param, 0, fnum); - SSVAL(param, 4, 0x7); + SIVAL(param, 4, 0x7); if (!cli_send_nt_trans(cli, NT_TRANSACT_QUERY_SECURITY_DESC, -- cgit From 2f84a990bcfae7acaee0759359dd8867b24f600c Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 24 Oct 2003 17:01:19 +0000 Subject: Commit Derrell's changes to libsmbclient plus a small change to configure.in to see if SGI and other platforms will build. (This used to be commit cf9311044c372695592db1b95b814b0870b8cf29) --- source3/libsmb/libsmb_compat.c | 190 +++- source3/libsmb/libsmbclient.c | 2209 ++++++++++++++++++++++++++++++++-------- 2 files changed, 1969 insertions(+), 430 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 27b274953a..4c96c41c56 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -5,6 +5,7 @@ Copyright (C) Richard Sharpe 2000 Copyright (C) John Terpstra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -34,14 +35,14 @@ struct smbc_compat_fdlist { static SMBCCTX * statcont = NULL; static int smbc_compat_initialized = 0; -static int smbc_currentfd = 10000; -static struct smbc_compat_fdlist * smbc_compat_fdlist = NULL; - +static int smbc_compat_nextfd = 0; +static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL; +static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL; /* Find an fd and return the SMBCFILE * or NULL on failure */ static SMBCFILE * find_fd(int fd) { - struct smbc_compat_fdlist * f = smbc_compat_fdlist; + struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; while (f) { if (f->fd == fd) return f->file; @@ -53,16 +54,36 @@ static SMBCFILE * find_fd(int fd) /* Add an fd, returns 0 on success, -1 on error with errno set */ static int add_fd(SMBCFILE * file) { - struct smbc_compat_fdlist * f = malloc(sizeof(struct smbc_compat_fdlist)); - if (!f) { - errno = ENOMEM; - return -1; - } + struct smbc_compat_fdlist * f = smbc_compat_fd_avail; + + if (f) { + /* We found one that's available */ + DLIST_REMOVE(smbc_compat_fd_avail, f); + + } else { + /* + * None were available, so allocate one. Keep the number of + * file descriptors determinate. This allows the application + * to allocate bitmaps or mapping of file descriptors based on + * a known maximum number of file descriptors that will ever + * be returned. + */ + if (smbc_compat_nextfd >= FD_SETSIZE) { + errno = EMFILE; + return -1; + } + + f = malloc(sizeof(struct smbc_compat_fdlist)); + if (!f) { + errno = ENOMEM; + return -1; + } - f->fd = smbc_currentfd++; + f->fd = SMBC_BASE_FD + smbc_compat_nextfd++; + } + f->file = file; - - DLIST_ADD(smbc_compat_fdlist, f); + DLIST_ADD(smbc_compat_fd_in_use, f); return f->fd; } @@ -72,16 +93,19 @@ static int add_fd(SMBCFILE * file) /* Delete an fd, returns 0 on success */ static int del_fd(int fd) { - struct smbc_compat_fdlist * f = smbc_compat_fdlist; + struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; + while (f) { if (f->fd == fd) break; f = f->next; } + if (f) { /* found */ - DLIST_REMOVE(smbc_compat_fdlist, f); - SAFE_FREE(f); + DLIST_REMOVE(smbc_compat_fd_in_use, f); + f->file = NULL; + DLIST_ADD(smbc_compat_fd_avail, f); return 0; } return 1; @@ -91,6 +115,9 @@ static int del_fd(int fd) int smbc_init(smbc_get_auth_data_fn fn, int debug) { + int i; + struct smbc_compat_fdlist * f; + if (!smbc_compat_initialized) { statcont = smbc_new_context(); if (!statcont) @@ -112,6 +139,22 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) } +SMBCCTX *smbc_set_context(SMBCCTX * context) +{ + SMBCCTX *old_context = statcont; + + if (context) { + /* Save provided context. It must have been initialized! */ + statcont = context; + + /* You'd better know what you're doing. We won't help you. */ + smbc_compat_initialized = 1; + } + + return old_context; +} + + int smbc_open(const char *furl, int flags, mode_t mode) { SMBCFILE * file; @@ -252,8 +295,121 @@ int smbc_fstat(int fd, struct stat *st) int smbc_chmod(const char *url, mode_t mode) { - /* NOT IMPLEMENTED IN LIBSMBCLIENT YET */ - return -1; + return statcont->chmod(statcont, url, mode); +} + +int smbc_utimes(const char *fname, struct timeval *tbuf) +{ + return statcont->utimes(statcont, fname, tbuf); +} + +#ifdef HAVE_UTIME_H +int smbc_utime(const char *fname, struct utimbuf *utbuf) +{ + struct timeval tv; + + if (utbuf == NULL) + return statcont->utimes(statcont, fname, NULL); + + tv.tv_sec = utbuf->modtime; + tv.tv_usec = 0; + return statcont->utimes(statcont, fname, &tv); +} +#endif + +int smbc_setxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + return statcont->setxattr(statcont, fname, name, value, size, flags); +} + +int smbc_lsetxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + return statcont->setxattr(statcont, fname, name, value, size, flags); +} + +int smbc_fsetxattr(int fd, + const char *name, + const void *value, + size_t size, + int flags) +{ + SMBCFILE * file = find_fd(fd); + return statcont->setxattr(statcont, file->fname, + name, value, size, flags); +} + +int smbc_getxattr(const char *fname, + const char *name, + const void *value, + size_t size) +{ + return statcont->getxattr(statcont, fname, name, value, size); +} + +int smbc_lgetxattr(const char *fname, + const char *name, + const void *value, + size_t size) +{ + return statcont->getxattr(statcont, fname, name, value, size); +} + +int smbc_fgetxattr(int fd, + const char *name, + const void *value, + size_t size) +{ + SMBCFILE * file = find_fd(fd); + return statcont->getxattr(statcont, file->fname, name, value, size); +} + +int smbc_removexattr(const char *fname, + const char *name) +{ + return statcont->removexattr(statcont, fname, name); +} + +int smbc_lremovexattr(const char *fname, + const char *name) +{ + return statcont->removexattr(statcont, fname, name); +} + +int smbc_fremovexattr(int fd, + const char *name) +{ + SMBCFILE * file = find_fd(fd); + return statcont->removexattr(statcont, file->fname, name); +} + +int smbc_listxattr(const char *fname, + char *list, + size_t size) +{ + return statcont->listxattr(statcont, fname, list, size); +} + +int smbc_llistxattr(const char *fname, + char *list, + size_t size) +{ + return statcont->listxattr(statcont, fname, list, size); +} + +int smbc_flistxattr(int fd, + char *list, + size_t size) +{ + SMBCFILE * file = find_fd(fd); + return statcont->listxattr(statcont, file->fname, list, size); } int smbc_print_file(const char *fname, const char *printq) diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 4eb7f49760..a11a965fde 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5,6 +5,7 @@ Copyright (C) Richard Sharpe 2000, 2002 Copyright (C) John Terpstra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +26,22 @@ #include "../include/libsmb_internal.h" +/* + * Internal flags for extended attributes + */ + +/* internal mode values */ +#define SMBC_XATTR_MODE_ADD 1 +#define SMBC_XATTR_MODE_REMOVE 2 +#define SMBC_XATTR_MODE_REMOVE_ALL 3 +#define SMBC_XATTR_MODE_SET 4 +#define SMBC_XATTR_MODE_CHOWN 5 +#define SMBC_XATTR_MODE_CHGRP 6 + +#define CREATE_ACCESS_READ READ_CONTROL_ACCESS + + + /* * Functions exported by libsmb_cache.c that we need here */ @@ -162,8 +179,9 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, /* see if it has the right prefix */ len = strlen(smbc_prefix); - if (strncmp(s,smbc_prefix,len) || - (s[len] != '/' && s[len] != 0)) return -1; /* What about no smb: ? */ + if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { + return -1; /* What about no smb: ? */ + } p = s + len; @@ -343,6 +361,67 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) return 0; } +SMBCSRV *find_server(SMBCCTX *context, + const char *server, + const char *share, + fstring workgroup, + fstring username, + fstring password) +{ + SMBCSRV *srv; + int auth_called = 0; + + check_server_cache: + + srv = context->callbacks.get_cached_srv_fn(context, server, share, + workgroup, username); + + if (!auth_called && !srv && (!username[0] || !password[0])) { + context->callbacks.auth_fn(server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + /* + * However, smbc_auth_fn may have picked up info relating to + * an existing connection, so try for an existing connection + * again ... + */ + auth_called = 1; + goto check_server_cache; + + } + + if (srv) { + if (context->callbacks.check_server_fn(context, srv)) { + /* + * This server is no good anymore + * Try to remove it and check for more possible + * servers in the cache + */ + if (context->callbacks.remove_unused_server_fn(context, + srv)) { + /* + * We could not remove the server completely, + * remove it from the cache so we will not get + * it again. It will be removed when the last + * file/dir is closed. + */ + context->callbacks.remove_cached_srv_fn(context, + srv); + } + + /* + * Maybe there are more cached connections to this + * server + */ + goto check_server_cache; + } + return srv; + } + + return NULL; +} + /* * Connect to a server, possibly on an existing connection * @@ -360,7 +439,6 @@ SMBCSRV *smbc_server(SMBCCTX *context, fstring password) { SMBCSRV *srv=NULL; - int auth_called = 0; struct cli_state c; struct nmb_name called, calling; char *p; @@ -378,45 +456,10 @@ SMBCSRV *smbc_server(SMBCCTX *context, return NULL; } - check_server_cache: - - srv = context->callbacks.get_cached_srv_fn(context, server, share, - workgroup, username); - - if (!auth_called && !srv && (!username[0] || !password[0])) { - context->callbacks.auth_fn(server, share, workgroup, sizeof(fstring), - username, sizeof(fstring), password, sizeof(fstring)); - /* - * However, smbc_auth_fn may have picked up info relating to an - * existing connection, so try for an existing connection again ... - */ - auth_called = 1; - goto check_server_cache; - - } - - if (srv) { - if (context->callbacks.check_server_fn(context, srv)) { - /* - * This server is no good anymore - * Try to remove it and check for more possible servers in the cache - */ - if (context->callbacks.remove_unused_server_fn(context, srv)) { - /* - * We could not remove the server completely, remove it from the cache - * so we will not get it again. It will be removed when the last file/dir - * is closed. - */ - context->callbacks.remove_cached_srv_fn(context, srv); - } - - /* - * Maybe there are more cached connections to this server - */ - goto check_server_cache; - } - return srv; - } + srv = find_server(context, server, share, + workgroup, username, password); + if (srv) + return srv; make_nmb_name(&calling, context->netbios_name, 0x0); make_nmb_name(&called , server, 0x20); @@ -441,16 +484,26 @@ SMBCSRV *smbc_server(SMBCCTX *context, /* have to open a new connection */ if (!cli_initialise(&c)) { - errno = ENOENT; + errno = ENOMEM; return NULL; } c.timeout = context->timeout; + /* Force use of port 139 for first try, so browse lists can work */ + c.port = 139; + if (!cli_connect(&c, server_n, &ip)) { - cli_shutdown(&c); - errno = ENOENT; - return NULL; + /* + * Port 139 connection failed. Try port 445 to handle + * connections to newer (e.g. XP) hosts with NetBIOS disabled. + */ + c.port = 445; + if (!cli_connect(&c, server_n, &ip)) { + cli_shutdown(&c); + errno = ENETUNREACH; + return NULL; + } } if (!cli_session_request(&c, &calling, &called)) { @@ -552,6 +605,101 @@ SMBCSRV *smbc_server(SMBCCTX *context, return NULL; } +/* + * Connect to a server for getting/setting attributes, possibly on an existing + * connection. This works similarly to smbc_server(). + */ +SMBCSRV *smbc_attr_server(SMBCCTX *context, + const char *server, const char *share, + fstring workgroup, + fstring username, fstring password) +{ + struct in_addr ip; + struct cli_state *ipc_cli; + NTSTATUS nt_status; + SMBCSRV *ipc_srv=NULL; + POLICY_HND pol; + + /* + * See if we've already created this special connection. Reference + * our "special" share name 'IPC$$'. + */ + ipc_srv = find_server(context, server, "IPC$$", + workgroup, username, password); + if (!ipc_srv) { + + /* We didn't find a cached connection. Get the password */ + if (*password == '\0') { + /* ... then retrieve it now. */ + context->callbacks.auth_fn(server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + } + + zero_ip(&ip); + nt_status = cli_full_connection(&ipc_cli, + global_myname(), server, + &ip, 0, "IPC$", "?????", + username, workgroup, + password, 0, + Undefined, NULL); + if (! NT_STATUS_IS_OK(nt_status)) { + DEBUG(0,("cli_full_connection failed! (%s)\n", + nt_errstr(nt_status))); + errno = ENOTSUP; + return NULL; + } + + if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) { + DEBUG(0, ("cli_nt_session_open fail! (%s)\n", + nt_errstr(nt_status))); + errno = ENOTSUP; + free(ipc_cli); + return NULL; + } + + /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, + but NT sends 0x2000000 so we might as well do it too. */ + + nt_status = cli_lsa_open_policy(ipc_cli, + ipc_cli->mem_ctx, + True, + GENERIC_EXECUTE_ACCESS, + &pol); + + if (!NT_STATUS_IS_OK(nt_status)) { + errno = smbc_errno(context, ipc_cli); + free(ipc_cli); + return NULL; + } + + ipc_srv = (SMBCSRV *)malloc(sizeof(*ipc_srv)); + if (!ipc_srv) { + errno = ENOMEM; + free(ipc_cli); + return NULL; + } + + ZERO_STRUCTP(ipc_srv); + ipc_srv->cli = *ipc_cli; + + free(ipc_cli); + + /* now add it to the cache (internal or external) */ + if (context->callbacks.add_cached_srv_fn(context, ipc_srv, + server, + "IPC$$", + workgroup, + username)) { + DEBUG(3, (" Failed to add server to cache\n")); + return NULL; + } + } + + return ipc_srv; +} + /* * Routine to open() a file ... */ @@ -850,7 +998,10 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, size, mode, ino)) return True; /* if this is NT then don't bother with the getatr */ - if (srv->cli.capabilities & CAP_NT_SMBS) return False; + if (srv->cli.capabilities & CAP_NT_SMBS) { + errno = EPERM; + return False; + } if (cli_getatr(&srv->cli, path, mode, size, m_time)) { a_time = c_time = m_time; @@ -858,6 +1009,7 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, return True; } + errno = EPERM; return False; } @@ -1202,9 +1354,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { - return -1; /* errno set by smbc_server */ - } /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { @@ -1584,18 +1734,17 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) /* * Get a connection to IPC$ on the server if we do not already have one */ - + srv = smbc_server(context, server, "IPC$", workgroup, user, password); - - if (!srv) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - return NULL; - } - + if (!srv) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; + } + dir->srv = srv; dir->dir_type = SMBC_WORKGROUP; @@ -2290,488 +2439,1722 @@ static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) } -/* - * Open a print file to be written to by other calls - */ - -static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) +int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) { - fstring server, share, user, password; + SMBCSRV *srv; + fstring server, share, user, password, workgroup; pstring path; - + uint16 mode; + if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; - return NULL; + errno = EINVAL; /* Best I can think of ... */ + return -1; } if (!fname) { errno = EINVAL; - return NULL; + return -1; } - DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); + DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ - /* What if the path is empty, or the file exists? */ - - return context->open(context, fname, O_WRONLY, 666); - -} - -/* - * Routine to print a file on a remote server ... - * - * We open the file, which we assume to be on a remote server, and then - * copy it to a print file on the share specified by printq. - */ - -static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq) -{ - SMBCFILE *fid1, *fid2; - int bytes, saverr, tot_bytes = 0; - char buf[4096]; - - if (!c_file || !c_file->internal->_initialized || !c_print || - !c_print->internal->_initialized) { - - errno = EINVAL; - return -1; - - } - - if (!fname && !printq) { - - errno = EINVAL; - return -1; - - } - - /* Try to open the file for reading ... */ - - if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { - - DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); - return -1; /* smbc_open sets errno */ - - } - - /* Now, try to open the printer file for writing */ - - if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { - - saverr = errno; /* Save errno */ - c_file->close(c_file, fid1); - errno = saverr; - return -1; - - } - - while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) { - - tot_bytes += bytes; - - if ((c_print->write(c_print, fid2, buf, bytes)) < 0) { + if (user[0] == (char)0) fstrcpy(user, context->user); - saverr = errno; - c_file->close(c_file, fid1); - c_print->close(c_print, fid2); - errno = saverr; + fstrcpy(workgroup, context->workgroup); - } + srv = smbc_server(context, server, share, workgroup, user, password); + if (!srv) { + return -1; /* errno set by smbc_server */ } - saverr = errno; + mode = 0; - c_file->close(c_file, fid1); /* We have to close these anyway */ - c_print->close(c_print, fid2); + if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; + if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; + if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; + if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - if (bytes < 0) { - - errno = saverr; + if (!cli_setatr(&srv->cli, path, mode, 0)) { + errno = smbc_errno(context, &srv->cli); return -1; - } - - return tot_bytes; - + + return 0; } -/* - * Routine to list print jobs on a printer share ... - */ - -static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn) +int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) { - SMBCSRV *srv; + SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; + uint16 mode; + time_t t = (tbuf == NULL ? time(NULL) : tbuf->tv_sec); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; + errno = EINVAL; /* Best I can think of ... */ return -1; - + } if (!fname) { - + errno = EINVAL; return -1; } - DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + DEBUG(4, ("smbc_utimes(%s, [%s])\n", fname, ctime(&t))); smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ if (user[0] == (char)0) fstrcpy(user, context->user); - + fstrcpy(workgroup, context->workgroup); srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { - return -1; /* errno set by smbc_server */ - } - if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) { - - errno = smbc_errno(context, &srv->cli); - return -1; + if (!smbc_getatr(context, srv, path, + &mode, NULL, + NULL, NULL, NULL, + NULL)) { + return -1; + } + if (!cli_setatr(&srv->cli, path, mode, t)) { + /* some servers always refuse directory changes */ + if (!(mode & aDIR)) { + errno = smbc_errno(context, &srv->cli); + return -1; + } } - - return 0; + return 0; } -/* - * Delete a print job from a remote printer share - */ - -static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id) -{ - SMBCSRV *srv; - fstring server, share, user, password, workgroup; - pstring path; - int err; - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - return -1; +/* The MSDN is contradictory over the ordering of ACE entries in an ACL. + However NT4 gives a "The information may have been modified by a + computer running Windows NT 5.0" if denied ACEs do not appear before + allowed ACEs. */ - } +static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2) +{ + if (sec_ace_equal(ace1, ace2)) + return 0; - if (!fname) { + if (ace1->type != ace2->type) + return ace2->type - ace1->type; - errno = EINVAL; - return -1; + if (sid_compare(&ace1->trustee, &ace2->trustee)) + return sid_compare(&ace1->trustee, &ace2->trustee); - } - - DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); + if (ace1->flags != ace2->flags) + return ace1->flags - ace2->flags; - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (ace1->info.mask != ace2->info.mask) + return ace1->info.mask - ace2->info.mask; - if (user[0] == (char)0) fstrcpy(user, context->user); + if (ace1->size != ace2->size) + return ace1->size - ace2->size; - fstrcpy(workgroup, context->workgroup); + return memcmp(ace1, ace2, sizeof(SEC_ACE)); +} - srv = smbc_server(context, server, share, workgroup, user, password); - if (!srv) { +static void sort_acl(SEC_ACL *the_acl) +{ + uint32 i; + if (!the_acl) return; - return -1; /* errno set by smbc_server */ + qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), QSORT_CAST ace_compare); + for (i=1;inum_aces;) { + if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) { + int j; + for (j=i; jnum_aces-1; j++) { + the_acl->ace[j] = the_acl->ace[j+1]; + } + the_acl->num_aces--; + } else { + i++; + } } +} - if ((err = cli_printjob_del(&srv->cli, id)) != 0) { +/* convert a SID to a string, either numeric or username/group */ +static void convert_sid_to_string(struct cli_state *ipc_cli, + POLICY_HND *pol, + fstring str, + BOOL numeric, + DOM_SID *sid) +{ + char **domains = NULL; + char **names = NULL; + uint32 *types = NULL; - if (err < 0) - errno = smbc_errno(context, &srv->cli); - else if (err == ERRnosuchprintjob) - errno = EINVAL; - return -1; + sid_to_string(str, sid); + if (numeric) return; /* no lookup desired */ + + /* Ask LSA to convert the sid to a name */ + + if (!NT_STATUS_IS_OK(cli_lsa_lookup_sids(ipc_cli, ipc_cli->mem_ctx, + pol, 1, sid, &domains, + &names, &types)) || + !domains || !domains[0] || !names || !names[0]) { + return; } - return 0; + /* Converted OK */ + slprintf(str, sizeof(fstring) - 1, "%s%s%s", + domains[0], lp_winbind_separator(), + names[0]); } -/* - * Get a new empty handle to fill in with your own info - */ -SMBCCTX * smbc_new_context(void) +/* convert a string to a SID, either numeric or username/group */ +static BOOL convert_string_to_sid(struct cli_state *ipc_cli, + POLICY_HND *pol, + BOOL numeric, + DOM_SID *sid, + const char *str) { - SMBCCTX * context; + uint32 *types = NULL; + DOM_SID *sids = NULL; + BOOL result = True; - context = malloc(sizeof(SMBCCTX)); - if (!context) { - errno = ENOMEM; - return NULL; - } + if (numeric) { + if (strncmp(str, "S-", 2) == 0) { + return string_to_sid(sid, str); + } - ZERO_STRUCTP(context); + result = False; + goto done; + } - context->internal = malloc(sizeof(struct smbc_internal_data)); - if (!context->internal) { - errno = ENOMEM; - return NULL; + if (!NT_STATUS_IS_OK(cli_lsa_lookup_names(ipc_cli, ipc_cli->mem_ctx, + pol, 1, &str, &sids, + &types))) { + result = False; + goto done; } - ZERO_STRUCTP(context->internal); + sid_copy(sid, &sids[0]); + done: - - /* ADD REASONABLE DEFAULTS */ - context->debug = 0; - context->timeout = 20000; /* 20 seconds */ - - context->open = smbc_open_ctx; - context->creat = smbc_creat_ctx; - context->read = smbc_read_ctx; - context->write = smbc_write_ctx; - context->close = smbc_close_ctx; - context->unlink = smbc_unlink_ctx; - context->rename = smbc_rename_ctx; - context->lseek = smbc_lseek_ctx; - context->stat = smbc_stat_ctx; - context->fstat = smbc_fstat_ctx; - context->opendir = smbc_opendir_ctx; - context->closedir = smbc_closedir_ctx; - context->readdir = smbc_readdir_ctx; - context->getdents = smbc_getdents_ctx; - context->mkdir = smbc_mkdir_ctx; - context->rmdir = smbc_rmdir_ctx; - context->telldir = smbc_telldir_ctx; - context->lseekdir = smbc_lseekdir_ctx; - context->fstatdir = smbc_fstatdir_ctx; - context->open_print_job = smbc_open_print_job_ctx; - context->print_file = smbc_print_file_ctx; - context->list_print_jobs = smbc_list_print_jobs_ctx; - context->unlink_print_job = smbc_unlink_print_job_ctx; - - context->callbacks.check_server_fn = smbc_check_server; - context->callbacks.remove_unused_server_fn = smbc_remove_unused_server; - - smbc_default_cache_functions(context); - - return context; + return result; } -/* - * Free a context - * - * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed - * and thus you'll be leaking memory if not handled properly. - * - */ -int smbc_free_context(SMBCCTX * context, int shutdown_ctx) + +/* parse an ACE in the same format as print_ace() */ +static BOOL parse_ace(struct cli_state *ipc_cli, + POLICY_HND *pol, + SEC_ACE *ace, + BOOL numeric, + char *str) { - if (!context) { - errno = EBADF; - return 1; + char *p; + const char *cp; + fstring tok; + unsigned atype, aflags, amask; + DOM_SID sid; + SEC_ACCESS mask; + const struct perm_value *v; + struct perm_value { + const char *perm; + uint32 mask; + }; + + /* These values discovered by inspection */ + static const struct perm_value special_values[] = { + { "R", 0x00120089 }, + { "W", 0x00120116 }, + { "X", 0x001200a0 }, + { "D", 0x00010000 }, + { "P", 0x00040000 }, + { "O", 0x00080000 }, + { NULL, 0 }, + }; + + static const struct perm_value standard_values[] = { + { "READ", 0x001200a9 }, + { "CHANGE", 0x001301bf }, + { "FULL", 0x001f01ff }, + { NULL, 0 }, + }; + + + ZERO_STRUCTP(ace); + p = strchr_m(str,':'); + if (!p) return False; + *p = '\0'; + p++; + /* Try to parse numeric form */ + + if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && + convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { + goto done; + } + + /* Try to parse text form */ + + if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { + return False; + } + + cp = p; + if (!next_token(&cp, tok, "/", sizeof(fstring))) { + return False; + } + + if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { + atype = SEC_ACE_TYPE_ACCESS_ALLOWED; + } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { + atype = SEC_ACE_TYPE_ACCESS_DENIED; + } else { + return False; } - - if (shutdown_ctx) { - SMBCFILE * f; - DEBUG(1,("Performing aggressive shutdown.\n")); - - f = context->internal->_files; - while (f) { - context->close(context, f); - f = f->next; - } - context->internal->_files = NULL; - - /* First try to remove the servers the nice way. */ - if (context->callbacks.purge_cached_fn(context)) { - SMBCSRV * s; - DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); - s = context->internal->_servers; - while (s) { - cli_shutdown(&s->cli); - context->callbacks.remove_cached_srv_fn(context, s); - SAFE_FREE(s); - s = s->next; - } - context->internal->_servers = NULL; + + /* Only numeric form accepted for flags at present */ + + if (!(next_token(&cp, tok, "/", sizeof(fstring)) && + sscanf(tok, "%i", &aflags))) { + return False; + } + + if (!next_token(&cp, tok, "/", sizeof(fstring))) { + return False; + } + + if (strncmp(tok, "0x", 2) == 0) { + if (sscanf(tok, "%i", &amask) != 1) { + return False; } + goto done; } - else { - /* This is the polite way */ - if (context->callbacks.purge_cached_fn(context)) { - DEBUG(1, ("Could not purge all servers, free_context failed.\n")); - errno = EBUSY; - return 1; + + for (v = standard_values; v->perm; v++) { + if (strcmp(tok, v->perm) == 0) { + amask = v->mask; + goto done; } - if (context->internal->_servers) { - DEBUG(1, ("Active servers in context, free_context failed.\n")); - errno = EBUSY; - return 1; + } + + p = tok; + + while(*p) { + BOOL found = False; + + for (v = special_values; v->perm; v++) { + if (v->perm[0] == *p) { + amask |= v->mask; + found = True; + } } - if (context->internal->_files) { - DEBUG(1, ("Active files in context, free_context failed.\n")); - errno = EBUSY; - return 1; - } + + if (!found) return False; + p++; } - /* Things we have to clean up */ - SAFE_FREE(context->workgroup); - SAFE_FREE(context->netbios_name); - SAFE_FREE(context->user); - - DEBUG(3, ("Context %p succesfully freed\n", context)); - SAFE_FREE(context->internal); - SAFE_FREE(context); - return 0; -} + if (*p) { + return False; + } + done: + mask.mask = amask; + init_sec_ace(ace, &sid, atype, mask, aflags); + return True; +} -/* - * Initialise the library etc - * - * We accept a struct containing handle information. - * valid values for info->debug from 0 to 100, - * and insist that info->fn must be non-null. - */ -SMBCCTX * smbc_init_context(SMBCCTX * context) +/* add an ACE to a list of ACEs in a SEC_ACL */ +static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) { - pstring conf; - int pid; - char *user = NULL, *home = NULL; + SEC_ACL *new; + SEC_ACE *aces; + if (! *the_acl) { + (*the_acl) = make_sec_acl(ctx, 3, 1, ace); + return True; + } - if (!context || !context->internal) { - errno = EBADF; + aces = calloc(1+(*the_acl)->num_aces,sizeof(SEC_ACE)); + memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); + memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); + new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); + SAFE_FREE(aces); + (*the_acl) = new; + return True; +} + + +/* parse a ascii version of a security descriptor */ +static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx, + struct cli_state *ipc_cli, + POLICY_HND *pol, + BOOL numeric, + char *str) +{ + const char *p = str; + fstring tok; + SEC_DESC *ret; + size_t sd_size; + DOM_SID *grp_sid=NULL, *owner_sid=NULL; + SEC_ACL *dacl=NULL; + int revision=1; + + while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) { + + if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { + revision = strtol(tok+9, NULL, 16); + continue; + } + + if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { + owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID)); + if (!owner_sid || + !convert_string_to_sid(ipc_cli, pol, + numeric, + owner_sid, tok+6)) { + DEBUG(5, ("Failed to parse owner sid\n")); + return NULL; + } + continue; + } + + if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { + owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID)); + if (!owner_sid || + !convert_string_to_sid(ipc_cli, pol, + False, + owner_sid, tok+7)) { + DEBUG(5, ("Failed to parse owner sid\n")); + return NULL; + } + continue; + } + + if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { + grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID)); + if (!grp_sid || + !convert_string_to_sid(ipc_cli, pol, + numeric, + grp_sid, tok+6)) { + DEBUG(5, ("Failed to parse group sid\n")); + return NULL; + } + continue; + } + + if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { + grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID)); + if (!grp_sid || + !convert_string_to_sid(ipc_cli, pol, + False, + grp_sid, tok+6)) { + DEBUG(5, ("Failed to parse group sid\n")); + return NULL; + } + continue; + } + + if (StrnCaseCmp(tok,"ACL:", 4) == 0) { + SEC_ACE ace; + if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { + DEBUG(5, ("Failed to parse ACL %s\n", tok)); + return NULL; + } + if(!add_ace(&dacl, &ace, ctx)) { + DEBUG(5, ("Failed to add ACL %s\n", tok)); + return NULL; + } + continue; + } + + if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { + SEC_ACE ace; + if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { + DEBUG(5, ("Failed to parse ACL %s\n", tok)); + return NULL; + } + if(!add_ace(&dacl, &ace, ctx)) { + DEBUG(5, ("Failed to add ACL %s\n", tok)); + return NULL; + } + continue; + } + + DEBUG(5, ("Failed to parse security descriptor\n")); return NULL; } - /* Do not initialise the same client twice */ - if (context->internal->_initialized) { - return 0; - } + ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, + owner_sid, grp_sid, NULL, dacl, &sd_size); - if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) { + SAFE_FREE(grp_sid); + SAFE_FREE(owner_sid); - errno = EINVAL; - return NULL; + return ret; +} + +/***************************************************** +retrieve the acls for a file +*******************************************************/ +static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli, + struct cli_state *ipc_cli, POLICY_HND *pol, + char *filename, char *name, char *buf, int bufsize) +{ + uint32 i; + int n = 0; + int n_used; + BOOL all; + BOOL numeric = True; + BOOL determine_size = (bufsize == 0); + int fnum = -1; + SEC_DESC *sd; + fstring sidstr; + char *p; + + fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); + + if (fnum == -1) { + DEBUG(5, ("cacl_get failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; } - if (!smbc_initialized) { - /* Do some library wide intialisations the first time we get called */ + sd = cli_query_secdesc(cli, fnum, ctx); - /* Set this to what the user wants */ - DEBUGLEVEL = context->debug; - - setup_logging( "libsmbclient", True); + if (!sd) { + DEBUG(5, ("cacl_get Failed to query old descriptor\n")); + errno = 0; + return -1; + } - /* Here we would open the smb.conf file if needed ... */ - - home = getenv("HOME"); + cli_close(cli, fnum); + + all = (*name == '*'); + numeric = (* (name + strlen(name) - 1) != '+'); + + n_used = 0; + + if (all) { + if (determine_size) { + p = talloc_asprintf(ctx, + "REVISION:%d", sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "REVISION:%d", sd->revision); + } + } else if (StrCaseCmp(name, "revision") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%d", sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%d", sd->revision); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; - slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - - load_interfaces(); /* Load the list of interfaces ... */ - - in_client = True; /* FIXME, make a param */ + /* Get owner and group sid */ - if (!lp_load(conf, True, False, False)) { + if (sd->owner_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, sd->owner_sid); + } else { + fstrcpy(sidstr, ""); + } + + if (all) { + if (determine_size) { + p = talloc_asprintf(ctx, ",OWNER:%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, ",OWNER:%s", sidstr); + } + } else if (StrnCaseCmp(name, "owner", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%s", sidstr); + } + } - /* - * Well, if that failed, try the dyn_CONFIGFILE - * Which points to the standard locn, and if that - * fails, silently ignore it and use the internal - * defaults ... - */ - - if (!lp_load(dyn_CONFIGFILE, True, False, False)) { - DEBUG(5, ("Could not load either config file: %s or %s\n", - conf, dyn_CONFIGFILE)); - } - } + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; - reopen_logs(); /* Get logging working ... */ - - /* - * Block SIGPIPE (from lib/util_sock.c: write()) - * It is not needed and should not stop execution - */ - BlockSignals(True, SIGPIPE); - - /* Done with one-time initialisation */ - smbc_initialized = 1; + if (sd->grp_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, sd->grp_sid); + } else { + fstrcpy(sidstr, ""); + } + + if (all) { + if (determine_size) { + p = talloc_asprintf(ctx, ",GROUP:%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, ",GROUP:%s", sidstr); + } + } else if (StrnCaseCmp(name, "group", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%s", sidstr); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + + /* Add aces to value buffer */ + for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { + + SEC_ACE *ace = &sd->dacl->ace[i]; + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, &ace->trustee); + + if (all) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",ACL:%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->info.mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",ACL:%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->info.mask); + } + } else if ((StrnCaseCmp(name, "acl", 3) == 0 && + StrCaseCmp(name + 3, sidstr) == 0) || + (StrnCaseCmp(name, "acl+", 4) == 0 && + StrCaseCmp(name + 4, sidstr) == 0)) { + if (determine_size) { + p = talloc_asprintf(ctx, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->info.mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%d/%d/0x%08x", + ace->type, ace->flags, ace->info.mask); + } + } + if (n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + } + + if (n_used == 0) { + errno = ENOATTR; + return -1; + } + return n_used; +} + + +/***************************************************** +set the ACLs on a file given an ascii description +*******************************************************/ +static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli, + struct cli_state *ipc_cli, POLICY_HND *pol, + const char *filename, const char *the_acl, + int mode, int flags) +{ + int fnum; + int err = 0; + SEC_DESC *sd = NULL, *old; + SEC_ACL *dacl = NULL; + DOM_SID *owner_sid = NULL; + DOM_SID *grp_sid = NULL; + uint32 i, j; + size_t sd_size; + int ret = 0; + char *p; + BOOL numeric = True; + + /* the_acl will be null for REMOVE_ALL operations */ + if (the_acl) { + numeric = ((p = strchr(the_acl, ':')) != NULL && + p > the_acl && + p[-1] != '+'); + + /* if this is to set the entire ACL... */ + if (*the_acl == '*') { + /* ... then increment past the first colon */ + the_acl = p + 1; + } + + sd = sec_desc_parse(ctx, ipc_cli, pol, + numeric, (char *) the_acl); + + if (!sd) { + errno = EINVAL; + return -1; + } + } + + /* The desired access below is the only one I could find that works + with NT4, W2KP and Samba */ + + fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); + if (fnum == -1) { + DEBUG(5, ("cacl_set failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; } - - if (!context->user) { - /* - * FIXME: Is this the best way to get the user info? - */ - user = getenv("USER"); - /* walk around as "guest" if no username can be found */ - if (!user) context->user = strdup("guest"); - else context->user = strdup(user); + + old = cli_query_secdesc(cli, fnum, ctx); + + if (!old) { + DEBUG(5, ("cacl_set Failed to query old descriptor\n")); + errno = 0; + return -1; } - if (!context->netbios_name) { - /* - * We try to get our netbios name from the config. If that fails we fall - * back on constructing our netbios name from our hostname etc - */ - if (global_myname()) { - context->netbios_name = strdup(global_myname()); + cli_close(cli, fnum); + + switch (mode) { + case SMBC_XATTR_MODE_REMOVE_ALL: + old->dacl->num_aces = 0; + SAFE_FREE(old->dacl->ace); + SAFE_FREE(old->dacl); + old->off_dacl = 0; + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_REMOVE: + for (i=0;sd->dacl && idacl->num_aces;i++) { + BOOL found = False; + + for (j=0;old->dacl && jdacl->num_aces;j++) { + if (sec_ace_equal(&sd->dacl->ace[i], + &old->dacl->ace[j])) { + uint32 k; + for (k=j; kdacl->num_aces-1;k++) { + old->dacl->ace[k] = old->dacl->ace[k+1]; + } + old->dacl->num_aces--; + if (old->dacl->num_aces == 0) { + SAFE_FREE(old->dacl->ace); + SAFE_FREE(old->dacl); + old->off_dacl = 0; + } + found = True; + dacl = old->dacl; + break; + } + } + + if (!found) { + err = ENOATTR; + ret = -1; + goto failed; + } } - else { - /* - * Hmmm, I want to get hostname as well, but I am too lazy for the moment - */ - pid = sys_getpid(); - context->netbios_name = malloc(17); - if (!context->netbios_name) { - errno = ENOMEM; - return NULL; + break; + + case SMBC_XATTR_MODE_ADD: + for (i=0;sd->dacl && idacl->num_aces;i++) { + BOOL found = False; + + for (j=0;old->dacl && jdacl->num_aces;j++) { + if (sid_equal(&sd->dacl->ace[i].trustee, + &old->dacl->ace[j].trustee)) { + if (!(flags & SMBC_XATTR_FLAG_CREATE)) { + err = EEXIST; + ret = -1; + goto failed; + } + old->dacl->ace[j] = sd->dacl->ace[i]; + ret = -1; + found = True; + } + } + + if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { + err = ENOATTR; + ret = -1; + goto failed; } - slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); + + for (i=0;sd->dacl && idacl->num_aces;i++) { + add_ace(&old->dacl, &sd->dacl->ace[i], ctx); + } } + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_SET: + old = sd; + owner_sid = old->owner_sid; + grp_sid = old->grp_sid; + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_CHOWN: + owner_sid = sd->owner_sid; + break; + + case SMBC_XATTR_MODE_CHGRP: + grp_sid = sd->grp_sid; + break; } - DEBUG(1, ("Using netbios name %s.\n", context->netbios_name)); + /* Denied ACE entries must come before allowed ones */ + sort_acl(old->dacl); - if (!context->workgroup) { - if (lp_workgroup()) { - context->workgroup = strdup(lp_workgroup()); - } - else { - /* TODO: Think about a decent default workgroup */ - context->workgroup = strdup("samba"); - } + /* Create new security descriptor and set it */ + sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, + owner_sid, grp_sid, NULL, dacl, &sd_size); + + fnum = cli_nt_create(cli, filename, + WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); + + if (fnum == -1) { + DEBUG(5, ("cacl_set failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; } - DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); - - /* shortest timeout is 1 second */ - if (context->timeout > 0 && context->timeout < 1000) - context->timeout = 1000; + if (!cli_set_secdesc(cli, fnum, sd)) { + DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli))); + ret = -1; + } - /* - * FIXME: Should we check the function pointers here? - */ + /* Clean up */ - context->internal->_initialized = 1; - - return context; + failed: + cli_close(cli, fnum); + + if (err != 0) { + errno = err; + } + + return ret; +} + + +int smbc_setxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + int ret; + SMBCSRV *srv; + SMBCSRV *ipc_srv; + fstring server, share, user, password, workgroup; + pstring path; + TALLOC_CTX *ctx; + POLICY_HND pol; + + if (!context || !context->internal || + !context->internal->_initialized) { + + errno = EINVAL; /* Best I can think of ... */ + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", + fname, name, (int) size, (char *) value)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) fstrcpy(user, context->user); + + fstrcpy(workgroup, context->workgroup); + + srv = smbc_server(context, server, share, workgroup, user, password); + if (!srv) { + return -1; /* errno set by smbc_server */ + } + + ipc_srv = smbc_attr_server(context, server, share, + workgroup, user, password); + if (!ipc_srv) { + return -1; + } + + ctx = talloc_init("smbc_setxattr"); + if (!ctx) { + errno = ENOMEM; + return -1; + } + + /* + * Are they asking to set an access control element or to set + * the entire access control list? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(ctx, "%s:%s", name+19, (char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(ctx, &srv->cli, + &ipc_srv->cli, &pol, path, + namevalue, + (*namevalue == '*' + ? SMBC_XATTR_MODE_SET + : SMBC_XATTR_MODE_ADD), + flags); + } + talloc_destroy(ctx); + return ret; + } + + /* + * Are they asking to set the owner? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(ctx, "%s:%s", name+19, (char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(ctx, &srv->cli, + &ipc_srv->cli, &pol, path, + namevalue, SMBC_XATTR_MODE_CHOWN, 0); + } + talloc_destroy(ctx); + return ret; + } + + /* + * Are they asking to set the group? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(ctx, "%s:%s", name+19, (char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(ctx, &srv->cli, + &ipc_srv->cli, &pol, path, + namevalue, SMBC_XATTR_MODE_CHOWN, 0); + } + talloc_destroy(ctx); + return ret; + } + + /* Unsupported attribute name */ + talloc_destroy(ctx); + errno = EINVAL; + return -1; +} + +int smbc_getxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size) +{ + int ret; + SMBCSRV *srv; + SMBCSRV *ipc_srv; + fstring server, share, user, password, workgroup; + pstring path; + TALLOC_CTX *ctx; + POLICY_HND pol; + + if (!context || !context->internal || + !context->internal->_initialized) { + + errno = EINVAL; /* Best I can think of ... */ + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) fstrcpy(user, context->user); + + fstrcpy(workgroup, context->workgroup); + + srv = smbc_server(context, server, share, workgroup, user, password); + if (!srv) { + return -1; /* errno set by smbc_server */ + } + + ipc_srv = smbc_attr_server(context, server, share, + workgroup, user, password); + if (!ipc_srv) { + return -1; + } + + ctx = talloc_init("smbc:getxattr"); + if (!ctx) { + errno = ENOMEM; + return -1; + } + + /* Are they requesting a supported attribute? */ + if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + + /* Yup. */ + ret = cacl_get(ctx, &srv->cli, + &ipc_srv->cli, &pol, + (char *) path, (char *) name + 19, + (char *) value, size); + if (ret < 0 && errno == 0) { + errno = smbc_errno(context, &srv->cli); + } + talloc_destroy(ctx); + return ret; + } + + /* Unsupported attribute name */ + talloc_destroy(ctx); + errno = EINVAL; + return -1; +} + + +int smbc_removexattr_ctx(SMBCCTX *context, + const char *fname, + const char *name) +{ + int ret; + SMBCSRV *srv; + SMBCSRV *ipc_srv; + fstring server, share, user, password, workgroup; + pstring path; + TALLOC_CTX *ctx; + POLICY_HND pol; + + if (!context || !context->internal || + !context->internal->_initialized) { + + errno = EINVAL; /* Best I can think of ... */ + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) fstrcpy(user, context->user); + + fstrcpy(workgroup, context->workgroup); + + srv = smbc_server(context, server, share, workgroup, user, password); + if (!srv) { + return -1; /* errno set by smbc_server */ + } + + ipc_srv = smbc_attr_server(context, server, share, + workgroup, user, password); + if (!ipc_srv) { + return -1; + } + + ipc_srv = smbc_attr_server(context, server, share, + workgroup, user, password); + if (!ipc_srv) { + return -1; + } + + ctx = talloc_init("smbc_removexattr"); + if (!ctx) { + errno = ENOMEM; + return -1; + } + + /* Are they asking to set the entire ACL? */ + if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { + + /* Yup. */ + ret = cacl_set(ctx, &srv->cli, + &ipc_srv->cli, &pol, path, + NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); + talloc_destroy(ctx); + return ret; + } + + /* + * Are they asking to remove one or more spceific security descriptor + * attributes? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + + /* Yup. */ + ret = cacl_set(ctx, &srv->cli, + &ipc_srv->cli, &pol, path, + name + 19, SMBC_XATTR_MODE_REMOVE, 0); + talloc_destroy(ctx); + return ret; + } + + /* Unsupported attribute name */ + talloc_destroy(ctx); + errno = EINVAL; + return -1; +} + +int smbc_listxattr_ctx(SMBCCTX *context, + const char *fname, + char *list, + size_t size) +{ + /* + * This isn't quite what listxattr() is supposed to do. This returns + * the complete set of attributes, always, rather than only those + * attribute names which actually exist for a file. Hmmm... + */ + const char supported[] = + "system.nt_sec_desc.revision\0" + "system.nt_sec_desc.owner\0" + "system.nt_sec_desc.owner+\0" + "system.nt_sec_desc.group\0" + "system.nt_sec_desc.group+\0" + "system.nt_sec_desc.acl\0" + "system.nt_sec_desc.acl+\0" + "system.nt_sec_desc.*\0" + "system.nt_sec_desc.*+\0" + ; + + if (size == 0) { + return sizeof(supported); + } + + if (sizeof(supported) > size) { + errno = ERANGE; + return -1; + } + + /* this can't be strcpy() because there are embedded null characters */ + memcpy(list, supported, sizeof(supported)); + return sizeof(supported); +} + + +/* + * Open a print file to be written to by other calls + */ + +static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) +{ + fstring server, share, user, password; + pstring path; + + if (!context || !context->internal || + !context->internal->_initialized) { + + errno = EINVAL; + return NULL; + + } + + if (!fname) { + + errno = EINVAL; + return NULL; + + } + + DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + /* What if the path is empty, or the file exists? */ + + return context->open(context, fname, O_WRONLY, 666); + +} + +/* + * Routine to print a file on a remote server ... + * + * We open the file, which we assume to be on a remote server, and then + * copy it to a print file on the share specified by printq. + */ + +static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq) +{ + SMBCFILE *fid1, *fid2; + int bytes, saverr, tot_bytes = 0; + char buf[4096]; + + if (!c_file || !c_file->internal->_initialized || !c_print || + !c_print->internal->_initialized) { + + errno = EINVAL; + return -1; + + } + + if (!fname && !printq) { + + errno = EINVAL; + return -1; + + } + + /* Try to open the file for reading ... */ + + if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { + + DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); + return -1; /* smbc_open sets errno */ + + } + + /* Now, try to open the printer file for writing */ + + if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { + + saverr = errno; /* Save errno */ + c_file->close(c_file, fid1); + errno = saverr; + return -1; + + } + + while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) { + + tot_bytes += bytes; + + if ((c_print->write(c_print, fid2, buf, bytes)) < 0) { + + saverr = errno; + c_file->close(c_file, fid1); + c_print->close(c_print, fid2); + errno = saverr; + + } + + } + + saverr = errno; + + c_file->close(c_file, fid1); /* We have to close these anyway */ + c_print->close(c_print, fid2); + + if (bytes < 0) { + + errno = saverr; + return -1; + + } + + return tot_bytes; + +} + +/* + * Routine to list print jobs on a printer share ... + */ + +static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn) +{ + SMBCSRV *srv; + fstring server, share, user, password, workgroup; + pstring path; + + if (!context || !context->internal || + !context->internal->_initialized) { + + errno = EINVAL; + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) fstrcpy(user, context->user); + + fstrcpy(workgroup, context->workgroup); + + srv = smbc_server(context, server, share, workgroup, user, password); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) { + + errno = smbc_errno(context, &srv->cli); + return -1; + + } + + return 0; + +} + +/* + * Delete a print job from a remote printer share + */ + +static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id) +{ + SMBCSRV *srv; + fstring server, share, user, password, workgroup; + pstring path; + int err; + + if (!context || !context->internal || + !context->internal->_initialized) { + + errno = EINVAL; + return -1; + + } + + if (!fname) { + + errno = EINVAL; + return -1; + + } + + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); + + smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + + if (user[0] == (char)0) fstrcpy(user, context->user); + + fstrcpy(workgroup, context->workgroup); + + srv = smbc_server(context, server, share, workgroup, user, password); + + if (!srv) { + + return -1; /* errno set by smbc_server */ + + } + + if ((err = cli_printjob_del(&srv->cli, id)) != 0) { + + if (err < 0) + errno = smbc_errno(context, &srv->cli); + else if (err == ERRnosuchprintjob) + errno = EINVAL; + return -1; + + } + + return 0; + +} + +/* + * Get a new empty handle to fill in with your own info + */ +SMBCCTX * smbc_new_context(void) +{ + SMBCCTX * context; + + context = malloc(sizeof(SMBCCTX)); + if (!context) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context); + + context->internal = malloc(sizeof(struct smbc_internal_data)); + if (!context->internal) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context->internal); + + + /* ADD REASONABLE DEFAULTS */ + context->debug = 0; + context->timeout = 20000; /* 20 seconds */ + + context->open = smbc_open_ctx; + context->creat = smbc_creat_ctx; + context->read = smbc_read_ctx; + context->write = smbc_write_ctx; + context->close = smbc_close_ctx; + context->unlink = smbc_unlink_ctx; + context->rename = smbc_rename_ctx; + context->lseek = smbc_lseek_ctx; + context->stat = smbc_stat_ctx; + context->fstat = smbc_fstat_ctx; + context->opendir = smbc_opendir_ctx; + context->closedir = smbc_closedir_ctx; + context->readdir = smbc_readdir_ctx; + context->getdents = smbc_getdents_ctx; + context->mkdir = smbc_mkdir_ctx; + context->rmdir = smbc_rmdir_ctx; + context->telldir = smbc_telldir_ctx; + context->lseekdir = smbc_lseekdir_ctx; + context->fstatdir = smbc_fstatdir_ctx; + context->chmod = smbc_chmod_ctx; + context->utimes = smbc_utimes_ctx; + context->setxattr = smbc_setxattr_ctx; + context->getxattr = smbc_getxattr_ctx; + context->removexattr = smbc_removexattr_ctx; + context->listxattr = smbc_listxattr_ctx; + context->open_print_job = smbc_open_print_job_ctx; + context->print_file = smbc_print_file_ctx; + context->list_print_jobs = smbc_list_print_jobs_ctx; + context->unlink_print_job = smbc_unlink_print_job_ctx; + + context->callbacks.check_server_fn = smbc_check_server; + context->callbacks.remove_unused_server_fn = smbc_remove_unused_server; + + smbc_default_cache_functions(context); + + return context; +} + +/* + * Free a context + * + * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed + * and thus you'll be leaking memory if not handled properly. + * + */ +int smbc_free_context(SMBCCTX * context, int shutdown_ctx) +{ + if (!context) { + errno = EBADF; + return 1; + } + + if (shutdown_ctx) { + SMBCFILE * f; + DEBUG(1,("Performing aggressive shutdown.\n")); + + f = context->internal->_files; + while (f) { + context->close(context, f); + f = f->next; + } + context->internal->_files = NULL; + + /* First try to remove the servers the nice way. */ + if (context->callbacks.purge_cached_fn(context)) { + SMBCSRV * s; + DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); + s = context->internal->_servers; + while (s) { + cli_shutdown(&s->cli); + context->callbacks.remove_cached_srv_fn(context, s); + SAFE_FREE(s); + s = s->next; + } + context->internal->_servers = NULL; + } + } + else { + /* This is the polite way */ + if (context->callbacks.purge_cached_fn(context)) { + DEBUG(1, ("Could not purge all servers, free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->internal->_servers) { + DEBUG(1, ("Active servers in context, free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->internal->_files) { + DEBUG(1, ("Active files in context, free_context failed.\n")); + errno = EBUSY; + return 1; + } + } + + /* Things we have to clean up */ + SAFE_FREE(context->workgroup); + SAFE_FREE(context->netbios_name); + SAFE_FREE(context->user); + + DEBUG(3, ("Context %p succesfully freed\n", context)); + SAFE_FREE(context->internal); + SAFE_FREE(context); + return 0; +} + + +/* + * Initialise the library etc + * + * We accept a struct containing handle information. + * valid values for info->debug from 0 to 100, + * and insist that info->fn must be non-null. + */ +SMBCCTX * smbc_init_context(SMBCCTX * context) +{ + pstring conf; + int pid; + char *user = NULL, *home = NULL; + + if (!context || !context->internal) { + errno = EBADF; + return NULL; + } + + /* Do not initialise the same client twice */ + if (context->internal->_initialized) { + return 0; + } + + if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) { + + errno = EINVAL; + return NULL; + + } + + if (!smbc_initialized) { + /* Do some library wide intialisations the first time we get called */ + + /* Set this to what the user wants */ + DEBUGLEVEL = context->debug; + + setup_logging( "libsmbclient", True); + + /* Here we would open the smb.conf file if needed ... */ + + home = getenv("HOME"); + + slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); + + load_interfaces(); /* Load the list of interfaces ... */ + + in_client = True; /* FIXME, make a param */ + + if (!lp_load(conf, True, False, False)) { + + /* + * Well, if that failed, try the dyn_CONFIGFILE + * Which points to the standard locn, and if that + * fails, silently ignore it and use the internal + * defaults ... + */ + + if (!lp_load(dyn_CONFIGFILE, True, False, False)) { + DEBUG(5, ("Could not load either config file: %s or %s\n", + conf, dyn_CONFIGFILE)); + } + } + + reopen_logs(); /* Get logging working ... */ + + /* + * Block SIGPIPE (from lib/util_sock.c: write()) + * It is not needed and should not stop execution + */ + BlockSignals(True, SIGPIPE); + + /* Done with one-time initialisation */ + smbc_initialized = 1; + + } + + if (!context->user) { + /* + * FIXME: Is this the best way to get the user info? + */ + user = getenv("USER"); + /* walk around as "guest" if no username can be found */ + if (!user) context->user = strdup("guest"); + else context->user = strdup(user); + } + + if (!context->netbios_name) { + /* + * We try to get our netbios name from the config. If that fails we fall + * back on constructing our netbios name from our hostname etc + */ + if (global_myname()) { + context->netbios_name = strdup(global_myname()); + } + else { + /* + * Hmmm, I want to get hostname as well, but I am too lazy for the moment + */ + pid = sys_getpid(); + context->netbios_name = malloc(17); + if (!context->netbios_name) { + errno = ENOMEM; + return NULL; + } + slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); + } + } + + DEBUG(1, ("Using netbios name %s.\n", context->netbios_name)); + + if (!context->workgroup) { + if (lp_workgroup()) { + context->workgroup = strdup(lp_workgroup()); + } + else { + /* TODO: Think about a decent default workgroup */ + context->workgroup = strdup("samba"); + } + } + + DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); + + /* shortest timeout is 1 second */ + if (context->timeout > 0 && context->timeout < 1000) + context->timeout = 1000; + + /* + * FIXME: Should we check the function pointers here? + */ + + context->internal->_initialized = 1; + + return context; } -- cgit From b0ead3a03da6af278731881260634ac9246d5e3b Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 24 Oct 2003 18:58:41 +0000 Subject: Apply latest of Derrell Lippman's changes to libsmbclient. (This used to be commit 84e620e5ba65c040df1c0ebdcf39fa5648dd37d9) --- source3/libsmb/libsmbclient.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index a11a965fde..735a3cba7c 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -610,15 +610,15 @@ SMBCSRV *smbc_server(SMBCCTX *context, * connection. This works similarly to smbc_server(). */ SMBCSRV *smbc_attr_server(SMBCCTX *context, - const char *server, const char *share, - fstring workgroup, - fstring username, fstring password) + const char *server, const char *share, + fstring workgroup, + fstring username, fstring password, + POLICY_HND *pol) { struct in_addr ip; struct cli_state *ipc_cli; NTSTATUS nt_status; SMBCSRV *ipc_srv=NULL; - POLICY_HND pol; /* * See if we've already created this special connection. Reference @@ -666,7 +666,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, ipc_cli->mem_ctx, True, GENERIC_EXECUTE_ACCESS, - &pol); + pol); if (!NT_STATUS_IS_OK(nt_status)) { errno = smbc_errno(context, ipc_cli); @@ -3362,7 +3362,8 @@ int smbc_setxattr_ctx(SMBCCTX *context, } ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password); + workgroup, user, password, + &pol); if (!ipc_srv) { return -1; } @@ -3493,7 +3494,8 @@ int smbc_getxattr_ctx(SMBCCTX *context, } ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password); + workgroup, user, password, + &pol); if (!ipc_srv) { return -1; } @@ -3575,13 +3577,15 @@ int smbc_removexattr_ctx(SMBCCTX *context, } ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password); + workgroup, user, password, + &pol); if (!ipc_srv) { return -1; } ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password); + workgroup, user, password, + &pol); if (!ipc_srv) { return -1; } -- cgit From 15b14fc8574b67e0661524e1d26a2f1561df0c39 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 25 Oct 2003 04:13:32 +0000 Subject: Put in a work-around for ENOTSUP not being defined on OpenBSD. (This used to be commit ca3d98d08bfe2c5c8a0f1a0d17160800f85d84b7) --- source3/libsmb/libsmbclient.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 735a3cba7c..21273ec431 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -40,7 +40,10 @@ #define CREATE_ACCESS_READ READ_CONTROL_ACCESS - +/*We should test for this in configure ... */ +#ifndef ENOTSUP +#define ENOTSUP EOPNOTSUPP +#endif /* * Functions exported by libsmb_cache.c that we need here -- cgit From 55f8ca432b60a8e85a6c68eaedaabf45615484af Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Mon, 27 Oct 2003 06:51:39 +0000 Subject: Remove some unused variables uncovered by the build farm. (This used to be commit 084e4678c0876ebd6e756192866103ae037f3258) --- source3/libsmb/libsmb_compat.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 4c96c41c56..cc23835ae3 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -115,9 +115,6 @@ static int del_fd(int fd) int smbc_init(smbc_get_auth_data_fn fn, int debug) { - int i; - struct smbc_compat_fdlist * f; - if (!smbc_compat_initialized) { statcont = smbc_new_context(); if (!statcont) -- cgit From 231124ced9237cdbc3732a722c8f373ee760927b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Oct 2003 21:28:00 +0000 Subject: Fixes to check for wraps which could cause coredumps. Jeremy. (This used to be commit ad06edd1bb58cc5e2c38a364b1af96a933b770af) --- source3/libsmb/clilist.c | 2 +- source3/libsmb/ntlmssp_parse.c | 7 +++---- 2 files changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 7822987ada..2c1831ae99 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -82,7 +82,7 @@ static int interpret_long_filename(struct cli_state *cli, case 260: /* NT uses this, but also accepts 2 */ { - int namelen, slen; + size_t namelen, slen; p += 4; /* next entry offset */ p += 4; /* fileindex */ diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 60cb4ab04a..b136dacf5a 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -226,7 +226,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, *ps = smb_xstrdup(""); } else { /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } if (len1 & 1) { @@ -255,7 +255,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if (len1 == 0 && len2 == 0) { *ps = smb_xstrdup(""); } else { - if (len1 != len2 || ptr + len1 > blob->length) { + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } @@ -280,7 +280,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, *b = data_blob(NULL, 0); } else { /* make sure its in the right format - be strict */ - if (len1 != len2 || ptr + len1 > blob->length) { + if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } *b = data_blob(blob->data + ptr, len1); @@ -314,4 +314,3 @@ BOOL msrpc_parse(const DATA_BLOB *blob, return True; } - -- cgit From fbb8f131c2336e921677f41e9fb8bce7406f3336 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 3 Nov 2003 14:34:25 +0000 Subject: Fix more 64-bit printf warnings. (This used to be commit 23443e3aa079710221557e18158d0ddb8ff48a36) --- source3/libsmb/ntlmssp_sign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index ff2f97c2e8..153c234d1f 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -169,8 +169,8 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, NTSTATUS nt_status; if (sig->length < 8) { - DEBUG(0, ("NTLMSSP packet check failed due to short signature (%u bytes)!\n", - sig->length)); + DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n", + (unsigned long)sig->length)); } nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, -- cgit From f581234a7a977632c117c5c61939bfba87053431 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Nov 2003 00:17:14 +0000 Subject: Fix coredump in cli_get_backup_list. Jeremy. (This used to be commit 29413db303d30d28c2fb0cc6e6e963e725ad4101) --- source3/libsmb/clidgram.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 5ab6bef87b..c4675f1938 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -75,7 +75,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot, SSVAL(ptr,smb_vwv15,1); SSVAL(ptr,smb_vwv16,2); p2 = smb_buf(ptr); - pstrcpy(p2,mailslot); + fstrcpy(p2,mailslot); p2 = skip_string(p2,1); memcpy(p2,buf,len); @@ -135,7 +135,7 @@ static char cli_backup_list[1024]; int cli_get_backup_list(const char *myname, const char *send_to_name) { - char outbuf[15]; + pstring outbuf; char *p; struct in_addr sendto_ip, my_ip; int dgram_sock; @@ -262,6 +262,3 @@ int cli_get_backup_server(char *my_name, char *target, char *servername, int nam return True; } - - - -- cgit From 4f65a3bd0356dfbf295418790b795f1774d6c520 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 22 Nov 2003 06:15:28 +0000 Subject: adding a useful debug (This used to be commit e374ce779efaec001c1476e0710ceaa9c3b84e8d) --- source3/libsmb/trusts_util.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index c18641bc84..2c6eb1b55a 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -181,6 +181,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, done: /* cleanup */ if (cli) { + DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n")); cli_nt_session_close( cli ); cli_shutdown( cli ); } -- cgit From fcbfc7ad0669009957c65fa61bb20df75a9701b4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:19:38 +0000 Subject: Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... (This used to be commit f3bbc87b0dac63426cda6fac7a295d3aad810ecc) --- source3/libsmb/cliconnect.c | 99 ++++-- source3/libsmb/clientgen.c | 5 +- source3/libsmb/clikrb5.c | 16 +- source3/libsmb/clispnego.c | 2 +- source3/libsmb/ntlmssp.c | 741 +++++++++++++++++++++++++++-------------- source3/libsmb/ntlmssp_parse.c | 33 +- source3/libsmb/ntlmssp_sign.c | 126 ++++--- source3/libsmb/smb_signing.c | 26 +- source3/libsmb/smbencrypt.c | 6 +- 9 files changed, 671 insertions(+), 383 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b5f7b97ae8..a920a1b7ff 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -241,9 +241,16 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -static void set_cli_session_key (struct cli_state *cli, DATA_BLOB session_key) +/** + * Set the user session key for a connection + * @param cli The cli structure to add it too + * @param session_key The session key used. (A copy of this is taken for the cli struct) + * + */ + +static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) { - memcpy(cli->user_session_key, session_key.data, MIN(session_key.length, sizeof(cli->user_session_key))); + cli->user_session_key = data_blob(session_key.data, session_key.length); } /**************************************************************************** @@ -311,7 +318,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - cli_simple_set_signing(cli, session_key.data, nt_response); + cli_simple_set_signing(cli, session_key, nt_response); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -373,14 +380,16 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, if (session_key.data) { /* Have plaintext orginal */ - set_cli_session_key(cli, session_key); + cli_set_session_key(cli, session_key); } ret = True; end: data_blob_free(&lm_response); data_blob_free(&nt_response); - data_blob_free(&session_key); + + if (!ret) + data_blob_free(&session_key); return ret; } @@ -484,19 +493,19 @@ static void use_in_memory_ccache(void) { Do a spnego/kerberos encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) +static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; - unsigned char session_key_krb5[16]; + DATA_BLOB session_key_krb5; DATA_BLOB null_blob = data_blob(NULL, 0); DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(principal, 0, session_key_krb5); + negTokenTarg = spnego_gen_negTokenTarg(principal, 0, &session_key_krb5); if (!negTokenTarg.data) - return False; + return NT_STATUS_UNSUCCESSFUL; #if 0 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); @@ -509,9 +518,16 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi /* we don't need this blob for kerberos */ data_blob_free(&blob2); + cli_set_session_key(cli, session_key_krb5); + data_blob_free(&negTokenTarg); - return !cli_is_error(cli); + if (cli_is_error(cli)) { + if (NT_STATUS_IS_OK(cli_nt_error(cli))) { + return NT_STATUS_UNSUCCESSFUL; + } + } + return NT_STATUS_OK; } #endif /* HAVE_KRB5 */ @@ -520,10 +536,10 @@ static BOOL cli_session_setup_kerberos(struct cli_state *cli, const char *princi Do a spnego/NTLMSSP encrypted session setup. ****************************************************************************/ -static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, +static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, const char *pass, const char *workgroup) { - struct ntlmssp_client_state *ntlmssp_state; + struct ntlmssp_state *ntlmssp_state; NTSTATUS nt_status; int turn = 1; DATA_BLOB msg1; @@ -534,21 +550,21 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, cli_temp_set_signing(cli); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { - return False; + return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { - return False; + return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, workgroup))) { - return False; + return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { - return False; + return nt_status; } do { - nt_status = ntlmssp_client_update(ntlmssp_state, + nt_status = ntlmssp_update(ntlmssp_state, blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { @@ -562,18 +578,27 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, } cli_simple_set_signing(cli, - ntlmssp_state->session_key.data, + data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length), null_blob); /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { - return False; + DEBUG(3, ("Failed to send NTLMSSP/SPENGO blob to server!\n")); + nt_status = NT_STATUS_UNSUCCESSFUL; + } else { + data_blob_free(&msg1); + + blob = cli_session_setup_blob_receive(cli); + + nt_status = cli_nt_error(cli); + if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) { + if (cli->smb_rw_error == READ_BAD_SIG) { + nt_status = NT_STATUS_ACCESS_DENIED; + } else { + nt_status = NT_STATUS_UNSUCCESSFUL; + } + } } - data_blob_free(&msg1); - - blob = cli_session_setup_blob_receive(cli); - - nt_status = cli_nt_error(cli); } if (!blob.length) { @@ -606,24 +631,22 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, if (NT_STATUS_IS_OK(nt_status)) { fstrcpy(cli->server_domain, ntlmssp_state->server_domain); - set_cli_session_key(cli, ntlmssp_state->session_key); + cli_set_session_key(cli, ntlmssp_state->session_key); } /* we have a reference conter on ntlmssp_state, if we are signing then the state will be kept by the signing engine */ - if (!NT_STATUS_IS_OK(ntlmssp_client_end(&ntlmssp_state))) { - return False; - } - - return (NT_STATUS_IS_OK(nt_status)); + ntlmssp_end(&ntlmssp_state); + + return nt_status; } /**************************************************************************** Do a spnego encrypted session setup. ****************************************************************************/ -BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, +NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, const char *pass, const char *workgroup) { char *principal; @@ -651,7 +674,7 @@ BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, reply */ if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { data_blob_free(&blob); - return False; + return NT_STATUS_INVALID_PARAMETER; } data_blob_free(&blob); @@ -681,7 +704,7 @@ BOOL cli_session_setup_spnego(struct cli_state *cli, const char *user, if (ret){ DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); - return False; + return NT_STATUS_LOGON_FAILURE; } } @@ -773,8 +796,14 @@ BOOL cli_session_setup(struct cli_state *cli, /* if the server supports extended security then use SPNEGO */ - if (cli->capabilities & CAP_EXTENDED_SECURITY) - return cli_session_setup_spnego(cli, user, pass, workgroup); + if (cli->capabilities & CAP_EXTENDED_SECURITY) { + NTSTATUS nt_status; + if (!NT_STATUS_IS_OK(nt_status = cli_session_setup_spnego(cli, user, pass, workgroup))) { + DEBUG(3, ("SPENGO login failed: %s\n", get_friendly_nt_error_msg(nt_status))); + return False; + } + return True; + } /* otherwise do a NT1 style session setup */ diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9b54acf775..0873700fc0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -339,7 +339,7 @@ close the session void cli_nt_session_close(struct cli_state *cli) { if (cli->ntlmssp_pipe_state) { - ntlmssp_client_end(&cli->ntlmssp_pipe_state); + ntlmssp_end(&cli->ntlmssp_pipe_state); } if (cli->nt_pipe_fnum != 0) @@ -375,9 +375,10 @@ void cli_close_connection(struct cli_state *cli) cli_free_signing_context(cli); data_blob_free(&cli->secblob); + data_blob_free(&cli->user_session_key); if (cli->ntlmssp_pipe_state) - ntlmssp_client_end(&cli->ntlmssp_pipe_state); + ntlmssp_end(&cli->ntlmssp_pipe_state); if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 1fccc04a01..5568b5e033 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -307,7 +307,7 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16]) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5) { krb5_error_code retval; krb5_data packet; @@ -369,7 +369,7 @@ failed: return data_blob(NULL, 0); } - BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, uint8 session_key[16], BOOL remote) + BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) { krb5_keyblock *skey; krb5_error_code err; @@ -383,11 +383,11 @@ failed: err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); if (err == 0 && skey != NULL) { DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); - if (KRB5_KEY_LENGTH(skey) == 16) { - memcpy(session_key, KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); - dump_data_pw("KRB5 Session Key:\n", session_key, 16); - ret = True; - } + *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + + ret = True; + krb5_free_keyblock(context, skey); } else { DEBUG(10, ("KRB5 error getting session key %d\n", err)); @@ -410,7 +410,7 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, unsigned char session_key_krb5[16]) +DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return data_blob(NULL, 0); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 63076a1a1c..92543736ff 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -323,7 +323,7 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16]) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *session_key_krb5) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index c51b599b04..a0da1efcc1 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -23,6 +23,35 @@ #include "includes.h" +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB reply, DATA_BLOB *next_request); +static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB in, DATA_BLOB *out); +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB reply, DATA_BLOB *next_request); +static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, + const DATA_BLOB request, DATA_BLOB *reply); + +/** + * Callbacks for NTLMSSP - for both client and server operating modes + * + */ + +static const struct ntlmssp_callbacks { + enum NTLMSSP_ROLE role; + enum NTLM_MESSAGE_TYPE ntlmssp_command; + NTSTATUS (*fn)(struct ntlmssp_state *ntlmssp_state, + DATA_BLOB in, DATA_BLOB *out); +} ntlmssp_callbacks[] = { + {NTLMSSP_CLIENT, NTLMSSP_INITIAL, ntlmssp_client_initial}, + {NTLMSSP_SERVER, NTLMSSP_NEGOTIATE, ntlmssp_server_negotiate}, + {NTLMSSP_CLIENT, NTLMSSP_CHALLENGE, ntlmssp_client_challenge}, + {NTLMSSP_SERVER, NTLMSSP_AUTH, ntlmssp_server_auth}, + {NTLMSSP_CLIENT, NTLMSSP_UNKNOWN, NULL}, + {NTLMSSP_SERVER, NTLMSSP_UNKNOWN, NULL} +}; + + /** * Print out the NTLMSSP flags for debugging * @param neg_flags The flags from the packet @@ -71,7 +100,7 @@ void debug_ntlmssp_flags(uint32 neg_flags) * */ -static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) +static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state) { static uchar chal[8]; generate_random_buffer(chal, sizeof(chal), False); @@ -79,6 +108,188 @@ static const uint8 *get_challenge(struct ntlmssp_state *ntlmssp_state) return chal; } +/** + * Default 'we can set the challenge to anything we like' implementation + * + */ + +static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state) +{ + return True; +} + +/** + * Default 'we can set the challenge to anything we like' implementation + * + * Does not actually do anything, as the value is always in the structure anyway. + * + */ + +static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) +{ + SMB_ASSERT(challenge->length == 8); + return NT_STATUS_OK; +} + +/** + * Set a username on an NTLMSSP context - ensures it is talloc()ed + * + */ + +NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) +{ + ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); + if (!ntlmssp_state->user) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a password on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) +{ + if (!password) { + ntlmssp_state->password = NULL; + } else { + ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); + if (!ntlmssp_state->password) { + return NT_STATUS_NO_MEMORY; + } + } + return NT_STATUS_OK; +} + +/** + * Set a domain on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) +{ + ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Set a workstation on an NTLMSSP context - ensures it is talloc()ed + * + */ +NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) +{ + ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation); + if (!ntlmssp_state->domain) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Store a DATA_BLOB containing an NTLMSSP response, for use later. + * This copies the data blob + */ + +NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, + DATA_BLOB response) +{ + ntlmssp_state->stored_response = data_blob_talloc(ntlmssp_state->mem_ctx, + response.data, response.length); + return NT_STATUS_OK; +} + +/** + * Next state function for the NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State + * @param in The packet in from the NTLMSSP partner, as a DATA_BLOB + * @param out The reply, as an allocated DATA_BLOB, caller to free. + * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. + */ + +NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, + const DATA_BLOB in, DATA_BLOB *out) +{ + DATA_BLOB input; + uint32 ntlmssp_command; + int i; + + *out = data_blob(NULL, 0); + + if (!in.length && ntlmssp_state->stored_response.length) { + input = ntlmssp_state->stored_response; + + /* we only want to read the stored response once - overwrite it */ + ntlmssp_state->stored_response = data_blob(NULL, 0); + } else { + input = in; + } + + if (!input.length) { + switch (ntlmssp_state->role) { + case NTLMSSP_CLIENT: + ntlmssp_command = NTLMSSP_INITIAL; + break; + case NTLMSSP_SERVER: + /* 'datagram' mode - no neg packet */ + ntlmssp_command = NTLMSSP_NEGOTIATE; + break; + } + } else { + if (!msrpc_parse(&input, "Cd", + "NTLMSSP", + &ntlmssp_command)) { + DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); + dump_data(2, (const char *)input.data, input.length); + return NT_STATUS_INVALID_PARAMETER; + } + } + + if (ntlmssp_command != ntlmssp_state->expected_state) { + DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); + return NT_STATUS_INVALID_PARAMETER; + } + + for (i=0; ntlmssp_callbacks[i].fn; i++) { + if (ntlmssp_callbacks[i].role == ntlmssp_state->role + && ntlmssp_callbacks[i].ntlmssp_command == ntlmssp_command) { + return ntlmssp_callbacks[i].fn(ntlmssp_state, input, out); + } + } + + DEBUG(1, ("failed to find NTLMSSP callback for NTLMSSP mode %u, command %u\n", + ntlmssp_state->role, ntlmssp_command)); + + return NT_STATUS_INVALID_PARAMETER; +} + +/** + * End an NTLMSSP state machine + * + * @param ntlmssp_state NTLMSSP State, free()ed by this function + */ + +void ntlmssp_end(NTLMSSP_STATE **ntlmssp_state) +{ + TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; + + (*ntlmssp_state)->ref_count--; + + if ((*ntlmssp_state)->ref_count == 0) { + data_blob_free(&(*ntlmssp_state)->chal); + data_blob_free(&(*ntlmssp_state)->lm_resp); + data_blob_free(&(*ntlmssp_state)->nt_resp); + + talloc_destroy(mem_ctx); + } + + *ntlmssp_state = NULL; + return; +} + /** * Determine correct target name flags for reply, given server role * and negotiated flags @@ -107,6 +318,46 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, } } +static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, + uint32 neg_flags, BOOL allow_lm) { + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; + ntlmssp_state->unicode = True; + } else { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; + ntlmssp_state->unicode = False; + } + + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY && allow_lm) { + /* other end forcing us to use LM */ + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; + ntlmssp_state->use_ntlmv2 = False; + } else { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; + } + + if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { + ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; + } + +} + + /** * Next state function for the Negotiate packet * @@ -150,31 +401,27 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, debug_ntlmssp_flags(neg_flags); } - cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); + ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); - data_blob_free(&ntlmssp_state->chal); - ntlmssp_state->chal = data_blob(cryptkey, 8); - - /* Give them the challenge. For now, ignore neg_flags and just - return the flags we want. Obviously this is not correct */ - - chal_flags = - NTLMSSP_NEGOTIATE_128 | - NTLMSSP_NEGOTIATE_NTLM; - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { - chal_flags |= NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->unicode = True; - } else { - chal_flags |= NTLMSSP_NEGOTIATE_OEM; - } + chal_flags = ntlmssp_state->neg_flags; target_name = ntlmssp_target_name(ntlmssp_state, neg_flags, &chal_flags); - - if (target_name == NULL) + if (target_name == NULL) return NT_STATUS_INVALID_PARAMETER; + /* Ask our caller what challenge they would like in the packet */ + cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); + + /* Check if we may set the challenge */ + if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; + } + + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); + ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); + + /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; get_mydomname(dnsdomname); @@ -184,6 +431,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, get_myfullname(dnsname); strlower_m(dnsname); + /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { const char *target_name_dns = ""; @@ -194,16 +442,17 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, } msrpc_gen(&struct_blob, "aaaaa", - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN, target_name, - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_DOMAIN_DNS, target_name_dns, - ntlmssp_state->unicode, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsdomname, - ntlmssp_state->unicode, 0, ""); + NTLMSSP_NAME_TYPE_DOMAIN, target_name, + NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), + NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname, + NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, + 0, ""); } else { struct_blob = data_blob(NULL, 0); } { + /* Marshel the packet in the right format, be it unicode or ASCII */ const char *gen_string; if (ntlmssp_state->unicode) { gen_string = "CdUdbddB"; @@ -240,13 +489,27 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) { - DATA_BLOB sess_key; - uint32 ntlmssp_command, neg_flags; + DATA_BLOB encrypted_session_key = data_blob(NULL, 0); + DATA_BLOB nt_session_key = data_blob(NULL, 0); + DATA_BLOB lm_session_key = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob(NULL, 0); + uint32 ntlmssp_command, auth_flags; NTSTATUS nt_status; + /* used by NTLM2 */ + BOOL doing_ntlm2 = False; + + uchar session_nonce[16]; + uchar session_nonce_hash[16]; + const char *parse_string; + char *domain = NULL; + char *user = NULL; + char *workstation = NULL; /* parse the NTLMSSP packet */ + *reply = data_blob(NULL, 0); + #if 0 file_save("ntlmssp_auth.dat", request.data, request.length); #endif @@ -260,9 +523,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&ntlmssp_state->lm_resp); data_blob_free(&ntlmssp_state->nt_resp); - SAFE_FREE(ntlmssp_state->user); - SAFE_FREE(ntlmssp_state->domain); - SAFE_FREE(ntlmssp_state->workstation); + ntlmssp_state->user = NULL; + ntlmssp_state->domain = NULL; + ntlmssp_state->workstation = NULL; /* now the NTLMSSP encoded auth hashes */ if (!msrpc_parse(&request, parse_string, @@ -270,18 +533,73 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &ntlmssp_command, &ntlmssp_state->lm_resp, &ntlmssp_state->nt_resp, - &ntlmssp_state->domain, - &ntlmssp_state->user, - &ntlmssp_state->workstation, - &sess_key, - &neg_flags)) { + &domain, + &user, + &workstation, + &encrypted_session_key, + &auth_flags)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); dump_data(2, (const char *)request.data, request.length); - return NT_STATUS_INVALID_PARAMETER; + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + auth_flags = 0; + + /* Try again with a shorter string (Win9X truncates this packet) */ + if (ntlmssp_state->unicode) { + parse_string = "CdBBUUU"; + } else { + parse_string = "CdBBAAA"; + } + + /* now the NTLMSSP encoded auth hashes */ + if (!msrpc_parse(&request, parse_string, + "NTLMSSP", + &ntlmssp_command, + &ntlmssp_state->lm_resp, + &ntlmssp_state->nt_resp, + &domain, + &user, + &workstation)) { + DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); + dump_data(2, (const char *)request.data, request.length); + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + + return NT_STATUS_INVALID_PARAMETER; + } } - data_blob_free(&sess_key); - + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_workstation(ntlmssp_state, workstation))) { + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + data_blob_free(&encrypted_session_key); + return nt_status; + } + + SAFE_FREE(domain); + SAFE_FREE(user); + SAFE_FREE(workstation); + DEBUG(3,("Got user=[%s] domain=[%s] workstation=[%s] len1=%lu len2=%lu\n", ntlmssp_state->user, ntlmssp_state->domain, ntlmssp_state->workstation, (unsigned long)ntlmssp_state->lm_resp.length, (unsigned long)ntlmssp_state->nt_resp.length)); @@ -290,9 +608,98 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, file_save("lmhash1.dat", &ntlmssp_state->lm_resp.data, &ntlmssp_state->lm_resp.length); #endif - nt_status = ntlmssp_state->check_password(ntlmssp_state); + /* NTLM2 uses a 'challenge' that is made of up both the server challenge, and a + client challenge - *reply = data_blob(NULL, 0); + However, the NTLM2 flag may still be set for the real NTLMv2 logins, be careful. + */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + if (ntlmssp_state->nt_resp.length == 24 && ntlmssp_state->lm_resp.length == 24) { + struct MD5Context md5_session_nonce_ctx; + SMB_ASSERT(ntlmssp_state->internal_chal.data && ntlmssp_state->internal_chal.length == 8); + + doing_ntlm2 = True; + + memcpy(session_nonce, ntlmssp_state->internal_chal.data, 8); + memcpy(&session_nonce[8], ntlmssp_state->lm_resp.data, 8); + + MD5Init(&md5_session_nonce_ctx); + MD5Update(&md5_session_nonce_ctx, session_nonce, 16); + MD5Final(session_nonce_hash, &md5_session_nonce_ctx); + + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, session_nonce_hash, 8); + + /* LM response is no longer useful */ + data_blob_free(&ntlmssp_state->lm_resp); + + /* We changed the effective challenge - set it */ + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->set_challenge(ntlmssp_state, &ntlmssp_state->chal))) { + data_blob_free(&encrypted_session_key); + return nt_status; + } + } + } + + /* Finally, actually ask if the password is OK */ + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) { + data_blob_free(&encrypted_session_key); + return nt_status; + } + + dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length); + dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length); + + /* Handle the different session key derivation for NTLM2 */ + if (doing_ntlm2) { + if (nt_session_key.data && nt_session_key.length == 16) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + hmac_md5(nt_session_key.data, session_nonce, + sizeof(session_nonce), session_key.data); + dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); + + } + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + if (lm_session_key.data && lm_session_key.length >= 8 && + ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, + session_key.data); + dump_data_pw("LM session key:\n", session_key.data, session_key.length); + } + } else if (nt_session_key.data) { + session_key = nt_session_key; + dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } + + /* With KEY_EXCH, the client supplies the proposed session key, + but encrypts it with the long-term key */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + if (!encrypted_session_key.data || encrypted_session_key.length != 16) { + data_blob_free(&encrypted_session_key); + DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", + encrypted_session_key.length)); + return NT_STATUS_INVALID_PARAMETER; + } else if (!session_key.data || session_key.length != 16) { + DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", + session_key.length)); + } else { + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); + SamOEMhash(encrypted_session_key.data, + session_key.data, + encrypted_session_key.length); + ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, + encrypted_session_key.data, + encrypted_session_key.length); + dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length); + } + } else { + ntlmssp_state->session_key = session_key; + } + + data_blob_free(&encrypted_session_key); + + /* allow arbitarily many authentications */ + ntlmssp_state->expected_state = NTLMSSP_AUTH; return nt_status; } @@ -316,8 +723,12 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) return NT_STATUS_NO_MEMORY; } + (*ntlmssp_state)->role = NTLMSSP_SERVER; + (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_challenge = get_challenge; + (*ntlmssp_state)->set_challenge = set_challenge; + (*ntlmssp_state)->may_set_challenge = may_set_challenge; (*ntlmssp_state)->get_global_myname = global_myname; (*ntlmssp_state)->get_domain = lp_workgroup; @@ -325,73 +736,18 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->expected_state = NTLMSSP_NEGOTIATE; - return NT_STATUS_OK; -} - -/** - * End an NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State, free()ed by this function - */ - -NTSTATUS ntlmssp_server_end(NTLMSSP_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); + (*ntlmssp_state)->ref_count = 1; - SAFE_FREE((*ntlmssp_state)->user); - SAFE_FREE((*ntlmssp_state)->domain); - SAFE_FREE((*ntlmssp_state)->workstation); + (*ntlmssp_state)->neg_flags = + NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_NTLM | + NTLMSSP_NEGOTIATE_NTLM2 | + NTLMSSP_NEGOTIATE_KEY_EXCH | + NTLMSSP_NEGOTIATE_SIGN; - talloc_destroy(mem_ctx); - *ntlmssp_state = NULL; return NT_STATUS_OK; } -/** - * Next state function for the NTLMSSP state machine - * - * @param ntlmssp_state NTLMSSP State - * @param request The request, as a DATA_BLOB - * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors, NT_STATUS_MORE_PROCESSING_REQUIRED or NT_STATUS_OK. - */ - -NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, - const DATA_BLOB request, DATA_BLOB *reply) -{ - uint32 ntlmssp_command; - *reply = data_blob(NULL, 0); - - if (request.length) { - if (!msrpc_parse(&request, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_INVALID_PARAMETER; - } - } else { - /* 'datagram' mode - no neg packet */ - ntlmssp_command = NTLMSSP_NEGOTIATE; - } - - if (ntlmssp_command != ntlmssp_state->expected_state) { - DEBUG(1, ("got NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); - return NT_STATUS_INVALID_PARAMETER; - } - - if (ntlmssp_command == NTLMSSP_NEGOTIATE) { - return ntlmssp_server_negotiate(ntlmssp_state, request, reply); - } else if (ntlmssp_command == NTLMSSP_AUTH) { - return ntlmssp_server_auth(ntlmssp_state, request, reply); - } else { - DEBUG(1, ("unknown NTLMSSP command %u, expected %u\n", ntlmssp_command, ntlmssp_state->expected_state)); - return NT_STATUS_INVALID_PARAMETER; - } -} - /********************************************************************* Client side NTLMSSP *********************************************************************/ @@ -405,11 +761,13 @@ NTSTATUS ntlmssp_server_update(NTLMSSP_STATE *ntlmssp_state, * @return Errors or NT_STATUS_OK. */ -static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_state, +static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, DATA_BLOB reply, DATA_BLOB *next_request) { if (ntlmssp_state->unicode) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; + } else { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; } if (ntlmssp_state->use_ntlmv2) { @@ -426,6 +784,8 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat ntlmssp_state->get_domain(), ntlmssp_state->get_global_myname()); + ntlmssp_state->expected_state = NTLMSSP_CHALLENGE; + return NT_STATUS_MORE_PROCESSING_REQUIRED; } @@ -438,7 +798,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_client_state *ntlmssp_stat * @return Errors or NT_STATUS_OK. */ -static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_state, +static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB reply, DATA_BLOB *next_request) { uint32 chal_flags, ntlmssp_command, unkn1, unkn2; @@ -469,17 +829,16 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st DEBUG(3, ("Got challenge flags:\n")); debug_ntlmssp_flags(chal_flags); - if (chal_flags & NTLMSSP_NEGOTIATE_UNICODE) { + ntlmssp_handle_neg_flags(ntlmssp_state, chal_flags, lp_client_lanman_auth()); + + if (ntlmssp_state->unicode) { if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { chal_parse_string = "CdUdbddB"; } else { chal_parse_string = "CdUdbdd"; } auth_gen_string = "CdBBUUUBd"; - ntlmssp_state->unicode = True; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; - } else if (chal_flags & NTLMSSP_NEGOTIATE_OEM) { + } else { if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { chal_parse_string = "CdAdbddB"; } else { @@ -487,32 +846,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st } auth_gen_string = "CdBBAAABd"; - - ntlmssp_state->unicode = False; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_UNICODE; - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_OEM; - } else { - return NT_STATUS_INVALID_PARAMETER; - } - - if (chal_flags & NTLMSSP_NEGOTIATE_LM_KEY && lp_client_lanman_auth()) { - /* server forcing us to use LM */ - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; - ntlmssp_state->use_ntlmv2 = False; - } else { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; - } - - if (!(chal_flags & NTLMSSP_NEGOTIATE_NTLM2)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - } - - if (!(chal_flags & NTLMSSP_NEGOTIATE_128)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; - } - - if (!(chal_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; } DEBUG(3, ("NTLMSSP: Set final flags:\n")); @@ -546,6 +879,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st if (!struct_blob.length) { /* be lazy, match win2k - we can't do NTLMv2 without it */ + DEBUG(1, ("Server did not provide 'target information', required for NTLMv2\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -569,7 +903,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st uchar nt_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); - lm_response = data_blob(NULL, 24); + lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); generate_random_buffer(lm_response.data, 8, False); memset(lm_response.data+8, 0, 16); @@ -580,16 +914,21 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st MD5Update(&md5_session_nonce_ctx, challenge_blob.data, 8); MD5Update(&md5_session_nonce_ctx, lm_response.data, 8); MD5Final(session_nonce_hash, &md5_session_nonce_ctx); + + DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); + DEBUG(5, ("challenge is: \n")); + dump_data(5, session_nonce_hash, 8); - nt_response = data_blob(NULL, 24); + nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password, session_nonce_hash, nt_response.data); - session_key = data_blob(NULL, 16); + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key); hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data); + dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { @@ -600,22 +939,24 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st /* lanman auth is insecure, it may be disabled */ if (lp_client_lanman_auth()) { - lm_response = data_blob(NULL, 24); + lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBencrypt(ntlmssp_state->password,challenge_blob.data, lm_response.data); - } + } - nt_response = data_blob(NULL, 24); + nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, nt_response.data); - session_key = data_blob(NULL, 16); + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && lp_client_lanman_auth()) { SMBsesskeygen_lmv1(lm_hash, lm_response.data, session_key.data); + dump_data_pw("LM session key\n", session_key.data, session_key.length); } else { SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + dump_data_pw("NT session key:\n", session_key.data, session_key.length); } } data_blob_free(&struct_blob); @@ -627,9 +968,12 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st generate_random_buffer(client_session_key, sizeof(client_session_key), False); encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); + dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); + SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); data_blob_free(&session_key); - session_key = data_blob(client_session_key, sizeof(client_session_key)); + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); } /* this generates the actual auth packet */ @@ -644,28 +988,24 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_client_state *ntlmssp_st encrypted_session_key.data, encrypted_session_key.length, ntlmssp_state->neg_flags)) { - data_blob_free(&lm_response); - data_blob_free(&nt_response); - data_blob_free(&session_key); return NT_STATUS_NO_MEMORY; } data_blob_free(&encrypted_session_key); data_blob_free(&ntlmssp_state->chal); - data_blob_free(&ntlmssp_state->lm_resp); - data_blob_free(&ntlmssp_state->nt_resp); - data_blob_free(&ntlmssp_state->session_key); ntlmssp_state->chal = challenge_blob; ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; ntlmssp_state->session_key = session_key; + ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; + return NT_STATUS_MORE_PROCESSING_REQUIRED; } -NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) +NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) { TALLOC_CTX *mem_ctx; @@ -678,6 +1018,8 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) return NT_STATUS_NO_MEMORY; } + (*ntlmssp_state)->role = NTLMSSP_CLIENT; + (*ntlmssp_state)->mem_ctx = mem_ctx; (*ntlmssp_state)->get_global_myname = global_myname; @@ -687,6 +1029,10 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) (*ntlmssp_state)->use_ntlmv2 = lp_client_ntlmv2_auth(); + (*ntlmssp_state)->expected_state = NTLMSSP_INITIAL; + + (*ntlmssp_state)->ref_count = 1; + (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_NTLM | @@ -700,101 +1046,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_CLIENT_STATE **ntlmssp_state) NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_REQUEST_TARGET; - (*ntlmssp_state)->ref_count = 1; - - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_client_end(NTLMSSP_CLIENT_STATE **ntlmssp_state) -{ - TALLOC_CTX *mem_ctx = (*ntlmssp_state)->mem_ctx; - - (*ntlmssp_state)->ref_count--; - - if ((*ntlmssp_state)->ref_count == 0) { - data_blob_free(&(*ntlmssp_state)->chal); - data_blob_free(&(*ntlmssp_state)->lm_resp); - data_blob_free(&(*ntlmssp_state)->nt_resp); - data_blob_free(&(*ntlmssp_state)->session_key); - data_blob_free(&(*ntlmssp_state)->stored_response); - talloc_destroy(mem_ctx); - } - - *ntlmssp_state = NULL; return NT_STATUS_OK; } -NTSTATUS ntlmssp_client_update(NTLMSSP_CLIENT_STATE *ntlmssp_state, - DATA_BLOB reply, DATA_BLOB *next_request) -{ - NTSTATUS nt_status = NT_STATUS_INVALID_PARAMETER; - uint32 ntlmssp_command; - *next_request = data_blob(NULL, 0); - - if (!reply.length) { - /* If there is a cached reply, use it - otherwise this is the first packet */ - if (!ntlmssp_state->stored_response.length) { - return ntlmssp_client_initial(ntlmssp_state, reply, next_request); - } - - reply = ntlmssp_state->stored_response; - } - - if (!msrpc_parse(&reply, "Cd", - "NTLMSSP", - &ntlmssp_command)) { - return NT_STATUS_INVALID_PARAMETER; - } - - if (ntlmssp_command == NTLMSSP_CHALLENGE) { - nt_status = ntlmssp_client_challenge(ntlmssp_state, reply, next_request); - } - if (ntlmssp_state->stored_response.length) { - data_blob_free(&ntlmssp_state->stored_response); - } - return nt_status; -} - -NTSTATUS ntlmssp_set_username(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *user) -{ - ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); - if (!ntlmssp_state->user) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_set_password(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *password) -{ - if (!password) { - ntlmssp_state->password = NULL; - } else { - ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); - if (!ntlmssp_state->password) { - return NT_STATUS_NO_MEMORY; - } - } - return NT_STATUS_OK; -} - -NTSTATUS ntlmssp_set_domain(NTLMSSP_CLIENT_STATE *ntlmssp_state, const char *domain) -{ - ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); - if (!ntlmssp_state->domain) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} - -/** - * Store a DATA_BLOB containing an NTLMSSP response, for use later. - * This 'keeps' the data blob - the caller must *not* free it. - */ - -NTSTATUS ntlmssp_client_store_response(NTLMSSP_CLIENT_STATE *ntlmssp_state, - DATA_BLOB response) -{ - data_blob_free(&ntlmssp_state->stored_response); - ntlmssp_state->stored_response = response; - return NT_STATUS_OK; -} diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index b136dacf5a..3444db0306 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -31,7 +31,7 @@ format specifiers are: U = unicode string (input is unix string) - a = address (input is BOOL unicode, char *unix_string) + a = address (input is char *unix_string) (1 byte type, 1 byte length, unicode/ASCII string, all inline) A = ASCII string (input is unix string) B = data blob (pointer + length) @@ -49,7 +49,6 @@ BOOL msrpc_gen(DATA_BLOB *blob, uint8 *b; int head_size=0, data_size=0; int head_ofs, data_ofs; - BOOL unicode; /* first scan the format to work out the header and body size */ va_start(ap, format); @@ -66,14 +65,9 @@ BOOL msrpc_gen(DATA_BLOB *blob, data_size += str_ascii_charnum(s); break; case 'a': - unicode = va_arg(ap, BOOL); n = va_arg(ap, int); s = va_arg(ap, char *); - if (unicode) { - data_size += (str_charnum(s) * 2) + 4; - } else { - data_size += (str_ascii_charnum(s)) + 4; - } + data_size += (str_charnum(s) * 2) + 4; break; case 'B': b = va_arg(ap, uint8 *); @@ -124,27 +118,16 @@ BOOL msrpc_gen(DATA_BLOB *blob, data_ofs += n; break; case 'a': - unicode = va_arg(ap, BOOL); n = va_arg(ap, int); SSVAL(blob->data, data_ofs, n); data_ofs += 2; s = va_arg(ap, char *); - if (unicode) { - n = str_charnum(s); - SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n*2, - STR_UNICODE|STR_NOALIGN); - } - data_ofs += n*2; - } else { - n = str_ascii_charnum(s); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n, - STR_ASCII|STR_NOALIGN); - } - data_ofs += n; + n = str_charnum(s); + SSVAL(blob->data, data_ofs, n*2); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n*2, + STR_UNICODE|STR_NOALIGN); } + data_ofs += n*2; break; case 'B': diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 153c234d1f..ea1a7037c9 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -102,7 +102,7 @@ enum ntlmssp_direction { NTLMSSP_RECEIVE }; -static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_state, +static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, const uchar *data, size_t length, enum ntlmssp_direction direction, DATA_BLOB *sig) @@ -113,7 +113,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx); + hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -124,10 +124,10 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat } switch (direction) { case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data+4, sig->length-4); + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); break; case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->srv_sign_hash, sig->data+4, sig->length-4); + NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); break; } } else { @@ -144,9 +144,9 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_CLIENT_STATE *ntlmssp_stat return NT_STATUS_OK; } -NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - const uchar *data, size_t length, - DATA_BLOB *sig) +NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, + const uchar *data, size_t length, + DATA_BLOB *sig) { NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); @@ -161,9 +161,9 @@ NTSTATUS ntlmssp_client_sign_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - const uchar *data, size_t length, - const DATA_BLOB *sig) +NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, + const uchar *data, size_t length, + const DATA_BLOB *sig) { DATA_BLOB local_sig; NTSTATUS nt_status; @@ -204,11 +204,11 @@ NTSTATUS ntlmssp_client_check_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, - uchar *data, size_t length, - DATA_BLOB *sig) +NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, + uchar *data, size_t length, + DATA_BLOB *sig) { - DEBUG(10,("ntlmssp_client_seal_data: seal\n")); + DEBUG(10,("ntlmssp_seal_data: seal\n")); dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; @@ -216,7 +216,7 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->cli_sign_const), 16, &ctx); + hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -227,13 +227,13 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, } dump_data_pw("ntlmssp client sealing hash:\n", - ntlmssp_state->cli_seal_hash, - sizeof(ntlmssp_state->cli_seal_hash)); - NTLMSSPcalc_ap(ntlmssp_state->cli_seal_hash, data, length); + ntlmssp_state->send_seal_hash, + sizeof(ntlmssp_state->send_seal_hash)); + NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length); dump_data_pw("ntlmssp client signing hash:\n", - ntlmssp_state->cli_sign_hash, - sizeof(ntlmssp_state->cli_sign_hash)); - NTLMSSPcalc_ap(ntlmssp_state->cli_sign_hash, sig->data+4, sig->length-4); + ntlmssp_state->send_sign_hash, + sizeof(ntlmssp_state->send_sign_hash)); + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); } else { uint32 crc; crc = crc32_calc_buffer((const char *)data, length); @@ -266,14 +266,14 @@ NTSTATUS ntlmssp_client_seal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, * */ -NTSTATUS ntlmssp_client_unseal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, +NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, DATA_BLOB *sig) { - DEBUG(10,("ntlmssp_client_unseal_data: seal\n")); + DEBUG(10,("ntlmssp__unseal_data: seal\n")); dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - NTLMSSPcalc_ap(ntlmssp_state->srv_seal_hash, data, length); + NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length); } else { dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); @@ -281,13 +281,13 @@ NTSTATUS ntlmssp_client_unseal_packet(NTLMSSP_CLIENT_STATE *ntlmssp_state, } dump_data_pw("ntlmssp clear data\n", data, length); - return ntlmssp_client_check_packet(ntlmssp_state, data, length, sig); + return ntlmssp_check_packet(ntlmssp_state, data, length, sig); } /** Initialise the state for NTLMSSP signing. */ -NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) +NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) { unsigned char p24[24]; ZERO_STRUCT(p24); @@ -297,34 +297,54 @@ NTSTATUS ntlmssp_client_sign_init(NTLMSSP_CLIENT_STATE *ntlmssp_state) if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + const char *send_sign_const; + const char *send_seal_const; + const char *recv_sign_const; + const char *recv_seal_const; + + switch (ntlmssp_state->role) { + case NTLMSSP_CLIENT: + send_sign_const = CLI_SIGN; + send_seal_const = CLI_SEAL; + recv_sign_const = SRV_SIGN; + recv_seal_const = SRV_SEAL; + break; + case NTLMSSP_SERVER: + send_sign_const = SRV_SIGN; + send_seal_const = SRV_SEAL; + recv_sign_const = CLI_SIGN; + recv_seal_const = CLI_SEAL; + break; + } + + calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, + ntlmssp_state->send_sign_const, + ntlmssp_state->session_key, send_sign_const); + dump_data_pw("NTLMSSP send sign hash:\n", + ntlmssp_state->send_sign_hash, + sizeof(ntlmssp_state->send_sign_hash)); + + calc_ntlmv2_hash(ntlmssp_state->send_seal_hash, + ntlmssp_state->send_seal_const, + ntlmssp_state->session_key, send_seal_const); + dump_data_pw("NTLMSSP send sesl hash:\n", + ntlmssp_state->send_seal_hash, + sizeof(ntlmssp_state->send_seal_hash)); + + calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, + ntlmssp_state->recv_sign_const, + ntlmssp_state->session_key, send_sign_const); + dump_data_pw("NTLMSSP receive sign hash:\n", + ntlmssp_state->recv_sign_hash, + sizeof(ntlmssp_state->recv_sign_hash)); + + calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, + ntlmssp_state->recv_seal_const, + ntlmssp_state->session_key, send_seal_const); + dump_data_pw("NTLMSSP receive seal hash:\n", + ntlmssp_state->recv_sign_hash, + sizeof(ntlmssp_state->recv_sign_hash)); - calc_ntlmv2_hash(ntlmssp_state->cli_sign_hash, - ntlmssp_state->cli_sign_const, - ntlmssp_state->session_key, CLI_SIGN); - dump_data_pw("NTLMSSP client sign hash:\n", - ntlmssp_state->cli_sign_hash, - sizeof(ntlmssp_state->cli_sign_hash)); - - calc_ntlmv2_hash(ntlmssp_state->cli_seal_hash, - ntlmssp_state->cli_seal_const, - ntlmssp_state->session_key, CLI_SEAL); - dump_data_pw("NTLMSSP client sesl hash:\n", - ntlmssp_state->cli_seal_hash, - sizeof(ntlmssp_state->cli_seal_hash)); - - calc_ntlmv2_hash(ntlmssp_state->srv_sign_hash, - ntlmssp_state->srv_sign_const, - ntlmssp_state->session_key, SRV_SIGN); - dump_data_pw("NTLMSSP server sign hash:\n", - ntlmssp_state->srv_sign_hash, - sizeof(ntlmssp_state->srv_sign_hash)); - - calc_ntlmv2_hash(ntlmssp_state->srv_seal_hash, - ntlmssp_state->srv_seal_const, - ntlmssp_state->session_key, SRV_SEAL); - dump_data_pw("NTLMSSP server seal hash:\n", - ntlmssp_state->cli_sign_hash, - sizeof(ntlmssp_state->cli_sign_hash)); } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 91509f0fb8..eec991072d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -405,11 +405,11 @@ static void simple_free_signing_context(struct smb_sign_info *si) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[16], const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) { struct smb_basic_signing_context *data; - if (!user_session_key) + if (!user_session_key.length) return False; if (!cli_set_smb_signing_common(cli)) { @@ -425,21 +425,23 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const uchar user_session_key[ cli->sign_info.signing_context = data; - data->mac_key = data_blob(NULL, response.length + 16); + data->mac_key = data_blob(NULL, response.length + user_session_key.length); - memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, (const char *)user_session_key, 16); + dump_data(10, (const char *)user_session_key.data, user_session_key.length); if (response.length) { - memcpy(&data->mac_key.data[16],response.data, response.length); + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); DEBUG(10, ("cli_simple_set_signing: response_data\n")); dump_data(10, (const char *)response.data, response.length); } else { DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); } + dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + /* Initialise the sequence number */ data->send_seq_num = 0; @@ -928,11 +930,11 @@ data->send_seq_num = %u\n", Turn on signing from this packet onwards. ************************************************************/ -void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) +void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) { struct smb_basic_signing_context *data; - if (!user_session_key) + if (!user_session_key.length) return; if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { @@ -957,11 +959,13 @@ void srv_set_signing(const uchar user_session_key[16], const DATA_BLOB response) srv_sign_info.signing_context = data; - data->mac_key = data_blob(NULL, response.length + 16); + data->mac_key = data_blob(NULL, response.length + user_session_key.length); - memcpy(&data->mac_key.data[0], user_session_key, 16); + memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); if (response.length) - memcpy(&data->mac_key.data[16],response.data, response.length); + memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); + + dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ data->send_seq_num = 0; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ec31bb5dba..2d02a23394 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -331,9 +331,9 @@ DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, DATA_BLOB names_blob = data_blob(NULL, 0); msrpc_gen(&names_blob, "aaa", - True, NTLMSSP_NAME_TYPE_DOMAIN, domain, - True, NTLMSSP_NAME_TYPE_SERVER, hostname, - True, 0, ""); + NTLMSSP_NAME_TYPE_DOMAIN, domain, + NTLMSSP_NAME_TYPE_SERVER, hostname, + 0, ""); return names_blob; } -- cgit From 78404434d055ff86177d7c659358c23f12a27a77 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 23:38:41 +0000 Subject: Add support for variable-length session keys in our client code. This means that we now support 'net rpc join' with KRB5 (des based) logins. Now, you need to hack 'net' to do that, but the principal is important... When we add kerberos to 'net rpc', it should be possible to still do user management and the like over RPC. (server-side support to follow shortly) Andrew Bartlett (This used to be commit 9ecf9408d98639186b283f1acf0fac46417547d0) --- source3/libsmb/smbdes.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index cde77f94a3..ae946b4a66 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -397,6 +397,46 @@ void SamOEMhash( unsigned char *data, const unsigned char *key, int val) } } +void SamOEMhashBlob( unsigned char *data, int len, DATA_BLOB *key) +{ + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) + { + s_box[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) + { + unsigned char tc; + + j += (s_box[ind] + key->data[ind%key->length]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + for( ind = 0; ind < len; ind++) + { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } +} + /* Decode a sam password hash into a password. The password hash is the same method used to store passwords in the NT registry. The DES key used is based on the RID of the user. */ -- cgit From efdd1ea572b1e05c3bf169a1a93dffcdabe600b5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 00:32:51 +0000 Subject: When server signing is set to "auto", if the client doesn't sign just ignore it. Only fail if signing is set to "required". Jeremy. (This used to be commit 8916ddfc39c3e70265188926f24034152f0e7b6b) --- source3/libsmb/smb_signing.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index eec991072d..2a53638d17 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -370,7 +370,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); #endif /* JRATEST */ } else { - DEBUG(10, ("client_check_incoming_message:: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); + DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } return signing_good(inbuf, si, good, saved_seq); @@ -743,7 +743,24 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq); + + if (!signing_good(inbuf, si, good, saved_seq)) { + if (si->mandatory_signing) { + /* Mandatory signing - fail and disconnect. */ + return False; + } else { + /* Non-mandatory signing - just turn off. */ + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ +isn't sending correct signatures. Turning off.\n")); + si->negotiated_smb_signing = False; + si->allow_smb_signing = False; + si->doing_signing = False; + free_signing_context(si); + return True; + } + } else { + return True; + } } /*********************************************************** @@ -967,6 +984,10 @@ void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); + DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n", + BOOLSTR(srv_sign_info.negotiated_smb_signing), + BOOLSTR(srv_sign_info.mandatory_signing) )); + /* Initialise the sequence number */ data->send_seq_num = 0; -- cgit From 1b6e6c98ba7175afb994a531bec06a7845950ff3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 25 Nov 2003 11:25:38 +0000 Subject: Do not add NTLM2 to the NTLMSSP flags unconditionally - allow the defaults specified by the caller to prevail. Don't use NTLM2 for RPC pipes, until we know how it works in signing or sealing. Call ntlmssp_sign_init() unconditionally in the client - we setup the session key, why not setup the rest of the data. Andrew Bartlett (This used to be commit 48123f7e42c3fde85887de23c80ceee04c2f6281) --- source3/libsmb/ntlmssp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index a0da1efcc1..d361196047 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -774,8 +774,6 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; - /* generate the ntlmssp negotiate packet */ msrpc_gen(next_request, "CddAA", "NTLMSSP", @@ -812,6 +810,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB encrypted_session_key = data_blob(NULL, 0); + NTSTATUS nt_status; if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -1002,6 +1001,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { + DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); + return nt_status; + } + return NT_STATUS_MORE_PROCESSING_REQUIRED; } -- cgit From 6ce882ef292b1e785b8b859b48256da11091c0d1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Nov 2003 18:15:52 +0000 Subject: If signing starts successfully, don't just turn it off automatically if it fails later. Only turn it off automatically if it fails at the start. Jeremy. (This used to be commit 4a145531c2b6353291cd25f14f5572aa31e86594) --- source3/libsmb/smb_signing.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 2a53638d17..755a1548eb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -745,11 +745,8 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); } if (!signing_good(inbuf, si, good, saved_seq)) { - if (si->mandatory_signing) { - /* Mandatory signing - fail and disconnect. */ - return False; - } else { - /* Non-mandatory signing - just turn off. */ + if (!si->mandatory_signing && (data->send_seq_num < 3)){ + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ isn't sending correct signatures. Turning off.\n")); si->negotiated_smb_signing = False; @@ -757,6 +754,9 @@ isn't sending correct signatures. Turning off.\n")); si->doing_signing = False; free_signing_context(si); return True; + } else { + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + return False; } } else { return True; -- cgit From 2ad1159990f5f1be37af12d36b35def37d69ab25 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 30 Nov 2003 19:40:57 +0000 Subject: Fix signing bug with secondary client trans requests. Turns out the last packet is the one that matters for checking the signing replies. Need to check the server code does this correctly too.... Bug #832 reported by Volker. Jeremy. (This used to be commit 6750dc33b46c422582176b704592d9b2f1fb04d7) --- source3/libsmb/clitrans.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 92c1cc99ee..3eb7fcc216 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -134,6 +134,16 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, * the primary. Important in signing. JRA. */ cli->mid = mid; + /* + * Turns out that we need to increment the + * sequence number for each packet until the + * last one in the signing sequence. That's + * the one that matters to check signing replies. JRA. + */ + + cli_signing_trans_stop(cli); + cli_signing_trans_start(cli); + show_msg(cli->outbuf); if (!cli_send_smb(cli)) { cli_signing_trans_stop(cli); @@ -427,6 +437,16 @@ BOOL cli_send_nt_trans(struct cli_state *cli, * the primary. Important in signing. JRA. */ cli->mid = mid; + /* + * Turns out that we need to increment the + * sequence number for each packet until the + * last one in the signing sequence. That's + * the one that matters to check signing replies. JRA. + */ + + cli_signing_trans_stop(cli); + cli_signing_trans_start(cli); + show_msg(cli->outbuf); if (!cli_send_smb(cli)) { -- cgit From 12d3246a6c0fe2d6241d7f7ec8573b263a559390 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 01:04:04 +0000 Subject: Better fix for client signing bug. Ensure we don't malloc/free trans signing state info each packet. Jeremy. (This used to be commit 818cf32d6330f7e7855ce662326003e75d4a1d46) --- source3/libsmb/clitrans.c | 56 ++++++++++++++++++++------------------------ source3/libsmb/smb_signing.c | 20 +++++++++++----- 2 files changed, 40 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3eb7fcc216..1602dcc683 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -50,6 +50,12 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, SCVAL(cli->outbuf,smb_com,trans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); + + /* + * Save the mid we're using. We need this for finding + * signing replies. + */ + mid = cli->mid; if (pipe_name) { @@ -87,16 +93,13 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); - cli_signing_trans_start(cli); if (!cli_send_smb(cli)) { - cli_signing_trans_stop(cli); return False; } if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - cli_signing_trans_stop(cli); return(False); } @@ -130,23 +133,14 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); - /* Ensure this packet has the same MID as - * the primary. Important in signing. JRA. */ - cli->mid = mid; - /* - * Turns out that we need to increment the - * sequence number for each packet until the - * last one in the signing sequence. That's - * the one that matters to check signing replies. JRA. + * Save the mid we're using. We need this for finding + * signing replies. */ - - cli_signing_trans_stop(cli); - cli_signing_trans_start(cli); + mid = cli->mid; show_msg(cli->outbuf); if (!cli_send_smb(cli)) { - cli_signing_trans_stop(cli); return False; } @@ -155,6 +149,10 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, } } + /* Note we're in a trans state. Save the sequence + * numbers for replies. */ + + cli_signing_trans_start(cli, mid); return(True); } @@ -362,6 +360,12 @@ BOOL cli_send_nt_trans(struct cli_state *cli, SCVAL(cli->outbuf,smb_com,SMBnttrans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); + + /* + * Save the mid we're using. We need this for finding + * signing replies. + */ + mid = cli->mid; outparam = smb_buf(cli->outbuf)+3; @@ -391,16 +395,13 @@ BOOL cli_send_nt_trans(struct cli_state *cli, cli_setup_bcc(cli, outdata+this_ldata); show_msg(cli->outbuf); - cli_signing_trans_start(cli); if (!cli_send_smb(cli)) { - cli_signing_trans_stop(cli); return False; } if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - cli_signing_trans_stop(cli); return(False); } @@ -433,24 +434,15 @@ BOOL cli_send_nt_trans(struct cli_state *cli, memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); - /* Ensure this packet has the same MID as - * the primary. Important in signing. JRA. */ - cli->mid = mid; - /* - * Turns out that we need to increment the - * sequence number for each packet until the - * last one in the signing sequence. That's - * the one that matters to check signing replies. JRA. + * Save the mid we're using. We need this for finding + * signing replies. */ - - cli_signing_trans_stop(cli); - cli_signing_trans_start(cli); + mid = cli->mid; show_msg(cli->outbuf); if (!cli_send_smb(cli)) { - cli_signing_trans_stop(cli); return False; } @@ -459,6 +451,10 @@ BOOL cli_send_nt_trans(struct cli_state *cli, } } + /* Note we're in a trans state. Save the sequence + * numbers for replies. */ + + cli_signing_trans_start(cli, mid); return(True); } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 755a1548eb..cb35fda220 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -457,9 +457,12 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_ /*********************************************************** Tell client code we are in a multiple trans reply state. + We call this after the last outgoing trans2 packet (which + has incremented the sequence numbers), so we must save the + current mid and sequence number -2. ************************************************************/ -void cli_signing_trans_start(struct cli_state *cli) +void cli_signing_trans_start(struct cli_state *cli, uint16 mid) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; @@ -469,9 +472,9 @@ void cli_signing_trans_start(struct cli_state *cli) data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); ZERO_STRUCTP(data->trans_info); - data->trans_info->send_seq_num = data->send_seq_num; - data->trans_info->mid = SVAL(cli->outbuf,smb_mid); - data->trans_info->reply_seq_num = data->send_seq_num+1; + data->trans_info->send_seq_num = data->send_seq_num-2; + data->trans_info->mid = mid; + data->trans_info->reply_seq_num = data->send_seq_num-1; DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ data->send_seq_num = %u\n", @@ -492,10 +495,15 @@ void cli_signing_trans_stop(struct cli_state *cli) if (!cli->sign_info.doing_signing || !data) return; + DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \ +data->send_seq_num = %u\n", + (unsigned int)data->trans_info->mid, + (unsigned int)data->trans_info->reply_seq_num, + (unsigned int)data->trans_info->send_seq_num, + (unsigned int)data->send_seq_num )); + SAFE_FREE(data->trans_info); data->trans_info = NULL; - - data->send_seq_num += 2; } /*********************************************************** -- cgit From b4fa65d0ad3852eb80826845473b99cccfdf20ed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 03:24:50 +0000 Subject: Ensure we use the same mid for the secondary trans requests, W2K3 does this. Jeremy. (This used to be commit 8adf0cd27a23b1bc6e0da08789a8b1e9eefb54a7) --- source3/libsmb/clitrans.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 1602dcc683..ae44ca1a77 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -143,6 +143,9 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, if (!cli_send_smb(cli)) { return False; } + + /* Ensure we use the same mid for the secondaries. */ + cli->mid = mid; tot_data += this_ldata; tot_param += this_lparam; @@ -446,6 +449,9 @@ BOOL cli_send_nt_trans(struct cli_state *cli, return False; } + /* Ensure we use the same mid for the secondaries. */ + cli->mid = mid; + tot_data += this_ldata; tot_param += this_lparam; } -- cgit From f7dfa789c1601d92a76fe0804b095f6931a93246 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 06:59:54 +0000 Subject: Fix spurious error msg. when seq=0. Jeremy (This used to be commit 4912ad8f18041c9c3abe2cfa67dd26a324c9c31e) --- source3/libsmb/smb_signing.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index cb35fda220..6b2abb9ccc 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -764,6 +764,8 @@ isn't sending correct signatures. Turning off.\n")); return True; } else { /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (saved_seq) + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u\n", (unsigned int)saved_seq)); return False; } } else { -- cgit From 026e4762585328ae7a9a5d23b01a074646e65bf3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 1 Dec 2003 22:55:43 +0000 Subject: Client connect signing error messages should be level zero else they're easy to miss. Jeremy. (This used to be commit 7fa89b093709053650d197d2d0f091b9a1cd8218) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a920a1b7ff..f6dfd40006 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1021,7 +1021,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) { - DEBUG(1,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); + DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); return False; } @@ -1057,7 +1057,7 @@ BOOL cli_negprot(struct cli_state *cli) if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { /* Fail if server says signing is mandatory and we don't want to support it. */ if (!cli->sign_info.allow_smb_signing) { - DEBUG(1,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); + DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); return False; } cli->sign_info.negotiated_smb_signing = True; -- cgit From 88dad93acb6b2c62ae08d27752ed6b4ab87e7ad0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 4 Dec 2003 04:16:16 +0000 Subject: Picked up by the build farm - despite all my efforts, security=server was broken by my NTLM2 commit. This should correctly cause the NTLM2 case not to be negotiated when 'security=server' is in effect. Andrew Bartlett (This used to be commit 19bb4b582f98eb1da41e22c9a2a2c11602cb95e4) --- source3/libsmb/ntlmssp.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index d361196047..ca1aa67403 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -340,7 +340,6 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; - ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { @@ -403,13 +402,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); - chal_flags = ntlmssp_state->neg_flags; - - target_name = ntlmssp_target_name(ntlmssp_state, - neg_flags, &chal_flags); - if (target_name == NULL) - return NT_STATUS_INVALID_PARAMETER; - /* Ask our caller what challenge they would like in the packet */ cryptkey = ntlmssp_state->get_challenge(ntlmssp_state); @@ -418,6 +410,19 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } + /* The flags we send back are not just the negotiated flags, + * they are also 'what is in this packet'. Therfore, we + * operate on 'chal_flags' from here on + */ + + chal_flags = ntlmssp_state->neg_flags; + + /* get the right name to fill in as 'target' */ + target_name = ntlmssp_target_name(ntlmssp_state, + neg_flags, &chal_flags); + if (target_name == NULL) + return NT_STATUS_INVALID_PARAMETER; + ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); -- cgit From 1f761ad3959cca29583844ac2f94b34a34bc2ec2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 4 Dec 2003 21:26:14 +0000 Subject: Fix incorrect smb flags2 for connections to pre-NT servers (causes smbclient to fail to OS2 for example) (This used to be commit 54e2fcb8f4a9d603b3210baa014b3f5f15070a22) --- source3/libsmb/cliconnect.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f6dfd40006..6e95944f92 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -53,6 +53,13 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, if (passlen > sizeof(pword)-1) return False; + /* LANMAN servers predate NT status codes and Unicode and ignore those + smb flags so we must disable the corresponding default capabilities + that would otherwise cause the Unicode and NT Status flags to be + set (and even returned by the server) */ + + cli->capabilities &= ~(CAP_UNICODE | CAP_STATUS32); + /* if in share level security then don't send a password now */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) passlen = 0; -- cgit From ee17580c85b6de40ca6911ab7a6b158cd69ca692 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 9 Dec 2003 02:29:27 +0000 Subject: Make intent to return only one address clear. Jeremy. (This used to be commit d3d0353baeba580d8a7a4688f847463b1b2e750c) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1de7413711..c7cc4848b7 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1006,9 +1006,9 @@ static BOOL internal_resolve_name(const char *name, int name_type, } } else { (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0; - *return_count = 1; } - return True; + *return_count = 1; + return True; } /* Check name cache */ -- cgit From 54cff4535e8237c43977faa372ebac8baf88b034 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 17 Dec 2003 06:18:13 +0000 Subject: Make sure we correctly generate the lm session key. This fixes a problem joining a Samba domain from a vanilla win2k client that doesn't set the NTLMSSP_NEGOTIATE_NTLM2 flag. Reported on samba ml as "decode_pw: incorrect password length" when handling a samr_set_userinfo(23 or 24) RPC. (This used to be commit ef4ab8d7c497e4229d0c1deeb20d05c95bd8feb9) --- source3/libsmb/ntlmssp.c | 8 ++++++-- source3/libsmb/smbencrypt.c | 20 ++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index ca1aa67403..3cfd6d2043 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -660,6 +660,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); hmac_md5(nt_session_key.data, session_nonce, sizeof(session_nonce), session_key.data); + DEBUG(10,("NTLM2 session key set\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } @@ -667,12 +668,14 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, if (lm_session_key.data && lm_session_key.length >= 8 && ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_lmv1(lm_session_key.data, ntlmssp_state->lm_resp.data, + SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, session_key.data); + DEBUG(10,("LM KEY session key set\n")); dump_data_pw("LM session key:\n", session_key.data, session_key.length); } } else if (nt_session_key.data) { session_key = nt_session_key; + DEBUG(10,("unmodified session key set\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } @@ -695,7 +698,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = data_blob_talloc(ntlmssp_state->mem_ctx, encrypted_session_key.data, encrypted_session_key.length); - dump_data_pw("KEY_EXCH session key:\n", session_key.data, session_key.length); + dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, + encrypted_session_key.length); } } else { ntlmssp_state->session_key = session_key; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 2d02a23394..cfcc24a1df 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -325,6 +325,26 @@ void SMBsesskeygen_lmv1(const uchar lm_hash[16], #endif } +void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], + const uchar lm_resp[24], /* only uses 8 */ + uint8 sess_key[16]) +{ + uchar p24[24]; + uchar partial_lm_hash[16]; + + memcpy(partial_lm_hash, lm_hash, 8); + memset(partial_lm_hash + 8, 0xbd, 8); + + SMBOWFencrypt(partial_lm_hash, lm_resp, p24); + + memcpy(sess_key, p24, 16); + +#ifdef DEBUG_PASSWORD + DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n")); + dump_data(100, sess_key, 16); +#endif +} + DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, const char *domain) { -- cgit From 93a983b7cbac4ee1d967627aa3bfd15f3f0311ea Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Dec 2003 20:11:39 +0000 Subject: Tidyup debug message in ntlmssp code. Add brackets around dodgy if statement. Jeremy (This used to be commit 5aab4b976c0aced68d71c1e71e85287072a6f3c7) --- source3/libsmb/ntlmssp.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 3cfd6d2043..10f2983180 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -330,7 +330,7 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->unicode = False; } - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY && allow_lm) { + if ((neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && allow_lm) { /* other end forcing us to use LM */ ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; ntlmssp_state->use_ntlmv2 = False; @@ -660,9 +660,13 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); hmac_md5(nt_session_key.data, session_nonce, sizeof(session_nonce), session_key.data); - DEBUG(10,("NTLM2 session key set\n")); + DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); + }else { + data_blob_free(&encrypted_session_key); + DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); + return NT_STATUS_INVALID_PARAMETER; } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (lm_session_key.data && lm_session_key.length >= 8 && @@ -670,13 +674,21 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, session_key.data); - DEBUG(10,("LM KEY session key set\n")); + DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); dump_data_pw("LM session key:\n", session_key.data, session_key.length); + } else { + data_blob_free(&encrypted_session_key); + DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); + return NT_STATUS_INVALID_PARAMETER; } } else if (nt_session_key.data) { session_key = nt_session_key; - DEBUG(10,("unmodified session key set\n")); + DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } else { + data_blob_free(&encrypted_session_key); + DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified nt session key.\n")); + return NT_STATUS_INVALID_PARAMETER; } /* With KEY_EXCH, the client supplies the proposed session key, @@ -1026,7 +1038,7 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); if (!*ntlmssp_state) { - DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); + DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); talloc_destroy(mem_ctx); return NT_STATUS_NO_MEMORY; } -- cgit From 68e692738b30f746a99a4392dd438ccdf14d95e0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Dec 2003 21:57:26 +0000 Subject: Add in comments explaining NTLMv2 selection. Use lm session key if that's all there is. Jeremy. (This used to be commit b611f8d170743f1f4d71b1def83bb757d9f467af) --- source3/libsmb/ntlmssp.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 10f2983180..7b821da0fd 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -645,7 +645,15 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } } + /* + * Note we don't check here for NTLMv2 auth settings. If NTLMv2 auth + * is required (by "ntlm auth = no" and "lm auth = no" being set in the + * smb.conf file) and no NTLMv2 response was sent then the password check + * will fail here. JRA. + */ + /* Finally, actually ask if the password is OK */ + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) { data_blob_free(&encrypted_session_key); return nt_status; @@ -685,9 +693,13 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = nt_session_key; DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); + } else if (lm_session_key.data) { + session_key = lm_session_key; + DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n")); + dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } else { data_blob_free(&encrypted_session_key); - DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified nt session key.\n")); + DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 82027c1ea2e44f51fa3a622af54736bac2e754a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 27 Dec 2003 10:11:26 +0000 Subject: Preliminary fix for our signing problem with failed NTLMSSP logins. This patch solves the problem for me here, I can still successfully set up signing using NTLMSSP against w2k3 and it does not show a signing error anymoe when the password was wrong. Jeremy, you might want to take a further look at it as this is not particularly elegant. Volker (This used to be commit f5afaafd61dc7bd191225ffa8eee184125dd97c3) --- source3/libsmb/cliconnect.c | 22 +++++++++++++++------- source3/libsmb/smb_signing.c | 6 ++++-- 2 files changed, 19 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6e95944f92..2aeac7273e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -325,7 +325,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - cli_simple_set_signing(cli, session_key, nt_response); + cli_simple_set_signing(cli, session_key, nt_response, 0); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -518,7 +518,7 @@ static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *pr file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif - cli_simple_set_signing(cli, session_key_krb5, null_blob); + cli_simple_set_signing(cli, session_key_krb5, null_blob, 0); blob2 = cli_session_setup_blob(cli, negTokenTarg); @@ -575,7 +575,6 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DATA_BLOB null_blob = data_blob(NULL, 0); if (turn == 1) { /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); @@ -584,10 +583,6 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use msg1 = spnego_gen_auth(blob_out); } - cli_simple_set_signing(cli, - data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length), - null_blob); - /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { DEBUG(3, ("Failed to send NTLMSSP/SPENGO blob to server!\n")); @@ -637,8 +632,21 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); if (NT_STATUS_IS_OK(nt_status)) { + + DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length); + DATA_BLOB null_blob = data_blob(NULL, 0); + fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); + + /* Using NTLMSSP session setup, signing on the net only starts + * after a successful authentication and the session key has + * been determined, but with a sequence number of 2. This + * assumes that NTLMSSP needs exactly 2 roundtrips, for any + * other SPNEGO mechanism it needs adapting. */ + + cli_simple_set_signing(cli, key, null_blob, 2); } /* we have a reference conter on ntlmssp_state, if we are signing diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 6b2abb9ccc..8a056f659f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -405,7 +405,9 @@ static void simple_free_signing_context(struct smb_sign_info *si) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) +BOOL cli_simple_set_signing(struct cli_state *cli, + const DATA_BLOB user_session_key, + const DATA_BLOB response, int initial_send_seq_num) { struct smb_basic_signing_context *data; @@ -443,7 +445,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_ dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ - data->send_seq_num = 0; + data->send_seq_num = initial_send_seq_num; /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; -- cgit From f73492a58aba4239a9e00cc1bfca51362ca6a9b8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Dec 2003 11:33:24 +0000 Subject: This patch corrects some errors in the NTLMSSP implementation, that would incorrectly return INVALID_PARAMETER, instead of allowing a login. Andrew Bartlett (This used to be commit 76c59469a340209959c420bd5c2e947d3347bdb1) --- source3/libsmb/ntlmssp.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 7b821da0fd..7026a02726 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -577,6 +577,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } } + if (auth_flags) + ntlmssp_handle_neg_flags(ntlmssp_state, auth_flags, lp_lanman_auth()); + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { SAFE_FREE(domain); SAFE_FREE(user); @@ -670,20 +673,26 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, sizeof(session_nonce), session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); - - }else { + + } else { data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); return NT_STATUS_INVALID_PARAMETER; } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - if (lm_session_key.data && lm_session_key.length >= 8 && - ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { - session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, - session_key.data); - DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); - dump_data_pw("LM session key:\n", session_key.data, session_key.length); + if (lm_session_key.data && lm_session_key.length >= 8) { + if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, + session_key.data); + DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); + dump_data_pw("LM session key:\n", session_key.data, session_key.length); + } else { + /* use the key unmodified - it's + * probably a NULL key from the guest + * login */ + session_key = lm_session_key; + } } else { data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); -- cgit From 5dff713735627288d69b55afeb540582a5b33d1a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 28 Dec 2003 09:57:29 +0000 Subject: Shutting down the connection closes outstanding sessions, so we don't need to do it twice... Amdrew Bartlett (This used to be commit 8f9a069c59cbd357cbef8814764c10f6d8b6e6e8) --- source3/libsmb/trusts_util.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 2c6eb1b55a..7c1000b9a5 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -182,7 +182,6 @@ done: /* cleanup */ if (cli) { DEBUG(10,("enumerate_domain_trusts: shutting down connection...\n")); - cli_nt_session_close( cli ); cli_shutdown( cli ); } -- cgit From adc07646a3057e5c572edb3ebdac2367206aaeef Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 30 Dec 2003 07:33:58 +0000 Subject: Move our basic password checking code from inside the authentication subsystem into a seperate file - ntlm_check.c. This allows us to call these routines from ntlm_auth. The purpose of this exercise is to allow ntlm_auth (when operating as an NTLMSSP server) to avoid talking to winbind. This should allow for easier debugging. ntlm_auth itself has been reorgainised, so as to share more code between the SPNEGO-wrapped and 'raw' NTLMSSP modes. A new 'client' NTLMSSP mode has been added, for use with a Cyrus-SASL module I am writing (based on vl's work) Andrew Bartlett (This used to be commit 48315e8fd227978e0161be293ad4411b45e3ea5b) --- source3/libsmb/ntlm_check.c | 377 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 source3/libsmb/ntlm_check.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c new file mode 100644 index 0000000000..362b640f91 --- /dev/null +++ b/source3/libsmb/ntlm_check.c @@ -0,0 +1,377 @@ +/* + Unix SMB/CIFS implementation. + Password and authentication handling + Copyright (C) Andrew Tridgell 1992-2000 + Copyright (C) Luke Kenneth Casson Leighton 1996-2000 + Copyright (C) Andrew Bartlett 2001-2003 + Copyright (C) Gerald Carter 2003 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_AUTH + +/**************************************************************************** + Core of smb password checking routine. +****************************************************************************/ + +static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, + const uchar *part_passwd, + const DATA_BLOB *sec_blob, + DATA_BLOB *user_sess_key) +{ + /* Finish the encryption of part_passwd. */ + uchar p24[24]; + + if (part_passwd == NULL) { + DEBUG(10,("No password set - DISALLOWING access\n")); + /* No password set - always false ! */ + return False; + } + + if (sec_blob->length != 8) { + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", + (unsigned long)sec_blob->length)); + return False; + } + + if (nt_response->length != 24) { + DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", + (unsigned long)nt_response->length)); + return False; + } + + SMBOWFencrypt(part_passwd, sec_blob->data, p24); + if (user_sess_key != NULL) { + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(part_passwd, NULL, user_sess_key->data); + } + + +#if DEBUG_PASSWORD + DEBUG(100,("Part password (P16) was |\n")); + dump_data(100, part_passwd, 16); + DEBUGADD(100,("Password from client was |\n")); + dump_data(100, nt_response->data, nt_response->length); + DEBUGADD(100,("Given challenge was |\n")); + dump_data(100, sec_blob->data, sec_blob->length); + DEBUGADD(100,("Value from encryption was |\n")); + dump_data(100, p24, 24); +#endif + return (memcmp(p24, nt_response->data, 24) == 0); +} + +/**************************************************************************** + Core of smb password checking routine. (NTLMv2, LMv2) + Note: The same code works with both NTLMv2 and LMv2. +****************************************************************************/ + +static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, + const uchar *part_passwd, + const DATA_BLOB *sec_blob, + const char *user, const char *domain, + DATA_BLOB *user_sess_key) +{ + /* Finish the encryption of part_passwd. */ + uchar kr[16]; + uchar value_from_encryption[16]; + uchar client_response[16]; + DATA_BLOB client_key_data; + + if (part_passwd == NULL) { + DEBUG(10,("No password set - DISALLOWING access\n")); + /* No password set - always False */ + return False; + } + + if (sec_blob->length != 8) { + DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", + (unsigned long)sec_blob->length)); + return False; + } + + if (ntv2_response->length < 24) { + /* We MUST have more than 16 bytes, or the stuff below will go + crazy. No known implementation sends less than the 24 bytes + for LMv2, let alone NTLMv2. */ + DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", + (unsigned long)ntv2_response->length)); + return False; + } + + client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16); + /* + todo: should we be checking this for anything? We can't for LMv2, + but for NTLMv2 it is meant to contain the current time etc. + */ + + memcpy(client_response, ntv2_response->data, sizeof(client_response)); + + if (!ntv2_owf_gen(part_passwd, user, domain, kr)) { + return False; + } + + SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); + if (user_sess_key != NULL) { + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv2(kr, value_from_encryption, user_sess_key->data); + } + +#if DEBUG_PASSWORD + DEBUG(100,("Part password (P16) was |\n")); + dump_data(100, part_passwd, 16); + DEBUGADD(100,("Password from client was |\n")); + dump_data(100, ntv2_response->data, ntv2_response->length); + DEBUGADD(100,("Variable data from client was |\n")); + dump_data(100, client_key_data.data, client_key_data.length); + DEBUGADD(100,("Given challenge was |\n")); + dump_data(100, sec_blob->data, sec_blob->length); + DEBUGADD(100,("Value from encryption was |\n")); + dump_data(100, value_from_encryption, 16); +#endif + data_blob_clear_free(&client_key_data); + return (memcmp(value_from_encryption, client_response, 16) == 0); +} + +/** + * Check a challenge-response password against the value of the NT or + * LM password hash. + * + * @param mem_ctx talloc context + * @param challenge 8-byte challenge. If all zero, forces plaintext comparison + * @param nt_response 'unicode' NT response to the challenge, or unicode password + * @param lm_response ASCII or LANMAN response to the challenge, or password in DOS code page + * @param username internal Samba username, for log messages + * @param client_username username the client used + * @param client_domain domain name the client used (may be mapped) + * @param nt_pw MD4 unicode password from our passdb or similar + * @param lm_pw LANMAN ASCII password from our passdb or similar + * @param user_sess_key User session key + * @param lm_sess_key LM session key (first 8 bytes of the LM hash) + */ + +NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, + const DATA_BLOB *challenge, + const DATA_BLOB *lm_response, + const DATA_BLOB *nt_response, + const char *username, + const char *client_username, + const char *client_domain, + const uint8 *lm_pw, const uint8 *nt_pw, + DATA_BLOB *user_sess_key, + DATA_BLOB *lm_sess_key) +{ + static const unsigned char zeros[8]; + if (nt_pw == NULL) { + DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", + username)); + } + + /* Check for cleartext netlogon. Used by Exchange 5.5. */ + if (challenge->length == sizeof(zeros) && + (memcmp(challenge->data, zeros, challenge->length) == 0 )) { + + DEBUG(4,("ntlm_password_check: checking plaintext passwords for user %s\n", + username)); + if (nt_pw && nt_response->length) { + unsigned char pwhash[16]; + mdfour(pwhash, nt_response->data, nt_response->length); + if (memcmp(pwhash, nt_pw, sizeof(pwhash)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NT (Unicode) plaintext password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + } else if (!lp_lanman_auth()) { + DEBUG(3,("ntlm_password_check: (plaintext password check) LANMAN passwords NOT PERMITTED for user %s\n", + username)); + + } else if (lm_pw && lm_response->length) { + uchar dospwd[14]; + uchar p16[16]; + ZERO_STRUCT(dospwd); + + memcpy(dospwd, lm_response->data, MIN(lm_response->length, sizeof(dospwd))); + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ + + /* we *might* need to upper-case the string here */ + E_P16((const unsigned char *)dospwd, p16); + + if (memcmp(p16, lm_pw, sizeof(p16)) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: LANMAN (ASCII) plaintext password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + } else { + DEBUG(3, ("Plaintext authentication for user %s attempted, but neither NT nor LM passwords available\n", username)); + return NT_STATUS_WRONG_PASSWORD; + } + } + + if (nt_response->length != 0 && nt_response->length < 24) { + DEBUG(2,("ntlm_password_check: invalid NT password length (%lu) for user %s\n", + (unsigned long)nt_response->length, username)); + } + + if (nt_response->length >= 24 && nt_pw) { + if (nt_response->length > 24) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain)); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + client_domain, + user_sess_key)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n")); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, + "", + user_sess_key)) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n")); + return NT_STATUS_WRONG_PASSWORD; + } + } + + if (lp_ntlm_auth()) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("ntlm_password_check: Checking NT MD4 password\n")); + if (smb_pwd_check_ntlmv1(nt_response, + nt_pw, challenge, + user_sess_key)) { + /* The LM session key for this response is not very secure, + so use it only if we otherwise allow LM authentication */ + + if (lp_lanman_auth() && lm_pw) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: NT MD4 password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + } else { + DEBUG(2,("ntlm_password_check: NTLMv1 passwords NOT PERMITTED for user %s\n", + username)); + /* no return, becouse we might pick up LMv2 in the LM field */ + } + } + + if (lm_response->length == 0) { + DEBUG(3,("ntlm_password_check: NEITHER LanMan nor NT password supplied for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (lm_response->length < 24) { + DEBUG(2,("ntlm_password_check: invalid LanMan password length (%lu) for user %s\n", + (unsigned long)nt_response->length, username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (!lp_lanman_auth()) { + DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n", + username)); + } else if (!lm_pw) { + DEBUG(3,("ntlm_password_check: NO LanMan password set for user %s (and no NT password supplied)\n", + username)); + } else { + DEBUG(4,("ntlm_password_check: Checking LM password\n")); + if (smb_pwd_check_ntlmv1(lm_response, + lm_pw, challenge, + NULL)) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + return NT_STATUS_OK; + } + } + + if (!nt_pw) { + DEBUG(4,("ntlm_password_check: LM password check failed for user, no NT password %s\n",username)); + return NT_STATUS_WRONG_PASSWORD; + } + + /* This is for 'LMv2' authentication. almost NTLMv2 but limited to 24 bytes. + - related to Win9X, legacy NAS pass-though authentication + */ + DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n", client_domain)); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + client_domain, + NULL)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n")); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + "", + NULL)) { + return NT_STATUS_OK; + } + + /* Apparently NT accepts NT responses in the LM field + - I think this is related to Win9X pass-though authentication + */ + DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n")); + if (lp_ntlm_auth()) { + if (smb_pwd_check_ntlmv1(lm_response, + nt_pw, challenge, + NULL)) { + /* The session key for this response is still very odd. + It not very secure, so use it only if we otherwise + allow LM authentication */ + + if (lp_lanman_auth() && lm_pw) { + uint8 first_8_lm_hash[16]; + memcpy(first_8_lm_hash, lm_pw, 8); + memset(first_8_lm_hash + 8, '\0', 8); + *user_sess_key = data_blob(first_8_lm_hash, 16); + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } + return NT_STATUS_OK; + } + DEBUG(3,("ntlm_password_check: LM password, NT MD4 password in LM field and LMv2 failed for user %s\n",username)); + } else { + DEBUG(3,("ntlm_password_check: LM password and LMv2 failed for user %s, and NT MD4 password in LM field not permitted\n",username)); + } + return NT_STATUS_WRONG_PASSWORD; +} + -- cgit From 5eee23cc64139ba1d23101c87709e6d5198a6c68 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Dec 2003 00:31:43 +0000 Subject: auth/auth_util.c: - Fill in the 'backup' idea of a domain, if the DC didn't supply one. This doesn't seem to occour in reality, hence why we missed the typo. lib/charcnv.c: lib/smbldap.c: libads/ldap.c: libsmb/libsmbclient.c: printing/nt_printing.c: - all the callers to pull_utf8_allocate() pass a char ** as the first parammeter, so don't make them all cast it to a void ** nsswitch/winbind_util.c: - Allow for a more 'correct' view of when usernames should be qualified in winbindd. If we are a PDC, or have 'winbind trusted domains only', then for the authentication returns stip the domain portion. - Fix valgrind warning about use of free()ed name when looking up our local domain. lp_workgroup() is maniplated inside a procedure that uses it's former value. Instead, use the fact that our local domain is always the first in the list. Andrew Bartlett (This used to be commit 494781f628683d6e68e8ba21ae54f738727e8c21) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 21273ec431..37e794478d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -144,7 +144,7 @@ decode_urlpart(char *segment, size_t sizeof_segment) free(new_usegment); /* realloc it with unix charset */ - pull_utf8_allocate((void**)&new_usegment, new_segment); + pull_utf8_allocate(&new_usegment, new_segment); /* this assumes (very safely) that removing %aa sequences only shortens the string */ -- cgit From 4cc701196e2a3603b62ae3ad8c8178fadcfa853b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 3 Jan 2004 01:12:56 +0000 Subject: There is not a particularly good excuse for complaining to the *client* that it sent 'INVALID_PARAMETER', when it was us as the server that could not come up with a session key. Instead, allow normal authentication to take place, but do not setup a session key. Andrew Bartlett (This used to be commit e5abd93d799e5f86839560feca448743c13a9055) --- source3/libsmb/ntlmssp.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 7026a02726..e58104367f 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -657,7 +657,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, /* Finally, actually ask if the password is OK */ - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, &nt_session_key, &lm_session_key))) { + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, + &nt_session_key, &lm_session_key))) { data_blob_free(&encrypted_session_key); return nt_status; } @@ -677,7 +678,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } else { data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); - return NT_STATUS_INVALID_PARAMETER; + session_key = data_blob(NULL, 0); } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (lm_session_key.data && lm_session_key.length >= 8) { @@ -696,7 +697,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } else { data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); - return NT_STATUS_INVALID_PARAMETER; + session_key = data_blob(NULL, 0); } } else if (nt_session_key.data) { session_key = nt_session_key; @@ -709,7 +710,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } else { data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); - return NT_STATUS_INVALID_PARAMETER; + session_key = data_blob(NULL, 0); } /* With KEY_EXCH, the client supplies the proposed session key, @@ -915,7 +916,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } if (!ntlmssp_state->password) { + static const uchar zeros[16]; /* do nothing - blobs are zero length */ + + /* session key is all zeros */ + session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); + + /* not doing NLTM2 without a password */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } else if (ntlmssp_state->use_ntlmv2) { if (!struct_blob.length) { -- cgit From cc02d8690c94620a4a026e70b70ae776c370f9f6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 4 Jan 2004 11:05:30 +0000 Subject: Even if the 'device type' is always an ascii string, use push_string to get it out onto the wire. Avoids valgrind warnings because the fstrcpy() causes part of the wire buffer to be 'marked'. Andrew Bartlett (This used to be commit 53d802c72aa712e099dc8de666ab66a21e18fae1) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2aeac7273e..f466b665eb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -910,7 +910,7 @@ BOOL cli_send_tconX(struct cli_state *cli, memcpy(p,pword,passlen); p += passlen; p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER); - fstrcpy(p, dev); p += strlen(dev)+1; + p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII); cli_setup_bcc(cli, p); -- cgit From e8984d6b9aac91082af745d22a4b195a1be5dee4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 00:11:02 +0000 Subject: Automaticly initialise the signing engine, if we have a session key. (This used to be commit cb063c1b6949a2a9637689537c6ab8dc881bc568) --- source3/libsmb/ntlmssp.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e58104367f..85ae279758 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -739,6 +739,12 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = session_key; } + if (!NT_STATUS_IS_OK(nt_status)) { + ntlmssp_state->session_key = data_blob(NULL, 0); + } else if (ntlmssp_state->session_key.length) { + nt_status = ntlmssp_sign_init(ntlmssp_state); + } + data_blob_free(&encrypted_session_key); /* allow arbitarily many authentications */ -- cgit From d4954eff579517f4a2189565bf7d49f119c886a2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 00:11:35 +0000 Subject: Make it clear that we cannot sign if we don't have a session key. (This used to be commit a2f6dec05b3b30292ec3e42808dc89f1bf5c7ab4) --- source3/libsmb/ntlmssp_sign.c | 57 ++++++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index ea1a7037c9..6ce7a76743 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -53,7 +53,7 @@ static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) hash[257] = index_j; } -static void calc_hash(unsigned char *hash, const char *k2, int k2l) +static void calc_hash(unsigned char hash[258], const char *k2, int k2l) { unsigned char j = 0; int ind; @@ -78,7 +78,7 @@ static void calc_hash(unsigned char *hash, const char *k2, int k2l) hash[257] = 0; } -static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], +static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char digest[16], DATA_BLOB session_key, const char *constant) { @@ -91,8 +91,8 @@ static void calc_ntlmv2_hash(unsigned char hash[16], char digest[16], MD5Init(&ctx3); MD5Update(&ctx3, session_key.data, session_key.length); - MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)); - MD5Final((unsigned char *)digest, &ctx3); + MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1); + MD5Final(digest, &ctx3); calc_hash(hash, digest, 16); } @@ -109,12 +109,12 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; - char seq_num[4]; + uchar seq_num[4]; uchar digest[16]; SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); - hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); + hmac_md5_update(seq_num, 4, &ctx); hmac_md5_update(data, length, &ctx); hmac_md5_final(digest, &ctx); @@ -122,13 +122,16 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, , ntlmssp_state->ntlmssp_seq_num)) { return NT_STATUS_NO_MEMORY; } - switch (direction) { - case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); - break; - case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); - break; + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + switch (direction) { + case NTLMSSP_SEND: + NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); + break; + case NTLMSSP_RECEIVE: + NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); + break; + } } } else { uint32 crc; @@ -148,7 +151,13 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, const uchar *data, size_t length, DATA_BLOB *sig) { - NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + NTSTATUS nt_status; + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot check sign packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); /* increment counter on send */ ntlmssp_state->ntlmssp_seq_num++; @@ -168,6 +177,11 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, DATA_BLOB local_sig; NTSTATUS nt_status; + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot check packet signature\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + if (sig->length < 8) { DEBUG(0, ("NTLMSSP packet check failed due to short signature (%lu bytes)!\n", (unsigned long)sig->length)); @@ -208,6 +222,11 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, DATA_BLOB *sig) { + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot seal packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + DEBUG(10,("ntlmssp_seal_data: seal\n")); dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -270,6 +289,11 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, DATA_BLOB *sig) { + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot unseal packet\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + DEBUG(10,("ntlmssp__unseal_data: seal\n")); dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { @@ -295,6 +319,11 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); + if (!ntlmssp_state->session_key.length) { + DEBUG(3, ("NO session key, cannot intialise signing\n")); + return NT_STATUS_NO_USER_SESSION_KEY; + } + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { const char *send_sign_const; -- cgit From a7f8c26d24b78dc6a0f829cf7b53112e5ddbdeda Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 04:10:28 +0000 Subject: Change our Domain controller lookup routines to more carefully seperate DNS names (realms) from NetBIOS domain names. Until now, we would experience delays as we broadcast lookups for DNS names onto the local network segments. Now if DNS comes back negative, we fall straight back to looking up the short name. Andrew Bartlett (This used to be commit 32397c8b01f1dec7b05140d210bb32f836a80ca6) --- source3/libsmb/namequery_dc.c | 27 +++++++++++---------------- source3/libsmb/trusts_util.c | 2 +- 2 files changed, 12 insertions(+), 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index df7f856cd7..31d759e0d2 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -29,27 +29,23 @@ Find the name and IP address for a server in he realm/domain *************************************************************************/ -static BOOL ads_dc_name(const char *domain, struct in_addr *dc_ip, fstring srv_name) +static BOOL ads_dc_name(const char *domain, const char *realm, struct in_addr *dc_ip, fstring srv_name) { ADS_STRUCT *ads; - const char *realm = domain; - if (strequal(realm, lp_workgroup())) + if (!realm && strequal(domain, lp_workgroup())) realm = lp_realm(); ads = ads_init(realm, domain, NULL); if (!ads) return False; - /* we don't need to bind, just connect */ - ads->auth.flags |= ADS_AUTH_NO_BIND; - DEBUG(4,("ads_dc_name: domain=%s\n", domain)); #ifdef HAVE_ADS - /* a full ads_connect() is actually overkill, as we don't srictly need - to do the SASL auth in order to get the info we need, but libads - doesn't offer a better way right now */ + /* we don't need to bind, just connect */ + ads->auth.flags |= ADS_AUTH_NO_BIND; + ads_connect(ads); #endif @@ -157,7 +153,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip wrapper around ads and rpc methods of finds DC's **********************************************************************/ -BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) +BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out) { struct in_addr dc_ip; BOOL ret; @@ -167,15 +163,14 @@ BOOL get_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) ret = False; - if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), domain) ) + if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) ) our_domain = True; - /* always try to obey what the admin specified in smb.conf. - If it is not our domain, assume that domain names with periods - in them are realm names */ + /* always try to obey what the admin specified in smb.conf + (for the local domain) */ - if ( (our_domain && lp_security()==SEC_ADS) || strchr_m(domain, '.') ) { - ret = ads_dc_name(domain, &dc_ip, srv_name); + if ( (our_domain && lp_security()==SEC_ADS) || realm ) { + ret = ads_dc_name(domain, realm, &dc_ip, srv_name); } if (!ret) { diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 7c1000b9a5..b420e4fa08 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -144,7 +144,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* lookup a DC first */ - if ( !get_dc_name(domain, dc_name, &dc_ip) ) { + if ( !get_dc_name(domain, NULL, dc_name, &dc_ip) ) { DEBUG(3,("enumerate_domain_trusts: can't locate a DC for domain %s\n", domain)); return False; -- cgit From 425699fce728a3d302a3e5288d0c59ec7b16aee2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 04:12:40 +0000 Subject: Correctly handle per-pipe NTLMSSP inside a NULL session. Previously we would attempt to supply a password to the 'inside' NTLMSSP, which the remote side naturally rejected. Andrew Bartlett (This used to be commit da408e0d5aa29ca1505c2fd96b32deae9ed940c4) --- source3/libsmb/pwd_cache.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index f45832d7d7..7ba6cfc96f 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -45,8 +45,14 @@ static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) { pwd_init(pwd); - nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); - pwd->null_pwd = False; + if (!clr) { + ZERO_STRUCT(pwd->smb_nt_pwd); + ZERO_STRUCT(pwd->smb_lm_pwd); + pwd->null_pwd = True; + } else { + nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); + pwd->null_pwd = False; + } pwd->crypted = False; } -- cgit From ed55d03c8a087b9a3df9764d3c983bf59af1defc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 12:36:21 +0000 Subject: Don't free the encrypted_session_key early - that causes the subsequent test for a valid length to fail... This should fix 'security=server' and hosts-equiv failures picked up by the build farm. Andrew Bartlett (This used to be commit 39311495de3bd0a902f730967f30176db97be05a) --- source3/libsmb/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 85ae279758..0ab51dc960 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -708,7 +708,6 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, DEBUG(10,("ntlmssp_server_auth: Using unmodified lm session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } else { - data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); session_key = data_blob(NULL, 0); } @@ -724,6 +723,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } else if (!session_key.data || session_key.length != 16) { DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", session_key.length)); + ntlmssp_state->session_key = session_key; } else { dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); SamOEMhash(encrypted_session_key.data, -- cgit From 2ed5a1a340598374a61e9eec9221598c26e749db Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 5 Jan 2004 19:21:06 +0000 Subject: Ensure we set "always sign" flag if set. We don't currently do anything with this but we should log the fact it was negotiated. Jeremy. (This used to be commit 84d34e32be03ec99ce19520f24bb4daaeeddbbc3) --- source3/libsmb/ntlmssp.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 0ab51dc960..95fd4c03e5 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -338,6 +338,10 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + } + if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2; } -- cgit From cfa4469c1e1a323ac27b502596f88695f463a738 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 5 Jan 2004 21:24:27 +0000 Subject: Fix more cases to ensure that as a server, we don't complain to the client about our server-side lack of session key. Andrew Bartlett (This used to be commit ba33f1e0d5fe2aed3e378c9c23511c0b4d6f7d14) --- source3/libsmb/ntlmssp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 95fd4c03e5..40d7f41109 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -680,7 +680,6 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { - data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); session_key = data_blob(NULL, 0); } @@ -699,7 +698,6 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key = lm_session_key; } } else { - data_blob_free(&encrypted_session_key); DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); session_key = data_blob(NULL, 0); } @@ -737,7 +735,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, encrypted_session_key.data, encrypted_session_key.length); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, - encrypted_session_key.length); + encrypted_session_key.length); } } else { ntlmssp_state->session_key = session_key; -- cgit From e0ec9d2d5697bf95626da736f6f9552e10e52ffc Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Jan 2004 02:57:42 +0000 Subject: Make it clearer that the domain here is the domain of the user for authentication. Andrew Bartlett (This used to be commit 7e6cc8f0037f9948230a1e1bd380f30cec5d511e) --- source3/libsmb/cliconnect.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f466b665eb..1dc46ab0e6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -544,7 +544,7 @@ static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *pr ****************************************************************************/ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) + const char *pass, const char *domain) { struct ntlmssp_state *ntlmssp_state; NTSTATUS nt_status; @@ -563,7 +563,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { return nt_status; } - if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, workgroup))) { + if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, domain))) { return nt_status; } if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, pass))) { @@ -662,7 +662,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use ****************************************************************************/ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) + const char *pass, const char *domain) { char *principal; char *OIDs[ASN1_MAX_OIDS]; @@ -723,7 +723,7 @@ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, } } - return cli_session_setup_kerberos(cli, principal, workgroup); + return cli_session_setup_kerberos(cli, principal, domain); } #endif @@ -731,7 +731,7 @@ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, ntlmssp: - return cli_session_setup_ntlmssp(cli, user, pass, workgroup); + return cli_session_setup_ntlmssp(cli, user, pass, domain); } /**************************************************************************** -- cgit From 7d068355aae99060acac03c6633509545aa782a4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Jan 2004 08:19:18 +0000 Subject: This merges in my 'always use ADS' patch. Tested on a mix of NT and ADS domains, this patch ensures that we always use the ADS backend when security=ADS, and the remote server is capable. The routines used for this behaviour have been upgraded to modern Samba codeing standards. This is a change in behaviour for mixed mode domains, and if the trusted domain cannot be reached with our current krb5.conf file, we will show that domain as disconnected. This is in line with existing behaviour for native mode domains, and for our primary domain. As a consequence of testing this patch, I found that our kerberos error handling was well below par - we would often throw away useful error values. These changes move more routines to ADS_STATUS to return kerberos errors. Also found when valgrinding the setup, fix a few memory leaks. While sniffing the resultant connections, I noticed we would query our list of trusted domains twice - so I have reworked some of the code to avoid that. Andrew Bartlett (This used to be commit 7c34de8096b86d2869e7177420fe129bd0c7541d) --- source3/libsmb/cliconnect.c | 31 +++++++++++++++++-------------- source3/libsmb/clikrb5.c | 24 +++++++++++++----------- source3/libsmb/clispnego.c | 17 ++++++++++------- 3 files changed, 40 insertions(+), 32 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 1dc46ab0e6..707a33881d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -500,19 +500,22 @@ static void use_in_memory_ccache(void) { Do a spnego/kerberos encrypted session setup. ****************************************************************************/ -static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) +static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { DATA_BLOB blob2, negTokenTarg; DATA_BLOB session_key_krb5; DATA_BLOB null_blob = data_blob(NULL, 0); - + int rc; + DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - negTokenTarg = spnego_gen_negTokenTarg(principal, 0, &session_key_krb5); + rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5); - if (!negTokenTarg.data) - return NT_STATUS_UNSUCCESSFUL; + if (rc) { + DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc))); + return ADS_ERROR_KRB5(rc); + } #if 0 file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); @@ -531,10 +534,10 @@ static NTSTATUS cli_session_setup_kerberos(struct cli_state *cli, const char *pr if (cli_is_error(cli)) { if (NT_STATUS_IS_OK(cli_nt_error(cli))) { - return NT_STATUS_UNSUCCESSFUL; + return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL); } } - return NT_STATUS_OK; + return ADS_ERROR_NT(cli_nt_error(cli)); } #endif /* HAVE_KRB5 */ @@ -661,7 +664,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use Do a spnego encrypted session setup. ****************************************************************************/ -NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, +ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, const char *pass, const char *domain) { char *principal; @@ -689,7 +692,7 @@ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, reply */ if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { data_blob_free(&blob); - return NT_STATUS_INVALID_PARAMETER; + return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); } data_blob_free(&blob); @@ -719,7 +722,7 @@ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, if (ret){ DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); - return NT_STATUS_LOGON_FAILURE; + return ADS_ERROR_KRB5(ret); } } @@ -731,7 +734,7 @@ NTSTATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, ntlmssp: - return cli_session_setup_ntlmssp(cli, user, pass, domain); + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain)); } /**************************************************************************** @@ -812,9 +815,9 @@ BOOL cli_session_setup(struct cli_state *cli, /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { - NTSTATUS nt_status; - if (!NT_STATUS_IS_OK(nt_status = cli_session_setup_spnego(cli, user, pass, workgroup))) { - DEBUG(3, ("SPENGO login failed: %s\n", get_friendly_nt_error_msg(nt_status))); + ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup); + if (!ADS_ERR_OK(status)) { + DEBUG(3, ("SPENGO login failed: %s\n", ads_errstr(status))); return False; } return True; diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5568b5e033..15b244a83d 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -307,14 +307,14 @@ cleanup_princ: /* get a kerberos5 ticket for the given service */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5) +int cli_krb5_get_ticket(const char *principal, time_t time_offset, + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) { krb5_error_code retval; krb5_data packet; krb5_ccache ccdef; krb5_context context; krb5_auth_context auth_context = NULL; - DATA_BLOB ret; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC ENCTYPE_ARCFOUR_HMAC, @@ -356,17 +356,18 @@ DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BL get_krb5_smb_session_key(context, auth_context, session_key_krb5, False); - ret = data_blob(packet.data, packet.length); + *ticket = data_blob(packet.data, packet.length); + /* Hmm, heimdal dooesn't have this - what's the correct call? */ -/* krb5_free_data_contents(context, &packet); */ - krb5_free_context(context); - return ret; +#ifdef HAVE_KRB5_FREE_DATA_CONTENTS + krb5_free_data_contents(context, &packet); +#endif failed: if ( context ) krb5_free_context(context); - return data_blob(NULL, 0); + return retval; } BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) @@ -410,10 +411,11 @@ failed: #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -DATA_BLOB cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *session_key_krb5) - { +int cli_krb5_get_ticket(const char *principal, time_t time_offset, + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) +{ DEBUG(0,("NO KERBEROS SUPPORT\n")); - return data_blob(NULL, 0); - } + return 1; +} #endif diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 92543736ff..e6cadc466c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -323,27 +323,30 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *session_key_krb5) +int spnego_gen_negTokenTarg(const char *principal, int time_offset, + DATA_BLOB *targ, + DATA_BLOB *session_key_krb5) { - DATA_BLOB tkt, tkt_wrapped, targ; + int retval; + DATA_BLOB tkt, tkt_wrapped; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service and extract the session key */ - tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5); + retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5); - if (tkt.data == NULL) - return tkt; + if (retval) + return retval; /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ - targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); + *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); data_blob_free(&tkt_wrapped); data_blob_free(&tkt); - return targ; + return retval; } -- cgit From 9e1c7dd51668961a4aed04900902989cdf338cec Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Jan 2004 02:38:58 +0000 Subject: Add a new type of name lookup 'ads'. This seperates this from normal hostname lookups, and ensures that we don't lookup 'short' (ie NetBIOS) domain names in DNS. Andrew Bartlett (This used to be commit 35f6347a73ce7423adb78c7e95492bb6d98f4c40) --- source3/libsmb/namequery.c | 92 +++++++++++++++++++++++++++++----------------- 1 file changed, 59 insertions(+), 33 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c7cc4848b7..dfc3bcd93f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -680,6 +680,8 @@ BOOL name_resolve_bcast(const char *name, int name_type, return False; } + SMB_ASSERT(strchr_m(name, '.') == NULL); + *return_iplist = NULL; *return_count = 0; @@ -742,6 +744,8 @@ BOOL resolve_wins(const char *name, int name_type, return False; } + SMB_ASSERT(strchr_m(name, '.') == NULL); + *return_iplist = NULL; *return_count = 0; @@ -884,6 +888,40 @@ static BOOL resolve_hosts(const char *name, int name_type, */ struct hostent *hp; + if ( name_type != 0x20 && name_type != 0x0) { + DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type)); + return False; + } + + *return_iplist = NULL; + *return_count = 0; + + DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type)); + + if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + struct in_addr return_ip; + putip((char *)&return_ip,(char *)hp->h_addr); + *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service)); + if(*return_iplist == NULL) { + DEBUG(3,("resolve_hosts: malloc fail !\n")); + return False; + } + (*return_iplist)->ip = return_ip; + (*return_iplist)->port = PORT_NONE; + *return_count = 1; + return True; + } + return False; +} + +/******************************************************** + Resolve via "ADS" method. +*********************************************************/ + +static BOOL resolve_ads(const char *name, int name_type, + struct ip_service **return_iplist, int *return_count) +{ + #ifdef HAVE_ADS if ( name_type == 0x1c ) { int count, i = 0; @@ -895,6 +933,8 @@ static BOOL resolve_hosts(const char *name, int name_type, if ( lp_security() != SEC_ADS ) return False; + SMB_ASSERT(strchr_m(name, '.') != NULL); + DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n", name)); @@ -935,28 +975,11 @@ static BOOL resolve_hosts(const char *name, int name_type, *return_count = i; return True; - } + } else #endif /* HAVE_ADS */ - - *return_iplist = NULL; - *return_count = 0; - - DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name)); - - if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { - struct in_addr return_ip; - putip((char *)&return_ip,(char *)hp->h_addr); - *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service)); - if(*return_iplist == NULL) { - DEBUG(3,("resolve_hosts: malloc fail !\n")); - return False; - } - (*return_iplist)->ip = return_ip; - (*return_iplist)->port = PORT_NONE; - *return_count = 1; - return True; + { + return False; } - return False; } /******************************************************************* @@ -1034,14 +1057,17 @@ static BOOL internal_resolve_name(const char *name, int name_type, while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { - /* deal with 0x20 & 0x1c names here. The latter will result - in a SRV record lookup for _ldap._tcp. if we are using - 'security = ads' */ - if ( name_type==0x20 || name_type == 0x1c ) { - if (resolve_hosts(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } + if (resolve_hosts(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "ads")) { + /* deal with 0x1c names here. This will result in a + SRV record lookup for _ldap._tcp. if we + are using 'security = ads' */ + if (resolve_ads(name, name_type, return_iplist, return_count)) { + result = True; + goto done; } } else if(strequal( tok, "lmhosts")) { if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { @@ -1207,14 +1233,14 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) /********************************************************************* small wrapper function to get the DC list and sort it if neccessary *********************************************************************/ -BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL dns_only ) +BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) { BOOL ordered; DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", - (dns_only ? "hosts" : lp_name_resolve_order()))); + (ads_only ? "ads" : lp_name_resolve_order()))); - if ( !get_dc_list(domain, ip_list, count, dns_only, &ordered) ) + if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) return False; /* only sort if we don't already have an ordered list */ @@ -1230,11 +1256,11 @@ BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *c *********************************************************/ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, - int *count, BOOL dns_only, int *ordered) + int *count, BOOL ads_only, int *ordered) { /* defined the name resolve order to internal_name_resolve() only used for looking up 0x1c names */ - const char *resolve_oder = (dns_only ? "hosts" : lp_name_resolve_order()); + const char *resolve_oder = (ads_only ? "ads" : lp_name_resolve_order()); *ordered = False; -- cgit From f1f24c7c6fbf6c55e807e1ddbc7e555744df3110 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Jan 2004 02:47:35 +0000 Subject: Romve debugging assertions (oops...) Andrew Bartlett (This used to be commit 7e75a6d681fc63cacc7e5caa7a04568c6019367f) --- source3/libsmb/namequery.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index dfc3bcd93f..83902971b0 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -680,8 +680,6 @@ BOOL name_resolve_bcast(const char *name, int name_type, return False; } - SMB_ASSERT(strchr_m(name, '.') == NULL); - *return_iplist = NULL; *return_count = 0; @@ -744,8 +742,6 @@ BOOL resolve_wins(const char *name, int name_type, return False; } - SMB_ASSERT(strchr_m(name, '.') == NULL); - *return_iplist = NULL; *return_count = 0; @@ -933,8 +929,6 @@ static BOOL resolve_ads(const char *name, int name_type, if ( lp_security() != SEC_ADS ) return False; - SMB_ASSERT(strchr_m(name, '.') != NULL); - DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n", name)); -- cgit From 500c28974ded4c4789d9f197de5860b20447e606 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 9 Jan 2004 14:54:33 +0000 Subject: fix some warnings from the Sun compiler (This used to be commit ebabf72a78f0165521268b73e0fcabe1ea7834fd) --- source3/libsmb/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 40d7f41109..a80b4b66b0 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -974,7 +974,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); DEBUG(5, ("challenge is: \n")); - dump_data(5, session_nonce_hash, 8); + dump_data(5, (const char *)session_nonce_hash, 8); nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt(ntlmssp_state->password, -- cgit From b085f0f08eb66fd5741b6cb221fbfa67504514f2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 13 Jan 2004 19:42:53 +0000 Subject: * allow dns lookups to be disabled for DOMAIN#1c (and #1b) names * fix some a mispelled variable name (This used to be commit bca702c97620ad8f66015d6e4b41abd4adf22076) --- source3/libsmb/namequery.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 83902971b0..dcbd11048e 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1036,6 +1036,11 @@ static BOOL internal_resolve_name(const char *name, int name_type, } /* set the name resolution order */ + + if ( strcmp( resolve_order, "NULL") == 0 ) { + DEBUG(8,("internal_resolve_name: all lookups disabled\n")); + return False; + } if ( !resolve_order ) pstrcpy(name_resolve_list, lp_name_resolve_order()); @@ -1252,9 +1257,23 @@ BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *c BOOL get_dc_list(const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only, int *ordered) { - /* defined the name resolve order to internal_name_resolve() - only used for looking up 0x1c names */ - const char *resolve_oder = (ads_only ? "ads" : lp_name_resolve_order()); + fstring resolve_order; + + /* if we are restricted to solely using DNS for looking + up a domain controller, make sure that host lookups + are enabled for the 'name resolve order'. If host lookups + are disabled and ads_only is True, then set the string to + NULL. */ + + fstrcpy( resolve_order, lp_name_resolve_order() ); + strlower_m( resolve_order ); + if ( ads_only ) { + if ( strstr( resolve_order, "host" ) ) + fstrcpy( resolve_order, "ads" ); + else + fstrcpy( resolve_order, "NULL" ); + } + *ordered = False; @@ -1275,7 +1294,7 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, if (!*pserver) - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder); + return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); p = pserver; @@ -1288,7 +1307,7 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) { - if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_oder) ) + if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) ) num_addresses += auto_count; done_auto_lookup = True; DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); @@ -1301,7 +1320,7 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, just return the list of DC's */ if ( (num_addresses == 0) && !done_auto_lookup ) - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder); + return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); /* maybe we just failed? */ @@ -1382,5 +1401,5 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, DEBUG(10,("get_dc_list: defaulting to internal auto lookup for domain %s\n", domain)); - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_oder); + return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); } -- cgit From b20f1a95a90033f711a26fdeeb49eaf3059ad91d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Jan 2004 19:03:18 +0000 Subject: * BUG 446 - setup_logging() in smbclient to be interactive (remove the timestamps) - Fix bad return value in pull_ucs2( needs more testing to make sure this didn't break something else) that caused clistr_pull() to always read the same string from the buffer (pull_usc2() could return -1 if the original source length was given as -1) - increment some debugging messages to avoid printing them out so often (This used to be commit 79fe75dcdf6cc38e18ca1231e4357893db4d4a08) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 707a33881d..84159e5d62 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -673,7 +673,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, BOOL got_kerberos_mechanism = False; DATA_BLOB blob; - DEBUG(2,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); + DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); /* the server might not even do spnego */ if (cli->secblob.length <= 16) { -- cgit From bb1119acca3f0735ca57871015d499d2358c9fb2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Jan 2004 00:30:35 +0000 Subject: Fix for a signing bug when the mid wraps. Found by Fran Fabrizio . Add to the *start* of the list not the end of the list. This ensures that the *last* send sequence with this mid is returned by preference. This can happen if the mid wraps and one of the early mid numbers didn't get a reply and is still lurking on the list. Jeremy. (This used to be commit 25d739978fe9081ba0946c36901492127248e3e0) --- source3/libsmb/smb_signing.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8a056f659f..9010dbf5cb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -46,15 +46,23 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; - struct outstanding_packet_lookup *tmp; - + t = smb_xmalloc(sizeof(*t)); ZERO_STRUCTP(t); - DLIST_ADD_END(*list, t, tmp); t->mid = mid; t->reply_seq_num = reply_seq_num; + /* + * Add to the *start* of the list not the end of the list. + * This ensures that the *last* send sequence with this mid + * is returned by preference. + * This can happen if the mid wraps and one of the early + * mid numbers didn't get a reply and is still lurking on + * the list. JRA. Found by Fran Fabrizio . + */ + + DLIST_ADD(*list, t); DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", (unsigned int)reply_seq_num, (unsigned int)mid )); } -- cgit From b31ec210fc27f8ba03ee34367d50a83aab557847 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 25 Jan 2004 01:11:10 +0000 Subject: Fix the initialisation vectors for NTLM2, so that they at least make sense, even if they don't work yet. Andrew Bartlett (This used to be commit 636b98dab9bc27f55bdc65d7dedb58cdf8d8563b) --- source3/libsmb/ntlmssp_sign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 6ce7a76743..2347619e57 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -362,14 +362,14 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, ntlmssp_state->recv_sign_const, - ntlmssp_state->session_key, send_sign_const); + ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP receive sign hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, ntlmssp_state->recv_seal_const, - ntlmssp_state->session_key, send_seal_const); + ntlmssp_state->session_key, recv_seal_const); dump_data_pw("NTLMSSP receive seal hash:\n", ntlmssp_state->recv_sign_hash, sizeof(ntlmssp_state->recv_sign_hash)); -- cgit From 784b05c4895fa8d7f5215d4444bc74e91a918114 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 26 Jan 2004 08:45:02 +0000 Subject: This adds client-side support for the unicode/SAMR password change scheme. As well as avoiding DOS charset issues, this scheme returns useful error codes, that we can map back via the pam interface. This patch also cleans up the interfaces used for password buffers, to avoid duplication of code. Andrew Bartlett (This used to be commit 2a2b1f0c872d154fbcce71a250e23dfad085ba1e) --- source3/libsmb/clirap.c | 12 ++++--- source3/libsmb/passchange.c | 88 ++++++++++++++++++++++++++++++++++++--------- source3/libsmb/smbencrypt.c | 68 ++++++++++++++++++----------------- 3 files changed, 113 insertions(+), 55 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 79ad38fc8c..36bc403e0b 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -291,7 +291,6 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char char *rparam = NULL; char *rdata = NULL; unsigned int rprcnt, rdrcnt; - pstring dos_new_password; if (strlen(user) >= sizeof(fstring)-1) { DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); @@ -317,10 +316,13 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char */ E_deshash(old_password, old_pw_hash); - clistr_push(cli, dos_new_password, new_password, sizeof(dos_new_password), STR_TERMINATE|STR_ASCII); - - if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False)) - return False; + encode_pw_buffer(data, new_password, STR_ASCII); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("make_oem_passwd_hash\n")); + dump_data(100, data, 516); +#endif + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); /* * Now place the old password hash in the data. diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 41b6095520..dc0cbbcb7c 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -30,6 +30,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, struct nmb_name calling, called; struct cli_state cli; struct in_addr ip; + struct ntuser_creds creds; + + NTSTATUS result; *err_str = '\0'; @@ -66,18 +69,28 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - /* - * We should connect as the anonymous user here, in case - * the server has "must change password" checked... - * Thanks to for this fix. - */ + /* Given things like SMB signing, restrict anonymous and the like, + try an authenticated connection first */ + if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { + /* + * We should connect as the anonymous user here, in case + * the server has "must change password" checked... + * Thanks to for this fix. + */ - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { - slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + + init_creds(&creds, "", "", NULL); + cli_init_creds(&cli, &creds); + } else { + init_creds(&creds, user_name, "", old_passwd); + cli_init_creds(&cli, &creds); + } if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", @@ -86,13 +99,54 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - if(!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } + /* Try not to give the password away to easily */ + + cli.pipe_auth_flags = AUTH_PIPE_NTLMSSP; + cli.pipe_auth_flags |= AUTH_PIPE_SIGN; + cli.pipe_auth_flags |= AUTH_PIPE_SEAL; + if ( !cli_nt_session_open( &cli, PI_SAMR ) ) { + if (lp_client_lanman_auth()) { + if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", + remote_machine); + cli_shutdown(&cli); + return False; + } + } + + if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name, + new_passwd, old_passwd))) { + + if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) + || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { + /* try the old Lanman method */ + if (lp_client_lanman_auth()) { + if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", + remote_machine); + cli_shutdown(&cli); + return False; + } + } else { + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, get_friendly_nt_error_msg(result)); + cli_shutdown(&cli); + return False; + } + } cli_shutdown(&cli); return True; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index cfcc24a1df..1d192b816a 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -70,20 +70,29 @@ void E_md4hash(const char *passwd, uchar p16[16]) * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. * @param p16 return password hashed with DES, caller allocated 16 byte buffer + * @return False if password was > 14 characters, and therefore may be incorrect, otherwise True + * @note p16 is filled in regardless */ -void E_deshash(const char *passwd, uchar p16[16]) +BOOL E_deshash(const char *passwd, uchar p16[16]) { + BOOL ret = True; fstring dospwd; ZERO_STRUCT(dospwd); /* Password must be converted to DOS charset - null terminated, uppercase. */ push_ascii(dospwd, passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE); - + /* Only the fisrt 14 chars are considered, password need not be null terminated. */ E_P16((const unsigned char *)dospwd, p16); + if (strlen(dospwd) > 14) { + ret = False; + } + ZERO_STRUCT(dospwd); + + return ret; } /** @@ -219,24 +228,7 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) { - int new_pw_len = strlen(passwd) * (unicode ? 2 : 1); - - if (new_pw_len > 512) - { - DEBUG(0,("make_oem_passwd_hash: new password is too long.\n")); - return False; - } - - /* - * Now setup the data area. - * We need to generate a random fill - * for this area to make it harder to - * decrypt. JRA. - */ - generate_random_buffer((unsigned char *)data, 516, False); - push_string(NULL, &data[512 - new_pw_len], passwd, new_pw_len, - STR_NOALIGN | (unicode?STR_UNICODE:STR_ASCII)); - SIVAL(data, 512, new_pw_len); + encode_pw_buffer(data, passwd, (unicode?STR_UNICODE:STR_ASCII)); #ifdef DEBUG_PASSWORD DEBUG(100,("make_oem_passwd_hash\n")); @@ -473,37 +465,46 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password } /*********************************************************** - encode a password buffer. The caller gets to figure out - what to put in it. + encode a password buffer with a unicode password. The buffer + is filled with random data to make it harder to attack. ************************************************************/ -BOOL encode_pw_buffer(char buffer[516], char *new_pw, int new_pw_length) +BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) { - generate_random_buffer((unsigned char *)buffer, 516, True); + uchar new_pw[512]; + size_t new_pw_len; - memcpy(&buffer[512 - new_pw_length], new_pw, new_pw_length); + new_pw_len = push_string(NULL, new_pw, + password, + sizeof(new_pw), string_flags); + + memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); + + generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, True); /* * The length of the new password is in the last 4 bytes of * the data buffer. */ - SIVAL(buffer, 512, new_pw_length); - + SIVAL(buffer, 512, new_pw_len); + ZERO_STRUCT(new_pw); return True; } + /*********************************************************** decode a password buffer *new_pw_len is the length in bytes of the possibly mulitbyte returned password including termination. ************************************************************/ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len) + int new_pwrd_size, uint32 *new_pw_len, + int string_flags) { int byte_len=0; /* Warning !!! : This function is called from some rpc call. - The password IN the buffer is a UNICODE string. + The password IN the buffer may be a UNICODE string. The password IN new_pwrd is an ASCII string If you reuse that code somewhere else check first. */ @@ -516,15 +517,16 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, dump_data(100, in_buffer, 516); #endif - /* Password cannot be longer than 128 characters */ - if ( (byte_len < 0) || (byte_len > new_pwrd_size - 1)) { + /* Password cannot be longer than the size of the password buffer */ + if ( (byte_len < 0) || (byte_len > 512)) { DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); return False; } - /* decode into the return buffer. Buffer must be a pstring */ - *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, byte_len, STR_UNICODE); + /* decode into the return buffer. Buffer length supplied */ + *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + byte_len, string_flags); #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); -- cgit From 2f2e5b01919fe4daf60f97430959ebc98e31ce92 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Jan 2004 18:38:48 +0000 Subject: Fix up name canonicalization (needed for krb5 keytab support later). Remove source_env handler (no longer used in any codepath). Jeremy. (This used to be commit 3a3e33603084048e647af86a9badaaf49433c789) --- source3/libsmb/ntlmssp.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index a80b4b66b0..60523ddf9d 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -433,12 +433,11 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname[0] = '\0'; - get_mydomname(dnsdomname); + get_mydnsdomname(dnsdomname); strlower_m(dnsdomname); dnsname[0] = '\0'; - get_myfullname(dnsname); - strlower_m(dnsname); + get_mydnsfullname(dnsname); /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) -- cgit From e45c217a14c0c6cb2456f04138b2fd55288b1dd4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 00:54:32 +0000 Subject: Make get_dc_list static - we only ask for a sorted list externally. Andrew Bartlett (This used to be commit e10e176c83da9eda0746e0bd108c72a01a0505e8) --- source3/libsmb/namequery.c | 47 +++++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index dcbd11048e..8bde6d37ea 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -230,7 +230,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t comparison function used by sort_ip_list */ -int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) { int max_bits1=0, max_bits2=0; int num_interfaces = iface_count(); @@ -292,7 +292,7 @@ static void sort_ip_list(struct in_addr *iplist, int count) qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); } -void sort_ip_list2(struct ip_service *iplist, int count) +static void sort_ip_list2(struct ip_service *iplist, int count) { if (count <= 1) { return; @@ -1229,32 +1229,12 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) return True; } -/********************************************************************* - small wrapper function to get the DC list and sort it if neccessary -*********************************************************************/ -BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) -{ - BOOL ordered; - - DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", - (ads_only ? "ads" : lp_name_resolve_order()))); - - if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) - return False; - - /* only sort if we don't already have an ordered list */ - if ( !ordered ) - sort_ip_list2( *ip_list, *count ); - - return True; -} - /******************************************************** Get the IP address list of the domain controllers for a domain. *********************************************************/ -BOOL get_dc_list(const char *domain, struct ip_service **ip_list, +static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only, int *ordered) { fstring resolve_order; @@ -1403,3 +1383,24 @@ BOOL get_dc_list(const char *domain, struct ip_service **ip_list, return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); } + +/********************************************************************* + small wrapper function to get the DC list and sort it if neccessary +*********************************************************************/ +BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) +{ + BOOL ordered; + + DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", + (ads_only ? "ads" : lp_name_resolve_order()))); + + if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) + return False; + + /* only sort if we don't already have an ordered list */ + if ( !ordered ) + sort_ip_list2( *ip_list, *count ); + + return True; +} + -- cgit From 7540296fd491f4a474d7afa823f7ca522aa2f390 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 00:58:56 +0000 Subject: Remove unused utility function. Andrew Bartlett (This used to be commit 4c4aa80177e05ed7900e9f24673a62064128c736) --- source3/libsmb/smbencrypt.c | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 1d192b816a..c5acedae51 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -226,19 +226,6 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) #endif } -BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode) -{ - encode_pw_buffer(data, passwd, (unicode?STR_UNICODE:STR_ASCII)); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("make_oem_passwd_hash\n")); - dump_data(100, data, 516); -#endif - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); - - return True; -} - /* Does the md5 encryption from the Key Response for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], const DATA_BLOB *srv_chal, -- cgit From fac5f989d3e7ca34ceac692a1d2a5de9e4ac4f23 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 02:49:30 +0000 Subject: Remove more unused functions - this time parts of the 'password cache'. Andrew Bartlett (This used to be commit 66569546e8cbb06b6de7e1ac5b2ebf662ea026de) --- source3/libsmb/pwd_cache.c | 45 --------------------------------------------- 1 file changed, 45 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 7ba6cfc96f..27ca4ddf57 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -80,51 +80,6 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) } -/**************************************************************************** - Gets lm and nt hashed passwords. -****************************************************************************/ - -void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16]) -{ - if (lm_pwd != NULL) - memcpy(lm_pwd, pwd->smb_lm_pwd, 16); - if (nt_pwd != NULL) - memcpy(nt_pwd, pwd->smb_nt_pwd, 16); -} - -/**************************************************************************** - Makes lm and nt OWF crypts. -****************************************************************************/ - -void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8]) -{ - -#ifdef DEBUG_PASSWORD - DEBUG(100,("client cryptkey: ")); - dump_data(100, (char *)cryptkey, 8); -#endif - - SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("nt_owf_passwd: ")); - dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf)); - DEBUG(100,("nt_sess_pwd: ")); - dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd)); -#endif - - SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf); - -#ifdef DEBUG_PASSWORD - DEBUG(100,("lm_owf_passwd: ")); - dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf)); - DEBUG(100,("lm_sess_pwd: ")); - dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd)); -#endif - - pwd->crypted = True; -} - /**************************************************************************** Gets lm and nt crypts. ****************************************************************************/ -- cgit From a69cb9c9639dc06a0be16958cbc29867b71f584e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Feb 2004 05:31:01 +0000 Subject: Remove more unused portions of the 'password cache'. Andrew Bartlett (This used to be commit 318e11748a86d92bfc6ebf0e58f3c8360cbf4b69) --- source3/libsmb/pwd_cache.c | 42 ++++++------------------------------------ 1 file changed, 6 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 27ca4ddf57..e010f226a0 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -27,43 +27,24 @@ static void pwd_init(struct pwd_info *pwd) { memset((char *)pwd->password , '\0', sizeof(pwd->password )); - memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd)); - memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd)); - memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf)); - memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf)); pwd->null_pwd = True; /* safest option... */ - pwd->cleartext = False; - pwd->crypted = False; } /**************************************************************************** - Makes lm and nt hashed passwords. + Stores a cleartext password. ****************************************************************************/ -static void pwd_make_lm_nt_16(struct pwd_info *pwd, const char *clr) +void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) { pwd_init(pwd); - - if (!clr) { - ZERO_STRUCT(pwd->smb_nt_pwd); - ZERO_STRUCT(pwd->smb_lm_pwd); - pwd->null_pwd = True; + if (clr) { + fstrcpy(pwd->password, clr); + pwd->null_pwd = False; } else { - nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd); - pwd->null_pwd = False; + pwd->null_pwd = True; } - pwd->crypted = False; -} - -/**************************************************************************** - Stores a cleartext password. -****************************************************************************/ -void pwd_set_cleartext(struct pwd_info *pwd, const char *clr) -{ - pwd_make_lm_nt_16(pwd, clr); - fstrcpy(pwd->password, clr); pwd->cleartext = True; } @@ -80,14 +61,3 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) } -/**************************************************************************** - Gets lm and nt crypts. -****************************************************************************/ - -void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24]) -{ - if (lm_owf != NULL) - memcpy(lm_owf, pwd->smb_lm_owf, 24); - if (nt_owf != NULL) - memcpy(nt_owf, pwd->smb_nt_owf, 24); -} -- cgit From 57dacbe948e10797776eaf214eaf393983ebda55 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Feb 2004 02:21:38 +0000 Subject: Fix for possible crash bug from Sebastian Krahmer (SuSE). Jeremy. (This used to be commit e275835b516ec2e319ad5a6943be007d34a55d75) --- source3/libsmb/ntlmssp_parse.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 3444db0306..4b3043aec8 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -216,7 +216,9 @@ BOOL msrpc_parse(const DATA_BLOB *blob, /* if odd length and unicode */ return False; } - + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + if (0 < len1) { pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, @@ -241,7 +243,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } - + + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + if (0 < len1) { pull_string(NULL, p, blob->data + ptr, sizeof(p), len1, @@ -266,6 +271,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { return False; } + + if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + return False; + *b = data_blob(blob->data + ptr, len1); } break; @@ -274,6 +283,9 @@ BOOL msrpc_parse(const DATA_BLOB *blob, len1 = va_arg(ap, unsigned); /* make sure its in the right format - be strict */ NEED_DATA(len1); + if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) + return False; + *b = data_blob(blob->data + head_ofs, len1); head_ofs += len1; break; @@ -284,6 +296,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); + + if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) + return False; + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), blob->length - head_ofs, STR_ASCII|STR_TERMINATE); -- cgit From 987083010441d091d693d6114a7015d5f05d6cd7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Feb 2004 19:59:17 +0000 Subject: Paranoia fixes :-). Jeremy. (This used to be commit 86b030197db63ac0a04b8ea877d80a3d74a7a187) --- source3/libsmb/asn1.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 576491dd3b..17170b015f 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -365,6 +365,10 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) int len; if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } *s = malloc(len+1); if (! *s) { data->has_error = True; @@ -383,6 +387,10 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) ZERO_STRUCTP(blob); if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; len = asn1_tag_remaining(data); + if (len < 0) { + data->has_error = True; + return False; + } *blob = data_blob(NULL, len); asn1_read(data, blob->data, len); asn1_end_tag(data); -- cgit From 9860bfe384dcdc578fb793bbc0736e51131fe9a2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Feb 2004 23:25:51 +0000 Subject: More paranoia checks. Jeremy. (This used to be commit adf8ee3df75b8336d14ad093ad2ebc3a480d0017) --- source3/libsmb/asn1.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 17170b015f..ecc5e3dee6 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -219,6 +219,11 @@ BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) /* read from a ASN1 buffer, advancing the buffer pointer */ BOOL asn1_read(ASN1_DATA *data, void *p, int len) { + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { + data->has_error = True; + return False; + } + if (data->ofs + len > data->length) { data->has_error = True; return False; -- cgit From 7d7849b18a625820b1fba05bd17a718c7f98837e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Feb 2004 22:45:53 +0000 Subject: Make us bug-for-bug compatible with W2K3 - to get delete on close semantics on an initial open the desired_access field *must* contain DELETE_ACCESS, simply having it map from a GENERIC_ALL won't do. Fixes delete on close test. Jeremy. (This used to be commit 5c6f8b1053fd1f170fbb76640649653f8aa80f18) --- source3/libsmb/clirap.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 36bc403e0b..c4b08d21d8 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -631,7 +631,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, /**************************************************************************** send a qfileinfo call ****************************************************************************/ -BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdata) +BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -639,9 +639,13 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat pstring param; char *rparam=NULL, *rdata=NULL; + *poutdata = NULL; + *poutlen = 0; + /* if its a win95 server then fail this - win95 totally screws it up */ - if (cli->win95) return False; + if (cli->win95) + return False; param_len = 4; @@ -665,7 +669,8 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char *outdat return False; } - memcpy(outdata, rdata, data_len); + memdup(poutdata, data_len); + *poutlen = data_len; SAFE_FREE(rdata); SAFE_FREE(rparam); -- cgit From ef8f8274492c142765a94cc453d3da640c9fef91 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 20 Feb 2004 23:19:39 +0000 Subject: Make SMB_FILE_ACCESS_INFORMATION call work correctly. Jeremy. (This used to be commit 0ea0ada6c609e1bb0fb4aace24e1beb7197495b5) --- source3/libsmb/clirap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index c4b08d21d8..9c10e9d938 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -669,7 +669,7 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd return False; } - memdup(poutdata, data_len); + *poutdata = memdup(rdata, data_len); *poutlen = data_len; SAFE_FREE(rdata); -- cgit From 24df38dbc6648261f86adcffd664ffc43f8f3346 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 23 Feb 2004 02:54:03 +0000 Subject: Janitor for tpot...bugzilla #1098, msleep already exists on aix (This used to be commit 4319df7fdc2d878c509381923cc1db4d731620ba) --- source3/libsmb/clilist.c | 2 +- source3/libsmb/clirap.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2c1831ae99..ab157d48e9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -232,7 +232,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); + smb_msleep(100); continue; } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 9c10e9d938..f8204e05d6 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -408,7 +408,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, uint32 ecode; cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); + smb_msleep(100); } } while (count-- && ret==False); @@ -720,7 +720,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin uint32 ecode; cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); + smb_msleep(100); } } while (count-- && ret==False); -- cgit From 0689a2630d920d2cc4a27c2c6617693cff549271 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2004 10:55:43 +0000 Subject: Apply some const Volker (This used to be commit 0b29d83d33153dc0e49406efa6735b6664d88ce7) --- source3/libsmb/clirap.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index f8204e05d6..98066629d1 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -206,8 +206,9 @@ The callback function takes 4 arguments: the machine name, the server type, the comment and a state pointer. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *, void *), - void *state) + void (*fn)(const char *, uint32, const char *, + const void *), + const void *state) { char *rparam = NULL; char *rdata = NULL; -- cgit From e1190848a17fc54b479315b5f11238461bc3fa62 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 26 Feb 2004 14:34:44 +0000 Subject: That const was one too many (This used to be commit 005d92d57ea912b68dd107152d478fae2162511a) --- source3/libsmb/clirap.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 98066629d1..f8204e05d6 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -206,9 +206,8 @@ The callback function takes 4 arguments: the machine name, the server type, the comment and a state pointer. ****************************************************************************/ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, - void (*fn)(const char *, uint32, const char *, - const void *), - const void *state) + void (*fn)(const char *, uint32, const char *, void *), + void *state) { char *rparam = NULL; char *rdata = NULL; -- cgit From 3fb52e5cc0fe632584704e807dde5f0ae6612413 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 28 Feb 2004 01:53:30 +0000 Subject: Can't set allocation size on directories, return correct error code on fail if file exists and target is a directory. gentest. Jeremy. (This used to be commit f4a7ea6dc2b9f379a9c735670a49ac63818754c7) --- source3/libsmb/errormap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 116d2cefe1..aeb68b6596 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1503,6 +1503,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY }, + { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, #ifdef EDQUOT { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, #endif -- cgit From fba5a722497c1e4577aa463921a0fec5f6d5fe55 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Mar 2004 20:55:59 +0000 Subject: Use a common function to parse all pathnames from the wire. This allows much closer emulation of Win2k3 error return codes. Jeremy. (This used to be commit c9f31fafeda6ad79e590276f36e03ecd2e93f818) --- source3/libsmb/clifile.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index c7f0cdb84b..9b766987ef 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -223,6 +223,44 @@ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ return True; } +/**************************************************************************** + NT Rename a file. +****************************************************************************/ + +BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 4, 0, True); + + SCVAL(cli->outbuf,smb_com,SMBntrename); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); + SSVAL(cli->outbuf,smb_vwv1, RENAME_FLAG_RENAME); + + p = smb_buf(cli->outbuf); + *p++ = 4; + p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + *p++ = 4; + p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + if (cli_is_error(cli)) + return False; + + return True; +} + /**************************************************************************** Delete a file. ****************************************************************************/ -- cgit From f0039da19654f0d75617e96d67054d1d1990515d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Mar 2004 23:14:23 +0000 Subject: Added client "hardlink" commant to test doing NT rename with hard links. Added hardlink_internals() code - UNIX extensions now use this too. Jeremy. (This used to be commit aad6eb2240393931940c982e25a981ce32264f38) --- source3/libsmb/clifile.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 9b766987ef..a3fa811e29 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -36,16 +36,18 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, cons pstring data; char *rparam=NULL, *rdata=NULL; char *p; + size_t srclen = 2*(strlen(fname_src)+1); + size_t destlen = 2*(strlen(fname_dst) + 1); memset(param, 0, sizeof(param)); SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK); p = ¶m[6]; - p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_src, MIN(srclen, sizeof(param)-6), STR_TERMINATE); param_len = PTR_DIFF(p, param); p = data; - p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_dst, MIN(destlen,sizeof(data)), STR_TERMINATE); data_len = PTR_DIFF(p, data); if (!cli_send_trans(cli, SMBtrans2, @@ -261,6 +263,44 @@ BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam return True; } +/**************************************************************************** + NT hardlink a file. +****************************************************************************/ + +BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf, 4, 0, True); + + SCVAL(cli->outbuf,smb_com,SMBntrename); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN | aDIR); + SSVAL(cli->outbuf,smb_vwv1, RENAME_FLAG_HARD_LINK); + + p = smb_buf(cli->outbuf); + *p++ = 4; + p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + *p++ = 4; + p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) + return False; + + if (cli_is_error(cli)) + return False; + + return True; +} + /**************************************************************************** Delete a file. ****************************************************************************/ -- cgit From e3f5b542707e2328030b9d5eff0836a904eccde5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Mar 2004 22:48:24 +0000 Subject: Restore the contract on all convert_stringXX() interfaces. Add a "allow_bad_conv" boolean parameter that allows broken iconv conversions to work. Gets rid of the nasty errno checks in mangle_hash2 and check_path_syntax and allows correct return code checking. Jeremy. (This used to be commit 7b96765c23637613f079d37566d95d5edd511f05) --- source3/libsmb/climessage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 035088212c..8429ca4f41 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -87,7 +87,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) p = smb_buf(cli->outbuf); *p++ = 1; - if ((lendos = convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **) &msgdos)) < 0 || !msgdos) { + if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **) &msgdos, True)) < 0 || !msgdos) { DEBUG(3,("Conversion failed, sending message in UNIX charset\n")); SSVAL(p, 0, len); p += 2; memcpy(p, msg, len); -- cgit From 220d663b744107e03a278b564f4e00712a6fcffe Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Fri, 12 Mar 2004 21:35:15 +0000 Subject: if we are truncating to the . we need to start at the beginning in case there are multiple "."'s in the name. This code is protected with an #ifdef TRUNCATE_NETBIOS_NAME and this is #define'd to 1 directly above. Should we also get rid of the #ifdef? (This used to be commit 0375dace248eb3dc660fa2bca2808552e502b3f7) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index ff38245435..d0ea57dc1c 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1116,7 +1116,7 @@ char *dns_to_netbios_name(char *dns_name) netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 15; i >= 0; i--) + for (i = 0; i >= 15; i--) { if (netbios_name[i] == '.') { -- cgit From fd2d4f87d440f24df0adc4cc29f22051536b0dee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 00:28:53 +0000 Subject: First part of patch from moriyama@miraclelinux.com (MORIYAMA Masayuki) to fix up netbios names with mb strings. Includes reformat of libsmb/nmblib.c so it's readable. Jeremy. (This used to be commit 966e49a48c352563cdd7f75fe2768f2d6612ec7e) --- source3/libsmb/namequery.c | 2 +- source3/libsmb/nmblib.c | 1659 +++++++++++++++++++++++--------------------- 2 files changed, 855 insertions(+), 806 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 8bde6d37ea..b6d1f8bda2 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -202,7 +202,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE); + pull_ascii_nstring(name, status[i].name); /* Store the result in the cache. */ /* but don't store an entry for 0x1c names here. Here we have diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d0ea57dc1c..cbe495cd95 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -39,274 +39,289 @@ static const struct opcode_names { }; /**************************************************************************** - * Lookup a nmb opcode name. - ****************************************************************************/ + Lookup a nmb opcode name. +****************************************************************************/ + static const char *lookup_opcode_name( int opcode ) { - const struct opcode_names *op_namep; - int i; - - for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { - op_namep = &nmb_header_opcode_names[i]; - if(opcode == op_namep->opcode) - return op_namep->nmb_opcode_name; - } - return ""; + const struct opcode_names *op_namep; + int i; + + for(i = 0; nmb_header_opcode_names[i].nmb_opcode_name != 0; i++) { + op_namep = &nmb_header_opcode_names[i]; + if(opcode == op_namep->opcode) + return op_namep->nmb_opcode_name; + } + return ""; } /**************************************************************************** - print out a res_rec structure - ****************************************************************************/ + Print out a res_rec structure. +****************************************************************************/ + static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) { - int i, j; - - DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", - hdr, - nmb_namestr(&res->rr_name), - res->rr_type, - res->rr_class, - res->ttl ) ); - - if( res->rdlength == 0 || res->rdata == NULL ) - return; - - for (i = 0; i < res->rdlength; i+= 16) - { - DEBUGADD(4, (" %s %3x char ", hdr, i)); - - for (j = 0; j < 16; j++) - { - uchar x = res->rdata[i+j]; - if (x < 32 || x > 127) x = '.'; + int i, j; + + DEBUGADD( 4, ( " %s: nmb_name=%s rr_type=%d rr_class=%d ttl=%d\n", + hdr, + nmb_namestr(&res->rr_name), + res->rr_type, + res->rr_class, + res->ttl ) ); + + if( res->rdlength == 0 || res->rdata == NULL ) + return; + + for (i = 0; i < res->rdlength; i+= MAX_NETBIOSNAME_LEN) { + DEBUGADD(4, (" %s %3x char ", hdr, i)); + + for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) { + unsigned char x = res->rdata[i+j]; + if (x < 32 || x > 127) + x = '.'; - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%c", x)); - } + if (i+j >= res->rdlength) + break; + DEBUGADD(4, ("%c", x)); + } - DEBUGADD(4, (" hex ")); + DEBUGADD(4, (" hex ")); - for (j = 0; j < 16; j++) - { - if (i+j >= res->rdlength) break; - DEBUGADD(4, ("%02X", (uchar)res->rdata[i+j])); - } + for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) { + if (i+j >= res->rdlength) + break; + DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); + } - DEBUGADD(4, ("\n")); - } + DEBUGADD(4, ("\n")); + } } /**************************************************************************** - process a nmb packet - ****************************************************************************/ + Process a nmb packet. +****************************************************************************/ + void debug_nmb_packet(struct packet_struct *p) { - struct nmb_packet *nmb = &p->packet.nmb; - - if( DEBUGLVL( 4 ) ) - { - dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", - inet_ntoa(p->ip), p->port, - nmb->header.name_trn_id, - lookup_opcode_name(nmb->header.opcode), - nmb->header.opcode, - BOOLSTR(nmb->header.response) ); - dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", - BOOLSTR(nmb->header.nm_flags.bcast), - BOOLSTR(nmb->header.nm_flags.recursion_available), - BOOLSTR(nmb->header.nm_flags.recursion_desired), - BOOLSTR(nmb->header.nm_flags.trunc), - BOOLSTR(nmb->header.nm_flags.authoritative) ); - dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", - nmb->header.rcode, - nmb->header.qdcount, - nmb->header.ancount, - nmb->header.nscount, - nmb->header.arcount ); - } - - if (nmb->header.qdcount) - { - DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", - nmb_namestr(&nmb->question.question_name), - nmb->question.question_type, - nmb->question.question_class) ); - } - - if (nmb->answers && nmb->header.ancount) - { - debug_nmb_res_rec(nmb->answers,"answers"); - } - if (nmb->nsrecs && nmb->header.nscount) - { - debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); - } - if (nmb->additional && nmb->header.arcount) - { - debug_nmb_res_rec(nmb->additional,"additional"); - } + struct nmb_packet *nmb = &p->packet.nmb; + + if( DEBUGLVL( 4 ) ) { + dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + inet_ntoa(p->ip), p->port, + nmb->header.name_trn_id, + lookup_opcode_name(nmb->header.opcode), + nmb->header.opcode, + BOOLSTR(nmb->header.response) ); + dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + BOOLSTR(nmb->header.nm_flags.bcast), + BOOLSTR(nmb->header.nm_flags.recursion_available), + BOOLSTR(nmb->header.nm_flags.recursion_desired), + BOOLSTR(nmb->header.nm_flags.trunc), + BOOLSTR(nmb->header.nm_flags.authoritative) ); + dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + nmb->header.rcode, + nmb->header.qdcount, + nmb->header.ancount, + nmb->header.nscount, + nmb->header.arcount ); + } + + if (nmb->header.qdcount) { + DEBUGADD( 4, ( " question: q_name=%s q_type=%d q_class=%d\n", + nmb_namestr(&nmb->question.question_name), + nmb->question.question_type, + nmb->question.question_class) ); + } + + if (nmb->answers && nmb->header.ancount) { + debug_nmb_res_rec(nmb->answers,"answers"); + } + if (nmb->nsrecs && nmb->header.nscount) { + debug_nmb_res_rec(nmb->nsrecs,"nsrecs"); + } + if (nmb->additional && nmb->header.arcount) { + debug_nmb_res_rec(nmb->additional,"additional"); + } } /******************************************************************* - handle "compressed" name pointers - ******************************************************************/ -static BOOL handle_name_ptrs(uchar *ubuf,int *offset,int length, + Handle "compressed" name pointers. +******************************************************************/ + +static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { - int loop_count=0; + int loop_count=0; - while ((ubuf[*offset] & 0xC0) == 0xC0) { - if (!*got_pointer) (*ret) += 2; - (*got_pointer)=True; - (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; - if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { - return(False); - } - } - return(True); + while ((ubuf[*offset] & 0xC0) == 0xC0) { + if (!*got_pointer) + (*ret) += 2; + (*got_pointer)=True; + (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; + if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { + return(False); + } + } + return(True); } /******************************************************************* - parse a nmb name from "compressed" format to something readable - return the space taken by the name, or 0 if the name is invalid - ******************************************************************/ + Parse a nmb name from "compressed" format to something readable + return the space taken by the name, or 0 if the name is invalid +******************************************************************/ + static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) { - int m,n=0; - uchar *ubuf = (uchar *)inbuf; - int ret = 0; - BOOL got_pointer=False; - int loop_count=0; - int offset = ofs; - - if (length - offset < 2) - return(0); - - /* handle initial name pointers */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); + int m,n=0; + unsigned char *ubuf = (unsigned char *)inbuf; + int ret = 0; + BOOL got_pointer=False; + int loop_count=0; + int offset = ofs; + + if (length - offset < 2) + return(0); + + /* handle initial name pointers */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); - m = ubuf[offset]; - - if (!m) - return(0); - if ((m & 0xC0) || offset+m+2 > length) - return(0); - - memset((char *)name,'\0',sizeof(*name)); - - /* the "compressed" part */ - if (!got_pointer) - ret += m + 2; - offset++; - while (m > 0) { - uchar c1,c2; - c1 = ubuf[offset++]-'A'; - c2 = ubuf[offset++]-'A'; - if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) - return(0); - name->name[n++] = (c1<<4) | c2; - m -= 2; - } - name->name[n] = 0; - - if (n==16) { - /* parse out the name type, - its always in the 16th byte of the name */ - name->name_type = ((uchar)name->name[15]) & 0xff; + m = ubuf[offset]; + + if (!m) + return(0); + if ((m & 0xC0) || offset+m+2 > length) + return(0); + + memset((char *)name,'\0',sizeof(*name)); + + /* the "compressed" part */ + if (!got_pointer) + ret += m + 2; + offset++; + while (m > 0) { + unsigned char c1,c2; + c1 = ubuf[offset++]-'A'; + c2 = ubuf[offset++]-'A'; + if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) + return(0); + name->name[n++] = (c1<<4) | c2; + m -= 2; + } + name->name[n] = 0; + + if (n==MAX_NETBIOSNAME_LEN) { + /* parse out the name type, its always in the 16th byte of the name */ + name->name_type = ((unsigned char)name->name[15]) & 0xff; - /* remove trailing spaces */ - name->name[15] = 0; - n = 14; - while (n && name->name[n]==' ') - name->name[n--] = 0; - } - - /* now the domain parts (if any) */ - n = 0; - while (ubuf[offset]) { - /* we can have pointers within the domain part as well */ - if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) - return(0); - - m = ubuf[offset]; - /* - * Don't allow null domain parts. - */ - if (!m) - return(0); - if (!got_pointer) - ret += m+1; - if (n) - name->scope[n++] = '.'; - if (m+2+offset>length || n+m+1>sizeof(name->scope)) - return(0); - offset++; - while (m--) - name->scope[n++] = (char)ubuf[offset++]; - - /* - * Watch for malicious loops. - */ - if (loop_count++ == 10) - return 0; - } - name->scope[n++] = 0; - - return(ret); + /* remove trailing spaces */ + name->name[15] = 0; + n = 14; + while (n && name->name[n]==' ') + name->name[n--] = 0; + } + + /* now the domain parts (if any) */ + n = 0; + while (ubuf[offset]) { + /* we can have pointers within the domain part as well */ + if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) + return(0); + + m = ubuf[offset]; + /* + * Don't allow null domain parts. + */ + if (!m) + return(0); + if (!got_pointer) + ret += m+1; + if (n) + name->scope[n++] = '.'; + if (m+2+offset>length || n+m+1>sizeof(name->scope)) + return(0); + offset++; + while (m--) + name->scope[n++] = (char)ubuf[offset++]; + + /* + * Watch for malicious loops. + */ + if (loop_count++ == 10) + return 0; + } + name->scope[n++] = 0; + + return(ret); } +/**************************************************************************** + Put a netbios name, padding(s) and a name type into a 16 character buffer. + name is already in DOS charset. + [15 bytes name + padding][1 byte name type]. +****************************************************************************/ + +static void put_name(char *dest, const char *name, int pad, unsigned int name_type) +{ + size_t len = strlen(name); + + memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1); + if (len < MAX_NETBIOSNAME_LEN - 1) { + memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len); + } + dest[MAX_NETBIOSNAME_LEN - 1] = name_type; +} /******************************************************************* - put a compressed nmb name into a buffer. return the length of the - compressed name + Put a compressed nmb name into a buffer. Return the length of the + compressed name. + + Compressed names are really weird. The "compression" doubles the + size. The idea is that it also means that compressed names conform + to the doman name system. See RFC1002. +******************************************************************/ - compressed names are really weird. The "compression" doubles the - size. The idea is that it also means that compressed names conform - to the doman name system. See RFC1002. - ******************************************************************/ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) { - int ret,m; - fstring buf1; - char *p; - - if (strcmp(name->name,"*") == 0) { - /* special case for wildcard name */ - memset(buf1,'\0',20); - buf1[0] = '*'; - buf1[15] = name->name_type; - } else { - slprintf(buf1, sizeof(buf1) - 1,"%-15.15s%c",name->name,name->name_type); - } - - buf[offset] = 0x20; - - ret = 34; - - for (m=0;m<16;m++) { - buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); - buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); - } - offset += 33; - - buf[offset] = 0; - - if (name->scope[0]) { - /* XXXX this scope handling needs testing */ - ret += strlen(name->scope) + 1; - safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); + int ret,m; + fstring buf1; + char *p; + + if (strcmp(name->name,"*") == 0) { + /* special case for wildcard name */ + put_name(buf1, "*", '\0', name->name_type); + } else { + put_name(buf1, name->name, ' ', name->name_type); + } + + buf[offset] = 0x20; + + ret = 34; + + for (m=0;m>4)&0xF); + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + } + offset += 33; + + buf[offset] = 0; + + if (name->scope[0]) { + /* XXXX this scope handling needs testing */ + ret += strlen(name->scope) + 1; + safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); - p = &buf[offset+1]; - while ((p = strchr_m(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset+1]); - offset += (buf[offset] + 1); - p = &buf[offset+1]; - } - buf[offset] = strlen(&buf[offset+1]); - } - - return(ret); + p = &buf[offset+1]; + while ((p = strchr_m(p,'.'))) { + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); + p = &buf[offset+1]; + } + buf[offset] = strlen(&buf[offset+1]); + } + + return(ret); } /******************************************************************* @@ -331,336 +346,347 @@ char *nmb_namestr(struct nmb_name *n) } /******************************************************************* - allocate and parse some resource records - ******************************************************************/ + Allocate and parse some resource records. +******************************************************************/ + static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, struct res_rec **recs, int count) { - int i; - *recs = (struct res_rec *)malloc(sizeof(**recs)*count); - if (!*recs) return(False); - - memset((char *)*recs,'\0',sizeof(**recs)*count); - - for (i=0;i length) { - SAFE_FREE(*recs); - return(False); - } - (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); - (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); - (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); - (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); - (*offset) += 10; - if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || - (*offset)+(*recs)[i].rdlength > length) { - SAFE_FREE(*recs); - return(False); - } - memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); - (*offset) += (*recs)[i].rdlength; - } - return(True); + int i; + + *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + if (!*recs) + return(False); + + memset((char *)*recs,'\0',sizeof(**recs)*count); + + for (i=0;i length) { + SAFE_FREE(*recs); + return(False); + } + (*recs)[i].rr_type = RSVAL(inbuf,(*offset)); + (*recs)[i].rr_class = RSVAL(inbuf,(*offset)+2); + (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); + (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); + (*offset) += 10; + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || + (*offset)+(*recs)[i].rdlength > length) { + SAFE_FREE(*recs); + return(False); + } + memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); + (*offset) += (*recs)[i].rdlength; + } + return(True); } /******************************************************************* - put a resource record into a packet - ******************************************************************/ + Put a resource record into a packet. +******************************************************************/ + static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) { - int ret=0; - int i; - - for (i=0;i> 8) & 0xFF)); - buf[offset+1] = (ptr_offset & 0xFF); - offset += 2; - ret += 2; - RSSVAL(buf,offset,rec->rr_type); - RSSVAL(buf,offset+2,rec->rr_class); - RSIVAL(buf,offset+4,rec->ttl); - RSSVAL(buf,offset+8,rec->rdlength); - memcpy(buf+offset+10,rec->rdata,rec->rdlength); - offset += 10+rec->rdlength; - ret += 10+rec->rdlength; + int ret=0; + buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); + buf[offset+1] = (ptr_offset & 0xFF); + offset += 2; + ret += 2; + RSSVAL(buf,offset,rec->rr_type); + RSSVAL(buf,offset+2,rec->rr_class); + RSIVAL(buf,offset+4,rec->ttl); + RSSVAL(buf,offset+8,rec->rdlength); + memcpy(buf+offset+10,rec->rdata,rec->rdlength); + offset += 10+rec->rdlength; + ret += 10+rec->rdlength; - return(ret); + return(ret); } /******************************************************************* - parse a dgram packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise + Parse a dgram packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise. + + This is documented in section 4.4.1 of RFC1002. +******************************************************************/ - this is documented in section 4.4.1 of RFC1002 - ******************************************************************/ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) { - int offset; - int flags; - - memset((char *)dgram,'\0',sizeof(*dgram)); - - if (length < 14) return(False); - - dgram->header.msg_type = CVAL(inbuf,0); - flags = CVAL(inbuf,1); - dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); - if (flags & 1) dgram->header.flags.more = True; - if (flags & 2) dgram->header.flags.first = True; - dgram->header.dgm_id = RSVAL(inbuf,2); - putip((char *)&dgram->header.source_ip,inbuf+4); - dgram->header.source_port = RSVAL(inbuf,8); - dgram->header.dgm_length = RSVAL(inbuf,10); - dgram->header.packet_offset = RSVAL(inbuf,12); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); - offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); - } + int offset; + int flags; + + memset((char *)dgram,'\0',sizeof(*dgram)); + + if (length < 14) + return(False); + + dgram->header.msg_type = CVAL(inbuf,0); + flags = CVAL(inbuf,1); + dgram->header.flags.node_type = (enum node_type)((flags>>2)&3); + if (flags & 1) + dgram->header.flags.more = True; + if (flags & 2) + dgram->header.flags.first = True; + dgram->header.dgm_id = RSVAL(inbuf,2); + putip((char *)&dgram->header.source_ip,inbuf+4); + dgram->header.source_port = RSVAL(inbuf,8); + dgram->header.dgm_length = RSVAL(inbuf,10); + dgram->header.packet_offset = RSVAL(inbuf,12); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); + offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); + } - if (offset >= length || (length-offset > sizeof(dgram->data))) - return(False); + if (offset >= length || (length-offset > sizeof(dgram->data))) + return(False); - dgram->datasize = length-offset; - memcpy(dgram->data,inbuf+offset,dgram->datasize); + dgram->datasize = length-offset; + memcpy(dgram->data,inbuf+offset,dgram->datasize); - return(True); + return(True); } - /******************************************************************* - parse a nmb packet. Return False if the packet can't be parsed - or is invalid for some reason, True otherwise - ******************************************************************/ + Parse a nmb packet. Return False if the packet can't be parsed + or is invalid for some reason, True otherwise. +******************************************************************/ + static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) { - int nm_flags,offset; - - memset((char *)nmb,'\0',sizeof(*nmb)); - - if (length < 12) return(False); - - /* parse the header */ - nmb->header.name_trn_id = RSVAL(inbuf,0); - - DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); - - nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; - nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; - nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); - nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; - nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; - nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; - nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; - nmb->header.rcode = CVAL(inbuf,3) & 0xF; - nmb->header.qdcount = RSVAL(inbuf,4); - nmb->header.ancount = RSVAL(inbuf,6); - nmb->header.nscount = RSVAL(inbuf,8); - nmb->header.arcount = RSVAL(inbuf,10); + int nm_flags,offset; + + memset((char *)nmb,'\0',sizeof(*nmb)); + + if (length < 12) + return(False); + + /* parse the header */ + nmb->header.name_trn_id = RSVAL(inbuf,0); + + DEBUG(10,("parse_nmb: packet id = %d\n", nmb->header.name_trn_id)); + + nmb->header.opcode = (CVAL(inbuf,2) >> 3) & 0xF; + nmb->header.response = ((CVAL(inbuf,2)>>7)&1)?True:False; + nm_flags = ((CVAL(inbuf,2) & 0x7) << 4) + (CVAL(inbuf,3)>>4); + nmb->header.nm_flags.bcast = (nm_flags&1)?True:False; + nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; + nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; + nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.rcode = CVAL(inbuf,3) & 0xF; + nmb->header.qdcount = RSVAL(inbuf,4); + nmb->header.ancount = RSVAL(inbuf,6); + nmb->header.nscount = RSVAL(inbuf,8); + nmb->header.arcount = RSVAL(inbuf,10); - if (nmb->header.qdcount) { - offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); - if (!offset) return(False); - - if (length - (12+offset) < 4) return(False); - nmb->question.question_type = RSVAL(inbuf,12+offset); - nmb->question.question_class = RSVAL(inbuf,12+offset+2); - - offset += 12+4; - } else { - offset = 12; - } - - /* and any resource records */ - if (nmb->header.ancount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, - nmb->header.ancount)) - return(False); - - if (nmb->header.nscount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, - nmb->header.nscount)) - return(False); + if (nmb->header.qdcount) { + offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); + if (!offset) + return(False); + + if (length - (12+offset) < 4) + return(False); + nmb->question.question_type = RSVAL(inbuf,12+offset); + nmb->question.question_class = RSVAL(inbuf,12+offset+2); + + offset += 12+4; + } else { + offset = 12; + } + + /* and any resource records */ + if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, + nmb->header.ancount)) + return(False); + + if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, + nmb->header.nscount)) + return(False); - if (nmb->header.arcount && - !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, - nmb->header.arcount)) - return(False); + if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, + nmb->header.arcount)) + return(False); - return(True); + return(True); } /******************************************************************* - 'Copy constructor' for an nmb packet - ******************************************************************/ + 'Copy constructor' for an nmb packet. +******************************************************************/ + static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) { - struct nmb_packet *nmb; - struct nmb_packet *copy_nmb; - struct packet_struct *pkt_copy; - - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) - { - DEBUG(0,("copy_nmb_packet: malloc fail.\n")); - return NULL; - } - - /* Structure copy of entire thing. */ - - *pkt_copy = *packet; - - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; - - /* Ensure this copy has no resource records. */ - nmb = &packet->packet.nmb; - copy_nmb = &pkt_copy->packet.nmb; - - copy_nmb->answers = NULL; - copy_nmb->nsrecs = NULL; - copy_nmb->additional = NULL; - - /* Now copy any resource records. */ - - if (nmb->answers) - { - if((copy_nmb->answers = (struct res_rec *) - malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->answers, (char *)nmb->answers, - nmb->header.ancount * sizeof(struct res_rec)); - } - if (nmb->nsrecs) - { - if((copy_nmb->nsrecs = (struct res_rec *) - malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, - nmb->header.nscount * sizeof(struct res_rec)); - } - if (nmb->additional) - { - if((copy_nmb->additional = (struct res_rec *) - malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) - goto free_and_exit; - memcpy((char *)copy_nmb->additional, (char *)nmb->additional, - nmb->header.arcount * sizeof(struct res_rec)); - } - - return pkt_copy; - -free_and_exit: - - SAFE_FREE(copy_nmb->answers); - SAFE_FREE(copy_nmb->nsrecs); - SAFE_FREE(copy_nmb->additional); - SAFE_FREE(pkt_copy); - - DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); - return NULL; + struct nmb_packet *nmb; + struct nmb_packet *copy_nmb; + struct packet_struct *pkt_copy; + + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + DEBUG(0,("copy_nmb_packet: malloc fail.\n")); + return NULL; + } + + /* Structure copy of entire thing. */ + + *pkt_copy = *packet; + + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; + + /* Ensure this copy has no resource records. */ + nmb = &packet->packet.nmb; + copy_nmb = &pkt_copy->packet.nmb; + + copy_nmb->answers = NULL; + copy_nmb->nsrecs = NULL; + copy_nmb->additional = NULL; + + /* Now copy any resource records. */ + + if (nmb->answers) { + if((copy_nmb->answers = (struct res_rec *) + malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->answers, (char *)nmb->answers, + nmb->header.ancount * sizeof(struct res_rec)); + } + if (nmb->nsrecs) { + if((copy_nmb->nsrecs = (struct res_rec *) + malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, + nmb->header.nscount * sizeof(struct res_rec)); + } + if (nmb->additional) { + if((copy_nmb->additional = (struct res_rec *) + malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + goto free_and_exit; + memcpy((char *)copy_nmb->additional, (char *)nmb->additional, + nmb->header.arcount * sizeof(struct res_rec)); + } + + return pkt_copy; + + free_and_exit: + + SAFE_FREE(copy_nmb->answers); + SAFE_FREE(copy_nmb->nsrecs); + SAFE_FREE(copy_nmb->additional); + SAFE_FREE(pkt_copy); + + DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n")); + return NULL; } /******************************************************************* - 'Copy constructor' for a dgram packet - ******************************************************************/ + 'Copy constructor' for a dgram packet. +******************************************************************/ + static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) { - struct packet_struct *pkt_copy; + struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) - { - DEBUG(0,("copy_dgram_packet: malloc fail.\n")); - return NULL; - } + if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + DEBUG(0,("copy_dgram_packet: malloc fail.\n")); + return NULL; + } - /* Structure copy of entire thing. */ + /* Structure copy of entire thing. */ - *pkt_copy = *packet; + *pkt_copy = *packet; - /* Ensure this copy is not locked. */ - pkt_copy->locked = False; + /* Ensure this copy is not locked. */ + pkt_copy->locked = False; - /* There are no additional pointers in a dgram packet, - we are finished. */ - return pkt_copy; + /* There are no additional pointers in a dgram packet, + we are finished. */ + return pkt_copy; } /******************************************************************* - 'Copy constructor' for a generic packet - ******************************************************************/ + 'Copy constructor' for a generic packet. +******************************************************************/ + struct packet_struct *copy_packet(struct packet_struct *packet) { - if(packet->packet_type == NMB_PACKET) - return copy_nmb_packet(packet); - else if (packet->packet_type == DGRAM_PACKET) - return copy_dgram_packet(packet); - return NULL; + if(packet->packet_type == NMB_PACKET) + return copy_nmb_packet(packet); + else if (packet->packet_type == DGRAM_PACKET) + return copy_dgram_packet(packet); + return NULL; } /******************************************************************* - free up any resources associated with an nmb packet - ******************************************************************/ + Free up any resources associated with an nmb packet. +******************************************************************/ + static void free_nmb_packet(struct nmb_packet *nmb) { - SAFE_FREE(nmb->answers); - SAFE_FREE(nmb->nsrecs); - SAFE_FREE(nmb->additional); + SAFE_FREE(nmb->answers); + SAFE_FREE(nmb->nsrecs); + SAFE_FREE(nmb->additional); } /******************************************************************* - free up any resources associated with a dgram packet - ******************************************************************/ + Free up any resources associated with a dgram packet. +******************************************************************/ + static void free_dgram_packet(struct dgram_packet *nmb) { - /* We have nothing to do for a dgram packet. */ + /* We have nothing to do for a dgram packet. */ } /******************************************************************* - free up any resources associated with a packet - ******************************************************************/ + Free up any resources associated with a packet. +******************************************************************/ + void free_packet(struct packet_struct *packet) { - if (packet->locked) - return; - if (packet->packet_type == NMB_PACKET) - free_nmb_packet(&packet->packet.nmb); - else if (packet->packet_type == DGRAM_PACKET) - free_dgram_packet(&packet->packet.dgram); - ZERO_STRUCTPN(packet); - SAFE_FREE(packet); + if (packet->locked) + return; + if (packet->packet_type == NMB_PACKET) + free_nmb_packet(&packet->packet.nmb); + else if (packet->packet_type == DGRAM_PACKET) + free_dgram_packet(&packet->packet.dgram); + ZERO_STRUCTPN(packet); + SAFE_FREE(packet); } /******************************************************************* -parse a packet buffer into a packet structure - ******************************************************************/ + Parse a packet buffer into a packet structure. +******************************************************************/ + struct packet_struct *parse_packet(char *buf,int length, enum packet_type packet_type) { @@ -670,7 +696,8 @@ struct packet_struct *parse_packet(char *buf,int length, BOOL ok=False; p = (struct packet_struct *)malloc(sizeof(*p)); - if (!p) return(NULL); + if (!p) + return(NULL); p->next = NULL; p->prev = NULL; @@ -699,9 +726,10 @@ struct packet_struct *parse_packet(char *buf,int length, } /******************************************************************* - read a packet from a socket and parse it, returning a packet ready - to be used or put on the queue. This assumes a UDP socket - ******************************************************************/ + Read a packet from a socket and parse it, returning a packet ready + to be used or put on the queue. This assumes a UDP socket. +******************************************************************/ + struct packet_struct *read_packet(int fd,enum packet_type packet_type) { struct packet_struct *packet; @@ -709,10 +737,12 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) int length; length = read_udp_socket(fd,buf,sizeof(buf)); - if (length < MIN_DGRAM_SIZE) return(NULL); + if (length < MIN_DGRAM_SIZE) + return(NULL); packet = parse_packet(buf, length, packet_type); - if (!packet) return NULL; + if (!packet) + return NULL; packet->fd = fd; @@ -724,96 +754,99 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) return(packet); } - /******************************************************************* - send a udp packet on a already open socket - ******************************************************************/ + Send a udp packet on a already open socket. +******************************************************************/ + static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) { - BOOL ret = False; - int i; - struct sockaddr_in sock_out; - - /* set the address and port */ - memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)&ip); - sock_out.sin_port = htons( port ); - sock_out.sin_family = AF_INET; + BOOL ret = False; + int i; + struct sockaddr_in sock_out; + + /* set the address and port */ + memset((char *)&sock_out,'\0',sizeof(sock_out)); + putip((char *)&sock_out.sin_addr,(char *)&ip); + sock_out.sin_port = htons( port ); + sock_out.sin_family = AF_INET; - DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", - len, inet_ntoa(ip), port ) ); + DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", + len, inet_ntoa(ip), port ) ); - /* - * Patch to fix asynch error notifications from Linux kernel. - */ + /* + * Patch to fix asynch error notifications from Linux kernel. + */ - for (i = 0; i < 5; i++) { - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); - if (ret || errno != ECONNREFUSED) - break; - } + for (i = 0; i < 5; i++) { + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); + if (ret || errno != ECONNREFUSED) + break; + } - if (!ret) - DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", - inet_ntoa(ip),port,strerror(errno))); + if (!ret) + DEBUG(0,("Packet send failed to %s(%d) ERRNO=%s\n", + inet_ntoa(ip),port,strerror(errno))); - if (ret) - num_good_sends++; + if (ret) + num_good_sends++; - return(ret); + return(ret); } /******************************************************************* - build a dgram packet ready for sending + Build a dgram packet ready for sending. - XXXX This currently doesn't handle packets too big for one - datagram. It should split them and use the packet_offset, more and - first flags to handle the fragmentation. Yuck. + XXXX This currently doesn't handle packets too big for one + datagram. It should split them and use the packet_offset, more and + first flags to handle the fragmentation. Yuck. - [...but it isn't clear that we would ever need to send a - a fragmented NBT Datagram. The IP layer does its own - fragmentation to ensure that messages can fit into the path - MTU. It *is* important to be able to receive and rebuild - fragmented NBT datagrams, just in case someone out there - really has implemented this 'feature'. crh -)------ ] + [...but it isn't clear that we would ever need to send a + a fragmented NBT Datagram. The IP layer does its own + fragmentation to ensure that messages can fit into the path + MTU. It *is* important to be able to receive and rebuild + fragmented NBT datagrams, just in case someone out there + really has implemented this 'feature'. crh -)------ ] + +******************************************************************/ - ******************************************************************/ static int build_dgram(char *buf,struct packet_struct *p) { - struct dgram_packet *dgram = &p->packet.dgram; - uchar *ubuf = (uchar *)buf; - int offset=0; - - /* put in the header */ - ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); - if (dgram->header.flags.more) ubuf[1] |= 1; - if (dgram->header.flags.first) ubuf[1] |= 2; - RSSVAL(ubuf,2,dgram->header.dgm_id); - putip(ubuf+4,(char *)&dgram->header.source_ip); - RSSVAL(ubuf,8,dgram->header.source_port); - RSSVAL(ubuf,12,dgram->header.packet_offset); - - offset = 14; - - if (dgram->header.msg_type == 0x10 || - dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); - offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); - } - - memcpy(ubuf+offset,dgram->data,dgram->datasize); - offset += dgram->datasize; - - /* automatically set the dgm_length - * NOTE: RFC1002 says the dgm_length does *not* - * include the fourteen-byte header. crh - */ - dgram->header.dgm_length = (offset - 14); - RSSVAL(ubuf,10,dgram->header.dgm_length); - - return(offset); + struct dgram_packet *dgram = &p->packet.dgram; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + if (dgram->header.flags.more) + ubuf[1] |= 1; + if (dgram->header.flags.first) + ubuf[1] |= 2; + RSSVAL(ubuf,2,dgram->header.dgm_id); + putip(ubuf+4,(char *)&dgram->header.source_ip); + RSSVAL(ubuf,8,dgram->header.source_port); + RSSVAL(ubuf,12,dgram->header.packet_offset); + + offset = 14; + + if (dgram->header.msg_type == 0x10 || + dgram->header.msg_type == 0x11 || + dgram->header.msg_type == 0x12) { + offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); + offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); + } + + memcpy(ubuf+offset,dgram->data,dgram->datasize); + offset += dgram->datasize; + + /* automatically set the dgm_length + * NOTE: RFC1002 says the dgm_length does *not* + * include the fourteen-byte header. crh + */ + dgram->header.dgm_length = (offset - 14); + RSSVAL(ubuf,10,dgram->header.dgm_length); + + return(offset); } /******************************************************************* @@ -830,92 +863,99 @@ void make_nmb_name( struct nmb_name *n, const char *name, int type) /******************************************************************* Compare two nmb names - ******************************************************************/ +******************************************************************/ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) { - return ((n1->name_type == n2->name_type) && - strequal(n1->name ,n2->name ) && - strequal(n1->scope,n2->scope)); + return ((n1->name_type == n2->name_type) && + strequal(n1->name ,n2->name ) && + strequal(n1->scope,n2->scope)); } /******************************************************************* - build a nmb packet ready for sending + Build a nmb packet ready for sending. + + XXXX this currently relies on not being passed something that expands + to a packet too big for the buffer. Eventually this should be + changed to set the trunc bit so the receiver can request the rest + via tcp (when that becomes supported) +******************************************************************/ - XXXX this currently relies on not being passed something that expands - to a packet too big for the buffer. Eventually this should be - changed to set the trunc bit so the receiver can request the rest - via tcp (when that becomes supported) - ******************************************************************/ static int build_nmb(char *buf,struct packet_struct *p) { - struct nmb_packet *nmb = &p->packet.nmb; - uchar *ubuf = (uchar *)buf; - int offset=0; - - /* put in the header */ - RSSVAL(ubuf,offset,nmb->header.name_trn_id); - ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; - if (nmb->header.response) ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative && - nmb->header.response) ubuf[offset+2] |= 0x4; - if (nmb->header.nm_flags.trunc) ubuf[offset+2] |= 0x2; - if (nmb->header.nm_flags.recursion_desired) ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available && - nmb->header.response) ubuf[offset+3] |= 0x80; - if (nmb->header.nm_flags.bcast) ubuf[offset+3] |= 0x10; - ubuf[offset+3] |= (nmb->header.rcode & 0xF); - - RSSVAL(ubuf,offset+4,nmb->header.qdcount); - RSSVAL(ubuf,offset+6,nmb->header.ancount); - RSSVAL(ubuf,offset+8,nmb->header.nscount); - RSSVAL(ubuf,offset+10,nmb->header.arcount); + struct nmb_packet *nmb = &p->packet.nmb; + unsigned char *ubuf = (unsigned char *)buf; + int offset=0; + + /* put in the header */ + RSSVAL(ubuf,offset,nmb->header.name_trn_id); + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) + ubuf[offset+2] |= (1<<7); + if (nmb->header.nm_flags.authoritative && + nmb->header.response) + ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.trunc) + ubuf[offset+2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) + ubuf[offset+2] |= 0x1; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) + ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.bcast) + ubuf[offset+3] |= 0x10; + ubuf[offset+3] |= (nmb->header.rcode & 0xF); + + RSSVAL(ubuf,offset+4,nmb->header.qdcount); + RSSVAL(ubuf,offset+6,nmb->header.ancount); + RSSVAL(ubuf,offset+8,nmb->header.nscount); + RSSVAL(ubuf,offset+10,nmb->header.arcount); - offset += 12; - if (nmb->header.qdcount) { - /* XXXX this doesn't handle a qdcount of > 1 */ - offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); - RSSVAL(ubuf,offset,nmb->question.question_type); - RSSVAL(ubuf,offset+2,nmb->question.question_class); - offset += 4; - } - - if (nmb->header.ancount) - offset += put_res_rec((char *)ubuf,offset,nmb->answers, - nmb->header.ancount); - - if (nmb->header.nscount) - offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, - nmb->header.nscount); - - /* - * The spec says we must put compressed name pointers - * in the following outgoing packets : - * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, - * NAME_RELEASE_REQUEST. - */ - - if((nmb->header.response == False) && - ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || - (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || - (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && - (nmb->header.arcount == 1)) { - - offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); - - } else if (nmb->header.arcount) { - offset += put_res_rec((char *)ubuf,offset,nmb->additional, - nmb->header.arcount); - } - return(offset); -} + offset += 12; + if (nmb->header.qdcount) { + /* XXXX this doesn't handle a qdcount of > 1 */ + offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); + RSSVAL(ubuf,offset,nmb->question.question_type); + RSSVAL(ubuf,offset+2,nmb->question.question_class); + offset += 4; + } + + if (nmb->header.ancount) + offset += put_res_rec((char *)ubuf,offset,nmb->answers, + nmb->header.ancount); + + if (nmb->header.nscount) + offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, + nmb->header.nscount); + + /* + * The spec says we must put compressed name pointers + * in the following outgoing packets : + * NAME_REGISTRATION_REQUEST, NAME_REFRESH_REQUEST, + * NAME_RELEASE_REQUEST. + */ + + if((nmb->header.response == False) && + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && + (nmb->header.arcount == 1)) { + + offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); + } else if (nmb->header.arcount) { + offset += put_res_rec((char *)ubuf,offset,nmb->additional, + nmb->header.arcount); + } + return(offset); +} /******************************************************************* -linearise a packet - ******************************************************************/ + Linearise a packet. +******************************************************************/ + int build_packet(char *buf, struct packet_struct *p) { int len = 0; @@ -934,26 +974,29 @@ int build_packet(char *buf, struct packet_struct *p) } /******************************************************************* - send a packet_struct - ******************************************************************/ + Send a packet_struct. +******************************************************************/ + BOOL send_packet(struct packet_struct *p) { - char buf[1024]; - int len=0; + char buf[1024]; + int len=0; - memset(buf,'\0',sizeof(buf)); + memset(buf,'\0',sizeof(buf)); - len = build_packet(buf, p); + len = build_packet(buf, p); - if (!len) return(False); + if (!len) + return(False); - return(send_udp(p->fd,buf,len,p->ip,p->port)); + return(send_udp(p->fd,buf,len,p->ip,p->port)); } /**************************************************************************** - receive a packet with timeout on a open UDP filedescriptor - The timeout is in milliseconds - ***************************************************************************/ + Receive a packet with timeout on a open UDP filedescriptor. + The timeout is in milliseconds +***************************************************************************/ + struct packet_struct *receive_packet(int fd,enum packet_type type,int t) { fd_set fds; @@ -980,12 +1023,12 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) return(NULL); } - /**************************************************************************** - receive a UDP/137 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified trn_id - The timeout is in milliseconds - ***************************************************************************/ + Receive a UDP/137 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified trn_id. + The timeout is in milliseconds. +***************************************************************************/ + struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) { struct packet_struct *p; @@ -993,20 +1036,22 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) p = receive_packet(fd, NMB_PACKET, t); if (p && p->packet.nmb.header.response && - p->packet.nmb.header.name_trn_id == trn_id) { + p->packet.nmb.header.name_trn_id == trn_id) { return p; } - if (p) free_packet(p); + if (p) + free_packet(p); /* try the unexpected packet queue */ return receive_unexpected(NMB_PACKET, trn_id, NULL); } /**************************************************************************** - receive a UDP/138 packet either via UDP or from the unexpected packet - queue. The packet must be a reply packet and have the specified mailslot name - The timeout is in milliseconds - ***************************************************************************/ + Receive a UDP/138 packet either via UDP or from the unexpected packet + queue. The packet must be a reply packet and have the specified mailslot name + The timeout is in milliseconds. +***************************************************************************/ + struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) { struct packet_struct *p; @@ -1016,16 +1061,17 @@ struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_n if (p && match_mailslot_name(p, mailslot_name)) { return p; } - if (p) free_packet(p); + if (p) + free_packet(p); /* try the unexpected packet queue */ return receive_unexpected(DGRAM_PACKET, 0, mailslot_name); } - /**************************************************************************** - see if a datagram has the right mailslot name + See if a datagram has the right mailslot name. ***************************************************************************/ + BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) { struct dgram_packet *dgram = &p->packet.dgram; @@ -1043,71 +1089,76 @@ BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) return False; } - /**************************************************************************** -return the number of bits that match between two 4 character buffers - ***************************************************************************/ -int matching_quad_bits(uchar *p1, uchar *p2) + Return the number of bits that match between two 4 character buffers +***************************************************************************/ + +int matching_quad_bits(unsigned char *p1, unsigned char *p2) { int i, j, ret = 0; for (i=0; i<4; i++) { - if (p1[i] != p2[i]) break; + if (p1[i] != p2[i]) + break; ret += 8; } - if (i==4) return ret; + if (i==4) + return ret; for (j=0; j<8; j++) { - if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; + if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) + break; ret++; } return ret; } - -static uchar sort_ip[4]; +static unsigned char sort_ip[4]; /**************************************************************************** -compare two query reply records - ***************************************************************************/ -static int name_query_comp(uchar *p1, uchar *p2) + Compare two query reply records. +***************************************************************************/ + +static int name_query_comp(unsigned char *p1, unsigned char *p2) { return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); } /**************************************************************************** -sort a set of 6 byte name query response records so that the IPs that -have the most leading bits in common with the specified address come first - ***************************************************************************/ + Sort a set of 6 byte name query response records so that the IPs that + have the most leading bits in common with the specified address come first. +***************************************************************************/ + void sort_query_replies(char *data, int n, struct in_addr ip) { - if (n <= 1) return; + if (n <= 1) + return; putip(sort_ip, (char *)&ip); qsort(data, n, 6, QSORT_CAST name_query_comp); } - #define TRUNCATE_NETBIOS_NAME 1 /******************************************************************* - convert, possibly using a stupid microsoft-ism which has destroyed + Convert, possibly using a stupid microsoft-ism which has destroyed the transport independence of netbios (for CIFS vendors that usually use the Win95-type methods, not for NT to NT communication, which uses DCE/RPC and therefore full-length unicode strings...) a dns name into a netbios name. - the netbios name (NOT necessarily null-terminated) is truncated to 15 + The netbios name (NOT necessarily null-terminated) is truncated to 15 characters. ******************************************************************/ -char *dns_to_netbios_name(char *dns_name) + +char *dns_to_netbios_name(const char *dns_name) { - static char netbios_name[16]; + static nstring netbios_name; int i; - StrnCpy(netbios_name, dns_name, 15); + StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); netbios_name[15] = 0; #ifdef TRUNCATE_NETBIOS_NAME @@ -1116,10 +1167,8 @@ char *dns_to_netbios_name(char *dns_name) netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 0; i >= 15; i--) - { - if (netbios_name[i] == '.') - { + for (i = 0; i >= 15; i--) { + if (netbios_name[i] == '.') { netbios_name[i] = 0; break; } @@ -1129,146 +1178,146 @@ char *dns_to_netbios_name(char *dns_name) return netbios_name; } - /**************************************************************************** -interpret the weird netbios "name" into a unix fstring. Return the name type + Interpret the weird netbios "name" into a unix fstring. Return the name type. ****************************************************************************/ + static int name_interpret(char *in, fstring name) { - int ret; - int len = (*in++) / 2; - fstring out_string; - char *out = out_string; - - *out=0; - - if (len > 30 || len<1) return(0); - - while (len--) - { - if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { - *out = 0; - return(0); - } - *out = ((in[0]-'A')<<4) + (in[1]-'A'); - in += 2; - out++; - } - ret = out[-1]; - out[-1] = 0; + int ret; + int len = (*in++) / 2; + fstring out_string; + char *out = out_string; + + *out=0; + + if (len > 30 || len<1) + return(0); + + while (len--) { + if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') { + *out = 0; + return(0); + } + *out = ((in[0]-'A')<<4) + (in[1]-'A'); + in += 2; + out++; + } + ret = out[-1]; + out[-1] = 0; #ifdef NETBIOS_SCOPE - /* Handle any scope names */ - while(*in) - { - *out++ = '.'; /* Scope names are separated by periods */ - len = *(uchar *)in++; - StrnCpy(out, in, len); - out += len; - *out=0; - in += len; - } + /* Handle any scope names */ + while(*in) { + *out++ = '.'; /* Scope names are separated by periods */ + len = *(unsigned char *)in++; + StrnCpy(out, in, len); + out += len; + *out=0; + in += len; + } #endif - pull_ascii(name, out_string, sizeof(fstring), sizeof(out_string), STR_TERMINATE); + pull_ascii_fstring(name, out_string); - return(ret); + return(ret); } /**************************************************************************** -mangle a name into netbios format - - Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. + Mangle a name into netbios format. + Note: must be (33 + strlen(scope) + 2) bytes long, at minimum. ****************************************************************************/ + int name_mangle( char *In, char *Out, char name_type ) - { - int i; - int c; - int len; - char buf[20]; - char *p = Out; - - /* Safely copy the input string, In, into buf[]. */ - (void)memset( buf, 0, 20 ); - if (strcmp(In,"*") == 0) - buf[0] = '*'; - else - (void)slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); - - /* Place the length of the first field into the output buffer. */ - p[0] = 32; - p++; - - /* Now convert the name to the rfc1001/1002 format. */ - for( i = 0; i < 16; i++ ) - { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; - p[(i*2)+1] = (c & 0x000F) + 'A'; - } - p += 32; - p[0] = '\0'; - - /* Add the scope string. */ - for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) - { - switch( (global_scope())[i] ) - { - case '\0': - p[0] = len; - if( len > 0 ) - p[len+1] = 0; - return( name_len(Out) ); - case '.': - p[0] = len; - p += (len + 1); - len = -1; - break; - default: - p[len+1] = (global_scope())[i]; - break; - } - } - - return( name_len(Out) ); - } /* name_mangle */ +{ + int i; + int c; + int len; + char buf[20]; + char *p = Out; + + /* Safely copy the input string, In, into buf[]. */ + memset( buf, 0, 20 ); + if (strcmp(In,"*") == 0) { + buf[0] = '*'; + } else { + slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + } + /* Place the length of the first field into the output buffer. */ + p[0] = 32; + p++; + + /* Now convert the name to the rfc1001/1002 format. */ + for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) { + c = toupper( buf[i] ); + p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; + p[(i*2)+1] = (c & 0x000F) + 'A'; + } + p += 32; + p[0] = '\0'; + + /* Add the scope string. */ + for( i = 0, len = 0; *(global_scope()) != '\0'; i++, len++ ) { + switch( (global_scope())[i] ) { + case '\0': + p[0] = len; + if( len > 0 ) + p[len+1] = 0; + return( name_len(Out) ); + case '.': + p[0] = len; + p += (len + 1); + len = -1; + break; + default: + p[len+1] = (global_scope())[i]; + break; + } + } + + return( name_len(Out) ); +} /**************************************************************************** -find a pointer to a netbios name + Find a pointer to a netbios name. ****************************************************************************/ + static char *name_ptr(char *buf,int ofs) { - uchar c = *(uchar *)(buf+ofs); - - if ((c & 0xC0) == 0xC0) - { - uint16 l = RSVAL(buf, ofs) & 0x3FFF; - DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); - return(buf + l); - } - else - return(buf+ofs); + unsigned char c = *(unsigned char *)(buf+ofs); + + if ((c & 0xC0) == 0xC0) { + uint16 l = RSVAL(buf, ofs) & 0x3FFF; + DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l)); + return(buf + l); + } else { + return(buf+ofs); + } } /**************************************************************************** -extract a netbios name from a buf (into a unix string) return name type + Extract a netbios name from a buf (into a unix string) return name type. ****************************************************************************/ + int name_extract(char *buf,int ofs, fstring name) { - char *p = name_ptr(buf,ofs); - int d = PTR_DIFF(p,buf+ofs); - pstrcpy(name,""); - if (d < -50 || d > 50) return(0); - return(name_interpret(p,name)); + char *p = name_ptr(buf,ofs); + int d = PTR_DIFF(p,buf+ofs); + + name[0] = '\0'; + if (d < -50 || d > 50) + return(0); + return(name_interpret(p,name)); } /**************************************************************************** -return the total storage length of a mangled name + Return the total storage length of a mangled name. ****************************************************************************/ + int name_len(char *s1) { /* NOTE: this argument _must_ be unsigned */ - uchar *s = (uchar *)s1; + unsigned char *s = (unsigned char *)s1; int len; /* If the two high bits of the byte are set, return 2. */ @@ -1282,4 +1331,4 @@ int name_len(char *s1) } return(len); -} /* name_len */ +} -- cgit From 6b9dbbcd249360fb9acd61d6900baccf621c9cce Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 02:16:21 +0000 Subject: Modified fix for bugid #784. Based on a patch from moriyama@miraclelinux.com (MORIYAMA Masayuki). Don't use nstrings to hold workgroup and netbios names. The problem with them is that MB netbios and workgroup names in unix charset (particularly utf8) may be up to 3x bigger than the name when represented in dos charset (ie. cp932). So go back to using fstrings for these but translate into nstrings (ie. 16 byte length values) for transport on the wire. Jeremy. (This used to be commit b4ea493599ab414f7828b83f40a5a8b43479ff64) --- source3/libsmb/libsmbclient.c | 2 +- source3/libsmb/namequery.c | 4 ++-- source3/libsmb/nmblib.c | 28 +++++++++++++++++----------- 3 files changed, 20 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 37e794478d..35e8a9786b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1787,7 +1787,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!is_ipaddress(server) && /* Not an IP addr so check next */ (resolve_name(server, &rem_ip, 0x1d) || /* Found LMB */ resolve_name(server, &rem_ip, 0x1b) )) { /* Found DMB */ - pstring buserver; + fstring buserver; dir->dir_type = SMBC_SERVER; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index b6d1f8bda2..b9bc4e1166 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -163,7 +163,7 @@ struct node_status *node_status_query(int fd,struct nmb_name *name, a servers name given its IP. Return the matched name in *name. **************************************************************************/ -BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, char *name) +BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name) { struct node_status *status = NULL; struct nmb_name nname; @@ -202,7 +202,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t if (i == count) goto done; - pull_ascii_nstring(name, status[i].name); + pull_ascii_nstring(name, sizeof(fstring), status[i].name); /* Store the result in the cache. */ /* but don't store an entry for 0x1c names here. Here we have diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index cbe495cd95..bc2cca0e0e 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -285,7 +285,7 @@ static void put_name(char *dest, const char *name, int pad, unsigned int name_ty static int put_nmb_name(char *buf,int offset,struct nmb_name *name) { int ret,m; - fstring buf1; + nstring buf1; char *p; if (strcmp(name->name,"*") == 0) { @@ -1230,17 +1230,24 @@ static int name_interpret(char *in, fstring name) int name_mangle( char *In, char *Out, char name_type ) { int i; - int c; int len; - char buf[20]; + nstring buf; char *p = Out; /* Safely copy the input string, In, into buf[]. */ - memset( buf, 0, 20 ); - if (strcmp(In,"*") == 0) { - buf[0] = '*'; - } else { - slprintf( buf, sizeof(buf) - 1, "%-15.15s%c", In, name_type ); + if (strcmp(In,"*") == 0) + put_name(buf, "*", '\0', 0x00); + else { + /* We use an fstring here as mb dos names can expend x3 when + going to utf8. */ + fstring buf_unix; + nstring buf_dos; + + pull_ascii_fstring(buf_unix, In); + strupper_m(buf_unix); + + push_ascii_nstring(buf_dos, buf_unix); + put_name(buf, buf_dos, ' ', name_type); } /* Place the length of the first field into the output buffer. */ @@ -1249,9 +1256,8 @@ int name_mangle( char *In, char *Out, char name_type ) /* Now convert the name to the rfc1001/1002 format. */ for( i = 0; i < MAX_NETBIOSNAME_LEN; i++ ) { - c = toupper( buf[i] ); - p[i*2] = ( (c >> 4) & 0x000F ) + 'A'; - p[(i*2)+1] = (c & 0x000F) + 'A'; + p[i*2] = ( (buf[i] >> 4) & 0x000F ) + 'A'; + p[(i*2)+1] = (buf[i] & 0x000F) + 'A'; } p += 32; p[0] = '\0'; -- cgit From a0034d3586dadfddc18e4a3096564bf158d43e4e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Mar 2004 02:47:21 +0000 Subject: Ensure we don't truncate strcmps to nstring anymore... Jeremy. (This used to be commit d7cf64b1e4e501bcd01ddc8279babc65d894a4b3) --- source3/libsmb/nmblib.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index bc2cca0e0e..3c25eba744 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -855,8 +855,11 @@ static int build_dgram(char *buf,struct packet_struct *p) void make_nmb_name( struct nmb_name *n, const char *name, int type) { + fstring unix_name; memset( (char *)n, '\0', sizeof(struct nmb_name) ); - push_ascii(n->name, name, sizeof(n->name), STR_TERMINATE|STR_UPPER); + fstrcpy(unix_name, name); + strupper_m(unix_name); + push_ascii(n->name, unix_name, sizeof(n->name), STR_TERMINATE); n->name_type = (unsigned int)type & 0xFF; push_ascii(n->scope, global_scope(), 64, STR_TERMINATE); } -- cgit From 56ce6136792478c63d371a7b187c1318043e081f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Mar 2004 16:22:47 +0000 Subject: updating release notes & merging Derrel Lipman's libsmbclient patch from HEAD (This used to be commit 5fbfaa687a3674287eeadd205f56b2b253a9e2a9) --- source3/libsmb/cliconnect.c | 86 +++++-- source3/libsmb/clientgen.c | 11 + source3/libsmb/libsmb_cache.c | 9 +- source3/libsmb/libsmbclient.c | 557 +++++++++++++++++++++++++++++++++++------- 4 files changed, 546 insertions(+), 117 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 84159e5d62..e75a361e25 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1590,42 +1590,88 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, return NULL; } -/* Return the IP address and workgroup of a master browser on the - network. */ +/* + * Given the IP address of a master browser on the network, return its + * workgroup and connect to it. + * + * This function is provided to allow additional processing beyond what + * get_ipc_connect_master_ip_bcast() does, e.g. to retrieve the list of master + * browsers and obtain each master browsers' list of domains (in case the + * first master browser is recently on the network and has not yet + * synchronized with other master browsers and therefore does not yet have the + * entire network browse list) + */ -struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) +struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info) { - struct ip_service *ip_list; + static fstring name; struct cli_state *cli; - int i, count; struct in_addr server_ip; - /* Go looking for workgroups by broadcasting on the local network */ + DEBUG(99, ("Looking up name of master browser %s\n", + inet_ntoa(mb_ip->ip))); + + /* + * Do a name status query to find out the name of the master browser. + * We use <01><02>__MSBROWSE__<02>#01 if *#00 fails because a domain + * master browser will not respond to a wildcard query (or, at least, + * an NT4 server acting as the domain master browser will not). + * + * We might be able to use ONLY the query on MSBROWSE, but that's not + * yet been tested with all Windows versions, so until it is, leave + * the original wildcard query as the first choice and fall back to + * MSBROWSE if the wildcard query fails. + */ + if (!name_status_find("*", 0, 0x1d, mb_ip->ip, name) && + !name_status_find(MSBROWSE, 1, 0x1d, mb_ip->ip, name)) { - if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { - return False; + DEBUG(99, ("Could not retrieve name status for %s\n", + inet_ntoa(mb_ip->ip))); + return NULL; } - for (i = 0; i < count; i++) { - static fstring name; - - if (!name_status_find("*", 0, 0x1d, ip_list[i].ip, name)) - continue; - - if (!find_master_ip(name, &server_ip)) - continue; + if (!find_master_ip(name, &server_ip)) { + DEBUG(99, ("Could not find master ip for %s\n", name)); + return NULL; + } pstrcpy(workgroup, name); DEBUG(4, ("found master browser %s, %s\n", - name, inet_ntoa(ip_list[i].ip))); + name, inet_ntoa(mb_ip->ip))); cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); - if (!cli) - continue; - return cli; + +} + +/* + * Return the IP address and workgroup of a master browser on the network, and + * connect to it. + */ + +struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) +{ + struct ip_service *ip_list; + struct cli_state *cli; + int i, count; + + DEBUG(99, ("Do broadcast lookup for workgroups on local network\n")); + + /* Go looking for workgroups by broadcasting on the local network */ + + if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + DEBUG(99, ("No master browsers responded\n")); + return False; + } + + for (i = 0; i < count; i++) { + DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); + + cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info); + if (cli) + return(cli); } return NULL; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0873700fc0..8542eea064 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -367,6 +367,17 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) void cli_close_connection(struct cli_state *cli) { + /* + * tell our peer to free his resources. Wihtout this, when an + * application attempts to do a graceful shutdown and calls + * smbc_free_context() to clean up all connections, some connections + * can remain active on the peer end, until some (long) timeout period + * later. This tree disconnect forces the peer to clean up, since the + * connection will be going away. + */ + if ( cli->cnum != (uint16)-1 ) + cli_tdis(cli); + cli_nt_session_close(cli); cli_nt_netlogon_netsec_session_close(cli); diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 67dc686b48..cb40b4aaa6 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -159,10 +159,15 @@ static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) */ static int smbc_purge_cached(SMBCCTX * context) { - struct smbc_server_cache * srv = NULL; + struct smbc_server_cache * srv; + struct smbc_server_cache * next; int could_not_purge_all = 0; - for (srv=((struct smbc_server_cache *) context->server_cache);srv;srv=srv->next) { + for (srv = ((struct smbc_server_cache *) context->server_cache), + next = (srv ? srv->next :NULL); + srv; + srv = next, next = (srv ? srv->next : NULL)) { + if (smbc_remove_unused_server(context, srv->server)) { /* could not be removed */ could_not_purge_all = 1; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 35e8a9786b..68bb6661eb 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -156,18 +156,63 @@ decode_urlpart(char *segment, size_t sizeof_segment) /* * Function to parse a path and turn it into components * - * We accept smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]] - * - * smb:// means show all the workgroups - * smb://name/ means, if name<1D> or name<1B> exists, list servers in workgroup, - * else, if name<20> exists, list all shares for server ... + * The general format of an SMB URI is explain in Christopher Hertel's CIFS + * book, at http://ubiqx.org/cifs/Appendix-D.html. We accept a subset of the + * general format ("smb:" only; we do not look for "cifs:"), and expand on + * what he calls "context", herein called "options" to avoid conflict with the + * SMBCCTX context used throughout this library. We add the "mb" keyword + * which applies as follows: + * + * + * We accept: + * smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]][?options] + * + * Meaning of URLs: + * + * smb:// show all workgroups known by the first master browser found + * smb://?mb=.any same as smb:// (i.e. without any options) + * + * smb://?mb=.all show all workgroups known by every master browser found. + * Why might you want this? In an "appliance" application + * where the workgroup/domain being used on the local network + * is not known ahead of time, but where one wanted to + * provide network services via samba, a unique workgroup + * could be used. However, when the appliance is first + * started, the local samba instance's master browser has not + * synchronized with the other master browser(s) on the + * network (and might not synchronize for 12 minutes) and + * therefore is not aware of the workgroup/ domain names + * available on the network. This option may be used to + * overcome the problem of a libsmbclient application + * arbitrarily selecting the local (still ignorant) master + * browser to obtain its list of workgroups/domains and + * getting back a practically emmpty list. By requesting + * the list of workgroups/domains from each found master + * browser on the local network, a complete list of + * workgroups/domains can be built. + * + * smb://?mb=name NOT YET IMPLEMENTED -- show all workgroups known by the + * master browser whose name is "name" + * + * smb://name/ if name<1D> or name<1B> exists, list servers in + * workgroup, else, if name<20> exists, list all shares + * for server ... + * + * If "options" are provided, this function returns the entire option list as + * a string, for later parsing by the caller. */ static const char *smbc_prefix = "smb:"; static int -smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, char *path, - char *user, char *password) /* FIXME, lengths of strings */ +smbc_parse_path(SMBCCTX *context, + const char *fname, + char *server, int server_len, + char *share, int share_len, + char *path, int path_len, + char *user, int user_len, + char *password, int password_len, + char *options, int options_len) { static pstring s; pstring userinfo; @@ -176,10 +221,11 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, int len; server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; + if (options != NULL && options_len > 0) { + options[0] = (char)0; + } pstrcpy(s, fname); - /* clean_fname(s); causing problems ... */ - /* see if it has the right prefix */ len = strlen(smbc_prefix); if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { @@ -192,11 +238,25 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { + DEBUG(1, ("Invalid path (does not begin with smb://")); return -1; } - p += 2; /* Skip the // or \\ */ + p += 2; /* Skip the double slash */ + + /* See if any options were specified */ + if (q = strrchr(p, '?')) { + /* There are options. Null terminate here and point to them */ + *q++ = '\0'; + + DEBUG(4, ("Found options '%s'", q)); + + /* Copy the options */ + if (options != NULL && options_len > 0) { + safe_strcpy(options, q, options_len - 1); + } + } if (*p == (char)0) goto decoding; @@ -247,10 +307,10 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, } if (username[0]) - strncpy(user, username, sizeof(fstring)); /* FIXME, size and domain */ + strncpy(user, username, user_len); /* FIXME, domain */ if (passwd[0]) - strncpy(password, passwd, sizeof(fstring)); /* FIXME, size */ + strncpy(password, passwd, password_len); } @@ -268,24 +328,57 @@ smbc_parse_path(SMBCCTX *context, const char *fname, char *server, char *share, } - pstrcpy(path, p); + safe_strcpy(path, p, path_len - 1); all_string_sub(path, "/", "\\", 0); decoding: - decode_urlpart(path, sizeof(pstring)); - decode_urlpart(server, sizeof(fstring)); - decode_urlpart(share, sizeof(fstring)); - decode_urlpart(user, sizeof(fstring)); - decode_urlpart(password, sizeof(fstring)); + decode_urlpart(path, path_len); + decode_urlpart(server, server_len); + decode_urlpart(share, share_len); + decode_urlpart(user, user_len); + decode_urlpart(password, password_len); return 0; } /* - * Convert an SMB error into a UNIX error ... + * Verify that the options specified in a URL are valid */ +static int smbc_check_options(char *server, char *share, char *path, char *options) +{ + DEBUG(4, ("smbc_check_options(): server='%s' share='%s' path='%s' options='%s'\n", server, share, path, options)); + + /* No options at all is always ok */ + if (! *options) return 0; + + /* + * For right now, we only support a very few options possibilities. + * No options are supported if server, share, or path are not empty. + * If all are empty, then we support the following two choices right + * now: + * + * mb=.any + * mb=.all + */ + if ((*server || *share || *path) && *options) { + /* Invalid: options provided with server, share, or path */ + DEBUG(1, ("Found unsupported options (%s) with non-empty server, share, or path\n", options)); + return -1; + } + + if (strcmp(options, "mb=.any") != 0 && + strcmp(options, "mb=.all") != 0) { + DEBUG(1, ("Found unsupported options (%s)\n", options)); + return -1; + } + return 0; +} + +/* + * Convert an SMB error into a UNIX error ... + */ static int smbc_errno(SMBCCTX *context, struct cli_state *c) { int ret = cli_errno(c); @@ -469,6 +562,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); +#if 0 /* djl: obsolete code? neither group nor p is used beyond here */ if ((p=strchr_m(server_n,'#')) && (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { @@ -477,6 +571,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, *p = 0; } +#endif DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); @@ -503,7 +598,6 @@ SMBCSRV *smbc_server(SMBCCTX *context, */ c.port = 445; if (!cli_connect(&c, server_n, &ip)) { - cli_shutdown(&c); errno = ENETUNREACH; return NULL; } @@ -598,6 +692,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, DEBUG(2, ("Server connect ok: //%s/%s: %p\n", server, share, srv)); + DLIST_ADD(context->internal->_servers, srv); return srv; failed: @@ -648,17 +743,16 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, password, 0, Undefined, NULL); if (! NT_STATUS_IS_OK(nt_status)) { - DEBUG(0,("cli_full_connection failed! (%s)\n", + DEBUG(1,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); errno = ENOTSUP; return NULL; } if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) { - DEBUG(0, ("cli_nt_session_open fail! (%s)\n", - nt_errstr(nt_status))); + DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; - free(ipc_cli); + cli_shutdown(ipc_cli); return NULL; } @@ -673,14 +767,14 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, if (!NT_STATUS_IS_OK(nt_status)) { errno = smbc_errno(context, ipc_cli); - free(ipc_cli); + cli_shutdown(ipc_cli); return NULL; } ipc_srv = (SMBCSRV *)malloc(sizeof(*ipc_srv)); if (!ipc_srv) { errno = ENOMEM; - free(ipc_cli); + cli_shutdown(ipc_cli); return NULL; } @@ -690,14 +784,23 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, free(ipc_cli); /* now add it to the cache (internal or external) */ + + errno = 0; /* let cache function set errno if it likes */ if (context->callbacks.add_cached_srv_fn(context, ipc_srv, server, "IPC$$", workgroup, username)) { DEBUG(3, (" Failed to add server to cache\n")); + if (errno == 0) { + errno = ENOMEM; + } + cli_shutdown(&ipc_srv->cli); + free(ipc_srv); return NULL; } + + DLIST_ADD(context->internal->_servers, ipc_srv); } return ipc_srv; @@ -730,7 +833,16 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m } - smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return NULL; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1042,7 +1154,16 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) } - smbc_parse_path(context, fname, server, share, path, user, password); /* FIXME, check errors */ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1141,11 +1262,23 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - smbc_parse_path(ocontext, oname, server1, share1, path1, user1, password1); + smbc_parse_path(ocontext, oname, + server1, sizeof(server1), + share1, sizeof(share1), + path1, sizeof(path1), + user1, sizeof(user1), + password1, sizeof(password1), + NULL, 0); if (user1[0] == (char)0) fstrcpy(user1, ocontext->user); - smbc_parse_path(ncontext, nname, server2, share2, path2, user2, password2); + smbc_parse_path(ncontext, nname, + server2, sizeof(server2), + share2, sizeof(share2), + path2, sizeof(path2), + user2, sizeof(user2), + password2, sizeof(password2), + NULL, 0); if (user2[0] == (char)0) fstrcpy(user2, ncontext->user); @@ -1348,7 +1481,16 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) DEBUG(4, ("smbc_stat(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1360,27 +1502,6 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) return -1; /* errno set by smbc_server */ } - /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { - - mode = aDIR | aRONLY; - - } - else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - - if (strcmp(path, "\\") == 0) { - - mode = aDIR | aRONLY; - - } - else { - - mode = aRONLY; - smbc_stat_printjob(srv, path, &size, &m_time); - c_time = a_time = m_time; - - } - else { */ - if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { @@ -1462,16 +1583,7 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) /* * Routine to open a directory - * - * We want to allow: - * - * smb: which should list all the workgroups available - * smb:workgroup - * smb:workgroup//server - * smb://server - * smb://server/share - * smb:// which should list shares on server - * smb:///share which should list files on share + * We accept the URL syntax explained in smbc_parse_path(), above. */ static void smbc_remove_dir(SMBCFILE *dir) @@ -1536,7 +1648,6 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint ZERO_STRUCTP(dir->dir_list); dir->dir_end = dir->dir_next = dir->dir_list; - } else { @@ -1552,7 +1663,6 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint ZERO_STRUCTP(dir->dir_end->next); dir->dir_end = dir->dir_end->next; - } dir->dir_end->next = NULL; @@ -1575,6 +1685,46 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint } +static void +list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *state) +{ + SMBCFILE *dir = (SMBCFILE *)state; + struct smbc_dir_list *dir_list; + struct smbc_dirent *dirent; + int dirent_type; + int remove = 0; + + dirent_type = dir->dir_type; + + if (add_dirent(dir, name, comment, dirent_type) < 0) { + + /* An error occurred, what do we do? */ + /* FIXME: Add some code here */ + } + + /* Point to the one just added */ + dirent = dir->dir_end->dirent; + + /* See if this was a duplicate */ + for (dir_list = dir->dir_list; + dir_list != dir->dir_end; + dir_list = dir_list->next) { + if (! remove && + strcmp(dir_list->dirent->name, dirent->name) == 0) { + /* Duplicate. End end of list need to be removed. */ + remove = 1; + } + + if (remove && dir_list->next == dir->dir_end) { + /* Found the end of the list. Remove it. */ + dir->dir_end = dir_list; + free(dir_list->next); + dir_list->next = NULL; + break; + } + } +} + static void list_fn(const char *name, uint32 type, const char *comment, void *state) { @@ -1615,7 +1765,6 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) /* FIXME: Add some code here */ } - } static void @@ -1635,7 +1784,7 @@ dir_list_fn(file_info *finfo, const char *mask, void *state) static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { - fstring server, share, user, password; + fstring server, share, user, password, options; pstring workgroup; pstring path; SMBCSRV *srv = NULL; @@ -1656,13 +1805,26 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - if (smbc_parse_path(context, fname, server, share, path, user, password)) { + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(path), + password, sizeof(password), + options, sizeof(options))) { DEBUG(4, ("no valid path\n")); errno = EINVAL; return NULL; } - DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s'\n", fname, server, share, path)); + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s' options='%s'\n", fname, server, share, path, options)); + + /* Ensure the options are valid */ + if (smbc_check_options(server, share, path, options)) { + DEBUG(4, ("unacceptable options (%s)\n", options)); + errno = EINVAL; + return NULL; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -1686,8 +1848,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) dir->file = False; dir->dir_list = dir->dir_next = dir->dir_end = NULL; - if (server[0] == (char)0) { - struct in_addr server_ip; + if (server[0] == (char)0 && + (! *options || strcmp(options, "mb=.any") == 0)) { + struct in_addr server_ip; if (share[0] != (char)0 || path[0] != (char)0) { errno = EINVAL; @@ -1698,9 +1861,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - /* We have server and share and path empty ... so list the workgroups */ - /* first try to get the LMB for our workgroup, and if that fails, */ - /* try the DMB */ + /* + * We have server and share and path empty ... so list the + * workgroups first try to get the LMB for our workgroup, and + * if that fails, try the DMB + */ pstrcpy(workgroup, lp_workgroup()); @@ -1726,7 +1891,21 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) cli_shutdown(cli); } else { - if (!name_status_find("*", 0, 0, server_ip, server)) { + /* + * Do a name status query to find out the name of the + * master browser. We use <01><02>__MSBROWSE__<02>#01 if + * *#00 fails because a domain master browser will not + * respond to a wildcard query (or, at least, an NT4 + * server acting as the domain master browser will not). + * + * We might be able to use ONLY the query on MSBROWSE, but + * that's not yet been tested with all Windows versions, + * so until it is, leave the original wildcard query as + * the first choice and fall back to MSBROWSE if the + * wildcard query fails. + */ + if (!name_status_find("*", 0, 0x1d, server_ip, server) && + !name_status_find(MSBROWSE, 1, 0x1d, server_ip, server)) { errno = ENOENT; return NULL; } @@ -1734,9 +1913,10 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); - /* - * Get a connection to IPC$ on the server if we do not already have one - */ + /* + * Get a connection to IPC$ on the server if we do not already + * have one + */ srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { @@ -1756,6 +1936,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_fn, (void *)dir)) { + DEBUG(1, ("Could not enumerate domains using '%s'\n", workgroup)); if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -1765,9 +1946,99 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - } - else { /* Server not an empty string ... Check the rest and see what gives */ + } else if (server[0] == (char)0 && + (! *options || strcmp(options, "mb=.all") == 0)) { + + int i; + int count; + struct ip_service *ip_list; + struct ip_service server_addr; + struct user_auth_info u_info; + struct cli_state *cli; + + if (share[0] != (char)0 || path[0] != (char)0) { + + errno = EINVAL; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; + } + + pstrcpy(u_info.username, user); + pstrcpy(u_info.password, password); + + /* + * We have server and share and path empty but options + * requesting that we scan all master browsers for their list + * of workgroups/domains. This implies that we must first try + * broadcast queries to find all master browsers, and if that + * doesn't work, then try our other methods which return only + * a single master browser. + */ + + if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + if (!find_master_ip(workgroup, &server_addr.ip)) { + + errno = ENOENT; + return NULL; + } + ip_list = &server_addr; + count = 1; + } + + for (i = 0; i < count; i++) { + DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); + + cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info); + fstrcpy(server, cli->desthost); + cli_shutdown(cli); + + DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); + + /* + * For each returned master browser IP address, get a + * connection to IPC$ on the server if we do not + * already have one, and determine the + * workgroups/domains that it knows about. + */ + + srv = smbc_server(context, server, + "IPC$", workgroup, user, password); + if (!srv) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; + } + + dir->srv = srv; + dir->dir_type = SMBC_WORKGROUP; + + /* Now, list the stuff ... */ + + if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, + (void *)dir)) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + errno = cli_errno(&srv->cli); + + return NULL; + + } + } + } else { + /* + * Server not an empty string ... Check the rest and see what + * gives + */ if (share[0] == (char)0) { if (path[0] != (char)0) { /* Should not have empty share with path */ @@ -1796,7 +2067,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) */ - if (!name_status_find("*", 0, 0, rem_ip, buserver)) { + if (!name_status_find(server, 0, 0, rem_ip, buserver)) { DEBUG(0, ("Could not get name of local/domain master browser for server %s\n", server)); errno = EPERM; /* FIXME, is this correct */ @@ -1835,7 +2106,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - } else { @@ -1962,7 +2232,6 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) SAFE_FREE(dir->fname); SAFE_FREE(dir); /* Free the space too */ - } return 0; @@ -1983,6 +2252,7 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) !context->internal->_initialized) { errno = EINVAL; + DEBUG(0, ("Invalid context in smbc_readdir_ctx()\n")); return NULL; } @@ -1990,6 +2260,7 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; + DEBUG(0, ("Invalid dir in smbc_readdir_ctx()\n")); return NULL; } @@ -1997,16 +2268,17 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; + DEBUG(0, ("Found file vs directory in smbc_readdir_ctx()\n")); return NULL; } - if (!dir->dir_next) + if (!dir->dir_next) { return NULL; + } else { dirent = dir->dir_next->dirent; - if (!dirent) { errno = ENOENT; @@ -2142,7 +2414,16 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -2229,7 +2510,17 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) + { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -2466,7 +2757,16 @@ int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -2518,7 +2818,16 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) DEBUG(4, ("smbc_utimes(%s, [%s])\n", fname, ctime(&t))); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3353,7 +3662,16 @@ int smbc_setxattr_ctx(SMBCCTX *context, DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (char *) value)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3485,7 +3803,16 @@ int smbc_getxattr_ctx(SMBCCTX *context, DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3568,7 +3895,16 @@ int smbc_removexattr_ctx(SMBCCTX *context, DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3700,7 +4036,16 @@ static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return NULL; + } /* What if the path is empty, or the file exists? */ @@ -3814,7 +4159,16 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_li DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3867,7 +4221,16 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - smbc_parse_path(context, fname, server, share, path, user, password); /*FIXME, errors*/ + if (smbc_parse_path(context, fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } if (user[0] == (char)0) fstrcpy(user, context->user); @@ -3989,13 +4352,17 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) /* First try to remove the servers the nice way. */ if (context->callbacks.purge_cached_fn(context)) { SMBCSRV * s; + SMBCSRV * next; DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); s = context->internal->_servers; while (s) { + DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", s, s->cli.fd)); cli_shutdown(&s->cli); context->callbacks.remove_cached_srv_fn(context, s); + next = s->next; + DLIST_REMOVE(context->internal->_servers, s); SAFE_FREE(s); - s = s->next; + s = next; } context->internal->_servers = NULL; } -- cgit From 90f64838f49283aaf2a14adc99113ac3d5ddd795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Mar 2004 03:48:08 +0000 Subject: Added cli_set_ea(), cli_get_ea next... Jeremy. (This used to be commit b0c109c40335a2f59406e1d2845d676d211faf14) --- source3/libsmb/clifile.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a3fa811e29..6641d6b056 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1161,3 +1161,67 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * return NT_STATUS_OK; } + +/********************************************************* + Set an extended attribute on a pathname. +*********************************************************/ + +BOOL cli_set_ea(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) +{ + unsigned int data_len = 0; + unsigned int param_len = 0; + uint16 setup = TRANSACT2_SETPATHINFO; + char param[sizeof(pstring)+6]; + char *data = NULL; + char *rparam=NULL, *rdata=NULL; + char *p; + size_t srclen = 2*(strlen(path)+1); + size_t ea_namelen = strlen(ea_name); + + memset(param, 0, sizeof(param)); + SSVAL(param,0,SMB_INFO_SET_EA); + p = ¶m[6]; + + p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + data_len = 4 + ea_namelen + 1 + ea_len; + data = malloc(data_len); + if (!data) { + return False; + } + p = data; + SCVAL(p, 0, 0); /* EA flags. */ + SCVAL(p, 1, ea_namelen); + SSVAL(p, 2, ea_len); + memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ + memcpy(p+4+ea_namelen+1, ea_val, ea_len); + data_len = 4 + ea_namelen + 1 + ea_len; + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + SAFE_FREE(data); + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + +BOOL cli_get_ea(struct cli_state *cli, const char *path, const char *ea_name, char **value, size_t *val_len) +{ + return False; +} -- cgit From 9a8e30d04b1cfc53e8c8949a56d4f1cf5aa26501 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 24 Mar 2004 17:32:55 +0000 Subject: Fix bugzilla # 1208 Winbind tickets expired. We now check the expiration time, and acquire new tickets. We couln't rely on renewing them, because if we didn't get a request before they expired, we wouldn't have renewed them. Also, there is a one-week limit in MS on renewal life, so new tickets would have been needed after a week anyway. Default is 10 hours, so we should only be acquiring them that often, unless the configuration on the DC is changed (and the minimum is 1 hour). (This used to be commit c2436c433afaab4006554a86307f76b6689d6929) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e75a361e25..3f87119ce2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -718,7 +718,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, int ret; use_in_memory_ccache(); - ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL); if (ret){ DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); -- cgit From 651d5b4683f4c97608a5f19c9996f85ae6b21fc6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 27 Mar 2004 02:13:58 +0000 Subject: Working (tested) client code for setting EA's by filename and fnum. Now for parsing out the retrieved EA's. Jeremy. (This used to be commit 5eeeee302cec2cc1f6c130ed44be9df028f73cde) --- source3/libsmb/clifile.c | 105 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 100 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 6641d6b056..23c98c16f3 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1166,7 +1166,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * Set an extended attribute on a pathname. *********************************************************/ -BOOL cli_set_ea(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) +BOOL cli_set_path_ea(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -1185,25 +1185,82 @@ BOOL cli_set_ea(struct cli_state *cli, const char *path, const char *ea_name, co p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE); param_len = PTR_DIFF(p, param); - data_len = 4 + ea_namelen + 1 + ea_len; + data_len = 4 + 4 + ea_namelen + 1 + ea_len; data = malloc(data_len); if (!data) { return False; } p = data; + SIVAL(p,0,data_len); + p += 4; SCVAL(p, 0, 0); /* EA flags. */ SCVAL(p, 1, ea_namelen); SSVAL(p, 2, ea_len); memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ memcpy(p+4+ea_namelen+1, ea_val, ea_len); - data_len = 4 + ea_namelen + 1 + ea_len; if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ + data, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + SAFE_FREE(data); + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + +/********************************************************* + Set an extended attribute on an fnum. +*********************************************************/ + +BOOL cli_set_fnum_ea(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len) +{ + unsigned int data_len = 0; + unsigned int param_len = 6; + uint16 setup = TRANSACT2_SETFILEINFO; + pstring param; + char *data = NULL; + char *rparam=NULL, *rdata=NULL; + char *p; + size_t ea_namelen = strlen(ea_name); + + memset(param, 0, sizeof(param)); + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_INFO_SET_EA); + + data_len = 4 + 4 + ea_namelen + 1 + ea_len; + data = malloc(data_len); + if (!data) { + return False; + } + p = data; + SIVAL(p,0,data_len); + p += 4; + SCVAL(p, 0, 0); /* EA flags. */ + SCVAL(p, 1, ea_namelen); + SSVAL(p, 2, ea_len); + memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ + memcpy(p+4+ea_namelen+1, ea_val, ea_len); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + data, data_len, cli->max_xmit /* data, length, max */ )) { return False; } @@ -1221,7 +1278,45 @@ BOOL cli_set_ea(struct cli_state *cli, const char *path, const char *ea_name, co return True; } -BOOL cli_get_ea(struct cli_state *cli, const char *path, const char *ea_name, char **value, size_t *val_len) +BOOL cli_get_eas(struct cli_state *cli, const char *path, + TALLOC_CTX *ctx, + size_t *pnum_eas, + struct ea_struct **ea_list) { + unsigned int data_len = 0; + unsigned int param_len = 0; + unsigned int rparam_len, rdata_len; + uint16 setup = TRANSACT2_QPATHINFO; + pstring param; + char *rparam=NULL, *rdata=NULL; + char *p; + + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); + p += 6; + p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); + + param_len = PTR_DIFF(p, param); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* Name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_len, + &rdata, &rdata_len)) { + return False; + } + + if (!rdata || rdata_len < 4) { + return False; + } return False; } -- cgit From e9a7e67e01c115328f95690cbf63ca1ef0b4d408 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:33:59 +0000 Subject: Merge from HEAD the SMB signing patch that I developed a couple of weeks ago. This patch re-adds support for 'optional' SMB signing. It also ensures that we are much more careful about when we enable signing, particularly with on-the-fly smb.conf reloads. The client code will now attempt to use smb signing by default, and disable it if the server doesn't correctly support it. Andrew Bartlett (This used to be commit e27b5cbe75d89ec839dafd52dd33101885a4c263) --- source3/libsmb/cliconnect.c | 23 +++++---- source3/libsmb/clientgen.c | 2 +- source3/libsmb/smb_signing.c | 120 +++++++++++++++++++++++++++---------------- 3 files changed, 91 insertions(+), 54 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3f87119ce2..63541e18b5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -325,7 +325,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, session_key = data_blob(NULL, 16); SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); } - cli_simple_set_signing(cli, session_key, nt_response, 0); + cli_simple_set_signing(cli, session_key, nt_response); } else { /* pre-encrypted password supplied. Only used for security=server, can't do @@ -521,7 +521,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif - cli_simple_set_signing(cli, session_key_krb5, null_blob, 0); + cli_simple_set_signing(cli, session_key_krb5, null_blob); blob2 = cli_session_setup_blob(cli, negTokenTarg); @@ -643,13 +643,16 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); - /* Using NTLMSSP session setup, signing on the net only starts - * after a successful authentication and the session key has - * been determined, but with a sequence number of 2. This - * assumes that NTLMSSP needs exactly 2 roundtrips, for any - * other SPNEGO mechanism it needs adapting. */ - - cli_simple_set_signing(cli, key, null_blob, 2); + if (cli_simple_set_signing(cli, key, null_blob)) { + + /* 'resign' the last message, so we get the right sequence numbers + for checking the first reply from the server */ + cli_calculate_sign_mac(cli); + + if (!cli_check_sign_mac(cli, True)) { + nt_status = NT_STATUS_ACCESS_DENIED; + } + } } /* we have a reference conter on ntlmssp_state, if we are signing @@ -1088,6 +1091,8 @@ BOOL cli_negprot(struct cli_state *cli) } cli->sign_info.negotiated_smb_signing = True; cli->sign_info.mandatory_signing = True; + } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { + cli->sign_info.negotiated_smb_signing = True; } } else if (cli->protocol >= PROTOCOL_LANMAN1) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8542eea064..66edc3ce38 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -117,7 +117,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_check_sign_mac(cli)) { + if (!cli_check_sign_mac(cli, True)) { DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = READ_BAD_SIG; close(cli->fd); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 9010dbf5cb..c71543959d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -150,7 +150,7 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) { return True; } @@ -197,25 +197,39 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq) +static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok) { - if (good && !si->doing_signing) { - si->doing_signing = True; - } + if (good) { - if (!good) { - if (si->doing_signing) { - struct smb_basic_signing_context *data = si->signing_context; + if (!si->doing_signing) { + si->doing_signing = True; + } + + if (!si->seen_valid) { + si->seen_valid = True; + } - /* W2K sends a bad first signature but the sign engine is on.... JRA. */ - if (data->send_seq_num > 1) - DEBUG(1, ("signing_good: SMB signature check failed on seq %u!\n", - (unsigned int)seq )); + } else { + if (!si->mandatory_signing && !si->seen_valid) { - return False; - } else { - DEBUG(3, ("signing_good: Peer did not sign reply correctly\n")); + if (!must_be_ok) { + return True; + } + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ +isn't sending correct signatures. Turning off.\n")); + si->negotiated_smb_signing = False; + si->allow_smb_signing = False; + si->doing_signing = False; free_signing_context(si); + return True; + } else if (!must_be_ok) { + /* This packet is known to be unsigned */ + return True; + } else { + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + if (seq) + DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); return False; } } @@ -323,7 +337,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) { BOOL good; uint32 reply_seq_number; @@ -381,7 +395,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq); + return signing_good(inbuf, si, good, saved_seq, must_be_ok); } /*********************************************************** @@ -415,7 +429,7 @@ static void simple_free_signing_context(struct smb_sign_info *si) BOOL cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, - const DATA_BLOB response, int initial_send_seq_num) + const DATA_BLOB response) { struct smb_basic_signing_context *data; @@ -453,7 +467,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); /* Initialise the sequence number */ - data->send_seq_num = initial_send_seq_num; + data->send_seq_num = 0; /* Initialise the list of outstanding packets */ data->outstanding_packet_list = NULL; @@ -535,7 +549,7 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo) { return True; } @@ -597,9 +611,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -BOOL cli_check_sign_mac(struct cli_state *cli) +BOOL cli_check_sign_mac(struct cli_state *cli, BOOL must_be_ok) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info)) { + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, must_be_ok)) { free_signing_context(&cli->sign_info); return False; } @@ -688,7 +702,7 @@ static BOOL is_oplock_break(char *inbuf) SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ -static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si) +static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) { BOOL good; struct smb_basic_signing_context *data = si->signing_context; @@ -762,25 +776,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); dump_data(10, (const char *)server_sent_mac, 8); } - if (!signing_good(inbuf, si, good, saved_seq)) { - if (!si->mandatory_signing && (data->send_seq_num < 3)){ - /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ -isn't sending correct signatures. Turning off.\n")); - si->negotiated_smb_signing = False; - si->allow_smb_signing = False; - si->doing_signing = False; - free_signing_context(si); - return True; - } else { - /* Mandatory signing or bad packet after signing started - fail and disconnect. */ - if (saved_seq) - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u\n", (unsigned int)saved_seq)); - return False; - } - } else { - return True; - } + return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); } /*********************************************************** @@ -813,13 +809,13 @@ BOOL srv_oplock_set_signing(BOOL onoff) Called to validate an incoming packet from the client. ************************************************************/ -BOOL srv_check_sign_mac(char *inbuf) +BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) { /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) return True; - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info); + return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); } /*********************************************************** @@ -907,6 +903,42 @@ BOOL srv_is_signing_active(void) return srv_sign_info.doing_signing; } + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +BOOL srv_is_signing_negotiated(void) +{ + return srv_sign_info.negotiated_smb_signing; +} + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +BOOL srv_signing_started(void) +{ + struct smb_basic_signing_context *data; + + if (!srv_sign_info.doing_signing) { + return False; + } + + data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!data) + return False; + + if (data->send_seq_num == 0) { + return False; + } + + return True; +} + + /*********************************************************** Tell server code we are in a multiple trans reply state. ************************************************************/ -- cgit From 6dbd02d056750de48dd09c2a222a36e74079d044 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:51:31 +0000 Subject: Make it clearer that this error refers to the peer, as this code is in both the client and server. Andrew Bartlett (This used to be commit 414d3fdc753b44262e9a281170d1058608d01bdf) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c71543959d..7a90e645b3 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -216,8 +216,8 @@ static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint3 return True; } /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and client \ -isn't sending correct signatures. Turning off.\n")); + DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" + "isn't sending correct signatures. Turning off.\n")); si->negotiated_smb_signing = False; si->allow_smb_signing = False; si->doing_signing = False; -- cgit From 873db3f5fd3fbfcf290cea61d7e9f58bf28b3983 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:53:47 +0000 Subject: Based on the detective work of Jianliang Lu , allow yet another NTLMv2 combination. We should allow the NTLMv2 response to be calculated with either the domain as supplied, or the domain in UPPER case (as we always did in the past). As a client, we always UPPER case it (as per the spec), but we also make sure to UPPER case the domain, when we send it. This should give us maximum compatability. Andrew Bartlett (This used to be commit 1e91cd0cf87b29899641585f46b0dcecaefd848e) --- source3/libsmb/cliconnect.c | 8 +++++--- source3/libsmb/ntlm_check.c | 31 ++++++++++++++++++++++++++++--- source3/libsmb/ntlmssp.c | 4 +++- source3/libsmb/smbencrypt.c | 10 +++++++--- 4 files changed, 43 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 63541e18b5..adfeec2290 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -358,7 +358,9 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, memcpy(p,nt_response.data, nt_response.length); p += nt_response.length; } p += clistr_push(cli, p, user, -1, STR_TERMINATE); - p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); + + /* Upper case here might help some NTLMv2 implementations */ + p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); @@ -649,7 +651,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use for checking the first reply from the server */ cli_calculate_sign_mac(cli); - if (!cli_check_sign_mac(cli, True)) { + if (!cli_check_sign_mac(cli, False)) { nt_status = NT_STATUS_ACCESS_DENIED; } } @@ -874,7 +876,7 @@ BOOL cli_send_tconX(struct cli_state *cli, if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { if (!lp_client_lanman_auth()) { - DEBUG(1, ("Server requested LANMAN password but 'client use lanman auth'" + DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'" " is disabled\n")); return False; } diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index 362b640f91..bc291b5128 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -85,6 +85,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, const uchar *part_passwd, const DATA_BLOB *sec_blob, const char *user, const char *domain, + BOOL upper_case_domain, /* should the domain be transformed into upper case? */ DATA_BLOB *user_sess_key) { /* Finish the encryption of part_passwd. */ @@ -122,7 +123,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, memcpy(client_response, ntv2_response->data, sizeof(client_response)); - if (!ntv2_owf_gen(part_passwd, user, domain, kr)) { + if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) { return False; } @@ -235,13 +236,24 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, if (nt_response->length >= 24 && nt_pw) { if (nt_response->length > 24) { /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). + use it */ DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain)); if (smb_pwd_check_ntlmv2( nt_response, nt_pw, challenge, - client_username, + client_username, + client_domain, + False, + user_sess_key)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain)); + if (smb_pwd_check_ntlmv2( nt_response, + nt_pw, challenge, + client_username, client_domain, + True, user_sess_key)) { return NT_STATUS_OK; } @@ -251,6 +263,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, nt_pw, challenge, client_username, "", + False, user_sess_key)) { return NT_STATUS_OK; } else { @@ -334,6 +347,17 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, nt_pw, challenge, client_username, client_domain, + False, + NULL)) { + return NT_STATUS_OK; + } + + DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain)); + if (smb_pwd_check_ntlmv2( lm_response, + nt_pw, challenge, + client_username, + client_domain, + True, NULL)) { return NT_STATUS_OK; } @@ -343,6 +367,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, nt_pw, challenge, client_username, "", + False, NULL)) { return NT_STATUS_OK; } diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 60523ddf9d..82eafc4cd5 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -168,7 +168,9 @@ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password */ NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) { - ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + /* Possibly make our NTLMv2 client more robust by always having + an uppercase domain */ + ntlmssp_state->domain = talloc_strdup_upper(ntlmssp_state->mem_ctx, domain); if (!ntlmssp_state->domain) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index c5acedae51..270a659e57 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -127,7 +127,9 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) /* Does both the NTLMv2 owfs of a user's password */ BOOL ntv2_owf_gen(const uchar owf[16], - const char *user_in, const char *domain_in, uchar kr_buf[16]) + const char *user_in, const char *domain_in, + BOOL upper_case_domain, /* Transform the domain into UPPER case */ + uchar kr_buf[16]) { smb_ucs2_t *user; smb_ucs2_t *domain; @@ -150,7 +152,9 @@ BOOL ntv2_owf_gen(const uchar owf[16], } strupper_w(user); - strupper_w(domain); + + if (upper_case_domain) + strupper_w(domain); SMB_ASSERT(user_byte_len >= 2); SMB_ASSERT(domain_byte_len >= 2); @@ -426,7 +430,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password the username and domain. This prevents username swapping during the auth exchange */ - if (!ntv2_owf_gen(nt_hash, user, domain, ntlm_v2_hash)) { + if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) { return False; } -- cgit From 63f5167a288043553b7efaf206cf5e4338d07db0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 08:43:09 +0000 Subject: Add a few comments explaining KEY_EXCH Andrew Bartlett (This used to be commit e5422d7413e22775bc81e36559cb69254aedb102) --- source3/libsmb/ntlmssp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 82eafc4cd5..ddc2e0325f 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -1022,16 +1022,19 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* Key exchange encryptes a new client-generated session key with the password-derived key */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + /* Make up a new session key */ uint8 client_session_key[16]; - - generate_random_buffer(client_session_key, sizeof(client_session_key), False); + generate_random_buffer(client_session_key, sizeof(client_session_key), False); + + /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); dump_data_pw("KEY_EXCH session key:\n", encrypted_session_key.data, encrypted_session_key.length); - SamOEMhash(encrypted_session_key.data, session_key.data, encrypted_session_key.length); + dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); + + /* Mark the new session key as the 'real' session key */ data_blob_free(&session_key); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, client_session_key, sizeof(client_session_key)); - dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); } /* this generates the actual auth packet */ -- cgit From b65d7d59c2e93e32225805389176751c9ffdafee Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 08:51:04 +0000 Subject: Revert bogus part of smb signing commit - when Win2k supports singing/SPNEGO, it does sign the first packet. Andrew Bartlett (This used to be commit 4b9c50db853eaf9eb8c68b85760c40c1a8f9bd94) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index adfeec2290..63c91469e3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -651,7 +651,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use for checking the first reply from the server */ cli_calculate_sign_mac(cli); - if (!cli_check_sign_mac(cli, False)) { + if (!cli_check_sign_mac(cli, True)) { nt_status = NT_STATUS_ACCESS_DENIED; } } -- cgit From 7c2b0d536b5b76aeec60a5c1d4be8316d19099d9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 10:32:59 +0000 Subject: Let the comment match the function... Andrew Bartlett (This used to be commit 43c71b3202e909cca7c41c54d0b340aea1323db6) --- source3/libsmb/smb_signing.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 7a90e645b3..7130453c0c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -915,8 +915,7 @@ BOOL srv_is_signing_negotiated(void) } /*********************************************************** - Returns whether signing is negotiated. We can't use it unless it was - in the negprot. + Returns whether signing is actually happening ************************************************************/ BOOL srv_signing_started(void) -- cgit From 099974aa1575bf580c69c3848bc73d5d3b4b2bf3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 29 Mar 2004 22:21:47 +0000 Subject: Fix get/set of EA's in client library. Added torture test for it. Jeremy. (This used to be commit 0d239a9c070bdc1ce2d2806fc02549c4750597aa) --- source3/libsmb/clifile.c | 237 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 163 insertions(+), 74 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 23c98c16f3..52164dc0b4 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1163,28 +1163,18 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * } /********************************************************* - Set an extended attribute on a pathname. + Set an extended attribute utility fn. *********************************************************/ -BOOL cli_set_path_ea(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) -{ +static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len, + const char *ea_name, const char *ea_val, size_t ea_len) +{ unsigned int data_len = 0; - unsigned int param_len = 0; - uint16 setup = TRANSACT2_SETPATHINFO; - char param[sizeof(pstring)+6]; char *data = NULL; char *rparam=NULL, *rdata=NULL; char *p; - size_t srclen = 2*(strlen(path)+1); size_t ea_namelen = strlen(ea_name); - memset(param, 0, sizeof(param)); - SSVAL(param,0,SMB_INFO_SET_EA); - p = ¶m[6]; - - p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE); - param_len = PTR_DIFF(p, param); - data_len = 4 + 4 + ea_namelen + 1 + ea_len; data = malloc(data_len); if (!data) { @@ -1223,82 +1213,65 @@ BOOL cli_set_path_ea(struct cli_state *cli, const char *path, const char *ea_nam } /********************************************************* - Set an extended attribute on an fnum. + Set an extended attribute on a pathname. *********************************************************/ -BOOL cli_set_fnum_ea(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len) +BOOL cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) { - unsigned int data_len = 0; - unsigned int param_len = 6; - uint16 setup = TRANSACT2_SETFILEINFO; - pstring param; - char *data = NULL; - char *rparam=NULL, *rdata=NULL; + uint16 setup = TRANSACT2_SETPATHINFO; + unsigned int param_len = 0; + char param[sizeof(pstring)+6]; + size_t srclen = 2*(strlen(path)+1); char *p; - size_t ea_namelen = strlen(ea_name); memset(param, 0, sizeof(param)); - SSVAL(param,0,fnum); - SSVAL(param,2,SMB_INFO_SET_EA); + SSVAL(param,0,SMB_INFO_SET_EA); + p = ¶m[6]; - data_len = 4 + 4 + ea_namelen + 1 + ea_len; - data = malloc(data_len); - if (!data) { - return False; - } - p = data; - SIVAL(p,0,data_len); - p += 4; - SCVAL(p, 0, 0); /* EA flags. */ - SCVAL(p, 1, ea_namelen); - SSVAL(p, 2, ea_len); - memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ - memcpy(p+4+ea_namelen+1, ea_val, ea_len); + p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE); + param_len = PTR_DIFF(p, param); - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - data, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } + return cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len); +} - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; - } +/********************************************************* + Set an extended attribute on an fnum. +*********************************************************/ - SAFE_FREE(data); - SAFE_FREE(rdata); - SAFE_FREE(rparam); +BOOL cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len) +{ + char param[6]; + uint16 setup = TRANSACT2_SETFILEINFO; - return True; + memset(param, 0, 6); + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_INFO_SET_EA); + + return cli_set_ea(cli, setup, param, 6, ea_name, ea_val, ea_len); } -BOOL cli_get_eas(struct cli_state *cli, const char *path, +/********************************************************* + Get an extended attribute list tility fn. +*********************************************************/ + +static BOOL cli_get_ea_list(struct cli_state *cli, + uint16 setup, char *param, unsigned int param_len, TALLOC_CTX *ctx, size_t *pnum_eas, - struct ea_struct **ea_list) + struct ea_struct **pea_list) { unsigned int data_len = 0; - unsigned int param_len = 0; unsigned int rparam_len, rdata_len; - uint16 setup = TRANSACT2_QPATHINFO; - pstring param; char *rparam=NULL, *rdata=NULL; char *p; - - p = param; - memset(p, 0, 6); - SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); - p += 6; - p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); - - param_len = PTR_DIFF(p, param); - + size_t ea_size; + size_t num_eas; + BOOL ret = False; + struct ea_struct *ea_list; + + *pnum_eas = 0; + *pea_list = NULL; + if (!cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ @@ -1308,15 +1281,131 @@ BOOL cli_get_eas(struct cli_state *cli, const char *path, )) { return False; } - + if (!cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_len, &rdata, &rdata_len)) { return False; } - + if (!rdata || rdata_len < 4) { - return False; + goto out; } - return False; + + ea_size = (size_t)IVAL(rdata,0); + if (ea_size > rdata_len) { + goto out; + } + + p = rdata + 4; + ea_size -= 4; + + /* Validate the EA list and count it. */ + for (num_eas = 0; ea_size >= 4; num_eas++) { + unsigned int ea_namelen = CVAL(p,1); + unsigned int ea_valuelen = SVAL(p,2); + if (ea_namelen == 0) { + goto out; + } + if (4 + ea_namelen + 1 + ea_valuelen > ea_size) { + goto out; + } + ea_size -= 4 + ea_namelen + 1 + ea_valuelen; + p += 4 + ea_namelen + 1 + ea_valuelen; + } + + if (num_eas == 0) { + ret = True; + goto out; + } + + *pnum_eas = num_eas; + if (!pea_list) { + /* Caller only wants number of EA's. */ + ret = True; + goto out; + } + + ea_list = (struct ea_struct *)talloc(ctx, num_eas*sizeof(struct ea_struct)); + if (!ea_list) { + goto out; + } + + ea_size = (size_t)IVAL(rdata,0); + p = rdata + 4; + + for (num_eas = 0; num_eas < *pnum_eas; num_eas++ ) { + struct ea_struct *ea = &ea_list[num_eas]; + fstring unix_ea_name; + unsigned int ea_namelen = CVAL(p,1); + unsigned int ea_valuelen = SVAL(p,2); + + ea->flags = CVAL(p,0); + unix_ea_name[0] = '\0'; + pull_ascii_fstring(unix_ea_name, p + 4); + ea->name = talloc_strdup(ctx, unix_ea_name); + /* Ensure the value is null terminated (in case it's a string). */ + ea->value = data_blob_talloc(ctx, NULL, ea_valuelen + 1); + if (!ea->value.data) { + goto out; + } + if (ea_valuelen) { + memcpy(ea->value.data, p+4+ea_namelen+1, ea_valuelen); + } + ea->value.data[ea_valuelen] = 0; + ea->value.length--; + p += 4 + ea_namelen + 1 + ea_valuelen; + } + + *pea_list = ea_list; + ret = True; + + out : + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return ret; +} + +/********************************************************* + Get an extended attribute list from a pathname. +*********************************************************/ + +BOOL cli_get_ea_list_path(struct cli_state *cli, const char *path, + TALLOC_CTX *ctx, + size_t *pnum_eas, + struct ea_struct **pea_list) +{ + uint16 setup = TRANSACT2_QPATHINFO; + unsigned int param_len = 0; + char param[sizeof(pstring)+6]; + char *p; + + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); + p += 6; + p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + return cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list); +} + +/********************************************************* + Get an extended attribute list from an fnum. +*********************************************************/ + +BOOL cli_get_ea_list_fnum(struct cli_state *cli, int fnum, + TALLOC_CTX *ctx, + size_t *pnum_eas, + struct ea_struct **pea_list) +{ + uint16 setup = TRANSACT2_QFILEINFO; + char param[6]; + + memset(param, 0, 6); + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_INFO_SET_EA); + + return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list); } -- cgit From 97b200d422ce7e4acc9a6a9e786c4d44b3c6dfc3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 30 Mar 2004 08:03:32 +0000 Subject: Apply some const (This used to be commit 8037750df568e6b51b2b0cba9192468110470388) --- source3/libsmb/samlogon_cache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 72c10007bf..4cd642c4e3 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -157,7 +157,7 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) free the user_info struct (malloc()'d memory) ***********************************************************************/ -NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, DOM_SID *user_sid) +NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) { NET_USER_INFO_3 *user = NULL; TDB_DATA data, key; @@ -218,7 +218,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, DOM_SID *user_sid) return user; } -BOOL netsamlogon_cache_have(DOM_SID *user_sid) +BOOL netsamlogon_cache_have(const DOM_SID *user_sid) { TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); NET_USER_INFO_3 *user = NULL; -- cgit From a1994d1c967082a5e97ff5ce01c9d5c63deb2db0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Mar 2004 18:38:21 +0000 Subject: Ensure we cope correctly with ea length of zero. Detect torture fail correctly. Jeremy. (This used to be commit 43db249fb814cef99afecd22c20a824d2519faf9) --- source3/libsmb/clifile.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 52164dc0b4..bf7923ec78 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1297,6 +1297,12 @@ static BOOL cli_get_ea_list(struct cli_state *cli, goto out; } + if (ea_size == 0) { + /* No EA's present. */ + ret = True; + goto out; + } + p = rdata + 4; ea_size -= 4; -- cgit From 70227784ba773eefe658ceaaf506f63509d5f5d1 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 31 Mar 2004 20:24:10 +0000 Subject: fix typo (This used to be commit 4b737b51a5cf0a862f4c1bd67d9d3dd49cc81b65) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 63c91469e3..cdf58c5b91 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -590,7 +590,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use /* now send that blob on its way */ if (!cli_session_setup_blob_send(cli, msg1)) { - DEBUG(3, ("Failed to send NTLMSSP/SPENGO blob to server!\n")); + DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n")); nt_status = NT_STATUS_UNSUCCESSFUL; } else { data_blob_free(&msg1); @@ -822,7 +822,7 @@ BOOL cli_session_setup(struct cli_state *cli, if (cli->capabilities & CAP_EXTENDED_SECURITY) { ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup); if (!ADS_ERR_OK(status)) { - DEBUG(3, ("SPENGO login failed: %s\n", ads_errstr(status))); + DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status))); return False; } return True; -- cgit From c2ff214772ac1934731938b3804d37e514e45c32 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 3 Apr 2004 15:41:32 +0000 Subject: Fix most of bug #169. For a (very) long time, we have had a bug in Samba were an NTLMv2-only PDC would fail, because it converted the password into NTLM format for checking. This patch performs the direct comparison required for interactive logons to function in this situation. It also removes the 'auth flags', which simply where not ever used. Natrually, this plays with the size of structures, so rebuild, rebuild rebuild... Andrew Bartlett (This used to be commit 9598593bcf2d877b1d08cd6a7323ee0bc160d4ba) --- source3/libsmb/ntlm_check.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index bc291b5128..a7764f9e98 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -170,6 +170,8 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, const DATA_BLOB *challenge, const DATA_BLOB *lm_response, const DATA_BLOB *nt_response, + const DATA_BLOB *lm_interactive_pwd, + const DATA_BLOB *nt_interactive_pwd, const char *username, const char *client_username, const char *client_domain, @@ -183,6 +185,47 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, username)); } + if (nt_interactive_pwd && nt_interactive_pwd->length && nt_pw) { + if (nt_interactive_pwd->length != 16) { + DEBUG(3,("ntlm_password_check: Interactive logon: Invalid NT password length (%d) supplied for user %s\n", (int)nt_interactive_pwd->length, + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (memcmp(nt_interactive_pwd->data, nt_pw, 16) == 0) { + if (user_sess_key) { + *user_sess_key = data_blob(NULL, 16); + SMBsesskeygen_ntv1(nt_pw, NULL, user_sess_key->data); + } + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: Interactive logon: NT password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + } else if (lm_interactive_pwd && lm_interactive_pwd->length && lm_pw) { + if (lm_interactive_pwd->length != 16) { + DEBUG(3,("ntlm_password_check: Interactive logon: Invalid LANMAN password length (%d) supplied for user %s\n", (int)lm_interactive_pwd->length, + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (!lp_lanman_auth()) { + DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + + if (memcmp(lm_interactive_pwd->data, lm_pw, 16) == 0) { + return NT_STATUS_OK; + } else { + DEBUG(3,("ntlm_password_check: Interactive logon: LANMAN password check failed for user %s\n", + username)); + return NT_STATUS_WRONG_PASSWORD; + } + } + /* Check for cleartext netlogon. Used by Exchange 5.5. */ if (challenge->length == sizeof(zeros) && (memcmp(challenge->data, zeros, challenge->length) == 0 )) { -- cgit From 931df5850e326ad0639fe317e0ca82e6d820a68e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 5 Apr 2004 12:19:50 +0000 Subject: r39: * importing .cvsignore files * updateing WHATSNEW with vl's change (This used to be commit a7e2730ec4389e0c249886a8bfe1ee14c5abac41) --- source3/libsmb/.cvsignore | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 source3/libsmb/.cvsignore (limited to 'source3/libsmb') diff --git a/source3/libsmb/.cvsignore b/source3/libsmb/.cvsignore deleted file mode 100644 index 07da2225c7..0000000000 --- a/source3/libsmb/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -*.po -*.po32 - -- cgit From d17425ed52b086b7046708a207e849271cedc804 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Apr 2004 08:11:16 +0000 Subject: r69: Global rename of 'nt_session_key' -> 'user_session_key'. The session key could be anything, and may not be based on anything 'NT'. This is also what microsoft calls it. (This used to be commit 724e8d3f33719543146280062435c69a835c491e) --- source3/libsmb/ntlmssp.c | 20 ++++++++++---------- source3/libsmb/smbencrypt.c | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index ddc2e0325f..7f451176ec 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -500,7 +500,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB encrypted_session_key = data_blob(NULL, 0); - DATA_BLOB nt_session_key = data_blob(NULL, 0); + DATA_BLOB user_session_key = data_blob(NULL, 0); DATA_BLOB lm_session_key = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); uint32 ntlmssp_command, auth_flags; @@ -663,19 +663,19 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, /* Finally, actually ask if the password is OK */ if (!NT_STATUS_IS_OK(nt_status = ntlmssp_state->check_password(ntlmssp_state, - &nt_session_key, &lm_session_key))) { + &user_session_key, &lm_session_key))) { data_blob_free(&encrypted_session_key); return nt_status; } - dump_data_pw("NT session key:\n", nt_session_key.data, nt_session_key.length); + dump_data_pw("NT session key:\n", user_session_key.data, user_session_key.length); dump_data_pw("LM first-8:\n", lm_session_key.data, lm_session_key.length); /* Handle the different session key derivation for NTLM2 */ if (doing_ntlm2) { - if (nt_session_key.data && nt_session_key.length == 16) { + if (user_session_key.data && user_session_key.length == 16) { session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - hmac_md5(nt_session_key.data, session_nonce, + hmac_md5(user_session_key.data, session_nonce, sizeof(session_nonce), session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM2 session key.\n")); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); @@ -702,8 +702,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); session_key = data_blob(NULL, 0); } - } else if (nt_session_key.data) { - session_key = nt_session_key; + } else if (user_session_key.data) { + session_key = user_session_key; DEBUG(10,("ntlmssp_server_auth: Using unmodified nt session key.\n")); dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } else if (lm_session_key.data) { @@ -958,7 +958,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, uchar nt_hash[16]; uchar session_nonce[16]; uchar session_nonce_hash[16]; - uchar nt_session_key[16]; + uchar user_session_key[16]; E_md4hash(ntlmssp_state->password, nt_hash); lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); @@ -984,8 +984,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, nt_session_key); - hmac_md5(nt_session_key, session_nonce, sizeof(session_nonce), session_key.data); + SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key); + hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 270a659e57..3b8a375bea 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -420,7 +420,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, - DATA_BLOB *nt_session_key) + DATA_BLOB *user_session_key) { uchar nt_hash[16]; uchar ntlm_v2_hash[16]; @@ -437,12 +437,12 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password if (nt_response) { *nt_response = NTLMv2_generate_response(ntlm_v2_hash, server_chal, names_blob); - if (nt_session_key) { - *nt_session_key = data_blob(NULL, 16); + if (user_session_key) { + *user_session_key = data_blob(NULL, 16); /* The NTLMv2 calculations also provide a session key, for signing etc later */ /* use only the first 16 bytes of nt_response for session key */ - SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, nt_session_key->data); + SMBsesskeygen_ntv2(ntlm_v2_hash, nt_response->data, user_session_key->data); } } -- cgit From c4255df992d6ec6bb892bf0d39a32a00d4d570ae Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 6 Apr 2004 11:45:02 +0000 Subject: r76: Fix smbfs problem with Tree Disconnect issued before smbfs starts its work. We use cli_state.smb_rw_error to pass this specific case into cli_close_connection() from smbmount as smb_rw_error can have only selected number of states and it is ignored in cli_close_connection(). Compiled and tested by Lars Mueller from SuSE on x86, x86_64, ppc, ppc64, s390 and s390x. (This used to be commit 738666ce0a310fae14476020fd6dac027b0e3ec5) --- source3/libsmb/clientgen.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 66edc3ce38..6edc83c9d7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -374,8 +374,12 @@ void cli_close_connection(struct cli_state *cli) * can remain active on the peer end, until some (long) timeout period * later. This tree disconnect forces the peer to clean up, since the * connection will be going away. + * + * Also, do not do tree disconnect when cli->smb_rw_error is DO_NOT_DO_TDIS + * the only user for this so far is smbmount which passes opened connection + * down to kernel's smbfs module. */ - if ( cli->cnum != (uint16)-1 ) + if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) cli_tdis(cli); cli_nt_session_close(cli); -- cgit From 869348dfcbf66a88998cb80c00902848db96901f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 6 Apr 2004 16:44:24 +0000 Subject: r84: Implement --required-membership-of=, an ntlm_auth option that restricts all authentication to members of this particular group. Also implement an option to allow ntlm_auth to get 'squashed' error codes, which are safer to communicate to remote network clients. Andrew Bartlett (This used to be commit eb1c1b5eb086f49a230142ad2de45dc0e9691df3) --- source3/libsmb/nterr.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 166229ec6c..b01451ea0f 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -717,3 +717,31 @@ NTSTATUS nt_status_string_to_code(char *nt_status_str) } return NT_STATUS_UNSUCCESSFUL; } + + +/** + * Squash an NT_STATUS in line with security requirements. + * In an attempt to avoid giving the whole game away when users + * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and + * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations + * (session setups in particular). + * + * @param nt_status NTSTATUS input for squashing. + * @return the 'squashed' nt_status + **/ + +NTSTATUS nt_status_squash(NTSTATUS nt_status) +{ + if NT_STATUS_IS_OK(nt_status) { + return nt_status; + } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) { + /* Match WinXP and don't give the game away */ + return NT_STATUS_LOGON_FAILURE; + + } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) { + /* Match WinXP and don't give the game away */ + return NT_STATUS_LOGON_FAILURE; + } else { + return nt_status; + } +} -- cgit From 1db9257c953c93c3f26596a535e4f26b609e7955 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Apr 2004 23:01:09 +0000 Subject: r96: Stupid f&%'n UNIX extensions.... SETPATHINFO normally takes as it's param entry the filename to be acted upon.... Unless it's UNIX extensions create hardlink, or UNIX extensions create symlink. Then it's param -> newfile name data -> oldfile name. This caused me to stuff them up in 3.0.2 (and the client commands link and symlink). Fixed them, everything is now called oldname and newname - thus specifying which name should already exist (hint - the old one...) and which will be created (newname). Jeremy. (This used to be commit 21cc6ab7e8a41160a3e2970623ade7445b5214d6) --- source3/libsmb/clifile.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index bf7923ec78..398c7cc4f0 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -25,9 +25,10 @@ /**************************************************************************** Hard/Symlink a file (UNIX extensions). + Creates new name (sym)linked to oldname. ****************************************************************************/ -static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, const char *fname_dst, BOOL hard_link) +static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, BOOL hard_link) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -36,18 +37,18 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *fname_src, cons pstring data; char *rparam=NULL, *rdata=NULL; char *p; - size_t srclen = 2*(strlen(fname_src)+1); - size_t destlen = 2*(strlen(fname_dst) + 1); + size_t oldlen = 2*(strlen(oldname)+1); + size_t newlen = 2*(strlen(newname)+1); memset(param, 0, sizeof(param)); SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK); p = ¶m[6]; - p += clistr_push(cli, p, fname_src, MIN(srclen, sizeof(param)-6), STR_TERMINATE); + p += clistr_push(cli, p, newname, MIN(newlen, sizeof(param)-6), STR_TERMINATE); param_len = PTR_DIFF(p, param); p = data; - p += clistr_push(cli, p, fname_dst, MIN(destlen,sizeof(data)), STR_TERMINATE); + p += clistr_push(cli, p, oldname, MIN(oldlen,sizeof(data)), STR_TERMINATE); data_len = PTR_DIFF(p, data); if (!cli_send_trans(cli, SMBtrans2, @@ -105,18 +106,18 @@ uint32 unix_perms_to_wire(mode_t perms) Symlink a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_symlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +BOOL cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname) { - return cli_link_internal(cli, fname_src, fname_dst, False); + return cli_link_internal(cli, oldname, newname, False); } /**************************************************************************** Hard a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +BOOL cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname) { - return cli_link_internal(cli, fname_src, fname_dst, True); + return cli_link_internal(cli, oldname, newname, True); } /**************************************************************************** -- cgit From 7af3777ab32ee220700ed3367d07ca18b2bbdd47 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 7 Apr 2004 12:43:44 +0000 Subject: r116: volker's patch for local group and group nesting (This used to be commit b393469d9581f20e4d4c52633b952ee984cca36f) --- source3/libsmb/libsmbclient.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 68bb6661eb..ebbf28a12d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -246,7 +246,7 @@ smbc_parse_path(SMBCCTX *context, p += 2; /* Skip the double slash */ /* See if any options were specified */ - if (q = strrchr(p, '?')) { + if ( (q = strrchr(p, '?')) != NULL ) { /* There are options. Null terminate here and point to them */ *q++ = '\0'; @@ -537,9 +537,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, SMBCSRV *srv=NULL; struct cli_state c; struct nmb_name called, calling; - char *p; const char *server_n = server; - fstring group; pstring ipenv; struct in_addr ip; int tried_reverse = 0; -- cgit From b81b4711f764d10c19b6a01aadcf6e945cb0c450 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 10 Apr 2004 19:24:31 +0000 Subject: r148: Ensure we do not dereference a null pointer when we return the user session key. (This used to be commit b09d333aed00a7ea599f45105e913d3a3ea25b31) --- source3/libsmb/ntlm_check.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index a7764f9e98..1d02b03e0c 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -330,7 +330,9 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, uint8 first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); - *lm_sess_key = data_blob(first_8_lm_hash, 16); + if (lm_sess_key) { + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } } return NT_STATUS_OK; } else { @@ -371,8 +373,13 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, uint8 first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(first_8_lm_hash, 16); + if (user_sess_key) { + *user_sess_key = data_blob(first_8_lm_hash, 16); + } + + if (lm_sess_key) { + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } return NT_STATUS_OK; } } @@ -431,8 +438,13 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, uint8 first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); - *user_sess_key = data_blob(first_8_lm_hash, 16); - *lm_sess_key = data_blob(first_8_lm_hash, 16); + if (user_sess_key) { + *user_sess_key = data_blob(first_8_lm_hash, 16); + } + + if (lm_sess_key) { + *lm_sess_key = data_blob(first_8_lm_hash, 16); + } } return NT_STATUS_OK; } -- cgit From 85a307bb3ea102be24fb1f0ecdc27c9eb08c9ce9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 12 Apr 2004 11:18:32 +0000 Subject: r176: Improve our fallback code for password changes - this would be better with more correct NTLMSSP support in client and server, but it will do for now. Also implement LANMAN password only in the classical session setup code, but #ifdef'ed out. In Samba4, I'll make this run-time so we can torture it. Lanman passwords over 14 dos characters long could be considered 'invalid' (they are truncated) - so SMBencrypt now returns 'False' if it generates such a password. Andrew Bartlett (This used to be commit 565305f7bb30c08120c3def5367adfd6f5dd84df) --- source3/libsmb/cliconnect.c | 63 +++++++++++++++++++++++----------- source3/libsmb/passchange.c | 83 +++++++++++++++++++++++++++++++++------------ source3/libsmb/smbencrypt.c | 12 +++++-- 3 files changed, 115 insertions(+), 43 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cdf58c5b91..06c9b5ea91 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -40,6 +40,18 @@ static const struct { {-1,NULL} }; +/** + * Set the user session key for a connection + * @param cli The cli structure to add it too + * @param session_key The session key used. (A copy of this is taken for the cli struct) + * + */ + +static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) +{ + cli->user_session_key = data_blob(session_key.data, session_key.length); +} + /**************************************************************************** Do an old lanman2 style session setup. ****************************************************************************/ @@ -47,6 +59,8 @@ static const struct { static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, const char *pass, size_t passlen, const char *workgroup) { + DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB lm_response = data_blob(NULL, 0); fstring pword; char *p; @@ -66,14 +80,15 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ - passlen = 24; - SMBencrypt(pass,cli->secblob.data,(uchar *)pword); + lm_response = data_blob(NULL, 24); + SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data); } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ - memcpy(pword, pass, passlen); + lm_response = data_blob(pass, passlen); } else if (passlen > 0) { /* Plaintext mode needed, assume plaintext supplied. */ passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); + lm_response = data_blob(pass, passlen); } /* send a session setup command */ @@ -87,10 +102,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, SSVAL(cli->outbuf,smb_vwv3,2); SSVAL(cli->outbuf,smb_vwv4,1); SIVAL(cli->outbuf,smb_vwv5,cli->sesskey); - SSVAL(cli->outbuf,smb_vwv7,passlen); + SSVAL(cli->outbuf,smb_vwv7,lm_response.length); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); + memcpy(p,lm_response.data,lm_response.length); p += passlen; p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); @@ -111,6 +126,11 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, cli->vuid = SVAL(cli->inbuf,smb_uid); fstrcpy(cli->user_name, user); + if (session_key.data) { + /* Have plaintext orginal */ + cli_set_session_key(cli, session_key); + } + return True; } @@ -248,18 +268,6 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, return True; } -/** - * Set the user session key for a connection - * @param cli The cli structure to add it too - * @param session_key The session key used. (A copy of this is taken for the cli struct) - * - */ - -static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) -{ - cli->user_session_key = data_blob(session_key.data, session_key.length); -} - /**************************************************************************** do a NT1 NTLM/LM encrypted session setup - for when extended security is not negotiated. @@ -310,22 +318,39 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, uchar nt_hash[16]; E_md4hash(pass, nt_hash); +#ifdef LANMAN_ONLY + nt_response = data_blob(NULL, 0); +#else nt_response = data_blob(NULL, 24); SMBNTencrypt(pass,cli->secblob.data,nt_response.data); - +#endif /* non encrypted password supplied. Ignore ntpass. */ if (lp_client_lanman_auth()) { lm_response = data_blob(NULL, 24); - SMBencrypt(pass,cli->secblob.data, lm_response.data); + if (!SMBencrypt(pass,cli->secblob.data, lm_response.data)) { + /* Oops, the LM response is invalid, just put + the NT response there instead */ + data_blob_free(&lm_response); + lm_response = data_blob(nt_response.data, nt_response.length); + } } else { /* LM disabled, place NT# in LM field instead */ lm_response = data_blob(nt_response.data, nt_response.length); } session_key = data_blob(NULL, 16); +#ifdef LANMAN_ONLY + E_deshash(pass, session_key.data); + memset(&session_key.data[8], '\0', 8); +#else SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); +#endif } +#ifdef LANMAN_ONLY + cli_simple_set_signing(cli, session_key, lm_response); +#else cli_simple_set_signing(cli, session_key, nt_response); +#endif } else { /* pre-encrypted password supplied. Only used for security=server, can't do diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index dc0cbbcb7c..9f46c131fe 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -121,32 +121,73 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, } } - if (!NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name, - new_passwd, old_passwd))) { - - if (NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) - || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)) { - /* try the old Lanman method */ - if (lp_client_lanman_auth()) { - if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return False; - } - } else { - slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", - remote_machine); + if (NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name, + new_passwd, old_passwd))) { + /* Great - it all worked! */ + cli_shutdown(&cli); + return True; + + } else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) + || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { + /* it failed, but for reasons such as wrong password, too short etc ... */ + + slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + remote_machine, get_friendly_nt_error_msg(result)); + cli_shutdown(&cli); + return False; + } + + /* OK, that failed, so try again... */ + cli_nt_session_close(&cli); + + /* Try anonymous NTLMSSP... */ + init_creds(&creds, "", "", NULL); + cli_init_creds(&cli, &creds); + + result = NT_STATUS_UNSUCCESSFUL; + + /* OK, this is ugly, but... */ + if ( cli_nt_session_open( &cli, PI_SAMR ) + && NT_STATUS_IS_OK(result + = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name, + new_passwd, old_passwd))) { + /* Great - it all worked! */ + cli_shutdown(&cli); + return True; + + } else { + if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) + || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { + /* it failed, but again it was due to things like new password too short */ + + slprintf(err_str, err_str_len-1, + "machine %s rejected the (anonymous) password change: Error was : %s.\n", + remote_machine, get_friendly_nt_error_msg(result)); + cli_shutdown(&cli); + return False; + } + + /* We have failed to change the user's password, and we think the server + just might not support SAMR password changes, so fall back */ + + if (lp_client_lanman_auth()) { + if (cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + /* SAMR failed, but the old LanMan protocol worked! */ + cli_shutdown(&cli); - return False; + return True; } + slprintf(err_str, err_str_len-1, + "machine %s rejected the password change: Error was : %s.\n", + remote_machine, cli_errstr(&cli) ); + cli_shutdown(&cli); + return False; } else { - slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, get_friendly_nt_error_msg(result)); + slprintf(err_str, err_str_len-1, + "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", + remote_machine); cli_shutdown(&cli); return False; } } - cli_shutdown(&cli); - return True; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 3b8a375bea..44f7428086 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -28,13 +28,17 @@ /* This implements the X/Open SMB password encryption It takes a password ('unix' string), a 8 byte "crypt key" - and puts 24 bytes of encrypted password into p24 */ -void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) + and puts 24 bytes of encrypted password into p24 + + Returns False if password must have been truncated to create LM hash +*/ +BOOL SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) { + BOOL ret; uchar p21[21]; memset(p21,'\0',21); - E_deshash(passwd, p21); + ret = E_deshash(passwd, p21); SMBOWFencrypt(p21, c8, p24); @@ -44,6 +48,8 @@ void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) dump_data(100, (const char *)c8, 8); dump_data(100, (char *)p24, 24); #endif + + return ret; } /** -- cgit From 0859a89166089b505e447034e119a9bb0eba7ba8 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 14 Apr 2004 17:34:48 +0000 Subject: r219: Obtain new tickets if current ones are expired. Next part of fix for bug 1208. Based on a fix from Guether Deschener. Outstanding pieces: - Heimdal FILE-based ccaches don't actually remove creds properly, so we need to code a check for this - what if ticket expires between our check and when we use it? Guenther has coded up fixes for these parts, but I still need to review them, as I'm not totally comfortable with the solutions. (This used to be commit ef008b9710e682f87f0bbf526d30eb5114264233) --- source3/libsmb/clikrb5.c | 48 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 36 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 15b244a83d..e957cbc91f 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -249,6 +249,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_creds * credsp; krb5_creds creds; krb5_data in_data; + BOOL have_creds = False; retval = krb5_parse_name(context, principal, &server); if (retval) { @@ -270,20 +271,43 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, goto cleanup_creds; } - if ((retval = krb5_get_credentials(context, 0, - ccache, &creds, &credsp))) { - DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", - principal, error_message(retval))); - goto cleanup_creds; + while(!have_creds) { + if ((retval = krb5_get_credentials(context, 0, ccache, + &creds, &credsp))) { + DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", + principal, error_message(retval))); + goto cleanup_creds; + } + + /* cope with ticket being in the future due to clock skew */ + if ((unsigned)credsp->times.starttime > time(NULL)) { + time_t t = time(NULL); + int time_offset =(unsigned)credsp->times.starttime-t; + DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + krb5_set_real_time(context, t + time_offset + 1, 0); + } + + /* cope with expired tickets */ + if ((unsigned)credsp->times.endtime < time(NULL)) { + DEBUG(3,("Ticket (%s) in ccache (%s) has expired (%s - %d). Obtaining new ticket.\n", + principal, krb5_cc_default_name(context), + http_timestring( + (unsigned)credsp->times.endtime), + (unsigned)credsp->times.endtime)); + if ((retval = krb5_cc_remove_cred(context, ccache, 0, + credsp))) { + DEBUG(1,("krb5_cc_remove_cred failed for %s (%s)\n", + principal, error_message(retval))); + } + } else { + have_creds = True; + } } - /* cope with the ticket being in the future due to clock skew */ - if ((unsigned)credsp->times.starttime > time(NULL)) { - time_t t = time(NULL); - int time_offset = (unsigned)credsp->times.starttime - t; - DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); - krb5_set_real_time(context, t + time_offset + 1, 0); - } + DEBUG(10,("Ticket (%s) in ccache (%s) is valid until: (%s - %d)\n", + principal, krb5_cc_default_name(context), + http_timestring((unsigned)credsp->times.endtime), + (unsigned)credsp->times.endtime)); in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, -- cgit From 3c62df47809865daf80c215135d46c722992134b Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 14 Apr 2004 19:06:45 +0000 Subject: r221: Remainder of bug 1208. We do not remove creds from _any_ FILE ccache, because not only does it not work on Heimdal, but also since ccaches created within samba are memory-based, so we shouldn't touch a FILE-based one (it was probably created via kinit or similar). (This used to be commit 5971b0980ca8abae2208f22485c5af4c0dde0459) --- source3/libsmb/clikrb5.c | 57 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 40 insertions(+), 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e957cbc91f..81797a7bfc 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -234,6 +234,42 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, } #endif +static BOOL ads_cleanup_expired_creds(krb5_context context, + krb5_ccache ccache, + krb5_creds *credsp) +{ + krb5_error_code retval; + + DEBUG(3, ("Ticket in ccache[%s] expiration %s\n", + krb5_cc_default_name(context), + http_timestring(credsp->times.endtime))); + + /* we will probably need new tickets if the current ones + will expire within 10 seconds. + */ + if (credsp->times.endtime >= (time(NULL) + 10)) + return False; + + /* heimdal won't remove creds from a file ccache, and + perhaps we shouldn't anyway, since internally we + use memory ccaches, and a FILE one probably means that + we're using creds obtained outside of our exectuable + */ + if (StrCaseCmp(krb5_cc_get_type(context, ccache), "FILE") == 0) { + DEBUG(5, ("We do not remove creds from a FILE ccache\n")); + return False; + } + + retval = krb5_cc_remove_cred(context, ccache, 0, credsp); + if (retval) { + DEBUG(1, ("krb5_cc_remove_cred failed, err %s\n", + error_message(retval))); + /* If we have an error in this, we want to display it, + but continue as though we deleted it */ + } + return True; +} + /* we can't use krb5_mk_req because w2k wants the service to be in a particular format */ @@ -249,7 +285,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_creds * credsp; krb5_creds creds; krb5_data in_data; - BOOL have_creds = False; + BOOL creds_ready = False; retval = krb5_parse_name(context, principal, &server); if (retval) { @@ -271,7 +307,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, goto cleanup_creds; } - while(!have_creds) { + while(!creds_ready) { if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", @@ -287,21 +323,8 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_set_real_time(context, t + time_offset + 1, 0); } - /* cope with expired tickets */ - if ((unsigned)credsp->times.endtime < time(NULL)) { - DEBUG(3,("Ticket (%s) in ccache (%s) has expired (%s - %d). Obtaining new ticket.\n", - principal, krb5_cc_default_name(context), - http_timestring( - (unsigned)credsp->times.endtime), - (unsigned)credsp->times.endtime)); - if ((retval = krb5_cc_remove_cred(context, ccache, 0, - credsp))) { - DEBUG(1,("krb5_cc_remove_cred failed for %s (%s)\n", - principal, error_message(retval))); - } - } else { - have_creds = True; - } + if (!ads_cleanup_expired_creds(context, ccache, credsp)) + creds_ready = True; } DEBUG(10,("Ticket (%s) in ccache (%s) is valid until: (%s - %d)\n", -- cgit From 0374be5d931903f1040fd4e759e6b1d681be2047 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 16 Apr 2004 03:57:30 +0000 Subject: r248: Add support for printing out the MAC address on nmblookup. (This used to be commit bf9f02be5fc1d09c8c08c78c3f2df23b2099ba4f) --- source3/libsmb/namequery.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index b9bc4e1166..2bb7359e74 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -45,7 +45,7 @@ static int generate_trn_id(void) Parse a node status response into an array of structures. ****************************************************************************/ -static struct node_status *parse_node_status(char *p, int *num_names) +static struct node_status *parse_node_status(char *p, int *num_names, struct node_status_extra *extra) { struct node_status *ret; int i; @@ -68,6 +68,12 @@ static struct node_status *parse_node_status(char *p, int *num_names) DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, ret[i].type, ret[i].flags)); } + /* + * Also, pick up the MAC address ... + */ + if (extra) { + memcpy(&extra->mac_addr, p, 6); /* Fill in the mac addr */ + } return ret; } @@ -78,7 +84,8 @@ static struct node_status *parse_node_status(char *p, int *num_names) **************************************************************************/ struct node_status *node_status_query(int fd,struct nmb_name *name, - struct in_addr to_ip, int *num_names) + struct in_addr to_ip, int *num_names, + struct node_status_extra *extra) { BOOL found=False; int retries = 2; @@ -149,7 +156,7 @@ struct node_status *node_status_query(int fd,struct nmb_name *name, continue; } - ret = parse_node_status(&nmb2->answers->rdata[0], num_names); + ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra); free_packet(p2); return ret; } @@ -190,7 +197,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t /* W2K PDC's seem not to respond to '*'#0. JRA */ make_nmb_name(&nname, q_name, q_type); - status = node_status_query(sock, &nname, to_ip, &count); + status = node_status_query(sock, &nname, to_ip, &count, NULL); close(sock); if (!status) goto done; -- cgit From 042209871c50e346fdcb9fd3cbeb30c5bf942792 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 20 Apr 2004 16:33:30 +0000 Subject: r296: patch from j.lu -- don't force an upper case domain name in the ntlmssp code (This used to be commit a2e93dda24d079693a220b4551d264cba4c2bc82) --- source3/libsmb/ntlmssp.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 7f451176ec..66d48afc46 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -168,9 +168,7 @@ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password */ NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) { - /* Possibly make our NTLMv2 client more robust by always having - an uppercase domain */ - ntlmssp_state->domain = talloc_strdup_upper(ntlmssp_state->mem_ctx, domain); + ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); if (!ntlmssp_state->domain) { return NT_STATUS_NO_MEMORY; } -- cgit From 0922c254c6c8c941ebc7321b1c7114c1a5abd880 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 29 Apr 2004 22:41:47 +0000 Subject: r415: Return NT_STATUS_ACCESS_DENIED not some LOCK message ... (This used to be commit 164ff9a192e82be6eaef7b6e7c03e5dc7203f3de) --- source3/libsmb/errormap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index aeb68b6596..77c71fce13 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -627,7 +627,7 @@ static const struct { {ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED}, {ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, {ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES}, - {ERRDOS, ERRbadaccess, NT_STATUS_INVALID_LOCK_SEQUENCE}, + {ERRDOS, ERRbadaccess, NT_STATUS_ACCESS_DENIED}, {ERRDOS, ERRbaddata, NT_STATUS_DATA_ERROR}, {ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, {ERRDOS, ERRremcd, NT_STATUS_DIRECTORY_NOT_EMPTY}, -- cgit From 5c2cd8aa38771cba24ce3872b35adefbd9050982 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 2 May 2004 10:42:08 +0000 Subject: r446: Close the open NT pipes before the tdis. Volker (This used to be commit ef80490baf9ce38b505b4b322051ae6e3332d662) --- source3/libsmb/clientgen.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6edc83c9d7..b75d6be0a6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -367,6 +367,9 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) void cli_close_connection(struct cli_state *cli) { + cli_nt_session_close(cli); + cli_nt_netlogon_netsec_session_close(cli); + /* * tell our peer to free his resources. Wihtout this, when an * application attempts to do a graceful shutdown and calls @@ -382,9 +385,6 @@ void cli_close_connection(struct cli_state *cli) if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) cli_tdis(cli); - cli_nt_session_close(cli); - cli_nt_netlogon_netsec_session_close(cli); - SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); -- cgit From 04e8a07bb5545e367a7b5ceed1cd0e25be37f921 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 5 May 2004 14:57:51 +0000 Subject: r494: patch from Stephan Kulow to fix a cut-n-paste error in strlen which caused Konqueror to crash (This used to be commit 5150b62420f6634391196501d0279ef039a7bcc8) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ebbf28a12d..50af223726 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1807,7 +1807,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) server, sizeof(server), share, sizeof(share), path, sizeof(path), - user, sizeof(path), + user, sizeof(user), password, sizeof(password), options, sizeof(options))) { DEBUG(4, ("no valid path\n")); -- cgit From ff343c516c02d4764935d0d38c8c87f8fc967780 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 May 2004 17:39:36 +0000 Subject: r523: Fix from kawasa_r@itg.hitachi.co.jp to initialise blob structs. Jeremy. (This used to be commit 6d0bdccaa67a2965fde5f9dff6cdc4059b8fbc90) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 06c9b5ea91..e345dbe479 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -580,9 +580,9 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use NTSTATUS nt_status; int turn = 1; DATA_BLOB msg1; - DATA_BLOB blob; + DATA_BLOB blob = data_blob(NULL, 0); DATA_BLOB blob_in = data_blob(NULL, 0); - DATA_BLOB blob_out; + DATA_BLOB blob_out = data_blob(NULL, 0); cli_temp_set_signing(cli); -- cgit From 309bbba38b82013f0a4e7e638d6ff3235f9966aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 May 2004 17:48:45 +0000 Subject: r525: More memory leak fixes from kawasa_r@itg.hitachi.co.jp in error code paths. Jeremy. (This used to be commit 88a97beac4f445f2a472167b3e5c0e8e1d019d17) --- source3/libsmb/cliconnect.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e345dbe479..afbd2079ea 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -421,9 +421,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, end: data_blob_free(&lm_response); data_blob_free(&nt_response); - - if (!ret) - data_blob_free(&session_key); + data_blob_free(&session_key); return ret; } @@ -558,6 +556,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * cli_set_session_key(cli, session_key_krb5); data_blob_free(&negTokenTarg); + data_blob_free(&session_key_krb5); if (cli_is_error(cli)) { if (NT_STATUS_IS_OK(cli_nt_error(cli))) { @@ -744,6 +743,8 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, * and do not store results */ if (got_kerberos_mechanism && cli->use_kerberos) { + ADS_STATUS rc; + if (pass && *pass) { int ret; @@ -751,16 +752,19 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL); if (ret){ + SAFE_FREE(principal); DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); return ADS_ERROR_KRB5(ret); } } - return cli_session_setup_kerberos(cli, principal, domain); + rc = cli_session_setup_kerberos(cli, principal, domain); + SAFE_FREE(principal); + return rc; } #endif - free(principal); + SAFE_FREE(principal); ntlmssp: -- cgit From 33ebb4bee57603288c37aa7f02a923b3d2804382 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 May 2004 18:23:01 +0000 Subject: r527: More memory leak fixes in error paths from kawasa_r@itg.hitachi.co.jp. Jeremy. (This used to be commit b2ba4d5c1be6089e3818a20c68e3894432b53d87) --- source3/libsmb/clikrb5.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 81797a7bfc..e688ad608c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -359,8 +359,8 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, { krb5_error_code retval; krb5_data packet; - krb5_ccache ccdef; krb5_context context; + krb5_ccache ccdef = NULL; krb5_auth_context auth_context = NULL; krb5_enctype enc_types[] = { #ifdef ENCTYPE_ARCFOUR_HMAC @@ -411,8 +411,14 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, #endif failed: - if ( context ) + + if ( context ) { + if (ccdef) + krb5_cc_close(context, ccdef); + if (auth_context) + krb5_auth_con_free(context, auth_context); krb5_free_context(context); + } return retval; } -- cgit From 675ecdd5babbcf2d87e807e21375a4c0d81dfa14 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 May 2004 23:16:52 +0000 Subject: r539: Mem leak fixes from kawasa_r@itg.hitachi.co.jp Jeremy. (This used to be commit 8fe47b0bf27a8ae690ab0fcff377c8fc12919f43) --- source3/libsmb/namequery_dc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 31d759e0d2..0c9f19313c 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -49,8 +49,10 @@ static BOOL ads_dc_name(const char *domain, const char *realm, struct in_addr *d ads_connect(ads); #endif - if (!ads->config.realm) + if (!ads->config.realm) { + ads_destroy(&ads); return False; + } fstrcpy(srv_name, ads->config.ldap_server_name); strupper_m(srv_name); -- cgit From 63378d6f0efa4612da1aecb5dee14992ac069d0f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 May 2004 02:48:03 +0000 Subject: r541: fixing segfault in winbindd caused -r527 -- looks like a bug in heimdal; also initialize some pointers (This used to be commit be74e88d9a4b74fcaf25b0816e3fa8a487c91ab5) --- source3/libsmb/clikrb5.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e688ad608c..9027f192ef 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -359,7 +359,7 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, { krb5_error_code retval; krb5_data packet; - krb5_context context; + krb5_context context = NULL; krb5_ccache ccdef = NULL; krb5_auth_context auth_context = NULL; krb5_enctype enc_types[] = { @@ -413,8 +413,11 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, failed: if ( context ) { +#if 0 /* JERRY -- disabled since it causes heimdal 0.6.1rc3 to die + SuSE 9.1 Pro */ if (ccdef) krb5_cc_close(context, ccdef); +#endif if (auth_context) krb5_auth_con_free(context, auth_context); krb5_free_context(context); -- cgit From 22cf8924a9b799bc7c833ac8a6caabbee381d6cb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 7 May 2004 09:50:43 +0000 Subject: r547: Add entry for NT_STATUS_DUPLICATE_NAME in the ntstatus to unix error mapping table (This used to be commit 31c21d520d030e27e4adc6075a50026724b87173) --- source3/libsmb/clierror.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index c27e1955e2..ec0ca53a85 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -319,6 +319,9 @@ static struct { {NT_STATUS_PORT_UNREACHABLE, EHOSTUNREACH}, {NT_STATUS_IO_TIMEOUT, ETIMEDOUT}, {NT_STATUS_RETRY, EAGAIN}, +#ifdef ENOTUNIQ + {NT_STATUS_DUPLICATE_NAME, ENOTUNIQ}, +#endif #ifdef ECOMM {NT_STATUS_NET_WRITE_FAULT, ECOMM}, #endif -- cgit From 3bbf2f1e0a9078b6888866979642962c8b8a90af Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 7 May 2004 15:59:13 +0000 Subject: r557: another patch from Stephan Kulow -- check cli * before dereferencing it (This used to be commit c385fb467fc2a669d54b9a2faddbf66f9e4699c6) --- source3/libsmb/libsmbclient.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 50af223726..2ef054473b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1991,6 +1991,12 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info); + + /* cli == NULL is the master browser refused to talk or + could not be found */ + if ( !cli ) + continue; + fstrcpy(server, cli->desthost); cli_shutdown(cli); -- cgit From a6e6cd569109f2176a6ef0450f681674a897f58a Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 7 May 2004 16:46:37 +0000 Subject: r559: Some fixes from coolo ... (This used to be commit d80e90d7c19fbcd2f7e998918b4fc6d9310081a3) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2ef054473b..f08d9440f9 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1902,8 +1902,8 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) * the first choice and fall back to MSBROWSE if the * wildcard query fails. */ - if (!name_status_find("*", 0, 0x1d, server_ip, server) && - !name_status_find(MSBROWSE, 1, 0x1d, server_ip, server)) { + if (!name_status_find("*", 0, 0x20, server_ip, server) && + !name_status_find(MSBROWSE, 1, 0x1b, server_ip, server)) { errno = ENOENT; return NULL; } -- cgit From 6a110a5d2bdbdea201dc3165586e6dff5d09ce90 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sat, 8 May 2004 20:15:52 +0000 Subject: r588: Some fixes from coolo ... I think that the ECONNREFUSED should probably be ENOENT. (This used to be commit faa8cc18df51c4406815b68caba5ed5b8d43ba18) --- source3/libsmb/clirap.c | 15 ++++++++++++++- source3/libsmb/libsmbclient.c | 5 +---- 2 files changed, 15 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index f8204e05d6..8cc5d8bf90 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -217,6 +217,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, int uLevel = 1; int count = -1; + errno = 0; /* reset */ + /* send a SMBtrans command with api NetServerEnum */ p = param; SSVAL(p,0,0x68); /* api number */ @@ -269,7 +271,18 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SAFE_FREE(rparam); SAFE_FREE(rdata); - + + if (count < 0) { + errno = cli_errno(cli); + } else { + if (!count) { + /* this is a very special case, when the domain master for the + work group isn't part of the work group itself, there is something + wild going on */ + errno = ENOENT; + } + } + return(count > 0); } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f08d9440f9..417b5ba8d4 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1939,7 +1939,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SAFE_FREE(dir->fname); SAFE_FREE(dir); } - errno = cli_errno(&srv->cli); return NULL; @@ -2032,7 +2031,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SAFE_FREE(dir->fname); SAFE_FREE(dir); } - errno = cli_errno(&srv->cli); return NULL; @@ -2106,7 +2104,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SAFE_FREE(dir->fname); SAFE_FREE(dir); } - errno = cli_errno(&srv->cli); return NULL; } @@ -2150,7 +2147,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } else { - errno = ENODEV; /* Neither the workgroup nor server exists */ + errno = ECONNREFUSED; /* Neither the workgroup nor server exists */ if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); -- cgit From 80728c70456dd30c86bcfed460212dc95d7fb02d Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 9 May 2004 17:29:09 +0000 Subject: r616: Bug #1333. Make sure we return an error code when things go wrong. (This used to be commit 21cdb45b54662c7835aea1d16fdd5902cf7a7496) --- source3/libsmb/libsmbclient.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 417b5ba8d4..949c5ffab6 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -680,12 +680,18 @@ SMBCSRV *smbc_server(SMBCCTX *context, srv->cli = c; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); - /* now add it to the cache (internal or external) */ + /* now add it to the cache (internal or external) */ + /* Let the cache function set errno if it wants to */ + errno = 0; if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { + int saved_errno = errno; DEBUG(3, (" Failed to add server to cache\n")); + saved_errno = errno; + if (errno == 0) { + errno = ENOMEM; + } goto failed; } - DEBUG(2, ("Server connect ok: //%s/%s: %p\n", server, share, srv)); -- cgit From 4b72f4841ae89e1a7525f4a78fab483d484b9d57 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Sun, 9 May 2004 22:39:39 +0000 Subject: r618: Bug #1333. Fix a problem pointed out by coolo where I was trying to ensure that the errno is not trashed by a DEBUG statement, but screwed up. (This used to be commit e642f3e7b7a5fdbb5d12136c909e9c57e7cf1985) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 949c5ffab6..e44bdea2d3 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -686,7 +686,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { int saved_errno = errno; DEBUG(3, (" Failed to add server to cache\n")); - saved_errno = errno; + errno = saved_errno; if (errno == 0) { errno = ENOMEM; } -- cgit From bb8a4a7991a04e16765f68e5cb770617d086e3d8 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 18 May 2004 18:13:19 +0000 Subject: r775: merge trunk 774 to samba 3_0 - fix bad compare in for loop (This used to be commit 3cb8f1d53583dac0b77495cbcd017c366af59891) --- source3/libsmb/nmblib.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 3c25eba744..51a5671144 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1143,8 +1143,6 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } -#define TRUNCATE_NETBIOS_NAME 1 - /******************************************************************* Convert, possibly using a stupid microsoft-ism which has destroyed the transport independence of netbios (for CIFS vendors that usually @@ -1164,19 +1162,17 @@ char *dns_to_netbios_name(const char *dns_name) StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); netbios_name[15] = 0; -#ifdef TRUNCATE_NETBIOS_NAME /* ok. this is because of a stupid microsoft-ism. if the called host name contains a '.', microsoft clients expect you to truncate the netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 0; i >= 15; i--) { + for (i = 0; i < 15; i--) { if (netbios_name[i] == '.') { netbios_name[i] = 0; break; } } -#endif /* TRUNCATE_NETBIOS_NAME */ return netbios_name; } -- cgit From 84cea46162d6328c2e3bc0166f5b27a0fa01b3f9 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 18 May 2004 20:48:14 +0000 Subject: r776: I should have just cut and pasted from my build area and I would have gotten this right :-) (This used to be commit 548070274efa12f8c9a4404145d8a2a8c85387b3) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 51a5671144..d883c5308d 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1167,7 +1167,7 @@ char *dns_to_netbios_name(const char *dns_name) netbios name up to and including the '.' this even applies, by mistake, to workgroup (domain) names, which is _really_ daft. */ - for (i = 0; i < 15; i--) { + for (i = 0; i < 15; i++) { if (netbios_name[i] == '.') { netbios_name[i] = 0; break; -- cgit From 8c0db1bbc469932694ed877eebecffa3d1948abd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 19 May 2004 21:49:58 +0000 Subject: r786: Memory leak fixes in (mostly) error code paths from kawasa_r@itg.hitachi.co.jp. A couple of mem leak fixes in mainline code paths though :-). Jeremy. (This used to be commit 4695cc95fe576b6da0d0cb0686f208fc306b2646) --- source3/libsmb/trustdom_cache.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 0128d08006..e63acd18c4 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -114,12 +114,14 @@ BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, { char *key, *alt_key; fstring sid_string; + BOOL ret; /* * we use gecache call to avoid annoying debug messages * about initialised trustdom */ - if (!gencache_init()) return False; + if (!gencache_init()) + return False; DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n", sid_string_static(sid), name)); @@ -134,11 +136,18 @@ BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, * try to put the names in the cache */ if (alt_key) { - return (gencache_set(alt_key, sid_string, timeout) - && gencache_set(key, sid_string, timeout)); + ret = gencache_set(alt_key, sid_string, timeout); + if ( ret ) { + ret = gencache_set(key, sid_string, timeout); + } + SAFE_FREE(alt_key); + SAFE_FREE(key); + return ret; } - - return gencache_set(key, sid_string, timeout); + + ret = gencache_set(key, sid_string, timeout); + SAFE_FREE(key); + return ret; } @@ -155,22 +164,26 @@ BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) { - char *key, *value; + char *key = NULL, *value = NULL; time_t timeout; /* init the cache */ - if (!gencache_init()) return False; + if (!gencache_init()) + return False; /* exit now if null pointers were passed as they're required further */ - if (!sid) return False; + if (!sid) + return False; /* prepare a key and get the value */ key = trustdom_cache_key(name); - if (!key) return False; + if (!key) + return False; if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for trusted domain %s found.\n", name)); SAFE_FREE(key); + SAFE_FREE(value); return False; } else { SAFE_FREE(key); @@ -180,9 +193,11 @@ BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) /* convert ip string representation into in_addr structure */ if(! string_to_sid(sid, value)) { sid = NULL; + SAFE_FREE(value); return False; } + SAFE_FREE(value); return True; } @@ -193,7 +208,7 @@ BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) uint32 trustdom_cache_fetch_timestamp( void ) { - char *value; + char *value = NULL; time_t timeout; uint32 timestamp; @@ -203,11 +218,13 @@ uint32 trustdom_cache_fetch_timestamp( void ) if (!gencache_get(TDOMTSKEY, &value, &timeout)) { DEBUG(5, ("no timestamp for trusted domain cache located.\n")); + SAFE_FREE(value); return 0; } timestamp = atoi(value); + SAFE_FREE(value); return timestamp; } -- cgit From fddef6fc201ed127eaac737e725d1c2dd8c6926e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jun 2004 17:54:23 +0000 Subject: r1115: Fix for #1427. Catch bad path errors at the right point. Ensure all our pathname parsing is consistent. Jeremy. (This used to be commit 5e8237e306f0bb0e492f10fb6487938132899384) --- source3/libsmb/smb_signing.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 7130453c0c..63838e6933 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -748,11 +748,11 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO if (!good) { - DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", (unsigned int)saved_seq)); dump_data(5, (const char *)calc_md5_mac, 8); - DEBUG(5, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", (unsigned int)saved_seq)); dump_data(5, (const char *)server_sent_mac, 8); -- cgit From 58686e844f30e0c1712ec87d7f1b3e743d09be96 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jun 2004 23:54:52 +0000 Subject: r1117: Doh ! Remember to turn off signing when sending a "break to level II" oplock message, or we mess up the signing sequence number.... Also improve sign error reporting. Also when deferring an open that had been deferred due to an oplock break, don't re-add the mid to the pending sign queue or we increment the sequence number twice and mess up signing again... I can now bounce between 2 WinXP/Win2003 boxes opening Excel spreadsheets with signing turned on and get correct "file in use" messages. Jeremy. (This used to be commit 1745ce4e2cf7fcb4c27c077973258d157cd241b1) --- source3/libsmb/smb_signing.c | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 63838e6933..868c991c16 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -42,11 +42,18 @@ struct smb_basic_signing_context { struct outstanding_packet_lookup *outstanding_packet_list; }; -static void store_sequence_for_reply(struct outstanding_packet_lookup **list, +static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; + /* Ensure we only add a mid once. */ + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + return False; + } + } + t = smb_xmalloc(sizeof(*t)); ZERO_STRUCTP(t); @@ -65,6 +72,7 @@ static void store_sequence_for_reply(struct outstanding_packet_lookup **list, DLIST_ADD(*list, t); DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", (unsigned int)reply_seq_num, (unsigned int)mid )); + return True; } static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, @@ -748,14 +756,16 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO if (!good) { - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", - (unsigned int)saved_seq)); - dump_data(5, (const char *)calc_md5_mac, 8); - - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + if (saved_seq) { + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", (unsigned int)saved_seq)); - dump_data(5, (const char *)server_sent_mac, 8); + dump_data(5, (const char *)calc_md5_mac, 8); + DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", + (unsigned int)reply_seq_number)); + dump_data(5, (const char *)server_sent_mac, 8); + } + #if 1 /* JRATEST */ { int i; @@ -848,9 +858,13 @@ void srv_defer_sign_response(uint16 mid) if (!data) return; - store_sequence_for_reply(&data->outstanding_packet_list, - mid, data->send_seq_num); - data->send_seq_num++; + /* + * Ensure we only store this mid reply once... + */ + + if (store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num)) { + data->send_seq_num++; + } } /*********************************************************** -- cgit From e27895d54fa487d28a87e1d31f172e6e468100e2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 13 Jun 2004 23:08:47 +0000 Subject: r1121: Fix memory leak in the trans2 signing code. We would start the trans2 state, which is fine, but never pull the expected reply off the packet queue. I'm not sure if this is still a major problem after jra's recent 'no duplicate mids on the list' change, but I think this is correct anyway. (This used to be commit ee23a4237d427ce72d6a8c5f180ef48d6454cddc) --- source3/libsmb/smb_signing.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 868c991c16..8c59e49ebb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -497,6 +497,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, void cli_signing_trans_start(struct cli_state *cli, uint16 mid) { struct smb_basic_signing_context *data = cli->sign_info.signing_context; + uint32 reply_seq_num; if (!cli->sign_info.doing_signing || !data) return; @@ -504,9 +505,16 @@ void cli_signing_trans_start(struct cli_state *cli, uint16 mid) data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); ZERO_STRUCTP(data->trans_info); - data->trans_info->send_seq_num = data->send_seq_num-2; + /* This ensures the sequence is pulled off the outstanding packet list */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, + mid, &reply_seq_num)) { + DEBUG(1, ("get_sequence_for_reply failed - did we enter the trans signing state without sending a packet?\n")); + return; + } + + data->trans_info->send_seq_num = reply_seq_num - 1; data->trans_info->mid = mid; - data->trans_info->reply_seq_num = data->send_seq_num-1; + data->trans_info->reply_seq_num = reply_seq_num; DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ data->send_seq_num = %u\n", -- cgit From 2acd0848663f28afedff9b11b738e048f5ead2cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jun 2004 18:36:45 +0000 Subject: r1154: Change default setting for case sensitivity to "auto". If set to auto then is the client supports it (current clients supported are Samba and CIFSVFS - detected by the negprot strings "Samba", "POSIX 2" and a bare "NT LM 0.12" string) then the setting of the per packet flag smb_flag FLAG_CASELESS_PATHNAMES is taken into account per packet. This allows the linux CIFS client to use Samba in a case sensitive manner. Additional command in smbclient "case_sensitive", toggles the flag in subsequent packets. Docs to follow. Jeremy. (This used to be commit cf84c0fe1a061acc0313f7db124b8f947cdf623d) --- source3/libsmb/clientgen.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b75d6be0a6..281ee3af84 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -176,7 +176,12 @@ void cli_setup_packet(struct cli_state *cli) SSVAL(cli->outbuf,smb_mid,cli->mid); if (cli->protocol > PROTOCOL_CORE) { uint16 flags2; - SCVAL(cli->outbuf,smb_flg,0x8); + if (cli->case_sensitive) { + SCVAL(cli->outbuf,smb_flg,0x0); + } else { + /* Default setting, case insensitive. */ + SCVAL(cli->outbuf,smb_flg,0x8); + } flags2 = FLAGS2_LONG_PATH_COMPONENTS; if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; @@ -273,6 +278,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; + cli->case_sensitive = False; cli->use_spnego = lp_client_use_spnego(); @@ -440,6 +446,17 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) return ret; } +/**************************************************************************** + Set the case sensitivity flag on the packets. Returns old state. +****************************************************************************/ + +BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) +{ + BOOL ret = cli->case_sensitive; + cli->case_sensitive = case_sensitive; + return ret; +} + /**************************************************************************** Send a keepalive packet to the server ****************************************************************************/ -- cgit From 59d179452780dae847281a85d52d8e6e20575747 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 19 Jun 2004 00:55:29 +0000 Subject: r1194: Definition of krb5_free_unparsed_name() if we do't have it. Jeremy. (This used to be commit 82c219ea023dd546fcde29569725865a42e4198e) --- source3/libsmb/clikrb5.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 9027f192ef..01fcfcc3dd 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -234,6 +234,13 @@ krb5_error_code get_kerberos_allowed_etypes(krb5_context context, } #endif +#if !defined(HAVE_KRB5_FREE_UNPARSED_NAME) + void krb5_free_unparsed_name(krb5_context context, char *val) +{ + SAFE_FREE(val); +} +#endif + static BOOL ads_cleanup_expired_creds(krb5_context context, krb5_ccache ccache, krb5_creds *credsp) -- cgit From 7825677b862bb62b8350b6fee458fbbecc53893f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jun 2004 00:20:31 +0000 Subject: r1222: Valgrind memory leak fixes. Still tracking down a strange one... Can't fix the krb5 memory leaks inside that library :-(. Jeremy. (This used to be commit ad440213aaae58fb5bff6e8a6fcf811c5ba83669) --- source3/libsmb/clikrb5.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 01fcfcc3dd..ab9bc28fe5 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -420,11 +420,12 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, failed: if ( context ) { -#if 0 /* JERRY -- disabled since it causes heimdal 0.6.1rc3 to die - SuSE 9.1 Pro */ +/* Removed by jra. They really need to fix their kerberos so we don't leak memory. + JERRY -- disabled since it causes heimdal 0.6.1rc3 to die + SuSE 9.1 Pro +*/ if (ccdef) krb5_cc_close(context, ccdef); -#endif if (auth_context) krb5_auth_con_free(context, auth_context); krb5_free_context(context); -- cgit From 2b76b28932d9d1ed714e79579414f630966342e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 05:56:44 +0000 Subject: r1236: Heimdal fixes from Guenther Deschner , more to come before it compiles with Heimdal. Jeremy. (This used to be commit dd07278b892770ac51750b87a4ab902d4de3a960) --- source3/libsmb/clikrb5.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index ab9bc28fe5..e7db33a1e8 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -473,6 +473,17 @@ failed: } #endif +krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) +{ +#if defined(HAVE_KRB5_KT_FREE_ENTRY) + return krb5_kt_free_entry(context, kt_entry); +#elif defined(HAVE_KRB5_FREE_KEYTAB_ENTRY_CONTENTS) + return krb5_free_keytab_entry_contents(context, kt_entry); +#else +#error UNKNOWN_KT_FREE_FUNCTION +#endif +} + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, -- cgit From 792776782e18417b8e6e63954db153f4d3d0d558 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 19:25:20 +0000 Subject: r1240: Ensure we don't shadow Heimdal globals. Jeremy. (This used to be commit 464d2e90480c676688a851a141aabddf992e0b0e) --- source3/libsmb/asn1.c | 12 ++++++------ source3/libsmb/clispnego.c | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index ecc5e3dee6..ca14f3fbb7 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -320,17 +320,17 @@ int asn1_tag_remaining(ASN1_DATA *data) BOOL asn1_read_OID(ASN1_DATA *data, char **OID) { uint8 b; - pstring oid; + pstring oid_str; fstring el; if (!asn1_start_tag(data, ASN1_OID)) return False; asn1_read_uint8(data, &b); - oid[0] = 0; + oid_str[0] = 0; fstr_sprintf(el, "%u", b/40); - pstrcat(oid, el); + pstrcat(oid_str, el); fstr_sprintf(el, " %u", b%40); - pstrcat(oid, el); + pstrcat(oid_str, el); while (asn1_tag_remaining(data) > 0) { unsigned v = 0; @@ -339,12 +339,12 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) v = (v<<7) | (b&0x7f); } while (!data->has_error && b & 0x80); fstr_sprintf(el, " %u", v); - pstrcat(oid, el); + pstrcat(oid_str, el); } asn1_end_tag(data); - *OID = strdup(oid); + *OID = strdup(oid_str); return !data->has_error; } diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e6cadc466c..85b7bd9e1e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -141,9 +141,9 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data,ASN1_CONTEXT(0)); asn1_start_tag(&data,ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *oid = NULL; - asn1_read_OID(&data,&oid); - OIDs[i] = oid; + char *oid_str = NULL; + asn1_read_OID(&data,&oid_str); + OIDs[i] = oid_str; } OIDs[i] = NULL; asn1_end_tag(&data); @@ -230,9 +230,9 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_start_tag(&data, ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *oid = NULL; - asn1_read_OID(&data,&oid); - OIDs[i] = oid; + char *oid_str = NULL; + asn1_read_OID(&data,&oid_str); + OIDs[i] = oid_str; } OIDs[i] = NULL; asn1_end_tag(&data); -- cgit From d095357d08e3944a7b2e490b2a809cc200f85995 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 28 Jun 2004 11:12:43 +0000 Subject: r1287: Attempt to fix the build for systems without kerberos headers. Volker (This used to be commit 43020cf459da24a915a39b770cec95a524d487c7) --- source3/libsmb/clikrb5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e7db33a1e8..4929bd63ef 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -124,13 +124,13 @@ #endif #if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) -krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes) { return krb5_get_permitted_enctypes(context, enctypes); } #elif defined(HAVE_KRB5_GET_DEFAULT_IN_TKT_ETYPES) -krb5_error_code get_kerberos_allowed_etypes(krb5_context context, + krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes) { return krb5_get_default_in_tkt_etypes(context, enctypes); @@ -473,7 +473,7 @@ failed: } #endif -krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) + krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) { #if defined(HAVE_KRB5_KT_FREE_ENTRY) return krb5_kt_free_entry(context, kt_entry); -- cgit From f5b4721d6d60bf3b2bb5081469465cc7ee7e17e6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Jul 2004 01:09:10 +0000 Subject: r1326: Modification to get_dc_list to check negative cache. From "Joe Meadows" . Jeremy. (This used to be commit 4cc38b8aea51b55cc449cd2144f18de7d4819637) --- source3/libsmb/conncache.c | 2 - source3/libsmb/namequery.c | 391 +++++++++++++++++++++++---------------------- 2 files changed, 203 insertions(+), 190 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index e6604617d6..15cc75b129 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -154,5 +154,3 @@ void flush_negative_conn_cache( void ) } } - - diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2bb7359e74..cee0015e25 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -56,7 +56,8 @@ static struct node_status *parse_node_status(char *p, int *num_names, struct nod return NULL; ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names)); - if (!ret) return NULL; + if (!ret) + return NULL; p++; for (i=0;i< *num_names;i++) { @@ -556,84 +557,80 @@ XFILE *startlmhosts(char *fname) BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) { - pstring line; - - while(!x_feof(fp) && !x_ferror(fp)) { - pstring ip,flags,extra; - const char *ptr; - char *ptr1; - int count = 0; + pstring line; - *name_type = -1; + while(!x_feof(fp) && !x_ferror(fp)) { + pstring ip,flags,extra; + const char *ptr; + char *ptr1; + int count = 0; - if (!fgets_slash(line,sizeof(pstring),fp)) - continue; + *name_type = -1; - if (*line == '#') - continue; + if (!fgets_slash(line,sizeof(pstring),fp)) { + continue; + } - pstrcpy(ip,""); - pstrcpy(name,""); - pstrcpy(flags,""); + if (*line == '#') { + continue; + } - ptr = line; + pstrcpy(ip,""); + pstrcpy(name,""); + pstrcpy(flags,""); - if (next_token(&ptr,ip ,NULL,sizeof(ip))) - ++count; - if (next_token(&ptr,name ,NULL, sizeof(pstring))) - ++count; - if (next_token(&ptr,flags,NULL, sizeof(flags))) - ++count; - if (next_token(&ptr,extra,NULL, sizeof(extra))) - ++count; + ptr = line; - if (count <= 0) - continue; + if (next_token(&ptr,ip ,NULL,sizeof(ip))) + ++count; + if (next_token(&ptr,name ,NULL, sizeof(pstring))) + ++count; + if (next_token(&ptr,flags,NULL, sizeof(flags))) + ++count; + if (next_token(&ptr,extra,NULL, sizeof(extra))) + ++count; - if (count > 0 && count < 2) - { - DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line)); - continue; - } + if (count <= 0) + continue; - if (count >= 4) - { - DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); - continue; - } + if (count > 0 && count < 2) { + DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line)); + continue; + } - DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); + if (count >= 4) { + DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); + continue; + } - if (strchr_m(flags,'G') || strchr_m(flags,'S')) - { - DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); - continue; - } + DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); - *ipaddr = *interpret_addr2(ip); + if (strchr_m(flags,'G') || strchr_m(flags,'S')) { + DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); + continue; + } - /* Extra feature. If the name ends in '#XX', where XX is a hex number, - then only add that name type. */ - if((ptr1 = strchr_m(name, '#')) != NULL) - { - char *endptr; + *ipaddr = *interpret_addr2(ip); - ptr1++; - *name_type = (int)strtol(ptr1, &endptr, 16); + /* Extra feature. If the name ends in '#XX', where XX is a hex number, + then only add that name type. */ + if((ptr1 = strchr_m(name, '#')) != NULL) { + char *endptr; + ptr1++; - if(!*ptr1 || (endptr == ptr1)) - { - DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); - continue; - } + *name_type = (int)strtol(ptr1, &endptr, 16); + if(!*ptr1 || (endptr == ptr1)) { + DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); + continue; + } - *(--ptr1) = '\0'; /* Truncate at the '#' */ - } + *(--ptr1) = '\0'; /* Truncate at the '#' */ + } - return True; - } + return True; + } - return False; + return False; } /******************************************************** @@ -998,145 +995,145 @@ static BOOL internal_resolve_name(const char *name, int name_type, struct ip_service **return_iplist, int *return_count, const char *resolve_order) { - pstring name_resolve_list; - fstring tok; - const char *ptr; - BOOL allones = (strcmp(name,"255.255.255.255") == 0); - BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); - BOOL is_address = is_ipaddress(name); - BOOL result = False; - int i; + pstring name_resolve_list; + fstring tok; + const char *ptr; + BOOL allones = (strcmp(name,"255.255.255.255") == 0); + BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); + BOOL is_address = is_ipaddress(name); + BOOL result = False; + int i; - *return_iplist = NULL; - *return_count = 0; + *return_iplist = NULL; + *return_count = 0; - DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); + DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); - if (allzeros || allones || is_address) { + if (allzeros || allones || is_address) { - if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) { - DEBUG(0,("internal_resolve_name: malloc fail !\n")); - return False; - } + if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) { + DEBUG(0,("internal_resolve_name: malloc fail !\n")); + return False; + } - if(is_address) { - /* ignore the port here */ - (*return_iplist)->port = PORT_NONE; + if(is_address) { + /* ignore the port here */ + (*return_iplist)->port = PORT_NONE; - /* if it's in the form of an IP address then get the lib to interpret it */ - if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){ - DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); - return False; + /* if it's in the form of an IP address then get the lib to interpret it */ + if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){ + DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); + return False; + } + } else { + (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0; } - } else { - (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0; + *return_count = 1; + return True; } - *return_count = 1; - return True; - } - /* Check name cache */ + /* Check name cache */ - if (namecache_fetch(name, name_type, return_iplist, return_count)) { - /* This could be a negative response */ - return (*return_count > 0); - } + if (namecache_fetch(name, name_type, return_iplist, return_count)) { + /* This could be a negative response */ + return (*return_count > 0); + } - /* set the name resolution order */ + /* set the name resolution order */ - if ( strcmp( resolve_order, "NULL") == 0 ) { - DEBUG(8,("internal_resolve_name: all lookups disabled\n")); - return False; - } - - if ( !resolve_order ) - pstrcpy(name_resolve_list, lp_name_resolve_order()); - else - pstrcpy(name_resolve_list, resolve_order); + if ( strcmp( resolve_order, "NULL") == 0 ) { + DEBUG(8,("internal_resolve_name: all lookups disabled\n")); + return False; + } - if ( !name_resolve_list[0] ) - ptr = "host"; - else - ptr = name_resolve_list; + if ( !resolve_order ) { + pstrcpy(name_resolve_list, lp_name_resolve_order()); + } else { + pstrcpy(name_resolve_list, resolve_order); + + if ( !name_resolve_list[0] ) { + ptr = "host"; + } else { + ptr = name_resolve_list; + } - /* iterate through the name resolution backends */ + /* iterate through the name resolution backends */ - while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { - if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (resolve_hosts(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "ads")) { - /* deal with 0x1c names here. This will result in a - SRV record lookup for _ldap._tcp. if we - are using 'security = ads' */ - if (resolve_ads(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "lmhosts")) { - if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "wins")) { - /* don't resolve 1D via WINS */ - if (name_type != 0x1D && - resolve_wins(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "bcast")) { - if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else { - DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); - } - } - - /* All of the resolve_* functions above have returned false. */ - - SAFE_FREE(*return_iplist); - *return_count = 0; - - return False; + while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { + if((strequal(tok, "host") || strequal(tok, "hosts"))) { + if (resolve_hosts(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "ads")) { + /* deal with 0x1c names here. This will result in a + SRV record lookup for _ldap._tcp. if we + are using 'security = ads' */ + if (resolve_ads(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "lmhosts")) { + if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "wins")) { + /* don't resolve 1D via WINS */ + if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "bcast")) { + if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else { + DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); + } + } - done: + /* All of the resolve_* functions above have returned false. */ + + SAFE_FREE(*return_iplist); + *return_count = 0; + + return False; - /* Remove duplicate entries. Some queries, notably #1c (domain - controllers) return the PDC in iplist[0] and then all domain - controllers including the PDC in iplist[1..n]. Iterating over - the iplist when the PDC is down will cause two sets of timeouts. */ + done: - if ( *return_count ) { - *return_count = remove_duplicate_addrs2( *return_iplist, *return_count ); - } + /* Remove duplicate entries. Some queries, notably #1c (domain + controllers) return the PDC in iplist[0] and then all domain + controllers including the PDC in iplist[1..n]. Iterating over + the iplist when the PDC is down will cause two sets of timeouts. */ + + if ( *return_count ) { + *return_count = remove_duplicate_addrs2( *return_iplist, *return_count ); + } - /* Save in name cache */ - if ( DEBUGLEVEL >= 100 ) { - for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) - DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name, - name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); - } + /* Save in name cache */ + if ( DEBUGLEVEL >= 100 ) { + for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) + DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name, + name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); + } - namecache_store(name, name_type, *return_count, *return_iplist); - - /* Display some debugging info */ + namecache_store(name, name_type, *return_count, *return_iplist); - if ( DEBUGLEVEL >= 10 ) { - DEBUG(10, ("internal_resolve_name: returning %d addresses: ", - *return_count)); + /* Display some debugging info */ - for (i = 0; i < *return_count; i++) - DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); + if ( DEBUGLEVEL >= 10 ) { + DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count)); - DEBUG(10, ("\n")); - } + for (i = 0; i < *return_count; i++) { + DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); + } + DEBUG(10, ("\n")); + } + } - return result; + return result; } /******************************************************** @@ -1218,8 +1215,9 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) /* Look up #1B name */ - if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) + if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) { return False; + } /* if we get more than 1 IP back we have to assume it is a multi-homed PDC and not a mess up */ @@ -1298,16 +1296,17 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, num_addresses += auto_count; done_auto_lookup = True; DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); - } - else + } else { num_addresses++; + } } /* if we have no addresses and haven't done the auto lookup, then just return the list of DC's */ - if ( (num_addresses == 0) && !done_auto_lookup ) + if ( (num_addresses == 0) && !done_auto_lookup ) { return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); + } /* maybe we just failed? */ @@ -1317,8 +1316,7 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, } if ( (return_iplist = (struct ip_service *) - malloc(num_addresses * sizeof(struct ip_service))) == NULL ) - { + malloc(num_addresses * sizeof(struct ip_service))) == NULL ) { DEBUG(3,("get_dc_list: malloc fail !\n")); return False; } @@ -1335,6 +1333,13 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, if ( strequal(name, "*") ) { for ( j=0; j= 4 ) { DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, @@ -1392,8 +1405,9 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, } /********************************************************************* - small wrapper function to get the DC list and sort it if neccessary + Small wrapper function to get the DC list and sort it if neccessary. *********************************************************************/ + BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) { BOOL ordered; @@ -1401,13 +1415,14 @@ BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *c DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", (ads_only ? "ads" : lp_name_resolve_order()))); - if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) - return False; + if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) { + return False; + } /* only sort if we don't already have an ordered list */ - if ( !ordered ) + if ( !ordered ) { sort_ip_list2( *ip_list, *count ); + } return True; } - -- cgit From 824bc32be71afafdbaaea94a6cf104a1b3d329ec Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 8 Jul 2004 15:36:23 +0000 Subject: r1399: applying heimdal krb5 fixes from Guenther and fixing compile warnings in libadskerberos_keyatb.c (This used to be commit 837f56ec8bc171497fb84d332002776313c26305) --- source3/libsmb/clikrb5.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 4929bd63ef..abb1eb4acb 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -425,7 +425,9 @@ failed: SuSE 9.1 Pro */ if (ccdef) +#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ krb5_cc_close(context, ccdef); +#endif if (auth_context) krb5_auth_con_free(context, auth_context); krb5_free_context(context); @@ -473,7 +475,7 @@ failed: } #endif - krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) +krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) { #if defined(HAVE_KRB5_KT_FREE_ENTRY) return krb5_kt_free_entry(context, kt_entry); -- cgit From 0122d4ef5e441e5470e190b77567d00b703e549e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 8 Jul 2004 18:14:07 +0000 Subject: r1407: revert change that broke the build on systems w/o krb5 files (This used to be commit 89a11b5d7c0939c9344115ef509cbb0567d7524a) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index abb1eb4acb..b9a3dda494 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -475,7 +475,7 @@ failed: } #endif -krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) + krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) { #if defined(HAVE_KRB5_KT_FREE_ENTRY) return krb5_kt_free_entry(context, kt_entry); -- cgit From 608172ebe31abd4ffa9584fd3fe411cb0955f5fa Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 10 Jul 2004 03:26:43 +0000 Subject: r1428: Remove *completly bogus* memset. (No doubt my bug, too...). This memset could well have clobbered bits of the stack, because session_key changed from char session_key[16]; to DATA_BLOB session_key Andrew Bartlett (This used to be commit 54248a405c9459f93f4200ebb0dc71748ae2fc83) --- source3/libsmb/clikrb5.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index b9a3dda494..5fcde4654a 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -442,8 +442,6 @@ failed: krb5_error_code err; BOOL ret = False; - memset(session_key, 0, 16); - if (remote) err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); else -- cgit From 8f93b500320d7d4341dfea37fd1f82d02b1ce980 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Jul 2004 01:20:50 +0000 Subject: r1487: Remove unused parameter for the client-side signing functions. Andrew Bartlett (This used to be commit 6d594d5bb119b6bc3f4c7699752666ac24d04745) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 2 +- source3/libsmb/smb_signing.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index afbd2079ea..ce404e1b9e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -675,7 +675,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use for checking the first reply from the server */ cli_calculate_sign_mac(cli); - if (!cli_check_sign_mac(cli, True)) { + if (!cli_check_sign_mac(cli)) { nt_status = NT_STATUS_ACCESS_DENIED; } } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 281ee3af84..974ebf91f5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -117,7 +117,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_check_sign_mac(cli, True)) { + if (!cli_check_sign_mac(cli)) { DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = READ_BAD_SIG; close(cli->fd); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 8c59e49ebb..39131debf5 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -627,9 +627,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -BOOL cli_check_sign_mac(struct cli_state *cli, BOOL must_be_ok) +BOOL cli_check_sign_mac(struct cli_state *cli) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, must_be_ok)) { + if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; } -- cgit From 9d0783bf211dffe58845b36b0669f05bf8bf25b5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 14 Jul 2004 04:36:01 +0000 Subject: r1492: Rework our random number generation system. On systems with /dev/urandom, this avoids a change to secrets.tdb for every fork(). For other systems, we now only re-seed after a fork, and on startup. No need to do it per-operation. This removes the 'need_reseed' parameter from generate_random_buffer(). Andrew Bartlett (This used to be commit 36741d3cf53a7bd17d361251f2bb50851cdb035f) --- source3/libsmb/ntlmssp.c | 6 +++--- source3/libsmb/smbencrypt.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 66d48afc46..6e41a61bf1 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -103,7 +103,7 @@ void debug_ntlmssp_flags(uint32 neg_flags) static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state) { static uchar chal[8]; - generate_random_buffer(chal, sizeof(chal), False); + generate_random_buffer(chal, sizeof(chal)); return chal; } @@ -960,7 +960,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, E_md4hash(ntlmssp_state->password, nt_hash); lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); - generate_random_buffer(lm_response.data, 8, False); + generate_random_buffer(lm_response.data, 8); memset(lm_response.data+8, 0, 16); memcpy(session_nonce, challenge_blob.data, 8); @@ -1022,7 +1022,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { /* Make up a new session key */ uint8 client_session_key[16]; - generate_random_buffer(client_session_key, sizeof(client_session_key), False); + generate_random_buffer(client_session_key, sizeof(client_session_key)); /* Encrypt the new session key with the old one */ encrypted_session_key = data_blob(client_session_key, sizeof(client_session_key)); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 44f7428086..9f936b77ae 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -352,7 +352,7 @@ static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) DATA_BLOB response = data_blob(NULL, 0); char long_date[8]; - generate_random_buffer(client_chal, sizeof(client_chal), False); + generate_random_buffer(client_chal, sizeof(client_chal)); put_long_date(long_date, time(NULL)); @@ -406,7 +406,7 @@ static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16], /* LMv2 */ /* client-supplied random data */ - generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length, False); + generate_random_buffer(lmv2_client_data.data, lmv2_client_data.length); /* Given that data, and the challenge from the server, generate a response */ SMBOWFencrypt_ntv2(ntlm_v2_hash, server_chal, &lmv2_client_data, lmv2_response); @@ -476,7 +476,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len, True); + generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len); /* * The length of the new password is in the last 4 bytes of -- cgit From 5cc398d23dcbc615341a74f42c9b2fff9bd00062 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 21 Jul 2004 12:22:58 +0000 Subject: r1560: Not that anybody uses this stuff (yet...), but at least get it correct :-) When sending a mailslot datagram, get the packet length correction correct. Volker (This used to be commit 530e7f09aea22f5782af0c6b333e15e01660b34a) --- source3/libsmb/clidgram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index c4675f1938..ba65c46d16 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -63,7 +63,7 @@ int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot, /* Setup the smb part. */ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ memcpy(tmp,ptr,4); - set_message(ptr,17,17 + len,True); + set_message(ptr,17,strlen(mailslot) + 1 + len,True); memcpy(ptr,tmp,4); SCVAL(ptr,smb_com,SMBtrans); -- cgit From 2a6ab279559da7e79229461c39c2c2bf09bb5ca8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 24 Jul 2004 23:57:07 +0000 Subject: r1581: 'NULL' NTLMSSP is both a pain to get right, and compleatly and utterly pointless. With a well-known session key, we may as well put the password change directly on the wire, with it's own 'crypted with old password' as the protection. This should fix some 'long password change' issues, against Samba in particular. Andrew Bartlett (This used to be commit 554a9132872187077a9c00abb18b9d809c59b7f1) --- source3/libsmb/passchange.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 9f46c131fe..8bce9c86a1 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -144,6 +144,8 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, init_creds(&creds, "", "", NULL); cli_init_creds(&cli, &creds); + cli.pipe_auth_flags = 0; + result = NT_STATUS_UNSUCCESSFUL; /* OK, this is ugly, but... */ -- cgit From 748e7e4a923ee89b94f376066b1778cce5a58dfe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 30 Jul 2004 11:14:47 +0000 Subject: r1612: Fix bug #1571 found by Guenter Kukkukk (Botched LANMAN2 session setup code) Andrew Bartlett (This used to be commit 3baa4ef6c58eb13bec1a8ddb1561a504f4a16107) --- source3/libsmb/cliconnect.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ce404e1b9e..559538aac9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -81,7 +81,10 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, if (passlen > 0 && (cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen != 24) { /* Encrypted mode needed, and non encrypted password supplied. */ lm_response = data_blob(NULL, 24); - SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data); + if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) { + DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n")); + return False; + } } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ lm_response = data_blob(pass, passlen); @@ -106,7 +109,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, p = smb_buf(cli->outbuf); memcpy(p,lm_response.data,lm_response.length); - p += passlen; + p += lm_response.length; p += clistr_push(cli, p, user, -1, STR_TERMINATE|STR_UPPER); p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE|STR_UPPER); p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE); -- cgit From 2723be12397c1ddadecac501fb2484c5aa56a564 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 Aug 2004 19:57:41 +0000 Subject: r1661: Changed the password history format so that each history entry consists of a 16 byte salt, followed by the 16 byte MD5 hash of the concatination of the salt plus the NThash of the historical password. Allows these to be exposed in LDAP without security issues. Jeremy. (This used to be commit 82e4036aaa2d283534a5bd8149857320fcf0d0dc) --- source3/libsmb/smbencrypt.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 9f936b77ae..d4b0557411 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -72,6 +72,26 @@ void E_md4hash(const char *passwd, uchar p16[16]) ZERO_STRUCT(wpwd); } +/** + * Creates the MD5 Hash of a combination of 16 byte salt and 16 byte NT hash. + * @param 16 byte salt. + * @param 16 byte NT hash. + * @param 16 byte return hashed with md5, caller allocated 16 byte buffer + */ + +void E_md5hash(const uchar salt[16], const uchar nthash[16], uchar hash_out[16]) +{ + struct MD5Context tctx; + uchar array[32]; + + memset(hash_out, '\0', 16); + memcpy(array, salt, 16); + memcpy(&array[16], nthash, 16); + MD5Init(&tctx); + MD5Update(&tctx, array, 32); + MD5Final(hash_out, &tctx); +} + /** * Creates the DES forward-only Hash of the users password in DOS ASCII charset * @param passwd password in 'unix' charset. -- cgit From 3eb42d3b6e64c817396ee4391e0dcaacc5db0029 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 20 Aug 2004 20:07:17 +0000 Subject: r1965: add cli_setattrE (inspired by samba4-code). needed for further migration-work. could someone possibly double-check the byte-count? Guenther (This used to be commit 27302905e88960d774c82eab6207ff6a918b0235) --- source3/libsmb/clifile.c | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 398c7cc4f0..ff0edc6bb4 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -982,6 +982,47 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, return True; } +/**************************************************************************** + Do a SMBsetattrE call. +****************************************************************************/ + +BOOL cli_setattrE(struct cli_state *cli, int fd, + time_t c_time, time_t a_time, time_t m_time) + +{ + char *p; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,7,0,True); + + SCVAL(cli->outbuf,smb_com,SMBsetattrE); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0, fd); + put_dos_date3(cli->outbuf,smb_vwv1, c_time); + put_dos_date3(cli->outbuf,smb_vwv3, a_time); + put_dos_date3(cli->outbuf,smb_vwv5, m_time); + + p = smb_buf(cli->outbuf); + *p++ = 4; + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_is_error(cli)) { + return False; + } + + return True; +} + /**************************************************************************** Do a SMBsetatr call. ****************************************************************************/ -- cgit From 77cc4121cf0a31a6594bccd1f86351aee785eb96 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Aug 2004 07:52:23 +0000 Subject: r2057: Although rarely used, prevent "net lookup kdc" from segfaulting when using our own implementation of krb5_lookup_kdc with heimdal. Also, heimdals krb5_krbhst_next() obviously does not retrieve the struct addrinfo in the krb5_krbhst_info-struct, using krb5_krbhst_get_addrinfo() instead. Guenther (This used to be commit cca660e109cc94b49ac6bf1f2802235d1d4d4383) --- source3/libsmb/clikrb5.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5fcde4654a..de2f0cec18 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -190,6 +190,7 @@ krb5_error_code rc; int num_kdcs, i; struct sockaddr *sa; + struct addrinfo **ai; *addr_pp = NULL; *naddrs = 0; @@ -219,10 +220,19 @@ return -1; } + *addr_pp = malloc(sizeof(struct sockaddr) * num_kdcs); memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { - if (hinfo->ai->ai_family == AF_INET) + +#if defined(HAVE_KRB5_KRBHST_GET_ADDRINFO) + rc = krb5_krbhst_get_addrinfo(ctx, hinfo, ai); + if (rc) { + DEBUG(0,("krb5_krbhst_get_addrinfo failed: %s\n", error_message(rc))); + return rc; + } +#endif + if (hinfo->ai && hinfo->ai->ai_family == AF_INET) memcpy(&sa[i], hinfo->ai->ai_addr, sizeof(struct sockaddr)); } -- cgit From ed5fd7117e931b2fce2c2a94adc53eeb3d8a8256 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 27 Aug 2004 13:39:09 +0000 Subject: r2086: fix bug with winbindd_getpwnam() caused by Microsoft DC's not filling in the username in the user_info3 (This used to be commit 4703a71fa88dff8bdc932f6c9af3a9d25a88938f) --- source3/libsmb/samlogon_cache.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 4cd642c4e3..0105bc08c3 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -106,9 +106,10 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) /*********************************************************************** Store a NET_USER_INFO_3 structure in a tdb for later user + username should be in UTF-8 format ***********************************************************************/ -BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) +BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USER_INFO_3 *user) { TDB_DATA data; fstring keystr; @@ -130,6 +131,14 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, NET_USER_INFO_3 *user) slprintf(keystr, sizeof(keystr), "%s", sid_string_static(&user_sid)); DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); + + /* only Samba fills in the username, not sure why NT doesn't */ + /* so we fill it in since winbindd_getpwnam() makes use of it */ + + if ( !user->uni_user_name.buffer ) { + init_unistr2( &user->uni_user_name, username, STR_TERMINATE ); + init_uni_hdr( &user->hdr_user_name, &user->uni_user_name ); + } /* Prepare data */ -- cgit From 571cc4811bc373a5b4aeda9e5635aff1ff650e06 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 4 Sep 2004 01:57:16 +0000 Subject: r2224: Make nmbd more robust against bad netbios packets. Jeremy. (This used to be commit dd9b17abd6b32c090840c1a0b797fd774711cb3a) --- source3/libsmb/nmblib.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index d883c5308d..7f22ce0096 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -475,6 +475,11 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) dgram->datasize = length-offset; memcpy(dgram->data,inbuf+offset,dgram->datasize); + /* Paranioa. Ensure the last 2 bytes in the dgram buffer are + zero. This should be true anyway, just enforce it for paranioa sake. JRA. */ + SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2)); + memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2); + return(True); } -- cgit From 20e9f051e2fe5867e11988139399bac692112fc6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Sep 2004 20:33:03 +0000 Subject: r2355: Now we've shipped 3.0.7, add in the DOS fix. Jeremy. (This used to be commit d6b26f9db76e81d65b7630e46af99fe03a982ec6) --- source3/libsmb/asn1.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index ca14f3fbb7..2807b4e1d3 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -219,6 +219,9 @@ BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) /* read from a ASN1 buffer, advancing the buffer pointer */ BOOL asn1_read(ASN1_DATA *data, void *p, int len) { + if (data->has_error) + return False; + if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { data->has_error = True; return False; @@ -309,6 +312,9 @@ BOOL asn1_end_tag(ASN1_DATA *data) /* work out how many bytes are left in this nested tag */ int asn1_tag_remaining(ASN1_DATA *data) { + if (data->has_error) + return 0; + if (!data->nesting) { data->has_error = True; return -1; -- cgit From 41b37207139b3cbfa293a84ab92113db8007afed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Sep 2004 00:49:41 +0000 Subject: r2371: Fix for talking to OS/2 clients (max_mux ignored) by Guenter Kukkukk . Bugid #1590. Jeremy. (This used to be commit 330025d1a669de927a3879a9c3a9fc20e1be464f) --- source3/libsmb/cliconnect.c | 1 + source3/libsmb/clireadwrite.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 559538aac9..98656c119d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1133,6 +1133,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); + cli->max_mux = SVAL(cli->inbuf, smb_vwv3); cli->sesskey = IVAL(cli->inbuf,smb_vwv6); cli->serverzone = SVALS(cli->inbuf,smb_vwv10); cli->serverzone *= 60; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 8eac7d07d8..60ac89aeb2 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -325,10 +325,16 @@ ssize_t cli_write(struct cli_state *cli, int bwritten = 0; int issued = 0; int received = 0; - int mpx = MAX(cli->max_mux-1, 1); + int mpx = 1; int block = cli->max_xmit - (smb_size+32); int blocks = (size + (block-1)) / block; + if(cli->max_mux == 0) { + mpx = 1; + } else { + mpx = cli->max_mux-1; + } + while (received < blocks) { while ((issued - received < mpx) && (issued < blocks)) { -- cgit From 40a89ce884de9de9cd013864e03a73b9c44ebde7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Sep 2004 00:53:17 +0000 Subject: r2373: Fix typo. Jeremy. (This used to be commit b1033fc77c97f0d9b5613a0b9f7d45dcf58e6b56) --- source3/libsmb/clireadwrite.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 60ac89aeb2..3f14e53094 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -329,10 +329,10 @@ ssize_t cli_write(struct cli_state *cli, int block = cli->max_xmit - (smb_size+32); int blocks = (size + (block-1)) / block; - if(cli->max_mux == 0) { - mpx = 1; - } else { + if(cli->max_mux > 1) { mpx = cli->max_mux-1; + } else { + mpx = 1; } while (received < blocks) { -- cgit From 10e4a96b5399a7ecbc893d2493a9ceb3ec66c8ed Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 17 Sep 2004 15:09:20 +0000 Subject: r2388: fix client quota support for the client we need the windows path and for server we need unix path metze (This used to be commit 54fd28f5e7b70ce2b192c2037ce28da3fea9ef92) --- source3/libsmb/cliquota.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index ed808aa1f5..af8b4422b7 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -22,13 +22,13 @@ BOOL cli_get_quota_handle(struct cli_state *cli, int *quota_fnum) { - *quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA, + *quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA_WIN32, 0x00000016, DESIRED_ACCESS_PIPE, 0x00000000, FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x00000000, 0x03); if (*quota_fnum == (-1)) { - return False; + return False; } return True; -- cgit From 0b9e4a98c821424fb12a71bfdf5f66ab98b780d4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 21 Sep 2004 07:55:49 +0000 Subject: r2466: Fix memleak found by sean.chandler@verizon.net. Thanks! Volker (This used to be commit 587d863ae87042e0193b8d27b52ab3f75c58974b) --- source3/libsmb/cliconnect.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 98656c119d..4ff60c1b1c 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -668,11 +668,16 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length); DATA_BLOB null_blob = data_blob(NULL, 0); + BOOL res; fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); - if (cli_simple_set_signing(cli, key, null_blob)) { + res = cli_simple_set_signing(cli, key, null_blob); + + data_blob_free(&key); + + if (res) { /* 'resign' the last message, so we get the right sequence numbers for checking the first reply from the server */ -- cgit From 83d5892eab7662053ca9ce3711d60760aadf6084 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 21 Sep 2004 10:40:45 +0000 Subject: r2472: Fixed krb5_krbhost_get_addrinfo()-parameters and make failure of this call non-critical. Thanks to Love for the patch and explaining the inner workings of heimdal. Guenther (This used to be commit 4bd9d8240b571fdd8546af4eea3f4f148987d57c) --- source3/libsmb/clikrb5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index de2f0cec18..2b0c054493 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -190,7 +190,7 @@ krb5_error_code rc; int num_kdcs, i; struct sockaddr *sa; - struct addrinfo **ai; + struct addrinfo *ai; *addr_pp = NULL; *naddrs = 0; @@ -226,10 +226,10 @@ for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { #if defined(HAVE_KRB5_KRBHST_GET_ADDRINFO) - rc = krb5_krbhst_get_addrinfo(ctx, hinfo, ai); + rc = krb5_krbhst_get_addrinfo(ctx, hinfo, &ai); if (rc) { DEBUG(0,("krb5_krbhst_get_addrinfo failed: %s\n", error_message(rc))); - return rc; + continue; } #endif if (hinfo->ai && hinfo->ai->ai_family == AF_INET) -- cgit From a71c7b4e173a9f99d470c4be2c6ecc2989d34486 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 21 Sep 2004 12:50:04 +0000 Subject: r2474: (re-)fix memleak (initially found by jra). heimdal 0.6.1rc3 had a bug causing winbindd to die, heimdal version 0.6.1 and higher have that fixed (thanks to Love from Heimdal). SuSE has been informed about this possible pitfall, any other vendors that ship with heimdal-0.6.1rc3 to be notified ? Guenther (This used to be commit 6239a5bec99c62032e0cde20679a71622dd7a059) --- source3/libsmb/clikrb5.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2b0c054493..f7f84f1e29 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -430,14 +430,8 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, failed: if ( context ) { -/* Removed by jra. They really need to fix their kerberos so we don't leak memory. - JERRY -- disabled since it causes heimdal 0.6.1rc3 to die - SuSE 9.1 Pro -*/ if (ccdef) -#if 0 /* redisabled by gd :) at least until any official heimdal version has it fixed. */ krb5_cc_close(context, ccdef); -#endif if (auth_context) krb5_auth_con_free(context, auth_context); krb5_free_context(context); -- cgit From 8875124a61c63d2def8ec193a98732f6fcfaa6a1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Sep 2004 00:55:46 +0000 Subject: r2575: Return correct error codes on old SEARCH call (from Samba4 torture tester). Jeremy. (This used to be commit fc51c97ea86bd1a86830d4ab2c6c7c4ec9fccc88) --- source3/libsmb/errormap.c | 3 ++- source3/libsmb/nterr.c | 16 +++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 77c71fce13..8ac1aed923 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -102,6 +102,7 @@ static const struct { * Not an official error, as only bit 0x80000000, not bits 0xC0000000 are set. */ {ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW}, + {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, {ERRDOS, ERRbadfid, NT_STATUS_OBJECT_TYPE_MISMATCH}, {ERRHRD, ERRgeneral, NT_STATUS_NONCONTINUABLE_EXCEPTION}, {ERRHRD, ERRgeneral, NT_STATUS_INVALID_DISPOSITION}, @@ -632,7 +633,7 @@ static const struct { {ERRDOS, 14, NT_STATUS_SECTION_NOT_EXTENDED}, {ERRDOS, ERRremcd, NT_STATUS_DIRECTORY_NOT_EMPTY}, {ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE}, - {ERRDOS, ERRnofiles, NT_STATUS(0x80000006)}, + {ERRDOS, ERRnofiles, STATUS_NO_MORE_FILES}, {ERRDOS, 19, NT_STATUS_MEDIA_WRITE_PROTECTED}, {ERRDOS, 21, NT_STATUS_NO_MEDIA_IN_DEVICE}, {ERRDOS, 22, NT_STATUS_INVALID_DEVICE_STATE}, diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index b01451ea0f..677c5d84c7 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -537,6 +537,7 @@ static nt_err_code_struct nt_errs[] = { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, + { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, { NULL, NT_STATUS(0) } }; @@ -634,14 +635,15 @@ nt_err_code_struct nt_err_desc[] = { "Insufficient logon information", NT_STATUS_INSUFFICIENT_LOGON_INFO }, { "License quota exceeded", NT_STATUS_LICENSE_QUOTA_EXCEEDED }, + { "No more files", STATUS_NO_MORE_FILES }, { NULL, NT_STATUS(0) } }; - /***************************************************************************** - returns an NT error message. not amazingly helpful, but better than a number. + Returns an NT error message. not amazingly helpful, but better than a number. *****************************************************************************/ + const char *nt_errstr(NTSTATUS nt_code) { static pstring msg; @@ -669,8 +671,7 @@ const char *get_friendly_nt_error_msg(NTSTATUS nt_code) int idx = 0; while (nt_err_desc[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) - { + if (NT_STATUS_V(nt_err_desc[idx].nt_errcode) == NT_STATUS_V(nt_code)) { return nt_err_desc[idx].nt_errstr; } idx++; @@ -682,8 +683,9 @@ const char *get_friendly_nt_error_msg(NTSTATUS nt_code) } /***************************************************************************** - returns an NT_STATUS constant as a string for inclusion in autogen C code + Returns an NT_STATUS constant as a string for inclusion in autogen C code. *****************************************************************************/ + const char *get_nt_error_c_code(NTSTATUS nt_code) { static pstring out; @@ -703,8 +705,9 @@ const char *get_nt_error_c_code(NTSTATUS nt_code) } /***************************************************************************** - returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) + Returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) *****************************************************************************/ + NTSTATUS nt_status_string_to_code(char *nt_status_str) { int idx = 0; @@ -718,7 +721,6 @@ NTSTATUS nt_status_string_to_code(char *nt_status_str) return NT_STATUS_UNSUCCESSFUL; } - /** * Squash an NT_STATUS in line with security requirements. * In an attempt to avoid giving the whole game away when users -- cgit From eb9a09954b97f78768f07cbb921c05b06321d5ec Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 26 Sep 2004 06:27:54 +0000 Subject: r2651: Added 'stat' command to smbclient to exercise the UNIX_FILE_BASIC info level. Outputs data on the file in the same format the the stat command in Linux. Should be useful to people wanting to learn how to parse the UNIX extension output. Yes I will add the docs later :-). Jeremy. (This used to be commit b25cc596417d29815814c3968ac2627bf59ffc0b) --- source3/libsmb/clifile.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 130 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ff0edc6bb4..d302206949 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -77,7 +77,7 @@ static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const Map standard UNIX permissions onto wire representations. ****************************************************************************/ -uint32 unix_perms_to_wire(mode_t perms) +uint32 unix_perms_to_wire(mode_t perms) { unsigned int ret = 0; @@ -102,6 +102,135 @@ uint32 unix_perms_to_wire(mode_t perms) return ret; } +/**************************************************************************** + Map wire permissions to standard UNIX. +****************************************************************************/ + +mode_t wire_perms_to_unix(uint32 perms) +{ + mode_t ret = (mode_t)0; + + ret |= ((perms & UNIX_X_OTH) ? S_IXOTH : 0); + ret |= ((perms & UNIX_W_OTH) ? S_IWOTH : 0); + ret |= ((perms & UNIX_R_OTH) ? S_IROTH : 0); + ret |= ((perms & UNIX_X_GRP) ? S_IXGRP : 0); + ret |= ((perms & UNIX_W_GRP) ? S_IWGRP : 0); + ret |= ((perms & UNIX_R_GRP) ? S_IRGRP : 0); + ret |= ((perms & UNIX_X_USR) ? S_IXUSR : 0); + ret |= ((perms & UNIX_W_USR) ? S_IWUSR : 0); + ret |= ((perms & UNIX_R_USR) ? S_IRUSR : 0); +#ifdef S_ISVTX + ret |= ((perms & UNIX_STICKY) ? S_ISVTX : 0); +#endif +#ifdef S_ISGID + ret |= ((perms & UNIX_SET_GID) ? S_ISGID : 0); +#endif +#ifdef S_ISUID + ret |= ((perms & UNIX_SET_UID) ? S_ISUID : 0); +#endif + return ret; +} + +/**************************************************************************** + Return the file type from the wire filetype for UNIX extensions. +****************************************************************************/ + +static mode_t unix_filetype_from_wire(uint32 wire_type) +{ + switch (wire_type) { + case UNIX_TYPE_FILE: + return S_IFREG; + case UNIX_TYPE_DIR: + return S_IFDIR; +#ifdef S_IFLNK + case UNIX_TYPE_SYMLINK: + return S_IFLNK; +#endif +#ifdef S_IFCHR + case UNIX_TYPE_CHARDEV: + return S_IFCHR; +#endif +#ifdef S_IFBLK + case UNIX_TYPE_BLKDEV: + return S_IFBLK; +#endif +#ifdef S_IFIFO + case UNIX_TYPE_FIFO: + return S_IFIFO; +#endif +#ifdef S_IFSOCK + case UNIX_TYPE_SOCKET: + return S_IFSOCK; +#endif + default: + return (mode_t)0; + } +} + +/**************************************************************************** + Stat a file (UNIX extensions). +****************************************************************************/ + +BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf) +{ + unsigned int param_len = 0; + unsigned int data_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + char param[sizeof(pstring)+6]; + char *rparam=NULL, *rdata=NULL; + char *p; + + ZERO_STRUCTP(sbuf); + + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC); + p += 6; + p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, 0, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */ + sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */ + sbuf->st_blocks /= STAT_ST_BLOCKSIZE; + sbuf->st_ctime = interpret_long_date(rdata + 16); /* time of last change */ + sbuf->st_atime = interpret_long_date(rdata + 24); /* time of last access */ + sbuf->st_mtime = interpret_long_date(rdata + 32); /* time of last modification */ + sbuf->st_uid = IVAL(rdata,40); /* user ID of owner */ + sbuf->st_gid = IVAL(rdata,48); /* group ID of owner */ + sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56)); +#if defined(HAVE_MAKEDEV) + { + uint32 dev_major = IVAL(rdata,60); + uint32 dev_minor = IVAL(rdata,68); + sbuf->st_rdev = makedev(dev_major, dev_minor); + } +#endif + sbuf->st_ino = (SMB_INO_T)IVAL2_TO_SMB_BIG_UINT(rdata,76); /* inode */ + sbuf->st_mode |= wire_perms_to_unix(IVAL(rdata,84)); /* protection */ + sbuf->st_nlink = IVAL(rdata,92); /* number of hard links */ + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + /**************************************************************************** Symlink a file (UNIX extensions). ****************************************************************************/ -- cgit From f128aa2a550f3672b2d12786ab4bf59e6d749c7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 26 Sep 2004 22:16:00 +0000 Subject: r2665: Ensure the UNIX info level returned enough data. Jeremy. (This used to be commit 8a7741dddf17dca136144fb26e2d7a42d313467a) --- source3/libsmb/clifile.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d302206949..144fc4a0c8 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -205,6 +205,12 @@ BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu return False; } + if (data_len < 96) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return False; + } + sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */ sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */ sbuf->st_blocks /= STAT_ST_BLOCKSIZE; -- cgit From 31441aaa137145511a2c09dd540d46876df56701 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 1 Oct 2004 20:34:12 +0000 Subject: r2768: BUG 1519: save the hostname used in the open_printer_ex() for later reuse when filling in the spolss replies (also gets rid of get_called_name() (This used to be commit 57db8ca91f52329c7f8985c04463b6b69015b0c4) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index cee0015e25..0fb6b5bf4b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -991,7 +991,7 @@ static BOOL resolve_ads(const char *name, int name_type, resolve_hosts() when looking up DC's via SRV RR entries in DNS **********************************************************************/ -static BOOL internal_resolve_name(const char *name, int name_type, +BOOL internal_resolve_name(const char *name, int name_type, struct ip_service **return_iplist, int *return_count, const char *resolve_order) { -- cgit From 13720fbb3e4f68fc88c1ae50812273d7a9a79c64 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 1 Oct 2004 20:52:50 +0000 Subject: r2770: oops; internal_resolve_name() should stay static in 3.0 (This used to be commit 316302ca4a79cfc201311e12df71fdbb974c09c4) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0fb6b5bf4b..cee0015e25 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -991,7 +991,7 @@ static BOOL resolve_ads(const char *name, int name_type, resolve_hosts() when looking up DC's via SRV RR entries in DNS **********************************************************************/ -BOOL internal_resolve_name(const char *name, int name_type, +static BOOL internal_resolve_name(const char *name, int name_type, struct ip_service **return_iplist, int *return_count, const char *resolve_order) { -- cgit From 66e689478a700d669a1abfcb272b4191aa528658 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 7 Oct 2004 03:55:39 +0000 Subject: r2834: Netapps can return NT_STATUS_ACCESS_DENIED when trying to return the security descriptor for a file. Return an error in this case instead of panicing trying to unpack a zero length buffer. Found by Brett Funderburg. (This used to be commit 588de0d4a84a5228d0f99f743ad327ad3b70ead1) --- source3/libsmb/clisecdesc.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 2989966f4d..b79ea9d14b 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -53,6 +53,9 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, goto cleanup; } + if (cli_is_error(cli)) + goto cleanup; + prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL); prs_copy_data_in(&pd, rdata, rdata_count); prs_set_offset(&pd,0); -- cgit From b4cf9e95059071df49b34ff8574e48cb96f42da1 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 7 Oct 2004 04:01:18 +0000 Subject: r2835: Since we always have -I. and -I$(srcdir) in CFLAGS, we can get rid of '..' from all #include preprocessor commands. This fixes bugzilla #1880 where OpenVMS gets confused about the '.' characters. (This used to be commit 7f161702fa4916979602cc0295919b541912acd6) --- source3/libsmb/libsmb_cache.c | 2 +- source3/libsmb/libsmb_compat.c | 2 +- source3/libsmb/libsmbclient.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index cb40b4aaa6..caf226c5a6 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -27,7 +27,7 @@ * Define this to get the real SMBCFILE and SMBCSRV structures */ #define _SMBC_INTERNAL -#include "../include/libsmbclient.h" +#include "include/libsmbclient.h" /* * Structure we use if internal caching mechanism is used diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index cc23835ae3..c4be848cc1 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -25,7 +25,7 @@ #include "includes.h" -#include "../include/libsmb_internal.h" +#include "include/libsmb_internal.h" struct smbc_compat_fdlist { SMBCFILE * file; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index e44bdea2d3..2c813a8481 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -24,7 +24,7 @@ #include "includes.h" -#include "../include/libsmb_internal.h" +#include "include/libsmb_internal.h" /* * Internal flags for extended attributes -- cgit From 8f49721fef2dfa66ac13ec7b860a3315019240da Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 11 Oct 2004 00:32:31 +0000 Subject: r2899: Change some #if DEBUG_PASSWORD's to #ifdef DEBUG_PASSWORD. Bugzilla #1903. (This used to be commit 1327d83d902b6a39096d387d734e73d85ed53f85) --- source3/libsmb/ntlm_check.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index 1d02b03e0c..a0ca08fb89 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -63,7 +63,7 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, } -#if DEBUG_PASSWORD +#ifdef DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |\n")); dump_data(100, part_passwd, 16); DEBUGADD(100,("Password from client was |\n")); -- cgit From 3eff1f48d5806aeb0347f13c50e7620bbdc04dd5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 13 Oct 2004 01:40:35 +0000 Subject: r2942: Add client-side support of triggering ads printer publishing over msrpc setprinter calls inside the net-tool. This is usefull to mimic the same queries a windows-client does. At least win2k returns WERR_IO_PENDING when printer is published via setprinter, samba returns WERR_OK but this does not hurt. Guenther (This used to be commit 69b745fb98b8054d1f52e8a3fe3b933fb04336db) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index c6348568cf..96c052c7c5 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -68,6 +68,7 @@ werror_code_struct dos_errs[] = { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, + { "WERR_IO_PENDING", WERR_IO_PENDING }, { NULL, W_ERROR(0) } }; -- cgit From 26c106e0838db54aafddf1e0f7e4781510dbc582 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Thu, 14 Oct 2004 03:19:57 +0000 Subject: r2959: If we want to support writes >= 65536 with cli_write, then it had better return a size_t, not an ssize_t, and we had better left shift the upper part of the write count, not right shift it. (This used to be commit 3eb33fbc64415600d62ff7b1f2edd67d2dac05b4) --- source3/libsmb/clireadwrite.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 3f14e53094..d1a23d36c8 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -318,9 +318,9 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, 0x0008 start of message mode named pipe protocol ****************************************************************************/ -ssize_t cli_write(struct cli_state *cli, - int fnum, uint16 write_mode, - const char *buf, off_t offset, size_t size) +size_t cli_write(struct cli_state *cli, + int fnum, uint16 write_mode, + const char *buf, off_t offset, size_t size) { int bwritten = 0; int issued = 0; @@ -358,7 +358,7 @@ ssize_t cli_write(struct cli_state *cli, break; bwritten += SVAL(cli->inbuf, smb_vwv2); - bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))>>16); + bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))<<16); } while (received < issued && cli_receive_smb(cli)) -- cgit From 2d7cd5375e4e5ddd7ca9cb32f18358bf8ffd44a1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 22 Oct 2004 18:38:57 +0000 Subject: r3138: Fix from Sorin Manolache for memory leak. Jeremy. (This used to be commit b35f48ad8ee63e44c70d0b198ccff39306ebdf74) --- source3/libsmb/libsmbclient.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2c813a8481..2b0115eaaa 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -596,6 +596,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, */ c.port = 445; if (!cli_connect(&c, server_n, &ip)) { + cli_shutdown(&c); errno = ENETUNREACH; return NULL; } -- cgit From 98ed2ecc1c585f1ebe8bef54faf07486ccc8306e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 23 Oct 2004 09:20:02 +0000 Subject: r3143: Allow for multiple DC's to be named as #1c names in lmhosts. Volker (This used to be commit 2af98ec054508055a63552cfdb48cfaf43f76b62) --- source3/libsmb/namequery.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index cee0015e25..2e6842088a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -855,22 +855,35 @@ static BOOL resolve_lmhosts(const char *name, int name_type, fp = startlmhosts(dyn_LMHOSTSFILE); if(fp) { - while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) { - if (strequal(name, lmhost_name) && - ((name_type2 == -1) || (name_type == name_type2)) - ) { - endlmhosts(fp); - if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) { - DEBUG(3,("resolve_lmhosts: malloc fail !\n")); - return False; - } - (*return_iplist)[0].ip = return_ip; - (*return_iplist)[0].port = PORT_NONE; - *return_count = 1; - return True; + while (getlmhostsent(fp, lmhost_name, &name_type2, + &return_ip)) { + + if (!strequal(name, lmhost_name)) + continue; + + if ((name_type2 != -1) && (name_type != name_type2)) + continue; + + *return_iplist = (struct ip_service *) + realloc((*return_iplist), + sizeof(struct ip_service) * + ((*return_count)+1)); + + if ((*return_iplist) == NULL) { + DEBUG(3,("resolve_lmhosts: malloc fail !\n")); + return False; } + + (*return_iplist)[*return_count].ip = return_ip; + (*return_iplist)[*return_count].port = PORT_NONE; + *return_count += 1; + + /* Multiple names only for DC lookup */ + if (name_type != 0x1c) + break; } endlmhosts(fp); + return True; } return False; } -- cgit From 0e1de2d773c274ae2981a69a05c61919b52143ee Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 26 Oct 2004 14:22:37 +0000 Subject: r3264: fix lmhosts lookup so that we don't say we found something when we really didn't (This used to be commit c7036f824627dc555185a52ed95d3e0132babcd8) --- source3/libsmb/namequery.c | 53 +++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 24 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 2e6842088a..cdbc7f758a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -847,6 +847,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, pstring lmhost_name; int name_type2; struct in_addr return_ip; + BOOL result = False; *return_iplist = NULL; *return_count = 0; @@ -854,38 +855,42 @@ static BOOL resolve_lmhosts(const char *name, int name_type, DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type)); fp = startlmhosts(dyn_LMHOSTSFILE); - if(fp) { - while (getlmhostsent(fp, lmhost_name, &name_type2, - &return_ip)) { - if (!strequal(name, lmhost_name)) - continue; + if ( fp == NULL ) + return False; - if ((name_type2 != -1) && (name_type != name_type2)) - continue; + while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) + { - *return_iplist = (struct ip_service *) - realloc((*return_iplist), - sizeof(struct ip_service) * - ((*return_count)+1)); + if (!strequal(name, lmhost_name)) + continue; - if ((*return_iplist) == NULL) { - DEBUG(3,("resolve_lmhosts: malloc fail !\n")); - return False; - } + if ((name_type2 != -1) && (name_type != name_type2)) + continue; - (*return_iplist)[*return_count].ip = return_ip; - (*return_iplist)[*return_count].port = PORT_NONE; - *return_count += 1; + *return_iplist = (struct ip_service *)realloc((*return_iplist), + sizeof(struct ip_service) * ((*return_count)+1)); - /* Multiple names only for DC lookup */ - if (name_type != 0x1c) - break; + if ((*return_iplist) == NULL) { + DEBUG(3,("resolve_lmhosts: malloc fail !\n")); + return False; } - endlmhosts(fp); - return True; + + (*return_iplist)[*return_count].ip = return_ip; + (*return_iplist)[*return_count].port = PORT_NONE; + *return_count += 1; + + /* we found something */ + result = True; + + /* Multiple names only for DC lookup */ + if (name_type != 0x1c) + break; } - return False; + + endlmhosts(fp); + + return result; } -- cgit From e798a6b9fee3874ea7bb2589e1ecc66b3c012353 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 Oct 2004 17:40:28 +0000 Subject: r3294: Fix for SMB signing with 56-bit DES session keys. From Nalin Dahyabhai . Jeremy. (This used to be commit 55d23cb253d869e58bd51cf179c6dc0f3cfab9d2) --- source3/libsmb/smb_signing.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 39131debf5..b02a13c73e 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -255,6 +255,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, const size_t offset_end_of_sig = (smb_ss_field + 8); unsigned char sequence_buf[8]; struct MD5Context md5_ctx; + unsigned char key_buf[16]; /* * Firstly put the sequence number into the first 4 bytes. @@ -276,8 +277,14 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Init(&md5_ctx); /* intialise with the key */ - MD5Update(&md5_ctx, data->mac_key.data, - data->mac_key.length); + /* NB. When making and verifying SMB signatures, Windows apparently + zero-pads the key to 128 bits if it isn't long enough. + From Nalin Dahyabhai */ + MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); + if (data->mac_key.length < sizeof(key_buf)) { + memset(key_buf, 0, sizeof(key_buf)); + MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); + } /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); -- cgit From 13542c7b5058d1fa0817ae9f371e013157b471d0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 Oct 2004 23:50:14 +0000 Subject: r3342: More MIT/Heimdal fixes to allow an enctype to be explicitly set in a krb5_creds struct. Jeremy. (This used to be commit c9b80490128e09442a01dd8ec6f4b453769e82c1) --- source3/libsmb/clikrb5.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index f7f84f1e29..291aa13de0 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -251,6 +251,17 @@ } #endif +void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) +{ +#if defined(HAVE_KRB5_KEYBLOCK_IN_CREDS) + KRB5_KEY_TYPE((&pcreds->keyblock)) = enctype; +#elif defined(HAVE_KRB5_SESSION_IN_CREDS) + KRB5_KEY_TYPE((&pcreds->session)) = enctype; +#else +#error UNKNOWN_KEYBLOCK_MEMBER_IN_KRB5_CREDS_STRUCT +#endif +} + static BOOL ads_cleanup_expired_creds(krb5_context context, krb5_ccache ccache, krb5_creds *credsp) -- cgit From b57feea6d312de778e232f478d768ac5f3552b3e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Oct 2004 00:02:32 +0000 Subject: r3345: More MIT/Heimdal tests for comparing enctypes now. Jeremy. (This used to be commit eefb911d0c66bdee586a86446e16723013f84101) --- source3/libsmb/clikrb5.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 291aa13de0..5aa1668705 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -262,6 +262,20 @@ void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) #endif } +krb5_boolean kerberos_compatible_enctypes(krb5_context context, + krb5_enctype enctype1, + krb5_enctype enctype2) +{ +#if defined(HAVE_KRB5_C_ENCTYPE_COMPARE) + krb5_boolean similar = 0; + + krb5_c_enctype_compare(context, enctype1, enctype2, &similar); + return similar; +#elif defined(HAVE_KRB5_ENCTYPES_COMPATIBLE_KEYS) + return krb5_enctypes_compatible_keys(context, enctype1, enctype2); +#endif +} + static BOOL ads_cleanup_expired_creds(krb5_context context, krb5_ccache ccache, krb5_creds *credsp) -- cgit From 0772ddbae1be394c538f1d3529ea84434eadcf97 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Oct 2004 22:38:10 +0000 Subject: r3377: Merge in first part of modified patch from Nalin Dahyabhai for bug #1717.The rest of the code needed to call this patch has not yet been checked in (that's my next task). This has not yet been tested - I'll do this once the rest of the patch is integrated. Jeremy. (This used to be commit 7565019286cf44f43c8066c005b1cd5c1556435f) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clikrb5.c | 47 ++++++++++++++++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4ff60c1b1c..60691287e6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -757,7 +757,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, int ret; use_in_memory_ccache(); - ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL, NULL); if (ret){ SAFE_FREE(principal); diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5aa1668705..32a50464e0 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -81,7 +81,7 @@ #endif #if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) - int create_kerberos_key_from_string(krb5_context context, + int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, @@ -102,7 +102,7 @@ return ret; } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) - int create_kerberos_key_from_string(krb5_context context, + int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, @@ -123,6 +123,27 @@ __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS #endif +int create_kerberos_key_from_string(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) +{ + krb5_principal salt_princ = NULL; + int ret; + /* + * Check if we've determined that the KDC is salting keys for this + * principal/enctype in a non-obvious way. If it is, try to match + * its behavior. + */ + salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype); + ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype); + if (salt_princ) { + krb5_free_principal(context, salt_princ); + } + return ret; +} + #if defined(HAVE_KRB5_GET_PERMITTED_ENCTYPES) krb5_error_code get_kerberos_allowed_etypes(krb5_context context, krb5_enctype **enctypes) @@ -251,6 +272,17 @@ } #endif +void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) +{ +#if !defined(HAVE_KRB5_FREE_DATA_CONTENTS) + if (pdata->data) { + krb5_free_data_contents(context, pdata); + } +#else + SAFE_FREE(pdata->data); +#endif +} + void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) { #if defined(HAVE_KRB5_KEYBLOCK_IN_CREDS) @@ -262,7 +294,7 @@ void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) #endif } -krb5_boolean kerberos_compatible_enctypes(krb5_context context, +BOOL kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2) { @@ -270,9 +302,9 @@ krb5_boolean kerberos_compatible_enctypes(krb5_context context, krb5_boolean similar = 0; krb5_c_enctype_compare(context, enctype1, enctype2, &similar); - return similar; + return similar ? True : False; #elif defined(HAVE_KRB5_ENCTYPES_COMPATIBLE_KEYS) - return krb5_enctypes_compatible_keys(context, enctype1, enctype2); + return krb5_enctypes_compatible_keys(context, enctype1, enctype2) ? True : False; #endif } @@ -447,10 +479,7 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, *ticket = data_blob(packet.data, packet.length); -/* Hmm, heimdal dooesn't have this - what's the correct call? */ -#ifdef HAVE_KRB5_FREE_DATA_CONTENTS - krb5_free_data_contents(context, &packet); -#endif + kerberos_free_data_contents(context, &packet); failed: -- cgit From cf47845b1c2e83d49f32bdfc455cd9114a234df8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 30 Oct 2004 00:34:58 +0000 Subject: r3379: More merging of kerberos keytab and salting fixes from Nalin Dahyabhai (bugid #1717). Jeremy. (This used to be commit 30b8807cf6d5c3c5b9947a7e841d69f0b22eb019) --- source3/libsmb/clikrb5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 32a50464e0..f81e86abf4 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -77,7 +77,7 @@ pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); } #else - __ERROR__XX__UNKNOWN_ADDRTYPE +#error UNKNOWN_ADDRTYPE #endif #if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) @@ -120,7 +120,7 @@ salt, key); } #else - __ERROR_XX_UNKNOWN_CREATE_KEY_FUNCTIONS +#error UNKNOWN_CREATE_KEY_FUNCTIONS #endif int create_kerberos_key_from_string(krb5_context context, -- cgit From c64df4d7466811b4083827e512e94e1a4cc44900 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 31 Oct 2004 11:20:07 +0000 Subject: r3407: Fix the build (This used to be commit b144ce557f516f62ab802fbb277799b10153c8fb) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index f81e86abf4..af0273853f 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -274,7 +274,7 @@ int create_kerberos_key_from_string(krb5_context context, void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) { -#if !defined(HAVE_KRB5_FREE_DATA_CONTENTS) +#if defined(HAVE_KRB5_FREE_DATA_CONTENTS) if (pdata->data) { krb5_free_data_contents(context, pdata); } -- cgit From 3688bb079e8d817dcfc3b9e5eb9d07e7b95a806f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 1 Nov 2004 19:35:55 +0000 Subject: r3439: Finally fix build for platforms without kerberos. Guenther (This used to be commit 05619cfdbf814e5c79e65934b82424eca00c76c4) --- source3/libsmb/clikrb5.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index af0273853f..5c5584763c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -123,7 +123,7 @@ #error UNKNOWN_CREATE_KEY_FUNCTIONS #endif -int create_kerberos_key_from_string(krb5_context context, + int create_kerberos_key_from_string(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, @@ -272,7 +272,7 @@ int create_kerberos_key_from_string(krb5_context context, } #endif -void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) + void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) { #if defined(HAVE_KRB5_FREE_DATA_CONTENTS) if (pdata->data) { @@ -283,7 +283,7 @@ void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) #endif } -void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) + void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) { #if defined(HAVE_KRB5_KEYBLOCK_IN_CREDS) KRB5_KEY_TYPE((&pcreds->keyblock)) = enctype; @@ -294,7 +294,7 @@ void kerberos_set_creds_enctype(krb5_creds *pcreds, int enctype) #endif } -BOOL kerberos_compatible_enctypes(krb5_context context, + BOOL kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2) { -- cgit From 5ec9dfbf9466bb1d0c0188ec8cd6db4ba9f67f99 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 4 Nov 2004 09:30:13 +0000 Subject: r3525: Fix a memleak Volker (This used to be commit 4c4da26aa19bedcbb52ed3e6d43ca380a7c1603c) --- source3/libsmb/ntlm_check.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index a0ca08fb89..26e4c76fd3 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -93,6 +93,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, uchar value_from_encryption[16]; uchar client_response[16]; DATA_BLOB client_key_data; + BOOL res; if (part_passwd == NULL) { DEBUG(10,("No password set - DISALLOWING access\n")); @@ -146,7 +147,10 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, dump_data(100, value_from_encryption, 16); #endif data_blob_clear_free(&client_key_data); - return (memcmp(value_from_encryption, client_response, 16) == 0); + res = (memcmp(value_from_encryption, client_response, 16) == 0); + if ((!res) && (user_sess_key != NULL)) + data_blob_clear_free(user_sess_key); + return res; } /** -- cgit From e73d23d1badbf76b6f53007fd48105b4e9f39eb1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Nov 2004 23:56:23 +0000 Subject: r3535: Tidy up error reporting. Memory leak with MIT krb5 1.3.5 turns out to be in the kerberos libraries, not in Samba. Now to test with Heimdal. Jeremy (This used to be commit b08e3bf6fb1052285e4efd669d9717d3a617499d) --- source3/libsmb/clikrb5.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5c5584763c..bc52805dff 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -330,13 +330,13 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, we're using creds obtained outside of our exectuable */ if (StrCaseCmp(krb5_cc_get_type(context, ccache), "FILE") == 0) { - DEBUG(5, ("We do not remove creds from a FILE ccache\n")); + DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a FILE ccache\n")); return False; } retval = krb5_cc_remove_cred(context, ccache, 0, credsp); if (retval) { - DEBUG(1, ("krb5_cc_remove_cred failed, err %s\n", + DEBUG(1, ("ads_cleanup_expired_creds: krb5_cc_remove_cred failed, err %s\n", error_message(retval))); /* If we have an error in this, we want to display it, but continue as though we deleted it */ @@ -363,7 +363,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, retval = krb5_parse_name(context, principal, &server); if (retval) { - DEBUG(1,("Failed to parse principal %s\n", principal)); + DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal)); return retval; } @@ -376,7 +376,9 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, } if ((retval = krb5_cc_get_principal(context, ccache, &creds.client))) { - DEBUG(1,("krb5_cc_get_principal failed (%s)\n", + /* This can commonly fail on smbd startup with no ticket in the cache. + * Report at higher level than 1. */ + DEBUG(3,("ads_krb5_mk_req: krb5_cc_get_principal failed (%s)\n", error_message(retval))); goto cleanup_creds; } @@ -384,7 +386,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, while(!creds_ready) { if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { - DEBUG(1,("krb5_get_credentials failed for %s (%s)\n", + DEBUG(1,("ads_krb5_mk_req: krb5_get_credentials failed for %s (%s)\n", principal, error_message(retval))); goto cleanup_creds; } @@ -393,7 +395,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, if ((unsigned)credsp->times.starttime > time(NULL)) { time_t t = time(NULL); int time_offset =(unsigned)credsp->times.starttime-t; - DEBUG(4,("Advancing clock by %d seconds to cope with clock skew\n", time_offset)); + DEBUG(4,("ads_krb5_mk_req: Advancing clock by %d seconds to cope with clock skew\n", time_offset)); krb5_set_real_time(context, t + time_offset + 1, 0); } @@ -401,7 +403,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, creds_ready = True; } - DEBUG(10,("Ticket (%s) in ccache (%s) is valid until: (%s - %d)\n", + DEBUG(10,("ads_krb5_mk_req: Ticket (%s) in ccache (%s) is valid until: (%s - %d)\n", principal, krb5_cc_default_name(context), http_timestring((unsigned)credsp->times.endtime), (unsigned)credsp->times.endtime)); @@ -410,7 +412,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); if (retval) { - DEBUG(1,("krb5_mk_req_extended failed (%s)\n", + DEBUG(1,("ads_krb5_mk_req: krb5_mk_req_extended failed (%s)\n", error_message(retval))); } @@ -446,7 +448,7 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, retval = krb5_init_context(&context); if (retval) { - DEBUG(1,("krb5_init_context failed (%s)\n", + DEBUG(1,("cli_krb5_get_ticket: krb5_init_context failed (%s)\n", error_message(retval))); goto failed; } @@ -456,13 +458,13 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, } if ((retval = krb5_cc_default(context, &ccdef))) { - DEBUG(1,("krb5_cc_default failed (%s)\n", + DEBUG(1,("cli_krb5_get_ticket: krb5_cc_default failed (%s)\n", error_message(retval))); goto failed; } if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { - DEBUG(1,("krb5_set_default_tgs_ktypes failed (%s)\n", + DEBUG(1,("cli_krb5_get_ticket: krb5_set_default_tgs_ktypes failed (%s)\n", error_message(retval))); goto failed; } -- cgit From 8ea9237d82857ecd6111c37d1ce6b9122ff50f44 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Nov 2004 00:57:29 +0000 Subject: r3538: Fix the build with the latest Heimdal code. Jeremy. (This used to be commit 34275bae787762646f02ea1dec19d7b3a9a733a3) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index bc52805dff..068e782207 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -80,7 +80,7 @@ #error UNKNOWN_ADDRTYPE #endif -#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) +#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) && defined(HAVE_KRB5_ENCRYPT_BLOCK) int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, -- cgit From f995b164b98221e224661e370d61ad08dadb2986 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Nov 2004 23:42:12 +0000 Subject: r3713: Implementation of get posix acls in UNIX extensions. Passes valgrind. Need to add printout functions in client and set posix acl in server. SteveF - take a look at this for the cifsfs client ! Once this is working and tested the next step is to write this up for the UNIX extensions spec. documents. Jeremy. (This used to be commit 1bd3f133442a472b4718b94a636f2fec89a2e0dc) --- source3/libsmb/clifile.c | 48 ++++++++++++++++++++++++++++++++++++++ source3/libsmb/clifsinfo.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 144fc4a0c8..b616abd4d2 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -167,6 +167,54 @@ static mode_t unix_filetype_from_wire(uint32 wire_type) } } +/**************************************************************************** + Do a POSIX getfacl (UNIX extensions). +****************************************************************************/ + +BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, char **retbuf) +{ + unsigned int param_len = 0; + unsigned int data_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + char param[sizeof(pstring)+6]; + char *rparam=NULL, *rdata=NULL; + char *p; + + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_QUERY_POSIX_ACL); + p += 6; + p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, 0, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + if (data_len < 6) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return False; + } + + SAFE_FREE(rparam); + *retbuf = rdata; + + return True; +} + /**************************************************************************** Stat a file (UNIX extensions). ****************************************************************************/ diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 00fe189e9a..22c8bff3ba 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -20,6 +20,64 @@ #include "includes.h" +/**************************************************************************** + Get UNIX extensions version info. +****************************************************************************/ + +BOOL cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor, + uint32 *pcaplow, uint32 *pcaphigh) +{ + BOOL ret = False; + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + + setup = TRANSACT2_QFSINFO; + + SSVAL(param,0,SMB_QUERY_CIFS_UNIX_INFO); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + NULL, 0, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count < 12) { + goto cleanup; + } + + *pmajor = SVAL(rdata,0); + *pminor = SVAL(rdata,2); + *pcaplow = IVAL(rdata,4); + *pcaphigh = IVAL(rdata,8); + + /* todo: but not yet needed + * return the other stuff + */ + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) { -- cgit From 1b31f46f22831781b9ec5592da189a5210cfbc45 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Nov 2004 00:35:31 +0000 Subject: r3714: Getfacl now seems to work on files and directories. Next do setfacl and port to Samba4. Jeremy. (This used to be commit 4d52bf7c8b3147dd4f0d3081fbf9a1f5ebd246a1) --- source3/libsmb/clifile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index b616abd4d2..7816ed0fc6 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -171,7 +171,7 @@ static mode_t unix_filetype_from_wire(uint32 wire_type) Do a POSIX getfacl (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, char **retbuf) +BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf) { unsigned int param_len = 0; unsigned int data_len = 0; @@ -211,6 +211,7 @@ BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, char **retbuf) SAFE_FREE(rparam); *retbuf = rdata; + *prb_size = (size_t)data_len; return True; } -- cgit From 24d3605d99513fd0ce11671a40ad3fca8a1caaf5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 18 Nov 2004 11:57:49 +0000 Subject: r3843: If a connection to a DC is requested, open connections simultaeneously to all DCs found. The first one to reply wins. Volker (This used to be commit 84ac54aef2bd56b5c889d3b05b8828aceb8ae00e) --- source3/libsmb/namequery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index cdbc7f758a..fef769314a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1009,9 +1009,9 @@ static BOOL resolve_ads(const char *name, int name_type, resolve_hosts() when looking up DC's via SRV RR entries in DNS **********************************************************************/ -static BOOL internal_resolve_name(const char *name, int name_type, - struct ip_service **return_iplist, - int *return_count, const char *resolve_order) +BOOL internal_resolve_name(const char *name, int name_type, + struct ip_service **return_iplist, + int *return_count, const char *resolve_order) { pstring name_resolve_list; fstring tok; -- cgit From 9604545ed841bd59b4844d9e96094b4193fd1cd5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 20 Nov 2004 20:10:43 +0000 Subject: r3892: Fix "might be used uninitialized" error. Jeremy. (This used to be commit eead77919b05e0a2bed32a4a192dd0d9e6a86008) --- source3/libsmb/ntlmssp_sign.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 2347619e57..ee0f9df024 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -344,6 +344,12 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) recv_sign_const = CLI_SIGN; recv_seal_const = CLI_SEAL; break; + default: + send_sign_const = "unknown role"; + send_seal_const = "unknown role"; + recv_sign_const = "unknown role"; + recv_seal_const = "unknown role"; + break; } calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, -- cgit From 90a18110e9c014ff33977be4656886b093c7e022 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Nov 2004 01:03:23 +0000 Subject: r3931: Fix all "may be used uninitialized" and "shadow" warnings. Jeremy. (This used to be commit 8e979772a640bb4f00f4d72b6a9c837b8ef14333) --- source3/libsmb/libsmbclient.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2b0115eaaa..3dec0c92b4 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1697,7 +1697,7 @@ list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *stat struct smbc_dir_list *dir_list; struct smbc_dirent *dirent; int dirent_type; - int remove = 0; + int do_remove = 0; dirent_type = dir->dir_type; @@ -1714,13 +1714,13 @@ list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *stat for (dir_list = dir->dir_list; dir_list != dir->dir_end; dir_list = dir_list->next) { - if (! remove && + if (! do_remove && strcmp(dir_list->dirent->name, dirent->name) == 0) { /* Duplicate. End end of list need to be removed. */ - remove = 1; + do_remove = 1; } - if (remove && dir_list->next == dir->dir_end) { + if (do_remove && dir_list->next == dir->dir_end) { /* Found the end of the list. Remove it. */ dir->dir_end = dir_list; free(dir_list->next); -- cgit From b9fcb5b961fc4165899487c7cb368ab2d8d15e8a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 29 Nov 2004 19:28:12 +0000 Subject: r4005: Fix for bug #2071 reported by Jason Mader . Use correct enum type for comparisons. Jeremy. (This used to be commit b926480d053e42205e959b9808a6e3bb90db9ce5) --- source3/libsmb/samlogon_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 0105bc08c3..ed2283725c 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -136,7 +136,7 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USE /* so we fill it in since winbindd_getpwnam() makes use of it */ if ( !user->uni_user_name.buffer ) { - init_unistr2( &user->uni_user_name, username, STR_TERMINATE ); + init_unistr2( &user->uni_user_name, username, UNI_STR_TERMINATE ); init_uni_hdr( &user->hdr_user_name, &user->uni_user_name ); } -- cgit From e7a0aabc2e50306983794c79e23daaf92993db7b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Nov 2004 18:58:58 +0000 Subject: r4020: Fix for crash reported by Bård Kalbakk . Don't go fishing for the authorisation data unless we know it's there. Jeremy. (This used to be commit 6f6b4c61e03afb4d35bf6b3ea468fb211d703aa7) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 068e782207..15be8967b8 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -184,7 +184,7 @@ void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) { #if defined(HAVE_KRB5_TKT_ENC_PART2) - if (tkt->enc_part2) + if (tkt->enc_part2 && tkt->enc_part2->authorization_data && tkt->enc_part2->authorization_data[0] && tkt->enc_part2->authorization_data[0]->length) *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, tkt->enc_part2->authorization_data[0]->length); #else -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/libsmb/asn1.c | 10 ++++----- source3/libsmb/clientgen.c | 6 +++--- source3/libsmb/clifile.c | 6 +++--- source3/libsmb/clilist.c | 4 ++-- source3/libsmb/cliquota.c | 8 +++---- source3/libsmb/clireadwrite.c | 4 ++-- source3/libsmb/clitrans.c | 8 +++---- source3/libsmb/conncache.c | 3 +-- source3/libsmb/libsmb_cache.c | 10 ++++----- source3/libsmb/libsmb_compat.c | 2 +- source3/libsmb/libsmbclient.c | 46 ++++++++++++++++++++--------------------- source3/libsmb/namequery.c | 21 +++++++++---------- source3/libsmb/nmblib.c | 17 +++++++-------- source3/libsmb/ntlmssp.c | 4 ++-- source3/libsmb/samlogon_cache.c | 2 +- source3/libsmb/smb_signing.c | 10 ++++----- source3/libsmb/spnego.c | 5 ++--- 17 files changed, 80 insertions(+), 86 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 2807b4e1d3..6db12fc612 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -32,7 +32,7 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) if (data->has_error) return False; if (data->length < data->ofs+len) { uint8 *newp; - newp = Realloc(data->data, data->ofs+len); + newp = SMB_REALLOC(data->data, data->ofs+len); if (!newp) { SAFE_FREE(data->data); data->has_error = True; @@ -58,7 +58,7 @@ BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) struct nesting *nesting; asn1_write_uint8(data, tag); - nesting = (struct nesting *)malloc(sizeof(struct nesting)); + nesting = SMB_MALLOC_P(struct nesting); if (!nesting) { data->has_error = True; return False; @@ -255,7 +255,7 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) data->has_error = True; return False; } - nesting = (struct nesting *)malloc(sizeof(struct nesting)); + nesting = SMB_MALLOC_P(struct nesting); if (!nesting) { data->has_error = True; return False; @@ -350,7 +350,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_end_tag(data); - *OID = strdup(oid_str); + *OID = SMB_STRDUP(oid_str); return !data->has_error; } @@ -380,7 +380,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) data->has_error = True; return False; } - *s = malloc(len+1); + *s = SMB_MALLOC(len+1); if (! *s) { data->has_error = True; return False; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 974ebf91f5..682e0d8b85 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -253,7 +253,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) } if (!cli) { - cli = (struct cli_state *)malloc(sizeof(*cli)); + cli = SMB_MALLOC_P(struct cli_state); if (!cli) return NULL; ZERO_STRUCTP(cli); @@ -275,8 +275,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->timeout = 20000; /* Timeout is in milliseconds. */ cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; - cli->outbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); - cli->inbuf = (char *)malloc(cli->bufsize+SAFETY_MARGIN); + cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); + cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = False; diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 7816ed0fc6..9d20ed3adc 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1351,7 +1351,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) pstring path2; clistr_pull(cli, path2, p, sizeof(path2), len, STR_ASCII); - *tmp_path = strdup(path2); + *tmp_path = SMB_STRDUP(path2); } return SVAL(cli->inbuf,smb_vwv0); @@ -1402,7 +1402,7 @@ static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigne size_t ea_namelen = strlen(ea_name); data_len = 4 + 4 + ea_namelen + 1 + ea_len; - data = malloc(data_len); + data = SMB_MALLOC(data_len); if (!data) { return False; } @@ -1558,7 +1558,7 @@ static BOOL cli_get_ea_list(struct cli_state *cli, goto out; } - ea_list = (struct ea_struct *)talloc(ctx, num_eas*sizeof(struct ea_struct)); + ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); if (!ea_list) { goto out; } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index ab157d48e9..8ab5854c8f 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -282,7 +282,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } /* and add them to the dirlist pool */ - tdl = Realloc(dirlist,dirlist_len + data_len); + tdl = SMB_REALLOC(dirlist,dirlist_len + data_len); if (!tdl) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); @@ -413,7 +413,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, first = False; - tdl = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + tdl = SMB_REALLOC(dirlist,(num_received + received)*DIR_STRUCT_SIZE); if (!tdl) { DEBUG(0,("cli_list_old: failed to expand dirlist")); diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index af8b4422b7..25c36c214f 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -321,12 +321,12 @@ BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST goto cleanup; } - if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) { + if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { DEBUG(0,("talloc_zero() failed\n")); return (-1); } - if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) { + if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { DEBUG(0,("talloc_zero() failed\n")); return (-1); } @@ -379,13 +379,13 @@ BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST goto cleanup; } - if ((tmp_list_ent=(SMB_NTQUOTA_LIST *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_LIST)))==NULL) { + if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { DEBUG(0,("talloc_zero() failed\n")); talloc_destroy(mem_ctx); goto cleanup; } - if ((tmp_list_ent->quotas=(SMB_NTQUOTA_STRUCT *)talloc_zero(mem_ctx,sizeof(SMB_NTQUOTA_STRUCT)))==NULL) { + if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { DEBUG(0,("talloc_zero() failed\n")); talloc_destroy(mem_ctx); goto cleanup; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index d1a23d36c8..3223098820 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -256,8 +256,8 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, BOOL bigoffset = False; if (size > cli->bufsize) { - cli->outbuf = realloc(cli->outbuf, size + 1024); - cli->inbuf = realloc(cli->inbuf, size + 1024); + cli->outbuf = SMB_REALLOC(cli->outbuf, size + 1024); + cli->inbuf = SMB_REALLOC(cli->inbuf, size + 1024); if (cli->outbuf == NULL || cli->inbuf == NULL) return False; cli->bufsize = size + 1024; diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index ae44ca1a77..761741a91b 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -210,7 +210,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, /* allocate it */ if (total_data!=0) { - tdata = Realloc(*data,total_data); + tdata = SMB_REALLOC(*data,total_data); if (!tdata) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); cli_signing_trans_stop(cli); @@ -221,7 +221,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, } if (total_param!=0) { - tparam = Realloc(*param,total_param); + tparam = SMB_REALLOC(*param,total_param); if (!tparam) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); cli_signing_trans_stop(cli); @@ -527,7 +527,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, /* allocate it */ if (total_data) { - tdata = Realloc(*data,total_data); + tdata = SMB_REALLOC(*data,total_data); if (!tdata) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); cli_signing_trans_stop(cli); @@ -538,7 +538,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, } if (total_param) { - tparam = Realloc(*param,total_param); + tparam = SMB_REALLOC(*param,total_param); if (!tparam) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); cli_signing_trans_stop(cli); diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index 15cc75b129..fe863db422 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -115,8 +115,7 @@ void add_failed_connection_entry(const char *domain, const char *server, NTSTATU /* Create negative lookup cache entry for this domain and controller */ - if ( !(fcc = (struct failed_connection_cache *)malloc(sizeof(struct failed_connection_cache))) ) - { + if ( !(fcc = SMB_MALLOC_P(struct failed_connection_cache)) ) { DEBUG(0, ("malloc failed in add_failed_connection_entry!\n")); return; } diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index caf226c5a6..ddb2753523 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -55,7 +55,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, { struct smbc_server_cache * srvcache = NULL; - if (!(srvcache = malloc(sizeof(*srvcache)))) { + if (!(srvcache = SMB_MALLOC_P(struct smbc_server_cache))) { errno = ENOMEM; DEBUG(3, ("Not enough space for server cache allocation\n")); return 1; @@ -65,25 +65,25 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, srvcache->server = new; - srvcache->server_name = strdup(server); + srvcache->server_name = SMB_STRDUP(server); if (!srvcache->server_name) { errno = ENOMEM; goto failed; } - srvcache->share_name = strdup(share); + srvcache->share_name = SMB_STRDUP(share); if (!srvcache->share_name) { errno = ENOMEM; goto failed; } - srvcache->workgroup = strdup(workgroup); + srvcache->workgroup = SMB_STRDUP(workgroup); if (!srvcache->workgroup) { errno = ENOMEM; goto failed; } - srvcache->username = strdup(username); + srvcache->username = SMB_STRDUP(username); if (!srvcache->username) { errno = ENOMEM; goto failed; diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index c4be848cc1..83088a14de 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -73,7 +73,7 @@ static int add_fd(SMBCFILE * file) return -1; } - f = malloc(sizeof(struct smbc_compat_fdlist)); + f = SMB_MALLOC_P(struct smbc_compat_fdlist); if (!f) { errno = ENOMEM; return -1; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3dec0c92b4..df9c4ddcad 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -99,7 +99,7 @@ decode_urlpart(char *segment, size_t sizeof_segment) } /* make a copy of the old one */ - new_usegment = (char*)malloc( old_length * 3 + 1 ); + new_usegment = (char*)SMB_MALLOC( old_length * 3 + 1 ); while( i < old_length ) { int bReencode = False; @@ -671,7 +671,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, * Let's find a free server_fd */ - srv = (SMBCSRV *)malloc(sizeof(*srv)); + srv = SMB_MALLOC_P(SMBCSRV); if (!srv) { errno = ENOMEM; goto failed; @@ -776,7 +776,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, return NULL; } - ipc_srv = (SMBCSRV *)malloc(sizeof(*ipc_srv)); + ipc_srv = SMB_MALLOC_P(SMBCSRV); if (!ipc_srv) { errno = ENOMEM; cli_shutdown(ipc_cli); @@ -871,7 +871,7 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m } else { - file = malloc(sizeof(SMBCFILE)); + file = SMB_MALLOC_P(SMBCFILE); if (!file) { @@ -895,7 +895,7 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m /* Fill in file struct */ file->cli_fd = fd; - file->fname = strdup(fname); + file->fname = SMB_STRDUP(fname); file->srv = srv; file->offset = 0; file->file = True; @@ -1629,7 +1629,7 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint size = sizeof(struct smbc_dirent) + u_name_len + u_comment_len + 1; - dirent = malloc(size); + dirent = SMB_MALLOC(size); if (!dirent) { @@ -1642,7 +1642,7 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint if (dir->dir_list == NULL) { - dir->dir_list = malloc(sizeof(struct smbc_dir_list)); + dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); if (!dir->dir_list) { SAFE_FREE(dirent); @@ -1656,7 +1656,7 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint } else { - dir->dir_end->next = malloc(sizeof(struct smbc_dir_list)); + dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); if (!dir->dir_end->next) { @@ -1835,7 +1835,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) pstrcpy(workgroup, context->workgroup); - dir = malloc(sizeof(*dir)); + dir = SMB_MALLOC_P(SMBCFILE); if (!dir) { @@ -1847,7 +1847,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) ZERO_STRUCTP(dir); dir->cli_fd = 0; - dir->fname = strdup(fname); + dir->fname = SMB_STRDUP(fname); dir->srv = NULL; dir->offset = 0; dir->file = False; @@ -3110,7 +3110,7 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) return True; } - aces = calloc(1+(*the_acl)->num_aces,sizeof(SEC_ACE)); + aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces); memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); @@ -3143,7 +3143,7 @@ static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx, } if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { - owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID)); + owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); if (!owner_sid || !convert_string_to_sid(ipc_cli, pol, numeric, @@ -3155,7 +3155,7 @@ static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx, } if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { - owner_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID)); + owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); if (!owner_sid || !convert_string_to_sid(ipc_cli, pol, False, @@ -3167,7 +3167,7 @@ static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx, } if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { - grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID)); + grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); if (!grp_sid || !convert_string_to_sid(ipc_cli, pol, numeric, @@ -3179,7 +3179,7 @@ static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx, } if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { - grp_sid = (DOM_SID *)calloc(1, sizeof(DOM_SID)); + grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); if (!grp_sid || !convert_string_to_sid(ipc_cli, pol, False, @@ -4273,7 +4273,7 @@ SMBCCTX * smbc_new_context(void) { SMBCCTX * context; - context = malloc(sizeof(SMBCCTX)); + context = SMB_MALLOC_P(SMBCCTX); if (!context) { errno = ENOMEM; return NULL; @@ -4281,7 +4281,7 @@ SMBCCTX * smbc_new_context(void) ZERO_STRUCTP(context); - context->internal = malloc(sizeof(struct smbc_internal_data)); + context->internal = SMB_MALLOC_P(struct smbc_internal_data); if (!context->internal) { errno = ENOMEM; return NULL; @@ -4488,8 +4488,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) */ user = getenv("USER"); /* walk around as "guest" if no username can be found */ - if (!user) context->user = strdup("guest"); - else context->user = strdup(user); + if (!user) context->user = SMB_STRDUP("guest"); + else context->user = SMB_STRDUP(user); } if (!context->netbios_name) { @@ -4498,14 +4498,14 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) * back on constructing our netbios name from our hostname etc */ if (global_myname()) { - context->netbios_name = strdup(global_myname()); + context->netbios_name = SMB_STRDUP(global_myname()); } else { /* * Hmmm, I want to get hostname as well, but I am too lazy for the moment */ pid = sys_getpid(); - context->netbios_name = malloc(17); + context->netbios_name = SMB_MALLOC(17); if (!context->netbios_name) { errno = ENOMEM; return NULL; @@ -4518,11 +4518,11 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) if (!context->workgroup) { if (lp_workgroup()) { - context->workgroup = strdup(lp_workgroup()); + context->workgroup = SMB_STRDUP(lp_workgroup()); } else { /* TODO: Think about a decent default workgroup */ - context->workgroup = strdup("samba"); + context->workgroup = SMB_STRDUP("samba"); } } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index fef769314a..e6868fb373 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -55,7 +55,7 @@ static struct node_status *parse_node_status(char *p, int *num_names, struct nod if (*num_names == 0) return NULL; - ret = (struct node_status *)malloc(sizeof(struct node_status)* (*num_names)); + ret = SMB_MALLOC_ARRAY(struct node_status,*num_names); if (!ret) return NULL; @@ -478,8 +478,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, continue; } - tmp_ip_list = (struct in_addr *)Realloc( ip_list, sizeof( ip_list[0] ) - * ( (*count) + nmb2->answers->rdlength/6 ) ); + tmp_ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr, + (*count) + nmb2->answers->rdlength/6 ); if (!tmp_ip_list) { DEBUG(0,("name_query: Realloc failed.\n")); @@ -655,7 +655,7 @@ static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_add return False; /* copy the ip address; port will be PORT_NONE */ - if ( (*return_iplist = (struct ip_service*)malloc(count*sizeof(struct ip_service))) == NULL ) { + if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) { DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count )); return False; } @@ -868,8 +868,8 @@ static BOOL resolve_lmhosts(const char *name, int name_type, if ((name_type2 != -1) && (name_type != name_type2)) continue; - *return_iplist = (struct ip_service *)realloc((*return_iplist), - sizeof(struct ip_service) * ((*return_count)+1)); + *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service, + (*return_count)+1); if ((*return_iplist) == NULL) { DEBUG(3,("resolve_lmhosts: malloc fail !\n")); @@ -919,7 +919,7 @@ static BOOL resolve_hosts(const char *name, int name_type, if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { struct in_addr return_ip; putip((char *)&return_ip,(char *)hp->h_addr); - *return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service)); + *return_iplist = SMB_MALLOC_P(struct ip_service); if(*return_iplist == NULL) { DEBUG(3,("resolve_hosts: malloc fail !\n")); return False; @@ -958,7 +958,7 @@ static BOOL resolve_ads(const char *name, int name_type, return False; count = count_chars(list, ' ') + 1; - if ( (*return_iplist = malloc(count * sizeof(struct ip_service))) == NULL ) { + if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) { DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count )); return False; } @@ -1029,7 +1029,7 @@ BOOL internal_resolve_name(const char *name, int name_type, if (allzeros || allones || is_address) { - if ( (*return_iplist = (struct ip_service *)malloc(sizeof(struct ip_service))) == NULL ) { + if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) { DEBUG(0,("internal_resolve_name: malloc fail !\n")); return False; } @@ -1333,8 +1333,7 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, return False; } - if ( (return_iplist = (struct ip_service *) - malloc(num_addresses * sizeof(struct ip_service))) == NULL ) { + if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { DEBUG(3,("get_dc_list: malloc fail !\n")); return False; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7f22ce0096..1c93f7b1e2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -354,7 +354,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, { int i; - *recs = (struct res_rec *)malloc(sizeof(**recs)*count); + *recs = SMB_MALLOC_ARRAY(struct res_rec, count); if (!*recs) return(False); @@ -557,7 +557,7 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) struct nmb_packet *copy_nmb; struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) { DEBUG(0,("copy_nmb_packet: malloc fail.\n")); return NULL; } @@ -580,22 +580,19 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) /* Now copy any resource records. */ if (nmb->answers) { - if((copy_nmb->answers = (struct res_rec *) - malloc(nmb->header.ancount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->answers = SMB_MALLOC_ARRAY(struct res_rec,nmb->header.ancount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->answers, (char *)nmb->answers, nmb->header.ancount * sizeof(struct res_rec)); } if (nmb->nsrecs) { - if((copy_nmb->nsrecs = (struct res_rec *) - malloc(nmb->header.nscount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.nscount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, nmb->header.nscount * sizeof(struct res_rec)); } if (nmb->additional) { - if((copy_nmb->additional = (struct res_rec *) - malloc(nmb->header.arcount * sizeof(struct res_rec))) == NULL) + if((copy_nmb->additional = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.arcount)) == NULL) goto free_and_exit; memcpy((char *)copy_nmb->additional, (char *)nmb->additional, nmb->header.arcount * sizeof(struct res_rec)); @@ -622,7 +619,7 @@ static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) { struct packet_struct *pkt_copy; - if(( pkt_copy = (struct packet_struct *)malloc(sizeof(*packet))) == NULL) { + if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) { DEBUG(0,("copy_dgram_packet: malloc fail.\n")); return NULL; } @@ -700,7 +697,7 @@ struct packet_struct *parse_packet(char *buf,int length, struct packet_struct *p; BOOL ok=False; - p = (struct packet_struct *)malloc(sizeof(*p)); + p = SMB_MALLOC_P(struct packet_struct); if (!p) return(NULL); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 6e41a61bf1..eb1fce5439 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -766,7 +766,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) mem_ctx = talloc_init("NTLMSSP context"); - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + *ntlmssp_state = TALLOC_ZERO_P(mem_ctx, NTLMSSP_STATE); if (!*ntlmssp_state) { DEBUG(0,("ntlmssp_server_start: talloc failed!\n")); talloc_destroy(mem_ctx); @@ -1075,7 +1075,7 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) mem_ctx = talloc_init("NTLMSSP Client context"); - *ntlmssp_state = talloc_zero(mem_ctx, sizeof(**ntlmssp_state)); + *ntlmssp_state = TALLOC_ZERO_P(mem_ctx, NTLMSSP_STATE); if (!*ntlmssp_state) { DEBUG(0,("ntlmssp_client_start: talloc failed!\n")); talloc_destroy(mem_ctx); diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index ed2283725c..fdfc92a750 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -188,7 +188,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user if ( data.dptr ) { - if ( (user = (NET_USER_INFO_3*)malloc(sizeof(NET_USER_INFO_3))) == NULL ) + if ( (user = SMB_MALLOC_P(NET_USER_INFO_3)) == NULL ) return NULL; prs_init( &ps, 0, mem_ctx, UNMARSHALL ); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index b02a13c73e..df69ff3e41 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -54,7 +54,7 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, } } - t = smb_xmalloc(sizeof(*t)); + t = SMB_XMALLOC_P(struct outstanding_packet_lookup); ZERO_STRUCTP(t); t->mid = mid; @@ -459,7 +459,7 @@ BOOL cli_simple_set_signing(struct cli_state *cli, return False; } - data = smb_xmalloc(sizeof(*data)); + data = SMB_XMALLOC_P(struct smb_basic_signing_context); memset(data, '\0', sizeof(*data)); cli->sign_info.signing_context = data; @@ -509,7 +509,7 @@ void cli_signing_trans_start(struct cli_state *cli, uint16 mid) if (!cli->sign_info.doing_signing || !data) return; - data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + data->trans_info = SMB_XMALLOC_P(struct trans_info_context); ZERO_STRUCTP(data->trans_info); /* This ensures the sequence is pulled off the outstanding packet list */ @@ -982,7 +982,7 @@ void srv_signing_trans_start(uint16 mid) if (!data) return; - data->trans_info = smb_xmalloc(sizeof(struct trans_info_context)); + data->trans_info = SMB_XMALLOC_P(struct trans_info_context); ZERO_STRUCTP(data->trans_info); data->trans_info->reply_seq_num = data->send_seq_num-1; @@ -1051,7 +1051,7 @@ void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) srv_sign_info.doing_signing = True; - data = smb_xmalloc(sizeof(*data)); + data = SMB_XMALLOC_P(struct smb_basic_signing_context); memset(data, '\0', sizeof(*data)); srv_sign_info.signing_context = data; diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 50caf7b4c0..a0f5565d4f 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -42,12 +42,11 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = malloc(sizeof(*token->mechTypes)); + token->mechTypes = SMB_MALLOC_P(char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = - realloc(token->mechTypes, (i + 2) * - sizeof(*token->mechTypes)); + SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2); asn1_read_OID(asn1, token->mechTypes + i); } token->mechTypes[i] = NULL; -- cgit From 5b713a206bf9c05faad750512886f4bbeebb21f8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Dec 2004 00:25:11 +0000 Subject: r4186: Fix client & server to allow 127k READX calls. Jeremy. (This used to be commit 831cb21a874601e4536c2cf76c5351e1d0defcb5) --- source3/libsmb/cliconnect.c | 15 +++++++++------ source3/libsmb/clireadwrite.c | 8 +++++++- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 60691287e6..29a9533bd2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -151,12 +151,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) if (cli->use_level_II_oplocks) capabilities |= CAP_LEVEL_II_OPLOCKS; - if (cli->capabilities & CAP_UNICODE) - capabilities |= CAP_UNICODE; - - if (cli->capabilities & CAP_LARGE_FILES) - capabilities |= CAP_LARGE_FILES; - + capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX)); return capabilities; } @@ -1134,6 +1129,14 @@ BOOL cli_negprot(struct cli_state *cli) cli->sign_info.negotiated_smb_signing = True; } + if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) { + SAFE_FREE(cli->outbuf); + SAFE_FREE(cli->inbuf); + cli->outbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); + cli->inbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); + cli->bufsize = CLI_MAX_LARGE_READX_SIZE; + } + } else if (cli->protocol >= PROTOCOL_LANMAN1) { cli->use_spnego = False; cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 3223098820..64f16e94ca 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -48,6 +48,7 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SIVAL(cli->outbuf,smb_vwv3,offset); SSVAL(cli->outbuf,smb_vwv5,size); SSVAL(cli->outbuf,smb_vwv6,size); + SSVAL(cli->outbuf,smb_vwv7,((size >> 16) & 1)); SSVAL(cli->outbuf,smb_mid,cli->mid + i); if (bigoffset) @@ -75,7 +76,11 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ * rounded down to a multiple of 1024. */ - readsize = (cli->max_xmit - (smb_size+32)) & ~1023; + if (cli->capabilities & CAP_LARGE_READX) { + readsize = CLI_MAX_LARGE_READX_SIZE; + } else { + readsize = (cli->max_xmit - (smb_size+32)) & ~1023; + } while (total < size) { readsize = MIN(readsize, size-total); @@ -117,6 +122,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ } size2 = SVAL(cli->inbuf, smb_vwv5); + size2 |= (SVAL(cli->inbuf, smb_vwv7) & 1); if (size2 > readsize) { DEBUG(5,("server returned more than we wanted!\n")); -- cgit From 4730a56263b0547faabbfadb845e8b92bd0b9441 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Dec 2004 00:33:53 +0000 Subject: r4188: Ensure we add in the upper length in the right place ! Jeremy. (This used to be commit 9d4e57f06c4f75f42036e91401b0d0392647752b) --- source3/libsmb/clireadwrite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 64f16e94ca..1785905ff2 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -122,7 +122,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ } size2 = SVAL(cli->inbuf, smb_vwv5); - size2 |= (SVAL(cli->inbuf, smb_vwv7) & 1); + size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7) & 1)) << 16); if (size2 > readsize) { DEBUG(5,("server returned more than we wanted!\n")); -- cgit From 9e3453459c9166e71f483d67c04be2e49da6c561 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Dec 2004 01:25:24 +0000 Subject: r4212: Ensure we only look at the bottom bit of large_readx. Set the 14 word version of write if size > 0xffff as well as 64-bit offset. Jeremy. (This used to be commit 94779ccb39560bf5eecab77d70f1fa04bfcf1456) --- source3/libsmb/clireadwrite.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 1785905ff2..9e52ed3594 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -259,7 +259,7 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { char *p; - BOOL bigoffset = False; + BOOL large_writex = False; if (size > cli->bufsize) { cli->outbuf = SMB_REALLOC(cli->outbuf, size + 1024); @@ -272,10 +272,11 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - if ((SMB_BIG_UINT)offset >> 32) - bigoffset = True; + if (((SMB_BIG_UINT)offset >> 32) || (size > 0xFFFF)) { + large_writex = True; + } - if (bigoffset) + if (large_writex) set_message(cli->outbuf,14,0,True); else set_message(cli->outbuf,12,0,True); @@ -303,7 +304,7 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); - if (bigoffset) + if (large_writex) SIVAL(cli->outbuf,smb_vwv12,(offset>>32) & 0xffffffff); p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); -- cgit From b46913fb95d59f3ec8e7e71da758cd16cda05f2c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Dec 2004 21:14:28 +0000 Subject: r4291: More *alloc fixes inspired by Albert Chin (china@thewrittenword.com). Jeremy (This used to be commit efc1b688cf9b1a17f1a6bf46d481280ed8bd0c46) --- source3/libsmb/clikrb5.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 15be8967b8..66c16b69ae 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -233,7 +233,7 @@ return -1; } - sa = malloc( sizeof(struct sockaddr) * num_kdcs ); + sa = SMB_MALLOC_ARRAY( struct sockaddr, num_kdcs ); if (!sa) { DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); krb5_krbhst_free(ctx, hnd); @@ -241,8 +241,7 @@ return -1; } - *addr_pp = malloc(sizeof(struct sockaddr) * num_kdcs); - memset(*addr_pp, '\0', sizeof(struct sockaddr) * num_kdcs ); + memset(sa, '\0', sizeof(struct sockaddr) * num_kdcs ); for (i = 0; i < num_kdcs && (rc = krb5_krbhst_next(ctx, hnd, &hinfo) == 0); i++) { -- cgit From c85d9e735c8294088203f1656ae07a4b0835292c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 6 Jan 2005 15:35:02 +0000 Subject: r4570: Replace cli->nt_pipe_fnum with an array of NT file numbers, one for each supported pipe. Netlogon is still special, as we open that twice, one to do the auth2, the other one with schannel. The client interface is completely unchanged for those who only use a single pie. cli->pipe_idx is used as the index for everything except the "real" client rpc calls, which have been explicitly converted in my last commit. Next step is to get winbind to just use a single smb connection for multiple pipes. Volker (This used to be commit dc294c52e0216424236057ca6cd35e1ebf51d0da) --- source3/libsmb/clientgen.c | 16 +++++++++++----- source3/libsmb/clitrans.c | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 682e0d8b85..39fe91172d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -245,6 +245,7 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; + int i; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -315,7 +316,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) /* initialise signing */ cli_null_set_signing(cli); - cli->nt_pipe_fnum = 0; + for (i=0; int_pipe_fnum[i] = 0; + cli->saved_netlogon_pipe_fnum = 0; cli->initialised = 1; @@ -344,14 +347,17 @@ close the session void cli_nt_session_close(struct cli_state *cli) { + int i; + if (cli->ntlmssp_pipe_state) { ntlmssp_end(&cli->ntlmssp_pipe_state); } - if (cli->nt_pipe_fnum != 0) - cli_close(cli, cli->nt_pipe_fnum); - - cli->nt_pipe_fnum = 0; + for (i=0; int_pipe_fnum[i] != 0) + cli_close(cli, cli->nt_pipe_fnum[i]); + cli->nt_pipe_fnum[i] = 0; + } cli->pipe_idx = -1; } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 761741a91b..3f1afa75d6 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -504,7 +504,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, */ if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if (cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + if (cli->nt_pipe_fnum[cli->pipe_idx] == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { cli_signing_trans_stop(cli); return(False); } @@ -638,7 +638,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, } if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + if(cli->nt_pipe_fnum[cli->pipe_idx] == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { cli_signing_trans_stop(cli); return(False); } -- cgit From 6f56a5be2e7e9259f020dd20c37d79f8f95c3815 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 22 Jan 2005 01:22:39 +0000 Subject: r4917: Merge some of Derrell.Lipman@UnwiredUniverse.com obvious fixes. Added text explaining units in pdbedit time fields. Jeremy. (This used to be commit 3d09c15d8f06ad06fae362291a6c986f7b6107e6) --- source3/libsmb/cliconnect.c | 7 ++++++- source3/libsmb/clisecdesc.c | 9 +++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 29a9533bd2..659e124292 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -989,7 +989,12 @@ BOOL cli_tdis(struct cli_state *cli) if (!cli_receive_smb(cli)) return False; - return !cli_is_error(cli); + if (cli_is_error(cli)) { + return False; + } + + cli->cnum = -1; + return True; } /**************************************************************************** diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index b79ea9d14b..2475743479 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -30,6 +30,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; prs_struct pd; + BOOL pd_initialized = False; SEC_DESC *psd = NULL; SIVAL(param, 0, fnum); @@ -56,7 +57,10 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, if (cli_is_error(cli)) goto cleanup; - prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL); + if (!prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL)) { + goto cleanup; + } + pd_initialized = True; prs_copy_data_in(&pd, rdata, rdata_count); prs_set_offset(&pd,0); @@ -70,7 +74,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, SAFE_FREE(rparam); SAFE_FREE(rdata); - prs_mem_free(&pd); + if (pd_initialized) + prs_mem_free(&pd); return psd; } -- cgit From c24c328a9e006473f4dba49fdf1842fb28952ec7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Jan 2005 20:21:15 +0000 Subject: r4970: Fix for bug 2092, allowing fallback after kerberos and allow gnome vfs to prevent auto-anonymous logon. Jeremy. (This used to be commit 843e85bcd978d025964c4d45d9a3886c7cf7f63c) --- source3/libsmb/cliconnect.c | 8 ++++++-- source3/libsmb/libsmbclient.c | 12 ++++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 659e124292..bffe9dfe8a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -757,13 +757,17 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, if (ret){ SAFE_FREE(principal); DEBUG(0, ("Kinit failed: %s\n", error_message(ret))); + if (cli->fallback_after_kerberos) + goto ntlmssp; return ADS_ERROR_KRB5(ret); } } rc = cli_session_setup_kerberos(cli, principal, domain); - SAFE_FREE(principal); - return rc; + if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) { + SAFE_FREE(principal); + return rc; + } } #endif diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index df9c4ddcad..8eeadc8a78 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -584,6 +584,13 @@ SMBCSRV *smbc_server(SMBCCTX *context, return NULL; } + if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { + c.use_kerberos = True; + } + if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { + c.fallback_after_kerberos = True; + } + c.timeout = context->timeout; /* Force use of port 139 for first try, so browse lists can work */ @@ -648,8 +655,9 @@ SMBCSRV *smbc_server(SMBCCTX *context, password, strlen(password), password, strlen(password), workgroup) && - /* try an anonymous login if it failed */ - !cli_session_setup(&c, "", "", 1,"", 0, workgroup)) { + /* Try an anonymous login if it failed and this was allowed by flags. */ + ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || + !cli_session_setup(&c, "", "", 1,"", 0, workgroup))) { cli_shutdown(&c); errno = EPERM; return NULL; -- cgit From 26dd1bab968d37d9cf9315ead3a71aad759682bb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 7 Feb 2005 22:42:43 +0000 Subject: r5272: BUG 2132, 2134: patch from Jason Mader to remove unused variables (This used to be commit 82c4e2f37f1f4c581cd7c792808c9a81ef80db94) --- source3/libsmb/ntlmssp.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index eb1fce5439..ec3186255a 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -442,13 +442,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This creates the 'blob' of names that appears at the end of the packet */ if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { - const char *target_name_dns = ""; - if (chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN) { - target_name_dns = dnsdomname; - } else if (chal_flags |= NTLMSSP_TARGET_TYPE_SERVER) { - target_name_dns = dnsname; - } - msrpc_gen(&struct_blob, "aaaaa", NTLMSSP_NAME_TYPE_DOMAIN, target_name, NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(), -- cgit From 4e8c17d98589c2983b6a4efdbe0563cbb8ab4e19 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 17 Feb 2005 15:32:19 +0000 Subject: r5432: compile fixes from Jason Mader -- BUGS 2340 (This used to be commit 3fd86a1f9d5b63aa066aed3347209913cdf782a8) --- source3/libsmb/ntlmssp_sign.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index ee0f9df024..b810597076 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -53,7 +53,7 @@ static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) hash[257] = index_j; } -static void calc_hash(unsigned char hash[258], const char *k2, int k2l) +static void calc_hash(unsigned char hash[258], unsigned char *k2, int k2l) { unsigned char j = 0; int ind; @@ -390,7 +390,7 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n")); - calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 8); + calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 8); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } else { @@ -402,7 +402,7 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n")); - calc_hash(ntlmssp_state->ntlmssp_hash, (const char *)(ntlmssp_state->session_key.data), 16); + calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 16); dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, sizeof(ntlmssp_state->ntlmssp_hash)); } -- cgit From acdf1aa308df48654e63b7072c47e8696ec670b9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 19 Feb 2005 09:27:06 +0000 Subject: r5455: Remove bogus DEBUG messages (dump for a failure to parse NTLMSSP, before trying the alternate format). This only caused confusion and bug reports... Andrew Bartlett (This used to be commit 5cb02b569b39aa7a9dc6692a79ff1d1dfa69aee6) --- source3/libsmb/ntlmssp.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index ec3186255a..4d9aaf989b 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -393,7 +393,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, &neg_flags, &cliname, &domname)) { - DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP:\n")); + DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate:\n")); dump_data(2, (const char *)request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } @@ -539,8 +539,6 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &workstation, &encrypted_session_key, &auth_flags)) { - DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); - dump_data(2, (const char *)request.data, request.length); SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); @@ -563,7 +561,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &domain, &user, &workstation)) { - DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP:\n")); + DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n")); dump_data(2, (const char *)request.data, request.length); SAFE_FREE(domain); SAFE_FREE(user); -- cgit From 37ea9da1fdf7eac31bb0d7ced407d49e3f5900bc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Feb 2005 03:31:22 +0000 Subject: r5495: * add in some code from Mike Nix for the SMBsplopen and SMBsplclose commands (BUG 2010) * clarify some debug messages in smbspool (also from Mike) my changes: * start adding msdfs client routines * enable smbclient to maintain multiple connections * set the CAP_DFS flag for our internal clienht routines. I actualy have a dfs referral working in do_cd() but that code is too ugly to live so I'm not checking it in just yet. Further work is to merge with vl's changes in trunk to support multiple TIDs per cli_state *. (This used to be commit 0449756309812d854037ba0af631abad678e670e) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clidfs.c | 154 ++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/clientgen.c | 4 +- source3/libsmb/cliprint.c | 105 ++++++++++++++++++++++++++++++ 4 files changed, 263 insertions(+), 2 deletions(-) create mode 100644 source3/libsmb/clidfs.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index bffe9dfe8a..fa98d55f25 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -151,7 +151,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) if (cli->use_level_II_oplocks) capabilities |= CAP_LEVEL_II_OPLOCKS; - capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX)); + capabilities |= (cli->capabilities & (CAP_UNICODE|CAP_LARGE_FILES|CAP_LARGE_READX|CAP_LARGE_WRITEX|CAP_DFS)); return capabilities; } diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c new file mode 100644 index 0000000000..bb82fbfabb --- /dev/null +++ b/source3/libsmb/clidfs.c @@ -0,0 +1,154 @@ +/* + Unix SMB/CIFS implementation. + client connect/disconnect routines + Copyright (C) Gerald (Jerry) Carter + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + +/******************************************************************** + check for dfs referral +********************************************************************/ + +BOOL check_for_dfs_referral( struct cli_state *cli ) +{ + uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); + + /* only deal with DS when we negotiated NT_STATUS codes and UNICODE */ + + if ( !( (flgs2&FLAGS2_32_BIT_ERROR_CODES) && (flgs2&FLAGS2_UNICODE_STRINGS) ) ) + return False; + + if ( NT_STATUS_EQUAL( NT_STATUS_PATH_NOT_COVERED, NT_STATUS(IVAL(cli->inbuf,smb_rcls)) ) ) + return True; + + return False; +} + +/******************************************************************** + split a dfs path into the server and share name components +********************************************************************/ + +void split_dfs_path( const char *nodepath, fstring server, fstring share ) +{ + char *p; + pstring path; + + pstrcpy( path, nodepath ); + + if ( path[0] != '\\' ) + return; + + p = strrchr_m( path, '\\' ); + + if ( !p ) + return; + + *p = '\0'; + p++; + + fstrcpy( share, p ); + fstrcpy( server, &path[1] ); +} + +/******************************************************************** + get the dfs referral link +********************************************************************/ + +BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, + struct referral **refs, size_t *num_refs) +{ + unsigned int data_len = 0; + unsigned int param_len = 0; + uint16 setup = TRANSACT2_GET_DFS_REFERRAL; + char param[sizeof(pstring)+2]; + pstring data; + char *rparam=NULL, *rdata=NULL; + char *p; + size_t pathlen = 2*(strlen(path)+1); + uint16 num_referrals; + struct referral *referrals; + + memset(param, 0, sizeof(param)); + SSVAL(param, 0, 0x03); /* max referral level */ + p = ¶m[2]; + + p += clistr_push(cli, p, path, MIN(pathlen, sizeof(param)-2), STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + num_referrals = SVAL( rdata, 2 ); + + if ( num_referrals != 0 ) { + uint16 ref_version; + uint16 ref_size; + int i; + uint16 node_offset; + + + referrals = SMB_XMALLOC_ARRAY( struct referral, num_referrals ); + + /* start at the referrals array */ + + p = rdata+8; + for ( i=0; icapabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; + if (cli->capabilities & CAP_DFS) + flags2 |= FLAGS2_DFS_PATHNAMES; if (cli->capabilities & CAP_STATUS32) flags2 |= FLAGS2_32_BIT_ERROR_CODES; if (cli->use_spnego) @@ -283,7 +285,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->use_spnego = lp_client_use_spnego(); - cli->capabilities = CAP_UNICODE | CAP_STATUS32; + cli->capabilities = CAP_UNICODE | CAP_STATUS32 | CAP_DFS; /* Set the CLI_FORCE_DOSERR environment variable to test client routines using DOS errors instead of STATUS32 diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 2fb0e59aca..732241a758 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -156,3 +156,108 @@ int cli_printjob_del(struct cli_state *cli, int job) } +/**************************************************************************** + Open a spool file +****************************************************************************/ + +int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_mode) +{ + char *p; + unsigned openfn=0; + unsigned accessmode=0; + + if (flags & O_CREAT) + openfn |= (1<<4); + if (!(flags & O_EXCL)) { + if (flags & O_TRUNC) + openfn |= (1<<1); + else + openfn |= (1<<0); + } + + accessmode = (share_mode<<4); + + if ((flags & O_ACCMODE) == O_RDWR) { + accessmode |= 2; + } else if ((flags & O_ACCMODE) == O_WRONLY) { + accessmode |= 1; + } + +#if defined(O_SYNC) + if ((flags & O_SYNC) == O_SYNC) { + accessmode |= (1<<14); + } +#endif /* O_SYNC */ + + if (share_mode == DENY_FCB) { + accessmode = 0xFF; + } + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,15,0,True); + + SCVAL(cli->outbuf,smb_com,SMBsplopen); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ + SSVAL(cli->outbuf,smb_vwv3,accessmode); + SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv5,0); + SSVAL(cli->outbuf,smb_vwv8,openfn); + + if (cli->use_oplocks) { + /* if using oplocks then ask for a batch oplock via + core and extended methods */ + SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)| + FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK); + SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); + } + + p = smb_buf(cli->outbuf); + p += clistr_push(cli, p, fname, -1, STR_TERMINATE); + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return -1; + } + + if (cli_is_error(cli)) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2); +} + +/**************************************************************************** + Close a file. +****************************************************************************/ + +BOOL cli_spl_close(struct cli_state *cli, int fnum) +{ + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,3,0,True); + + SCVAL(cli->outbuf,smb_com,SMBsplclose); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SIVALS(cli->outbuf,smb_vwv1,-1); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + return !cli_is_error(cli); +} + + -- cgit From 01b87c63c90083dbb7a56d038f714bde1a49fb2a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Feb 2005 17:29:28 +0000 Subject: r5518: Add initial msdfs support to smbclient. Currently I can only cd up and down the tree and get directory listings. Still have to figure out how to get a directory listing on a 2k dfs root. Also have to work out some issues with relative paths that cross dfs mount points. We're protected from the new code paths when connecting to a non-dfs root share ( the flag from the tcon&X is stored in the struct cli_state* ) (This used to be commit e57fd2c5f00de2b11a2b44374830e89a90bc0022) --- source3/libsmb/cliconnect.c | 3 + source3/libsmb/clidfs.c | 257 +++++++++++++++++++++++++++++++++++++++----- source3/libsmb/clirap.c | 59 +++++++++- 3 files changed, 290 insertions(+), 29 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index fa98d55f25..01a92a89ba 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -972,6 +972,9 @@ BOOL cli_send_tconX(struct cli_state *cli, /* almost certainly win95 - enable bug fixes */ cli->win95 = True; } + + if ( cli->protocol >= PROTOCOL_LANMAN2 ) + cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS); cli->cnum = SVAL(cli->inbuf,smb_tid); return True; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index bb82fbfabb..ea66eba998 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -1,8 +1,8 @@ /* Unix SMB/CIFS implementation. client connect/disconnect routines - Copyright (C) Gerald (Jerry) Carter - + Copyright (C) Gerald (Jerry) Carter 2004 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or @@ -22,30 +22,12 @@ #include "includes.h" -/******************************************************************** - check for dfs referral -********************************************************************/ - -BOOL check_for_dfs_referral( struct cli_state *cli ) -{ - uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); - - /* only deal with DS when we negotiated NT_STATUS codes and UNICODE */ - - if ( !( (flgs2&FLAGS2_32_BIT_ERROR_CODES) && (flgs2&FLAGS2_UNICODE_STRINGS) ) ) - return False; - - if ( NT_STATUS_EQUAL( NT_STATUS_PATH_NOT_COVERED, NT_STATUS(IVAL(cli->inbuf,smb_rcls)) ) ) - return True; - - return False; -} /******************************************************************** split a dfs path into the server and share name components ********************************************************************/ -void split_dfs_path( const char *nodepath, fstring server, fstring share ) +static void split_dfs_path( const char *nodepath, fstring server, fstring share ) { char *p; pstring path; @@ -67,12 +49,112 @@ void split_dfs_path( const char *nodepath, fstring server, fstring share ) fstrcpy( server, &path[1] ); } +/**************************************************************************** + return the original path truncated at the first wildcard character + (also strips trailing \'s). Trust the caller to provide a NULL + terminated string +****************************************************************************/ + +static void clean_path( pstring clean, const char *path ) +{ + int len; + char *p; + pstring newpath; + + pstrcpy( newpath, path ); + p = newpath; + + while ( p ) { + /* first check for '*' */ + + p = strrchr_m( newpath, '*' ); + if ( p ) { + *p = '\0'; + p = newpath; + continue; + } + + /* first check for '?' */ + + p = strrchr_m( newpath, '?' ); + if ( p ) { + *p = '\0'; + p = newpath; + } + } + + /* strip a trailing backslash */ + + len = strlen( newpath ); + if ( newpath[len-1] == '\\' ) + newpath[len-1] = '\0'; + + pstrcpy( clean, newpath ); +} + +/**************************************************************************** +****************************************************************************/ + +static BOOL make_full_path( pstring path, const char *server, const char *share, + const char *dir ) +{ + pstring servicename; + char *sharename; + const char *directory; + + + /* make a copy so we don't modify the global string 'service' */ + + pstrcpy(servicename, share); + sharename = servicename; + + if (*sharename == '\\') { + + server = sharename+2; + sharename = strchr_m(server,'\\'); + + if (!sharename) + return False; + + *sharename = 0; + sharename++; + } + + directory = dir; + if ( *directory == '\\' ) + directory++; + + pstr_sprintf( path, "\\%s\\%s\\%s", server, sharename, directory ); + + return True; +} + +/******************************************************************** + check for dfs referral +********************************************************************/ + +static BOOL cli_dfs_check_error( struct cli_state *cli ) +{ + uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); + + /* only deal with DS when we negotiated NT_STATUS codes and UNICODE */ + + if ( !( (flgs2&FLAGS2_32_BIT_ERROR_CODES) && (flgs2&FLAGS2_UNICODE_STRINGS) ) ) + return False; + + if ( NT_STATUS_EQUAL( NT_STATUS_PATH_NOT_COVERED, NT_STATUS(IVAL(cli->inbuf,smb_rcls)) ) ) + return True; + + return False; +} + /******************************************************************** get the dfs referral link ********************************************************************/ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, - struct referral **refs, size_t *num_refs) + CLIENT_DFS_REFERRAL**refs, size_t *num_refs, + uint16 *consumed) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -83,7 +165,7 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, char *p; size_t pathlen = 2*(strlen(path)+1); uint16 num_referrals; - struct referral *referrals; + CLIENT_DFS_REFERRAL *referrals; memset(param, 0, sizeof(param)); SSVAL(param, 0, 0x03); /* max referral level */ @@ -108,6 +190,7 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, return False; } + *consumed = SVAL( rdata, 0 ); num_referrals = SVAL( rdata, 2 ); if ( num_referrals != 0 ) { @@ -117,7 +200,7 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, uint16 node_offset; - referrals = SMB_XMALLOC_ARRAY( struct referral, num_referrals ); + referrals = SMB_XMALLOC_ARRAY( CLIENT_DFS_REFERRAL, num_referrals ); /* start at the referrals array */ @@ -132,11 +215,11 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, continue; } - referrals[0].proximity = SVAL( p, 8 ); - referrals[0].ttl = SVAL( p, 10 ); + referrals[i].proximity = SVAL( p, 8 ); + referrals[i].ttl = SVAL( p, 10 ); - clistr_pull( cli, referrals[0].alternate_path, p+node_offset, - sizeof(referrals[0].alternate_path), -1, STR_TERMINATE|STR_UNICODE ); + clistr_pull( cli, referrals[i].dfspath, p+node_offset, + sizeof(referrals[i].dfspath), -1, STR_TERMINATE|STR_UNICODE ); p += ref_size; } @@ -152,3 +235,121 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, return True; } +#if 0 +/******************************************************************** +********************************************************************/ + +BOOL cli_dfs_handle_referral( struct cli_state *cli, const char *path ) +{ + struct cli_state *cli_ipc; + pstring fullpath; + CLIENT_DFS_REFERRAL *refs = NULL; + size_t num_refs; + uint16 consumed; + fstring server, share; + + if ( !cli_dfs_check_error(cli) ) + return False; + + if ( !(cli_ipc = cli_cm_open( cli->desthost, "IPC$", False )) ) + return False; + + make_full_path( fullpath, cli->desthost, cli->share, path ); + + if ( !cli_dfs_get_referral( cli_ipc, fullpath, &refs, &num_refs, &consumed ) ) { + d_printf("cli_get_dfs_referral() failed!\n"); + /* reset the current client connection */ + cli_cm_open( cli->desthost, cli->share, False ); + + return False; + } + + /* just pick the first one */ + if ( num_refs ) { + split_dfs_path( refs[0].alternate_path, server, share ); + if ( cli_cm_open( server, share, False ) == NULL ) { + d_printf("Unable to follow dfs referral [\\\\%s\\%s]\n", + server, share ); + cli_cm_open( cli->desthost, cli->share, False ); + + return False; + } + } + + SAFE_FREE( refs ); + + return True; +} +#endif + +/******************************************************************** +********************************************************************/ + +BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, + struct cli_state **targetcli, pstring targetpath ) +{ + CLIENT_DFS_REFERRAL *refs = NULL; + size_t num_refs; + uint16 consumed; + struct cli_state *cli_ipc; + pstring fullpath, cleanpath; + int pathlen; + fstring server, share; + + SMB_STRUCT_STAT sbuf; + uint32 attributes; + + if ( !rootcli || !path || !targetcli ) + return False; + + /* send a trans2_query_path_info to check for a referral */ + + clean_path( cleanpath, path ); + make_full_path( fullpath, rootcli->desthost, rootcli->share, cleanpath ); + + /* don't bother continuing if this is not a dfs root */ + + if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, fullpath, &sbuf, &attributes ) ) { + *targetcli = rootcli; + pstrcpy( targetpath, path ); + return True; + } + + /* we got an error, check for DFS referral */ + + if ( !cli_dfs_check_error(rootcli) ) + return False; + + /* check for the referral */ + + if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) ) + return False; + + if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed) + || !num_refs ) + { + return False; + } + + /* just store the first referral for now + Make sure to recreate the original string including any wildcards */ + + make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); + pathlen = strlen( fullpath )*2; + consumed = MIN(pathlen, consumed ); + pstrcpy( targetpath, &fullpath[consumed/2] ); + + split_dfs_path( refs[0].dfspath, server, share ); + SAFE_FREE( refs ); + + /* open the connection to the target path */ + + if ( (*targetcli = cli_cm_open(server, share, False)) == NULL ) { + d_printf("Unable to follow dfs referral [//%s/%s]\n", + server, share ); + + return False; + } + + return True; +} diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 8cc5d8bf90..6ede1b2b53 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -1,7 +1,8 @@ /* Unix SMB/CIFS implementation. client RAP calls - Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Gerald (Jerry) Carter 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -641,9 +642,65 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return True; } + +/**************************************************************************** +send a qpathinfo BASIC_INFO call +****************************************************************************/ +BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, + SMB_STRUCT_STAT *sbuf, uint32 *attributes ) +{ + unsigned int param_len = 0; + unsigned int data_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + char param[sizeof(pstring)+6]; + char *rparam=NULL, *rdata=NULL; + char *p; + + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO); + p += 6; + p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, 0, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + if (data_len < 36) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return False; + } + + sbuf->st_atime = interpret_long_date( rdata+8 ); + sbuf->st_mtime = interpret_long_date( rdata+16 ); + sbuf->st_ctime = interpret_long_date( rdata+24 ); + + *attributes = IVAL( rdata, 32 ); + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return True; +} + /**************************************************************************** send a qfileinfo call ****************************************************************************/ + BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen) { unsigned int data_len = 0; -- cgit From 1b0f75ddfb8ed296ca0166f0606bfc108584b833 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Feb 2005 19:26:32 +0000 Subject: r5520: fix last remaining dfs issues with smbclient. * all the unix extension commands should work * send the correct TRANS2_FINDFIRST format to 2k to get a listing from a msdfs root share (tested against smbd as well). * mkdir, rmdir, etc... all seem ok. I'm sure bugs will pop up so keep testing. Last thing I plan on doing is to clean up the horrible mess with connection management in smbclient and global variables (so i can move the cli_cm_xx() routines to a separate file). (This used to be commit 53d6a5f9d16aef4afc60b4b37b296b256da00dfd) --- source3/libsmb/clilist.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 8ab5854c8f..532fb3a772 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -171,8 +171,14 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; - - pstrcpy(mask,Mask); + + /* when getting a directory listing from a 2k dfs root share, + we have to include the full path (\server\share\mask) here */ + + if ( cli->dfsroot ) + pstr_sprintf( mask, "\\%s\\%s\\%s", cli->desthost, cli->share, Mask ); + else + pstrcpy(mask,Mask); while (ff_eos == 0) { loop_count++; -- cgit From ca9d4c13db2bdd629bf9b97f77c3cb89c4df8676 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Feb 2005 20:00:26 +0000 Subject: r5521: allow smbclient to follow multiple leveles of dfs referrals (no loop checking currently) (This used to be commit 3c09b1f30f8b85036c487fdaf7fca11886bc90d7) --- source3/libsmb/clidfs.c | 57 +++++++++---------------------------------------- 1 file changed, 10 insertions(+), 47 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index ea66eba998..ea5d1d1acb 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -235,53 +235,6 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, return True; } -#if 0 -/******************************************************************** -********************************************************************/ - -BOOL cli_dfs_handle_referral( struct cli_state *cli, const char *path ) -{ - struct cli_state *cli_ipc; - pstring fullpath; - CLIENT_DFS_REFERRAL *refs = NULL; - size_t num_refs; - uint16 consumed; - fstring server, share; - - if ( !cli_dfs_check_error(cli) ) - return False; - - if ( !(cli_ipc = cli_cm_open( cli->desthost, "IPC$", False )) ) - return False; - - make_full_path( fullpath, cli->desthost, cli->share, path ); - - if ( !cli_dfs_get_referral( cli_ipc, fullpath, &refs, &num_refs, &consumed ) ) { - d_printf("cli_get_dfs_referral() failed!\n"); - /* reset the current client connection */ - cli_cm_open( cli->desthost, cli->share, False ); - - return False; - } - - /* just pick the first one */ - if ( num_refs ) { - split_dfs_path( refs[0].alternate_path, server, share ); - if ( cli_cm_open( server, share, False ) == NULL ) { - d_printf("Unable to follow dfs referral [\\\\%s\\%s]\n", - server, share ); - cli_cm_open( cli->desthost, cli->share, False ); - - return False; - } - } - - SAFE_FREE( refs ); - - return True; -} -#endif - /******************************************************************** ********************************************************************/ @@ -295,6 +248,8 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, pstring fullpath, cleanpath; int pathlen; fstring server, share; + struct cli_state *newcli; + pstring newpath; SMB_STRUCT_STAT sbuf; uint32 attributes; @@ -350,6 +305,14 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, return False; } + + /* check for another dfs refeerrali, note that we are not + checking for loops here */ + + if ( cli_resolve_path( *targetcli, targetpath, &newcli, newpath ) ) { + *targetcli = newcli; + pstrcpy( targetpath, newpath ); + } return True; } -- cgit From 584c412e0a87bb73d41e260f93b9915286888ba2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Feb 2005 19:10:28 +0000 Subject: r5542: fix a few more msdfs bugs in smbclient against both smbd and 2k dfs root shares. (This used to be commit 5d2624c453b0bc961302edd9f2421a7c3d504d1f) --- source3/libsmb/clidfs.c | 12 ++++++++---- source3/libsmb/clirap.c | 17 ++++++++++++++++- 2 files changed, 24 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index ea5d1d1acb..6d0d4a8edf 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -254,6 +254,8 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, SMB_STRUCT_STAT sbuf; uint32 attributes; + *targetcli = NULL; + if ( !rootcli || !path || !targetcli ) return False; @@ -264,7 +266,7 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, /* don't bother continuing if this is not a dfs root */ - if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, fullpath, &sbuf, &attributes ) ) { + if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, cleanpath, &sbuf, &attributes ) ) { *targetcli = rootcli; pstrcpy( targetpath, path ); return True; @@ -309,9 +311,11 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, /* check for another dfs refeerrali, note that we are not checking for loops here */ - if ( cli_resolve_path( *targetcli, targetpath, &newcli, newpath ) ) { - *targetcli = newcli; - pstrcpy( targetpath, newpath ); + if ( !strequal( targetpath, "\\" ) ) { + if ( cli_resolve_path( *targetcli, targetpath, &newcli, newpath ) ) { + *targetcli = newcli; + pstrcpy( targetpath, newpath ); + } } return True; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 6ede1b2b53..8e6742d438 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -655,12 +655,27 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, char param[sizeof(pstring)+6]; char *rparam=NULL, *rdata=NULL; char *p; + pstring path; + int len; + + /* send full paths to dfs root shares */ + + if ( cli->dfsroot ) + pstr_sprintf(path, "\\%s\\%s\\%s", cli->desthost, cli->share, name ); + else + pstrcpy( path, name ); + + /* cleanup */ + + len = strlen( path ); + if ( path[len] == '\\' ) + path[len] = '\0'; p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO); p += 6; - p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, -- cgit From 038d939c2aeafcf6e0cd174d5509588e6f953f32 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Feb 2005 21:54:52 +0000 Subject: r5545: move cli_cm_XXX() connection handling code to clidfs and out of client.c; client.c still maintains a pointer to the first connection so the change is fairly reansparent to other smbclient functions such as -L and -M (This used to be commit d6a05ffd664e2e304f6e481af34a4c5d640fc3f9) --- source3/libsmb/clidfs.c | 278 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 278 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 6d0d4a8edf..1b0860b675 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -1,6 +1,7 @@ /* Unix SMB/CIFS implementation. client connect/disconnect routines + Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Gerald (Jerry) Carter 2004 This program is free software; you can redistribute it and/or modify @@ -23,6 +24,283 @@ #include "includes.h" +struct client_connection { + struct client_connection *prev, *next; + struct cli_state *cli; +}; + +/* global state....globals reek! */ + +static pstring username; +static pstring password; +static BOOL use_kerberos; +static BOOL got_pass; +static int signing_state; + +static int port; +static int name_type = 0x20; +static int max_protocol = PROTOCOL_NT1; +static BOOL have_ip; +static struct in_addr dest_ip; + +static struct client_connection *connections; + +/******************************************************************** + Return a connection to a server. +********************************************************************/ + +static struct cli_state *do_connect( const char *server, const char *share, + BOOL show_sessetup ) +{ + struct cli_state *c; + struct nmb_name called, calling; + const char *server_n; + struct in_addr ip; + pstring servicename; + char *sharename; + + /* make a copy so we don't modify the global string 'service' */ + pstrcpy(servicename, share); + sharename = servicename; + if (*sharename == '\\') { + server = sharename+2; + sharename = strchr_m(server,'\\'); + if (!sharename) return NULL; + *sharename = 0; + sharename++; + } + + server_n = server; + + zero_ip(&ip); + + make_nmb_name(&calling, global_myname(), 0x0); + make_nmb_name(&called , server, name_type); + + again: + zero_ip(&ip); + if (have_ip) + ip = dest_ip; + + /* have to open a new connection */ + if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) || + !cli_connect(c, server_n, &ip)) { + d_printf("Connection to %s failed\n", server_n); + return NULL; + } + + c->protocol = max_protocol; + c->use_kerberos = use_kerberos; + cli_setup_signing_state(c, signing_state); + + + if (!cli_session_request(c, &calling, &called)) { + char *p; + d_printf("session request to %s failed (%s)\n", + called.name, cli_errstr(c)); + cli_shutdown(c); + if ((p=strchr_m(called.name, '.'))) { + *p = 0; + goto again; + } + if (strcmp(called.name, "*SMBSERVER")) { + make_nmb_name(&called , "*SMBSERVER", 0x20); + goto again; + } + return NULL; + } + + DEBUG(4,(" session request ok\n")); + + if (!cli_negprot(c)) { + d_printf("protocol negotiation failed\n"); + cli_shutdown(c); + return NULL; + } + + if (!got_pass) { + char *pass = getpass("Password: "); + if (pass) { + pstrcpy(password, pass); + got_pass = 1; + } + } + + if (!cli_session_setup(c, username, + password, strlen(password), + password, strlen(password), + lp_workgroup())) { + /* if a password was not supplied then try again with a null username */ + if (password[0] || !username[0] || use_kerberos || + !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) { + d_printf("session setup failed: %s\n", cli_errstr(c)); + if (NT_STATUS_V(cli_nt_error(c)) == + NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) + d_printf("did you forget to run kinit?\n"); + cli_shutdown(c); + return NULL; + } + d_printf("Anonymous login successful\n"); + } + + if ( show_sessetup ) { + if (*c->server_domain) { + DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + c->server_domain,c->server_os,c->server_type)); + } else if (*c->server_os || *c->server_type){ + DEBUG(1,("OS=[%s] Server=[%s]\n", + c->server_os,c->server_type)); + } + } + DEBUG(4,(" session setup ok\n")); + + if (!cli_send_tconX(c, sharename, "?????", + password, strlen(password)+1)) { + d_printf("tree connect failed: %s\n", cli_errstr(c)); + cli_shutdown(c); + return NULL; + } + + DEBUG(4,(" tconx ok\n")); + + return c; +} + +/******************************************************************** + Add a new connection to the list +********************************************************************/ + +static struct cli_state* cli_cm_connect( const char *server, const char *share, + BOOL show_hdr ) +{ + struct client_connection *node; + + node = SMB_XMALLOC_P( struct client_connection ); + + node->cli = do_connect( server, share, show_hdr ); + + if ( !node->cli ) { + SAFE_FREE( node ); + return NULL; + } + + DLIST_ADD( connections, node ); + + return node->cli; + +} + +/******************************************************************** + Return a connection to a server. +********************************************************************/ + +static struct cli_state* cli_cm_find( const char *server, const char *share ) +{ + struct client_connection *p; + + for ( p=connections; p; p=p->next ) { + if ( strequal(server, p->cli->desthost) && strequal(share,p->cli->share) ) + return p->cli; + } + + return NULL; +} + +/**************************************************************************** + open a client connection to a \\server\share. Set's the current *cli + global variable as a side-effect (but only if the connection is successful). +****************************************************************************/ + +struct cli_state* cli_cm_open( const char *server, const char *share, BOOL show_hdr ) +{ + struct cli_state *c; + + /* try to reuse an existing connection */ + + c = cli_cm_find( server, share ); + + if ( !c ) + c = cli_cm_connect( server, share, show_hdr ); + + return c; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_shutdown( void ) +{ + + struct client_connection *p, *x; + + for ( p=connections; p; ) { + cli_shutdown( p->cli ); + x = p; + p = p->next; + + SAFE_FREE( x ); + } + + connections = NULL; + + return; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_display(void) +{ + struct client_connection *p; + int i; + + for ( p=connections,i=0; p; p=p->next,i++ ) { + d_printf("%d:\tserver=%s, share=%s\n", + i, p->cli->desthost, p->cli->share ); + } +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_credentials( struct user_auth_info *user ) +{ + pstrcpy( username, user->username ); + + if ( user->got_pass ) { + pstrcpy( password, user->password ); + got_pass = True; + } + + use_kerberos = user->use_kerberos; + signing_state = user->signing_state; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_port( int port_number ) +{ + port = port_number; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_dest_name_type( int type ) +{ + name_type = type; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_dest_ip(struct in_addr ip ) +{ + dest_ip = ip; + have_ip = True; +} + /******************************************************************** split a dfs path into the server and share name components ********************************************************************/ -- cgit From d8b85fa12b1224c8db3ae3ec4f767801e1c9713a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 25 Feb 2005 15:22:49 +0000 Subject: r5560: make sure session setup message is displayed after changes to client.c (This used to be commit 3f5e52e90861d071870a369fac246a822f4ff2ce) --- source3/libsmb/clidfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 1b0860b675..6db6330ca6 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -145,10 +145,10 @@ static struct cli_state *do_connect( const char *server, const char *share, if ( show_sessetup ) { if (*c->server_domain) { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + DEBUG(0,("Domain=[%s] OS=[%s] Server=[%s]\n", c->server_domain,c->server_os,c->server_type)); } else if (*c->server_os || *c->server_type){ - DEBUG(1,("OS=[%s] Server=[%s]\n", + DEBUG(0,("OS=[%s] Server=[%s]\n", c->server_os,c->server_type)); } } -- cgit From 96572957fc3df956ec0fad242fc7d04ab6a6961f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 26 Feb 2005 14:42:55 +0000 Subject: r5577: get recurse; dir working across single level dfs referrals (This used to be commit d4443807bc7a5a8615c69517365a92709db7ce29) --- source3/libsmb/clidfs.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/clilist.c | 13 +++++++----- 2 files changed, 61 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 6db6330ca6..62b682a748 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -27,6 +27,7 @@ struct client_connection { struct client_connection *prev, *next; struct cli_state *cli; + pstring mount; }; /* global state....globals reek! */ @@ -166,6 +167,54 @@ static struct cli_state *do_connect( const char *server, const char *share, return c; } +/**************************************************************************** +****************************************************************************/ + +static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) +{ + struct client_connection *p; + int i; + pstring path; + char *ppath; + + for ( p=connections,i=0; p; p=p->next,i++ ) { + if ( strequal(p->cli->desthost, c->desthost) && strequal(p->cli->share, c->share) ) + break; + } + + if ( p ) { + pstrcpy( p->mount, mnt ); + dos_clean_name( p->mount ); + +#if 0 + /* strip any leading '\\' */ + ppath = path; + if ( *ppath == '\\' ) + ppath++; + pstrcpy( p->mount, ppath ); +#endif + } +} + +/**************************************************************************** +****************************************************************************/ + +const char * cli_cm_get_mntpoint( struct cli_state *c ) +{ + struct client_connection *p; + int i; + + for ( p=connections,i=0; p; p=p->next,i++ ) { + if ( strequal(p->cli->desthost, c->desthost) && strequal(p->cli->share, c->share) ) + break; + } + + if ( p ) + return p->mount; + + return NULL; +} + /******************************************************************** Add a new connection to the list ********************************************************************/ @@ -186,6 +235,8 @@ static struct cli_state* cli_cm_connect( const char *server, const char *share, DLIST_ADD( connections, node ); + cli_cm_set_mntpoint( node->cli, "" ); + return node->cli; } @@ -585,6 +636,8 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, return False; } + + cli_cm_set_mntpoint( *targetcli, cleanpath ); /* check for another dfs refeerrali, note that we are not checking for loops here */ diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 532fb3a772..4e90a79719 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -143,7 +143,7 @@ static int interpret_long_filename(struct cli_state *cli, ****************************************************************************/ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *, void *), void *state) + void (*fn)(const char *, file_info *, const char *, void *), void *state) { #if 0 int max_matches = 1366; /* Match W2k - was 512. */ @@ -322,8 +322,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } for (p=dirlist,i=0;iprotocol <= PROTOCOL_LANMAN1) return cli_list_old(cli, Mask, attribute, fn, state); -- cgit From fb84318c34418d6f11344b5497efde3a37b5446a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 26 Feb 2005 15:03:16 +0000 Subject: r5578: get 'recurse; dir' working across multiple levels of dfs referrals note that this does not handle the situation where the same \\server\share is mounted mutliple times in the dfs tree since I store a single mount path per struct cli_state * (This used to be commit 52c82b51ba9729cc53a049d8e9fbb7365d652c51) --- source3/libsmb/clidfs.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 62b682a748..867e8e9ba0 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -174,8 +174,6 @@ static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) { struct client_connection *p; int i; - pstring path; - char *ppath; for ( p=connections,i=0; p; p=p->next,i++ ) { if ( strequal(p->cli->desthost, c->desthost) && strequal(p->cli->share, c->share) ) @@ -185,14 +183,6 @@ static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) if ( p ) { pstrcpy( p->mount, mnt ); dos_clean_name( p->mount ); - -#if 0 - /* strip any leading '\\' */ - ppath = path; - if ( *ppath == '\\' ) - ppath++; - pstrcpy( p->mount, ppath ); -#endif } } @@ -567,7 +557,7 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, /******************************************************************** ********************************************************************/ -BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, +BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const char *path, struct cli_state **targetcli, pstring targetpath ) { CLIENT_DFS_REFERRAL *refs = NULL; @@ -579,6 +569,8 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, fstring server, share; struct cli_state *newcli; pstring newpath; + pstring newmount; + char *ppath; SMB_STRUCT_STAT sbuf; uint32 attributes; @@ -637,17 +629,28 @@ BOOL cli_resolve_path( struct cli_state *rootcli, const char *path, return False; } - cli_cm_set_mntpoint( *targetcli, cleanpath ); + /* parse out the consumed mount path */ + /* trim off the \server\share\ */ - /* check for another dfs refeerrali, note that we are not + fullpath[consumed/2] = '\0'; + dos_clean_name( fullpath ); + ppath = strchr_m( fullpath, '\\' ); + ppath = strchr_m( ppath+1, '\\' ); + ppath = strchr_m( ppath+1, '\\' ); + ppath++; + + pstr_sprintf( newmount, "%s\\%s", mountpt, ppath ); + cli_cm_set_mntpoint( *targetcli, newmount ); + + /* check for another dfs referral, note that we are not checking for loops here */ if ( !strequal( targetpath, "\\" ) ) { - if ( cli_resolve_path( *targetcli, targetpath, &newcli, newpath ) ) { + if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) { *targetcli = newcli; pstrcpy( targetpath, newpath ); } } - + return True; } -- cgit From 4eed5ad01647728a258cfda9c676711d524014a4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 5 Mar 2005 08:12:40 +0000 Subject: r5657: Fix uninitialized variable warning (This used to be commit f74737ce574aa4b47367fccb1b95769778187515) --- source3/libsmb/clidfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 867e8e9ba0..e4308fdb5a 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -484,7 +484,7 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, char *p; size_t pathlen = 2*(strlen(path)+1); uint16 num_referrals; - CLIENT_DFS_REFERRAL *referrals; + CLIENT_DFS_REFERRAL *referrals = NULL; memset(param, 0, sizeof(param)); SSVAL(param, 0, 0x03); /* max referral level */ -- cgit From 9d23e37a6f9887fed08ba495555d23fefab585ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Mar 2005 00:06:27 +0000 Subject: r5702: Fix bug #2271. Correctly pull out and use resume names in a directory listing (we were incorrectly understanding what was returned in the "last name" entry). Jeremy. (This used to be commit 4f2da9ecf1e5cee4749839ea1b35a942d27de09e) --- source3/libsmb/clilist.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4e90a79719..d60739cf7c 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -268,24 +268,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, p = rdata; /* we might need the lastname for continuations */ - if (ff_lastname > 0) { - switch(info_level) { - case 260: - clistr_pull(cli, mask, p+ff_lastname, - sizeof(mask), - data_len-ff_lastname, - STR_TERMINATE); - break; - case 1: - clistr_pull(cli, mask, p+ff_lastname+1, - sizeof(mask), - -1, - STR_TERMINATE); - break; - } - } else { - pstrcpy(mask,""); - } /* and add them to the dirlist pool */ tdl = SMB_REALLOC(dirlist,dirlist_len + data_len); @@ -299,10 +281,18 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* put in a length for the last entry, to ensure we can chain entries into the next packet */ - for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(cli,info_level,p2,NULL); + for (p2=p,i=0;i<(ff_searchcount-1);i++) { + p2 += interpret_long_filename(cli,info_level,p2,&finfo); + } SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); + /* we might need the lastname for continuations */ + if (ff_lastname > 0) { + pstrcpy(mask, finfo.name); + } else { + pstrcpy(mask,""); + } + /* grab the data for later use */ memcpy(dirlist+dirlist_len,p,data_len); dirlist_len += data_len; -- cgit From 4a62d418d9dbed3838dda871e4ead052fbe2bf0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 10 Mar 2005 02:00:24 +0000 Subject: r5723: Add missing part of fix for #2271. After analysing the actions of a XP client against a Samba server. It never uses the "continue" flag, but always does "new search, continue from this file" instead. Change our client code to do the same (it appears that's all they test in W2K etc.). Jeremy. (This used to be commit 710bceee325005b8ca8e8ed04acc50bafa92b6e6) --- source3/libsmb/clilist.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d60739cf7c..dcac17d24a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -191,7 +191,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,4+2); /* resume required + close on end */ + SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; @@ -203,7 +203,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ - SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ + /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren + can miss filenames. Use last filename continue instead. JRA */ + SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); -- cgit From 82379c7bd1827601630da120f5b5ebb9061ce2b5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Mar 2005 20:14:24 +0000 Subject: r5729: partial fixes for BUG 2308; libsmbclient patches from Derrell Lipman (This used to be commit 88678bc05c3018eb181f97523a0b84b60e3c358d) --- source3/libsmb/cliconnect.c | 7 ++++++- source3/libsmb/clientgen.c | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 01a92a89ba..aa37a29391 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -888,7 +888,12 @@ BOOL cli_ulogoff(struct cli_state *cli) if (!cli_receive_smb(cli)) return False; - return !cli_is_error(cli); + if (cli_is_error(cli)) { + return False; + } + + cli->cnum = -1; + return True; } /**************************************************************************** diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 369fba3521..b7bc780a1a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -282,6 +282,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = False; + cli->smb_rw_error = 0; cli->use_spnego = lp_client_use_spnego(); -- cgit From 9d65e0778425b1e49e789178999ce98e59395569 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Mar 2005 23:41:19 +0000 Subject: r5735: rest of derrel's patch for BUG 2308; had to move the options structure from the _SMBCCTX to the internals structure to maintain binary compatibility (derrel, we should talk more about this) (This used to be commit a5ea01bf15758bb2be26ba16784dc0975be783bf) --- source3/libsmb/libsmb_cache.c | 55 +- source3/libsmb/libsmbclient.c | 1579 +++++++++++++++++++++++++++-------------- 2 files changed, 1099 insertions(+), 535 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index ddb2753523..dabf5a527d 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -1,3 +1,4 @@ + /* Unix SMB/CIFS implementation. SMB client library implementation (server cache) @@ -23,12 +24,8 @@ #include "includes.h" -/* - * Define this to get the real SMBCFILE and SMBCSRV structures - */ -#define _SMBC_INTERNAL #include "include/libsmbclient.h" - +#include "../include/libsmb_internal.h" /* * Structure we use if internal caching mechanism is used * nothing fancy here. @@ -115,11 +112,53 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, /* Search the cache lines */ for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { + if (strcmp(server,srv->server_name) == 0 && - strcmp(share,srv->share_name) == 0 && strcmp(workgroup,srv->workgroup) == 0 && - strcmp(user, srv->username) == 0) - return srv->server; + strcmp(user, srv->username) == 0) { + + /* If the share name matches, we're cool */ + if (strcmp(share, srv->share_name) == 0) { + return srv->server; + } + + /* + * We only return an empty share name or the attribute + * server on an exact match (which would have been + * caught above). + */ + if (*share == '\0' || strcmp(share, "*IPC$") == 0) + continue; + + /* + * Never return an empty share name or the attribute + * server if it wasn't what was requested. + */ + if (*srv->share_name == '\0' || + strcmp(srv->share_name, "*IPC$") == 0) + continue; + + /* + * If we're only allowing one share per server, then + * a connection to the server (other than the + * attribute server connection) is cool. + */ + if (context->options.one_share_per_server) { + /* + * The currently connected share name + * doesn't match the requested share, so + * disconnect from the current share. + */ + if (! cli_tdis(&srv->server->cli)) { + /* Sigh. Couldn't disconnect. */ + cli_shutdown(&srv->server->cli); + context->callbacks.remove_cached_srv_fn(context, srv->server); + continue; + } + + return srv->server; + } + } } return NULL; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 8eeadc8a78..bc15fe7d50 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5,7 +5,7 @@ Copyright (C) Richard Sharpe 2000, 2002 Copyright (C) John Terpstra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 - Copyright (C) Derrell Lipman 2003 + Copyright (C) Derrell Lipman 2003, 2004 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,6 +26,21 @@ #include "include/libsmb_internal.h" + +/* + * DOS Attribute values (used internally) + */ +typedef struct DOS_ATTR_DESC +{ + int mode; + unsigned long long size; + time_t a_time; + time_t c_time; + time_t m_time; + unsigned long long inode; +} DOS_ATTR_DESC; + + /* * Internal flags for extended attributes */ @@ -84,73 +99,103 @@ hex2int( unsigned int _char ) return -1; } -static void -decode_urlpart(char *segment, size_t sizeof_segment) +/* + * smbc_urldecode() + * + * Convert strings of %xx to their single character equivalent. Each 'x' must + * be a valid hexadecimal digit, or that % sequence is left undecoded. + * + * dest may, but need not be, the same pointer as src. + * + * Returns the number of % sequences which could not be converted due to lack + * of two following hexadecimal digits. + */ +int +smbc_urldecode(char *dest, char * src, size_t max_dest_len) { - int old_length = strlen(segment); - int new_length = 0; - int new_length2 = 0; - int i = 0; - pstring new_segment; - char *new_usegment = 0; - - if ( !old_length ) { - return; - } + int old_length = strlen(src); + int i = 0; + int err_count = 0; + pstring temp; + char * p; - /* make a copy of the old one */ - new_usegment = (char*)SMB_MALLOC( old_length * 3 + 1 ); - - while( i < old_length ) { - int bReencode = False; - unsigned char character = segment[ i++ ]; - if ((character <= ' ') || (character > 127)) - bReencode = True; - - new_usegment [ new_length2++ ] = character; - if (character == '%' ) { - int a = i+1 < old_length ? hex2int( segment[i] ) : -1; - int b = i+1 < old_length ? hex2int( segment[i+1] ) : -1; - if ((a == -1) || (b == -1)) { /* Only replace if sequence is valid */ - /* Contains stray %, make sure to re-encode! */ - bReencode = True; - } else { - /* Valid %xx sequence */ - character = a * 16 + b; /* Replace with value of %dd */ - if (!character) - break; /* Stop at %00 */ - - new_usegment [ new_length2++ ] = (unsigned char) segment[i++]; - new_usegment [ new_length2++ ] = (unsigned char) segment[i++]; - } - } - if (bReencode) { - unsigned int c = character / 16; - new_length2--; - new_usegment [ new_length2++ ] = '%'; - - c += (c > 9) ? ('A' - 10) : '0'; - new_usegment[ new_length2++ ] = c; - - c = character % 16; - c += (c > 9) ? ('A' - 10) : '0'; - new_usegment[ new_length2++ ] = c; - } - - new_segment [ new_length++ ] = character; - } - new_segment [ new_length ] = 0; + if ( old_length == 0 ) { + return 0; + } + + p = temp; + while ( i < old_length ) { + unsigned char character = src[ i++ ]; - free(new_usegment); + if (character == '%') { + int a = i+1 < old_length ? hex2int( src[i] ) : -1; + int b = i+1 < old_length ? hex2int( src[i+1] ) : -1; - /* realloc it with unix charset */ - pull_utf8_allocate(&new_usegment, new_segment); + /* Replace valid sequence */ + if (a != -1 && b != -1) { - /* this assumes (very safely) that removing %aa sequences - only shortens the string */ - strncpy(segment, new_usegment, sizeof_segment); + /* Replace valid %xx sequence with %dd */ + character = (a * 16) + b; + + if (character == '\0') { + break; /* Stop at %00 */ + } + + i += 2; + } else { + + err_count++; + } + } + + *p++ = character; + } + + *p = '\0'; + + strncpy(dest, temp, max_dest_len); + + return err_count; +} + +/* + * smbc_urlencode() + * + * Convert any characters not specifically allowed in a URL into their %xx + * equivalent. + * + * Returns the remaining buffer length. + */ +int +smbc_urlencode(char * dest, char * src, int max_dest_len) +{ + char hex[] = "0123456789ABCDEF"; + + for (; *src != '\0' && max_dest_len >= 3; src++) { + + if ((*src < '0' && + *src != '-' && + *src != '.') || + (*src > '9' && + *src < 'A') || + (*src > 'Z' && + *src < 'a' && + *src != '_') || + (*src > 'z')) { + *dest++ = '%'; + *dest++ = hex[(*src >> 4) & 0x0f]; + *dest++ = hex[*src & 0x0f]; + max_dest_len -= 3; + } else { + *dest++ = *src; + max_dest_len--; + } + } - free(new_usegment); + *dest++ = '\0'; + max_dest_len--; + + return max_dest_len; } /* @@ -158,10 +203,7 @@ decode_urlpart(char *segment, size_t sizeof_segment) * * The general format of an SMB URI is explain in Christopher Hertel's CIFS * book, at http://ubiqx.org/cifs/Appendix-D.html. We accept a subset of the - * general format ("smb:" only; we do not look for "cifs:"), and expand on - * what he calls "context", herein called "options" to avoid conflict with the - * SMBCCTX context used throughout this library. We add the "mb" keyword - * which applies as follows: + * general format ("smb:" only; we do not look for "cifs:"). * * * We accept: @@ -169,37 +211,28 @@ decode_urlpart(char *segment, size_t sizeof_segment) * * Meaning of URLs: * - * smb:// show all workgroups known by the first master browser found - * smb://?mb=.any same as smb:// (i.e. without any options) - * - * smb://?mb=.all show all workgroups known by every master browser found. - * Why might you want this? In an "appliance" application - * where the workgroup/domain being used on the local network - * is not known ahead of time, but where one wanted to - * provide network services via samba, a unique workgroup - * could be used. However, when the appliance is first - * started, the local samba instance's master browser has not - * synchronized with the other master browser(s) on the - * network (and might not synchronize for 12 minutes) and - * therefore is not aware of the workgroup/ domain names - * available on the network. This option may be used to - * overcome the problem of a libsmbclient application - * arbitrarily selecting the local (still ignorant) master - * browser to obtain its list of workgroups/domains and - * getting back a practically emmpty list. By requesting - * the list of workgroups/domains from each found master - * browser on the local network, a complete list of - * workgroups/domains can be built. + * smb:// Show all workgroups. * - * smb://?mb=name NOT YET IMPLEMENTED -- show all workgroups known by the - * master browser whose name is "name" + * The method of locating the list of workgroups varies + * depending upon the setting of the context variable + * context->options.browse_max_lmb_count. This value + * determine the maximum number of local master browsers to + * query for the list of workgroups. In order to ensure that + * a complete list of workgroups is obtained, all master + * browsers must be queried, but if there are many + * workgroups, the time spent querying can begin to add up. + * For small networks (not many workgroups), it is suggested + * that this variable be set to 0, indicating query all local + * master browsers. When the network has many workgroups, a + * reasonable setting for this variable might be around 3. * * smb://name/ if name<1D> or name<1B> exists, list servers in * workgroup, else, if name<20> exists, list all shares * for server ... * - * If "options" are provided, this function returns the entire option list as - * a string, for later parsing by the caller. + * If "options" are provided, this function returns the entire option list as a + * string, for later parsing by the caller. Note that currently, no options + * are supported. */ static const char *smbc_prefix = "smb:"; @@ -246,7 +279,7 @@ smbc_parse_path(SMBCCTX *context, p += 2; /* Skip the double slash */ /* See if any options were specified */ - if ( (q = strrchr(p, '?')) != NULL ) { + if ((q = strrchr(p, '?')) != NULL ) { /* There are options. Null terminate here and point to them */ *q++ = '\0'; @@ -333,11 +366,11 @@ smbc_parse_path(SMBCCTX *context, all_string_sub(path, "/", "\\", 0); decoding: - decode_urlpart(path, path_len); - decode_urlpart(server, server_len); - decode_urlpart(share, share_len); - decode_urlpart(user, user_len); - decode_urlpart(password, password_len); + (void) smbc_urldecode(path, path, path_len); + (void) smbc_urldecode(server, server, server_len); + (void) smbc_urldecode(share, share, share_len); + (void) smbc_urldecode(user, user, user_len); + (void) smbc_urldecode(password, password, password_len); return 0; } @@ -352,28 +385,8 @@ static int smbc_check_options(char *server, char *share, char *path, char *optio /* No options at all is always ok */ if (! *options) return 0; - /* - * For right now, we only support a very few options possibilities. - * No options are supported if server, share, or path are not empty. - * If all are empty, then we support the following two choices right - * now: - * - * mb=.any - * mb=.all - */ - if ((*server || *share || *path) && *options) { - /* Invalid: options provided with server, share, or path */ - DEBUG(1, ("Found unsupported options (%s) with non-empty server, share, or path\n", options)); - return -1; - } - - if (strcmp(options, "mb=.any") != 0 && - strcmp(options, "mb=.all") != 0) { - DEBUG(1, ("Found unsupported options (%s)\n", options)); - return -1; - } - - return 0; + /* Currently, we don't support any options. */ + return -1; } /* @@ -452,8 +465,6 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) context->callbacks.remove_cached_srv_fn(context, srv); - SAFE_FREE(srv); - return 0; } @@ -471,7 +482,7 @@ SMBCSRV *find_server(SMBCCTX *context, srv = context->callbacks.get_cached_srv_fn(context, server, share, workgroup, username); - + if (!auth_called && !srv && (!username[0] || !password[0])) { context->callbacks.auth_fn(server, share, workgroup, sizeof(fstring), @@ -512,6 +523,7 @@ SMBCSRV *find_server(SMBCCTX *context, */ goto check_server_cache; } + return srv; } @@ -541,6 +553,8 @@ SMBCSRV *smbc_server(SMBCCTX *context, pstring ipenv; struct in_addr ip; int tried_reverse = 0; + int port_try_first; + int port_try_next; zero_ip(&ip); ZERO_STRUCT(c); @@ -552,25 +566,56 @@ SMBCSRV *smbc_server(SMBCCTX *context, srv = find_server(context, server, share, workgroup, username, password); - if (srv) + + /* + * If we found a connection and we're only allowed one share per + * server... + */ + if (srv && *share != '\0' && context->internal->options.one_share_per_server) { + + /* + * ... then if there's no current connection to the share, + * connect to it. find_server(), or rather the function + * pointed to by context->callbacks.get_cached_srv_fn which + * was called by find_server(), will have issued a tree + * disconnect if the requested share is not the same as the + * one that was already connected. + */ + if (srv->cli.cnum == (uint16) -1) { + /* Ensure we have accurate auth info */ + context->callbacks.auth_fn(server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + + if (! cli_send_tconX(&srv->cli, share, "?????", + password, strlen(password)+1)) { + + errno = smbc_errno(context, &srv->cli); + cli_shutdown(&srv->cli); + context->callbacks.remove_cached_srv_fn(context, srv); + srv = NULL; + } + + /* Regenerate the dev value since it's based on both server and share */ + if (srv) { + srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); + } + } + } + + /* If we have a connection... */ + if (srv) { + + /* ... then we're done here. Give 'em what they came for. */ return srv; + } make_nmb_name(&calling, context->netbios_name, 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); -#if 0 /* djl: obsolete code? neither group nor p is used beyond here */ - if ((p=strchr_m(server_n,'#')) && - (strcmp(p+1,"1D")==0 || strcmp(p+1,"01")==0)) { - - fstrcpy(group, server_n); - p = strchr_m(group,'#'); - *p = 0; - - } -#endif - DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again: @@ -593,18 +638,31 @@ SMBCSRV *smbc_server(SMBCCTX *context, c.timeout = context->timeout; - /* Force use of port 139 for first try, so browse lists can work */ - c.port = 139; + /* + * Force use of port 139 for first try if share is $IPC, empty, or + * null, so browse lists can work + */ + if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) + { + port_try_first = 139; + port_try_next = 445; + } + else + { + port_try_first = 445; + port_try_next = 139; + } + + c.port = port_try_first; if (!cli_connect(&c, server_n, &ip)) { - /* - * Port 139 connection failed. Try port 445 to handle - * connections to newer (e.g. XP) hosts with NetBIOS disabled. - */ - c.port = 445; + + /* First connection attempt failed. Try alternate port. */ + c.port = port_try_next; + if (!cli_connect(&c, server_n, &ip)) { - cli_shutdown(&c); - errno = ENETUNREACH; + cli_shutdown(&c); + errno = ETIMEDOUT; return NULL; } } @@ -625,7 +683,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server)); - errno = ENOENT; + errno = ETIMEDOUT; return NULL; } @@ -639,7 +697,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, } } - errno = ENOENT; + errno = ETIMEDOUT; return NULL; } @@ -647,7 +705,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, if (!cli_negprot(&c)) { cli_shutdown(&c); - errno = ENOENT; + errno = ETIMEDOUT; return NULL; } @@ -732,10 +790,11 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, SMBCSRV *ipc_srv=NULL; /* - * See if we've already created this special connection. Reference - * our "special" share name 'IPC$$'. + * See if we've already created this special connection. Reference our + * "special" share name '*IPC$', which is an impossible real share name + * due to the leading asterisk. */ - ipc_srv = find_server(context, server, "IPC$$", + ipc_srv = find_server(context, server, "*IPC$", workgroup, username, password); if (!ipc_srv) { @@ -801,7 +860,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, errno = 0; /* let cache function set errno if it likes */ if (context->callbacks.add_cached_srv_fn(context, ipc_srv, server, - "IPC$$", + "*IPC$", workgroup, username)) { DEBUG(3, (" Failed to add server to cache\n")); @@ -1621,21 +1680,15 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint { struct smbc_dirent *dirent; int size; - char *u_name = NULL, *u_comment = NULL; - size_t u_name_len = 0, u_comment_len = 0; - - if (name) - u_name_len = push_utf8_allocate(&u_name, name); - if (comment) - u_comment_len = push_utf8_allocate(&u_comment, comment); + int name_length = (name == NULL ? 0 : strlen(name)); + int comment_len = (comment == NULL ? 0 : strlen(comment)); /* * Allocate space for the dirent, which must be increased by the - * size of the name and the comment and 1 for the null on the comment. - * The null on the name is already accounted for. + * size of the name and the comment and 1 each for the null terminator. */ - size = sizeof(struct smbc_dirent) + u_name_len + u_comment_len + 1; + size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; dirent = SMB_MALLOC(size); @@ -1682,18 +1735,15 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint dir->dir_end->dirent = dirent; dirent->smbc_type = type; - dirent->namelen = u_name_len; - dirent->commentlen = u_comment_len; + dirent->namelen = name_length; + dirent->commentlen = comment_len; dirent->dirlen = size; - strncpy(dirent->name, (u_name?u_name:""), dirent->namelen + 1); + strncpy(dirent->name, (name?name:""), dirent->namelen + 1); dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); - strncpy(dirent->comment, (u_comment?u_comment:""), dirent->commentlen + 1); + strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); - SAFE_FREE(u_comment); - SAFE_FREE(u_name); - return 0; } @@ -1781,7 +1831,7 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) } static void -dir_list_fn(file_info *finfo, const char *mask, void *state) +dir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state) { if (add_dirent((SMBCFILE *)state, finfo->name, "", @@ -1807,14 +1857,14 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!context || !context->internal || !context->internal->_initialized) { DEBUG(4, ("no valid context\n")); - errno = EINVAL; + errno = EINVAL + 8192; return NULL; } if (!fname) { DEBUG(4, ("no valid fname\n")); - errno = EINVAL; + errno = EINVAL + 8193; return NULL; } @@ -1826,7 +1876,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) password, sizeof(password), options, sizeof(options))) { DEBUG(4, ("no valid path\n")); - errno = EINVAL; + errno = EINVAL + 8194; return NULL; } @@ -1835,7 +1885,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) /* Ensure the options are valid */ if (smbc_check_options(server, share, path, options)) { DEBUG(4, ("unacceptable options (%s)\n", options)); - errno = EINVAL; + errno = EINVAL + 8195; return NULL; } @@ -1861,108 +1911,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) dir->file = False; dir->dir_list = dir->dir_next = dir->dir_end = NULL; - if (server[0] == (char)0 && - (! *options || strcmp(options, "mb=.any") == 0)) { - struct in_addr server_ip; - if (share[0] != (char)0 || path[0] != (char)0) { - - errno = EINVAL; - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - return NULL; - } - - /* - * We have server and share and path empty ... so list the - * workgroups first try to get the LMB for our workgroup, and - * if that fails, try the DMB - */ - - pstrcpy(workgroup, lp_workgroup()); - - if (!find_master_ip(workgroup, &server_ip)) { - struct user_auth_info u_info; - struct cli_state *cli; - - DEBUG(4, ("Unable to find master browser for workgroup %s\n", - workgroup)); - - /* find the name of the server ... */ - pstrcpy(u_info.username, user); - pstrcpy(u_info.password, password); - - if (!(cli = get_ipc_connect_master_ip_bcast(workgroup, &u_info))) { - DEBUG(4, ("Unable to find master browser by " - "broadcast\n")); - errno = ENOENT; - return NULL; - } - - fstrcpy(server, cli->desthost); - - cli_shutdown(cli); - } else { - /* - * Do a name status query to find out the name of the - * master browser. We use <01><02>__MSBROWSE__<02>#01 if - * *#00 fails because a domain master browser will not - * respond to a wildcard query (or, at least, an NT4 - * server acting as the domain master browser will not). - * - * We might be able to use ONLY the query on MSBROWSE, but - * that's not yet been tested with all Windows versions, - * so until it is, leave the original wildcard query as - * the first choice and fall back to MSBROWSE if the - * wildcard query fails. - */ - if (!name_status_find("*", 0, 0x20, server_ip, server) && - !name_status_find(MSBROWSE, 1, 0x1b, server_ip, server)) { - errno = ENOENT; - return NULL; - } - } - - DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); - - /* - * Get a connection to IPC$ on the server if we do not already - * have one - */ - - srv = smbc_server(context, server, "IPC$", workgroup, user, password); - if (!srv) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - return NULL; - } - - dir->srv = srv; - dir->dir_type = SMBC_WORKGROUP; - - /* Now, list the stuff ... */ - - if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_fn, - (void *)dir)) { - - DEBUG(1, ("Could not enumerate domains using '%s'\n", workgroup)); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - - return NULL; - - } - } else if (server[0] == (char)0 && - (! *options || strcmp(options, "mb=.all") == 0)) { + if (server[0] == (char)0) { int i; int count; + int max_lmb_count; struct ip_service *ip_list; struct ip_service server_addr; struct user_auth_info u_info; @@ -1970,7 +1923,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (share[0] != (char)0 || path[0] != (char)0) { - errno = EINVAL; + errno = EINVAL + 8196; if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -1978,6 +1931,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } + /* Determine how many local master browsers to query */ + max_lmb_count = (context->internal->options.browse_max_lmb_count == 0 + ? INT_MAX + : context->internal->options.browse_max_lmb_count); + pstrcpy(u_info.username, user); pstrcpy(u_info.password, password); @@ -2001,11 +1959,10 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) count = 1; } - for (i = 0; i < count; i++) { + for (i = 0; i < count && i < max_lmb_count; i++) { DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info); - /* cli == NULL is the master browser refused to talk or could not be found */ if ( !cli ) @@ -2060,7 +2017,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (path[0] != (char)0) { /* Should not have empty share with path */ - errno = EINVAL; + errno = EINVAL + 8197; if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -2254,12 +2211,54 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) } +static void smbc_readdir_internal(SMBCCTX * context, + struct smbc_dirent *dest, + struct smbc_dirent *src, + int max_namebuf_len) +{ + if (context->internal->options.urlencode_readdir_entries) { + + /* url-encode the name. get back remaining buffer space */ + max_namebuf_len = + smbc_urlencode(dest->name, src->name, max_namebuf_len); + + /* We now know the name length */ + dest->namelen = strlen(dest->name); + + /* Save the pointer to the beginning of the comment */ + dest->comment = dest->name + dest->namelen + 1; + + /* Copy the comment */ + strncpy(dest->comment, src->comment, max_namebuf_len); + + /* Ensure the comment is null terminated */ + if (max_namebuf_len > src->commentlen) { + dest->comment[src->commentlen] = '\0'; + } else { + dest->comment[max_namebuf_len - 1] = '\0'; + } + + /* Save other fields */ + dest->smbc_type = src->smbc_type; + dest->commentlen = strlen(dest->comment); + dest->dirlen = ((dest->comment + dest->commentlen + 1) - + (char *) dest); + } else { + + /* No encoding. Just copy the entry as is. */ + memcpy(dest, src, src->dirlen); + dest->comment = (char *)(&dest->name + src->namelen + 1); + } + +} + /* * Routine to get a directory entry */ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) { + int maxlen; struct smbc_dirent *dirp, *dirent; /* Check that all is ok first ... */ @@ -2292,37 +2291,40 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) if (!dir->dir_next) { return NULL; } - else { - dirent = dir->dir_next->dirent; - if (!dirent) { + dirent = dir->dir_next->dirent; + if (!dirent) { - errno = ENOENT; - return NULL; + errno = ENOENT; + return NULL; - } + } - /* Hmmm, do I even need to copy it? */ + dirp = (struct smbc_dirent *)context->internal->_dirent; + maxlen = (sizeof(context->internal->_dirent) - + sizeof(struct smbc_dirent)); - memcpy(context->internal->_dirent, dirent, dirent->dirlen); /* Copy the dirent */ - dirp = (struct smbc_dirent *)context->internal->_dirent; - dirp->comment = (char *)(&dirp->name + dirent->namelen + 1); - dir->dir_next = dir->dir_next->next; + smbc_readdir_internal(context, dirp, dirent, maxlen); - return (struct smbc_dirent *)context->internal->_dirent; - } + dir->dir_next = dir->dir_next->next; + return dirp; } /* * Routine to get directory entries */ -static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent *dirp, int count) +static int smbc_getdents_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct smbc_dirent *dirp, + int count) { - struct smbc_dir_list *dirlist; - int rem = count, reqd; + int rem = count; + int reqd; + int maxlen; char *ndir = (char *)dirp; + struct smbc_dir_list *dirlist; /* Check that all is ok first ... */ @@ -2364,8 +2366,15 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent } - if (rem < (reqd = (sizeof(struct smbc_dirent) + dirlist->dirent->namelen + - dirlist->dirent->commentlen + 1))) { + /* Do urlencoding of next entry, if so selected */ + dirent = (struct smbc_dirent *)context->internal->_dirent; + maxlen = (sizeof(context->internal->_dirent) - + sizeof(struct smbc_dirent)); + smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen); + + reqd = dirent->dirlen; + + if (rem < reqd) { if (rem < count) { /* We managed to copy something */ @@ -2382,12 +2391,12 @@ static int smbc_getdents_ctx(SMBCCTX *context, SMBCFILE *dir, struct smbc_dirent } - dirent = dirlist->dirent; - memcpy(ndir, dirent, reqd); /* Copy the data in ... */ ((struct smbc_dirent *)ndir)->comment = - (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1); + (char *)(&((struct smbc_dirent *)ndir)->name + + dirent->namelen + + 1); ndir += reqd; @@ -2453,27 +2462,6 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) } - /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { - - mode = aDIR | aRONLY; - - } - else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - - if (strcmp(path, "\\") == 0) { - - mode = aDIR | aRONLY; - - } - else { - - mode = aRONLY; - smbc_stat_printjob(srv, path, &size, &m_time); - c_time = a_time = m_time; - - } - else { */ - if (!cli_mkdir(&srv->cli, path)) { errno = smbc_errno(context, &srv->cli); @@ -2491,7 +2479,7 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) static int smbc_rmdir_dirempty = True; -static void rmdir_list_fn(file_info *finfo, const char *mask, void *state) +static void rmdir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state) { if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0) @@ -3238,10 +3226,93 @@ static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx, } +/* Obtain the current dos attributes */ +static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, + TALLOC_CTX *ctx, + const char *filename, + SMBCSRV *srv) +{ + time_t m_time = 0, a_time = 0, c_time = 0; + size_t size = 0; + uint16 mode = 0; + SMB_INO_T inode = 0; + DOS_ATTR_DESC *ret; + + ret = talloc(ctx, sizeof(DOS_ATTR_DESC)); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + /* Obtain the DOS attributes */ + if (!smbc_getatr(context, srv, filename, &mode, &size, + &c_time, &a_time, &m_time, &inode)) { + + errno = smbc_errno(context, &srv->cli); + DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); + return NULL; + + } + + ret->mode = mode; + ret->size = size; + ret->a_time = a_time; + ret->c_time = c_time; + ret->m_time = m_time; + ret->inode = inode; + + return ret; +} + + +/* parse a ascii version of a security descriptor */ +static void dos_attr_parse(SMBCCTX *context, + DOS_ATTR_DESC *dad, + SMBCSRV *srv, + char *str) +{ + const char *p = str; + fstring tok; + + while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) { + + if (StrnCaseCmp(tok, "MODE:", 5) == 0) { + dad->mode = strtol(tok+5, NULL, 16); + continue; + } + + if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { + dad->size = strtoll(tok+5, NULL, 10); + continue; + } + + if (StrnCaseCmp(tok, "A_TIME:", 7) == 0) { + dad->a_time = strtoll(tok+7, NULL, 10); + continue; + } + + if (StrnCaseCmp(tok, "C_TIME:", 7) == 0) { + dad->c_time = strtoll(tok+7, NULL, 10); + continue; + } + + if (StrnCaseCmp(tok, "M_TIME:", 7) == 0) { + dad->m_time = strtoll(tok+7, NULL, 10); + continue; + } + + if (StrnCaseCmp(tok, "INODE:", 6) == 0) { + dad->inode = strtoll(tok+6, NULL, 10); + continue; + } + } +} + + /***************************************************** retrieve the acls for a file *******************************************************/ -static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli, +static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, struct cli_state *ipc_cli, POLICY_HND *pol, char *filename, char *name, char *buf, int bufsize) { @@ -3249,166 +3320,446 @@ static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli, int n = 0; int n_used; BOOL all; + BOOL all_nt; + BOOL all_dos; + BOOL some_nt; + BOOL some_dos; BOOL numeric = True; BOOL determine_size = (bufsize == 0); int fnum = -1; SEC_DESC *sd; fstring sidstr; char *p; + time_t m_time = 0, a_time = 0, c_time = 0; + size_t size = 0; + uint16 mode = 0; + SMB_INO_T ino = 0; + struct cli_state *cli = &srv->cli; - fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - - if (fnum == -1) { - DEBUG(5, ("cacl_get failed to open %s: %s\n", - filename, cli_errstr(cli))); - errno = 0; - return -1; - } + all = (StrnCaseCmp(name, "system.*", 8) == 0); + all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); + all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0); + some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); + some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); + numeric = (* (name + strlen(name) - 1) != '+'); - sd = cli_query_secdesc(cli, fnum, ctx); + n_used = 0; - if (!sd) { - DEBUG(5, ("cacl_get Failed to query old descriptor\n")); - errno = 0; - return -1; - } + /* + * If we are (possibly) talking to an NT or new system and some NT + * attributes have been requested... + */ + if (ipc_cli && (all || some_nt)) { + /* Point to the portion after "system.nt_sec_desc." */ + name += 19; /* if (all) this will be invalid but unused */ - cli_close(cli, fnum); + /* ... then obtain any NT attributes which were requested */ + fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - all = (*name == '*'); - numeric = (* (name + strlen(name) - 1) != '+'); + if (fnum == -1) { + DEBUG(5, ("cacl_get failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; + } - n_used = 0; + sd = cli_query_secdesc(cli, fnum, ctx); - if (all) { - if (determine_size) { - p = talloc_asprintf(ctx, - "REVISION:%d", sd->revision); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "REVISION:%d", sd->revision); + if (!sd) { + DEBUG(5, + ("cacl_get Failed to query old descriptor\n")); + errno = 0; + return -1; } - } else if (StrCaseCmp(name, "revision") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%d", sd->revision); - if (!p) { - errno = ENOMEM; - return -1; + + cli_close(cli, fnum); + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, + "REVISION:%d", + sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "REVISION:%d", sd->revision); + } + } else if (StrCaseCmp(name, "revision") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%d", sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%d", sd->revision); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%d", sd->revision); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; - /* Get owner and group sid */ + /* Get owner and group sid */ - if (sd->owner_sid) { - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, sd->owner_sid); - } else { - fstrcpy(sidstr, ""); - } + if (sd->owner_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, sd->owner_sid); + } else { + fstrcpy(sidstr, ""); + } - if (all) { - if (determine_size) { - p = talloc_asprintf(ctx, ",OWNER:%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, ",OWNER:%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",OWNER:%s", sidstr); } - n = strlen(p); + } else if (StrnCaseCmp(name, "owner", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%s", sidstr); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + + if (sd->grp_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, sd->grp_sid); } else { - n = snprintf(buf, bufsize, ",OWNER:%s", sidstr); + fstrcpy(sidstr, ""); } - } else if (StrnCaseCmp(name, "owner", 5) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%s", sidstr); - if (!p) { - errno = ENOMEM; + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, ",GROUP:%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",GROUP:%s", sidstr); + } + } else if (StrnCaseCmp(name, "group", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%s", sidstr); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + + /* Add aces to value buffer */ + for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { + + SEC_ACE *ace = &sd->dacl->ace[i]; + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, &ace->trustee); + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",ACL:" + "%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->info.mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",ACL:%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->info.mask); + } + } else if ((StrnCaseCmp(name, "acl", 3) == 0 && + StrCaseCmp(name + 3, sidstr) == 0) || + (StrnCaseCmp(name, "acl+", 4) == 0 && + StrCaseCmp(name + 4, sidstr) == 0)) { + if (determine_size) { + p = talloc_asprintf(ctx, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->info.mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->info.mask); + } + } + if (n > bufsize) { + errno = ERANGE; return -1; } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%s", sidstr); + buf += n; + n_used += n; + bufsize -= n; } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; + /* Restore name pointer to its original value */ + name -= 19; } - buf += n; - n_used += n; - bufsize -= n; - if (sd->grp_sid) { - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, sd->grp_sid); - } else { - fstrcpy(sidstr, ""); - } + if (all || some_dos) { + /* Point to the portion after "system.dos_attr." */ + name += 16; /* if (all) this will be invalid but unused */ - if (all) { - if (determine_size) { - p = talloc_asprintf(ctx, ",GROUP:%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; + /* Obtain the DOS attributes */ + if (!smbc_getatr(context, srv, filename, &mode, &size, + &c_time, &a_time, &m_time, &ino)) { + + errno = smbc_errno(context, &srv->cli); + return -1; + + } + + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + "%sMODE:0x%x", + (ipc_cli && + (all || some_nt) + ? "," + : ""), + mode); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%sMODE:0x%x", + (ipc_cli && + (all || some_nt) + ? "," + : ""), + mode); + } + } else if (StrCaseCmp(name, "mode") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "0x%x", mode); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "0x%x", mode); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, ",GROUP:%s", sidstr); } - } else if (StrnCaseCmp(name, "group", 5) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",SIZE:%llu", + (unsigned long long) size); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",SIZE:%llu", + (unsigned long long) size); + } + } else if (StrCaseCmp(name, "size") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, + "%llu", + (unsigned long long) size); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%llu", + (unsigned long long) size); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%s", sidstr); } - } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",C_TIME:%lu", c_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",C_TIME:%lu", c_time); + } + } else if (StrCaseCmp(name, "c_time") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", c_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%lu", c_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; - /* Add aces to value buffer */ - for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",A_TIME:%lu", a_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",A_TIME:%lu", a_time); + } + } else if (StrCaseCmp(name, "a_time") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", a_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%lu", a_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; - SEC_ACE *ace = &sd->dacl->ace[i]; - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, &ace->trustee); + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",M_TIME:%lu", m_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",M_TIME:%lu", m_time); + } + } else if (StrCaseCmp(name, "m_time") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", m_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%lu", m_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; - if (all) { + if (all || all_dos) { if (determine_size) { - p = talloc_asprintf(ctx, - ",ACL:%s:%d/%d/0x%08x", - sidstr, - ace->type, - ace->flags, - ace->info.mask); + p = talloc_asprintf(ctx, + ",INODE:%llu", + (unsigned long long) ino); if (!p) { errno = ENOMEM; return -1; @@ -3416,22 +3767,14 @@ static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli, n = strlen(p); } else { n = snprintf(buf, bufsize, - ",ACL:%s:%d/%d/0x%08x", - sidstr, - ace->type, - ace->flags, - ace->info.mask); + ",INODE:%llu", + (unsigned long long) ino); } - } else if ((StrnCaseCmp(name, "acl", 3) == 0 && - StrCaseCmp(name + 3, sidstr) == 0) || - (StrnCaseCmp(name, "acl+", 4) == 0 && - StrCaseCmp(name + 4, sidstr) == 0)) { + } else if (StrCaseCmp(name, "inode") == 0) { if (determine_size) { - p = talloc_asprintf(ctx, - "%d/%d/0x%08x", - ace->type, - ace->flags, - ace->info.mask); + p = talloc_asprintf(ctx, + "%llu", + (unsigned long long) ino); if (!p) { errno = ENOMEM; return -1; @@ -3439,23 +3782,28 @@ static int cacl_get(TALLOC_CTX *ctx, struct cli_state *cli, n = strlen(p); } else { n = snprintf(buf, bufsize, - "%d/%d/0x%08x", - ace->type, ace->flags, ace->info.mask); + "%llu", + (unsigned long long) ino); } } - if (n > bufsize) { + + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; } buf += n; n_used += n; bufsize -= n; - } + + /* Restore name pointer to its original value */ + name -= 16; + } if (n_used == 0) { errno = ENOATTR; return -1; } + return n_used; } @@ -3492,8 +3840,7 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli, the_acl = p + 1; } - sd = sec_desc_parse(ctx, ipc_cli, pol, - numeric, (char *) the_acl); + sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl); if (!sd) { errno = EINVAL; @@ -3653,12 +4000,14 @@ int smbc_setxattr_ctx(SMBCCTX *context, int flags) { int ret; + int ret2; SMBCSRV *srv; SMBCSRV *ipc_srv; fstring server, share, user, password, workgroup; pstring path; TALLOC_CTX *ctx; POLICY_HND pol; + DOS_ATTR_DESC *dad; if (!context || !context->internal || !context->internal->_initialized) { @@ -3675,8 +4024,7 @@ int smbc_setxattr_ctx(SMBCCTX *context, } - DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", - fname, name, (int) size, (char *) value)); + DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (const char*)value)); if (smbc_parse_path(context, fname, server, sizeof(server), @@ -3698,11 +4046,13 @@ int smbc_setxattr_ctx(SMBCCTX *context, return -1; /* errno set by smbc_server */ } - ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password, - &pol); - if (!ipc_srv) { - return -1; + if (! srv->no_nt_session) { + ipc_srv = smbc_attr_server(context, server, share, + workgroup, user, password, + &pol); + srv->no_nt_session = True; + } else { + ipc_srv = NULL; } ctx = talloc_init("smbc_setxattr"); @@ -3711,6 +4061,71 @@ int smbc_setxattr_ctx(SMBCCTX *context, return -1; } + /* + * Are they asking to set the entire set of known attributes? + */ + if (StrCaseCmp(name, "system.*") == 0 || + StrCaseCmp(name, "system.*+") == 0) { + /* Yup. */ + char *namevalue = + talloc_asprintf(ctx, "%s:%s", name+7, (const char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + return -1; + } + + if (ipc_srv) { + ret = cacl_set(ctx, &srv->cli, + &ipc_srv->cli, &pol, path, + namevalue, + (*namevalue == '*' + ? SMBC_XATTR_MODE_SET + : SMBC_XATTR_MODE_ADD), + flags); + } else { + ret = 0; + } + + /* get a DOS Attribute Descriptor with current attributes */ + dad = dos_attr_query(context, ctx, path, srv); + if (dad) { + /* Overwrite old with new, using what was provided */ + dos_attr_parse(context, dad, srv, namevalue); + + /* Set the new DOS attributes */ +#warning "Should try Set Path Info first, but it's not yet implemented" +#if 0 /* not yet implemented */ + if (! cli_setpathinfo(&srv->cli, path, + dad->c_time, + dad->a_time, + dad->m_time, + dad->mode)) { + if (!cli_setatr(&srv->cli, path, + dad->mode, dad->m_time)) { + errno = smbc_errno(context, &srv->cli); + } + } +#else + if (!cli_setatr(&srv->cli, path, + dad->mode, dad->m_time)) { + errno = smbc_errno(context, &srv->cli); + } +#endif + } + + /* we only fail if both NT and DOS sets failed */ + if (ret < 0 && ! dad) { + ret = -1; /* in case dad was null */ + } + else { + ret = 0; + } + + talloc_destroy(ctx); + return ret; + } + /* * Are they asking to set an access control element or to set * the entire access control list? @@ -3723,8 +4138,12 @@ int smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", name+19, (char *) value); - if (! namevalue) { + talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value); + + if (! ipc_srv) { + ret = -1; /* errno set by smbc_server() */ + } + else if (! namevalue) { errno = ENOMEM; ret = -1; } else { @@ -3748,8 +4167,13 @@ int smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", name+19, (char *) value); - if (! namevalue) { + talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value); + + if (! ipc_srv) { + + ret = -1; /* errno set by smbc_server() */ + } + else if (! namevalue) { errno = ENOMEM; ret = -1; } else { @@ -3769,8 +4193,13 @@ int smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", name+19, (char *) value); - if (! namevalue) { + talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value); + + if (! ipc_srv) { + /* errno set by smbc_server() */ + ret = -1; + } + else if (! namevalue) { errno = ENOMEM; ret = -1; } else { @@ -3782,6 +4211,67 @@ int smbc_setxattr_ctx(SMBCCTX *context, return ret; } + /* + * Are they asking to set a DOS attribute? + */ + if (StrCaseCmp(name, "system.dos_attr.*") == 0 || + StrCaseCmp(name, "system.dos_attr.mode") == 0 || + StrCaseCmp(name, "system.dos_attr.c_time") == 0 || + StrCaseCmp(name, "system.dos_attr.a_time") == 0 || + StrCaseCmp(name, "system.dos_attr.m_time") == 0) { + + /* get a DOS Attribute Descriptor with current attributes */ + dad = dos_attr_query(context, ctx, path, srv); + if (dad) { + char *namevalue = + talloc_asprintf(ctx, "%s:%s", name+16, (const char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + /* Overwrite old with provided new params */ + dos_attr_parse(context, dad, srv, namevalue); + + /* Set the new DOS attributes */ +#warning "Should try Set Path Info first, but it's not yet implemented" +#if 0 /* not yet implemented */ + ret2 = cli_setpathinfo(&srv->cli, path, + dad->c_time, + dad->a_time, + dad->m_time, + dad->mode); + if (! ret2) { + ret2 = cli_setatr(&srv->cli, path, + dad->mode, + dad->m_time); + if (! ret2) { + errno = smbc_errno(context, + &srv->cli); + } + } +#else + ret2 = cli_setatr(&srv->cli, path, + dad->mode, dad->m_time); + if (! ret2) { + errno = smbc_errno(context, &srv->cli); + } +#endif + + /* ret2 has True (success) / False (failure) */ + if (ret2) { + ret = 0; + } else { + ret = -1; + } + } + } else { + ret = -1; + } + + talloc_destroy(ctx); + return ret; + } + /* Unsupported attribute name */ talloc_destroy(ctx); errno = EINVAL; @@ -3802,6 +4292,7 @@ int smbc_getxattr_ctx(SMBCCTX *context, TALLOC_CTX *ctx; POLICY_HND pol; + if (!context || !context->internal || !context->internal->_initialized) { @@ -3839,11 +4330,15 @@ int smbc_getxattr_ctx(SMBCCTX *context, return -1; /* errno set by smbc_server */ } - ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password, - &pol); - if (!ipc_srv) { - return -1; + if (! srv->no_nt_session) { + ipc_srv = smbc_attr_server(context, server, share, + workgroup, user, password, + &pol); + if (! ipc_srv) { + srv->no_nt_session = True; + } + } else { + ipc_srv = NULL; } ctx = talloc_init("smbc:getxattr"); @@ -3853,7 +4348,9 @@ int smbc_getxattr_ctx(SMBCCTX *context, } /* Are they requesting a supported attribute? */ - if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + if (StrCaseCmp(name, "system.*") == 0 || + StrCaseCmp(name, "system.*+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || @@ -3861,13 +4358,21 @@ int smbc_getxattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 || + StrCaseCmp(name, "system.dos_attr.*") == 0 || + StrCaseCmp(name, "system.dos_attr.mode") == 0 || + StrCaseCmp(name, "system.dos_attr.size") == 0 || + StrCaseCmp(name, "system.dos_attr.c_time") == 0 || + StrCaseCmp(name, "system.dos_attr.a_time") == 0 || + StrCaseCmp(name, "system.dos_attr.m_time") == 0 || + StrCaseCmp(name, "system.dos_attr.inode") == 0) { /* Yup. */ - ret = cacl_get(ctx, &srv->cli, - &ipc_srv->cli, &pol, - (char *) path, (char *) name + 19, - (char *) value, size); + ret = cacl_get(context, ctx, srv, + ipc_srv == NULL ? NULL : &ipc_srv->cli, + &pol, + (char *) path, (char *) name, + (const char *) value, size); if (ret < 0 && errno == 0) { errno = smbc_errno(context, &srv->cli); } @@ -3931,20 +4436,19 @@ int smbc_removexattr_ctx(SMBCCTX *context, return -1; /* errno set by smbc_server */ } - ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password, - &pol); - if (!ipc_srv) { - return -1; + if (! srv->no_nt_session) { + ipc_srv = smbc_attr_server(context, server, share, + workgroup, user, password, + &pol); + srv->no_nt_session = True; + } else { + ipc_srv = NULL; } - ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password, - &pol); - if (!ipc_srv) { - return -1; + if (! ipc_srv) { + return -1; /* errno set by smbc_attr_server */ } - + ctx = talloc_init("smbc_removexattr"); if (!ctx) { errno = ENOMEM; @@ -3996,10 +4500,12 @@ int smbc_listxattr_ctx(SMBCCTX *context, { /* * This isn't quite what listxattr() is supposed to do. This returns - * the complete set of attributes, always, rather than only those + * the complete set of attribute names, always, rather than only those * attribute names which actually exist for a file. Hmmm... */ const char supported[] = + "system.*\0" + "system.*+\0" "system.nt_sec_desc.revision\0" "system.nt_sec_desc.owner\0" "system.nt_sec_desc.owner+\0" @@ -4009,6 +4515,11 @@ int smbc_listxattr_ctx(SMBCCTX *context, "system.nt_sec_desc.acl+\0" "system.nt_sec_desc.*\0" "system.nt_sec_desc.*+\0" + "system.dos_attr.*\0" + "system.dos_attr.mode\0" + "system.dos_attr.c_time\0" + "system.dos_attr.a_time\0" + "system.dos_attr.m_time\0" ; if (size == 0) { @@ -4295,6 +4806,8 @@ SMBCCTX * smbc_new_context(void) return NULL; } + context->flags = SMBCCTX_FLAG_CTXVER; + ZERO_STRUCTP(context->internal); @@ -4302,37 +4815,41 @@ SMBCCTX * smbc_new_context(void) context->debug = 0; context->timeout = 20000; /* 20 seconds */ - context->open = smbc_open_ctx; - context->creat = smbc_creat_ctx; - context->read = smbc_read_ctx; - context->write = smbc_write_ctx; - context->close = smbc_close_ctx; - context->unlink = smbc_unlink_ctx; - context->rename = smbc_rename_ctx; - context->lseek = smbc_lseek_ctx; - context->stat = smbc_stat_ctx; - context->fstat = smbc_fstat_ctx; - context->opendir = smbc_opendir_ctx; - context->closedir = smbc_closedir_ctx; - context->readdir = smbc_readdir_ctx; - context->getdents = smbc_getdents_ctx; - context->mkdir = smbc_mkdir_ctx; - context->rmdir = smbc_rmdir_ctx; - context->telldir = smbc_telldir_ctx; - context->lseekdir = smbc_lseekdir_ctx; - context->fstatdir = smbc_fstatdir_ctx; - context->chmod = smbc_chmod_ctx; - context->utimes = smbc_utimes_ctx; - context->setxattr = smbc_setxattr_ctx; - context->getxattr = smbc_getxattr_ctx; - context->removexattr = smbc_removexattr_ctx; - context->listxattr = smbc_listxattr_ctx; - context->open_print_job = smbc_open_print_job_ctx; - context->print_file = smbc_print_file_ctx; - context->list_print_jobs = smbc_list_print_jobs_ctx; - context->unlink_print_job = smbc_unlink_print_job_ctx; - - context->callbacks.check_server_fn = smbc_check_server; + context->internal->options.browse_max_lmb_count = 3; /* # LMBs to query */ + context->internal->options.urlencode_readdir_entries = False;/* backward compat */ + context->internal->options.one_share_per_server = False;/* backward compat */ + + context->open = smbc_open_ctx; + context->creat = smbc_creat_ctx; + context->read = smbc_read_ctx; + context->write = smbc_write_ctx; + context->close = smbc_close_ctx; + context->unlink = smbc_unlink_ctx; + context->rename = smbc_rename_ctx; + context->lseek = smbc_lseek_ctx; + context->stat = smbc_stat_ctx; + context->fstat = smbc_fstat_ctx; + context->opendir = smbc_opendir_ctx; + context->closedir = smbc_closedir_ctx; + context->readdir = smbc_readdir_ctx; + context->getdents = smbc_getdents_ctx; + context->mkdir = smbc_mkdir_ctx; + context->rmdir = smbc_rmdir_ctx; + context->telldir = smbc_telldir_ctx; + context->lseekdir = smbc_lseekdir_ctx; + context->fstatdir = smbc_fstatdir_ctx; + context->chmod = smbc_chmod_ctx; + context->utimes = smbc_utimes_ctx; + context->setxattr = smbc_setxattr_ctx; + context->getxattr = smbc_getxattr_ctx; + context->removexattr = smbc_removexattr_ctx; + context->listxattr = smbc_listxattr_ctx; + context->open_print_job = smbc_open_print_job_ctx; + context->print_file = smbc_print_file_ctx; + context->list_print_jobs = smbc_list_print_jobs_ctx; + context->unlink_print_job = smbc_unlink_print_job_ctx; + + context->callbacks.check_server_fn = smbc_check_server; context->callbacks.remove_unused_server_fn = smbc_remove_unused_server; smbc_default_cache_functions(context); @@ -4548,3 +5065,11 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) return context; } + + +/* Return the verion of samba, and thus libsmbclient */ +const char * +smbc_version(void) +{ + return samba_version_string(); +} -- cgit From 44f1a1a510d0776fb4a892e65f4c11fa19418fb7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Mar 2005 10:35:41 +0000 Subject: r5738: fix my build breakage; fix a few compiler warnings (This used to be commit acbe9efeb6de33610776560978f8632cbb847821) --- source3/libsmb/libsmb_cache.c | 2 +- source3/libsmb/libsmbclient.c | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index dabf5a527d..71399f14db 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -143,7 +143,7 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, * a connection to the server (other than the * attribute server connection) is cool. */ - if (context->options.one_share_per_server) { + if (context->internal->options.one_share_per_server) { /* * The currently connected share name * doesn't match the requested share, so diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index bc15fe7d50..c876720cfa 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4370,9 +4370,7 @@ int smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, ipc_srv == NULL ? NULL : &ipc_srv->cli, - &pol, - (char *) path, (char *) name, - (const char *) value, size); + &pol, path, name, (const char *) value, size); if (ret < 0 && errno == 0) { errno = smbc_errno(context, &srv->cli); } -- cgit From 51310680ce751e30fd5b143e87d025e0dc92ff3c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Mar 2005 17:01:30 +0000 Subject: r5752: implement derrell's solution for binary compatibilty in the _SMBCCTX structure; note that we break compat with 3.0.11 but are ok with earlier versions (This used to be commit 6e8d171551bfe480cb1a526469defc33276550f6) --- source3/libsmb/libsmb_cache.c | 2 +- source3/libsmb/libsmbclient.c | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 71399f14db..dabf5a527d 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -143,7 +143,7 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, * a connection to the server (other than the * attribute server connection) is cool. */ - if (context->internal->options.one_share_per_server) { + if (context->options.one_share_per_server) { /* * The currently connected share name * doesn't match the requested share, so diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c876720cfa..441ca96478 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -571,7 +571,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, * If we found a connection and we're only allowed one share per * server... */ - if (srv && *share != '\0' && context->internal->options.one_share_per_server) { + if (srv && *share != '\0' && context->options.one_share_per_server) { /* * ... then if there's no current connection to the share, @@ -1932,9 +1932,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } /* Determine how many local master browsers to query */ - max_lmb_count = (context->internal->options.browse_max_lmb_count == 0 + max_lmb_count = (context->options.browse_max_lmb_count == 0 ? INT_MAX - : context->internal->options.browse_max_lmb_count); + : context->options.browse_max_lmb_count); pstrcpy(u_info.username, user); pstrcpy(u_info.password, password); @@ -2216,7 +2216,7 @@ static void smbc_readdir_internal(SMBCCTX * context, struct smbc_dirent *src, int max_namebuf_len) { - if (context->internal->options.urlencode_readdir_entries) { + if (context->options.urlencode_readdir_entries) { /* url-encode the name. get back remaining buffer space */ max_namebuf_len = @@ -4804,8 +4804,6 @@ SMBCCTX * smbc_new_context(void) return NULL; } - context->flags = SMBCCTX_FLAG_CTXVER; - ZERO_STRUCTP(context->internal); @@ -4813,9 +4811,9 @@ SMBCCTX * smbc_new_context(void) context->debug = 0; context->timeout = 20000; /* 20 seconds */ - context->internal->options.browse_max_lmb_count = 3; /* # LMBs to query */ - context->internal->options.urlencode_readdir_entries = False;/* backward compat */ - context->internal->options.one_share_per_server = False;/* backward compat */ + context->options.browse_max_lmb_count = 3; /* # LMBs to query */ + context->options.urlencode_readdir_entries = False;/* backward compat */ + context->options.one_share_per_server = False;/* backward compat */ context->open = smbc_open_ctx; context->creat = smbc_creat_ctx; -- cgit From 3b7dccf076628114d4fb1f67ab7aa05457de367d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Mar 2005 18:21:35 +0000 Subject: r5804: Revert the signing change by Nalin Dahyabhai . Seems to be incorrect (several user reports). Jeremy. (This used to be commit 0abfb67c79dde280b3dae14a7c7bcdb5f4d58e44) --- source3/libsmb/smb_signing.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index df69ff3e41..500ff7cc6e 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -277,14 +277,17 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Init(&md5_ctx); /* intialise with the key */ + MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); +#if 0 + /* JRA - apparently this is incorrect. */ /* NB. When making and verifying SMB signatures, Windows apparently zero-pads the key to 128 bits if it isn't long enough. From Nalin Dahyabhai */ - MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); if (data->mac_key.length < sizeof(key_buf)) { memset(key_buf, 0, sizeof(key_buf)); MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); } +#endif /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); -- cgit From d177f1bc8f0cb5ad91c9146871ba2e93eb2988d2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 15 Mar 2005 20:12:51 +0000 Subject: r5806: * fix a couple more segvs in spoolss * comment out unused variable after jra's change to revert the 56bit des smb signing changes (This used to be commit 13ed08cd2a1097021cc44f4109859ba89db7df81) --- source3/libsmb/smb_signing.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 500ff7cc6e..f0f2024e7b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -255,7 +255,10 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, const size_t offset_end_of_sig = (smb_ss_field + 8); unsigned char sequence_buf[8]; struct MD5Context md5_ctx; +#if 0 + /* JRA - apparently this is incorrect. */ unsigned char key_buf[16]; +#endif /* * Firstly put the sequence number into the first 4 bytes. -- cgit From 7069d481c0c96edfa552aa74b192f63125416228 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Mar 2005 20:07:08 +0000 Subject: r5835: Make smbclient obey the max protocol argument again. Jeremy. (This used to be commit 7cb9618e5de8aae5e910e620e70ea130b76f6099) --- source3/libsmb/clidfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e4308fdb5a..dcffdf42fe 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -37,10 +37,10 @@ static pstring password; static BOOL use_kerberos; static BOOL got_pass; static int signing_state; +int max_protocol = PROTOCOL_NT1; static int port; static int name_type = 0x20; -static int max_protocol = PROTOCOL_NT1; static BOOL have_ip; static struct in_addr dest_ip; -- cgit From 3fc141baace52635dd5757f6b9d997c37f87deca Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Mar 2005 00:37:39 +0000 Subject: r5840: Fix findfirst/findnext with protocol level < NT1. Jeremy. (This used to be commit d53b5891a7d372b3ed2488bac06939d29388f709) --- source3/libsmb/clitrans.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3f1afa75d6..27da63ccda 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -195,11 +195,12 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, /* * An NT RPC pipe call can return ERRDOS, ERRmoredata * to a trans call. This is not an error and should not - * be treated as such. + * be treated as such. Note that STATUS_NO_MORE_FILES is + * returned when a trans2 findfirst/next finishes. */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status)) { + if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) { cli_signing_trans_stop(cli); return False; } -- cgit From 9a4e3f7e6fdffeb51ac608aecdb029ae2af7cb34 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 17 Mar 2005 04:55:00 +0000 Subject: r5851: BUG 2456: reported by Jason Mader; remove non standard pragma (my fault); should fix some builds with non-gcc compilers (This used to be commit 300150a1bee1bf927236c6d9942784a1359e7054) --- source3/libsmb/libsmbclient.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 441ca96478..3761074e04 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4094,7 +4094,6 @@ int smbc_setxattr_ctx(SMBCCTX *context, dos_attr_parse(context, dad, srv, namevalue); /* Set the new DOS attributes */ -#warning "Should try Set Path Info first, but it's not yet implemented" #if 0 /* not yet implemented */ if (! cli_setpathinfo(&srv->cli, path, dad->c_time, @@ -4233,7 +4232,6 @@ int smbc_setxattr_ctx(SMBCCTX *context, dos_attr_parse(context, dad, srv, namevalue); /* Set the new DOS attributes */ -#warning "Should try Set Path Info first, but it's not yet implemented" #if 0 /* not yet implemented */ ret2 = cli_setpathinfo(&srv->cli, path, dad->c_time, -- cgit From 4b831f8e16d305666b0f2b018c35f5427efc21cc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 15:12:50 +0000 Subject: r5952: BUG 2469: patch from Jason Mader to cleanup compiler warning when not using krb5 (This used to be commit 19a639ac468237b22f16d917c0150fbf10c9623e) --- source3/libsmb/cliconnect.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index aa37a29391..c5154827c6 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -702,7 +702,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, char *principal; char *OIDs[ASN1_MAX_OIDS]; int i; +#ifdef HAVE_KRB5 BOOL got_kerberos_mechanism = False; +#endif DATA_BLOB blob; DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); @@ -731,10 +733,12 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { DEBUG(3,("got OID=%s\n", OIDs[i])); +#ifdef HAVE_KRB5 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || strcmp(OIDs[i], OID_KERBEROS5) == 0) { got_kerberos_mechanism = True; } +#endif free(OIDs[i]); } DEBUG(3,("got principal=%s\n", principal)); -- cgit From 0d579953042b5c361ead51f57957accb3706e3f0 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 15:39:24 +0000 Subject: r5953: more compiler cleanups; moved SID_LIST from smb.h to privileges.c to cleanup the name space (This used to be commit 7dfafa712deb115e425c7367296400c54827a217) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3761074e04..44f77117de 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4368,7 +4368,7 @@ int smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, ipc_srv == NULL ? NULL : &ipc_srv->cli, - &pol, path, name, (const char *) value, size); + &pol, path, name, (char *) value, size); if (ret < 0 && errno == 0) { errno = smbc_errno(context, &srv->cli); } -- cgit From 93e04e941e15034c8e7aa1faedc74ce536049153 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 18:07:58 +0000 Subject: r5961: final round of compiler warning fixes based on feedback from Jason Mader (This used to be commit 9e77da9320c900b3e437d534e31fa5ff81e9acfd) --- source3/libsmb/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index d4b0557411..55e06ffe97 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -513,7 +513,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) *new_pw_len is the length in bytes of the possibly mulitbyte returned password including termination. ************************************************************/ -BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd, +BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, int new_pwrd_size, uint32 *new_pw_len, int string_flags) { -- cgit From b360f556a5c1a6e9ed7a941451eca5d278a8a633 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Mar 2005 20:54:19 +0000 Subject: r5967: Fix typo bug where flags overwrote info level. Jeremy. (This used to be commit 214a2cbe5aed9f0540b03350b60d0eec1c61bad8) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index dcac17d24a..704babc919 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -205,7 +205,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,6,0); /* ff_resume_key */ /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren can miss filenames. Use last filename continue instead. JRA */ - SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ + SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); -- cgit From b3e57cb3ffb6eeb3edb1a7b02be35f70e1e7dfcf Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 22 Mar 2005 21:17:01 +0000 Subject: r5968: derrell's large file fix for libsmbclient (BUG 2505) (This used to be commit 85be4c5df398faa6c5bfacd1f9d2f12c39d411e1) --- source3/libsmb/clifile.c | 4 +-- source3/libsmb/clirap.c | 30 ++++++++++----------- source3/libsmb/libsmbclient.c | 63 +++++++++++++++++++++---------------------- 3 files changed, 48 insertions(+), 49 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 9d20ed3adc..93492ec082 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1071,7 +1071,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ ****************************************************************************/ BOOL cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, SMB_BIG_UINT *size, + uint16 *attr, SMB_OFF_T *size, time_t *c_time, time_t *a_time, time_t *m_time) { memset(cli->outbuf,'\0',smb_size); @@ -1122,7 +1122,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, ****************************************************************************/ BOOL cli_getatr(struct cli_state *cli, const char *fname, - uint16 *attr, size_t *size, time_t *t) + uint16 *attr, SMB_OFF_T *size, time_t *t) { char *p; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 8e6742d438..1f6a99d4be 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -382,7 +382,7 @@ send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - size_t *size, uint16 *mode) + SMB_OFF_T *size, uint16 *mode) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -462,7 +462,7 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, size_t *size, uint16 *mode, + time_t *w_time, SMB_OFF_T *size, uint16 *mode, SMB_INO_T *ino) { unsigned int data_len = 0; @@ -516,7 +516,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, *mode = SVAL(rdata, 32); } if (size) { - *size = IVAL(rdata, 48); + *size = IVAL2_TO_SMB_BIG_UINT(rdata,48); } if (ino) { *ino = IVAL(rdata, 64); @@ -546,11 +546,11 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum, SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO); if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ )) { return False; } @@ -575,7 +575,7 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum, send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, - uint16 *mode, size_t *size, + uint16 *mode, SMB_OFF_T *size, time_t *c_time, time_t *a_time, time_t *m_time, time_t *w_time, SMB_INO_T *ino) { @@ -596,11 +596,11 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, data_len, cli->max_xmit /* data, length, max */ )) { return False; } @@ -631,7 +631,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, *mode = SVAL(rdata, 32); } if (size) { - *size = IVAL(rdata, 48); + *size = IVAL2_TO_SMB_BIG_UINT(rdata,48); } if (ino) { *ino = IVAL(rdata, 64); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 44f77117de..5289f36d0f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1017,6 +1017,17 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t { int ret; + /* + * offset: + * + * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- + * appears to pass file->offset (which is type off_t) differently than + * a local variable of type off_t. Using local variable "offset" in + * the call to cli_read() instead of file->offset fixes a problem + * retrieving data at an offset greater than 4GB. + */ + off_t offset = file->offset; + if (!context || !context->internal || !context->internal->_initialized) { @@ -1043,7 +1054,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t } - ret = cli_read(&file->srv->cli, file->cli_fd, buf, file->offset, count); + ret = cli_read(&file->srv->cli, file->cli_fd, buf, offset, count); if (ret < 0) { @@ -1067,6 +1078,7 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { int ret; + off_t offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ if (!context || !context->internal || !context->internal->_initialized) { @@ -1092,7 +1104,7 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ } - ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, file->offset, count); + ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, offset, count); if (ret <= 0) { @@ -1165,7 +1177,7 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo */ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, - uint16 *mode, size_t *size, + uint16 *mode, SMB_OFF_T *size, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino) { @@ -1272,7 +1284,7 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) if (errno == EACCES) { /* Check if the file is a directory */ int saverr = errno; - size_t size = 0; + SMB_OFF_T size = 0; uint16 mode = 0; time_t m_time = 0, a_time = 0, c_time = 0; SMB_INO_T ino = 0; @@ -1396,7 +1408,7 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence) { - size_t size; + SMB_OFF_T size; if (!context || !context->internal || !context->internal->_initialized) { @@ -1482,7 +1494,8 @@ ino_t smbc_inode(SMBCCTX *context, const char *name) */ static -int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, size_t size, int mode) +int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, + SMB_OFF_T size, int mode) { st->st_mode = 0; @@ -1532,7 +1545,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) fstring server, share, user, password, workgroup; pstring path; time_t m_time = 0, a_time = 0, c_time = 0; - size_t size = 0; + SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; @@ -1602,7 +1615,7 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) { time_t c_time, a_time, m_time; - size_t size; + SMB_OFF_T size; uint16 mode; SMB_INO_T ino = 0; @@ -1629,15 +1642,12 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) { - SMB_BIG_UINT b_size = size; if (!cli_getattrE(&file->srv->cli, file->cli_fd, - &mode, &b_size, &c_time, &a_time, &m_time)) { + &mode, &size, &c_time, &a_time, &m_time)) { errno = EINVAL; return -1; - } else - size = b_size; - + } } st->st_ino = ino; @@ -1960,7 +1970,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } for (i = 0; i < count && i < max_lmb_count; i++) { - DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); + DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), inet_ntoa(ip_list[i].ip))); cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info); /* cli == NULL is the master browser refused to talk or @@ -1983,12 +1993,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) srv = smbc_server(context, server, "IPC$", workgroup, user, password); if (!srv) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - return NULL; + continue; } dir->srv = srv; @@ -1999,13 +2004,7 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, (void *)dir)) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - - return NULL; - + continue; } } } else { @@ -3233,7 +3232,7 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, SMBCSRV *srv) { time_t m_time = 0, a_time = 0, c_time = 0; - size_t size = 0; + SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T inode = 0; DOS_ATTR_DESC *ret; @@ -3245,7 +3244,7 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, } /* Obtain the DOS attributes */ - if (!smbc_getatr(context, srv, filename, &mode, &size, + if (!smbc_getatr(context, srv, (char *) filename, &mode, &size, &c_time, &a_time, &m_time, &inode)) { errno = smbc_errno(context, &srv->cli); @@ -3331,7 +3330,7 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, fstring sidstr; char *p; time_t m_time = 0, a_time = 0, c_time = 0; - size_t size = 0; + SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; struct cli_state *cli = &srv->cli; @@ -3840,7 +3839,7 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli, the_acl = p + 1; } - sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, the_acl); + sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, (char *) the_acl); if (!sd) { errno = EINVAL; @@ -4368,7 +4367,7 @@ int smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, ipc_srv == NULL ? NULL : &ipc_srv->cli, - &pol, path, name, (char *) value, size); + &pol, path, (char*)name, (char *) value, size); if (ret < 0 && errno == 0) { errno = smbc_errno(context, &srv->cli); } -- cgit From f8f090ad2471056ae77705ce55eddf06419ada3d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Mar 2005 21:22:59 +0000 Subject: r5970: Fix old bug where ff_searchcount was being compared -1 ! This caused a filename to be processed twice. Jeremy. (This used to be commit 2ed7e30cbb3e194a08d5d9b46993652666193bec) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 704babc919..5138bca8df 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -283,7 +283,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* put in a length for the last entry, to ensure we can chain entries into the next packet */ - for (p2=p,i=0;i<(ff_searchcount-1);i++) { + for (p2=p,i=0;i Date: Tue, 22 Mar 2005 21:43:51 +0000 Subject: r5973: Fix up overwrite of last 2 bytes on clilist (could cause coredump). Jeremy. (This used to be commit b0de2d761f6697ca1f4859ba098af6162ab42027) --- source3/libsmb/clilist.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 5138bca8df..33bf32bb94 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -281,14 +281,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, dirlist = tdl; } - /* put in a length for the last entry, to ensure we can chain entries - into the next packet */ + /* we might need the lastname for continuations */ for (p2=p,i=0;i 0) { pstrcpy(mask, finfo.name); } else { -- cgit From 656140bf4b0c62e1bfdb4ea59db15808ae25edec Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Mar 2005 22:04:01 +0000 Subject: r5975: Re-arrange code and comments to make more sense. Jeremy. (This used to be commit 08616ad80d96d1b7b558eec036bafb4bf3663942) --- source3/libsmb/clilist.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 33bf32bb94..eea4391e55 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -269,18 +269,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* point to the data bytes */ p = rdata; - /* we might need the lastname for continuations */ - - /* and add them to the dirlist pool */ - tdl = SMB_REALLOC(dirlist,dirlist_len + data_len); - - if (!tdl) { - DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); - break; - } else { - dirlist = tdl; - } - /* we might need the lastname for continuations */ for (p2=p,i=0;i Date: Tue, 22 Mar 2005 23:45:57 +0000 Subject: r5981: Hack to fix DFS code to work with Win98 server. JERRY PLEASE REVIEW THIS ! I don't think this is correct - it just happens to work and fix bug #2530 to return all the files. Jeremy. (This used to be commit 1ee180a6dd7f8d787396f359a8ff3ed25433357b) --- source3/libsmb/clidfs.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index dcffdf42fe..e2456800dd 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -595,8 +595,26 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* we got an error, check for DFS referral */ - if ( !cli_dfs_check_error(rootcli) ) + if ( !cli_dfs_check_error(rootcli) ) { + /* Check for Win98 server - doesn't support this call. */ + uint32 flgs2 = SVAL(rootcli->inbuf,smb_flg2); + + /* only deal with DS when we negotiated NT_STATUS codes and UNICODE */ + + if ( !( (flgs2&FLAGS2_32_BIT_ERROR_CODES) && (flgs2&FLAGS2_UNICODE_STRINGS) ) ) { + uint8 eclass = 0; + uint32 ecode = 0; + cli_dos_error(rootcli, &eclass, &ecode); + if ((eclass == ERRDOS) && (ecode == ERRbadfunc)) { + rootcli->dfsroot = 0; + *targetcli = rootcli; + pstrcpy( targetpath, path ); + return True; + } + } + return False; + } /* check for the referral */ -- cgit From 7478d77b315c71fba9d807d171907639f8bc5721 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Mar 2005 03:55:02 +0000 Subject: r5991: Fixup last entry offset correctly for level 260. Should fix bug found by Derrell.Lipman@UnwiredUniverse.com. Jeremy. (This used to be commit 5ded615679e346d1ea155cde3413396d3e3c3a6b) --- source3/libsmb/clilist.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index eea4391e55..0f1b9efed0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -29,7 +29,7 @@ by NT and 2 is used by OS/2 ****************************************************************************/ -static int interpret_long_filename(struct cli_state *cli, +static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { extern file_info def_finfo; @@ -130,12 +130,12 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, 0); - return SVAL(base, 0); + return (size_t)IVAL(base, 0); } } DEBUG(1,("Unknown long filename format %d\n",level)); - return(SVAL(p,0)); + return (size_t)IVAL(base,0); } /**************************************************************************** @@ -168,6 +168,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, unsigned int param_len, data_len; uint16 setup; pstring param; + const char *mnt; /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; @@ -271,6 +272,10 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* we might need the lastname for continuations */ for (p2=p,i=0;i Date: Wed, 23 Mar 2005 15:36:48 +0000 Subject: r5994: proper fix for smbclient and win98 file servers; check the WCT value in the tcon&X reply before setting the cli_state->dfsroot flag (This used to be commit d3822d889dbc0812335e9242566256a0f88bc00d) --- source3/libsmb/cliconnect.c | 8 ++++++-- source3/libsmb/clidfs.c | 20 +------------------- 2 files changed, 7 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c5154827c6..4208d6378d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -982,8 +982,12 @@ BOOL cli_send_tconX(struct cli_state *cli, cli->win95 = True; } - if ( cli->protocol >= PROTOCOL_LANMAN2 ) - cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS); + /* Make sure that we have the optional support 16-bit field. WCT > 2 */ + /* Avoids issues when connecting to Win9x boxes sharing files */ + + cli->dfsroot = False; + if ( (CVAL(cli->inbuf, smb_wct))>2 && cli->protocol >= PROTOCOL_LANMAN2 ) + cli->dfsroot = (SVAL( cli->inbuf, smb_vwv2 ) & SMB_SHARE_IN_DFS) ? True : False; cli->cnum = SVAL(cli->inbuf,smb_tid); return True; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e2456800dd..21046cd380 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -595,26 +595,8 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* we got an error, check for DFS referral */ - if ( !cli_dfs_check_error(rootcli) ) { - /* Check for Win98 server - doesn't support this call. */ - uint32 flgs2 = SVAL(rootcli->inbuf,smb_flg2); - - /* only deal with DS when we negotiated NT_STATUS codes and UNICODE */ - - if ( !( (flgs2&FLAGS2_32_BIT_ERROR_CODES) && (flgs2&FLAGS2_UNICODE_STRINGS) ) ) { - uint8 eclass = 0; - uint32 ecode = 0; - cli_dos_error(rootcli, &eclass, &ecode); - if ((eclass == ERRDOS) && (ecode == ERRbadfunc)) { - rootcli->dfsroot = 0; - *targetcli = rootcli; - pstrcpy( targetpath, path ); - return True; - } - } - + if ( !cli_dfs_check_error(rootcli) ) return False; - } /* check for the referral */ -- cgit From 259d44dbb2c2239339f6888fd5da12632abcbb28 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Mar 2005 16:11:23 +0000 Subject: r6038: adding more flesh to 'net rpc service' open and close the service control manager. Also experimenting with ideas for cli_xxx() interface. (This used to be commit 4da89ef17b8c4644b97b923cebfe8e446b508b4d) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 96c052c7c5..daac5c4664 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -31,6 +31,7 @@ typedef const struct werror_code_struct dos_errs[] = { { "WERR_OK", WERR_OK }, + { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, { "WERR_BADFILE", WERR_BADFILE }, { "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED }, { "WERR_BADFID", WERR_BADFID }, -- cgit From 66e8ed2632f8efb4e749a79609eb34dc488aacdc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 25 Mar 2005 00:38:30 +0000 Subject: r6051: finish off net rpc service stop net rpc service start net rpc service pause net rpc service resume (This used to be commit a7fb2c50b07a7d9965675272a71f42beba92acfe) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index daac5c4664..0dca265348 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -70,6 +70,7 @@ werror_code_struct dos_errs[] = { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { "WERR_IO_PENDING", WERR_IO_PENDING }, + { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL }, { NULL, W_ERROR(0) } }; -- cgit From 0411d1a73529bf517038ac496b18fd71ada64eed Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 28 Mar 2005 19:52:23 +0000 Subject: r6102: add support for opening a file for write with O_APPEND in libsmbclient (This used to be commit 542922cb2e5c8e7522f14492418686c339f0a5a4) --- source3/libsmb/libsmbclient.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 5289f36d0f..87ca030b10 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -80,6 +80,9 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { return False; } +static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file); +static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence); + extern BOOL in_client; /* @@ -968,6 +971,37 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m file->file = True; DLIST_ADD(context->internal->_files, file); + + /* + * If the file was opened in O_APPEND mode, all write + * operations should be appended to the file. To do that, + * though, using this protocol, would require a getattrE() + * call for each and every write, to determine where the end + * of the file is. (There does not appear to be an append flag + * in the protocol.) Rather than add all of that overhead of + * retrieving the current end-of-file offset prior to each + * write operation, we'll assume that most append operations + * will continuously write, so we'll just set the offset to + * the end of the file now and hope that's adequate. + * + * Note to self: If this proves inadequate, and O_APPEND + * should, in some cases, be forced for each write, add a + * field in the context options structure, for + * "strict_append_mode" which would select between the current + * behavior (if FALSE) or issuing a getattrE() prior to each + * write and forcing the write to the end of the file (if + * TRUE). Adding that capability will likely require adding + * an "append" flag into the _SMBCFILE structure to track + * whether a file was opened in O_APPEND mode. -- djl + */ + if (flags & O_APPEND) { + if (smbc_lseek_ctx(context, file, 0, SEEK_END) < 0) { + (void) smbc_close_ctx(context, file); + errno = ENXIO; + return NULL; + } + } + return file; } @@ -4367,7 +4401,7 @@ int smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, ipc_srv == NULL ? NULL : &ipc_srv->cli, - &pol, path, (char*)name, (char *) value, size); + &pol, path, (char *) name, (char *) value, size); if (ret < 0 && errno == 0) { errno = smbc_errno(context, &srv->cli); } -- cgit From 3fb83080723f53a7dbd51cafe291bd0eae9197a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Mar 2005 00:47:57 +0000 Subject: r6120: Added "volume" command to smbclient that prints out the volume name and serial number. Jeremy. (This used to be commit c69623072e4112a4719867ea4809f5145b3cb64c) --- source3/libsmb/clifsinfo.c | 115 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 22c8bff3ba..2874ee6ca1 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -132,3 +132,118 @@ cleanup: return ret; } + +BOOL cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number) +{ + BOOL ret = False; + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + unsigned char nlen; + + setup = TRANSACT2_QFSINFO; + + SSVAL(param,0,SMB_INFO_VOLUME); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + NULL, 0, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count < 5) { + goto cleanup; + } + + if (pserial_number) { + *pserial_number = IVAL(rdata,0); + } + nlen = CVAL(rdata,l2_vol_cch); + clistr_pull(cli, volume_name, rdata + l2_vol_szVolLabel, sizeof(fstring), nlen, STR_NOALIGN); + + /* todo: but not yet needed + * return the other stuff + */ + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} + +BOOL cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate) +{ + BOOL ret = False; + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + unsigned int nlen; + + setup = TRANSACT2_QFSINFO; + + SSVAL(param,0,SMB_QUERY_FS_VOLUME_INFO); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + NULL, 0, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + + if (rdata_count < 19) { + goto cleanup; + } + + if (pdate) { + *pdate = interpret_long_date(rdata); + } + if (pserial_number) { + *pserial_number = IVAL(rdata,8); + } + nlen = IVAL(rdata,12); + clistr_pull(cli, volume_name, rdata + 18, sizeof(fstring), nlen, STR_UNICODE); + + /* todo: but not yet needed + * return the other stuff + */ + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} -- cgit From 1635d50a20fb03b402465731494826471efc8f88 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 30 Mar 2005 02:35:31 +0000 Subject: r6125: smbc_stat() returned incorrect timestamps IFF it used cli_qpathinfo2() to retrieve the timestamps (Win2k) and not if it used cli-getatr() to retrieve the timestamps (Win98). Timestamps are supposed to be in GMT, and should not have serverzone deducted from them in cli_qpathinfo2(). (This used to be commit 443d8df94c2937b7d458b7228bdc1d433581558a) --- source3/libsmb/clirap.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 1f6a99d4be..06b683b038 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -501,16 +501,16 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, } if (c_time) { - *c_time = interpret_long_date(rdata+0) - cli->serverzone; + *c_time = interpret_long_date(rdata+0); } if (a_time) { - *a_time = interpret_long_date(rdata+8) - cli->serverzone; + *a_time = interpret_long_date(rdata+8); } if (m_time) { - *m_time = interpret_long_date(rdata+16) - cli->serverzone; + *m_time = interpret_long_date(rdata+16); } if (w_time) { - *w_time = interpret_long_date(rdata+24) - cli->serverzone; + *w_time = interpret_long_date(rdata+24); } if (mode) { *mode = SVAL(rdata, 32); -- cgit From 934d41d23956c663406ff9d68e5a8ba9d81b5096 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 30 Mar 2005 04:40:24 +0000 Subject: r6127: Eliminated all compiler warnings pertaining to mismatched "qualifiers". The whole of samba comiles warning-free with the default compiler flags. Temporarily defined -Wall to locate other potential problems. Found an unused static function (#ifdefed out rather than deleted, in case it's needed for something in progress). There are also a number of uses of undeclared functions, mostly krb5_*. Files with these problems need to have appropriate header files included, but they are not fixed in this update. oplock_linux.c.c has undefined functions capget() and capset(), which need to have "#undef _POSIX_SOURCE" specified before including , but that could potentially have other side effects, so that remains uncorrected as well. The flag -Wall should be added permanently to CFLAGS, and all warnings then generated should be eliminated. (This used to be commit 5b19ede88ed80318e392f8017f4573fbb2ecbe0f) --- source3/libsmb/spnego.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index a0f5565d4f..090148d415 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -42,12 +42,12 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = SMB_MALLOC_P(char *); + token->mechTypes = SMB_MALLOC_P(const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = - SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2); - asn1_read_OID(asn1, token->mechTypes + i); + SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2); + asn1_read_OID(asn1, (char **) (token->mechTypes + i)); } token->mechTypes[i] = NULL; @@ -182,7 +182,7 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) break; case ASN1_CONTEXT(1): asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, &token->supportedMech); + asn1_read_OID(asn1, (char **) &token->supportedMech); asn1_end_tag(asn1); break; case ASN1_CONTEXT(2): @@ -317,7 +317,7 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego) if (spnego->negTokenInit.mechTypes) { int i; for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { - free(spnego->negTokenInit.mechTypes[i]); + free((void *) spnego->negTokenInit.mechTypes[i]); } free(spnego->negTokenInit.mechTypes); } @@ -326,7 +326,7 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego) break; case SPNEGO_NEG_TOKEN_TARG: if (spnego->negTokenTarg.supportedMech) { - free(spnego->negTokenTarg.supportedMech); + free((void *) spnego->negTokenTarg.supportedMech); } data_blob_free(&spnego->negTokenTarg.responseToken); data_blob_free(&spnego->negTokenTarg.mechListMIC); -- cgit From 9840db418bad5a39edc4a32a1786f5e2d2c9dff8 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 05:06:04 +0000 Subject: r6149: Fixes bugs #2498 and 2484. 1. using smbc_getxattr() et al, one may now request all access control entities in the ACL without getting all other NT attributes. 2. added the ability to exclude specified attributes from the result set provided by smbc_getxattr() et al, when requesting all attributes, all NT attributes, or all DOS attributes. 3. eliminated all compiler warnings, including when --enable-developer compiler flags are in use. removed -Wcast-qual flag from list, as that is specifically to force warnings in the case of casting away qualifiers. Note: In the process of eliminating compiler warnings, a few nasties were discovered. In the file libads/sasl.c, PRIVATE kerberos interfaces are being used; and in libsmb/clikrb5.c, both PRIAVE and DEPRECATED kerberos interfaces are being used. Someone who knows kerberos should look at these and determine if there is an alternate method of accomplishing the task. (This used to be commit 994694f7f26da5099f071e1381271a70407f33bb) --- source3/libsmb/clikrb5.c | 3 + source3/libsmb/clispnego.c | 3 +- source3/libsmb/libsmbclient.c | 824 +++++++++++++++++++++++++----------------- source3/libsmb/spnego.c | 11 +- 4 files changed, 501 insertions(+), 340 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 66c16b69ae..c35b53a9dd 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -19,6 +19,9 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ +#define KRB5_PRIVATE 1 /* this file uses PRIVATE interfaces! */ +#define KRB5_DEPRECATED 1 /* this file uses DEPRECATED interfaces! */ + #include "includes.h" #ifdef HAVE_KRB5 diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 85b7bd9e1e..5d07999bc3 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -338,7 +338,8 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, return retval; /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); + tkt_wrapped = spnego_gen_krb5_wrap( + tkt, CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REQ)); /* and wrap that in a shiny SPNEGO wrapper */ *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 87ca030b10..ae9a660a09 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3278,7 +3278,8 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, } /* Obtain the DOS attributes */ - if (!smbc_getatr(context, srv, (char *) filename, &mode, &size, + if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename), + &mode, &size, &c_time, &a_time, &m_time, &inode)) { errno = smbc_errno(context, &srv->cli); @@ -3347,21 +3348,35 @@ retrieve the acls for a file *******************************************************/ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, struct cli_state *ipc_cli, POLICY_HND *pol, - char *filename, char *name, char *buf, int bufsize) + char *filename, char *attr_name, char *buf, int bufsize) { uint32 i; int n = 0; int n_used; BOOL all; BOOL all_nt; + BOOL all_nt_acls; BOOL all_dos; BOOL some_nt; BOOL some_dos; + BOOL exclude_nt_revision = False; + BOOL exclude_nt_owner = False; + BOOL exclude_nt_group = False; + BOOL exclude_nt_acl = False; + BOOL exclude_dos_mode = False; + BOOL exclude_dos_size = False; + BOOL exclude_dos_ctime = False; + BOOL exclude_dos_atime = False; + BOOL exclude_dos_mtime = False; + BOOL exclude_dos_inode = False; BOOL numeric = True; BOOL determine_size = (bufsize == 0); int fnum = -1; SEC_DESC *sd; fstring sidstr; + fstring name_sandbox; + char *name; + char *pExclude; char *p; time_t m_time = 0, a_time = 0, c_time = 0; SMB_OFF_T size = 0; @@ -3369,20 +3384,88 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, SMB_INO_T ino = 0; struct cli_state *cli = &srv->cli; + /* Copy name so we can strip off exclusions (if any are specified) */ + strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); + + /* Ensure name is null terminated */ + name_sandbox[sizeof(name_sandbox) - 1] = '\0'; + + /* Play in the sandbox */ + name = name_sandbox; + + /* If there are any exclusions, point to them and mask them from name */ + if ((pExclude = strchr(name, '!')) != NULL) + { + *pExclude++ = '\0'; + } + all = (StrnCaseCmp(name, "system.*", 8) == 0); all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); + all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0); some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); numeric = (* (name + strlen(name) - 1) != '+'); + /* Look for exclusions from "all" requests */ + if (all || all_nt || all_dos) { + + /* Exclusions are delimited by '!' */ + for (; pExclude != NULL; pExclude = (p == NULL ? NULL : p + 1)) { + + /* Find end of this exclusion name */ + if ((p = strchr(pExclude, '!')) != NULL) + { + *p = '\0'; + } + + /* Which exclusion name is this? */ + if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) { + exclude_nt_revision = True; + } + else if (StrCaseCmp(pExclude, "nt_sec_desc.owner") == 0) { + exclude_nt_owner = True; + } + else if (StrCaseCmp(pExclude, "nt_sec_desc.group") == 0) { + exclude_nt_group = True; + } + else if (StrCaseCmp(pExclude, "nt_sec_desc.acl") == 0) { + exclude_nt_acl = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.mode") == 0) { + exclude_dos_mode = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) { + exclude_dos_size = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.c_time") == 0) { + exclude_dos_ctime = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.a_time") == 0) { + exclude_dos_atime = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.m_time") == 0) { + exclude_dos_mtime = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { + exclude_dos_inode = True; + } + else { + DEBUG(5, ("cacl_get received unknown exclusion: %s\n", + pExclude)); + errno = ENOATTR; + return -1; + } + } + } + n_used = 0; /* * If we are (possibly) talking to an NT or new system and some NT * attributes have been requested... */ - if (ipc_cli && (all || some_nt)) { + if (ipc_cli && (all || some_nt || all_nt_acls)) { /* Point to the portion after "system.nt_sec_desc." */ name += 19; /* if (all) this will be invalid but unused */ @@ -3407,139 +3490,105 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, cli_close(cli, fnum); - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, - "REVISION:%d", - sd->revision); - if (!p) { - errno = ENOMEM; - return -1; + if (! exclude_nt_revision) { + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, + "REVISION:%d", + sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "REVISION:%d", sd->revision); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "REVISION:%d", sd->revision); - } - } else if (StrCaseCmp(name, "revision") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%d", sd->revision); - if (!p) { - errno = ENOMEM; - return -1; + } else if (StrCaseCmp(name, "revision") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%d", + sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%d", + sd->revision); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%d", sd->revision); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - - /* Get owner and group sid */ - - if (sd->owner_sid) { - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, sd->owner_sid); - } else { - fstrcpy(sidstr, ""); + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; } - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, ",OWNER:%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",OWNER:%s", sidstr); - } - } else if (StrnCaseCmp(name, "owner", 5) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); + if (! exclude_nt_owner) { + /* Get owner and group sid */ + if (sd->owner_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, + numeric, + sd->owner_sid); } else { - n = snprintf(buf, bufsize, "%s", sidstr); + fstrcpy(sidstr, ""); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - - if (sd->grp_sid) { - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, sd->grp_sid); - } else { - fstrcpy(sidstr, ""); - } - - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, ",GROUP:%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, ",OWNER:%s", + sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",OWNER:%s", sidstr); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",GROUP:%s", sidstr); - } - } else if (StrnCaseCmp(name, "group", 5) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; + } else if (StrnCaseCmp(name, "owner", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%s", + sidstr); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%s", sidstr); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; } - buf += n; - n_used += n; - bufsize -= n; - /* Add aces to value buffer */ - for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { - - SEC_ACE *ace = &sd->dacl->ace[i]; - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, &ace->trustee); + if (! exclude_nt_group) { + if (sd->grp_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, + sd->grp_sid); + } else { + fstrcpy(sidstr, ""); + } if (all || all_nt) { if (determine_size) { - p = talloc_asprintf(ctx, - ",ACL:" - "%s:%d/%d/0x%08x", - sidstr, - ace->type, - ace->flags, - ace->info.mask); + p = talloc_asprintf(ctx, ",GROUP:%s", + sidstr); if (!p) { errno = ENOMEM; return -1; @@ -3547,36 +3596,22 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, n = strlen(p); } else { n = snprintf(buf, bufsize, - ",ACL:%s:%d/%d/0x%08x", - sidstr, - ace->type, - ace->flags, - ace->info.mask); + ",GROUP:%s", sidstr); } - } else if ((StrnCaseCmp(name, "acl", 3) == 0 && - StrCaseCmp(name + 3, sidstr) == 0) || - (StrnCaseCmp(name, "acl+", 4) == 0 && - StrCaseCmp(name + 4, sidstr) == 0)) { + } else if (StrnCaseCmp(name, "group", 5) == 0) { if (determine_size) { - p = talloc_asprintf(ctx, - "%d/%d/0x%08x", - ace->type, - ace->flags, - ace->info.mask); + p = talloc_asprintf(ctx, "%s", sidstr); if (!p) { errno = ENOMEM; return -1; } n = strlen(p); } else { - n = snprintf(buf, bufsize, - "%d/%d/0x%08x", - ace->type, - ace->flags, - ace->info.mask); + n = snprintf(buf, bufsize, "%s", sidstr); } } - if (n > bufsize) { + + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; } @@ -3585,6 +3620,97 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, bufsize -= n; } + if (! exclude_nt_acl) { + /* Add aces to value buffer */ + for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { + + SEC_ACE *ace = &sd->dacl->ace[i]; + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, + &ace->trustee); + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",ACL:" + "%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->info.mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf( + buf, bufsize, + ",ACL:%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->info.mask); + } + } else if ((StrnCaseCmp(name, "acl", 3) == 0 && + StrCaseCmp(name + 3, sidstr) == 0) || + (StrnCaseCmp(name, "acl+", 4) == 0 && + StrCaseCmp(name + 4, sidstr) == 0)) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->info.mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->info.mask); + } + } else if (all_nt_acls) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%s%s:%d/%d/0x%08x", + i ? "," : "", + sidstr, + ace->type, + ace->flags, + ace->info.mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%s%s:%d/%d/0x%08x", + i ? "," : "", + sidstr, + ace->type, + ace->flags, + ace->info.mask); + } + } + if (n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + } + } + /* Restore name pointer to its original value */ name -= 19; } @@ -3602,231 +3728,250 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, } - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - "%sMODE:0x%x", - (ipc_cli && - (all || some_nt) - ? "," - : ""), - mode); - if (!p) { - errno = ENOMEM; - return -1; + if (! exclude_dos_mode) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + "%sMODE:0x%x", + (ipc_cli && + (all || some_nt) + ? "," + : ""), + mode); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%sMODE:0x%x", + (ipc_cli && + (all || some_nt) + ? "," + : ""), + mode); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%sMODE:0x%x", - (ipc_cli && - (all || some_nt) - ? "," - : ""), - mode); - } - } else if (StrCaseCmp(name, "mode") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "0x%x", mode); - if (!p) { - errno = ENOMEM; - return -1; + } else if (StrCaseCmp(name, "mode") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "0x%x", mode); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "0x%x", mode); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "0x%x", mode); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; } - buf += n; - n_used += n; - bufsize -= n; - - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",SIZE:%llu", - (unsigned long long) size); - if (!p) { - errno = ENOMEM; - return -1; + + if (! exclude_dos_size) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",SIZE:%llu", + (unsigned long long) size); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",SIZE:%llu", + (unsigned long long) size); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",SIZE:%llu", - (unsigned long long) size); - } - } else if (StrCaseCmp(name, "size") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, - "%llu", - (unsigned long long) size); - if (!p) { - errno = ENOMEM; - return -1; + } else if (StrCaseCmp(name, "size") == 0) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%llu", + (unsigned long long) size); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%llu", + (unsigned long long) size); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%llu", - (unsigned long long) size); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; } - buf += n; - n_used += n; - bufsize -= n; - - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",C_TIME:%lu", c_time); - if (!p) { - errno = ENOMEM; - return -1; + + if (! exclude_dos_ctime) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",C_TIME:%lu", + c_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",C_TIME:%lu", c_time); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",C_TIME:%lu", c_time); - } - } else if (StrCaseCmp(name, "c_time") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", c_time); - if (!p) { - errno = ENOMEM; - return -1; + } else if (StrCaseCmp(name, "c_time") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", c_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%lu", c_time); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%lu", c_time); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; } - buf += n; - n_used += n; - bufsize -= n; - - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",A_TIME:%lu", a_time); - if (!p) { - errno = ENOMEM; - return -1; + + if (! exclude_dos_atime) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",A_TIME:%lu", + a_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",A_TIME:%lu", a_time); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",A_TIME:%lu", a_time); - } - } else if (StrCaseCmp(name, "a_time") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", a_time); - if (!p) { - errno = ENOMEM; - return -1; + } else if (StrCaseCmp(name, "a_time") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", a_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%lu", a_time); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%lu", a_time); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; } - buf += n; - n_used += n; - bufsize -= n; - - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",M_TIME:%lu", m_time); - if (!p) { - errno = ENOMEM; - return -1; + + if (! exclude_dos_mtime) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",M_TIME:%lu", + m_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",M_TIME:%lu", m_time); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",M_TIME:%lu", m_time); - } - } else if (StrCaseCmp(name, "m_time") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", m_time); - if (!p) { - errno = ENOMEM; - return -1; + } else if (StrCaseCmp(name, "m_time") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", m_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%lu", m_time); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%lu", m_time); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; } - buf += n; - n_used += n; - bufsize -= n; - - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",INODE:%llu", - (unsigned long long) ino); - if (!p) { - errno = ENOMEM; - return -1; + + if (! exclude_dos_inode) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",INODE:%llu", + (unsigned long long) ino); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",INODE:%llu", + (unsigned long long) ino); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",INODE:%llu", - (unsigned long long) ino); - } - } else if (StrCaseCmp(name, "inode") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, - "%llu", - (unsigned long long) ino); - if (!p) { - errno = ENOMEM; - return -1; + } else if (StrCaseCmp(name, "inode") == 0) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%llu", + (unsigned long long) ino); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%llu", + (unsigned long long) ino); } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%llu", - (unsigned long long) ino); } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; } - buf += n; - n_used += n; - bufsize -= n; /* Restore name pointer to its original value */ name -= 16; @@ -3873,7 +4018,8 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli, the_acl = p + 1; } - sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, (char *) the_acl); + sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, + CONST_DISCARD(char *, the_acl)); if (!sd) { errno = EINVAL; @@ -4380,9 +4526,13 @@ int smbc_getxattr_ctx(SMBCCTX *context, /* Are they requesting a supported attribute? */ if (StrCaseCmp(name, "system.*") == 0 || + StrnCaseCmp(name, "system.*!", 9) == 0 || StrCaseCmp(name, "system.*+") == 0 || + StrnCaseCmp(name, "system.*+!", 10) == 0 || StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 || StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 || StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || @@ -4391,6 +4541,7 @@ int smbc_getxattr_ctx(SMBCCTX *context, StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 || StrCaseCmp(name, "system.dos_attr.*") == 0 || + StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 || StrCaseCmp(name, "system.dos_attr.mode") == 0 || StrCaseCmp(name, "system.dos_attr.size") == 0 || StrCaseCmp(name, "system.dos_attr.c_time") == 0 || @@ -4401,7 +4552,9 @@ int smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, ipc_srv == NULL ? NULL : &ipc_srv->cli, - &pol, path, (char *) name, (char *) value, size); + &pol, path, + CONST_DISCARD(char *, name), + CONST_DISCARD(char *, value), size); if (ret < 0 && errno == 0) { errno = smbc_errno(context, &srv->cli); } @@ -4540,6 +4693,7 @@ int smbc_listxattr_ctx(SMBCCTX *context, "system.nt_sec_desc.owner+\0" "system.nt_sec_desc.group\0" "system.nt_sec_desc.group+\0" + "system.nt_sec_desc.acl.*\0" "system.nt_sec_desc.acl\0" "system.nt_sec_desc.acl+\0" "system.nt_sec_desc.*\0" diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 090148d415..0387e8f67d 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -47,7 +47,9 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2); - asn1_read_OID(asn1, (char **) (token->mechTypes + i)); + asn1_read_OID(asn1, + CONST_DISCARD(char **, + (token->mechTypes + i))); } token->mechTypes[i] = NULL; @@ -182,7 +184,7 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) break; case ASN1_CONTEXT(1): asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, (char **) &token->supportedMech); + asn1_read_OID(asn1, CONST_DISCARD(char **, &token->supportedMech)); asn1_end_tag(asn1); break; case ASN1_CONTEXT(2): @@ -317,7 +319,8 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego) if (spnego->negTokenInit.mechTypes) { int i; for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { - free((void *) spnego->negTokenInit.mechTypes[i]); + free(CONST_DISCARD(void *, + spnego->negTokenInit.mechTypes[i])); } free(spnego->negTokenInit.mechTypes); } @@ -326,7 +329,7 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego) break; case SPNEGO_NEG_TOKEN_TARG: if (spnego->negTokenTarg.supportedMech) { - free((void *) spnego->negTokenTarg.supportedMech); + free(CONST_DISCARD(void *, spnego->negTokenTarg.supportedMech)); } data_blob_free(&spnego->negTokenTarg.responseToken); data_blob_free(&spnego->negTokenTarg.mechListMIC); -- cgit From 8de11f06df03e19fe92f44da10a10eab30e118b2 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 20:28:47 +0000 Subject: r6155: Fixes bug #1133 Added provision for overloading some global configuration options via the new, per-user file ~/.smb/smb.conf.append which is read after the global config file is read (and only if the global config file was read). This leave the original, BC behavior of ~/.smb/smb.conf which, if found, is read but causes the global config file to not be read. Also fixed a potential seg fault in to lp_dump_one(). (This used to be commit 2c5a6305bd127b1a7e65356c2b3aa5c13cd2bd74) --- source3/libsmb/libsmbclient.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ae9a660a09..657d0925b0 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5169,10 +5169,25 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) * defaults ... */ - if (!lp_load(dyn_CONFIGFILE, True, False, False)) { - DEBUG(5, ("Could not load either config file: %s or %s\n", - conf, dyn_CONFIGFILE)); - } + if (!lp_load(dyn_CONFIGFILE, True, False, False)) { + DEBUG(5, ("Could not load either config file: " + "%s or %s\n", + conf, dyn_CONFIGFILE)); + } else { + /* + * We loaded the global config file. Now lets + * load user-specific modifications to the + * global config. + */ + slprintf(conf, sizeof(conf), + "%s/.smb/smb.conf.append", home); + if (!lp_load(conf, True, False, False)) { + DEBUG(10, + ("Could not append config file: " + "%s\n", + conf)); + } + } } reopen_logs(); /* Get logging working ... */ -- cgit From 523ba5ed3221bb81eea0428e4d6900e35bd24f03 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 21:16:20 +0000 Subject: r6156: Fixes bug #2543. Properly cache anonmous username when reverting to anonymous login, in libsmbclient. (This used to be commit cf2dcc110824cb3a4ce4e4bf608de25b7cfc2054) --- source3/libsmb/libsmbclient.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 657d0925b0..3e8e604ab1 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -558,6 +558,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, int tried_reverse = 0; int port_try_first; int port_try_next; + const char *username_used; zero_ip(&ip); ZERO_STRUCT(c); @@ -712,16 +713,26 @@ SMBCSRV *smbc_server(SMBCCTX *context, return NULL; } - if (!cli_session_setup(&c, username, + username_used = username; + + if (!cli_session_setup(&c, username_used, password, strlen(password), password, strlen(password), - workgroup) && - /* Try an anonymous login if it failed and this was allowed by flags. */ - ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || - !cli_session_setup(&c, "", "", 1,"", 0, workgroup))) { - cli_shutdown(&c); - errno = EPERM; - return NULL; + workgroup)) { + + /* Failed. Try an anonymous login, if allowed by flags. */ + username_used = ""; + + if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || + !cli_session_setup(&c, username_used, + password, 1, + password, 0, + workgroup)) { + + cli_shutdown(&c); + errno = EPERM; + return NULL; + } } DEBUG(4,(" session setup ok\n")); @@ -753,7 +764,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, /* now add it to the cache (internal or external) */ /* Let the cache function set errno if it wants to */ errno = 0; - if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { + if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username_used)) { int saved_errno = errno; DEBUG(3, (" Failed to add server to cache\n")); errno = saved_errno; -- cgit From 978ca8486031e43754a3c23757f361bf3a85f335 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 6 Apr 2005 16:28:04 +0000 Subject: r6225: get rid of warnings from my compiler about nested externs (This used to be commit efea76ac71412f8622cd233912309e91b9ea52da) --- source3/libsmb/cliconnect.c | 3 +-- source3/libsmb/clientgen.c | 3 ++- source3/libsmb/clilist.c | 4 ++-- source3/libsmb/nmblib.c | 5 +++-- 4 files changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4208d6378d..5a9992d4e0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -23,6 +23,7 @@ #include "includes.h" +extern pstring user_socket_options; static const struct { int prot; @@ -1200,7 +1201,6 @@ BOOL cli_session_request(struct cli_state *cli, { char *p; int len = 4; - extern pstring user_socket_options; memcpy(&(cli->calling), calling, sizeof(*calling)); memcpy(&(cli->called ), called , sizeof(*called )); @@ -1290,7 +1290,6 @@ BOOL cli_session_request(struct cli_state *cli, BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { - extern pstring user_socket_options; int name_type = 0x20; char *p; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b7bc780a1a..e787650c2f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,6 +22,8 @@ #include "includes.h" +extern int smb_read_error; + /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -81,7 +83,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { - extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 0f1b9efed0..79c2ef66a1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -22,6 +22,8 @@ #include "includes.h" +extern file_info def_finfo; + /**************************************************************************** Interpret a long filename structure - this is mostly guesses at the moment. The length of the structure is returned @@ -32,7 +34,6 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { - extern file_info def_finfo; file_info finfo2; int len; char *base = p; @@ -332,7 +333,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { - extern file_info def_finfo; *finfo = def_finfo; diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 1c93f7b1e2..164f85be7b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -21,6 +21,9 @@ #include "includes.h" +extern struct in_addr lastip; +extern int lastport; + int num_good_sends = 0; int num_good_receives = 0; @@ -692,8 +695,6 @@ void free_packet(struct packet_struct *packet) struct packet_struct *parse_packet(char *buf,int length, enum packet_type packet_type) { - extern struct in_addr lastip; - extern int lastport; struct packet_struct *p; BOOL ok=False; -- cgit From 1875e46d05c21f4ca0e1163ecfd41b470dbce09a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 10 Apr 2005 14:44:56 +0000 Subject: r6275: Implement RAP version of enumusers/enumgroups level 0. No, I've not gone mad, this is to test future changes to enumeration functions... This can successfully list users from nt4 and w2k3sp1. Volker (This used to be commit c73f2656fd89e227a8a3e2ab20f7393ff2c515c7) --- source3/libsmb/clirap2.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 12a3d63aff..d8a8519550 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -329,6 +329,70 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char return res; } +int cli_RNetGroupEnum0(struct cli_state *cli, + void (*fn)(const char *, void *), + void *state) +{ + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetGroupEnum_REQ) /* parm string */ + +sizeof(RAP_GROUP_INFO_L0) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + char *p; + char *rparam = NULL; + char *rdata = NULL; + unsigned int rprcnt, rdrcnt; + int res = -1; + + + memset(param, '\0', sizeof(param)); + p = make_header(param, RAP_WGroupEnum, + RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L0); + PUTWORD(p,0); /* Info level 0 */ /* Hmmm. I *very* much suspect this + is the resume count, at least + that's what smbd believes... */ + PUTWORD(p,0xFFE0); /* Return buffer size */ + + if (cli_api(cli, + param, PTR_DIFF(p,param),8, + NULL, 0, 0xFFE0 /* data area size */, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { + res = GETRES(rparam); + cli->rap_error = res; + if(cli->rap_error == 234) + DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n")); + else if (cli->rap_error != 0) { + DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error)); + } + } + + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + + p = rparam + WORDSIZE; /* skip result */ + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata;irap_error = res; + if (cli->rap_error != 0) { + DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error)); + } + } + if (rdata) { + if (res == 0 || res == ERRmoredata) { + int i, converter, count; + char username[RAP_USERNAME_LEN]; + + p = rparam + WORDSIZE; /* skip result */ + GETWORD(p, converter); + GETWORD(p, count); + + for (i=0,p=rdata;i Date: Tue, 19 Apr 2005 19:23:49 +0000 Subject: r6392: - Fixes bug 2564: when smbc_opendir() was called with a file rather than a directory, the errno returned could end up as ENOENT rather than ENOTDIR. - Fixes some compiler warnings which showed up on IRIX, as reported by James Peach. (This used to be commit 615a62b21f8d2f7f97bde2f166ddd6849d39b95c) --- source3/libsmb/clifile.c | 4 ++-- source3/libsmb/clikrb5.c | 4 ++-- source3/libsmb/clirap2.c | 41 +++++++++++++++++------------------------ source3/libsmb/libsmbclient.c | 31 ++++++++++++++++++++++++++----- source3/libsmb/trustdom_cache.c | 2 +- source3/libsmb/trusts_util.c | 3 --- 6 files changed, 48 insertions(+), 37 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 93492ec082..5304f5d8cf 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -266,8 +266,8 @@ BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu sbuf->st_ctime = interpret_long_date(rdata + 16); /* time of last change */ sbuf->st_atime = interpret_long_date(rdata + 24); /* time of last access */ sbuf->st_mtime = interpret_long_date(rdata + 32); /* time of last modification */ - sbuf->st_uid = IVAL(rdata,40); /* user ID of owner */ - sbuf->st_gid = IVAL(rdata,48); /* group ID of owner */ + sbuf->st_uid = (uid_t) IVAL(rdata,40); /* user ID of owner */ + sbuf->st_gid = (gid_t) IVAL(rdata,48); /* group ID of owner */ sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56)); #if defined(HAVE_MAKEDEV) { diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index c35b53a9dd..43252b94d8 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -396,7 +396,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, /* cope with ticket being in the future due to clock skew */ if ((unsigned)credsp->times.starttime > time(NULL)) { time_t t = time(NULL); - int time_offset =(unsigned)credsp->times.starttime-t; + int time_offset =(int)((unsigned)credsp->times.starttime-t); DEBUG(4,("ads_krb5_mk_req: Advancing clock by %d seconds to cope with clock skew\n", time_offset)); krb5_set_real_time(context, t + time_offset + 1, 0); } @@ -405,7 +405,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, creds_ready = True; } - DEBUG(10,("ads_krb5_mk_req: Ticket (%s) in ccache (%s) is valid until: (%s - %d)\n", + DEBUG(10,("ads_krb5_mk_req: Ticket (%s) in ccache (%s) is valid until: (%s - %u)\n", principal, krb5_cc_default_name(context), http_timestring((unsigned)credsp->times.endtime), (unsigned)credsp->times.endtime)); diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index d8a8519550..b15ee1a63e 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -369,10 +369,9 @@ int cli_RNetGroupEnum0(struct cli_state *cli, if (rdata) { if (res == 0 || res == ERRmoredata) { - int i, converter, count; + int i, count; - p = rparam + WORDSIZE; /* skip result */ - GETWORD(p, converter); + p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ GETWORD(p, count); for (i=0,p=rdata;irap_error = res; if (res == 0 || res == ERRmoredata) { - int i, converter, count; + int i, count; - p = rparam + WORDSIZE; - GETWORD(p, converter); + p = rparam + WORDSIZE + WORDSIZE; GETWORD(p, count); p = rdata; @@ -1798,10 +1792,9 @@ int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const ch if (rdata) { if (res == 0 || res == ERRmoredata) { - int i, converter, count; + int i, count; - p = rparam + WORDSIZE; /* skip result */ - GETWORD(p, converter); + p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ GETWORD(p, count); for (i=0,p=rdata;icli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, @@ -2207,6 +2207,27 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SAFE_FREE(dir); } errno = smbc_errno(context, &srv->cli); + + if (errno == EINVAL) { + /* + * See if they asked to opendir something + * other than a directory. If so, the + * converted error value we got would have + * been EINVAL rather than ENOTDIR. + */ + *p = '\0'; /* restore original path */ + + if (smbc_getatr(context, srv, path, + &mode, NULL, + NULL, NULL, NULL, + NULL) && + ! IS_DOS_DIR(mode)) { + + /* It is. Correct the error value */ + errno = ENOTDIR; + } + } + return NULL; } diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index e63acd18c4..8c5fb4d907 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -320,7 +320,7 @@ void update_trustdom_cache( void ) if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 ) trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL); - time_diff = now - last_check; + time_diff = (int) (now - last_check); if ( (time_diff > 0) && (time_diff < TRUSTDOM_UPDATE_INTERVAL) ) { DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n")); diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index b420e4fa08..aab0d7d151 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -104,11 +104,8 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, const char *domain) { unsigned char old_trust_passwd_hash[16]; - char *up_domain; uint32 sec_channel_type = 0; - up_domain = talloc_strdup(mem_ctx, domain); - if (!secrets_fetch_trust_account_password(domain, old_trust_passwd_hash, NULL, &sec_channel_type)) { -- cgit From d7173b35e918292694b9cf27ecbcad3c9cc86da6 Mon Sep 17 00:00:00 2001 From: Steve French Date: Sun, 24 Apr 2005 02:59:40 +0000 Subject: r6447: Add missing error mapping for EMLINK to NT_STATUS_TOO_MANY_LINKS (we have it the other direction in clierror already). This fixes the return code when we try to hardlink from a client. (This used to be commit ccbdffb94e22c17b03b0a464071df027ebdc6264) --- source3/libsmb/errormap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 8ac1aed923..c79561bda8 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1505,6 +1505,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY }, { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, + { EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS }, #ifdef EDQUOT { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, #endif -- cgit From 1c4bbe06549d86614318718a45b9bc48e3bfc81f Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Mon, 2 May 2005 17:49:43 +0000 Subject: r6586: get rid of a few more compiler warnings (This used to be commit 173375f8d88bf8e8db8d60e5d5f0e5dcc28767d9) --- source3/libsmb/clikrb5.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 43252b94d8..e70c2b8bec 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -525,11 +525,13 @@ failed: #if defined(HAVE_KRB5_PRINCIPAL_GET_COMP_STRING) && !defined(HAVE_KRB5_PRINC_COMPONENT) + const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ); + const krb5_data *krb5_princ_component(krb5_context context, krb5_principal principal, int i ) { static krb5_data kdata; - kdata.data = krb5_principal_get_comp_string(context, principal, i); + kdata.data = (char *)krb5_principal_get_comp_string(context, principal, i); kdata.length = strlen(kdata.data); return &kdata; } -- cgit From 7b9d6ac23e1a7d8136fffd2e3977b09a815da65a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 3 May 2005 07:33:49 +0000 Subject: r6595: This is Volkers new-talloc patch. Just got the go-ahead from Volker to commit. Woo Hoo ! Jeremy. (This used to be commit 316df944a456f150944761dab34add5e8c4ab699) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 791427f249..ee7516630b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3303,7 +3303,7 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, SMB_INO_T inode = 0; DOS_ATTR_DESC *ret; - ret = talloc(ctx, sizeof(DOS_ATTR_DESC)); + ret = TALLOC_P(ctx, DOS_ATTR_DESC); if (!ret) { errno = ENOMEM; return NULL; -- cgit From 6a3a0766d5772a33d888c51ac4d68d2fa3e504ae Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 9 May 2005 22:39:20 +0000 Subject: r6685: smbclient fixes * BUG 2680: copy files from an MSDFS win2k root share * BUG 2688: re-implement support for the -P (--port) option * support connecting to an 'msdfs proxy' share on a Samba server (This used to be commit 9e3e473632fee669eda477d8cbe309b7109552ea) --- source3/libsmb/clidfs.c | 69 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 21046cd380..6d1e597410 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -59,6 +59,7 @@ static struct cli_state *do_connect( const char *server, const char *share, struct in_addr ip; pstring servicename; char *sharename; + fstring newserver, newshare; /* make a copy so we don't modify the global string 'service' */ pstrcpy(servicename, share); @@ -155,8 +156,19 @@ static struct cli_state *do_connect( const char *server, const char *share, } DEBUG(4,(" session setup ok\n")); - if (!cli_send_tconX(c, sharename, "?????", - password, strlen(password)+1)) { + /* here's the fun part....to support 'msdfs proxy' shares + (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL + here before trying to connect to the original share. + check_dfs_proxy() will fail if it is a normal share. */ + + if ( cli_check_msdfs_proxy( c, sharename, newserver, newshare ) ) { + cli_shutdown(c); + return do_connect( newserver, newshare, False ); + } + + /* must be a normal share */ + + if (!cli_send_tconX(c, sharename, "?????", password, strlen(password)+1)) { d_printf("tree connect failed: %s\n", cli_errstr(c)); cli_shutdown(c); return NULL; @@ -414,7 +426,7 @@ static void clean_path( pstring clean, const char *path ) /**************************************************************************** ****************************************************************************/ -static BOOL make_full_path( pstring path, const char *server, const char *share, +BOOL cli_dfs_make_full_path( pstring path, const char *server, const char *share, const char *dir ) { pstring servicename; @@ -583,7 +595,7 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* send a trans2_query_path_info to check for a referral */ clean_path( cleanpath, path ); - make_full_path( fullpath, rootcli->desthost, rootcli->share, cleanpath ); + cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, cleanpath ); /* don't bother continuing if this is not a dfs root */ @@ -612,7 +624,7 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* just store the first referral for now Make sure to recreate the original string including any wildcards */ - make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); + cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); pathlen = strlen( fullpath )*2; consumed = MIN(pathlen, consumed ); pstrcpy( targetpath, &fullpath[consumed/2] ); @@ -654,3 +666,50 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha return True; } + +/******************************************************************** +********************************************************************/ + +BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, + fstring newserver, fstring newshare ) +{ + CLIENT_DFS_REFERRAL *refs = NULL; + size_t num_refs; + uint16 consumed; + struct cli_state *cli_ipc; + pstring fullpath; + + if ( !cli || !sharename ) + return False; + + /* special case. never check for a referral on the IPC$ share */ + + if ( strequal( sharename, "IPC$" ) ) + return False; + + /* send a trans2_query_path_info to check for a referral */ + + pstr_sprintf( fullpath, "\\%s\\%s", cli->desthost, sharename ); + + /* check for the referral */ + + if ( !(cli_ipc = cli_cm_open( cli->desthost, "IPC$", False )) ) + return False; + + if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed) + || !num_refs ) + { + return False; + } + + split_dfs_path( refs[0].dfspath, newserver, newshare ); + + /* check that this is not a self-referral */ + + if ( strequal( cli->desthost, newserver ) && strequal( sharename, newshare ) ) + return False; + + SAFE_FREE( refs ); + + return True; +} -- cgit From 5d5d596206e08be5bb159d9a474dc0b10e07b169 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 10 May 2005 12:21:02 +0000 Subject: r6706: * fix bug that prevented smbclient from creating directories on non-dfs paths * add patch from James Peach to remove use of uninitialized variables (This used to be commit c71f20f1ae5ccfd49cf81af0299c96fe27351222) --- source3/libsmb/clidfs.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 6d1e597410..30c8701619 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -464,7 +464,7 @@ BOOL cli_dfs_make_full_path( pstring path, const char *server, const char *share check for dfs referral ********************************************************************/ -static BOOL cli_dfs_check_error( struct cli_state *cli ) +static BOOL cli_dfs_check_error( struct cli_state *cli, NTSTATUS status ) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); @@ -473,7 +473,7 @@ static BOOL cli_dfs_check_error( struct cli_state *cli ) if ( !( (flgs2&FLAGS2_32_BIT_ERROR_CODES) && (flgs2&FLAGS2_UNICODE_STRINGS) ) ) return False; - if ( NT_STATUS_EQUAL( NT_STATUS_PATH_NOT_COVERED, NT_STATUS(IVAL(cli->inbuf,smb_rcls)) ) ) + if ( NT_STATUS_EQUAL( status, NT_STATUS(IVAL(cli->inbuf,smb_rcls)) ) ) return True; return False; @@ -605,9 +605,17 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha return True; } + /* special case where client asked for a path that does not exist */ + + if ( cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND) ) { + *targetcli = rootcli; + pstrcpy( targetpath, path ); + return True; + } + /* we got an error, check for DFS referral */ - if ( !cli_dfs_check_error(rootcli) ) + if ( !cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED) ) return False; /* check for the referral */ -- cgit From d5e18ed8fdd114baa6e0060447dd46ae9fe3066a Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 12 May 2005 12:50:03 +0000 Subject: r6753: Fixes bug 2663. cli_getattrE() and cli_setattrE() were not formatting or parsing the timestamp values correctly. It turns out they were using the incorrect function for formatting and parsing values. Thanks to Satwik Hebbar for reporting this and testing the patch. (This used to be commit 9144778d09c1650a775fdd08767ac65189fad457) --- source3/libsmb/clifile.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 5304f5d8cf..90ca98d17e 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1103,15 +1103,15 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, } if (c_time) { - *c_time = make_unix_date3(cli->inbuf+smb_vwv0); + *c_time = make_unix_date2(cli->inbuf+smb_vwv0); } if (a_time) { - *a_time = make_unix_date3(cli->inbuf+smb_vwv2); + *a_time = make_unix_date2(cli->inbuf+smb_vwv2); } if (m_time) { - *m_time = make_unix_date3(cli->inbuf+smb_vwv4); + *m_time = make_unix_date2(cli->inbuf+smb_vwv4); } return True; @@ -1186,9 +1186,9 @@ BOOL cli_setattrE(struct cli_state *cli, int fd, cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0, fd); - put_dos_date3(cli->outbuf,smb_vwv1, c_time); - put_dos_date3(cli->outbuf,smb_vwv3, a_time); - put_dos_date3(cli->outbuf,smb_vwv5, m_time); + put_dos_date2(cli->outbuf,smb_vwv1, c_time); + put_dos_date2(cli->outbuf,smb_vwv3, a_time); + put_dos_date2(cli->outbuf,smb_vwv5, m_time); p = smb_buf(cli->outbuf); *p++ = 4; -- cgit From 45d03e327ae8b2b9b9761ed76161d4467b27f730 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 May 2005 19:39:40 +0000 Subject: r6994: Fix for bugid #2729 - it turns out resume keys are *mandatory* for a search when listing a W2K and above server from a FATxx filesystem only. Thanks to Steve Langasek for giving me the essential info that allowed me to reproduce and thus fix this. Jeremy. (This used to be commit 8227675d3dbcd4f8bb2a24ea7e3e05c428b7c929) --- source3/libsmb/clilist.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 79c2ef66a1..892a457255 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -32,7 +32,7 @@ extern file_info def_finfo; ****************************************************************************/ static size_t interpret_long_filename(struct cli_state *cli, - int level,char *p,file_info *finfo) + int level,char *p,file_info *finfo, uint32 *p_resume_key) { file_info finfo2; int len; @@ -40,6 +40,7 @@ static size_t interpret_long_filename(struct cli_state *cli, if (!finfo) finfo = &finfo2; + *p_resume_key = 0; memcpy(finfo,&def_finfo,sizeof(*finfo)); switch (level) { @@ -85,6 +86,8 @@ static size_t interpret_long_filename(struct cli_state *cli, { size_t namelen, slen; p += 4; /* next entry offset */ + + *p_resume_key = IVAL(p,0); p += 4; /* fileindex */ /* these dates appear to arrive in a @@ -146,7 +149,7 @@ static size_t interpret_long_filename(struct cli_state *cli, int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { -#if 0 +#if 1 int max_matches = 1366; /* Match W2k - was 512. */ #else int max_matches = 512; @@ -170,6 +173,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, uint16 setup; pstring param; const char *mnt; + uint32 resume_key = 0; /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; @@ -204,7 +208,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,0,ff_dir_handle); SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); - SIVAL(param,6,0); /* ff_resume_key */ + /* For W2K servers serving out FAT filesystems we *must* set the + resume key. If it's not FAT then it's returned as zero. */ + SIVAL(param,6,resume_key); /* ff_resume_key */ /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ @@ -277,7 +283,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* Last entry - fixup the last offset length. */ SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); } - p2 += interpret_long_filename(cli,info_level,p2,&finfo); + p2 += interpret_long_filename(cli,info_level,p2,&finfo,&resume_key); } if (ff_lastname > 0) { @@ -317,7 +323,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mnt = cli_cm_get_mntpoint( cli ); for (p=dirlist,i=0;i Date: Fri, 27 May 2005 16:15:56 +0000 Subject: r7031: Added encrypt/decrypt function for LSA secrets and trusted domain passwords on the wire. Jeremy. (This used to be commit f82dcac25faf7876655cb1839846cc5e01e4add7) --- source3/libsmb/smbdes.c | 2 +- source3/libsmb/smbencrypt.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index ae946b4a66..70581f1b2d 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -276,7 +276,7 @@ static void str_to_key(const unsigned char *str,unsigned char *key) } -static void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) +void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { int i; char outb[64]; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 55e06ffe97..d3573d0e1e 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -513,6 +513,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) *new_pw_len is the length in bytes of the possibly mulitbyte returned password including termination. ************************************************************/ + BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, int new_pwrd_size, uint32 *new_pw_len, int string_flags) @@ -554,3 +555,31 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, return True; } + +/*********************************************************** + Encrypt/Decrypt used for LSA secrets and trusted domain + passwords. +************************************************************/ + +void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *session_key, int forward) +{ + int i, k; + + for (i=0,k=0; + ilength; + i += 8, k += 7) { + uint8_t bin[8], bout[8], key[7]; + + memset(bin, 0, 8); + memcpy(bin, &in->data[i], MIN(8, in->length-i)); + + if (k + 7 > session_key->length) { + k = (session_key->length - k); + } + memcpy(key, &session_key->data[k], 7); + + smbhash(bout, bin, key, forward?1:0); + + memcpy(&out->data[i], bout, MIN(8, in->length-i)); + } +} -- cgit From e9b511a32df8e61e34e585d66fc5c4b187da60f0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 May 2005 16:21:19 +0000 Subject: r7033: Call a spade a spade :-). Jeremy. (This used to be commit f5027f6370bd085a8d4c1a221881eebb0e4ffbab) --- source3/libsmb/smbdes.c | 174 +++++++++++++++++++++----------------------- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 85 insertions(+), 91 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 70581f1b2d..b7f0cd05c3 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -276,7 +276,7 @@ static void str_to_key(const unsigned char *str,unsigned char *key) } -void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) +void des_crypt56(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { int i; char outb[64]; @@ -307,35 +307,35 @@ void smbhash(unsigned char *out, const unsigned char *in, const unsigned char *k void E_P16(const unsigned char *p14,unsigned char *p16) { unsigned char sp8[8] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; - smbhash(p16, sp8, p14, 1); - smbhash(p16+8, sp8, p14+7, 1); + des_crypt56(p16, sp8, p14, 1); + des_crypt56(p16+8, sp8, p14+7, 1); } void E_P24(const unsigned char *p21, const unsigned char *c8, unsigned char *p24) { - smbhash(p24, c8, p21, 1); - smbhash(p24+8, c8, p21+7, 1); - smbhash(p24+16, c8, p21+14, 1); + des_crypt56(p24, c8, p21, 1); + des_crypt56(p24+8, c8, p21+7, 1); + des_crypt56(p24+16, c8, p21+14, 1); } void D_P16(const unsigned char *p14, const unsigned char *in, unsigned char *out) { - smbhash(out, in, p14, 0); - smbhash(out+8, in+8, p14+7, 0); + des_crypt56(out, in, p14, 0); + des_crypt56(out+8, in+8, p14+7, 0); } void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char *out) { - smbhash(out, in, p14, 1); - smbhash(out+8, in+8, p14+7, 1); + des_crypt56(out, in, p14, 1); + des_crypt56(out+8, in+8, p14+7, 1); } void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char *key) { unsigned char buf[8]; - smbhash(buf, in, key, 1); - smbhash(out, buf, key+9, 1); + des_crypt56(buf, in, key, 1); + des_crypt56(out, buf, key+9, 1); } void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key) @@ -343,98 +343,92 @@ void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char unsigned char buf[8]; static unsigned char key2[8]; - smbhash(buf, in, key, 1); + des_crypt56(buf, in, key, 1); key2[0] = key[7]; - smbhash(out, buf, key2, 1); + des_crypt56(out, buf, key2, 1); } void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw) { static unsigned char key2[8]; - smbhash(out, in, key, forw); + des_crypt56(out, in, key, forw); key2[0] = key[7]; - smbhash(out + 8, in + 8, key2, forw); + des_crypt56(out + 8, in + 8, key2, forw); } void SamOEMhash( unsigned char *data, const unsigned char *key, int val) { - unsigned char s_box[256]; - unsigned char index_i = 0; - unsigned char index_j = 0; - unsigned char j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - s_box[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (s_box[ind] + key[ind%16]); - - tc = s_box[ind]; - s_box[ind] = s_box[j]; - s_box[j] = tc; - } - for( ind = 0; ind < val; ind++) - { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += s_box[index_i]; - - tc = s_box[index_i]; - s_box[index_i] = s_box[index_j]; - s_box[index_j] = tc; - - t = s_box[index_i] + s_box[index_j]; - data[ind] = data[ind] ^ s_box[t]; - } + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) { + s_box[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) { + unsigned char tc; + + j += (s_box[ind] + key[ind%16]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + for( ind = 0; ind < val; ind++) { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } } void SamOEMhashBlob( unsigned char *data, int len, DATA_BLOB *key) { - unsigned char s_box[256]; - unsigned char index_i = 0; - unsigned char index_j = 0; - unsigned char j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - s_box[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (s_box[ind] + key->data[ind%key->length]); - - tc = s_box[ind]; - s_box[ind] = s_box[j]; - s_box[j] = tc; - } - for( ind = 0; ind < len; ind++) - { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += s_box[index_i]; - - tc = s_box[index_i]; - s_box[index_i] = s_box[index_j]; - s_box[index_j] = tc; - - t = s_box[index_i] + s_box[index_j]; - data[ind] = data[ind] ^ s_box[t]; - } + unsigned char s_box[256]; + unsigned char index_i = 0; + unsigned char index_j = 0; + unsigned char j = 0; + int ind; + + for (ind = 0; ind < 256; ind++) { + s_box[ind] = (unsigned char)ind; + } + + for( ind = 0; ind < 256; ind++) { + unsigned char tc; + + j += (s_box[ind] + key->data[ind%key->length]); + + tc = s_box[ind]; + s_box[ind] = s_box[j]; + s_box[j] = tc; + } + for( ind = 0; ind < len; ind++) { + unsigned char tc; + unsigned char t; + + index_i++; + index_j += s_box[index_i]; + + tc = s_box[index_i]; + s_box[index_i] = s_box[index_j]; + s_box[index_j] = tc; + + t = s_box[index_i] + s_box[index_j]; + data[ind] = data[ind] ^ s_box[t]; + } } /* Decode a sam password hash into a password. The password hash is the @@ -450,6 +444,6 @@ void sam_pwd_hash(unsigned int rid, const uchar *in, uchar *out, int forw) s[2] = s[6] = s[10] = (uchar)((rid >> 16) & 0xFF); s[3] = s[7] = s[11] = (uchar)((rid >> 24) & 0xFF); - smbhash(out, in, s, forw); - smbhash(out+8, in+8, s+7, forw); + des_crypt56(out, in, s, forw); + des_crypt56(out+8, in+8, s+7, forw); } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index d3573d0e1e..ab61f6b419 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -578,7 +578,7 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessi } memcpy(key, &session_key->data[k], 7); - smbhash(bout, bin, key, forward?1:0); + des_crypt56(bout, bin, key, forward?1:0); memcpy(&out->data[i], bout, MIN(8, in->length-i)); } -- cgit From f24d88cf9da46680d52b42b92bd484e7b09ce99b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 31 May 2005 13:46:45 +0000 Subject: r7139: trying to reduce the number of diffs between trunk and 3.0; changing version to 3.0.20pre1 (This used to be commit 9727d05241574042dd3aa8844ae5c701d22e2da1) --- source3/libsmb/clispnego.c | 3 +-- source3/libsmb/spnego.c | 15 ++++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 5d07999bc3..85b7bd9e1e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -338,8 +338,7 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, return retval; /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap( - tkt, CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REQ)); + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 0387e8f67d..a0f5565d4f 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -42,14 +42,12 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = SMB_MALLOC_P(const char *); + token->mechTypes = SMB_MALLOC_P(char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = - SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2); - asn1_read_OID(asn1, - CONST_DISCARD(char **, - (token->mechTypes + i))); + SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2); + asn1_read_OID(asn1, token->mechTypes + i); } token->mechTypes[i] = NULL; @@ -184,7 +182,7 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) break; case ASN1_CONTEXT(1): asn1_start_tag(asn1, ASN1_CONTEXT(1)); - asn1_read_OID(asn1, CONST_DISCARD(char **, &token->supportedMech)); + asn1_read_OID(asn1, &token->supportedMech); asn1_end_tag(asn1); break; case ASN1_CONTEXT(2): @@ -319,8 +317,7 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego) if (spnego->negTokenInit.mechTypes) { int i; for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { - free(CONST_DISCARD(void *, - spnego->negTokenInit.mechTypes[i])); + free(spnego->negTokenInit.mechTypes[i]); } free(spnego->negTokenInit.mechTypes); } @@ -329,7 +326,7 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego) break; case SPNEGO_NEG_TOKEN_TARG: if (spnego->negTokenTarg.supportedMech) { - free(CONST_DISCARD(void *, spnego->negTokenTarg.supportedMech)); + free(spnego->negTokenTarg.supportedMech); } data_blob_free(&spnego->negTokenTarg.responseToken); data_blob_free(&spnego->negTokenTarg.mechListMIC); -- cgit From 57fa7e154737df74a6a4fd9b2e3cf29917bd5ff0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 31 May 2005 19:06:52 +0000 Subject: r7151: Fix for bug #2698. If a unicode to unix charset conversion fails (due to buggy iconv?) we can be left with a filename that doesn't exist on the remote machine. If we then do a findnext with this file the server gets confused and restarts from the beginning of the directory, causing directory listing loops. Fix this by keeping a copy of the "raw" filename data and length and using this as the argument to findnext. This won't fix the incorrect iconv conversion into the finfo struct but at least it ensures that directory listings always terminate. Tested against NTFS and FAT directories. Jeremy. (This used to be commit 848940d5a91b310e58d0631ead293418ea4186f0) --- source3/libsmb/clilist.c | 50 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 892a457255..a1434338c9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -31,16 +31,20 @@ extern file_info def_finfo; by NT and 2 is used by OS/2 ****************************************************************************/ -static size_t interpret_long_filename(struct cli_state *cli, - int level,char *p,file_info *finfo, uint32 *p_resume_key) +static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo, + uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len) { file_info finfo2; int len; char *base = p; - if (!finfo) finfo = &finfo2; + if (!finfo) { + finfo = &finfo2; + } - *p_resume_key = 0; + if (p_resume_key) { + *p_resume_key = 0; + } memcpy(finfo,&def_finfo,sizeof(*finfo)); switch (level) { @@ -87,7 +91,9 @@ static size_t interpret_long_filename(struct cli_state *cli, size_t namelen, slen; p += 4; /* next entry offset */ - *p_resume_key = IVAL(p,0); + if (p_resume_key) { + *p_resume_key = IVAL(p,0); + } p += 4; /* fileindex */ /* these dates appear to arrive in a @@ -134,6 +140,22 @@ static size_t interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, 0); + + /* To be robust in the face of unicode conversion failures + we need to copy the raw bytes of the last name seen here. + Namelen doesn't include the terminating unicode null, so + copy it here. */ + + if (p_last_name_raw && p_last_name_raw_len) { + if (namelen + 2 > p_last_name_raw->length) { + memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length)); + *p_last_name_raw_len = 0; + } else { + memcpy(p_last_name_raw->data, p, namelen); + SSVAL(p_last_name_raw->data, namelen, 0); + *p_last_name_raw_len = namelen + 2; + } + } return (size_t)IVAL(base, 0); } } @@ -174,6 +196,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, pstring param; const char *mnt; uint32 resume_key = 0; + uint32 last_name_raw_len = 0; + DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring)); /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; @@ -215,8 +239,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; - p += clistr_push(cli, param+12, mask, sizeof(param)-12, - STR_TERMINATE); + if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) { + memcpy(p, last_name_raw.data, last_name_raw_len); + p += last_name_raw_len; + } else { + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); + } } param_len = PTR_DIFF(p, param); @@ -283,7 +311,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* Last entry - fixup the last offset length. */ SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); } - p2 += interpret_long_filename(cli,info_level,p2,&finfo,&resume_key); + p2 += interpret_long_filename(cli,info_level,p2,&finfo, + &resume_key,&last_name_raw,&last_name_raw_len); } if (ff_lastname > 0) { @@ -323,12 +352,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mnt = cli_cm_get_mntpoint( cli ); for (p=dirlist,i=0;i Date: Wed, 1 Jun 2005 00:00:07 +0000 Subject: r7157: Ensure we abort a directory listing if we see the same name twice between packets. Jeremy. (This used to be commit f9063b383ed2c53841ac27691b6a593b80c20b12) --- source3/libsmb/clilist.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a1434338c9..d9a6f4709d 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -313,6 +313,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } p2 += interpret_long_filename(cli,info_level,p2,&finfo, &resume_key,&last_name_raw,&last_name_raw_len); + + if (!First && *mask && strcsequal(finfo.name, mask)) { + DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n", + finfo.name)); + ff_eos = 1; + break; + } } if (ff_lastname > 0) { -- cgit From e317034997bbeab447298070afdb1b78c60e0e69 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 1 Jun 2005 17:40:40 +0000 Subject: r7168: Updating file times from libsmbclient was not working for win98. Although the function that was being used to set attributes is a core protocol function (SMBsetatr = 0x09), it does not appear to work on win98. As a temporary measure, when file times are to be set, this version opens the file and uses SMBsetattrE = 0x22 instead. (The other advantage of this function over the original one is that it supports setting access time as well as modification time.) The next step, the proper solution if it can be made to work, is to write functions that use TRANS2_SET_PATH_INFO instead. (This used to be commit bab0bf7f4f9d2a4b6fcee4429094349302bbeb33) --- source3/libsmb/libsmb_compat.c | 10 +++-- source3/libsmb/libsmbclient.c | 95 +++++++++++++++++++++++++++--------------- 2 files changed, 68 insertions(+), 37 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 83088a14de..3dc60f7240 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -303,14 +303,16 @@ int smbc_utimes(const char *fname, struct timeval *tbuf) #ifdef HAVE_UTIME_H int smbc_utime(const char *fname, struct utimbuf *utbuf) { - struct timeval tv; + struct timeval tv[2]; if (utbuf == NULL) return statcont->utimes(statcont, fname, NULL); - tv.tv_sec = utbuf->modtime; - tv.tv_usec = 0; - return statcont->utimes(statcont, fname, &tv); + tv[0].tv_sec = utbuf->actime; + tv[1].tv_sec = utbuf->modtime; + tv[0].tv_usec = tv[1].tv_usec = 0; + + return statcont->utimes(statcont, fname, tv); } #endif diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ee7516630b..296dbc7f5b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1245,7 +1245,10 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, } if (cli_getatr(&srv->cli, path, mode, size, m_time)) { - a_time = c_time = m_time; + if (m_time != NULL) { + if (a_time != NULL) *a_time = *m_time; + if (c_time != NULL) *c_time = *m_time; + } srv->no_pathinfo2 = True; return True; } @@ -1303,22 +1306,6 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) } - /* if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - - int job = smbc_stat_printjob(srv, path, NULL, NULL); - if (job == -1) { - - return -1; - - } - if ((err = cli_printjob_del(&srv->cli, job)) != 0) { - - - return -1; - - } - } else */ - if (!cli_unlink(&srv->cli, path)) { errno = smbc_errno(context, &srv->cli); @@ -2864,11 +2851,14 @@ int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) { + int fd; + int ret; SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - uint16 mode; - time_t t = (tbuf == NULL ? time(NULL) : tbuf->tv_sec); + time_t c_time; + time_t a_time; + time_t m_time; if (!context || !context->internal || !context->internal->_initialized) { @@ -2885,7 +2875,22 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) } - DEBUG(4, ("smbc_utimes(%s, [%s])\n", fname, ctime(&t))); + if (tbuf == NULL) { + a_time = m_time = time(NULL); + } else { + a_time = tbuf[0].tv_sec; + m_time = tbuf[1].tv_sec; + } + + { + char atimebuf[32]; + char mtimebuf[32]; + + DEBUG(4, ("smbc_utimes(%s, atime = %s mtime = %s)\n", + fname, + ctime_r(&a_time, atimebuf), + ctime_r(&m_time, mtimebuf))); + } if (smbc_parse_path(context, fname, server, sizeof(server), @@ -2908,22 +2913,46 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) return -1; /* errno set by smbc_server */ } - if (!smbc_getatr(context, srv, path, - &mode, NULL, - NULL, NULL, NULL, - NULL)) { + /* + * cli_setatr() does not work on win98, and it also doesn't support + * setting the access time (only the modification time), so in all + * cases, we open the specified file and use cli_setattrE() which + * should work on all OS versions, and supports both times. + */ + if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + + errno = smbc_errno(context, &srv->cli); return -1; - } + + } - if (!cli_setatr(&srv->cli, path, mode, t)) { - /* some servers always refuse directory changes */ - if (!(mode & aDIR)) { - errno = smbc_errno(context, &srv->cli); - return -1; - } - } + /* Get the creat time of the file; we'll need it in the set call */ + ret = cli_getattrE(&srv->cli, fd, NULL, NULL, &c_time, NULL, NULL); - return 0; + /* Some OS versions don't support create time */ + if (c_time == 0) { + c_time = time(NULL); + } + + /* + * For sanity sake, since there is no POSIX function to set the create + * time of a file, if the existing create time is greater than either + * of access time or modification time, set create time to the + * smallest of those. This ensure that the create time of a file is + * never greater than its last access or modification time. + */ + if (c_time > a_time) c_time = a_time; + if (c_time > m_time) c_time = m_time; + + /* If we sucessfully retrieved the create time... */ + if (ret) { + /* ... then set the new attributes */ + ret = cli_setattrE(&srv->cli, fd, c_time, a_time, m_time); + } + + cli_close(&srv->cli, fd); + + return ret; } -- cgit From f3ad9323c62860107ad222a0014d6e661aee42f3 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 1 Jun 2005 20:17:16 +0000 Subject: r7172: This is the proper fix for setting file times from libsmbclient. We now try setpathinfo, and if that doesn't work (e.g. on win98), revert to the previous slower method. (This used to be commit 6c05812bd90b0db69d974ee2758721dc2974a507) --- source3/libsmb/clirap.c | 95 +++++++++++++++++ source3/libsmb/libsmb_cache.c | 2 +- source3/libsmb/libsmbclient.c | 231 +++++++++++++++++++++++++++--------------- 3 files changed, 243 insertions(+), 85 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 06b683b038..4766811c8e 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -457,6 +457,101 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, return True; } + +/**************************************************************************** +send a setpathinfo call +****************************************************************************/ +BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, + time_t c_time, time_t a_time, time_t m_time, uint16 mode) +{ + unsigned int data_len = 0; + unsigned int param_len = 0; + unsigned int rparam_len, rdata_len; + uint16 setup = TRANSACT2_SETPATHINFO; + pstring param; + pstring data; + char *rparam=NULL, *rdata=NULL; + int count=8; + BOOL ret; + void (*date_fn)(char *buf,int offset,time_t unixdate); + char *p; + + memset(param, 0, sizeof(param)); + memset(data, 0, sizeof(data)); + + p = param; + + /* Add the information level */ + SSVAL(p, 0, SMB_INFO_STANDARD); + + /* Skip reserved */ + p += 6; + + /* Add the file name */ + p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); + + param_len = PTR_DIFF(p, param); + + p = data; + + if (cli->win95) { + date_fn = put_dos_date; + } else { + date_fn = put_dos_date2; + } + + /* Add the create, last access, and modification times */ + (*date_fn)(p, 0, c_time); + (*date_fn)(p, 4, a_time); + (*date_fn)(p, 8, m_time); + p += 12; + + /* Skip DataSize and AllocationSize */ + p += 8; + + /* Add attributes */ + SSVAL(p, 0, mode); + p += 2; + + /* Add EA size (none) */ + SIVAL(p, 0, 0); + p += 4; + + data_len = PTR_DIFF(p, data); + + do { + ret = (cli_send_trans(cli, SMBtrans2, + NULL, /* Name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + data, data_len, cli->max_xmit /* data, length, max */ + ) && + cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_len, + &rdata, &rdata_len)); + if (!cli_is_dos_error(cli)) break; + if (!ret) { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_dos_error(cli, &eclass, &ecode); + if (eclass != ERRSRV || ecode != ERRerror) break; + smb_msleep(100); + } + } while (count-- && ret==False); + + if (!ret) { + return False; + } + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return True; +} + + /**************************************************************************** send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index dabf5a527d..de9a1656d8 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -102,7 +102,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, /* * Search the server cache for a server - * returns server_fd on success, -1 on error (not found) + * returns server handle on success, NULL on error (not found) * This function is only used if the external cache is not enabled */ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 296dbc7f5b..404d9def69 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -420,7 +420,7 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c) } /* - * Check a server_fd. + * Check a server for being alive and well. * returns 0 if the server is in shape. Returns 1 on error * * Also useable outside libsmbclient to enable external cache @@ -745,7 +745,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, /* * Ok, we have got a nice connection - * Let's find a free server_fd + * Let's allocate a server structure. */ srv = SMB_MALLOC_P(SMBCSRV); @@ -757,6 +757,9 @@ SMBCSRV *smbc_server(SMBCCTX *context, ZERO_STRUCTP(srv); srv->cli = c; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); + srv->no_pathinfo = False; + srv->no_pathinfo2 = False; + srv->no_nt_session = False; /* now add it to the cache (internal or external) */ /* Let the cache function set errno if it wants to */ @@ -1259,10 +1262,133 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, } /* - * Routine to unlink() a file + * Set file info on an SMB server. Use setpathinfo call first. If that + * fails, use setattrE.. + * + * Time parameters are always used and must be provided. + * "mode" (attributes) parameter may be set to -1 if it is not to be set. */ +static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, + time_t c_time, time_t a_time, time_t m_time, + uint16 mode) +{ + int fd; + int ret; + + /* + * Get the create time of the file (if not provided); we'll need it in + * the set call. + */ + if (! srv->no_pathinfo && c_time != 0) { + if (! cli_qpathinfo(&srv->cli, path, + &c_time, NULL, NULL, NULL, NULL)) { + /* qpathinfo not available */ + srv->no_pathinfo = True; + } else { + /* + * We got a creation time. For sanity sake, since + * there is no POSIX function to set the create time + * of a file, if the existing create time is greater + * than either of access time or modification time, + * set create time to the smallest of those. This + * ensure that the create time of a file is never + * greater than its last access or modification time. + */ + if (c_time > a_time) c_time = a_time; + if (c_time > m_time) c_time = m_time; + } + } + + /* + * First, try setpathinfo (if qpathinfo succeeded), for it is the + * modern function for "new code" to be using, and it works given a + * filename rather than requiring that the file be opened to have its + * attributes manipulated. + */ + if (srv->no_pathinfo || + ! cli_setpathinfo(&srv->cli, path, c_time, a_time, m_time, mode)) { + + /* + * setpathinfo is not supported; go to plan B. + * + * cli_setatr() does not work on win98, and it also doesn't + * support setting the access time (only the modification + * time), so in all cases, we open the specified file and use + * cli_setattrE() which should work on all OS versions, and + * supports both times. + */ -static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) + /* Don't try {q,set}pathinfo() again, with this server */ + srv->no_pathinfo = True; + + /* Open the file */ + if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + + errno = smbc_errno(context, &srv->cli); + return -1; + } + + /* + * Get the creat time of the file (if it wasn't provided). + * We'll need it in the set call + */ + if (c_time == 0) { + ret = cli_getattrE(&srv->cli, fd, + NULL, NULL, + &c_time, NULL, NULL); + } else { + ret = True; + } + + /* If we got create time, set times */ + if (ret) { + /* Some OS versions don't support create time */ + if (c_time == 0) { + c_time = time(NULL); + } + + /* + * For sanity sake, since there is no POSIX function + * to set the create time of a file, if the existing + * create time is greater than either of access time + * or modification time, set create time to the + * smallest of those. This ensure that the create + * time of a file is never greater than its last + * access or modification time. + */ + if (c_time > a_time) c_time = a_time; + if (c_time > m_time) c_time = m_time; + + /* Set the new attributes */ + ret = cli_setattrE(&srv->cli, fd, + c_time, a_time, m_time); + cli_close(&srv->cli, fd); + } + + /* + * Unfortunately, setattrE() doesn't have a provision for + * setting the access mode (attributes). We'll have to try + * cli_setatr() for that, and with only this parameter, it + * seems to work on win98. + */ + if (ret && mode != (uint16) -1) { + ret = cli_setatr(&srv->cli, path, mode, 0); + } + + if (! ret) { + errno = smbc_errno(context, &srv->cli); + return False; + } + } + + return True; +} + + /* + * Routine to unlink() a file + */ + + static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; pstring path; @@ -2851,12 +2977,9 @@ int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) { - int fd; - int ret; SMBCSRV *srv; fstring server, share, user, password, workgroup; pstring path; - time_t c_time; time_t a_time; time_t m_time; @@ -2910,49 +3033,14 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) srv = smbc_server(context, server, share, workgroup, user, password); if (!srv) { - return -1; /* errno set by smbc_server */ + return -1; /* errno set by smbc_server */ } - /* - * cli_setatr() does not work on win98, and it also doesn't support - * setting the access time (only the modification time), so in all - * cases, we open the specified file and use cli_setattrE() which - * should work on all OS versions, and supports both times. - */ - if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) { - - errno = smbc_errno(context, &srv->cli); - return -1; - + if (!smbc_setatr(context, srv, path, 0, a_time, m_time, 0)) { + return -1; /* errno set by smbc_setatr */ } - /* Get the creat time of the file; we'll need it in the set call */ - ret = cli_getattrE(&srv->cli, fd, NULL, NULL, &c_time, NULL, NULL); - - /* Some OS versions don't support create time */ - if (c_time == 0) { - c_time = time(NULL); - } - - /* - * For sanity sake, since there is no POSIX function to set the create - * time of a file, if the existing create time is greater than either - * of access time or modification time, set create time to the - * smallest of those. This ensure that the create time of a file is - * never greater than its last access or modification time. - */ - if (c_time > a_time) c_time = a_time; - if (c_time > m_time) c_time = m_time; - - /* If we sucessfully retrieved the create time... */ - if (ret) { - /* ... then set the new attributes */ - ret = cli_setattrE(&srv->cli, fd, c_time, a_time, m_time); - } - - cli_close(&srv->cli, fd); - - return ret; + return 0; } @@ -4334,23 +4422,15 @@ int smbc_setxattr_ctx(SMBCCTX *context, dos_attr_parse(context, dad, srv, namevalue); /* Set the new DOS attributes */ -#if 0 /* not yet implemented */ - if (! cli_setpathinfo(&srv->cli, path, - dad->c_time, - dad->a_time, - dad->m_time, - dad->mode)) { - if (!cli_setatr(&srv->cli, path, - dad->mode, dad->m_time)) { - errno = smbc_errno(context, &srv->cli); - } + if (! smbc_setatr(context, srv, path, + dad->c_time, + dad->a_time, + dad->m_time, + dad->mode)) { + + /* cause failure if NT failed too */ + dad = NULL; } -#else - if (!cli_setatr(&srv->cli, path, - dad->mode, dad->m_time)) { - errno = smbc_errno(context, &srv->cli); - } -#endif } /* we only fail if both NT and DOS sets failed */ @@ -4472,28 +4552,11 @@ int smbc_setxattr_ctx(SMBCCTX *context, dos_attr_parse(context, dad, srv, namevalue); /* Set the new DOS attributes */ -#if 0 /* not yet implemented */ - ret2 = cli_setpathinfo(&srv->cli, path, - dad->c_time, - dad->a_time, - dad->m_time, - dad->mode); - if (! ret2) { - ret2 = cli_setatr(&srv->cli, path, - dad->mode, - dad->m_time); - if (! ret2) { - errno = smbc_errno(context, - &srv->cli); - } - } -#else - ret2 = cli_setatr(&srv->cli, path, - dad->mode, dad->m_time); - if (! ret2) { - errno = smbc_errno(context, &srv->cli); - } -#endif + ret2 = smbc_setatr(context, srv, path, + dad->c_time, + dad->a_time, + dad->m_time, + dad->mode); /* ret2 has True (success) / False (failure) */ if (ret2) { -- cgit From 2efe68918d84d2028b447f8133ed3919dd7fe3aa Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 1 Jun 2005 20:25:33 +0000 Subject: r7175: fix incorrect comment (This used to be commit 6f951c863ea4671a62075c6ac963f198fbf322b1) --- source3/libsmb/libsmbclient.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 404d9def69..bf3307cfb8 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1265,7 +1265,10 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, * Set file info on an SMB server. Use setpathinfo call first. If that * fails, use setattrE.. * - * Time parameters are always used and must be provided. + * Access and modification time parameters are always used and must be + * provided. Create time, if zero, will be determined from the actual create + * time of the file. If non-zero, the create time will be set as well. + * * "mode" (attributes) parameter may be set to -1 if it is not to be set. */ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, -- cgit From bf484a8f8e7d3c925a4916fdbb91c2843532ec63 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 3 Jun 2005 18:54:32 +0000 Subject: r7245: bug fixes in libsmbclient, setting time attributes (This used to be commit bf33902c059b7f222f89673ce07c8f929860a85f) --- source3/libsmb/libsmbclient.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index bf3307cfb8..2b511050ce 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1282,12 +1282,21 @@ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * Get the create time of the file (if not provided); we'll need it in * the set call. */ - if (! srv->no_pathinfo && c_time != 0) { + if (! srv->no_pathinfo && c_time == 0) { if (! cli_qpathinfo(&srv->cli, path, &c_time, NULL, NULL, NULL, NULL)) { /* qpathinfo not available */ srv->no_pathinfo = True; } else { + /* + * We got a creation time. Some OS versions don't + * return a valid create time, though. If we got an + * invalid time, start with the current time instead. + */ + if (c_time == 0 || c_time == (time_t) -1) { + c_time = time(NULL); + } + /* * We got a creation time. For sanity sake, since * there is no POSIX function to set the create time @@ -1346,7 +1355,7 @@ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, /* If we got create time, set times */ if (ret) { /* Some OS versions don't support create time */ - if (c_time == 0) { + if (c_time == 0 || c_time == -1) { c_time = time(NULL); } -- cgit From 7344cc3ba4031b00cb0bd3636a0bbbbd01c394a5 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 6 Jun 2005 14:37:31 +0000 Subject: r7339: only check for dfs proxy referrals when the server supports dfs (This used to be commit 9e93244fa5bd06b142a980d4090fa8f95afc983a) --- source3/libsmb/clidfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 30c8701619..7ce4871b4d 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -161,7 +161,7 @@ static struct cli_state *do_connect( const char *server, const char *share, here before trying to connect to the original share. check_dfs_proxy() will fail if it is a normal share. */ - if ( cli_check_msdfs_proxy( c, sharename, newserver, newshare ) ) { + if ( (c->capabilities & CAP_DFS) && cli_check_msdfs_proxy( c, sharename, newserver, newshare ) ) { cli_shutdown(c); return do_connect( newserver, newshare, False ); } -- cgit From 4bc39f05b77a8601506fa144a20d7e9ab9c3efe6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 8 Jun 2005 13:59:03 +0000 Subject: r7391: - Added client-support for various lsa_query_trust_dom_info-calls and a rpcclient-tester for some info-levels. Jerry, I tried to adopt to prs_pointer() where possible and to not interfere with your work for usrmgr. - Add "net rpc trustdom vampire"-tool. This allows to retrieve Interdomain Trust(ed)-Relationships from NT4-Servers including cleartext-passwords (still stored in the local secrets.tdb). The net-hook was done in cooperation with Lars Mueller . To vampire trusted domains simply call: net rpc trustdom vampire -S nt4dc -Uadmin%pass Guenther (This used to be commit 512585293963a1737f831af697ea1dc092d63cb0) --- source3/libsmb/smbencrypt.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ab61f6b419..8361c35a8e 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -583,3 +583,69 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessi memcpy(&out->data[i], bout, MIN(8, in->length-i)); } } + +/* Decrypts password-blob with session-key + * @param pass password for session-key + * @param data_in DATA_BLOB encrypted password + * + * Returns cleartext password in CH_UNIX + * Caller must free the returned string + */ + +char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in) +{ + DATA_BLOB data_out, sess_key; + uchar nt_hash[16]; + uint32_t length; + uint32_t version; + fstring cleartextpwd; + + if (!data_in || !pass) + return NULL; + + /* generate md4 password-hash derived from the NT UNICODE password */ + E_md4hash(pass, nt_hash); + + /* hashed twice with md4 */ + mdfour(nt_hash, nt_hash, 16); + + /* 16-Byte session-key */ + sess_key = data_blob(nt_hash, 16); + if (sess_key.data == NULL) + return NULL; + + data_out = data_blob(NULL, data_in->length); + if (data_out.data == NULL) + return NULL; + + /* decrypt with des3 */ + sess_crypt_blob(&data_out, data_in, &sess_key, 0); + + /* 4 Byte length, 4 Byte version */ + length = IVAL(data_out.data, 0); + version = IVAL(data_out.data, 4); + + if (length > data_in->length - 8) { + DEBUG(0,("decrypt_trustdom_secret: invalid length (%d)\n", length)); + return NULL; + } + + if (version != 1) { + DEBUG(0,("decrypt_trustdom_secret: unknown version number (%d)\n", version)); + return NULL; + } + + rpcstr_pull(cleartextpwd, data_out.data + 8, sizeof(fstring), length, 0 ); + +#ifdef DEBUG_PASSWORD + DEBUG(100,("decrypt_trustdom_secret: length is: %d, version is: %d, password is: %s\n", + length, version, cleartextpwd)); +#endif + + data_blob_free(&data_out); + data_blob_free(&sess_key); + + return SMB_STRDUP(cleartextpwd); + +} + -- cgit From fed660877c16562265327c6093ea645cf4176b5c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 8 Jun 2005 22:10:34 +0000 Subject: r7415: * big change -- volker's new async winbindd from trunk (This used to be commit a0ac9a8ffd4af31a0ebc423b4acbb2f043d865b8) --- source3/libsmb/clidgram.c | 283 +++++++++++++++++---------------------------- source3/libsmb/clientgen.c | 31 +++-- source3/libsmb/clitrans.c | 4 +- 3 files changed, 124 insertions(+), 194 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index ba65c46d16..819616105e 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -26,105 +26,101 @@ * cli_send_mailslot, send a mailslot for client code ... */ -int cli_send_mailslot(int dgram_sock, BOOL unique, const char *mailslot, - char *buf, int len, - const char *srcname, int src_type, - const char *dstname, int dest_type, - struct in_addr dest_ip, struct in_addr src_ip, - int dest_port, int src_port) +BOOL cli_send_mailslot(BOOL unique, const char *mailslot, + uint16 priority, + char *buf, int len, + const char *srcname, int src_type, + const char *dstname, int dest_type, + struct in_addr dest_ip) { - struct packet_struct p; - struct dgram_packet *dgram = &p.packet.dgram; - char *ptr, *p2; - char tmp[4]; - - memset((char *)&p, '\0', sizeof(p)); - - /* - * Next, build the DGRAM ... - */ - - /* DIRECT GROUP or UNIQUE datagram. */ - dgram->header.msg_type = unique ? 0x10 : 0x11; - dgram->header.flags.node_type = M_NODE; - dgram->header.flags.first = True; - dgram->header.flags.more = False; - dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)sys_getpid()%(unsigned)100); - dgram->header.source_ip.s_addr = src_ip.s_addr; - dgram->header.source_port = ntohs(src_port); - dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ - dgram->header.packet_offset = 0; + struct packet_struct p; + struct dgram_packet *dgram = &p.packet.dgram; + char *ptr, *p2; + char tmp[4]; + pid_t nmbd_pid; + + if ((nmbd_pid = pidfile_pid("nmbd")) == 0) { + DEBUG(3, ("No nmbd found\n")); + return False; + } + + if (!message_init()) + return False; + + memset((char *)&p, '\0', sizeof(p)); + + /* + * Next, build the DGRAM ... + */ + + /* DIRECT GROUP or UNIQUE datagram. */ + dgram->header.msg_type = unique ? 0x10 : 0x11; + dgram->header.flags.node_type = M_NODE; + dgram->header.flags.first = True; + dgram->header.flags.more = False; + dgram->header.dgm_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + + ((unsigned)sys_getpid()%(unsigned)100); + /* source ip is filled by nmbd */ + dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ + dgram->header.packet_offset = 0; - make_nmb_name(&dgram->source_name,srcname,src_type); - make_nmb_name(&dgram->dest_name,dstname,dest_type); - - ptr = &dgram->data[0]; - - /* Setup the smb part. */ - ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ - memcpy(tmp,ptr,4); - set_message(ptr,17,strlen(mailslot) + 1 + len,True); - memcpy(ptr,tmp,4); - - SCVAL(ptr,smb_com,SMBtrans); - SSVAL(ptr,smb_vwv1,len); - SSVAL(ptr,smb_vwv11,len); - SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); - SSVAL(ptr,smb_vwv13,3); - SSVAL(ptr,smb_vwv14,1); - SSVAL(ptr,smb_vwv15,1); - SSVAL(ptr,smb_vwv16,2); - p2 = smb_buf(ptr); - fstrcpy(p2,mailslot); - p2 = skip_string(p2,1); - - memcpy(p2,buf,len); - p2 += len; - - dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ - - p.ip = dest_ip; - p.port = dest_port; - p.fd = dgram_sock; - p.timestamp = time(NULL); - p.packet_type = DGRAM_PACKET; - - DEBUG(4,("send_mailslot: Sending to mailslot %s from %s IP %s ", mailslot, - nmb_namestr(&dgram->source_name), inet_ntoa(src_ip))); - DEBUG(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip))); - - return send_packet(&p); - + make_nmb_name(&dgram->source_name,srcname,src_type); + make_nmb_name(&dgram->dest_name,dstname,dest_type); + + ptr = &dgram->data[0]; + + /* Setup the smb part. */ + ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ + memcpy(tmp,ptr,4); + set_message(ptr,17,strlen(mailslot) + 1 + len,True); + memcpy(ptr,tmp,4); + + SCVAL(ptr,smb_com,SMBtrans); + SSVAL(ptr,smb_vwv1,len); + SSVAL(ptr,smb_vwv11,len); + SSVAL(ptr,smb_vwv12,70 + strlen(mailslot)); + SSVAL(ptr,smb_vwv13,3); + SSVAL(ptr,smb_vwv14,1); + SSVAL(ptr,smb_vwv15,priority); + SSVAL(ptr,smb_vwv16,2); + p2 = smb_buf(ptr); + fstrcpy(p2,mailslot); + p2 = skip_string(p2,1); + + memcpy(p2,buf,len); + p2 += len; + + dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ + + p.packet_type = DGRAM_PACKET; + p.ip = dest_ip; + p.timestamp = time(NULL); + + DEBUG(4,("send_mailslot: Sending to mailslot %s from %s ", + mailslot, nmb_namestr(&dgram->source_name))); + DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), + inet_ntoa(dest_ip))); + + return message_send_pid(nmbd_pid, MSG_SEND_PACKET, &p, sizeof(p), + False); } /* * cli_get_response: Get a response ... */ -int cli_get_response(int dgram_sock, BOOL unique, const char *mailslot, char *buf, int bufsiz) +BOOL cli_get_response(const char *mailslot, char *buf, int bufsiz) { - struct packet_struct *packet; - - packet = receive_dgram_packet(dgram_sock, 5, mailslot); - - if (packet) { /* We got one, pull what we want out of the SMB data ... */ - - struct dgram_packet *dgram = &packet->packet.dgram; - - /* - * We should probably parse the SMB, but for now, we will pull what - * from fixed, known locations ... - */ + struct packet_struct *p; - /* Copy the data to buffer, respecting sizes ... */ + p = receive_unexpected(DGRAM_PACKET, 0, mailslot); - memcpy(buf, &dgram->data[92], MIN(bufsiz, (dgram->datasize - 92))); + if (p == NULL) + return False; - } - else - return -1; - - return 0; + memcpy(buf, &p->packet.dgram.data[92], + MIN(bufsiz, p->packet.dgram.datasize-92)); + return True; } /* @@ -135,108 +131,43 @@ static char cli_backup_list[1024]; int cli_get_backup_list(const char *myname, const char *send_to_name) { - pstring outbuf; - char *p; - struct in_addr sendto_ip, my_ip; - int dgram_sock; - struct sockaddr_in sock_out; - socklen_t name_size; - - if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) { - - DEBUG(0, ("Could not resolve name: %s<1D>\n", send_to_name)); - return False; - - } - - my_ip.s_addr = inet_addr("0.0.0.0"); - - if (!resolve_name(myname, &my_ip, 0x00)) { /* FIXME: Call others here */ - - DEBUG(0, ("Could not resolve name: %s<00>\n", myname)); - - } - - if ((dgram_sock = open_socket_out(SOCK_DGRAM, &sendto_ip, 138, LONG_CONNECT_TIMEOUT)) < 0) { - - DEBUG(4, ("open_sock_out failed ...")); - return False; - - } - - /* Make it a broadcast socket ... */ + pstring outbuf; + char *p; + struct in_addr sendto_ip; - set_socket_options(dgram_sock, "SO_BROADCAST"); + if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) { - /* Make it non-blocking??? */ + DEBUG(0, ("Could not resolve name: %s<1D>\n", send_to_name)); + return False; - if (fcntl(dgram_sock, F_SETFL, O_NONBLOCK) < 0) { + } - DEBUG(0, ("Unable to set non blocking on dgram sock\n")); + memset(cli_backup_list, '\0', sizeof(cli_backup_list)); + memset(outbuf, '\0', sizeof(outbuf)); - } - - /* Now, bind a local addr to it ... Try port 138 first ... */ - - memset((char *)&sock_out, '\0', sizeof(sock_out)); - sock_out.sin_addr.s_addr = INADDR_ANY; - sock_out.sin_port = htons(138); - sock_out.sin_family = AF_INET; - - if (bind(dgram_sock, (struct sockaddr *)&sock_out, sizeof(sock_out)) < 0) { - - /* Try again on any port ... */ - - sock_out.sin_port = INADDR_ANY; - - if (bind(dgram_sock, (struct sockaddr *)&sock_out, sizeof(sock_out)) < 0) { - - DEBUG(4, ("failed to bind socket to address ...\n")); - return False; - - } - - } + p = outbuf; - /* Now, figure out what socket name we were bound to. We want the port */ + SCVAL(p, 0, ANN_GetBackupListReq); + p++; - name_size = sizeof(sock_out); + SCVAL(p, 0, 1); /* Count pointer ... */ + p++; - getsockname(dgram_sock, (struct sockaddr *)&sock_out, &name_size); + SIVAL(p, 0, 1); /* The sender's token ... */ + p += 4; - DEBUG(5, ("Socket bound to IP:%s, port: %d\n", inet_ntoa(sock_out.sin_addr), ntohs(sock_out.sin_port))); + cli_send_mailslot(True, "\\MAILSLOT\\BROWSE", 1, outbuf, + PTR_DIFF(p, outbuf), myname, 0, send_to_name, + 0x1d, sendto_ip); - /* Now, build the request */ + /* We should check the error and return if we got one */ - memset(cli_backup_list, '\0', sizeof(cli_backup_list)); - memset(outbuf, '\0', sizeof(outbuf)); + /* Now, get the response ... */ - p = outbuf; + cli_get_response("\\MAILSLOT\\BROWSE", + cli_backup_list, sizeof(cli_backup_list)); - SCVAL(p, 0, ANN_GetBackupListReq); - p++; - - SCVAL(p, 0, 1); /* Count pointer ... */ - p++; - - SIVAL(p, 0, 1); /* The sender's token ... */ - p += 4; - - cli_send_mailslot(dgram_sock, True, "\\MAILSLOT\\BROWSE", outbuf, - PTR_DIFF(p, outbuf), myname, 0, send_to_name, - 0x1d, sendto_ip, my_ip, 138, sock_out.sin_port); - - /* We should check the error and return if we got one */ - - /* Now, get the response ... */ - - cli_get_response(dgram_sock, True, "\\MAILSLOT\\BROWSE", cli_backup_list, sizeof(cli_backup_list)); - - /* Should check the response here ... FIXME */ - - close(dgram_sock); - - return True; + return True; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e787650c2f..2977099f7d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -22,8 +22,6 @@ #include "includes.h" -extern int smb_read_error; - /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -83,6 +81,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { + extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -321,9 +320,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli_null_set_signing(cli); for (i=0; int_pipe_fnum[i] = 0; + cli->pipes[i].fnum = 0; - cli->saved_netlogon_pipe_fnum = 0; + cli->netlogon_pipe.fnum = 0; cli->initialised = 1; cli->allocated = alloced_cli; @@ -353,14 +352,14 @@ void cli_nt_session_close(struct cli_state *cli) { int i; - if (cli->ntlmssp_pipe_state) { - ntlmssp_end(&cli->ntlmssp_pipe_state); - } - for (i=0; int_pipe_fnum[i] != 0) - cli_close(cli, cli->nt_pipe_fnum[i]); - cli->nt_pipe_fnum[i] = 0; + if (cli->pipes[i].pipe_auth_flags & AUTH_PIPE_NTLMSSP) { + ntlmssp_end(&cli->pipes[i].ntlmssp_pipe_state); + } + + if (cli->pipes[i].fnum != 0) + cli_close(cli, cli->pipes[i].fnum); + cli->pipes[i].fnum = 0; } cli->pipe_idx = -1; } @@ -371,9 +370,9 @@ close the NETLOGON session holding the session key for NETSEC void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) { - if (cli->saved_netlogon_pipe_fnum != 0) { - cli_close(cli, cli->saved_netlogon_pipe_fnum); - cli->saved_netlogon_pipe_fnum = 0; + if (cli->netlogon_pipe.fnum != 0) { + cli_close(cli, cli->netlogon_pipe.fnum); + cli->netlogon_pipe.fnum = 0; } } @@ -408,8 +407,8 @@ void cli_close_connection(struct cli_state *cli) data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); - if (cli->ntlmssp_pipe_state) - ntlmssp_end(&cli->ntlmssp_pipe_state); + if (cli->pipes[cli->pipe_idx].pipe_auth_flags & AUTH_PIPE_NTLMSSP) + ntlmssp_end(&cli->pipes[cli->pipe_idx].ntlmssp_pipe_state); if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 27da63ccda..75afe5195e 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -505,7 +505,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, */ if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if (cli->nt_pipe_fnum[cli->pipe_idx] == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + if (cli->pipes[cli->pipe_idx].fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { cli_signing_trans_stop(cli); return(False); } @@ -639,7 +639,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, } if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if(cli->nt_pipe_fnum[cli->pipe_idx] == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + if(cli->pipes[cli->pipe_idx].fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { cli_signing_trans_stop(cli); return(False); } -- cgit From 46c94b2659fa1f9d7ce2b6fd798e3abb3c7760d8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 10 Jun 2005 22:03:33 +0000 Subject: r7472: fix smbpasswd user password change (still worked by bad error messages) due to trying to strdup a NULL pointer (This used to be commit a48ff479dd4fe99d199ff934aae14ac6e688d8f4) --- source3/libsmb/ntlmssp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 4d9aaf989b..574b37d4a0 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -138,7 +138,7 @@ static NTSTATUS set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *ch NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) { - ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user); + ntlmssp_state->user = talloc_strdup(ntlmssp_state->mem_ctx, user ? user : "" ); if (!ntlmssp_state->user) { return NT_STATUS_NO_MEMORY; } @@ -168,7 +168,7 @@ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password */ NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) { - ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain); + ntlmssp_state->domain = talloc_strdup(ntlmssp_state->mem_ctx, domain ? domain : "" ); if (!ntlmssp_state->domain) { return NT_STATUS_NO_MEMORY; } -- cgit From 33a4c0b5a1052026193dcbb800e2bccb1b832730 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Jun 2005 22:26:08 +0000 Subject: r7554: Refactor very messy code in util_sock.c Remove write_socket_data/read_socket_data as they do nothing that write_socket/read_socket don't do. Add a more useful error message when read_socket/write_socket error out on the main client fd for a process (ie. try and list the IP of the client that errored). Jeremy. (This used to be commit cbd7578e7c226e6a8002542141b914ed4c7a8269) --- source3/libsmb/clientgen.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2977099f7d..2e21473511 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -127,6 +127,21 @@ BOOL cli_receive_smb(struct cli_state *cli) return True; } +static ssize_t write_socket(int fd, const char *buf, size_t len) +{ + ssize_t ret=0; + + DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); + ret = write_data(fd,buf,len); + + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); + if(ret <= 0) + DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", + (int)len, fd, strerror(errno) )); + + return(ret); +} + /**************************************************************************** Send an smb to a fd. ****************************************************************************/ -- cgit From 3f657f41cc7a71b3d5b769b31be030ebf543a645 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 15 Jun 2005 12:43:36 +0000 Subject: r7606: add WERR_NET_NAME_NOT_FOUND. This is what windows returns when trying to manipulate non-existing shares. Guenther (This used to be commit 2e5cb531ab8a8babbc425b22d17a39c18f602d4f) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 0dca265348..4449c92ab1 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -71,6 +71,7 @@ werror_code_struct dos_errs[] = { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { "WERR_IO_PENDING", WERR_IO_PENDING }, { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL }, + { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, { NULL, W_ERROR(0) } }; -- cgit From 3005405b521c2b88a4dcdaece505d8887d7d0c37 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 21 Jun 2005 20:34:24 +0000 Subject: r7817: Eliminate use of ctime_r() in libsmbclient DEBUG statement. It seems that ctime_r() takes different parameters on Solaris than it does on Linux, and it's easier to just eliminate the use of it than to write a configure test. (This used to be commit 513ea79b2ebc9a78c118042abca942da061d4647) --- source3/libsmb/libsmbclient.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2b511050ce..dac30b934e 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3017,14 +3017,26 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) m_time = tbuf[1].tv_sec; } + if (DEBUGLVL(4)) { + char *p; char atimebuf[32]; char mtimebuf[32]; - DEBUG(4, ("smbc_utimes(%s, atime = %s mtime = %s)\n", - fname, - ctime_r(&a_time, atimebuf), - ctime_r(&m_time, mtimebuf))); + strncpy(atimebuf, ctime(&a_time), sizeof(atimebuf)); + atimebuf[sizeof(atimebuf) - 1] = '\0'; + if ((p = strchr(atimebuf, '\n')) != NULL) { + *p = '\0'; + } + + strncpy(mtimebuf, ctime(&m_time), sizeof(mtimebuf)); + mtimebuf[sizeof(mtimebuf) - 1] = '\0'; + if ((p = strchr(mtimebuf, '\n')) != NULL) { + *p = '\0'; + } + + dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n", + fname, atimebuf, mtimebuf); } if (smbc_parse_path(context, fname, -- cgit From 19ca97a70f6b7b41d251eaa76e4d3c980c6eedff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Jun 2005 20:25:18 +0000 Subject: r7882: Looks like a large patch - but what it actually does is make Samba safe for using our headers and linking with C++ modules. Stops us from using C++ reserved keywords in our code. Jeremy (This used to be commit 9506b8e145982b1160a2f0aee5c9b7a54980940a) --- source3/libsmb/clierror.c | 4 ++-- source3/libsmb/libsmb_cache.c | 4 ++-- source3/libsmb/libsmbclient.c | 6 +++--- source3/libsmb/namequery.c | 12 ++++++------ source3/libsmb/smberr.c | 34 +++++++++++++++++----------------- source3/libsmb/spnego.c | 2 +- 6 files changed, 31 insertions(+), 31 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index ec0ca53a85..a16c1f5241 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -153,9 +153,9 @@ NTSTATUS cli_nt_error(struct cli_state *cli) int flgs2 = SVAL(cli->inbuf,smb_flg2); if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) { - int class = CVAL(cli->inbuf,smb_rcls); + int e_class = CVAL(cli->inbuf,smb_rcls); int code = SVAL(cli->inbuf,smb_err); - return dos_to_ntstatus(class, code); + return dos_to_ntstatus(e_class, code); } return NT_STATUS(IVAL(cli->inbuf,smb_rcls)); diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index de9a1656d8..e6033faf50 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -46,7 +46,7 @@ struct smbc_server_cache { * Add a new connection to the server cache. * This function is only used if the external cache is not enabled */ -static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, +static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv, const char * server, const char * share, const char * workgroup, const char * username) { @@ -60,7 +60,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * new, ZERO_STRUCTP(srvcache); - srvcache->server = new; + srvcache->server = newsrv; srvcache->server_name = SMB_STRDUP(server); if (!srvcache->server_name) { diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index dac30b934e..1823bb2ace 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3305,7 +3305,7 @@ static BOOL parse_ace(struct cli_state *ipc_cli, /* add an ACE to a list of ACEs in a SEC_ACL */ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) { - SEC_ACL *new; + SEC_ACL *newacl; SEC_ACE *aces; if (! *the_acl) { (*the_acl) = make_sec_acl(ctx, 3, 1, ace); @@ -3315,9 +3315,9 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces); memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); - new = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); + newacl = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); SAFE_FREE(aces); - (*the_acl) = new; + (*the_acl) = newacl; return True; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e6868fb373..28b89db908 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -45,9 +45,9 @@ static int generate_trn_id(void) Parse a node status response into an array of structures. ****************************************************************************/ -static struct node_status *parse_node_status(char *p, int *num_names, struct node_status_extra *extra) +static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra) { - struct node_status *ret; + NODE_STATUS_STRUCT *ret; int i; *num_names = CVAL(p,0); @@ -55,7 +55,7 @@ static struct node_status *parse_node_status(char *p, int *num_names, struct nod if (*num_names == 0) return NULL; - ret = SMB_MALLOC_ARRAY(struct node_status,*num_names); + ret = SMB_MALLOC_ARRAY(NODE_STATUS_STRUCT,*num_names); if (!ret) return NULL; @@ -84,7 +84,7 @@ static struct node_status *parse_node_status(char *p, int *num_names, struct nod structures holding the returned names or NULL if the query failed. **************************************************************************/ -struct node_status *node_status_query(int fd,struct nmb_name *name, +NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, struct in_addr to_ip, int *num_names, struct node_status_extra *extra) { @@ -95,7 +95,7 @@ struct node_status *node_status_query(int fd,struct nmb_name *name, struct packet_struct p; struct packet_struct *p2; struct nmb_packet *nmb = &p.packet.nmb; - struct node_status *ret; + NODE_STATUS_STRUCT *ret; ZERO_STRUCT(p); @@ -173,7 +173,7 @@ struct node_status *node_status_query(int fd,struct nmb_name *name, BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name) { - struct node_status *status = NULL; + NODE_STATUS_STRUCT *status = NULL; struct nmb_name nname; int count, i; int sock; diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 82efbdb689..b014fb947e 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -142,7 +142,7 @@ err_code_struct hard_msgs[] = { const struct { int code; - const char *class; + const char *e_class; err_code_struct *err_msgs; } err_classes[] = { {0,"SUCCESS",NULL}, @@ -160,13 +160,13 @@ const struct /**************************************************************************** return a SMB error name from a class and code ****************************************************************************/ -const char *smb_dos_err_name(uint8 class, uint16 num) +const char *smb_dos_err_name(uint8 e_class, uint16 num) { static pstring ret; int i,j; - for (i=0;err_classes[i].class;i++) - if (err_classes[i].code == class) { + for (i=0;err_classes[i].e_class;i++) + if (err_classes[i].code == e_class) { if (err_classes[i].err_msgs) { err_code_struct *err = err_classes[i].err_msgs; for (j=0;err[j].name;j++) @@ -178,7 +178,7 @@ const char *smb_dos_err_name(uint8 class, uint16 num) return ret; } - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error class (%d,%d)",class,num); + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error class (%d,%d)",e_class,num); return(ret); } @@ -196,18 +196,18 @@ const char *get_dos_error_msg(WERROR result) /**************************************************************************** return a SMB error class name as a string. ****************************************************************************/ -const char *smb_dos_err_class(uint8 class) +const char *smb_dos_err_class(uint8 e_class) { static pstring ret; int i; - for (i=0;err_classes[i].class;i++) { - if (err_classes[i].code == class) { - return err_classes[i].class; + for (i=0;err_classes[i].e_class;i++) { + if (err_classes[i].code == e_class) { + return err_classes[i].e_class; } } - slprintf(ret, sizeof(ret) - 1, "Error: Unknown class (%d)",class); + slprintf(ret, sizeof(ret) - 1, "Error: Unknown class (%d)",e_class); return(ret); } @@ -217,32 +217,32 @@ return a SMB string from an SMB buffer char *smb_dos_errstr(char *inbuf) { static pstring ret; - int class = CVAL(inbuf,smb_rcls); + int e_class = CVAL(inbuf,smb_rcls); int num = SVAL(inbuf,smb_err); int i,j; - for (i=0;err_classes[i].class;i++) - if (err_classes[i].code == class) { + for (i=0;err_classes[i].e_class;i++) + if (err_classes[i].code == e_class) { if (err_classes[i].err_msgs) { err_code_struct *err = err_classes[i].err_msgs; for (j=0;err[j].name;j++) if (num == err[j].code) { if (DEBUGLEVEL > 0) slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)", - err_classes[i].class, + err_classes[i].e_class, err[j].name,err[j].message); else slprintf(ret, sizeof(ret) - 1, "%s - %s", - err_classes[i].class,err[j].name); + err_classes[i].e_class,err[j].name); return ret; } } - slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num); + slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].e_class,num); return ret; } - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num); + slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",e_class,num); return(ret); } diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index a0f5565d4f..2eaec61ed7 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -47,7 +47,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2); - asn1_read_OID(asn1, token->mechTypes + i); + asn1_read_OID(asn1, &token->mechTypes[i]); } token->mechTypes[i] = NULL; -- cgit From 600935af498739db32874e57e763e9ce056f1bf5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Jun 2005 18:53:38 +0000 Subject: r7954: Fix from tridge from Samba4 (same code exists here) : fixed handling of ASN.1 objects bigger than 64k Jeremy. (This used to be commit 0da60e9954b84bac29bb219803f6175b7a30b591) --- source3/libsmb/asn1.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 6db12fc612..0999840794 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -86,7 +86,16 @@ BOOL asn1_pop_tag(ASN1_DATA *data) /* yes, this is ugly. We don't know in advance how many bytes the length of a tag will take, so we assumed 1 byte. If we were wrong then we need to correct our mistake */ - if (len > 255) { + if (len > 0xFFFF) { + data->data[nesting->start] = 0x83; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return False; + memmove(data->data+nesting->start+4, data->data+nesting->start+1, len); + data->data[nesting->start+1] = (len>>16) & 0xFF; + data->data[nesting->start+2] = (len>>8) & 0xFF; + data->data[nesting->start+3] = len&0xff; + } else if (len > 255) { data->data[nesting->start] = 0x82; if (!asn1_write_uint8(data, 0)) return False; if (!asn1_write_uint8(data, 0)) return False; -- cgit From 0a01b2246abb61bac833649bb189cf26db62fba2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 1 Jul 2005 22:24:00 +0000 Subject: r8064: * add the REG_XXX error codes to the pretty error messages * more work on the store_values() functions for the Printers key * add Control\Print\Monitors key to list for reg_db (This used to be commit 89f17b41cee633838b8cbd0d1bf8119a4b8d707e) --- source3/libsmb/doserr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 4449c92ab1..ef71a883f7 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -72,6 +72,9 @@ werror_code_struct dos_errs[] = { "WERR_IO_PENDING", WERR_IO_PENDING }, { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL }, { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, + { "WERR_REG_CORRUPT", WERR_REG_CORRUPT }, + { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, + { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, { NULL, W_ERROR(0) } }; -- cgit From 3a8af94424c8d60dd80f6b57806ef0b79465badc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 3 Jul 2005 12:05:07 +0000 Subject: r8093: Next round. Now it compiles with --enable-socket-wrapper. Volker (This used to be commit 25cbcfba30f534f3fb31627ba43421c42ccd5b0f) --- source3/libsmb/libsmb_compat.c | 6 +++--- source3/libsmb/libsmbclient.c | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 3dc60f7240..f9461f9368 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -163,7 +163,7 @@ int smbc_open(const char *furl, int flags, mode_t mode) fd = add_fd(file); if (fd == -1) - statcont->close(statcont, file); + statcont->close_fn(statcont, file); return fd; } @@ -180,7 +180,7 @@ int smbc_creat(const char *furl, mode_t mode) fd = add_fd(file); if (fd == -1) { /* Hmm... should we delete the file too ? I guess we could try */ - statcont->close(statcont, file); + statcont->close_fn(statcont, file); statcont->unlink(statcont, furl); } return fd; @@ -209,7 +209,7 @@ int smbc_close(int fd) { SMBCFILE * file = find_fd(fd); del_fd(fd); - return statcont->close(statcont, file); + return statcont->close_fn(statcont, file); } int smbc_unlink(const char *fname) diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 1823bb2ace..9104a083f5 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4953,7 +4953,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { saverr = errno; /* Save errno */ - c_file->close(c_file, fid1); + c_file->close_fn(c_file, fid1); errno = saverr; return -1; @@ -4966,8 +4966,8 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr if ((c_print->write(c_print, fid2, buf, bytes)) < 0) { saverr = errno; - c_file->close(c_file, fid1); - c_print->close(c_print, fid2); + c_file->close_fn(c_file, fid1); + c_print->close_fn(c_print, fid2); errno = saverr; } @@ -4976,8 +4976,8 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr saverr = errno; - c_file->close(c_file, fid1); /* We have to close these anyway */ - c_print->close(c_print, fid2); + c_file->close_fn(c_file, fid1); /* We have to close these anyway */ + c_print->close_fn(c_print, fid2); if (bytes < 0) { @@ -5152,7 +5152,7 @@ SMBCCTX * smbc_new_context(void) context->creat = smbc_creat_ctx; context->read = smbc_read_ctx; context->write = smbc_write_ctx; - context->close = smbc_close_ctx; + context->close_fn = smbc_close_ctx; context->unlink = smbc_unlink_ctx; context->rename = smbc_rename_ctx; context->lseek = smbc_lseek_ctx; @@ -5206,7 +5206,7 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) f = context->internal->_files; while (f) { - context->close(context, f); + context->close_fn(context, f); f = f->next; } context->internal->_files = NULL; -- cgit From 38e006fe8bc81c950302cc1e1700075b84eec329 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 6 Jul 2005 14:46:36 +0000 Subject: r8184: fix build issue on Solaris in smbclient (This used to be commit 137d270ee3bec297732380050bb53cf6b5487914) --- source3/libsmb/clifile.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 90ca98d17e..2fb5b456cc 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -262,7 +262,12 @@ BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */ sbuf->st_blocks = IVAL2_TO_SMB_BIG_UINT(rdata,8); /* number of blocks allocated */ +#if defined (HAVE_STAT_ST_BLOCKS) && defined(STAT_ST_BLOCKSIZE) sbuf->st_blocks /= STAT_ST_BLOCKSIZE; +#else + /* assume 512 byte blocks */ + sbuf->st_blocks /= 512; +#endif sbuf->st_ctime = interpret_long_date(rdata + 16); /* time of last change */ sbuf->st_atime = interpret_long_date(rdata + 24); /* time of last access */ sbuf->st_mtime = interpret_long_date(rdata + 32); /* time of last modification */ -- cgit From af8a691db11a5072865f8b03fd1cbd3aab5cb6d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Jul 2005 04:51:27 +0000 Subject: r8219: Merge the new open code from HEAD to 3.0. Haven't yet run the torture tests on this as it's very late NY time (just wanted to get this work into the tree). I'll test this over the weekend.... Jerry - in looking at the difference between the two trees there seem to be some printing/ntprinting.c and registry changes we might want to examine to try keep in sync. Jeremy. (This used to be commit c7fe18761e2c753afbffd3a78abff46472a9b8eb) --- source3/libsmb/clifile.c | 2 +- source3/libsmb/errormap.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 2fb5b456cc..87c6f2568b 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -705,7 +705,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess) { return cli_nt_create_full(cli, fname, 0, DesiredAccess, 0, - FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_EXISTS_OPEN, 0x0, 0x0); + FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0); } /**************************************************************************** diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index c79561bda8..8462fbee87 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -124,9 +124,9 @@ static const struct { {ERRHRD, ERRgeneral, NT_STATUS_HANDLE_NOT_WAITABLE}, {ERRDOS, ERRbadfid, NT_STATUS_PORT_DISCONNECTED}, {ERRHRD, ERRgeneral, NT_STATUS_DEVICE_ALREADY_ATTACHED}, - {ERRDOS, 161, NT_STATUS_OBJECT_PATH_INVALID}, + {ERRDOS, ERRinvalidpath, NT_STATUS_OBJECT_PATH_INVALID}, {ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND}, - {ERRDOS, 161, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, + {ERRDOS, ERRinvalidpath, NT_STATUS_OBJECT_PATH_SYNTAX_BAD}, {ERRHRD, ERRgeneral, NT_STATUS_DATA_OVERRUN}, {ERRHRD, ERRgeneral, NT_STATUS_DATA_LATE_ERROR}, {ERRDOS, 23, NT_STATUS_DATA_ERROR}, -- cgit From a3a85172167eba787a61e0eb8a7c914407e593ea Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 14 Jul 2005 14:40:30 +0000 Subject: r8475: BUG 2872: fix cut-n-paste error when checking pointer value in ntlmssp_set_workstation() (This used to be commit f1763c5decd14eb71ee3d7ea71859a85d5ee0dc1) --- source3/libsmb/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 574b37d4a0..b02c2384a8 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -182,7 +182,7 @@ NTSTATUS ntlmssp_set_domain(NTLMSSP_STATE *ntlmssp_state, const char *domain) NTSTATUS ntlmssp_set_workstation(NTLMSSP_STATE *ntlmssp_state, const char *workstation) { ntlmssp_state->workstation = talloc_strdup(ntlmssp_state->mem_ctx, workstation); - if (!ntlmssp_state->domain) { + if (!ntlmssp_state->workstation) { return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; -- cgit From ab398643a4e44211696ef5ce72b62ab7ecee7bc9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 19 Jul 2005 02:37:04 +0000 Subject: r8572: Remove crufty #define NO_SYSLOG as it's not used at all anymore. (This used to be commit 985dbb47d925e79c1195ca219f7ab5d6648b22b8) --- source3/libsmb/cliconnect.c | 2 -- source3/libsmb/clidfs.c | 2 -- source3/libsmb/clientgen.c | 2 -- source3/libsmb/clierror.c | 2 -- source3/libsmb/clifile.c | 2 -- source3/libsmb/clilist.c | 2 -- source3/libsmb/climessage.c | 2 -- source3/libsmb/clioplock.c | 2 -- source3/libsmb/cliprint.c | 2 -- source3/libsmb/clirap.c | 2 -- source3/libsmb/clirap2.c | 2 -- source3/libsmb/clireadwrite.c | 2 -- source3/libsmb/clitrans.c | 2 -- source3/libsmb/smberr.c | 2 -- 14 files changed, 28 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 5a9992d4e0..3d8e36c493 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" extern pstring user_socket_options; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 7ce4871b4d..51f21397f7 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2e21473511..f1794ab5dc 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /**************************************************************************** diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index a16c1f5241..355a2adf34 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /***************************************************** diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 87c6f2568b..a7e6fbfe3f 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /**************************************************************************** diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d9a6f4709d..a0be40bdc9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" extern file_info def_finfo; diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 8429ca4f41..f646096a4e 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index 0ffeb1926b..037d7147db 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /**************************************************************************** diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 732241a758..4a5ee5ae08 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /***************************************************************************** diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 4766811c8e..b53e19ef98 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -19,8 +19,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index b15ee1a63e..a327bae317 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -76,8 +76,6 @@ /* */ /*****************************************************/ -#define NO_SYSLOG - #include "includes.h" #define WORDSIZE 2 diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 9e52ed3594..1220907629 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /**************************************************************************** diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 75afe5195e..c6b1d465ff 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index b014fb947e..a21063e52a 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -17,8 +17,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" /* error code stuff - put together by Merik Karman -- cgit From 7fff6638fca113694ef1570ce1331cc8c2e056f8 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 5 Aug 2005 12:33:00 +0000 Subject: r9112: Fix #2953 - credentials chain on DC gets out of sync with client when NT_STATUS_NO_USER returned. We were moving to the next step in the chain when the client wasn't. Only update when the user logs on. (This used to be commit b01a3a4111f544eef5bd678237d07a82d1ce9c22) --- source3/libsmb/credentials.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 0d521bae8a..322b25ee43 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -208,8 +208,36 @@ BOOL deal_with_creds(uchar sess_key[8], DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data))); - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); + /* Bug #2953 - don't store new seed in client credentials + here, because we need to make sure we're moving forward first + */ return True; } + +/* + stores new seed in client credentials + jmcd - Bug #2953 - moved this functionality out of deal_with_creds, because we're + not supposed to move to the next step in the chain if a nonexistent user tries to logon +*/ +void reseed_client_creds(DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_clnt_cred) +{ + UTIME new_clnt_time; + uint32 new_cred; + + /* increment client time by one second */ + new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1; + + /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ + new_cred = IVAL(sto_clnt_cred->challenge.data, 0); + new_cred += new_clnt_time.time; + + DEBUG(5,("reseed_client_creds: new_cred[0]=%x\n", new_cred)); + DEBUG(5,("reseed_client_creds: new_clnt_time=%x\n", + new_clnt_time.time)); + DEBUG(5,("reseed_client_creds: clnt_cred=%s\n", + credstr(sto_clnt_cred->challenge.data))); + + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); +} -- cgit From dab71bed4e61b816b112433fc44e5f7259e4d2ab Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 24 Aug 2005 16:19:07 +0000 Subject: r9588: remove netsamlogon_cache interface...everything seems to work fine. Will deal with any fallout from special environments using a non-cache solution (This used to be commit e1de6f238f3981d81e49fb41919fdce4f07c8280) --- source3/libsmb/samlogon_cache.c | 247 ---------------------------------------- 1 file changed, 247 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index fdfc92a750..e69de29bb2 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -1,247 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Net_sam_logon info3 helpers - Copyright (C) Alexander Bokovoy 2002. - Copyright (C) Andrew Bartlett 2002. - Copyright (C) Gerald Carter 2003. - Copyright (C) Tim Potter 2003. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "includes.h" - -#define NETSAMLOGON_TDB "netsamlogon_cache.tdb" - -static TDB_CONTEXT *netsamlogon_tdb = NULL; - -/*********************************************************************** - open the tdb - ***********************************************************************/ - -BOOL netsamlogon_cache_init(void) -{ - if (!netsamlogon_tdb) { - netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0, - TDB_DEFAULT, O_RDWR | O_CREAT, 0600); - } - - return (netsamlogon_tdb != NULL); -} - - -/*********************************************************************** - Shutdown samlogon_cache database -***********************************************************************/ - -BOOL netsamlogon_cache_shutdown(void) -{ - if(netsamlogon_tdb) - return (tdb_close(netsamlogon_tdb) == 0); - - return True; -} - -/*********************************************************************** - Clear cache getpwnam and getgroups entries from the winbindd cache -***********************************************************************/ -void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) -{ - fstring domain; - TDB_DATA key; - BOOL got_tdb = False; - - /* We may need to call this function from smbd which will not have - winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ - - if (!tdb) { - tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000, - TDB_DEFAULT, O_RDWR, 0600); - if (!tdb) { - DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n")); - return; - } - got_tdb = True; - } - - unistr2_to_ascii(domain, &user->uni_logon_dom, sizeof(domain) - 1); - - /* Clear U/DOMAIN/RID cache entry */ - - asprintf(&key.dptr, "U/%s/%d", domain, user->user_rid); - key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */ - - DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); - - tdb_delete(tdb, key); - - SAFE_FREE(key.dptr); - - /* Clear UG/DOMAIN/RID cache entry */ - - asprintf(&key.dptr, "UG/%s/%d", domain, user->user_rid); - key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */ - - DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); - - tdb_delete(tdb, key); - - SAFE_FREE(key.dptr); - - if (got_tdb) - tdb_close(tdb); -} - -/*********************************************************************** - Store a NET_USER_INFO_3 structure in a tdb for later user - username should be in UTF-8 format -***********************************************************************/ - -BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USER_INFO_3 *user) -{ - TDB_DATA data; - fstring keystr; - prs_struct ps; - BOOL result = False; - DOM_SID user_sid; - time_t t = time(NULL); - - - if (!netsamlogon_cache_init()) { - DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); - return False; - } - - sid_copy( &user_sid, &user->dom_sid.sid ); - sid_append_rid( &user_sid, user->user_rid ); - - /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s", sid_string_static(&user_sid)); - - DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); - - /* only Samba fills in the username, not sure why NT doesn't */ - /* so we fill it in since winbindd_getpwnam() makes use of it */ - - if ( !user->uni_user_name.buffer ) { - init_unistr2( &user->uni_user_name, username, UNI_STR_TERMINATE ); - init_uni_hdr( &user->hdr_user_name, &user->uni_user_name ); - } - - /* Prepare data */ - - prs_init( &ps,MAX_PDU_FRAG_LEN , mem_ctx, MARSHALL); - - if ( !prs_uint32( "timestamp", &ps, 0, (uint32*)&t ) ) - return False; - - if ( net_io_user_info3("", user, &ps, 0, 3) ) - { - data.dsize = prs_offset( &ps ); - data.dptr = prs_data_p( &ps ); - - if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) - result = True; - - prs_mem_free( &ps ); - } - - return result; -} - -/*********************************************************************** - Retrieves a NET_USER_INFO_3 structure from a tdb. Caller must - free the user_info struct (malloc()'d memory) -***********************************************************************/ - -NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) -{ - NET_USER_INFO_3 *user = NULL; - TDB_DATA data, key; - prs_struct ps; - fstring keystr; - uint32 t; - - if (!netsamlogon_cache_init()) { - DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); - return False; - } - - /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s", sid_string_static(user_sid)); - DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); - key.dptr = keystr; - key.dsize = strlen(keystr)+1; - data = tdb_fetch( netsamlogon_tdb, key ); - - if ( data.dptr ) { - - if ( (user = SMB_MALLOC_P(NET_USER_INFO_3)) == NULL ) - return NULL; - - prs_init( &ps, 0, mem_ctx, UNMARSHALL ); - prs_give_memory( &ps, data.dptr, data.dsize, True ); - - if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) { - prs_mem_free( &ps ); - return False; - } - - if ( !net_io_user_info3("", user, &ps, 0, 3) ) { - SAFE_FREE( user ); - } - - prs_mem_free( &ps ); - -#if 0 /* The netsamlogon cache needs to hang around. Something about - this feels wrong, but it is the only way we can get all of the - groups. The old universal groups cache didn't expire either. - --jerry */ - { - time_t now = time(NULL); - uint32 time_diff; - - /* is the entry expired? */ - time_diff = now - t; - - if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) { - DEBUG(10,("netsamlogon_cache_get: cache entry expired \n")); - tdb_delete( netsamlogon_tdb, key ); - SAFE_FREE( user ); - } -#endif - } - - return user; -} - -BOOL netsamlogon_cache_have(const DOM_SID *user_sid) -{ - TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); - NET_USER_INFO_3 *user = NULL; - BOOL result; - - if (!mem_ctx) - return False; - - user = netsamlogon_cache_get(mem_ctx, user_sid); - - result = (user != NULL); - - talloc_destroy(mem_ctx); - SAFE_FREE(user); - - return result; -} -- cgit From f02a98d9b67f91fcce8e38717b59a634c2406904 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 24 Aug 2005 16:50:18 +0000 Subject: r9590: forget to remove this from the 3.0 tree (This used to be commit 74f8718438c73170d394c61eb91da9d8388f84d0) --- source3/libsmb/samlogon_cache.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 source3/libsmb/samlogon_cache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c deleted file mode 100644 index e69de29bb2..0000000000 -- cgit From a451584b2a83f0e63a072d6ccea8cbce5a2a465e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 2 Sep 2005 13:39:39 +0000 Subject: r9955: Fix misleading comments. Guenther (This used to be commit 0c3b7499d4bf11805a9fc5db88eb62dd003481af) --- source3/libsmb/clidfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 51f21397f7..1389f42df9 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -155,7 +155,7 @@ static struct cli_state *do_connect( const char *server, const char *share, DEBUG(4,(" session setup ok\n")); /* here's the fun part....to support 'msdfs proxy' shares - (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL + (on Samba) we have to issues a TRANS_GET_DFS_REFERRAL here before trying to connect to the original share. check_dfs_proxy() will fail if it is a normal share. */ -- cgit From ce3b4a10791117ade07425d3cbd8c4c804b1d6a4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 2 Sep 2005 14:12:04 +0000 Subject: r9958: revert last commit. Guenther (This used to be commit 351c783295672a327b6040537bd09d91dd210e53) --- source3/libsmb/clidfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 1389f42df9..51f21397f7 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -155,7 +155,7 @@ static struct cli_state *do_connect( const char *server, const char *share, DEBUG(4,(" session setup ok\n")); /* here's the fun part....to support 'msdfs proxy' shares - (on Samba) we have to issues a TRANS_GET_DFS_REFERRAL + (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL here before trying to connect to the original share. check_dfs_proxy() will fail if it is a normal share. */ -- cgit From a44e97c99f61916db3f7cc02cd2581c8d64be73a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 3 Sep 2005 16:40:05 +0000 Subject: r10001: adding in libmsrpc from Chris Nicholls (SoC project). not built by default per conversation with Jeremy until the rpc changes from trunk are merged back (This used to be commit e813de1e522692a6471828bf1fdf503d33f8cd72) --- source3/libsmb/libsmbclient.c | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 9104a083f5..ce47277c26 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -835,26 +835,29 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, return NULL; } - if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) { - DEBUG(1, ("cli_nt_session_open fail!\n")); - errno = ENOTSUP; - cli_shutdown(ipc_cli); - return NULL; - } - - /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, - but NT sends 0x2000000 so we might as well do it too. */ - - nt_status = cli_lsa_open_policy(ipc_cli, - ipc_cli->mem_ctx, - True, - GENERIC_EXECUTE_ACCESS, - pol); - - if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, ipc_cli); - cli_shutdown(ipc_cli); - return NULL; + if(pol) { + + if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) { + DEBUG(1, ("cli_nt_session_open fail!\n")); + errno = ENOTSUP; + cli_shutdown(ipc_cli); + return NULL; + } + + /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, + but NT sends 0x2000000 so we might as well do it too. */ + + nt_status = cli_lsa_open_policy(ipc_cli, + ipc_cli->mem_ctx, + True, + GENERIC_EXECUTE_ACCESS, + pol); + + if (!NT_STATUS_IS_OK(nt_status)) { + errno = smbc_errno(context, ipc_cli); + cli_shutdown(ipc_cli); + return NULL; + } } ipc_srv = SMB_MALLOC_P(SMBCSRV); -- cgit From 34721ad233227300d9c2e8b5483ba2c6c798a7da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 5 Sep 2005 20:36:07 +0000 Subject: r10042: Add in external LGPL library for accessing the share mode db. Allow others to examine & test. May not end up here eventually... Jeremy. (This used to be commit 7cc70ae63399eacd55bd0bf51ac2c7b004d761bf) --- source3/libsmb/smb_share_modes.c | 452 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 452 insertions(+) create mode 100644 source3/libsmb/smb_share_modes.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c new file mode 100644 index 0000000000..0ba68aed06 --- /dev/null +++ b/source3/libsmb/smb_share_modes.c @@ -0,0 +1,452 @@ +/* + Samba share mode database library external interface library. + Used by non-Samba products needing access to the Samba share mode db. + + Copyright (C) Jeremy Allison 2005. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "includes.h" +#include "smb_share_modes.h" + +/* + * open/close sharemode database. + */ + +struct smbdb_ctx *smb_share_mode_db_open(const char *db_path) +{ + struct smbdb_ctx *smb_db = SMB_MALLOC_P(struct smbdb_ctx); + + if (!smb_db) { + return NULL; + } + + memset(smb_db, '\0', sizeof(struct smbdb_ctx)); + + smb_db->smb_tdb = tdb_open_log(lock_path("locking.tdb"), + 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, + O_RDWR|O_CREAT, + 0644); + + if (!smb_db->smb_tdb) { + free(smb_db); + return NULL; + } + + /* Should check that this is the correct version.... */ + return smb_db; +} + +int smb_share_mode_db_close(struct smbdb_ctx *db_ctx) +{ + int ret = tdb_close(db_ctx->smb_tdb); + free(db_ctx); + return ret; +} + +/* Create locking key. */ + +struct samba_locking_key { + SMB_DEV_T dev; + SMB_INO_T ino; +}; + +static TDB_DATA get_locking_key(uint64_t dev, uint64_t ino) +{ + static struct samba_locking_key lk; + TDB_DATA ld; + + memset(&lk, '\0', sizeof(struct samba_locking_key)); + lk.dev = (SMB_DEV_T)dev; + lk.ino = (SMB_INO_T)ino; + ld.dptr = (char *)&lk; + ld.dsize = sizeof(lk); + return ld; +} + +/* + * lock/unlock entry in sharemode database. + */ + +int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx, + uint64_t dev, + uint64_t ino) +{ + return tdb_chainlock(db_ctx->smb_tdb, get_locking_key(dev, ino)); +} + +int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, + dev_t dev, + ino_t ino) +{ + return tdb_chainunlock(db_ctx->smb_tdb, get_locking_key(dev, ino)); +} + +/* Internal structure of Samba share mode db. */ +/* FIXME ! This should be moved into a Samba include file. */ + +struct locking_data { + union { + struct { + int num_share_mode_entries; + BOOL delete_on_close; + } s; + share_mode_entry dummy; /* Needed for alignment. */ + } u; + /* the following two entries are implicit + share_mode_entry modes[num_share_mode_entries]; + char file_name[]; + */ +}; + +/* + * Check if an external smb_share_mode_entry and an internal share_mode entry match. + */ + +static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const share_mode_entry *entry) +{ + return (e_entry->pid == entry->pid && + e_entry->file_id == (uint32_t)entry->share_file_id && + e_entry->open_time.tv_sec == entry->time.tv_sec && + e_entry->open_time.tv_usec == entry->time.tv_usec && + e_entry->share_access == (uint32_t)entry->share_access && + e_entry->access_mask == (uint32_t)entry->access_mask && + e_entry->dev == (uint64_t)entry->dev && + e_entry->ino == (uint64_t)entry->inode); +} + +/* + * Create an internal Samba share_mode entry from an external smb_share_mode_entry. + */ + +static void create_share_mode_entry(share_mode_entry *out, const struct smb_share_mode_entry *in) +{ + memset(out, '\0', sizeof(share_mode_entry)); + + out->pid = in->pid; + out->share_file_id = (unsigned long)in->file_id; + out->time.tv_sec = in->open_time.tv_sec; + out->time.tv_usec = in->open_time.tv_usec; + out->share_access = in->share_access; + out->access_mask = in->access_mask; + out->dev = (SMB_DEV_T)in->dev; + out->inode = (SMB_INO_T)in->ino; +} + +/* + * Return the current share mode list for an open file. + * This uses similar (but simplified) logic to locking/locking.c + */ + +int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, + uint64_t dev, + uint64_t ino, + struct smb_share_mode_entry **pp_list, + unsigned char *p_delete_on_close) +{ + TDB_DATA db_data; + struct smb_share_mode_entry *list = NULL; + int num_share_modes = 0; + struct locking_data *ld = NULL; /* internal samba db state. */ + share_mode_entry *shares = NULL; + size_t i; + + *pp_list = NULL; + *p_delete_on_close = 0; + + db_data = tdb_fetch(db_ctx->smb_tdb, get_locking_key(dev, ino)); + if (!db_data.dptr) { + return 0; + } + + ld = (struct locking_data *)db_data.dptr; + num_share_modes = ld->u.s.num_share_mode_entries; + + if (!num_share_modes) { + free(db_data.dptr); + return 0; + } + + list = SMB_MALLOC_ARRAY(struct smb_share_mode_entry, num_share_modes); + if (!list) { + free(db_data.dptr); + return -1; + } + + memset(list, '\0', num_share_modes * sizeof(struct smb_share_mode_entry)); + + shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); + + for (i = 0; i < num_share_modes; i++) { + share_mode_entry *share = &shares[i]; + struct smb_share_mode_entry *sme = &list[i]; + pid_t pid = share->pid; + + /* Check this process really exists. */ + if (kill(pid, 0) == -1 && (errno == ESRCH)) { + continue; /* No longer exists. */ + } + + /* Copy into the external list. */ + sme->dev = (uint64_t)share->dev; + sme->ino = (uint64_t)share->inode; + sme->share_access = (uint32_t)share->share_access; + sme->access_mask = (uint32_t)share->access_mask; + sme->open_time.tv_sec = share->time.tv_sec; + sme->open_time.tv_usec = share->time.tv_usec; + sme->file_id = (uint32_t)share->share_file_id; + sme->pid = share->pid; + } + + if (i == 0) { + free(db_data.dptr); + free(list); + return 0; + } + + *p_delete_on_close = ld->u.s.delete_on_close; + *pp_list = list; + return i; +} + +/* + * Create an entry in the Samba share mode db. + */ + +int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, + uint64_t dev, + uint64_t ino, + const struct smb_share_mode_entry *new_entry, + const char *filename) /* Must be abolute utf8 path. */ +{ + TDB_DATA db_data; + TDB_DATA locking_key = get_locking_key(dev, ino); + int orig_num_share_modes = 0; + struct locking_data *ld = NULL; /* internal samba db state. */ + share_mode_entry *shares = NULL; + char *new_data_p = NULL; + size_t new_data_size = 0; + + db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); + if (!db_data.dptr) { + /* We must create the entry. */ + db_data.dptr = SMB_MALLOC(sizeof(struct locking_data) + sizeof(share_mode_entry) + strlen(filename) + 1); + if (!db_data.dptr) { + return -1; + } + ld = (struct locking_data *)db_data.dptr; + ld->u.s.num_share_mode_entries = 1; + ld->u.s.delete_on_close = 0; + shares = (share_mode_entry *)db_data.dptr + sizeof(struct locking_data); + create_share_mode_entry(shares, new_entry); + memcpy(db_data.dptr + sizeof(struct locking_data) + sizeof(share_mode_entry), + filename, + strlen(filename) + 1); + + db_data.dsize = sizeof(struct locking_data) + sizeof(share_mode_entry) + strlen(filename) + 1; + if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) { + free(db_data.dptr); + return -1; + } + free(db_data.dptr); + return 0; + } + + /* Entry exists, we must add a new entry. */ + new_data_p = SMB_MALLOC(db_data.dsize + sizeof(share_mode_entry)); + if (!new_data_p) { + free(db_data.dptr); + return -1; + } + + ld = (struct locking_data *)db_data.dptr; + orig_num_share_modes = ld->u.s.num_share_mode_entries; + + /* Copy the original data. */ + memcpy(new_data_p, db_data.dptr, sizeof(struct locking_data) + (orig_num_share_modes*sizeof(share_mode_entry))); + + /* Add in the new share mode */ + shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes*sizeof(share_mode_entry))); + create_share_mode_entry(shares, new_entry); + + ld = (struct locking_data *)new_data_p; + ld->u.s.num_share_mode_entries++; + + /* Append the original filename */ + memcpy(new_data_p + sizeof(struct locking_data) + (ld->u.s.num_share_mode_entries * sizeof(share_mode_entry)), + db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes * sizeof(share_mode_entry)), + db_data.dsize - (sizeof(struct locking_data) + (orig_num_share_modes * sizeof(share_mode_entry)))); + + new_data_size = db_data.dsize + sizeof(share_mode_entry); + + free(db_data.dptr); + + db_data.dptr = new_data_p; + db_data.dsize = new_data_size; + + if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { + free(db_data.dptr); + return -1; + } + free(db_data.dptr); + return 0; +} + +int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, + uint64_t dev, + uint64_t ino, + const struct smb_share_mode_entry *del_entry) +{ + TDB_DATA db_data; + TDB_DATA locking_key = get_locking_key(dev, ino); + int orig_num_share_modes = 0; + struct locking_data *ld = NULL; /* internal samba db state. */ + share_mode_entry *shares = NULL; + char *new_data_p = NULL; + size_t filename_size = 0; + size_t i; + + db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); + if (!db_data.dptr) { + return -1; /* Error - missing entry ! */ + } + + ld = (struct locking_data *)db_data.dptr; + orig_num_share_modes = ld->u.s.num_share_mode_entries; + shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); + + if (orig_num_share_modes == 1) { + /* Only one entry - better be ours... */ + if (!share_mode_entry_equal(del_entry, shares)) { + /* Error ! We can't delete someone else's entry ! */ + free(db_data.dptr); + return -1; + } + /* It's ours - just remove the entire record. */ + free(db_data.dptr); + return tdb_delete(db_ctx->smb_tdb, locking_key); + } + + /* More than one - allocate a new record minus the one we'll delete. */ + new_data_p = SMB_MALLOC(db_data.dsize - sizeof(share_mode_entry)); + if (!new_data_p) { + free(db_data.dptr); + return -1; + } + + /* Copy the header. */ + memcpy(new_data_p, db_data.dptr, sizeof(struct locking_data)); + + for (i = 0; i < orig_num_share_modes; i++) { + share_mode_entry *share = &shares[i]; + pid_t pid = share->pid; + + /* Check this process really exists. */ + if (kill(pid, 0) == -1 && (errno == ESRCH)) { + continue; /* No longer exists. */ + } + + if (share_mode_entry_equal(del_entry, share)) { + continue; /* This is our delete taget. */ + } + + memcpy(new_data_p + sizeof(struct locking_data) + (i*sizeof(share_mode_entry)), + share, sizeof(share_mode_entry) ); + } + + if (i == 0) { + /* None left after pruning. Delete record. */ + free(db_data.dptr); + free(new_data_p); + return tdb_delete(db_ctx->smb_tdb, locking_key); + } + + /* Copy the terminating filename. */ + filename_size = db_data.dsize - ( sizeof(struct locking_data) + (orig_num_share_modes * sizeof(share_mode_entry))); + + memcpy(new_data_p + sizeof(struct locking_data) + (i*sizeof(share_mode_entry)), + db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes * sizeof(share_mode_entry)), + filename_size); + + free(db_data.dptr); + + db_data.dptr = new_data_p; + + /* Re-save smaller record. */ + ld = (struct locking_data *)db_data.dptr; + ld->u.s.num_share_mode_entries = i; + + db_data.dsize = sizeof(struct locking_data) + (i*sizeof(share_mode_entry)) + filename_size; + + if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { + free(db_data.dptr); + return -1; + } + free(db_data.dptr); + return 0; +} + +int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, + uint64_t dev, + uint64_t ino, + const struct smb_share_mode_entry *set_entry, + const struct smb_share_mode_entry *new_entry) +{ + TDB_DATA db_data; + TDB_DATA locking_key = get_locking_key(dev, ino); + int num_share_modes = 0; + struct locking_data *ld = NULL; /* internal samba db state. */ + share_mode_entry *shares = NULL; + size_t i; + int found_entry = 0; + + db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); + if (!db_data.dptr) { + return -1; /* Error - missing entry ! */ + } + + ld = (struct locking_data *)db_data.dptr; + num_share_modes = ld->u.s.num_share_mode_entries; + shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); + + for (i = 0; i < num_share_modes; i++) { + share_mode_entry *share = &shares[i]; + pid_t pid = share->pid; + + /* Check this process really exists. */ + if (kill(pid, 0) == -1 && (errno == ESRCH)) { + continue; /* No longer exists. */ + } + + if (share_mode_entry_equal(set_entry, share)) { + create_share_mode_entry(share, new_entry); + break; + } + } + + if (!found_entry) { + free(db_data.dptr); + return -1; + } + + /* Save modified data. */ + if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { + free(db_data.dptr); + return -1; + } + free(db_data.dptr); + return 0; +} -- cgit From dcf4bc5e7fd8af2b9e5d8f53b3d65004cb4974ed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Sep 2005 16:52:25 +0000 Subject: r10054: Actually use the given db path (:-) Jeremy. (This used to be commit ac7cf320dfa2fd980188e72c9b8baa726c5cdaa1) --- source3/libsmb/smb_share_modes.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 0ba68aed06..180b5b4bfd 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -36,7 +36,11 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path) memset(smb_db, '\0', sizeof(struct smbdb_ctx)); - smb_db->smb_tdb = tdb_open_log(lock_path("locking.tdb"), + if (!db_path) { + db_path = lock_path("locking.tdb"); + } + + smb_db->smb_tdb = tdb_open_log(db_path, 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0644); -- cgit From 1ff0de8b6d3de21325d92e7ebffbc74602a13c49 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Sep 2005 21:49:49 +0000 Subject: r10135: Remove external dependencies for libsmbsharemodes.so Jeremy. (This used to be commit 2521ae826f1a0344c882090832646d56f248488f) --- source3/libsmb/smb_share_modes.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 180b5b4bfd..1c95fe1a30 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -22,13 +22,18 @@ #include "includes.h" #include "smb_share_modes.h" +/* Remove the paranoid malloc checker. */ +#ifdef malloc +#undef malloc +#endif + /* * open/close sharemode database. */ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path) { - struct smbdb_ctx *smb_db = SMB_MALLOC_P(struct smbdb_ctx); + struct smbdb_ctx *smb_db = (struct smbdb_ctx *)malloc(sizeof(struct smbdb_ctx)); if (!smb_db) { return NULL; @@ -36,11 +41,7 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path) memset(smb_db, '\0', sizeof(struct smbdb_ctx)); - if (!db_path) { - db_path = lock_path("locking.tdb"); - } - - smb_db->smb_tdb = tdb_open_log(db_path, + smb_db->smb_tdb = tdb_open(db_path, 0, TDB_DEFAULT|TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0644); @@ -184,7 +185,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, return 0; } - list = SMB_MALLOC_ARRAY(struct smb_share_mode_entry, num_share_modes); + list = (struct smb_share_mode_entry *)malloc(sizeof(struct smb_share_mode_entry)*num_share_modes); if (!list) { free(db_data.dptr); return -1; @@ -247,7 +248,7 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { /* We must create the entry. */ - db_data.dptr = SMB_MALLOC(sizeof(struct locking_data) + sizeof(share_mode_entry) + strlen(filename) + 1); + db_data.dptr = malloc(sizeof(struct locking_data) + sizeof(share_mode_entry) + strlen(filename) + 1); if (!db_data.dptr) { return -1; } @@ -270,7 +271,7 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, } /* Entry exists, we must add a new entry. */ - new_data_p = SMB_MALLOC(db_data.dsize + sizeof(share_mode_entry)); + new_data_p = malloc(db_data.dsize + sizeof(share_mode_entry)); if (!new_data_p) { free(db_data.dptr); return -1; @@ -345,7 +346,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* More than one - allocate a new record minus the one we'll delete. */ - new_data_p = SMB_MALLOC(db_data.dsize - sizeof(share_mode_entry)); + new_data_p = malloc(db_data.dsize - sizeof(share_mode_entry)); if (!new_data_p) { free(db_data.dptr); return -1; -- cgit From b03137d568f598eb0b506c6c4871a1311bc682e7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Sep 2005 05:16:54 +0000 Subject: r10150: Fix from Steve Williams to make the args consistent (uint64_t). Jeremy. (This used to be commit 08de7261720f7bfd72396ea7c9777dc0734c4593) --- source3/libsmb/smb_share_modes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 1c95fe1a30..9e7f196b82 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -94,8 +94,8 @@ int smb_lock_share_mode_entry(struct smbdb_ctx *db_ctx, } int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, - dev_t dev, - ino_t ino) + uint64_t dev, + uint64_t ino) { return tdb_chainunlock(db_ctx->smb_tdb, get_locking_key(dev, ino)); } -- cgit From dade4d9e95e13e187aa59475e82a250a124063fc Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 12 Sep 2005 18:12:53 +0000 Subject: r10176: adding smbctool from Kalim's SoC project; requires make bin/smbctool (This used to be commit 79fcc3bb7b955da5eb1b2af475aa6ef7694a7157) --- source3/libsmb/libsmbclient.c | 289 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 253 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ce47277c26..fe8f878aa5 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -903,6 +903,8 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m { fstring server, share, user, password, workgroup; pstring path; + pstring targetpath; + struct cli_state *targetcli; SMBCSRV *srv = NULL; SMBCFILE *file = NULL; int fd; @@ -966,12 +968,27 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m ZERO_STRUCTP(file); - if ((fd = cli_open(&srv->cli, path, flags, DENY_NONE)) < 0) { + /*d_printf(">>>open: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return NULL; + } + /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ + + if ( targetcli->dfsroot ) + { + pstring temppath; + pstrcpy(temppath, targetpath); + cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath); + } + + if ((fd = cli_open(targetcli, targetpath, flags, DENY_NONE)) < 0) { /* Handle the error ... */ SAFE_FREE(file); - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, targetcli); return NULL; } @@ -1064,6 +1081,9 @@ static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) { int ret; + fstring server, share, user, password; + pstring path, targetpath; + struct cli_state *targetcli; /* * offset: @@ -1102,11 +1122,31 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t } - ret = cli_read(&file->srv->cli, file->cli_fd, buf, offset, count); + /*d_printf(">>>read: parsing %s\n", file->fname);*/ + if (smbc_parse_path(context, file->fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } + + /*d_printf(">>>read: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + ret = cli_read(targetcli, file->cli_fd, buf, offset, count); if (ret < 0) { - errno = smbc_errno(context, &file->srv->cli); + errno = smbc_errno(context, targetcli); return -1; } @@ -1127,6 +1167,9 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ { int ret; off_t offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ + fstring server, share, user, password; + pstring path, targetpath; + struct cli_state *targetcli; if (!context || !context->internal || !context->internal->_initialized) { @@ -1152,11 +1195,32 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ } - ret = cli_write(&file->srv->cli, file->cli_fd, 0, buf, offset, count); + /*d_printf(">>>write: parsing %s\n", file->fname);*/ + if (smbc_parse_path(context, file->fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } + + /*d_printf(">>>write: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return -1; + } + /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ + + + ret = cli_write(targetcli, file->cli_fd, 0, buf, offset, count); if (ret <= 0) { - errno = smbc_errno(context, &file->srv->cli); + errno = smbc_errno(context, targetcli); return -1; } @@ -1173,6 +1237,9 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { SMBCSRV *srv; + fstring server, share, user, password; + pstring path, targetpath; + struct cli_state *targetcli; if (!context || !context->internal || !context->internal->_initialized) { @@ -1196,13 +1263,33 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) } - if (!cli_close(&file->srv->cli, file->cli_fd)) { + /*d_printf(">>>close: parsing %s\n", file->fname);*/ + if (smbc_parse_path(context, file->fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } + + /*d_printf(">>>close: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return -1; + } + /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ + + if (!cli_close(targetcli, file->cli_fd)) { DEBUG(3, ("cli_close failed on %s. purging server.\n", file->fname)); /* Deallocate slot and remove the server * from the server cache if unused */ - errno = smbc_errno(context, &file->srv->cli); + errno = smbc_errno(context, targetcli); srv = file->srv; DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); @@ -1229,7 +1316,9 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, time_t *c_time, time_t *a_time, time_t *m_time, SMB_INO_T *ino) { - + pstring fixedpath; + pstring targetpath; + struct cli_state *targetcli; if (!context || !context->internal || !context->internal->_initialized) { @@ -1238,19 +1327,41 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, } + /* path fixup for . and .. */ + if (strequal(path, ".") || strequal(path, "..")) + pstrcpy(fixedpath, "\\"); + else + { + pstrcpy(fixedpath, path); + trim_string(fixedpath, NULL, "\\.."); + trim_string(fixedpath, NULL, "\\."); + } DEBUG(4,("smbc_getatr: sending qpathinfo\n")); + if (!cli_resolve_path( "", &srv->cli, fixedpath, &targetcli, targetpath)) + { + d_printf("Couldn't resolve %s\n", path); + return False; + } + + if ( targetcli->dfsroot ) + { + pstring temppath; + pstrcpy(temppath, targetpath); + cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath); + } + if (!srv->no_pathinfo2 && - cli_qpathinfo2(&srv->cli, path, c_time, a_time, m_time, NULL, + cli_qpathinfo2(targetcli, targetpath, c_time, a_time, m_time, NULL, size, mode, ino)) return True; /* if this is NT then don't bother with the getatr */ - if (srv->cli.capabilities & CAP_NT_SMBS) { + if (targetcli->capabilities & CAP_NT_SMBS) { errno = EPERM; return False; } - if (cli_getatr(&srv->cli, path, mode, size, m_time)) { + if (cli_getatr(targetcli, targetpath, mode, size, m_time)) { if (m_time != NULL) { if (a_time != NULL) *a_time = *m_time; if (c_time != NULL) *c_time = *m_time; @@ -1406,7 +1517,8 @@ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; - pstring path; + pstring path, targetpath; + struct cli_state *targetcli; SMBCSRV *srv = NULL; if (!context || !context->internal || @@ -1447,9 +1559,17 @@ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, } - if (!cli_unlink(&srv->cli, path)) { + /*d_printf(">>>unlink: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return -1; + } + /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ - errno = smbc_errno(context, &srv->cli); + if (!cli_unlink(targetcli, targetpath)) { + + errno = smbc_errno(context, targetcli); if (errno == EACCES) { /* Check if the file is a directory */ @@ -1464,7 +1584,7 @@ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, /* Hmmm, bad error ... What? */ - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, targetcli); return -1; } @@ -1494,7 +1614,8 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, SMBCCTX *ncontext, const char *nname) { fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup; - pstring path1, path2; + pstring path1, path2, targetpath1, targetpath2; + struct cli_state *targetcli1, *targetcli2; SMBCSRV *srv = NULL; if (!ocontext || !ncontext || @@ -1555,12 +1676,35 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, } - if (!cli_rename(&srv->cli, path1, path2)) { - int eno = smbc_errno(ocontext, &srv->cli); + /*d_printf(">>>rename: resolving %s\n", path1);*/ + if (!cli_resolve_path( "", &srv->cli, path1, &targetcli1, targetpath1)) + { + d_printf("Could not resolve %s\n", path1); + return -1; + } + /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ + /*d_printf(">>>rename: resolving %s\n", path2);*/ + if (!cli_resolve_path( "", &srv->cli, path2, &targetcli2, targetpath2)) + { + d_printf("Could not resolve %s\n", path2); + return -1; + } + /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ + + if (strcmp(targetcli1->desthost, targetcli2->desthost) || strcmp(targetcli1->share, targetcli2->share)) + { + /* can't rename across file systems */ + + errno = EXDEV; + return -1; + } + + if (!cli_rename(targetcli1, targetpath1, targetpath2)) { + int eno = smbc_errno(ocontext, targetcli1); if (eno != EEXIST || - !cli_unlink(&srv->cli, path2) || - !cli_rename(&srv->cli, path1, path2)) { + !cli_unlink(targetcli1, targetpath2) || + !cli_rename(targetcli1, targetpath1, targetpath2)) { errno = eno; return -1; @@ -1579,6 +1723,9 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence) { SMB_OFF_T size; + fstring server, share, user, password; + pstring path, targetpath; + struct cli_state *targetcli; if (!context || !context->internal || !context->internal->_initialized) { @@ -1612,11 +1759,31 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int break; case SEEK_END: - if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, NULL, &size, NULL, NULL, + /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ + if (smbc_parse_path(context, file->fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } + + /*d_printf(">>>lseek: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return -1; + } + /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ + + if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL, NULL, NULL, NULL)) { SMB_BIG_UINT b_size = size; - if (!cli_getattrE(&file->srv->cli, file->cli_fd, NULL, &b_size, NULL, NULL, + if (!cli_getattrE(targetcli, file->cli_fd, NULL, &b_size, NULL, NULL, NULL)) { errno = EINVAL; @@ -1787,6 +1954,9 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) time_t c_time, a_time, m_time; SMB_OFF_T size; uint16 mode; + fstring server, share, user, password; + pstring path, targetpath; + struct cli_state *targetcli; SMB_INO_T ino = 0; if (!context || !context->internal || @@ -1810,9 +1980,29 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) } - if (!cli_qfileinfo(&file->srv->cli, file->cli_fd, + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ + if (smbc_parse_path(context, file->fname, + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; + return -1; + } + + /*d_printf(">>>fstat: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) { - if (!cli_getattrE(&file->srv->cli, file->cli_fd, + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time)) { errno = EINVAL; @@ -2303,6 +2493,8 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } else { /* The server and share are specified ... work from there ... */ + pstring targetpath; + struct cli_state *targetcli; /* Well, we connect to the server and list the directory */ @@ -2327,14 +2519,20 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) p = path + strlen(path); pstrcat(path, "\\*"); - if (cli_list(&srv->cli, path, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, + if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return NULL; + } + + if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, (void *)dir) < 0) { if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); } - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, targetcli); if (errno == EINVAL) { /* @@ -2613,7 +2811,8 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) { SMBCSRV *srv; fstring server, share, user, password, workgroup; - pstring path; + pstring path, targetpath; + struct cli_state *targetcli; if (!context || !context->internal || !context->internal->_initialized) { @@ -2655,9 +2854,17 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) } - if (!cli_mkdir(&srv->cli, path)) { + /*d_printf(">>>mkdir: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return -1; + } + /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ + + if (!cli_mkdir(targetcli, targetpath)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, targetcli); return -1; } @@ -2688,7 +2895,8 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) { SMBCSRV *srv; fstring server, share, user, password, workgroup; - pstring path; + pstring path, targetpath; + struct cli_state *targetcli; if (!context || !context->internal || !context->internal->_initialized) { @@ -2752,9 +2960,18 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) } else { */ - if (!cli_rmdir(&srv->cli, path)) { + /*d_printf(">>>rmdir: resolving %s\n", path);*/ + if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + { + d_printf("Could not resolve %s\n", path); + return -1; + } + /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ + - errno = smbc_errno(context, &srv->cli); + if (!cli_rmdir(targetcli, targetpath)) { + + errno = smbc_errno(context, targetcli); if (errno == EACCES) { /* Check if the dir empty or not */ @@ -2762,16 +2979,16 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) smbc_rmdir_dirempty = True; /* Make this so ... */ - pstrcpy(lpath, path); + pstrcpy(lpath, targetpath); pstrcat(lpath, "\\*"); - if (cli_list(&srv->cli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn, + if (cli_list(targetcli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn, NULL) < 0) { /* Fix errno to ignore latest error ... */ DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n", - smbc_errno(context, &srv->cli))); + smbc_errno(context, targetcli))); errno = EACCES; } -- cgit From c2f9fdcb46c81415aefd7852ad1bd45e1762c90d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Sep 2005 16:54:59 +0000 Subject: r10204: I love valgrind :-). Found stupid missing parantheses :-). Jeremy. (This used to be commit b406a202128c1ba9800784ab8c571584b37c746b) --- source3/libsmb/smb_share_modes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 9e7f196b82..e0c2387793 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -255,7 +255,7 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; ld->u.s.num_share_mode_entries = 1; ld->u.s.delete_on_close = 0; - shares = (share_mode_entry *)db_data.dptr + sizeof(struct locking_data); + shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); create_share_mode_entry(shares, new_entry); memcpy(db_data.dptr + sizeof(struct locking_data) + sizeof(share_mode_entry), filename, -- cgit From 2d878a4b6d66663938e3540b9726ce158ec9a253 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 13 Sep 2005 21:21:43 +0000 Subject: r10210: Fix memleak. Guenther (This used to be commit 10358d16d7946f6b0c989db8bc26f8840144389b) --- source3/libsmb/clikrb5.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e70c2b8bec..1741c1db3c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -119,8 +119,10 @@ DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); return ret; } - return krb5_string_to_key_salt(context, enctype, password->data, - salt, key); + + ret = krb5_string_to_key_salt(context, enctype, password->data, salt, key); + krb5_free_salt(context, salt); + return ret; } #else #error UNKNOWN_CREATE_KEY_FUNCTIONS -- cgit From 6a8ce7487b9282a6a6025c7b18bbe3bc1fc75178 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Sep 2005 22:23:59 +0000 Subject: r10215: Fix several memory corruption bugs now we're testing this. Jeremy. (This used to be commit 3d1207aaf66bafd84935b21dbe1a0fd8efeb661d) --- source3/libsmb/smb_share_modes.c | 70 +++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 33 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index e0c2387793..ddc4e13ff6 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -62,21 +62,14 @@ int smb_share_mode_db_close(struct smbdb_ctx *db_ctx) return ret; } -/* Create locking key. */ - -struct samba_locking_key { - SMB_DEV_T dev; - SMB_INO_T ino; -}; - static TDB_DATA get_locking_key(uint64_t dev, uint64_t ino) { - static struct samba_locking_key lk; + static struct locking_key lk; TDB_DATA ld; - memset(&lk, '\0', sizeof(struct samba_locking_key)); + memset(&lk, '\0', sizeof(struct locking_key)); lk.dev = (SMB_DEV_T)dev; - lk.ino = (SMB_INO_T)ino; + lk.inode = (SMB_INO_T)ino; ld.dptr = (char *)&lk; ld.dsize = sizeof(lk); return ld; @@ -168,6 +161,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, struct locking_data *ld = NULL; /* internal samba db state. */ share_mode_entry *shares = NULL; size_t i; + int list_num; *pp_list = NULL; *p_delete_on_close = 0; @@ -193,11 +187,12 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, memset(list, '\0', num_share_modes * sizeof(struct smb_share_mode_entry)); - shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); + shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry)); + list_num = 0; for (i = 0; i < num_share_modes; i++) { share_mode_entry *share = &shares[i]; - struct smb_share_mode_entry *sme = &list[i]; + struct smb_share_mode_entry *sme = &list[list_num]; pid_t pid = share->pid; /* Check this process really exists. */ @@ -214,9 +209,10 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, sme->open_time.tv_usec = share->time.tv_usec; sme->file_id = (uint32_t)share->share_file_id; sme->pid = share->pid; + list_num++; } - if (i == 0) { + if (list_num == 0) { free(db_data.dptr); free(list); return 0; @@ -224,7 +220,8 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, *p_delete_on_close = ld->u.s.delete_on_close; *pp_list = list; - return i; + free(db_data.dptr); + return list_num; } /* @@ -248,20 +245,20 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { /* We must create the entry. */ - db_data.dptr = malloc(sizeof(struct locking_data) + sizeof(share_mode_entry) + strlen(filename) + 1); + db_data.dptr = malloc((2*sizeof(share_mode_entry)) + strlen(filename) + 1); if (!db_data.dptr) { return -1; } ld = (struct locking_data *)db_data.dptr; ld->u.s.num_share_mode_entries = 1; ld->u.s.delete_on_close = 0; - shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); + shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry)); create_share_mode_entry(shares, new_entry); - memcpy(db_data.dptr + sizeof(struct locking_data) + sizeof(share_mode_entry), + memcpy(db_data.dptr + 2*sizeof(share_mode_entry), filename, strlen(filename) + 1); - db_data.dsize = sizeof(struct locking_data) + sizeof(share_mode_entry) + strlen(filename) + 1; + db_data.dsize = 2*sizeof(share_mode_entry) + strlen(filename) + 1; if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) { free(db_data.dptr); return -1; @@ -281,19 +278,21 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, orig_num_share_modes = ld->u.s.num_share_mode_entries; /* Copy the original data. */ - memcpy(new_data_p, db_data.dptr, sizeof(struct locking_data) + (orig_num_share_modes*sizeof(share_mode_entry))); + memcpy(new_data_p, db_data.dptr, (orig_num_share_modes+1)*sizeof(share_mode_entry)); /* Add in the new share mode */ - shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes*sizeof(share_mode_entry))); + shares = (share_mode_entry *)(new_data_p + + ((orig_num_share_modes+1)*sizeof(share_mode_entry))); + create_share_mode_entry(shares, new_entry); ld = (struct locking_data *)new_data_p; ld->u.s.num_share_mode_entries++; /* Append the original filename */ - memcpy(new_data_p + sizeof(struct locking_data) + (ld->u.s.num_share_mode_entries * sizeof(share_mode_entry)), - db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes * sizeof(share_mode_entry)), - db_data.dsize - (sizeof(struct locking_data) + (orig_num_share_modes * sizeof(share_mode_entry)))); + memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(share_mode_entry)), + db_data.dptr + ((orig_num_share_modes+1)*sizeof(share_mode_entry)), + db_data.dsize - ((orig_num_share_modes+1) * sizeof(share_mode_entry))); new_data_size = db_data.dsize + sizeof(share_mode_entry); @@ -322,7 +321,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, share_mode_entry *shares = NULL; char *new_data_p = NULL; size_t filename_size = 0; - size_t i; + size_t i, num_share_modes; + const char *fname_ptr = NULL; db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { @@ -331,7 +331,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; orig_num_share_modes = ld->u.s.num_share_mode_entries; - shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); + shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry)); if (orig_num_share_modes == 1) { /* Only one entry - better be ours... */ @@ -353,8 +353,9 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* Copy the header. */ - memcpy(new_data_p, db_data.dptr, sizeof(struct locking_data)); + memcpy(new_data_p, db_data.dptr, sizeof(share_mode_entry)); + num_share_modes = 0; for (i = 0; i < orig_num_share_modes; i++) { share_mode_entry *share = &shares[i]; pid_t pid = share->pid; @@ -368,11 +369,13 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, continue; /* This is our delete taget. */ } - memcpy(new_data_p + sizeof(struct locking_data) + (i*sizeof(share_mode_entry)), + memcpy(new_data_p + ((num_share_modes+1)*sizeof(share_mode_entry)), share, sizeof(share_mode_entry) ); + + num_share_modes++; } - if (i == 0) { + if (num_share_modes == 0) { /* None left after pruning. Delete record. */ free(db_data.dptr); free(new_data_p); @@ -380,10 +383,11 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* Copy the terminating filename. */ - filename_size = db_data.dsize - ( sizeof(struct locking_data) + (orig_num_share_modes * sizeof(share_mode_entry))); + fname_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(share_mode_entry)); + filename_size = db_data.dsize - (fname_ptr - db_data.dptr); - memcpy(new_data_p + sizeof(struct locking_data) + (i*sizeof(share_mode_entry)), - db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes * sizeof(share_mode_entry)), + memcpy(new_data_p + ((num_share_modes+1)*sizeof(share_mode_entry)), + fname_ptr, filename_size); free(db_data.dptr); @@ -392,9 +396,9 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, /* Re-save smaller record. */ ld = (struct locking_data *)db_data.dptr; - ld->u.s.num_share_mode_entries = i; + ld->u.s.num_share_mode_entries = num_share_modes; - db_data.dsize = sizeof(struct locking_data) + (i*sizeof(share_mode_entry)) + filename_size; + db_data.dsize = ((num_share_modes+1)*sizeof(share_mode_entry)) + filename_size; if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { free(db_data.dptr); -- cgit From f94d9826465b391faa4a4697e03459104065c115 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Sep 2005 23:11:23 +0000 Subject: r10217: Remember to exit correctly when we find a matching entry to change. Jeremy. (This used to be commit 142c84eb31a4f2577d5f4bb0f541440d84eb607f) --- source3/libsmb/smb_share_modes.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index ddc4e13ff6..87a386307c 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -429,7 +429,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; num_share_modes = ld->u.s.num_share_mode_entries; - shares = (share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); + shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry)); for (i = 0; i < num_share_modes; i++) { share_mode_entry *share = &shares[i]; @@ -442,6 +442,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, if (share_mode_entry_equal(set_entry, share)) { create_share_mode_entry(share, new_entry); + found_entry = 1; break; } } -- cgit From c2e5ce15017270cfc62ea4fed23976115305b0d5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Sep 2005 16:20:48 +0000 Subject: r10269: Server-side fix for creds change - revert jcmd's change. Jeremy. (This used to be commit e1c9813d63a441037bc71622a29acda099d72f71) --- source3/libsmb/credentials.c | 32 ++------------------------------ 1 file changed, 2 insertions(+), 30 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 322b25ee43..0d521bae8a 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -208,36 +208,8 @@ BOOL deal_with_creds(uchar sess_key[8], DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data))); - /* Bug #2953 - don't store new seed in client credentials - here, because we need to make sure we're moving forward first - */ + /* store new seed in client credentials */ + SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); return True; } - -/* - stores new seed in client credentials - jmcd - Bug #2953 - moved this functionality out of deal_with_creds, because we're - not supposed to move to the next step in the chain if a nonexistent user tries to logon -*/ -void reseed_client_creds(DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_clnt_cred) -{ - UTIME new_clnt_time; - uint32 new_cred; - - /* increment client time by one second */ - new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1; - - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->challenge.data, 0); - new_cred += new_clnt_time.time; - - DEBUG(5,("reseed_client_creds: new_cred[0]=%x\n", new_cred)); - DEBUG(5,("reseed_client_creds: new_clnt_time=%x\n", - new_clnt_time.time)); - DEBUG(5,("reseed_client_creds: clnt_cred=%s\n", - credstr(sto_clnt_cred->challenge.data))); - - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); -} -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/libsmb/cliconnect.c | 27 +-- source3/libsmb/clidgram.c | 2 +- source3/libsmb/clientgen.c | 83 ++++--- source3/libsmb/clierror.c | 17 ++ source3/libsmb/clikrb5.c | 451 ++++++++++++++++++++++++++++++++++++++- source3/libsmb/clireadwrite.c | 12 +- source3/libsmb/clispnego.c | 5 +- source3/libsmb/clitrans.c | 19 +- source3/libsmb/credentials.c | 295 +++++++++++++++---------- source3/libsmb/errormap.c | 4 +- source3/libsmb/libsmb_compat.c | 2 +- source3/libsmb/libsmbclient.c | 89 +++++--- source3/libsmb/ntlmssp.c | 84 ++++++-- source3/libsmb/ntlmssp_parse.c | 6 +- source3/libsmb/ntlmssp_sign.c | 436 ++++++++++++++++++++----------------- source3/libsmb/passchange.c | 66 +++--- source3/libsmb/pwd_cache.c | 1 - source3/libsmb/smb_share_modes.c | 93 ++++---- source3/libsmb/smbdes.c | 78 ++----- source3/libsmb/smbencrypt.c | 30 +-- source3/libsmb/smberr.c | 1 + source3/libsmb/spnego.c | 4 +- source3/libsmb/trusts_util.c | 47 ++-- 23 files changed, 1216 insertions(+), 636 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3d8e36c493..7ecc769517 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -532,7 +532,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5); + rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0); if (rc) { DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc))); @@ -600,7 +600,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use nt_status = ntlmssp_update(ntlmssp_state, blob_in, &blob_out); data_blob_free(&blob_in); - if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(nt_status)) { if (turn == 1) { /* and wrap it in a SPNEGO wrapper */ msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out); @@ -1337,25 +1337,6 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) return True; } -/**************************************************************************** - Initialise client credentials for authenticated pipe access. -****************************************************************************/ - -void init_creds(struct ntuser_creds *creds, const char* username, - const char* domain, const char* password) -{ - ZERO_STRUCTP(creds); - - pwd_set_cleartext(&creds->pwd, password); - - fstrcpy(creds->user_name, username); - fstrcpy(creds->domain, domain); - - if (!*username) { - creds->pwd.null_pwd = True; - } -} - /** establishes a connection to after the negprot. @param output_cli A fully initialised cli structure, non-null only on success @@ -1474,7 +1455,6 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, int signing_state, BOOL *retry) { - struct ntuser_creds creds; NTSTATUS nt_status; struct cli_state *cli = NULL; @@ -1513,8 +1493,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, } } - init_creds(&creds, user, domain, password); - cli_init_creds(cli, &creds); + cli_init_creds(cli, user, domain, password); *output_cli = cli; return NT_STATUS_OK; diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 819616105e..dfb613238f 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -101,7 +101,7 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot, DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip))); - return message_send_pid(nmbd_pid, MSG_SEND_PACKET, &p, sizeof(p), + return message_send_pid(pid_to_procid(nmbd_pid), MSG_SEND_PACKET, &p, sizeof(p), False); } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f1794ab5dc..bc64cc919b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -221,15 +221,16 @@ void cli_setup_bcc(struct cli_state *cli, void *p) Initialise credentials of a client structure. ****************************************************************************/ -void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr) +void cli_init_creds(struct cli_state *cli, const char *username, const char *domain, const char *password) { - /* copy_nt_creds(&cli->usr, usr); */ - fstrcpy(cli->domain , usr->domain); - fstrcpy(cli->user_name, usr->user_name); - memcpy(&cli->pwd, &usr->pwd, sizeof(usr->pwd)); + fstrcpy(cli->domain, domain); + fstrcpy(cli->user_name, username); + pwd_set_cleartext(&cli->pwd, password); + if (!*username) { + cli->pwd.null_pwd = True; + } - DEBUG(10,("cli_init_creds: user %s domain %s\n", - cli->user_name, cli->domain)); + DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain)); } /**************************************************************************** @@ -260,7 +261,6 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) struct cli_state *cli_initialise(struct cli_state *cli) { BOOL alloced_cli = False; - int i; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -332,16 +332,9 @@ struct cli_state *cli_initialise(struct cli_state *cli) /* initialise signing */ cli_null_set_signing(cli); - for (i=0; ipipes[i].fnum = 0; - - cli->netlogon_pipe.fnum = 0; - cli->initialised = 1; cli->allocated = alloced_cli; - cli->pipe_idx = -1; - return cli; /* Clean up after malloc() error */ @@ -358,34 +351,42 @@ struct cli_state *cli_initialise(struct cli_state *cli) } /**************************************************************************** -close the session -****************************************************************************/ + External interface. + Close an open named pipe over SMB. Free any authentication data. + ****************************************************************************/ -void cli_nt_session_close(struct cli_state *cli) +void cli_rpc_pipe_close(struct rpc_pipe_client *cli) { - int i; - - for (i=0; ipipes[i].pipe_auth_flags & AUTH_PIPE_NTLMSSP) { - ntlmssp_end(&cli->pipes[i].ntlmssp_pipe_state); - } + if (!cli_close(cli->cli, cli->fnum)) { + DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s " + "to machine %s. Error was %s\n", + cli->pipe_name, + cli->cli->desthost, + cli_errstr(cli->cli))); + } - if (cli->pipes[i].fnum != 0) - cli_close(cli, cli->pipes[i].fnum); - cli->pipes[i].fnum = 0; + if (cli->auth.cli_auth_data_free_func) { + (*cli->auth.cli_auth_data_free_func)(&cli->auth); } - cli->pipe_idx = -1; + + DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", + cli->pipe_name, cli->cli->desthost )); + + DLIST_REMOVE(cli->cli->pipe_list, cli); + talloc_destroy(cli->mem_ctx); } /**************************************************************************** -close the NETLOGON session holding the session key for NETSEC + Close all pipes open on this session. ****************************************************************************/ -void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) +void cli_nt_pipes_close(struct cli_state *cli) { - if (cli->netlogon_pipe.fnum != 0) { - cli_close(cli, cli->netlogon_pipe.fnum); - cli->netlogon_pipe.fnum = 0; + struct rpc_pipe_client *cp, *next; + + for (cp = cli->pipe_list; cp; cp = next) { + next = cp->next; + cli_rpc_pipe_close(cp); } } @@ -395,8 +396,7 @@ void cli_nt_netlogon_netsec_session_close(struct cli_state *cli) void cli_close_connection(struct cli_state *cli) { - cli_nt_session_close(cli); - cli_nt_netlogon_netsec_session_close(cli); + cli_nt_pipes_close(cli); /* * tell our peer to free his resources. Wihtout this, when an @@ -410,8 +410,9 @@ void cli_close_connection(struct cli_state *cli) * the only user for this so far is smbmount which passes opened connection * down to kernel's smbfs module. */ - if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) + if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) { cli_tdis(cli); + } SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); @@ -420,19 +421,16 @@ void cli_close_connection(struct cli_state *cli) data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); - if (cli->pipes[cli->pipe_idx].pipe_auth_flags & AUTH_PIPE_NTLMSSP) - ntlmssp_end(&cli->pipes[cli->pipe_idx].ntlmssp_pipe_state); - if (cli->mem_ctx) { talloc_destroy(cli->mem_ctx); cli->mem_ctx = NULL; } - if (cli->fd != -1) + if (cli->fd != -1) { close(cli->fd); + } cli->fd = -1; cli->smb_rw_error = 0; - } /**************************************************************************** @@ -444,8 +442,9 @@ void cli_shutdown(struct cli_state *cli) BOOL allocated = cli->allocated; cli_close_connection(cli); ZERO_STRUCTP(cli); - if (allocated) + if (allocated) { free(cli); + } } /**************************************************************************** diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 355a2adf34..6938702e1e 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -404,3 +404,20 @@ BOOL cli_is_dos_error(struct cli_state *cli) return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES); } + +/* Return the last error always as an NTSTATUS. */ + +NTSTATUS cli_get_nt_error(struct cli_state *cli) +{ + if (cli_is_nt_error(cli)) { + return cli_nt_error(cli); + } else if (cli_is_dos_error(cli)) { + uint32 ecode; + uint8 eclass; + cli_dos_error(cli, &eclass, &ecode); + return dos_to_ntstatus(eclass, ecode); + } else { + /* Something went wrong, we don't know what. */ + return NT_STATUS_UNSUCCESSFUL; + } +} diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 1741c1db3c..e3ad5f17cb 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -3,6 +3,8 @@ simple kerberos5 routines for active directory Copyright (C) Andrew Tridgell 2001 Copyright (C) Luke Howard 2002-2003 + Copyright (C) Andrew Bartlett 2005 + Copyright (C) Guenther Deschner 2005 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -186,17 +188,107 @@ } #endif - void get_auth_data_from_tkt(DATA_BLOB *auth_data, krb5_ticket *tkt) +BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data) { + DATA_BLOB pac_contents; + ASN1_DATA data; + int data_type; + + if (!auth_data->length) { + return False; + } + + asn1_load(&data, *auth_data); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_Integer(&data, &data_type); + + if (data_type != KRB5_AUTHDATA_WIN2K_PAC ) { + DEBUG(10,("authorization data is not a Windows PAC (type: %d)\n", data_type)); + asn1_free(&data); + return False; + } + + asn1_end_tag(&data); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_read_OctetString(&data, &pac_contents); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_free(&data); + + *unwrapped_pac_data = data_blob_talloc(mem_ctx, pac_contents.data, pac_contents.length); + + data_blob_free(&pac_contents); + + return True; +} + + BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt) +{ + DATA_BLOB auth_data_wrapped; + BOOL got_auth_data_pac = False; + int i; + #if defined(HAVE_KRB5_TKT_ENC_PART2) - if (tkt->enc_part2 && tkt->enc_part2->authorization_data && tkt->enc_part2->authorization_data[0] && tkt->enc_part2->authorization_data[0]->length) - *auth_data = data_blob(tkt->enc_part2->authorization_data[0]->contents, - tkt->enc_part2->authorization_data[0]->length); + if (tkt->enc_part2 && tkt->enc_part2->authorization_data && + tkt->enc_part2->authorization_data[0] && + tkt->enc_part2->authorization_data[0]->length) + { + for (i = 0; tkt->enc_part2->authorization_data[i] != NULL; i++) { + + if (tkt->enc_part2->authorization_data[i]->ad_type != + KRB5_AUTHDATA_IF_RELEVANT) { + DEBUG(10,("get_auth_data_from_tkt: ad_type is %d\n", + tkt->enc_part2->authorization_data[i]->ad_type)); + continue; + } + + auth_data_wrapped = data_blob(tkt->enc_part2->authorization_data[i]->contents, + tkt->enc_part2->authorization_data[i]->length); + + /* check if it is a PAC */ + got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data); + data_blob_free(&auth_data_wrapped); + + if (!got_auth_data_pac) { + continue; + } + } + + return got_auth_data_pac; + } + #else - if (tkt->ticket.authorization_data && tkt->ticket.authorization_data->len) - *auth_data = data_blob(tkt->ticket.authorization_data->val->ad_data.data, - tkt->ticket.authorization_data->val->ad_data.length); + if (tkt->ticket.authorization_data && + tkt->ticket.authorization_data->len) + { + for (i = 0; i < tkt->ticket.authorization_data->len; i++) { + + if (tkt->ticket.authorization_data->val[i].ad_type != + KRB5_AUTHDATA_IF_RELEVANT) { + DEBUG(10,("get_auth_data_from_tkt: ad_type is %d\n", + tkt->ticket.authorization_data->val[i].ad_type)); + continue; + } + + auth_data_wrapped = data_blob(tkt->ticket.authorization_data->val[i].ad_data.data, + tkt->ticket.authorization_data->val[i].ad_data.length); + + /* check if it is a PAC */ + got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data); + data_blob_free(&auth_data_wrapped); + + if (!got_auth_data_pac) { + continue; + } + } + + return got_auth_data_pac; + } #endif + return False; } krb5_const_principal get_principal_from_tkt(krb5_ticket *tkt) @@ -435,7 +527,7 @@ cleanup_princ: get a kerberos5 ticket for the given service */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) { krb5_error_code retval; krb5_data packet; @@ -475,7 +567,7 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, if ((retval = ads_krb5_mk_req(context, &auth_context, - AP_OPTS_USE_SUBKEY, + AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts, principal, ccdef, &packet))) { goto failed; @@ -550,10 +642,349 @@ failed: #endif } +void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, + PAC_SIGNATURE_DATA *sig) +{ +#ifdef HAVE_CHECKSUM_IN_KRB5_CHECKSUM + cksum->cksumtype = (krb5_cksumtype)sig->type; + cksum->checksum.length = sig->signature.buf_len; + cksum->checksum.data = sig->signature.buffer; +#else + cksum->checksum_type = (krb5_cksumtype)sig->type; + cksum->length = sig->signature.buf_len; + cksum->contents = sig->signature.buffer; +#endif +} + +krb5_error_code smb_krb5_verify_checksum(krb5_context context, + krb5_keyblock *keyblock, + krb5_keyusage usage, + krb5_checksum *cksum, + uint8 *data, + size_t length) +{ + krb5_error_code ret; + + /* verify the checksum */ + + /* welcome to the wonderful world of samba's kerberos abstraction layer: + * + * function heimdal 0.6.1rc3 heimdal 0.7 MIT krb 1.4.2 + * ----------------------------------------------------------------------------- + * krb5_c_verify_checksum - works works + * krb5_verify_checksum works (6 args) works (6 args) broken (7 args) + */ + +#if defined(HAVE_KRB5_C_VERIFY_CHECKSUM) + { + krb5_boolean checksum_valid = False; + krb5_data input; + + input.data = (char *)data; + input.length = length; + + ret = krb5_c_verify_checksum(context, + keyblock, + usage, + &input, + cksum, + &checksum_valid); + if (!checksum_valid) + ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; + } + +#elif KRB5_VERIFY_CHECKSUM_ARGS == 6 && defined(HAVE_KRB5_CRYPTO_INIT) && defined(HAVE_KRB5_CRYPTO) && defined(HAVE_KRB5_CRYPTO_DESTROY) + + /* Warning: MIT's krb5_verify_checksum cannot be used as it will use a key + * without enctype and it ignores any key_usage types - Guenther */ + + { + + krb5_crypto crypto; + ret = krb5_crypto_init(context, + keyblock, + 0, + &crypto); + if (ret) { + DEBUG(0,("smb_krb5_verify_checksum: krb5_crypto_init() failed: %s\n", + error_message(ret))); + return ret; + } + + ret = krb5_verify_checksum(context, + crypto, + usage, + data, + length, + cksum); + + krb5_crypto_destroy(context, crypto); + } + +#else +#error UNKNOWN_KRB5_VERIFY_CHECKSUM_FUNCTION +#endif + + return ret; +} + +time_t get_authtime_from_tkt(krb5_ticket *tkt) +{ +#if defined(HAVE_KRB5_TKT_ENC_PART2) + return tkt->enc_part2->times.authtime; +#else + return tkt->ticket.authtime; +#endif +} + +static int get_kvno_from_ap_req(krb5_ap_req *ap_req) +{ +#ifdef HAVE_TICKET_POINTER_IN_KRB5_AP_REQ /* MIT */ + if (ap_req->ticket->enc_part.kvno) + return ap_req->ticket->enc_part.kvno; +#else /* Heimdal */ + if (ap_req->ticket.enc_part.kvno) + return *ap_req->ticket.enc_part.kvno; +#endif + return 0; +} + +static krb5_enctype get_enctype_from_ap_req(krb5_ap_req *ap_req) +{ +#ifdef HAVE_ETYPE_IN_ENCRYPTEDDATA /* Heimdal */ + return ap_req->ticket.enc_part.etype; +#else /* MIT */ + return ap_req->ticket->enc_part.enctype; +#endif +} + +static krb5_error_code +get_key_from_keytab(krb5_context context, + krb5_keytab keytab, + krb5_const_principal server, + krb5_enctype enctype, + krb5_kvno kvno, + krb5_keyblock **out_key) +{ + krb5_keytab_entry entry; + krb5_error_code ret; + krb5_keytab real_keytab; + char *name = NULL; + + if (keytab == NULL) { + krb5_kt_default(context, &real_keytab); + } else { + real_keytab = keytab; + } + + if ( DEBUGLEVEL >= 10 ) { + krb5_unparse_name(context, server, &name); + DEBUG(10,("get_key_from_keytab: will look for kvno %d, enctype %d and name: %s\n", + kvno, enctype, name)); + krb5_free_unparsed_name(context, name); + } + + ret = krb5_kt_get_entry(context, + real_keytab, + server, + kvno, + enctype, + &entry); + + if (ret) { + DEBUG(0,("get_key_from_keytab: failed to retrieve key: %s\n", error_message(ret))); + goto out; + } + +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ + ret = krb5_copy_keyblock(context, &entry.keyblock, out_key); +#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) /* MIT */ + ret = krb5_copy_keyblock(context, &entry.key, out_key); +#else +#error UNKNOWN_KRB5_KEYTAB_ENTRY_FORMAT +#endif + + if (ret) { + DEBUG(0,("get_key_from_keytab: failed to copy key: %s\n", error_message(ret))); + goto out; + } + + smb_krb5_kt_free_entry(context, &entry); + +out: + if (keytab == NULL) { + krb5_kt_close(context, real_keytab); + } + + return ret; +} + +void smb_krb5_free_ap_req(krb5_context context, + krb5_ap_req *ap_req) +{ +#ifdef HAVE_KRB5_FREE_AP_REQ /* MIT */ + krb5_free_ap_req(context, ap_req); +#elif defined(HAVE_FREE_AP_REQ) /* Heimdal */ + free_AP_REQ(ap_req); +#else +#error UNKNOWN_KRB5_AP_REQ_FREE_FUNCTION +#endif +} + +/* Prototypes */ +#if defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */ +krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); +#endif + +krb5_error_code smb_krb5_get_keyinfo_from_ap_req(krb5_context context, + const krb5_data *inbuf, + krb5_kvno *kvno, + krb5_enctype *enctype) +{ + krb5_error_code ret; +#ifdef HAVE_KRB5_DECODE_AP_REQ /* Heimdal */ + { + krb5_ap_req ap_req; + + ret = krb5_decode_ap_req(context, inbuf, &ap_req); + if (ret) + return ret; + + *kvno = get_kvno_from_ap_req(&ap_req); + *enctype = get_enctype_from_ap_req(&ap_req); + + smb_krb5_free_ap_req(context, &ap_req); + } +#elif defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */ + { + krb5_ap_req *ap_req = NULL; + + ret = decode_krb5_ap_req(inbuf, &ap_req); + if (ret) + return ret; + + *kvno = get_kvno_from_ap_req(ap_req); + *enctype = get_enctype_from_ap_req(ap_req); + + smb_krb5_free_ap_req(context, ap_req); + } +#else +#error UNKOWN_KRB5_AP_REQ_DECODING_FUNCTION +#endif + return ret; +} + +krb5_error_code krb5_rd_req_return_keyblock_from_keytab(krb5_context context, + krb5_auth_context *auth_context, + const krb5_data *inbuf, + krb5_const_principal server, + krb5_keytab keytab, + krb5_flags *ap_req_options, + krb5_ticket **ticket, + krb5_keyblock **keyblock) +{ + krb5_error_code ret; + krb5_ap_req *ap_req = NULL; + krb5_kvno kvno; + krb5_enctype enctype; + krb5_keyblock *local_keyblock; + + ret = krb5_rd_req(context, + auth_context, + inbuf, + server, + keytab, + ap_req_options, + ticket); + if (ret) { + return ret; + } + + ret = smb_krb5_get_keyinfo_from_ap_req(context, inbuf, &kvno, &enctype); + if (ret) { + return ret; + } + + ret = get_key_from_keytab(context, + keytab, + server, + enctype, + kvno, + &local_keyblock); + if (ret) { + DEBUG(0,("krb5_rd_req_return_keyblock_from_keytab: failed to call get_key_from_keytab\n")); + goto out; + } + +out: + if (ap_req) { + smb_krb5_free_ap_req(context, ap_req); + } + + if (ret && local_keyblock != NULL) { + krb5_free_keyblock(context, local_keyblock); + } else { + *keyblock = local_keyblock; + } + + return ret; +} + +krb5_error_code smb_krb5_parse_name_norealm(krb5_context context, + const char *name, + krb5_principal *principal) +{ +#ifdef HAVE_KRB5_PARSE_NAME_NOREALM + return krb5_parse_name_norealm(context, name, principal); +#endif + + /* we are cheating here because parse_name will in fact set the realm. + * We don't care as the only caller of smb_krb5_parse_name_norealm + * ignores the realm anyway when calling + * smb_krb5_principal_compare_any_realm later - Guenther */ + + return krb5_parse_name(context, name, principal); +} + +BOOL smb_krb5_principal_compare_any_realm(krb5_context context, + krb5_const_principal princ1, + krb5_const_principal princ2) +{ +#ifdef HAVE_KRB5_PRINCIPAL_COMPARE_ANY_REALM + + return krb5_principal_compare_any_realm(context, princ1, princ2); + +/* krb5_princ_size is a macro in MIT */ +#elif defined(HAVE_KRB5_PRINC_SIZE) || defined(krb5_princ_size) + + int i, len1, len2; + const krb5_data *p1, *p2; + + len1 = krb5_princ_size(context, princ1); + len2 = krb5_princ_size(context, princ2); + + if (len1 != len2) + return False; + + for (i = 0; i < len1; i++) { + + p1 = krb5_princ_component(context, CONST_DISCARD(krb5_principal, princ1), i); + p2 = krb5_princ_component(context, CONST_DISCARD(krb5_principal, princ2), i); + + if (p1->length != p2->length || memcmp(p1->data, p2->data, p1->length)) + return False; + } + + return True; +#else +#error NO_SUITABLE_PRINCIPAL_COMPARE_FUNCTION +#endif +} + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5) + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return 1; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 1220907629..55e36b646b 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -323,13 +323,13 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, 0x0008 start of message mode named pipe protocol ****************************************************************************/ -size_t cli_write(struct cli_state *cli, +ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, const char *buf, off_t offset, size_t size) { - int bwritten = 0; - int issued = 0; - int received = 0; + ssize_t bwritten = 0; + unsigned int issued = 0; + unsigned int received = 0; int mpx = 1; int block = cli->max_xmit - (smb_size+32); int blocks = (size + (block-1)) / block; @@ -343,8 +343,8 @@ size_t cli_write(struct cli_state *cli, while (received < blocks) { while ((issued - received < mpx) && (issued < blocks)) { - int bsent = issued * block; - int size1 = MIN(block, size - bsent); + ssize_t bsent = issued * block; + ssize_t size1 = MIN(block, size - bsent); if (!cli_issue_write(cli, fnum, offset + bsent, write_mode, diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 85b7bd9e1e..33fc265f79 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -325,14 +325,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) */ int spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *targ, - DATA_BLOB *session_key_krb5) + DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) { int retval; DATA_BLOB tkt, tkt_wrapped; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service and extract the session key */ - retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5); + retval = cli_krb5_get_ticket(principal, time_offset, + &tkt, session_key_krb5, extra_ap_opts); if (retval) return retval; diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index c6b1d465ff..5d3710b92e 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -464,8 +464,8 @@ BOOL cli_send_nt_trans(struct cli_state *cli, } /**************************************************************************** - receive a SMB nttrans response allocating the necessary memory - ****************************************************************************/ + Receive a SMB nttrans response allocating the necessary memory. +****************************************************************************/ BOOL cli_receive_nt_trans(struct cli_state *cli, char **param, unsigned int *param_len, @@ -503,7 +503,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, */ if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if (cli->pipes[cli->pipe_idx].fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + if (!(eclass == ERRDOS && ecode == ERRmoredata)) { cli_signing_trans_stop(cli); return(False); } @@ -637,11 +637,22 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, } if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); - if(cli->pipes[cli->pipe_idx].fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata)) { + if(!(eclass == ERRDOS && ecode == ERRmoredata)) { + cli_signing_trans_stop(cli); + return(False); + } + } + /* + * Likewise for NT_STATUS_BUFFER_TOO_SMALL + */ + if (cli_is_nt_error(cli)) { + if (!NT_STATUS_EQUAL(cli_nt_error(cli), + NT_STATUS_BUFFER_TOO_SMALL)) { cli_signing_trans_stop(cli); return(False); } } + /* parse out the total lengths again - they can shrink! */ if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 0d521bae8a..3f2dcd850b 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. code to manipulate domain credentials Copyright (C) Andrew Tridgell 1997-1998 + Largely rewritten by Jeremy Allison 2005. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,8 +22,9 @@ #include "includes.h" /**************************************************************************** -represent a credential as a string + Represent a credential as a string. ****************************************************************************/ + char *credstr(const uchar *cred) { static fstring buf; @@ -34,182 +36,243 @@ char *credstr(const uchar *cred) /**************************************************************************** - setup the session key. -Input: 8 byte challenge block + Setup the session key. + Input: 8 byte challenge block 8 byte server challenge block 16 byte md4 encrypted password -Output: - 8 byte session key + Output: + 16 byte session key (last 8 bytes zero). ****************************************************************************/ -void cred_session_key(const DOM_CHAL *clnt_chal, const DOM_CHAL *srv_chal, const uchar *pass, - uchar session_key[8]) + +static void cred_create_session_key(const DOM_CHAL *clnt_chal_in, + const DOM_CHAL *srv_chal_in, + const uchar *pass_in, + uchar session_key_out[16]) { uint32 sum[2]; unsigned char sum2[8]; - sum[0] = IVAL(clnt_chal->data, 0) + IVAL(srv_chal->data, 0); - sum[1] = IVAL(clnt_chal->data, 4) + IVAL(srv_chal->data, 4); + sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0); + sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4); SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(session_key, sum2, pass); + cred_hash1(session_key_out, sum2, pass_in); + memset(&session_key_out[8], '\0', 8); /* debug output */ - DEBUG(4,("cred_session_key\n")); + DEBUG(4,("cred_create_session_key\n")); - DEBUG(5,(" clnt_chal: %s\n", credstr(clnt_chal->data))); - DEBUG(5,(" srv_chal : %s\n", credstr(srv_chal->data))); + DEBUG(5,(" clnt_chal_in: %s\n", credstr(clnt_chal_in->data))); + DEBUG(5,(" srv_chal_in : %s\n", credstr(srv_chal_in->data))); DEBUG(5,(" clnt+srv : %s\n", credstr(sum2))); - DEBUG(5,(" sess_key : %s\n", credstr(session_key))); + DEBUG(5,(" sess_key_out : %s\n", credstr(session_key_out))); } - /**************************************************************************** -create a credential - -Input: - 8 byte sesssion key - 8 byte stored credential - 4 byte timestamp - -Output: - 8 byte credential + Utility function to step credential chain one forward. + Deliberately doesn't update the seed. See reseed comment below. ****************************************************************************/ -void cred_create(uchar session_key[8], DOM_CHAL *stor_cred, UTIME timestamp, - DOM_CHAL *cred) + +static void creds_step(struct dcinfo *dc) { - DOM_CHAL time_cred; + DOM_CHAL time_chal; - SIVAL(time_cred.data, 0, IVAL(stor_cred->data, 0) + timestamp.time); - SIVAL(time_cred.data, 4, IVAL(stor_cred->data, 4)); + DEBUG(5,("\tsequence = 0x%x\n", (unsigned int)dc->sequence )); - cred_hash2(cred->data, time_cred.data, session_key); + DEBUG(5,("\tseed: %s\n", credstr(dc->seed_chal.data) )); - /* debug output*/ - DEBUG(4,("cred_create\n")); + SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence); + SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4)); + + DEBUG(5,("\tseed+seq %s\n", credstr(time_chal.data) )); - DEBUG(5,(" sess_key : %s\n", credstr(session_key))); - DEBUG(5,(" stor_cred: %s\n", credstr(stor_cred->data))); - DEBUG(5,(" timestamp: %x\n" , timestamp.time)); - DEBUG(5,(" timecred : %s\n", credstr(time_cred.data))); - DEBUG(5,(" calc_cred: %s\n", credstr(cred->data))); -} + cred_hash2(dc->clnt_chal.data, time_chal.data, dc->sess_key); + DEBUG(5,("\tCLIENT %s\n", credstr(dc->clnt_chal.data) )); -/**************************************************************************** - check a supplied credential + SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1); + SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4)); + + DEBUG(5,("\tseed+seq+1 %s\n", credstr(time_chal.data) )); -Input: - 8 byte received credential - 8 byte sesssion key - 8 byte stored credential - 4 byte timestamp + cred_hash2(dc->srv_chal.data, time_chal.data, dc->sess_key); + + DEBUG(5,("\tSERVER %s\n", credstr(dc->srv_chal.data) )); +} -Output: - returns 1 if computed credential matches received credential - returns 0 otherwise + +/**************************************************************************** + Create a server credential struct. ****************************************************************************/ -int cred_assert(DOM_CHAL *cred, uchar session_key[8], DOM_CHAL *stored_cred, - UTIME timestamp) + +void creds_server_init(struct dcinfo *dc, + DOM_CHAL *clnt_chal, + DOM_CHAL *srv_chal, + const char mach_pw[16], + DOM_CHAL *init_chal_out) { - DOM_CHAL cred2; + DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) )); + DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) )); + dump_data_pw("creds_server_init: machine pass", mach_pw, 16); - cred_create(session_key, stored_cred, timestamp, &cred2); + /* Just in case this isn't already there */ + memcpy(dc->mach_pw, mach_pw, 16); - /* debug output*/ - DEBUG(4,("cred_assert\n")); + /* Generate the session key. */ + cred_create_session_key(clnt_chal, /* Stored client challenge. */ + srv_chal, /* Stored server challenge. */ + dc->mach_pw, /* input machine password. */ + dc->sess_key); /* output session key. */ - DEBUG(5,(" challenge : %s\n", credstr(cred->data))); - DEBUG(5,(" calculated: %s\n", credstr(cred2.data))); + dump_data_pw("creds_server_init: session key", dc->sess_key, 16); - if (memcmp(cred->data, cred2.data, 8) == 0) - { - DEBUG(5, ("credentials check ok\n")); - return True; - } - else - { - DEBUG(5, ("credentials check wrong\n")); + /* Generate the next client and server creds. */ + cred_hash2(dc->clnt_chal.data, /* output */ + clnt_chal->data, /* input */ + dc->sess_key); /* input */ + + cred_hash2(dc->srv_chal.data, /* output */ + srv_chal->data, /* input */ + dc->sess_key); /* input */ + + /* Seed is the client chal. */ + memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8); + + DEBUG(10,("creds_server_init: clnt : %s\n", credstr(dc->clnt_chal.data) )); + DEBUG(10,("creds_server_init: server : %s\n", credstr(dc->srv_chal.data) )); + DEBUG(10,("creds_server_init: seed : %s\n", credstr(dc->seed_chal.data) )); + + memcpy(init_chal_out->data, dc->srv_chal.data, 8); +} + +/**************************************************************************** + Check a credential sent by the client. +****************************************************************************/ + +BOOL creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in) +{ + if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) { + DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data))); + DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data))); + DEBUG(0,("creds_server_check: credentials check failed.\n")); return False; } + DEBUG(10,("creds_server_check: credentials check OK.\n")); + return True; } - /**************************************************************************** - checks credentials; generates next step in the credential chain + Replace current seed chal. Internal function - due to split server step below. ****************************************************************************/ -BOOL clnt_deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, DOM_CRED *rcv_srv_cred) + +static void creds_reseed(struct dcinfo *dc) { - UTIME new_clnt_time; - uint32 new_cred; + DOM_CHAL time_chal; - DEBUG(5,("clnt_deal_with_creds: %d\n", __LINE__)); + SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1); + SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4)); - /* increment client time by one second */ - new_clnt_time.time = sto_clnt_cred->timestamp.time + 1; + dc->seed_chal = time_chal; - /* check that the received server credentials are valid */ - if (!cred_assert(&rcv_srv_cred->challenge, sess_key, - &sto_clnt_cred->challenge, new_clnt_time)) - { - return False; - } + DEBUG(5,("cred_reseed: seed %s\n", credstr(dc->seed_chal.data) )); +} - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->challenge.data, 0); - new_cred += new_clnt_time.time; +/**************************************************************************** + Step the server credential chain one forward. +****************************************************************************/ - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); +BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out) +{ + dc->sequence = received_cred->timestamp.time; - DEBUG(5,(" new clnt cred: %s\n", credstr(sto_clnt_cred->challenge.data))); - return True; -} + creds_step(dc); + + /* Create the outgoing credentials */ + cred_out->timestamp.time = dc->sequence + 1; + cred_out->challenge = dc->srv_chal; + creds_reseed(dc); + + return creds_server_check(dc, &received_cred->challenge); +} /**************************************************************************** - checks credentials; generates next step in the credential chain + Create a client credential struct. ****************************************************************************/ -BOOL deal_with_creds(uchar sess_key[8], - DOM_CRED *sto_clnt_cred, - DOM_CRED *rcv_clnt_cred, DOM_CRED *rtn_srv_cred) + +void creds_client_init(struct dcinfo *dc, + DOM_CHAL *clnt_chal, + DOM_CHAL *srv_chal, + const char mach_pw[16], + DOM_CHAL *init_chal_out) { - UTIME new_clnt_time; - uint32 new_cred; + dc->sequence = time(NULL); - DEBUG(5,("deal_with_creds: %d\n", __LINE__)); + DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) )); + DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) )); + dump_data_pw("creds_client_init: machine pass", mach_pw, 16); - /* check that the received client credentials are valid */ - if (!cred_assert(&rcv_clnt_cred->challenge, sess_key, - &sto_clnt_cred->challenge, rcv_clnt_cred->timestamp)) - { - return False; - } + /* Just in case this isn't already there */ + memcpy(dc->mach_pw, mach_pw, 16); - /* increment client time by one second */ - new_clnt_time.time = rcv_clnt_cred->timestamp.time + 1; + /* Generate the session key. */ + cred_create_session_key(clnt_chal, /* Stored client challenge. */ + srv_chal, /* Stored server challenge. */ + dc->mach_pw, /* input machine password. */ + dc->sess_key); /* output session key. */ - /* first 4 bytes of the new seed is old client 4 bytes + clnt time + 1 */ - new_cred = IVAL(sto_clnt_cred->challenge.data, 0); - new_cred += new_clnt_time.time; + dump_data_pw("creds_client_init: session key", dc->sess_key, 16); - DEBUG(5,("deal_with_creds: new_cred[0]=%x\n", new_cred)); + /* Generate the next client and server creds. */ + cred_hash2(dc->clnt_chal.data, /* output */ + clnt_chal->data, /* input */ + dc->sess_key); /* input */ - /* doesn't matter that server time is 0 */ - rtn_srv_cred->timestamp.time = 0; + cred_hash2(dc->srv_chal.data, /* output */ + srv_chal->data, /* input */ + dc->sess_key); /* input */ - DEBUG(5,("deal_with_creds: new_clnt_time=%x\n", new_clnt_time.time)); + /* Seed is the client cred. */ + memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8); - /* create return credentials for inclusion in the reply */ - cred_create(sess_key, &sto_clnt_cred->challenge, new_clnt_time, - &rtn_srv_cred->challenge); - - DEBUG(5,("deal_with_creds: clnt_cred=%s\n", credstr(sto_clnt_cred->challenge.data))); + DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) )); + DEBUG(10,("creds_client_init: server : %s\n", credstr(dc->srv_chal.data) )); + DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) )); - /* store new seed in client credentials */ - SIVAL(sto_clnt_cred->challenge.data, 0, new_cred); + memcpy(init_chal_out->data, dc->clnt_chal.data, 8); +} + +/**************************************************************************** + Check a credential returned by the server. +****************************************************************************/ +BOOL creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in) +{ + if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, 8)) { + DEBUG(5,("creds_client_check: challenge : %s\n", credstr(rcv_srv_chal_in->data))); + DEBUG(5,("calculated: %s\n", credstr(dc->srv_chal.data))); + DEBUG(0,("creds_client_check: credentials check failed.\n")); + return False; + } + DEBUG(10,("creds_client_check: credentials check OK.\n")); return True; } + +/**************************************************************************** + Step the client credentials to the next element in the chain, updating the + current client and server credentials and the seed + produce the next authenticator in the sequence ready to send to + the server +****************************************************************************/ + +void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out) +{ + dc->sequence += 2; + creds_step(dc); + creds_reseed(dc); + + next_cred_out->challenge = dc->clnt_chal; + next_cred_out->timestamp.time = dc->sequence; +} diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 8462fbee87..3c0b13ad6f 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -62,7 +62,7 @@ static const struct { {ERRDOS, 193, NT_STATUS_BAD_INITIAL_PC}, {ERRDOS, 87, NT_STATUS_INVALID_CID}, {ERRHRD, ERRgeneral, NT_STATUS_TIMER_NOT_CANCELED}, - {ERRDOS, 87, NT_STATUS_INVALID_PARAMETER}, + {ERRDOS, ERRinvalidparam, NT_STATUS_INVALID_PARAMETER}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_DEVICE}, {ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE}, {ERRDOS, ERRbadfunc, NT_STATUS_INVALID_DEVICE_REQUEST}, @@ -338,7 +338,7 @@ static const struct { {ERRDOS, 203, NT_STATUS(0xc0000100)}, {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, {ERRHRD, ERRgeneral, NT_STATUS_FILE_CORRUPT_ERROR}, - {ERRDOS, 267, NT_STATUS_NOT_A_DIRECTORY}, + {ERRDOS, ERRbaddirectory, NT_STATUS_NOT_A_DIRECTORY}, {ERRHRD, ERRgeneral, NT_STATUS_BAD_LOGON_SESSION_STATE}, {ERRHRD, ERRgeneral, NT_STATUS_LOGON_SESSION_COLLISION}, {ERRDOS, 206, NT_STATUS_NAME_TOO_LONG}, diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index f9461f9368..5699e153bb 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -420,7 +420,7 @@ int smbc_open_print_job(const char *fname) { SMBCFILE * file = statcont->open_print_job(statcont, fname); if (!file) return -1; - return (int) file; + return file->cli_fd; } int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn) diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index fe8f878aa5..1e729abb22 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -80,6 +80,23 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { return False; } +/* + * Find an lsa pipe handle associated with a cli struct. + */ + +static struct rpc_pipe_client *find_lsa_pipe_hnd(struct cli_state *ipc_cli) +{ + struct rpc_pipe_client *pipe_hnd; + + for (pipe_hnd = ipc_cli->pipe_list; pipe_hnd; pipe_hnd = pipe_hnd->next) { + if (pipe_hnd->pipe_idx == PI_LSARPC) { + return pipe_hnd; + } + } + + return NULL; +} + static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file); static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence); @@ -800,6 +817,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, { struct in_addr ip; struct cli_state *ipc_cli; + struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; SMBCSRV *ipc_srv=NULL; @@ -835,29 +853,27 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, return NULL; } - if(pol) { + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_cli, PI_LSARPC, &nt_status); + if (!pipe_hnd) { + DEBUG(1, ("cli_nt_session_open fail!\n")); + errno = ENOTSUP; + cli_shutdown(ipc_cli); + return NULL; + } - if (!cli_nt_session_open(ipc_cli, PI_LSARPC)) { - DEBUG(1, ("cli_nt_session_open fail!\n")); - errno = ENOTSUP; - cli_shutdown(ipc_cli); - return NULL; - } - - /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, - but NT sends 0x2000000 so we might as well do it too. */ - - nt_status = cli_lsa_open_policy(ipc_cli, - ipc_cli->mem_ctx, - True, - GENERIC_EXECUTE_ACCESS, - pol); - - if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, ipc_cli); - cli_shutdown(ipc_cli); - return NULL; - } + /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, + but NT sends 0x2000000 so we might as well do it too. */ + + nt_status = rpccli_lsa_open_policy(pipe_hnd, + ipc_cli->mem_ctx, + True, + GENERIC_EXECUTE_ACCESS, + pol); + + if (!NT_STATUS_IS_OK(nt_status)) { + errno = smbc_errno(context, ipc_cli); + cli_shutdown(ipc_cli); + return NULL; } ipc_srv = SMB_MALLOC_P(SMBCSRV); @@ -1782,7 +1798,7 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL, NULL, NULL, NULL)) { - SMB_BIG_UINT b_size = size; + SMB_OFF_T b_size = size; if (!cli_getattrE(targetcli, file->cli_fd, NULL, &b_size, NULL, NULL, NULL)) { @@ -3041,7 +3057,7 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) /* * We return the pointer here as the offset */ - ret_val = (int)dir->dir_next; + ret_val = (off_t)(long)dir->dir_next; return ret_val; } @@ -3347,14 +3363,20 @@ static void convert_sid_to_string(struct cli_state *ipc_cli, char **domains = NULL; char **names = NULL; uint32 *types = NULL; - + struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); sid_to_string(str, sid); - if (numeric) return; /* no lookup desired */ - + if (numeric) { + return; /* no lookup desired */ + } + + if (!pipe_hnd) { + return; + } + /* Ask LSA to convert the sid to a name */ - if (!NT_STATUS_IS_OK(cli_lsa_lookup_sids(ipc_cli, ipc_cli->mem_ctx, + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ipc_cli->mem_ctx, pol, 1, sid, &domains, &names, &types)) || !domains || !domains[0] || !names || !names[0]) { @@ -3378,6 +3400,11 @@ static BOOL convert_string_to_sid(struct cli_state *ipc_cli, uint32 *types = NULL; DOM_SID *sids = NULL; BOOL result = True; + struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); + + if (!pipe_hnd) { + return False; + } if (numeric) { if (strncmp(str, "S-", 2) == 0) { @@ -3388,7 +3415,7 @@ static BOOL convert_string_to_sid(struct cli_state *ipc_cli, goto done; } - if (!NT_STATUS_IS_OK(cli_lsa_lookup_names(ipc_cli, ipc_cli->mem_ctx, + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx, pol, 1, &str, &sids, &types))) { result = False; @@ -5161,7 +5188,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr /* Try to open the file for reading ... */ - if ((int)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { + if ((long)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); return -1; /* smbc_open sets errno */ @@ -5170,7 +5197,7 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr /* Now, try to open the printer file for writing */ - if ((int)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { + if ((long)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { saverr = errno; /* Save errno */ c_file->close_fn(c_file, fid1); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index b02c2384a8..6b551e8774 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -5,6 +5,7 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Andrew Bartlett 2001-2003 + Copyright (C) Andrew Bartlett 2005 (Updated from gensec). This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -217,6 +218,12 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, uint32 ntlmssp_command; int i; + if (ntlmssp_state->expected_state == NTLMSSP_DONE) { + /* Called update after negotiations finished. */ + DEBUG(1, ("Called NTLMSSP after state machine was 'done'\n")); + return NT_STATUS_INVALID_PARAMETER; + } + *out = data_blob(NULL, 0); if (!in.length && ntlmssp_state->stored_response.length) { @@ -348,6 +355,13 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; + if (neg_flags & NTLMSSP_NEGOTIATE_56) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; + } + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_56; } if (!(neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { @@ -360,6 +374,34 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, } +/** + Weaken NTLMSSP keys to cope with down-level clients and servers. + + We probably should have some parameters to control this, but as + it only occours for LM_KEY connections, and this is controlled + by the client lanman auth/lanman auth parameters, it isn't too bad. +*/ + +void ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state) +{ + /* Key weakening not performed on the master key for NTLM2 + and does not occour for NTLM1. Therefore we only need + to do this for the LM_KEY. + */ + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { + ; + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { + ntlmssp_state->session_key.data[7] = 0xa0; + } else { /* forty bits */ + ntlmssp_state->session_key.data[5] = 0xe5; + ntlmssp_state->session_key.data[6] = 0x38; + ntlmssp_state->session_key.data[7] = 0xb0; + } + ntlmssp_state->session_key.length = 8; + } +} /** * Next state function for the Negotiate packet @@ -398,6 +440,9 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_INVALID_PARAMETER; } + DEBUG(10, ("ntlmssp_server_negotiate: client = %s, domain = %s\n", + cliname ? cliname : "", domname ? domname : "")); + SAFE_FREE(cliname); SAFE_FREE(domname); @@ -495,7 +540,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, DATA_BLOB lm_session_key = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); uint32 ntlmssp_command, auth_flags; - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_OK; /* used by NTLM2 */ BOOL doing_ntlm2 = False; @@ -639,6 +684,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&encrypted_session_key); return nt_status; } + + /* LM Key is incompatible. */ + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } } @@ -710,11 +758,11 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, if (!encrypted_session_key.data || encrypted_session_key.length != 16) { data_blob_free(&encrypted_session_key); DEBUG(1, ("Client-supplied KEY_EXCH session key was of invalid length (%u)!\n", - encrypted_session_key.length)); + (unsigned int)encrypted_session_key.length)); return NT_STATUS_INVALID_PARAMETER; } else if (!session_key.data || session_key.length != 16) { DEBUG(5, ("server session key is invalid (len == %u), cannot do KEY_EXCH!\n", - session_key.length)); + (unsigned int)session_key.length)); ntlmssp_state->session_key = session_key; } else { dump_data_pw("KEY_EXCH session key (enc):\n", encrypted_session_key.data, encrypted_session_key.length); @@ -731,6 +779,9 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = session_key; } + /* The client might need us to use a partial-strength session key */ + ntlmssp_weaken_keys(ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { ntlmssp_state->session_key = data_blob(NULL, 0); } else if (ntlmssp_state->session_key.length) { @@ -739,8 +790,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, data_blob_free(&encrypted_session_key); - /* allow arbitarily many authentications */ - ntlmssp_state->expected_state = NTLMSSP_AUTH; + /* Only one authentication allowed per server state. */ + ntlmssp_state->expected_state = NTLMSSP_DONE; return nt_status; } @@ -784,7 +835,8 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | - NTLMSSP_NEGOTIATE_SIGN; + NTLMSSP_NEGOTIATE_SIGN | + NTLMSSP_NEGOTIATE_SEAL; return NT_STATUS_OK; } @@ -851,7 +903,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB encrypted_session_key = data_blob(NULL, 0); - NTSTATUS nt_status; + NTSTATUS nt_status = NT_STATUS_OK; if (!msrpc_parse(&reply, "CdBd", "NTLMSSP", @@ -977,8 +1029,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { - - uchar lm_hash[16]; uchar nt_hash[16]; E_deshash(ntlmssp_state->password, lm_hash); @@ -998,8 +1048,8 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && lp_client_lanman_auth()) { - SMBsesskeygen_lmv1(lm_hash, lm_response.data, - session_key.data); + SMBsesskeygen_lm_sess_key(lm_hash, lm_response.data, + session_key.data); dump_data_pw("LM session key\n", session_key.data, session_key.length); } else { SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); @@ -1045,19 +1095,22 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, data_blob_free(&ntlmssp_state->chal); + ntlmssp_state->session_key = session_key; + + /* The client might be using 56 or 40 bit weakened keys */ + ntlmssp_weaken_keys(ntlmssp_state); + ntlmssp_state->chal = challenge_blob; ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; - ntlmssp_state->session_key = session_key; - ntlmssp_state->expected_state = NTLMSSP_UNKNOWN; + ntlmssp_state->expected_state = NTLMSSP_DONE; if (!NT_STATUS_IS_OK(nt_status = ntlmssp_sign_init(ntlmssp_state))) { DEBUG(1, ("Could not setup NTLMSSP signing/sealing system (error was: %s)\n", nt_errstr(nt_status))); - return nt_status; } - return NT_STATUS_MORE_PROCESSING_REQUIRED; + return nt_status; } NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) @@ -1103,4 +1156,3 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) return NT_STATUS_OK; } - diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 4b3043aec8..e71504867e 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -216,7 +216,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, /* if odd length and unicode */ return False; } - if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) return False; if (0 < len1) { @@ -244,7 +244,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, return False; } - if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) return False; if (0 < len1) { @@ -272,7 +272,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, return False; } - if (blob->data + ptr < (uint8 *)ptr || blob->data + ptr < blob->data) + if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) return False; *b = data_blob(blob->data + ptr, len1); diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index b810597076..51023ca356 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -2,8 +2,7 @@ * Unix SMB/CIFS implementation. * Version 3.0 * NTLMSSP Signing routines - * Copyright (C) Luke Kenneth Casson Leighton 1996-2001 - * Copyright (C) Andrew Bartlett 2003 + * Copyright (C) Andrew Bartlett 2003-2005 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,74 +26,25 @@ #define SRV_SIGN "session key to server-to-client signing key magic constant" #define SRV_SEAL "session key to server-to-client sealing key magic constant" -static void NTLMSSPcalc_ap( unsigned char *hash, unsigned char *data, int len) -{ - unsigned char index_i = hash[256]; - unsigned char index_j = hash[257]; - int ind; - - for (ind = 0; ind < len; ind++) - { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += hash[index_i]; - - tc = hash[index_i]; - hash[index_i] = hash[index_j]; - hash[index_j] = tc; - - t = hash[index_i] + hash[index_j]; - data[ind] = data[ind] ^ hash[t]; - } - - hash[256] = index_i; - hash[257] = index_j; -} - -static void calc_hash(unsigned char hash[258], unsigned char *k2, int k2l) -{ - unsigned char j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) - { - hash[ind] = (unsigned char)ind; - } - - for (ind = 0; ind < 256; ind++) - { - unsigned char tc; - - j += (hash[ind] + k2[ind%k2l]); - - tc = hash[ind]; - hash[ind] = hash[j]; - hash[j] = tc; - } - - hash[256] = 0; - hash[257] = 0; -} +/** + * Some notes on then NTLM2 code: + * + * NTLM2 is a AEAD system. This means that the data encrypted is not + * all the data that is signed. In DCE-RPC case, the headers of the + * DCE-RPC packets are also signed. This prevents some of the + * fun-and-games one might have by changing them. + * + */ -static void calc_ntlmv2_hash(unsigned char hash[258], unsigned char digest[16], - DATA_BLOB session_key, - const char *constant) +static void calc_ntlmv2_key(unsigned char subkey[16], + DATA_BLOB session_key, + const char *constant) { struct MD5Context ctx3; - - /* NOTE: This code is currently complate fantasy - it's - got more in common with reality than the previous code - (the LM session key is not the right thing to use) but - it still needs work */ - MD5Init(&ctx3); MD5Update(&ctx3, session_key.data, session_key.length); - MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1); - MD5Final(digest, &ctx3); - - calc_hash(hash, digest, 16); + MD5Update(&ctx3, constant, strlen(constant)+1); + MD5Final(subkey, &ctx3); } enum ntlmssp_direction { @@ -103,64 +53,107 @@ enum ntlmssp_direction { }; static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, - const uchar *data, size_t length, - enum ntlmssp_direction direction, - DATA_BLOB *sig) + const uchar *data, size_t length, + const uchar *whole_pdu, size_t pdu_length, + enum ntlmssp_direction direction, + DATA_BLOB *sig, + BOOL encrypt_sig) { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; uchar seq_num[4]; uchar digest[16]; - SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - - hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); - hmac_md5_update(seq_num, 4, &ctx); - hmac_md5_update(data, length, &ctx); - hmac_md5_final(digest, &ctx); - if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */ - , ntlmssp_state->ntlmssp_seq_num)) { + *sig = data_blob(NULL, NTLMSSP_SIG_SIZE); + if (!sig->data) { return NT_STATUS_NO_MEMORY; } - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + switch (direction) { + case NTLMSSP_SEND: + DEBUG(100,("ntlmssp_make_packet_signature: SEND seq = %u, len = %u, pdu_len = %u\n", + ntlmssp_state->ntlm2_send_seq_num, + (unsigned int)length, + (unsigned int)pdu_length)); + + SIVAL(seq_num, 0, ntlmssp_state->ntlm2_send_seq_num); + ntlmssp_state->ntlm2_send_seq_num++; + hmac_md5_init_limK_to_64(ntlmssp_state->send_sign_key, 16, &ctx); + break; + case NTLMSSP_RECEIVE: + + DEBUG(100,("ntlmssp_make_packet_signature: RECV seq = %u, len = %u, pdu_len = %u\n", + ntlmssp_state->ntlm2_recv_seq_num, + (unsigned int)length, + (unsigned int)pdu_length)); + + SIVAL(seq_num, 0, ntlmssp_state->ntlm2_recv_seq_num); + ntlmssp_state->ntlm2_recv_seq_num++; + hmac_md5_init_limK_to_64(ntlmssp_state->recv_sign_key, 16, &ctx); + break; + } + + dump_data_pw("pdu data ", whole_pdu, pdu_length); + + hmac_md5_update(seq_num, 4, &ctx); + hmac_md5_update(whole_pdu, pdu_length, &ctx); + hmac_md5_final(digest, &ctx); + + if (encrypt_sig && (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH)) { switch (direction) { case NTLMSSP_SEND: - NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); + smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, digest, 8); break; case NTLMSSP_RECEIVE: - NTLMSSPcalc_ap(ntlmssp_state->recv_sign_hash, sig->data+4, sig->length-4); + smb_arc4_crypt(ntlmssp_state->recv_seal_arc4_state, digest, 8); break; } } + + SIVAL(sig->data, 0, NTLMSSP_SIGN_VERSION); + memcpy(sig->data + 4, digest, 8); + memcpy(sig->data + 12, seq_num, 4); + + dump_data_pw("ntlmssp v2 sig ", sig->data, sig->length); + } else { uint32 crc; crc = crc32_calc_buffer((const char *)data, length); - if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) { return NT_STATUS_NO_MEMORY; } - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + ntlmssp_state->ntlmv1_seq_num++; + + dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmv1_arc4_state, + sizeof(ntlmssp_state->ntlmv1_arc4_state)); + smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4); } return NT_STATUS_OK; } NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, const uchar *data, size_t length, + const uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { NTSTATUS nt_status; + + if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { + DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot check sign packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; } - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, NTLMSSP_SEND, sig); + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, + data, length, + whole_pdu, pdu_length, + NTLMSSP_SEND, sig, True); - /* increment counter on send */ - ntlmssp_state->ntlmssp_seq_num++; return nt_status; } @@ -171,8 +164,9 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, */ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, - const uchar *data, size_t length, - const DATA_BLOB *sig) + const uchar *data, size_t length, + const uchar *whole_pdu, size_t pdu_length, + const DATA_BLOB *sig) { DATA_BLOB local_sig; NTSTATUS nt_status; @@ -187,32 +181,51 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, (unsigned long)sig->length)); } - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, - length, NTLMSSP_RECEIVE, &local_sig); + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, + data, length, + whole_pdu, pdu_length, + NTLMSSP_RECEIVE, &local_sig, True); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("NTLMSSP packet check failed with %s\n", nt_errstr(nt_status))); + data_blob_free(&local_sig); return nt_status; } - if (memcmp(sig->data+sig->length - 8, local_sig.data+local_sig.length - 8, 8) != 0) { - DEBUG(5, ("BAD SIG: wanted signature of\n")); - dump_data(5, (const char *)local_sig.data, local_sig.length); - - DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, (const char *)(sig->data), sig->length); + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + if (local_sig.length != sig->length || + memcmp(local_sig.data, sig->data, sig->length) != 0) { + DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n")); + dump_data(5, local_sig.data, local_sig.length); - DEBUG(0, ("NTLMSSP packet check failed due to invalid signature!\n")); - return NT_STATUS_ACCESS_DENIED; - } + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, sig->data, sig->length); + + DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); + data_blob_free(&local_sig); + return NT_STATUS_ACCESS_DENIED; + } + } else { + if (local_sig.length != sig->length || + memcmp(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) { + DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n")); + dump_data(5, local_sig.data, local_sig.length); + + DEBUG(5, ("BAD SIG: got signature of\n")); + dump_data(5, sig->data, sig->length); - /* increment counter on recieive */ - ntlmssp_state->ntlmssp_seq_num++; + DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n")); + data_blob_free(&local_sig); + return NT_STATUS_ACCESS_DENIED; + } + } + dump_data_pw("checked ntlmssp signature\n", sig->data, sig->length); + DEBUG(10,("ntlmssp_check_packet: NTLMSSP signature OK !\n")); + data_blob_free(&local_sig); return NT_STATUS_OK; } - /** * Seal data with the NTLMSSP algorithm * @@ -220,8 +233,16 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *data, size_t length, + uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { + NTSTATUS nt_status; + + if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n")); + return NT_STATUS_INVALID_PARAMETER; + } + if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot seal packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; @@ -230,53 +251,44 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, DEBUG(10,("ntlmssp_seal_data: seal\n")); dump_data_pw("ntlmssp clear data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - HMACMD5Context ctx; - char seq_num[4]; - uchar digest[16]; - SIVAL(seq_num, 0, ntlmssp_state->ntlmssp_seq_num); - - hmac_md5_init_limK_to_64((const unsigned char *)(ntlmssp_state->send_sign_const), 16, &ctx); - hmac_md5_update((const unsigned char *)seq_num, 4, &ctx); - hmac_md5_update(data, length, &ctx); - hmac_md5_final(digest, &ctx); - - if (!msrpc_gen(sig, "dBd", NTLMSSP_SIGN_VERSION, digest, 8 /* only copy first 8 bytes */ - , ntlmssp_state->ntlmssp_seq_num)) { - return NT_STATUS_NO_MEMORY; + /* The order of these two operations matters - we must first seal the packet, + then seal the sequence number - this is becouse the send_seal_hash is not + constant, but is is rather updated with each iteration */ + nt_status = ntlmssp_make_packet_signature(ntlmssp_state, + data, length, + whole_pdu, pdu_length, + NTLMSSP_SEND, sig, False); + smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, data, length); + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, sig->data+4, 8); } - - dump_data_pw("ntlmssp client sealing hash:\n", - ntlmssp_state->send_seal_hash, - sizeof(ntlmssp_state->send_seal_hash)); - NTLMSSPcalc_ap(ntlmssp_state->send_seal_hash, data, length); - dump_data_pw("ntlmssp client signing hash:\n", - ntlmssp_state->send_sign_hash, - sizeof(ntlmssp_state->send_sign_hash)); - NTLMSSPcalc_ap(ntlmssp_state->send_sign_hash, sig->data+4, sig->length-4); } else { uint32 crc; crc = crc32_calc_buffer((const char *)data, length); - if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmssp_seq_num)) { + if (!msrpc_gen(sig, "dddd", NTLMSSP_SIGN_VERSION, 0, crc, ntlmssp_state->ntlmv1_seq_num)) { return NT_STATUS_NO_MEMORY; } /* The order of these two operations matters - we must first seal the packet, - then seal the sequence number - this is becouse the ntlmssp_hash is not + then seal the sequence number - this is becouse the ntlmv1_arc4_state is not constant, but is is rather updated with each iteration */ - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); + dump_data_pw("ntlmv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state, + sizeof(ntlmssp_state->ntlmv1_arc4_state)); + smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, data, length); + + dump_data_pw("ntlmv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state, + sizeof(ntlmssp_state->ntlmv1_arc4_state)); + + smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4); - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, sig->data+4, sig->length-4); + ntlmssp_state->ntlmv1_seq_num++; + + nt_status = NT_STATUS_OK; } + dump_data_pw("ntlmssp signature\n", sig->data, sig->length); dump_data_pw("ntlmssp sealed data\n", data, length); - /* increment counter on send */ - ntlmssp_state->ntlmssp_seq_num++; - return NT_STATUS_OK; } @@ -286,26 +298,27 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, */ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, - uchar *data, size_t length, - DATA_BLOB *sig) + uchar *data, size_t length, + uchar *whole_pdu, size_t pdu_length, + DATA_BLOB *sig) { if (!ntlmssp_state->session_key.length) { DEBUG(3, ("NO session key, cannot unseal packet\n")); return NT_STATUS_NO_USER_SESSION_KEY; } - DEBUG(10,("ntlmssp__unseal_data: seal\n")); + DEBUG(10,("ntlmssp_unseal_data: seal\n")); dump_data_pw("ntlmssp sealed data\n", data, length); + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { - NTLMSSPcalc_ap(ntlmssp_state->recv_seal_hash, data, length); + /* First unseal the data. */ + smb_arc4_crypt(ntlmssp_state->recv_seal_arc4_state, data, length); + dump_data_pw("ntlmv2 clear data\n", data, length); } else { - dump_data_pw("ntlmssp hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); - NTLMSSPcalc_ap(ntlmssp_state->ntlmssp_hash, data, length); + smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, data, length); + dump_data_pw("ntlmv1 clear data\n", data, length); } - dump_data_pw("ntlmssp clear data\n", data, length); - - return ntlmssp_check_packet(ntlmssp_state, data, length, sig); + return ntlmssp_check_packet(ntlmssp_state, data, length, whole_pdu, pdu_length, sig); } /** @@ -326,6 +339,7 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { + DATA_BLOB weak_session_key = ntlmssp_state->session_key; const char *send_sign_const; const char *send_seal_const; const char *recv_sign_const; @@ -352,62 +366,96 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) break; } - calc_ntlmv2_hash(ntlmssp_state->send_sign_hash, - ntlmssp_state->send_sign_const, - ntlmssp_state->session_key, send_sign_const); - dump_data_pw("NTLMSSP send sign hash:\n", - ntlmssp_state->send_sign_hash, - sizeof(ntlmssp_state->send_sign_hash)); - - calc_ntlmv2_hash(ntlmssp_state->send_seal_hash, - ntlmssp_state->send_seal_const, - ntlmssp_state->session_key, send_seal_const); - dump_data_pw("NTLMSSP send sesl hash:\n", - ntlmssp_state->send_seal_hash, - sizeof(ntlmssp_state->send_seal_hash)); - - calc_ntlmv2_hash(ntlmssp_state->recv_sign_hash, - ntlmssp_state->recv_sign_const, - ntlmssp_state->session_key, recv_sign_const); - dump_data_pw("NTLMSSP receive sign hash:\n", - ntlmssp_state->recv_sign_hash, - sizeof(ntlmssp_state->recv_sign_hash)); - - calc_ntlmv2_hash(ntlmssp_state->recv_seal_hash, - ntlmssp_state->recv_seal_const, - ntlmssp_state->session_key, recv_seal_const); - dump_data_pw("NTLMSSP receive seal hash:\n", - ntlmssp_state->recv_sign_hash, - sizeof(ntlmssp_state->recv_sign_hash)); - - } - else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 8) { - /* can't sign or check signatures yet */ - DEBUG(5, ("NTLMSSP Sign/Seal - cannot use LM KEY yet\n")); - return NT_STATUS_UNSUCCESSFUL; + /** + Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions. + We probably should have some parameters to control this, once we get NTLM2 working. + */ + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { + ; + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { + weak_session_key.length = 6; + } else { /* forty bits */ + weak_session_key.length = 5; } + + dump_data_pw("NTLMSSP weakend master key:\n", + weak_session_key.data, + weak_session_key.length); + + /* SEND */ + calc_ntlmv2_key(ntlmssp_state->send_sign_key, + ntlmssp_state->session_key, send_sign_const); + dump_data_pw("NTLMSSP send sign key:\n", + ntlmssp_state->send_sign_key, 16); + + calc_ntlmv2_key(ntlmssp_state->send_seal_key, + weak_session_key, send_seal_const); + dump_data_pw("NTLMSSP send seal key:\n", + ntlmssp_state->send_seal_key, 16); + + smb_arc4_init(ntlmssp_state->send_seal_arc4_state, + ntlmssp_state->send_seal_key, 16); + + dump_data_pw("NTLMSSP send seal arc4 state:\n", + ntlmssp_state->send_seal_arc4_state, + sizeof(ntlmssp_state->send_seal_arc4_state)); + + /* RECV */ + calc_ntlmv2_key(ntlmssp_state->recv_sign_key, + ntlmssp_state->session_key, recv_sign_const); + dump_data_pw("NTLMSSP recv send sign key:\n", + ntlmssp_state->recv_sign_key, 16); + + calc_ntlmv2_key(ntlmssp_state->recv_seal_key, + weak_session_key, recv_seal_const); - DEBUG(5, ("NTLMSSP Sign/Seal - using LM KEY\n")); + dump_data_pw("NTLMSSP recv seal key:\n", + ntlmssp_state->recv_seal_key, 16); + + smb_arc4_init(ntlmssp_state->recv_seal_arc4_state, + ntlmssp_state->recv_seal_key, 16); + + dump_data_pw("NTLMSSP recv seal arc4 state:\n", + ntlmssp_state->recv_seal_arc4_state, + sizeof(ntlmssp_state->recv_seal_arc4_state)); + + ntlmssp_state->ntlm2_send_seq_num = 0; + ntlmssp_state->ntlm2_recv_seq_num = 0; + - calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 8); - dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); } else { - if (!ntlmssp_state->session_key.data || ntlmssp_state->session_key.length < 16) { - /* can't sign or check signatures yet */ - DEBUG(5, ("NTLMSSP Sign/Seal - cannot use NT KEY yet\n")); - return NT_STATUS_UNSUCCESSFUL; +#if 0 + /* Hmmm. Shouldn't we also weaken keys for ntlmv1 ? JRA. */ + + DATA_BLOB weak_session_key = ntlmssp_state->session_key; + /** + Weaken NTLMSSP keys to cope with down-level clients, servers and export restrictions. + We probably should have some parameters to control this, once we get NTLM2 working. + */ + + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { + ; + } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { + weak_session_key.length = 6; + } else { /* forty bits */ + weak_session_key.length = 5; } - - DEBUG(5, ("NTLMSSP Sign/Seal - using NT KEY\n")); + dump_data_pw("NTLMSSP weakend master key:\n", + weak_session_key.data, + weak_session_key.length); +#endif - calc_hash(ntlmssp_state->ntlmssp_hash, ntlmssp_state->session_key.data, 16); - dump_data_pw("NTLMSSP hash:\n", ntlmssp_state->ntlmssp_hash, - sizeof(ntlmssp_state->ntlmssp_hash)); - } + DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); + + smb_arc4_init(ntlmssp_state->ntlmv1_arc4_state, + ntlmssp_state->session_key.data, ntlmssp_state->session_key.length); - ntlmssp_state->ntlmssp_seq_num = 0; + dump_data_pw("NTLMv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state, + sizeof(ntlmssp_state->ntlmv1_arc4_state)); + + ntlmssp_state->ntlmv1_seq_num = 0; + } return NT_STATUS_OK; } diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 8bce9c86a1..b104a4678d 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -21,16 +21,17 @@ #include "includes.h" /************************************************************* -change a password on a remote machine using IPC calls + Change a password on a remote machine using IPC calls. *************************************************************/ + BOOL remote_password_change(const char *remote_machine, const char *user_name, const char *old_passwd, const char *new_passwd, char *err_str, size_t err_str_len) { struct nmb_name calling, called; struct cli_state cli; + struct rpc_pipe_client *pipe_hnd; struct in_addr ip; - struct ntuser_creds creds; NTSTATUS result; @@ -85,11 +86,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - init_creds(&creds, "", "", NULL); - cli_init_creds(&cli, &creds); + cli_init_creds(&cli, "", "", NULL); } else { - init_creds(&creds, user_name, "", old_passwd); - cli_init_creds(&cli, &creds); + cli_init_creds(&cli, user_name, "", old_passwd); } if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { @@ -99,14 +98,19 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } - /* Try not to give the password away to easily */ + /* Try not to give the password away too easily */ - cli.pipe_auth_flags = AUTH_PIPE_NTLMSSP; - cli.pipe_auth_flags |= AUTH_PIPE_SIGN; - cli.pipe_auth_flags |= AUTH_PIPE_SEAL; - - if ( !cli_nt_session_open( &cli, PI_SAMR ) ) { + pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli, + PI_SAMR, + PIPE_AUTH_LEVEL_PRIVACY, + "", /* what domain... ? */ + user_name, + old_passwd, + &result); + + if (!pipe_hnd) { if (lp_client_lanman_auth()) { + /* Use the old RAP method. */ if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", remote_machine, cli_errstr(&cli) ); @@ -114,14 +118,16 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, return False; } } else { - slprintf(err_str, err_str_len-1, "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", - remote_machine); + slprintf(err_str, err_str_len-1, + "SAMR connection to machine %s failed. Error was %s, " + "but LANMAN password changed are disabled\n", + nt_errstr(result), remote_machine); cli_shutdown(&cli); return False; } } - if (NT_STATUS_IS_OK(result = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name, + if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli.mem_ctx, user_name, new_passwd, old_passwd))) { /* Great - it all worked! */ cli_shutdown(&cli); @@ -138,25 +144,25 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, } /* OK, that failed, so try again... */ - cli_nt_session_close(&cli); + cli_rpc_pipe_close(pipe_hnd); /* Try anonymous NTLMSSP... */ - init_creds(&creds, "", "", NULL); - cli_init_creds(&cli, &creds); + cli_init_creds(&cli, "", "", NULL); - cli.pipe_auth_flags = 0; - result = NT_STATUS_UNSUCCESSFUL; - /* OK, this is ugly, but... */ - if ( cli_nt_session_open( &cli, PI_SAMR ) - && NT_STATUS_IS_OK(result - = cli_samr_chgpasswd_user(&cli, cli.mem_ctx, user_name, - new_passwd, old_passwd))) { + /* OK, this is ugly, but... try an anonymous pipe. */ + pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result); + + if ( pipe_hnd && + (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, + cli.mem_ctx, + user_name, + new_passwd, + old_passwd)))) { /* Great - it all worked! */ cli_shutdown(&cli); return True; - } else { if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { @@ -173,6 +179,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, just might not support SAMR password changes, so fall back */ if (lp_client_lanman_auth()) { + /* Use the old RAP method. */ if (cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { /* SAMR failed, but the old LanMan protocol worked! */ @@ -185,9 +192,10 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, cli_shutdown(&cli); return False; } else { - slprintf(err_str, err_str_len-1, - "machine %s does not support SAMR connections, but LANMAN password changed are disabled\n", - remote_machine); + slprintf(err_str, err_str_len-1, + "SAMR connection to machine %s failed. Error was %s, " + "but LANMAN password changed are disabled\n", + nt_errstr(result), remote_machine); cli_shutdown(&cli); return False; } diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index e010f226a0..a0f3383e29 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -60,4 +60,3 @@ void pwd_get_cleartext(struct pwd_info *pwd, fstring clr) clr[0] = 0; } - diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 87a386307c..7659d1cd6e 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -55,6 +55,12 @@ struct smbdb_ctx *smb_share_mode_db_open(const char *db_path) return smb_db; } +/* key and data records in the tdb locking database */ +struct locking_key { + SMB_DEV_T dev; + SMB_INO_T inode; +}; + int smb_share_mode_db_close(struct smbdb_ctx *db_ctx) { int ret = tdb_close(db_ctx->smb_tdb); @@ -102,10 +108,10 @@ struct locking_data { int num_share_mode_entries; BOOL delete_on_close; } s; - share_mode_entry dummy; /* Needed for alignment. */ + struct share_mode_entry dummy; /* Needed for alignment. */ } u; /* the following two entries are implicit - share_mode_entry modes[num_share_mode_entries]; + struct share_mode_entry modes[num_share_mode_entries]; char file_name[]; */ }; @@ -114,9 +120,9 @@ struct locking_data { * Check if an external smb_share_mode_entry and an internal share_mode entry match. */ -static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const share_mode_entry *entry) +static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const struct share_mode_entry *entry) { - return (e_entry->pid == entry->pid && + return (procid_equal(&e_entry->pid, &entry->pid) && e_entry->file_id == (uint32_t)entry->share_file_id && e_entry->open_time.tv_sec == entry->time.tv_sec && e_entry->open_time.tv_usec == entry->time.tv_usec && @@ -130,9 +136,9 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, co * Create an internal Samba share_mode entry from an external smb_share_mode_entry. */ -static void create_share_mode_entry(share_mode_entry *out, const struct smb_share_mode_entry *in) +static void create_share_mode_entry(struct share_mode_entry *out, const struct smb_share_mode_entry *in) { - memset(out, '\0', sizeof(share_mode_entry)); + memset(out, '\0', sizeof(struct share_mode_entry)); out->pid = in->pid; out->share_file_id = (unsigned long)in->file_id; @@ -159,7 +165,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, struct smb_share_mode_entry *list = NULL; int num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ - share_mode_entry *shares = NULL; + struct share_mode_entry *shares = NULL; size_t i; int list_num; @@ -187,19 +193,24 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, memset(list, '\0', num_share_modes * sizeof(struct smb_share_mode_entry)); - shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry)); + shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); list_num = 0; for (i = 0; i < num_share_modes; i++) { - share_mode_entry *share = &shares[i]; + struct share_mode_entry *share = &shares[i]; struct smb_share_mode_entry *sme = &list[list_num]; - pid_t pid = share->pid; + struct process_id pid = share->pid; /* Check this process really exists. */ - if (kill(pid, 0) == -1 && (errno == ESRCH)) { + if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { continue; /* No longer exists. */ } + /* Ignore deferred open entries. */ + if (share->op_type == DEFERRED_OPEN_ENTRY) { + continue; + } + /* Copy into the external list. */ sme->dev = (uint64_t)share->dev; sme->ino = (uint64_t)share->inode; @@ -238,27 +249,27 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, TDB_DATA locking_key = get_locking_key(dev, ino); int orig_num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ - share_mode_entry *shares = NULL; + struct share_mode_entry *shares = NULL; char *new_data_p = NULL; size_t new_data_size = 0; db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { /* We must create the entry. */ - db_data.dptr = malloc((2*sizeof(share_mode_entry)) + strlen(filename) + 1); + db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) + strlen(filename) + 1); if (!db_data.dptr) { return -1; } ld = (struct locking_data *)db_data.dptr; ld->u.s.num_share_mode_entries = 1; ld->u.s.delete_on_close = 0; - shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry)); + shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); create_share_mode_entry(shares, new_entry); - memcpy(db_data.dptr + 2*sizeof(share_mode_entry), + memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry), filename, strlen(filename) + 1); - db_data.dsize = 2*sizeof(share_mode_entry) + strlen(filename) + 1; + db_data.dsize = 2*sizeof(struct share_mode_entry) + strlen(filename) + 1; if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) { free(db_data.dptr); return -1; @@ -268,7 +279,7 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, } /* Entry exists, we must add a new entry. */ - new_data_p = malloc(db_data.dsize + sizeof(share_mode_entry)); + new_data_p = malloc(db_data.dsize + sizeof(struct share_mode_entry)); if (!new_data_p) { free(db_data.dptr); return -1; @@ -278,11 +289,11 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, orig_num_share_modes = ld->u.s.num_share_mode_entries; /* Copy the original data. */ - memcpy(new_data_p, db_data.dptr, (orig_num_share_modes+1)*sizeof(share_mode_entry)); + memcpy(new_data_p, db_data.dptr, (orig_num_share_modes+1)*sizeof(struct share_mode_entry)); /* Add in the new share mode */ - shares = (share_mode_entry *)(new_data_p + - ((orig_num_share_modes+1)*sizeof(share_mode_entry))); + shares = (struct share_mode_entry *)(new_data_p + + ((orig_num_share_modes+1)*sizeof(struct share_mode_entry))); create_share_mode_entry(shares, new_entry); @@ -290,11 +301,11 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, ld->u.s.num_share_mode_entries++; /* Append the original filename */ - memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(share_mode_entry)), - db_data.dptr + ((orig_num_share_modes+1)*sizeof(share_mode_entry)), - db_data.dsize - ((orig_num_share_modes+1) * sizeof(share_mode_entry))); + memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(struct share_mode_entry)), + db_data.dptr + ((orig_num_share_modes+1)*sizeof(struct share_mode_entry)), + db_data.dsize - ((orig_num_share_modes+1) * sizeof(struct share_mode_entry))); - new_data_size = db_data.dsize + sizeof(share_mode_entry); + new_data_size = db_data.dsize + sizeof(struct share_mode_entry); free(db_data.dptr); @@ -318,7 +329,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, TDB_DATA locking_key = get_locking_key(dev, ino); int orig_num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ - share_mode_entry *shares = NULL; + struct share_mode_entry *shares = NULL; char *new_data_p = NULL; size_t filename_size = 0; size_t i, num_share_modes; @@ -331,7 +342,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; orig_num_share_modes = ld->u.s.num_share_mode_entries; - shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry)); + shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); if (orig_num_share_modes == 1) { /* Only one entry - better be ours... */ @@ -346,22 +357,22 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* More than one - allocate a new record minus the one we'll delete. */ - new_data_p = malloc(db_data.dsize - sizeof(share_mode_entry)); + new_data_p = malloc(db_data.dsize - sizeof(struct share_mode_entry)); if (!new_data_p) { free(db_data.dptr); return -1; } /* Copy the header. */ - memcpy(new_data_p, db_data.dptr, sizeof(share_mode_entry)); + memcpy(new_data_p, db_data.dptr, sizeof(struct share_mode_entry)); num_share_modes = 0; for (i = 0; i < orig_num_share_modes; i++) { - share_mode_entry *share = &shares[i]; - pid_t pid = share->pid; + struct share_mode_entry *share = &shares[i]; + struct process_id pid = share->pid; /* Check this process really exists. */ - if (kill(pid, 0) == -1 && (errno == ESRCH)) { + if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { continue; /* No longer exists. */ } @@ -369,8 +380,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, continue; /* This is our delete taget. */ } - memcpy(new_data_p + ((num_share_modes+1)*sizeof(share_mode_entry)), - share, sizeof(share_mode_entry) ); + memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)), + share, sizeof(struct share_mode_entry) ); num_share_modes++; } @@ -383,10 +394,10 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* Copy the terminating filename. */ - fname_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(share_mode_entry)); + fname_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(struct share_mode_entry)); filename_size = db_data.dsize - (fname_ptr - db_data.dptr); - memcpy(new_data_p + ((num_share_modes+1)*sizeof(share_mode_entry)), + memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)), fname_ptr, filename_size); @@ -398,7 +409,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; ld->u.s.num_share_mode_entries = num_share_modes; - db_data.dsize = ((num_share_modes+1)*sizeof(share_mode_entry)) + filename_size; + db_data.dsize = ((num_share_modes+1)*sizeof(struct share_mode_entry)) + filename_size; if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { free(db_data.dptr); @@ -418,7 +429,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, TDB_DATA locking_key = get_locking_key(dev, ino); int num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ - share_mode_entry *shares = NULL; + struct share_mode_entry *shares = NULL; size_t i; int found_entry = 0; @@ -429,14 +440,14 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; num_share_modes = ld->u.s.num_share_mode_entries; - shares = (share_mode_entry *)(db_data.dptr + sizeof(share_mode_entry)); + shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); for (i = 0; i < num_share_modes; i++) { - share_mode_entry *share = &shares[i]; - pid_t pid = share->pid; + struct share_mode_entry *share = &shares[i]; + struct process_id pid = share->pid; /* Check this process really exists. */ - if (kill(pid, 0) == -1 && (errno == ESRCH)) { + if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { continue; /* No longer exists. */ } diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index b7f0cd05c3..dc49396d9e 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -357,78 +357,24 @@ void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, des_crypt56(out + 8, in + 8, key2, forw); } -void SamOEMhash( unsigned char *data, const unsigned char *key, int val) -{ - unsigned char s_box[256]; - unsigned char index_i = 0; - unsigned char index_j = 0; - unsigned char j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) { - s_box[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) { - unsigned char tc; +/***************************************************************** + arc4 crypt/decrypt with a 16 byte key. +*****************************************************************/ - j += (s_box[ind] + key[ind%16]); - - tc = s_box[ind]; - s_box[ind] = s_box[j]; - s_box[j] = tc; - } - for( ind = 0; ind < val; ind++) { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += s_box[index_i]; - - tc = s_box[index_i]; - s_box[index_i] = s_box[index_j]; - s_box[index_j] = tc; +void SamOEMhash( unsigned char *data, const unsigned char key[16], size_t len) +{ + unsigned char arc4_state[258]; - t = s_box[index_i] + s_box[index_j]; - data[ind] = data[ind] ^ s_box[t]; - } + smb_arc4_init(arc4_state, key, 16); + smb_arc4_crypt(arc4_state, data, len); } -void SamOEMhashBlob( unsigned char *data, int len, DATA_BLOB *key) +void SamOEMhashBlob( unsigned char *data, size_t len, DATA_BLOB *key) { - unsigned char s_box[256]; - unsigned char index_i = 0; - unsigned char index_j = 0; - unsigned char j = 0; - int ind; - - for (ind = 0; ind < 256; ind++) { - s_box[ind] = (unsigned char)ind; - } - - for( ind = 0; ind < 256; ind++) { - unsigned char tc; - - j += (s_box[ind] + key->data[ind%key->length]); - - tc = s_box[ind]; - s_box[ind] = s_box[j]; - s_box[j] = tc; - } - for( ind = 0; ind < len; ind++) { - unsigned char tc; - unsigned char t; - - index_i++; - index_j += s_box[index_i]; + unsigned char arc4_state[258]; - tc = s_box[index_i]; - s_box[index_i] = s_box[index_j]; - s_box[index_j] = tc; - - t = s_box[index_i] + s_box[index_j]; - data[ind] = data[ind] ^ s_box[t]; - } + smb_arc4_init(arc4_state, key->data, key->length); + smb_arc4_crypt(arc4_state, data, len); } /* Decode a sam password hash into a password. The password hash is the diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 8361c35a8e..0c9eacfe4c 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -308,32 +308,6 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #endif } -void SMBsesskeygen_lmv1(const uchar lm_hash[16], - const uchar lm_resp[24], /* only uses 8 */ - uint8 sess_key[16]) -{ - /* Calculate the LM session key (effective length 40 bits, - but changes with each session) */ - - uchar p24[24]; - uchar partial_lm_hash[16]; - - memcpy(partial_lm_hash, lm_hash, 8); - memset(partial_lm_hash + 8, 0xbd, 8); - - SMBOWFencrypt(lm_hash, lm_resp, p24); - - memcpy(sess_key, p24, 16); - sess_key[5] = 0xe5; - sess_key[6] = 0x38; - sess_key[7] = 0xb0; - -#ifdef DEBUG_PASSWORD - DEBUG(100, ("SMBsesskeygen_lmv1:\n")); - dump_data(100, sess_key, 16); -#endif -} - void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], const uchar lm_resp[24], /* only uses 8 */ uint8 sess_key[16]) @@ -485,7 +459,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. ************************************************************/ -BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) +BOOL encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags) { uchar new_pw[512]; size_t new_pw_len; @@ -496,7 +470,7 @@ BOOL encode_pw_buffer(char buffer[516], const char *password, int string_flags) memcpy(&buffer[512 - new_pw_len], new_pw, new_pw_len); - generate_random_buffer((unsigned char *)buffer, 512 - new_pw_len); + generate_random_buffer(buffer, 512 - new_pw_len); /* * The length of the new password is in the last 4 bytes of diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index a21063e52a..82a06bde2b 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -75,6 +75,7 @@ err_code_struct dos_msgs[] = { {"ERRlogonfailure",ERRlogonfailure,"Logon failure"}, {"ERRdiskfull",ERRdiskfull,"Disk full"}, {"ERRgeneral",ERRgeneral, "General failure"}, + {"ERRbaddirectory", ERRbaddirectory, "Bad directory name"}, {"ERRunknownlevel",ERRunknownlevel, "Unknown info level"}, {NULL,-1,NULL}}; diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 2eaec61ed7..2cf3480fce 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -42,11 +42,11 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) asn1_start_tag(asn1, ASN1_CONTEXT(0)); asn1_start_tag(asn1, ASN1_SEQUENCE(0)); - token->mechTypes = SMB_MALLOC_P(char *); + token->mechTypes = SMB_MALLOC_P(const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { token->mechTypes = - SMB_REALLOC_ARRAY(token->mechTypes, char *, i + 2); + SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2); asn1_read_OID(asn1, &token->mechTypes[i]); } token->mechTypes[i] = NULL; diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index aab0d7d151..50fa613e72 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -29,22 +29,36 @@ Caller must have the cli connected to the netlogon pipe already. **********************************************************/ -static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ctx, + +static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, unsigned char orig_trust_passwd_hash[16], unsigned char new_trust_passwd_hash[16], uint32 sec_channel_type) { NTSTATUS result; - /* ensure that schannel uses the right domain */ - fstrcpy(cli->domain, lp_workgroup()); - if (! NT_STATUS_IS_OK(result = cli_nt_establish_netlogon(cli, sec_channel_type, orig_trust_passwd_hash))) { - DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", - nt_errstr(result))); - return result; + /* Check if the netlogon pipe is open using schannel. If so we + already have valid creds. If not we must set them up. */ + + if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; + + result = rpccli_netlogon_setup_creds(cli, + cli->cli->desthost, + lp_workgroup(), + global_myname(), + orig_trust_passwd_hash, + sec_channel_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", + nt_errstr(result))); + return result; + } } - - result = cli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); + + result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", @@ -59,7 +73,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_ Caller must have already setup the connection to the NETLOGON pipe **********************************************************/ -NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx, +NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *domain, unsigned char orig_trust_passwd_hash[16], uint32 sec_channel_type) @@ -99,7 +113,7 @@ NTSTATUS trust_pw_change_and_store_it(struct cli_state *cli, TALLOC_CTX *mem_ctx already setup the connection to the NETLOGON pipe **********************************************************/ -NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, +NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *domain) { @@ -116,7 +130,6 @@ NTSTATUS trust_pw_find_change_and_store_it(struct cli_state *cli, return trust_pw_change_and_store_it(cli, mem_ctx, domain, old_trust_passwd_hash, sec_channel_type); - } /********************************************************************* @@ -133,6 +146,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, struct in_addr dc_ip; uint32 enum_ctx = 0; struct cli_state *cli = NULL; + struct rpc_pipe_client *lsa_pipe; BOOL retry; *domain_names = NULL; @@ -156,21 +170,21 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* open the LSARPC_PIPE */ - if ( !cli_nt_session_open( cli, PI_LSARPC ) ) { - result = NT_STATUS_UNSUCCESSFUL; + lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result ); + if ( !lsa_pipe) { goto done; } /* get a handle */ - result = cli_lsa_open_policy(cli, mem_ctx, True, + result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True, POLICY_VIEW_LOCAL_INFORMATION, &pol); if ( !NT_STATUS_IS_OK(result) ) goto done; /* Lookup list of trusted domains */ - result = cli_lsa_enum_trust_dom(cli, mem_ctx, &pol, &enum_ctx, + result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx, num_domains, domain_names, sids); if ( !NT_STATUS_IS_OK(result) ) goto done; @@ -184,4 +198,3 @@ done: return NT_STATUS_IS_OK(result); } - -- cgit From aa0dff680d2ea351a0a21cb86a51cd99887237c4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Oct 2005 09:43:53 +0000 Subject: r10671: Attempt to fix the build on machines without kerberos headers. Volker (This used to be commit cb816e65a95802d5172c410d1acda2da070b871d) --- source3/libsmb/clikrb5.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e3ad5f17cb..df5ad867da 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -642,7 +642,7 @@ failed: #endif } -void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, + void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, PAC_SIGNATURE_DATA *sig) { #ifdef HAVE_CHECKSUM_IN_KRB5_CHECKSUM @@ -656,7 +656,7 @@ void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, #endif } -krb5_error_code smb_krb5_verify_checksum(krb5_context context, + krb5_error_code smb_krb5_verify_checksum(krb5_context context, krb5_keyblock *keyblock, krb5_keyusage usage, krb5_checksum *cksum, @@ -728,7 +728,7 @@ krb5_error_code smb_krb5_verify_checksum(krb5_context context, return ret; } -time_t get_authtime_from_tkt(krb5_ticket *tkt) + time_t get_authtime_from_tkt(krb5_ticket *tkt) { #if defined(HAVE_KRB5_TKT_ENC_PART2) return tkt->enc_part2->times.authtime; @@ -819,7 +819,7 @@ out: return ret; } -void smb_krb5_free_ap_req(krb5_context context, + void smb_krb5_free_ap_req(krb5_context context, krb5_ap_req *ap_req) { #ifdef HAVE_KRB5_FREE_AP_REQ /* MIT */ @@ -836,7 +836,7 @@ void smb_krb5_free_ap_req(krb5_context context, krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); #endif -krb5_error_code smb_krb5_get_keyinfo_from_ap_req(krb5_context context, + krb5_error_code smb_krb5_get_keyinfo_from_ap_req(krb5_context context, const krb5_data *inbuf, krb5_kvno *kvno, krb5_enctype *enctype) @@ -874,7 +874,7 @@ krb5_error_code smb_krb5_get_keyinfo_from_ap_req(krb5_context context, return ret; } -krb5_error_code krb5_rd_req_return_keyblock_from_keytab(krb5_context context, + krb5_error_code krb5_rd_req_return_keyblock_from_keytab(krb5_context context, krb5_auth_context *auth_context, const krb5_data *inbuf, krb5_const_principal server, @@ -930,7 +930,7 @@ out: return ret; } -krb5_error_code smb_krb5_parse_name_norealm(krb5_context context, + krb5_error_code smb_krb5_parse_name_norealm(krb5_context context, const char *name, krb5_principal *principal) { @@ -946,7 +946,7 @@ krb5_error_code smb_krb5_parse_name_norealm(krb5_context context, return krb5_parse_name(context, name, principal); } -BOOL smb_krb5_principal_compare_any_realm(krb5_context context, + BOOL smb_krb5_principal_compare_any_realm(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2) { @@ -983,7 +983,7 @@ BOOL smb_krb5_principal_compare_any_realm(krb5_context context, #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -int cli_krb5_get_ticket(const char *principal, time_t time_offset, + int cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) { DEBUG(0,("NO KERBEROS SUPPORT\n")); -- cgit From 879eb0933efedd900aba336024ebfec75407d373 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 11 Oct 2005 16:27:05 +0000 Subject: r10907: Handle the case when we can't verify the PAC signature because the ticket was encrypted using a DES key (and the Windows KDC still puts CKSUMTYPE_HMAC_MD5_ARCFOUR in the PAC). In that case, return to old behaviour and ignore the PAC. Thanks to Chengjie Liu . Guenther (This used to be commit 48d8a9dd9f573d0d913a26a62e4ad3d224731343) --- source3/libsmb/clikrb5.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index df5ad867da..e87ec32197 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -689,6 +689,12 @@ failed: &input, cksum, &checksum_valid); + if (ret) { + DEBUG(3,("smb_krb5_verify_checksum: krb5_c_verify_checksum() failed: %s\n", + error_message(ret))); + return ret; + } + if (!checksum_valid) ret = KRB5KRB_AP_ERR_BAD_INTEGRITY; } -- cgit From a5b2ec0ba0b13095d5b129ff2f4d3d6e1fea951a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 11 Oct 2005 18:42:25 +0000 Subject: r10909: Give better shutdown messages (This used to be commit 8075b99b44085d107fa42d431300c60133ec53eb) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index ef71a883f7..dd0358f69a 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -66,6 +66,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, + { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, -- cgit From b82981bbc86dbdd057cea9d55e2c0f38f90fa186 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Oct 2005 18:08:25 +0000 Subject: r10970: Fix bug #3166 - null pointer dereference if $HOME not defined. Also clarified confusing error messages. Jeremy. (This used to be commit e2639ac9ff8319dde04fc6b4a0c257f7af29cf44) --- source3/libsmb/libsmbclient.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 1e729abb22..9c7376da44 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5539,6 +5539,7 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) if (!smbc_initialized) { /* Do some library wide intialisations the first time we get called */ + BOOL conf_loaded = False; /* Set this to what the user wants */ DEBUGLEVEL = context->debug; @@ -5547,16 +5548,22 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) /* Here we would open the smb.conf file if needed ... */ - home = getenv("HOME"); - - slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - load_interfaces(); /* Load the list of interfaces ... */ in_client = True; /* FIXME, make a param */ - if (!lp_load(conf, True, False, False)) { - + home = getenv("HOME"); + if (home) { + slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); + if (lp_load(conf, True, False, False)) { + conf_loaded = True; + } else { + DEBUG(5, ("Could not load config file: %s\n", + conf)); + } + } + + if (!conf_loaded) { /* * Well, if that failed, try the dyn_CONFIGFILE * Which points to the standard locn, and if that @@ -5565,10 +5572,9 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) */ if (!lp_load(dyn_CONFIGFILE, True, False, False)) { - DEBUG(5, ("Could not load either config file: " - "%s or %s\n", - conf, dyn_CONFIGFILE)); - } else { + DEBUG(5, ("Could not load config file: %s\n", + dyn_CONFIGFILE)); + } else if (home) { /* * We loaded the global config file. Now lets * load user-specific modifications to the -- cgit From daf33dc4fc888b839aa38d1e757ed066edf06996 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 14 Oct 2005 21:59:36 +0000 Subject: r11075: Still working on bug #1828, PPC hell. The PPC client sends the NTLMSSP client and domain strings as Unicode, even when setting flags as OEM. Cope with this. Jeremy. (This used to be commit 458da8987e8f406cdfd5bd602b3c3cf315675725) --- source3/libsmb/ntlmssp.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 6b551e8774..42a4b95e29 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -429,14 +429,31 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, #endif if (request.length) { - if (!msrpc_parse(&request, "CddAA", + BOOL parse_ok = msrpc_parse(&request, "CddAA", "NTLMSSP", &ntlmssp_command, &neg_flags, &cliname, - &domname)) { + &domname); + + if (!parse_ok) { + /* PocketPC 2003 sends the cliname and domname strings in unicode, + but doesn't set the unicode bit. Try with a parse string of "CddUU" */ + SAFE_FREE(cliname); + SAFE_FREE(domname); + parse_ok = msrpc_parse(&request, "CddUU", + "NTLMSSP", + &ntlmssp_command, + &neg_flags, + &cliname, + &domname); + } + + if (!parse_ok) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate:\n")); dump_data(2, (const char *)request.data, request.length); + SAFE_FREE(cliname); + SAFE_FREE(domname); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 1c5c61e3703ffca912f81496324ce82c2f19efa0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Oct 2005 00:46:38 +0000 Subject: r11079: Narrowing down on the #1828 PPC bug. The PPC client sends an initial NTLMSSP negotiate blob of only 16 bytes - no strings added ! (So don't try parsing them). Jeremy. (This used to be commit e15b758f5fa6f500214bb60599a89f3c795c9fed) --- source3/libsmb/ntlmssp.c | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 42a4b95e29..0becc7fdee 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -419,7 +419,6 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, fstring dnsname, dnsdomname; uint32 neg_flags = 0; uint32 ntlmssp_command, chal_flags; - char *cliname=NULL, *domname=NULL; const uint8 *cryptkey; const char *target_name; @@ -429,40 +428,15 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, #endif if (request.length) { - BOOL parse_ok = msrpc_parse(&request, "CddAA", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname); - - if (!parse_ok) { - /* PocketPC 2003 sends the cliname and domname strings in unicode, - but doesn't set the unicode bit. Try with a parse string of "CddUU" */ - SAFE_FREE(cliname); - SAFE_FREE(domname); - parse_ok = msrpc_parse(&request, "CddUU", - "NTLMSSP", - &ntlmssp_command, - &neg_flags, - &cliname, - &domname); - } - - if (!parse_ok) { - DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate:\n")); + if ((request.length < 16) || !msrpc_parse(&request, "Cdd", + "NTLMSSP", + &ntlmssp_command, + &neg_flags)) { + DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n", + (unsigned int)request.length)); dump_data(2, (const char *)request.data, request.length); - SAFE_FREE(cliname); - SAFE_FREE(domname); return NT_STATUS_INVALID_PARAMETER; } - - DEBUG(10, ("ntlmssp_server_negotiate: client = %s, domain = %s\n", - cliname ? cliname : "", domname ? domname : "")); - - SAFE_FREE(cliname); - SAFE_FREE(domname); - debug_ntlmssp_flags(neg_flags); } -- cgit From 846d52efaed2c3272c2327dcded76b2d335d53d2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 17 Oct 2005 16:44:26 +0000 Subject: r11124: Commit Chris' fixes for libmsrpc after the rpc_client rewrite. His comments: I've gotten the libmsrpc code to work with TRUNK. I've put the patch at: www.uoguelph.ca/~cnicholl/libmsrpc_trunk_v1.patch.gz It is from revision 11093. I also fixed a minor bug in the svcctl code, the timeout parameter for all the control functions was working in milliseconds instead of seconds. Also fixed bug in Makefile when building libmsrpc.a (This used to be commit d3a52900ec223316779e59a13cea87ecb500bccc) --- source3/libsmb/libsmbclient.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 9c7376da44..8a8211d34a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -853,27 +853,29 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, return NULL; } + if(pol) { pipe_hnd = cli_rpc_pipe_open_noauth(ipc_cli, PI_LSARPC, &nt_status); - if (!pipe_hnd) { - DEBUG(1, ("cli_nt_session_open fail!\n")); - errno = ENOTSUP; - cli_shutdown(ipc_cli); - return NULL; - } + if (!pipe_hnd) { + DEBUG(1, ("cli_nt_session_open fail!\n")); + errno = ENOTSUP; + cli_shutdown(ipc_cli); + return NULL; + } - /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, - but NT sends 0x2000000 so we might as well do it too. */ + /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, + but NT sends 0x2000000 so we might as well do it too. */ - nt_status = rpccli_lsa_open_policy(pipe_hnd, - ipc_cli->mem_ctx, - True, - GENERIC_EXECUTE_ACCESS, - pol); + nt_status = rpccli_lsa_open_policy(pipe_hnd, + ipc_cli->mem_ctx, + True, + GENERIC_EXECUTE_ACCESS, + pol); - if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, ipc_cli); - cli_shutdown(ipc_cli); - return NULL; + if (!NT_STATUS_IS_OK(nt_status)) { + errno = smbc_errno(context, ipc_cli); + cli_shutdown(ipc_cli); + return NULL; + } } ipc_srv = SMB_MALLOC_P(SMBCSRV); -- cgit From 8d7c88667190fe286971ac4fffb64ee5bd9eeeb0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Oct 2005 03:24:00 +0000 Subject: r11137: Compile with only 2 warnings (I'm still working on that code) on a gcc4 x86_64 box. Jeremy. (This used to be commit d720867a788c735e56d53d63265255830ec21208) --- source3/libsmb/clirap.c | 6 +++--- source3/libsmb/clispnego.c | 2 +- source3/libsmb/credentials.c | 6 +++--- source3/libsmb/ntlm_check.c | 18 +++++++++--------- source3/libsmb/ntlmssp_sign.c | 10 +++++----- source3/libsmb/smbdes.c | 2 +- source3/libsmb/smbencrypt.c | 24 ++++++++++++------------ source3/libsmb/spnego.c | 6 ++++-- source3/libsmb/trusts_util.c | 4 ++-- 9 files changed, 40 insertions(+), 38 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index b53e19ef98..34f73cfafe 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -294,7 +294,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char const char *old_password) { pstring param; - char data[532]; + unsigned char data[532]; char *p = param; unsigned char old_pw_hash[16]; unsigned char new_pw_hash[16]; @@ -332,7 +332,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char #ifdef DEBUG_PASSWORD DEBUG(100,("make_oem_passwd_hash\n")); - dump_data(100, data, 516); + dump_data(100, (char *)data, 516); #endif SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); @@ -350,7 +350,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ - data,data_len,0 /* data, length, max */ + (char *)data,data_len,0 /* data, length, max */ ) == False) { DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", user )); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 33fc265f79..6340a9bdcd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -26,7 +26,7 @@ generate a negTokenInit packet given a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ -DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], +DATA_BLOB spnego_gen_negTokenInit(char guid[16], const char *OIDs[], const char *principal) { diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 3f2dcd850b..edb242df7e 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -115,7 +115,7 @@ void creds_server_init(struct dcinfo *dc, { DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) )); DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) )); - dump_data_pw("creds_server_init: machine pass", mach_pw, 16); + dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16); /* Just in case this isn't already there */ memcpy(dc->mach_pw, mach_pw, 16); @@ -205,14 +205,14 @@ BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRE void creds_client_init(struct dcinfo *dc, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, - const char mach_pw[16], + const unsigned char mach_pw[16], DOM_CHAL *init_chal_out) { dc->sequence = time(NULL); DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) )); DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) )); - dump_data_pw("creds_client_init: machine pass", mach_pw, 16); + dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16); /* Just in case this isn't already there */ memcpy(dc->mach_pw, mach_pw, 16); diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index 26e4c76fd3..212bc19767 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -65,13 +65,13 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, #ifdef DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); + dump_data(100, (const char *)part_passwd, 16); DEBUGADD(100,("Password from client was |\n")); - dump_data(100, nt_response->data, nt_response->length); + dump_data(100, (const char *)nt_response->data, nt_response->length); DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); + dump_data(100, (const char *)sec_blob->data, sec_blob->length); DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, p24, 24); + dump_data(100, (const char *)p24, 24); #endif return (memcmp(p24, nt_response->data, 24) == 0); } @@ -136,15 +136,15 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, #if DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, part_passwd, 16); + dump_data(100, (const char *)part_passwd, 16); DEBUGADD(100,("Password from client was |\n")); - dump_data(100, ntv2_response->data, ntv2_response->length); + dump_data(100, (const char *)ntv2_response->data, ntv2_response->length); DEBUGADD(100,("Variable data from client was |\n")); - dump_data(100, client_key_data.data, client_key_data.length); + dump_data(100, (const char *)client_key_data.data, client_key_data.length); DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, sec_blob->data, sec_blob->length); + dump_data(100, (const char *)sec_blob->data, sec_blob->length); DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, value_from_encryption, 16); + dump_data(100, (const char *)value_from_encryption, 16); #endif data_blob_clear_free(&client_key_data); res = (memcmp(value_from_encryption, client_response, 16) == 0); diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 51023ca356..e41cd6437c 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -43,7 +43,7 @@ static void calc_ntlmv2_key(unsigned char subkey[16], struct MD5Context ctx3; MD5Init(&ctx3); MD5Update(&ctx3, session_key.data, session_key.length); - MD5Update(&ctx3, constant, strlen(constant)+1); + MD5Update(&ctx3, (const unsigned char *)constant, strlen(constant)+1); MD5Final(subkey, &ctx3); } @@ -196,10 +196,10 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, if (local_sig.length != sig->length || memcmp(local_sig.data, sig->data, sig->length) != 0) { DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n")); - dump_data(5, local_sig.data, local_sig.length); + dump_data(5, (const char *)local_sig.data, local_sig.length); DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, sig->data, sig->length); + dump_data(5, (const char *)sig->data, sig->length); DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); data_blob_free(&local_sig); @@ -209,10 +209,10 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, if (local_sig.length != sig->length || memcmp(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) { DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n")); - dump_data(5, local_sig.data, local_sig.length); + dump_data(5, (const char *)local_sig.data, local_sig.length); DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, sig->data, sig->length); + dump_data(5, (const char *)sig->data, sig->length); DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n")); data_blob_free(&local_sig); diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index dc49396d9e..4378385f3f 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -348,7 +348,7 @@ void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char des_crypt56(out, buf, key2, 1); } -void cred_hash3(unsigned char *out, unsigned char *in, const unsigned char *key, int forw) +void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { static unsigned char key2[8]; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 0c9eacfe4c..f99e48a0b9 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -44,9 +44,9 @@ BOOL SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) #ifdef DEBUG_PASSWORD DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); - dump_data(100, (char *)p21, 16); + dump_data(100, (const char *)p21, 16); dump_data(100, (const char *)c8, 8); - dump_data(100, (char *)p24, 24); + dump_data(100, (const char *)p24, 24); #endif return ret; @@ -198,8 +198,8 @@ BOOL ntv2_owf_gen(const uchar owf[16], DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); dump_data(100, (const char *)user, user_byte_len); dump_data(100, (const char *)domain, domain_byte_len); - dump_data(100, owf, 16); - dump_data(100, kr_buf, 16); + dump_data(100, (const char *)owf, 16); + dump_data(100, (const char *)kr_buf, 16); #endif SAFE_FREE(user); @@ -271,9 +271,9 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); - dump_data(100, srv_chal->data, srv_chal->length); - dump_data(100, cli_chal->data, cli_chal->length); - dump_data(100, resp_buf, 16); + dump_data(100, (const char *)srv_chal->data, srv_chal->length); + dump_data(100, (const char *)cli_chal->data, cli_chal->length); + dump_data(100, (const char *)resp_buf, 16); #endif } @@ -290,7 +290,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_ntv2:\n")); - dump_data(100, sess_key, 16); + dump_data(100, (const char *)sess_key, 16); #endif } @@ -304,7 +304,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_ntv1:\n")); - dump_data(100, sess_key, 16); + dump_data(100, (const char *)sess_key, 16); #endif } @@ -324,7 +324,7 @@ void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n")); - dump_data(100, sess_key, 16); + dump_data(100, (const char *)sess_key, 16); #endif } @@ -506,7 +506,7 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, byte_len = IVAL(in_buffer, 512); #ifdef DEBUG_PASSWORD - dump_data(100, in_buffer, 516); + dump_data(100, (const char *)in_buffer, 516); #endif /* Password cannot be longer than the size of the password buffer */ @@ -522,7 +522,7 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (char *)new_pwrd, *new_pw_len); + dump_data(100, (const char *)new_pwrd, *new_pw_len); DEBUG(100,("multibyte len:%d\n", *new_pw_len)); DEBUG(100,("original char len:%d\n", byte_len/2)); #endif diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 2cf3480fce..6cc4436a0c 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -45,9 +45,11 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) token->mechTypes = SMB_MALLOC_P(const char *); for (i = 0; !asn1->has_error && 0 < asn1_tag_remaining(asn1); i++) { + char *p_oid = NULL; token->mechTypes = SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2); - asn1_read_OID(asn1, &token->mechTypes[i]); + asn1_read_OID(asn1, &p_oid); + token->mechTypes[i] = p_oid; } token->mechTypes[i] = NULL; @@ -317,7 +319,7 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego) if (spnego->negTokenInit.mechTypes) { int i; for (i = 0; spnego->negTokenInit.mechTypes[i]; i++) { - free(spnego->negTokenInit.mechTypes[i]); + free(CONST_DISCARD(char *,spnego->negTokenInit.mechTypes[i])); } free(spnego->negTokenInit.mechTypes); } diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 50fa613e72..87d20107fa 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -31,8 +31,8 @@ **********************************************************/ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - unsigned char orig_trust_passwd_hash[16], - unsigned char new_trust_passwd_hash[16], + const unsigned char orig_trust_passwd_hash[16], + const unsigned char new_trust_passwd_hash[16], uint32 sec_channel_type) { NTSTATUS result; -- cgit From cd310c19cefddc799ec5f8b374bc9c5ea9dec5f1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 21 Oct 2005 02:14:23 +0000 Subject: r11240: * fix invalid read reported by valgrind in the spoolss backchannel connection by rewriting spoolss_connect_to_client(). Ensure that we save the cli_state* in the rpc_pipe_client struct. * fix typo in debug message in cli_start_connection" (This used to be commit 18400f96628ffdd332c2fb2aa52b5e9aee5cb3ce) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7ecc769517..8118f073df 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1388,7 +1388,7 @@ again: DEBUG(3,("Connecting to host=%s\n", dest_host)); if (!cli_connect(cli, dest_host, &ip)) { - DEBUG(1,("cli_full_connection: failed to connect to %s (%s)\n", + DEBUG(1,("cli_start_connection: failed to connect to %s (%s)\n", nmb_namestr(&called), inet_ntoa(ip))); cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; -- cgit From cef9443a8761c51be03657b0cdffa16cc29d62b2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 21 Oct 2005 22:48:27 +0000 Subject: r11256: Remove use of long long and strtoll in libsmbclient (we can't assume long long is always there). Removed unused var in new a/c rename code. long long still used in eventlog code but Jerry has promised to fix that. Jeremy. (This used to be commit f46d8470652b8bc5c4b8cac8e96973c6165ab19a) --- source3/libsmb/libsmbclient.c | 61 +++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 31 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 8a8211d34a..f180072a70 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -30,14 +30,13 @@ /* * DOS Attribute values (used internally) */ -typedef struct DOS_ATTR_DESC -{ - int mode; - unsigned long long size; - time_t a_time; - time_t c_time; - time_t m_time; - unsigned long long inode; +typedef struct DOS_ATTR_DESC { + int mode; + SMB_OFF_T size; + time_t a_time; + time_t c_time; + time_t m_time; + SMB_INO_T inode; } DOS_ATTR_DESC; @@ -3738,36 +3737,36 @@ static void dos_attr_parse(SMBCCTX *context, } if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { - dad->size = strtoll(tok+5, NULL, 10); + dad->size = (SMB_OFF_T)atof(tok+5); continue; } if (StrnCaseCmp(tok, "A_TIME:", 7) == 0) { - dad->a_time = strtoll(tok+7, NULL, 10); + dad->a_time = (time_t)strtol(tok+7, NULL, 10); continue; } if (StrnCaseCmp(tok, "C_TIME:", 7) == 0) { - dad->c_time = strtoll(tok+7, NULL, 10); + dad->c_time = (time_t)strtol(tok+7, NULL, 10); continue; } if (StrnCaseCmp(tok, "M_TIME:", 7) == 0) { - dad->m_time = strtoll(tok+7, NULL, 10); + dad->m_time = (time_t)strtol(tok+7, NULL, 10); continue; } if (StrnCaseCmp(tok, "INODE:", 6) == 0) { - dad->inode = strtoll(tok+6, NULL, 10); + dad->inode = (SMB_INO_T)atof(tok+6); continue; } } } - /***************************************************** -retrieve the acls for a file + Retrieve the acls for a file. *******************************************************/ + static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, struct cli_state *ipc_cli, POLICY_HND *pol, char *filename, char *attr_name, char *buf, int bufsize) @@ -4201,8 +4200,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, if (determine_size) { p = talloc_asprintf( ctx, - ",SIZE:%llu", - (unsigned long long) size); + ",SIZE:%.0f", + (double)size); if (!p) { errno = ENOMEM; return -1; @@ -4210,15 +4209,15 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, n = strlen(p); } else { n = snprintf(buf, bufsize, - ",SIZE:%llu", - (unsigned long long) size); + ",SIZE:%.0f", + (double)size); } } else if (StrCaseCmp(name, "size") == 0) { if (determine_size) { p = talloc_asprintf( ctx, - "%llu", - (unsigned long long) size); + "%.0f", + (double)size); if (!p) { errno = ENOMEM; return -1; @@ -4226,8 +4225,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, n = strlen(p); } else { n = snprintf(buf, bufsize, - "%llu", - (unsigned long long) size); + "%.0f", + (double)size); } } @@ -4356,8 +4355,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, if (determine_size) { p = talloc_asprintf( ctx, - ",INODE:%llu", - (unsigned long long) ino); + ",INODE:%.0f", + (double)ino); if (!p) { errno = ENOMEM; return -1; @@ -4365,15 +4364,15 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, n = strlen(p); } else { n = snprintf(buf, bufsize, - ",INODE:%llu", - (unsigned long long) ino); + ",INODE:%.0f", + (double) ino); } } else if (StrCaseCmp(name, "inode") == 0) { if (determine_size) { p = talloc_asprintf( ctx, - "%llu", - (unsigned long long) ino); + "%.0f", + (double) ino); if (!p) { errno = ENOMEM; return -1; @@ -4381,8 +4380,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, n = strlen(p); } else { n = snprintf(buf, bufsize, - "%llu", - (unsigned long long) ino); + "%.0f", + (double) ino); } } -- cgit From a04dd5f4ad14b58664060411dcaeef8a935d3bd8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Oct 2005 20:36:21 +0000 Subject: r11379: Remove external dependencies from sharemodes library. Jeremy. (This used to be commit 7fb05872612c9e1816ac24d25a020073e3b41950) --- source3/libsmb/smb_share_modes.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 7659d1cd6e..40ccf15f94 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -3,6 +3,12 @@ Used by non-Samba products needing access to the Samba share mode db. Copyright (C) Jeremy Allison 2005. + + sharemodes_procid functions (C) Copyright (C) Volker Lendecke 2005 + + ** NOTE! The following LGPL license applies to this module only. + ** This does NOT imply that all of Samba is released + ** under the LGPL This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -27,6 +33,16 @@ #undef malloc #endif +static BOOL sharemodes_procid_equal(const struct process_id *p1, const struct process_id *p2) +{ + return (p1->pid == p2->pid); +} + +static pid_t sharemodes_procid_to_pid(const struct process_id *proc) +{ + return proc->pid; +} + /* * open/close sharemode database. */ @@ -122,7 +138,7 @@ struct locking_data { static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const struct share_mode_entry *entry) { - return (procid_equal(&e_entry->pid, &entry->pid) && + return (sharemodes_procid_equal(&e_entry->pid, &entry->pid) && e_entry->file_id == (uint32_t)entry->share_file_id && e_entry->open_time.tv_sec == entry->time.tv_sec && e_entry->open_time.tv_usec == entry->time.tv_usec && @@ -202,7 +218,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, struct process_id pid = share->pid; /* Check this process really exists. */ - if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { + if (kill(sharemodes_procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { continue; /* No longer exists. */ } @@ -372,7 +388,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, struct process_id pid = share->pid; /* Check this process really exists. */ - if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { + if (kill(sharemodes_procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { continue; /* No longer exists. */ } @@ -447,7 +463,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, struct process_id pid = share->pid; /* Check this process really exists. */ - if (kill(procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { + if (kill(sharemodes_procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { continue; /* No longer exists. */ } -- cgit From 6baec64a7370ff1871f0b806a623b1fc1a898acb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 31 Oct 2005 20:11:58 +0000 Subject: r11420: Fix issue pointed out by Dina Fine . We can only tell at parse time from the wire if an incoming name has wildcards or not. If it's a mangled name and we demangle the demangled name may contain wildcard characters. Ensure these are ignored. Jeremy. (This used to be commit 4cd8e2a96b98ff711905e8c6f416b22440c16062) --- source3/libsmb/clifile.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a7e6fbfe3f..ff42e64143 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1404,19 +1404,29 @@ static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigne char *p; size_t ea_namelen = strlen(ea_name); - data_len = 4 + 4 + ea_namelen + 1 + ea_len; - data = SMB_MALLOC(data_len); - if (!data) { - return False; + if (ea_namelen == 0 && ea_len == 0) { + data_len = 4; + data = SMB_MALLOC(data_len); + if (!data) { + return False; + } + p = data; + SIVAL(p,0,data_len); + } else { + data_len = 4 + 4 + ea_namelen + 1 + ea_len; + data = SMB_MALLOC(data_len); + if (!data) { + return False; + } + p = data; + SIVAL(p,0,data_len); + p += 4; + SCVAL(p, 0, 0); /* EA flags. */ + SCVAL(p, 1, ea_namelen); + SSVAL(p, 2, ea_len); + memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ + memcpy(p+4+ea_namelen+1, ea_val, ea_len); } - p = data; - SIVAL(p,0,data_len); - p += 4; - SCVAL(p, 0, 0); /* EA flags. */ - SCVAL(p, 1, ea_namelen); - SSVAL(p, 2, ea_len); - memcpy(p+4, ea_name, ea_namelen+1); /* Copy in the name. */ - memcpy(p+4+ea_namelen+1, ea_val, ea_len); if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -- cgit From 5678e4abb04e546735bff4907854ca32094a5b71 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Nov 2005 00:03:55 +0000 Subject: r11492: Fix bug #3224 (I hope). Correctly use machine_account_name and client_name when doing netlogon credential setup. Jeremy. (This used to be commit 37e6ef9389041f58eada167239fd022f01c5fecb) --- source3/libsmb/trusts_util.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 87d20107fa..9d94c1d00a 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -44,9 +44,10 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; result = rpccli_netlogon_setup_creds(cli, - cli->cli->desthost, - lp_workgroup(), - global_myname(), + cli->cli->desthost, /* server name */ + lp_workgroup(), /* domain */ + global_myname(), /* client name */ + global_myname(), /* machine account name */ orig_trust_passwd_hash, sec_channel_type, &neg_flags); -- cgit From 6d5757395a0e54245543794d0d6d6d6a32cd857a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Nov 2005 04:21:55 +0000 Subject: r11511: A classic "friday night check-in" :-). This moves much of the Samba4 timezone handling code back into Samba3. Gets rid of "kludge-gmt" and removes the effectiveness of the parameter "time offset" (I can add this back in very easily if needed) - it's no longer being looked at. I'm hoping this will fix the problems people have been having with DST transitions. I'll start comprehensive testing tomorrow, but for now all modifications are done. Splits time get/set functions into srv_XXX and cli_XXX as they need to look at different timezone offsets. Get rid of much of the "efficiency" cruft that was added to Samba back in the day when the C library timezone handling functions were slow. Jeremy. (This used to be commit 414303bc0272f207046b471a0364fa296b67c1f8) --- source3/libsmb/cliconnect.c | 4 ++-- source3/libsmb/clifile.c | 16 ++++++++-------- source3/libsmb/clilist.c | 14 +++++++------- source3/libsmb/cliprint.c | 2 +- source3/libsmb/clirap.c | 24 ++++++++++++------------ 5 files changed, 30 insertions(+), 30 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8118f073df..b352d3572a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1170,7 +1170,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone = SVALS(cli->inbuf,smb_vwv10); cli->serverzone *= 60; /* this time is converted to GMT by make_unix_date */ - cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); + cli->servertime = cli_make_unix_date(cli,cli->inbuf+smb_vwv8); cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); @@ -1178,7 +1178,7 @@ BOOL cli_negprot(struct cli_state *cli) /* the old core protocol */ cli->use_spnego = False; cli->sec_mode = 0; - cli->serverzone = TimeDiff(time(NULL)); + cli->serverzone = get_time_zone(time(NULL)); } cli->max_xmit = MIN(cli->max_xmit, CLI_BUFFER_SIZE); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ff42e64143..443f515665 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1106,15 +1106,15 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, } if (c_time) { - *c_time = make_unix_date2(cli->inbuf+smb_vwv0); + *c_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv0); } if (a_time) { - *a_time = make_unix_date2(cli->inbuf+smb_vwv2); + *a_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv2); } if (m_time) { - *m_time = make_unix_date2(cli->inbuf+smb_vwv4); + *m_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv4); } return True; @@ -1158,7 +1158,7 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, } if (t) { - *t = make_unix_date3(cli->inbuf+smb_vwv1); + *t = cli_make_unix_date3(cli, cli->inbuf+smb_vwv1); } if (attr) { @@ -1189,9 +1189,9 @@ BOOL cli_setattrE(struct cli_state *cli, int fd, cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0, fd); - put_dos_date2(cli->outbuf,smb_vwv1, c_time); - put_dos_date2(cli->outbuf,smb_vwv3, a_time); - put_dos_date2(cli->outbuf,smb_vwv5, m_time); + cli_put_dos_date2(cli, cli->outbuf,smb_vwv1, c_time); + cli_put_dos_date2(cli, cli->outbuf,smb_vwv3, a_time); + cli_put_dos_date2(cli, cli->outbuf,smb_vwv5, m_time); p = smb_buf(cli->outbuf); *p++ = 4; @@ -1228,7 +1228,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0, attr); - put_dos_date3(cli->outbuf,smb_vwv1, t); + cli_put_dos_date3(cli, cli->outbuf,smb_vwv1, t); p = smb_buf(cli->outbuf); *p++ = 4; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a0be40bdc9..e09a6514ad 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -49,9 +49,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); + finfo->ctime = cli_make_unix_date2(cli, p+4); + finfo->atime = cli_make_unix_date2(cli, p+8); + finfo->mtime = cli_make_unix_date2(cli, p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); @@ -70,9 +70,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 2: /* this is what OS/2 uses mostly */ /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); + finfo->ctime = cli_make_unix_date2(cli, p+4); + finfo->atime = cli_make_unix_date2(cli, p+8); + finfo->mtime = cli_make_unix_date2(cli, p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); @@ -380,7 +380,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mode = CVAL(p,21); /* this date is converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date(p+22); + finfo->ctime = cli_make_unix_date(cli, p+22); finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 4a5ee5ae08..5798e94554 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -97,7 +97,7 @@ int cli_print_queue(struct cli_state *cli, fstrcpy(job.user, fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt)); - job.t = make_unix_date3(p + 12); + job.t = cli_make_unix_date3(cli, p + 12); job.size = IVAL(p,16); fstrcpy(job.name,fix_char_ptr(SVAL(p,24), converter, diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 34f73cfafe..172dea4090 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -390,7 +390,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, char *rparam=NULL, *rdata=NULL; int count=8; BOOL ret; - time_t (*date_fn)(void *); + time_t (*date_fn)(struct cli_state *, void *); char *p; p = param; @@ -429,19 +429,19 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, } if (cli->win95) { - date_fn = make_unix_date; + date_fn = cli_make_unix_date; } else { - date_fn = make_unix_date2; + date_fn = cli_make_unix_date2; } if (c_time) { - *c_time = date_fn(rdata+0); + *c_time = date_fn(cli, rdata+0); } if (a_time) { - *a_time = date_fn(rdata+4); + *a_time = date_fn(cli, rdata+4); } if (m_time) { - *m_time = date_fn(rdata+8); + *m_time = date_fn(cli, rdata+8); } if (size) { *size = IVAL(rdata, 12); @@ -471,7 +471,7 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, char *rparam=NULL, *rdata=NULL; int count=8; BOOL ret; - void (*date_fn)(char *buf,int offset,time_t unixdate); + void (*date_fn)(struct cli_state *, char *buf,int offset,time_t unixdate); char *p; memset(param, 0, sizeof(param)); @@ -493,15 +493,15 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, p = data; if (cli->win95) { - date_fn = put_dos_date; + date_fn = cli_put_dos_date; } else { - date_fn = put_dos_date2; + date_fn = cli_put_dos_date2; } /* Add the create, last access, and modification times */ - (*date_fn)(p, 0, c_time); - (*date_fn)(p, 4, a_time); - (*date_fn)(p, 8, m_time); + (*date_fn)(cli, p, 0, c_time); + (*date_fn)(cli, p, 4, a_time); + (*date_fn)(cli, p, 8, m_time); p += 12; /* Skip DataSize and AllocationSize */ -- cgit From f99b429446595944991bd2b3e9f4e6a9dd2c13cb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 Nov 2005 14:16:50 +0000 Subject: r11551: Add a few more initialize_krb5_error_table (This used to be commit d92c83aa42fe64a0e996094d1a983f0279c7c707) --- source3/libsmb/clikrb5.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e87ec32197..67e9f539ad 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -542,6 +542,7 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, ENCTYPE_DES_CBC_CRC, ENCTYPE_NULL}; + initialize_krb5_error_table(); retval = krb5_init_context(&context); if (retval) { DEBUG(1,("cli_krb5_get_ticket: krb5_init_context failed (%s)\n", -- cgit From ce0a1fa159baab4c4bdaac601d0f56e29a406945 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 10 Nov 2005 20:28:23 +0000 Subject: r11652: Reinstate the netsamlogon_cache in order to work around failed query_user calls. This fixes logons to a member of a Samba domain as a user from a trusted AD domain. As per comments on samba-technical, I still need to add (a) cache the PAC info as werll as NTLM net_user_info_3 (b) expire the cache when the SMB session goes away Both Jeremy and Guenther have signed off on the idea. (This used to be commit 0c2bb5ba7b92d9210e7fa9f7b70aa67dfe9faaf4) --- source3/libsmb/samlogon_cache.c | 247 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 247 insertions(+) create mode 100644 source3/libsmb/samlogon_cache.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c new file mode 100644 index 0000000000..ceb7b7c35a --- /dev/null +++ b/source3/libsmb/samlogon_cache.c @@ -0,0 +1,247 @@ +/* + Unix SMB/CIFS implementation. + Net_sam_logon info3 helpers + Copyright (C) Alexander Bokovoy 2002. + Copyright (C) Andrew Bartlett 2002. + Copyright (C) Gerald Carter 2003. + Copyright (C) Tim Potter 2003. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#define NETSAMLOGON_TDB "netsamlogon_cache.tdb" + +static TDB_CONTEXT *netsamlogon_tdb = NULL; + +/*********************************************************************** + open the tdb + ***********************************************************************/ + +BOOL netsamlogon_cache_init(void) +{ + if (!netsamlogon_tdb) { + netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0, + TDB_DEFAULT, O_RDWR | O_CREAT, 0600); + } + + return (netsamlogon_tdb != NULL); +} + + +/*********************************************************************** + Shutdown samlogon_cache database +***********************************************************************/ + +BOOL netsamlogon_cache_shutdown(void) +{ + if(netsamlogon_tdb) + return (tdb_close(netsamlogon_tdb) == 0); + + return True; +} + +/*********************************************************************** + Clear cache getpwnam and getgroups entries from the winbindd cache +***********************************************************************/ +void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) +{ + fstring domain; + TDB_DATA key; + BOOL got_tdb = False; + + /* We may need to call this function from smbd which will not have + winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ + + if (!tdb) { + tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000, + TDB_DEFAULT, O_RDWR, 0600); + if (!tdb) { + DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n")); + return; + } + got_tdb = True; + } + + unistr2_to_ascii(domain, &user->uni_logon_dom, sizeof(domain) - 1); + + /* Clear U/DOMAIN/RID cache entry */ + + asprintf(&key.dptr, "U/%s/%d", domain, user->user_rid); + key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */ + + DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); + + tdb_delete(tdb, key); + + SAFE_FREE(key.dptr); + + /* Clear UG/DOMAIN/RID cache entry */ + + asprintf(&key.dptr, "UG/%s/%d", domain, user->user_rid); + key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */ + + DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); + + tdb_delete(tdb, key); + + SAFE_FREE(key.dptr); + + if (got_tdb) + tdb_close(tdb); +} + +/*********************************************************************** + Store a NET_USER_INFO_3 structure in a tdb for later user + username should be in UTF-8 format +***********************************************************************/ + +BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USER_INFO_3 *user) +{ + TDB_DATA data; + fstring keystr; + prs_struct ps; + BOOL result = False; + DOM_SID user_sid; + time_t t = time(NULL); + + + if (!netsamlogon_cache_init()) { + DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); + return False; + } + + sid_copy( &user_sid, &user->dom_sid.sid ); + sid_append_rid( &user_sid, user->user_rid ); + + /* Prepare key as DOMAIN-SID/USER-RID string */ + slprintf(keystr, sizeof(keystr), "%s", sid_string_static(&user_sid)); + + DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); + + /* only Samba fills in the username, not sure why NT doesn't */ + /* so we fill it in since winbindd_getpwnam() makes use of it */ + + if ( !user->uni_user_name.buffer ) { + init_unistr2( &user->uni_user_name, username, UNI_STR_TERMINATE ); + init_uni_hdr( &user->hdr_user_name, &user->uni_user_name ); + } + + /* Prepare data */ + + prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + + if ( !prs_uint32( "timestamp", &ps, 0, (uint32*)&t ) ) + return False; + + if ( net_io_user_info3("", user, &ps, 0, 3, 0) ) + { + data.dsize = prs_offset( &ps ); + data.dptr = prs_data_p( &ps ); + + if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) + result = True; + + prs_mem_free( &ps ); + } + + return result; +} + +/*********************************************************************** + Retrieves a NET_USER_INFO_3 structure from a tdb. Caller must + free the user_info struct (malloc()'d memory) +***********************************************************************/ + +NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) +{ + NET_USER_INFO_3 *user = NULL; + TDB_DATA data, key; + prs_struct ps; + fstring keystr; + uint32 t; + + if (!netsamlogon_cache_init()) { + DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); + return False; + } + + /* Prepare key as DOMAIN-SID/USER-RID string */ + slprintf(keystr, sizeof(keystr), "%s", sid_string_static(user_sid)); + DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); + key.dptr = keystr; + key.dsize = strlen(keystr)+1; + data = tdb_fetch( netsamlogon_tdb, key ); + + if ( data.dptr ) { + + if ( (user = SMB_MALLOC_P(NET_USER_INFO_3)) == NULL ) + return NULL; + + prs_init( &ps, 0, mem_ctx, UNMARSHALL ); + prs_give_memory( &ps, data.dptr, data.dsize, True ); + + if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) { + prs_mem_free( &ps ); + return False; + } + + if ( !net_io_user_info3("", user, &ps, 0, 3, 0) ) { + SAFE_FREE( user ); + } + + prs_mem_free( &ps ); + +#if 0 /* The netsamlogon cache needs to hang around. Something about + this feels wrong, but it is the only way we can get all of the + groups. The old universal groups cache didn't expire either. + --jerry */ + { + time_t now = time(NULL); + uint32 time_diff; + + /* is the entry expired? */ + time_diff = now - t; + + if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) { + DEBUG(10,("netsamlogon_cache_get: cache entry expired \n")); + tdb_delete( netsamlogon_tdb, key ); + SAFE_FREE( user ); + } +#endif + } + + return user; +} + +BOOL netsamlogon_cache_have(const DOM_SID *user_sid) +{ + TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); + NET_USER_INFO_3 *user = NULL; + BOOL result; + + if (!mem_ctx) + return False; + + user = netsamlogon_cache_get(mem_ctx, user_sid); + + result = (user != NULL); + + talloc_destroy(mem_ctx); + SAFE_FREE(user); + + return result; +} -- cgit From a4d729bdfadfc39fece612fcdd68955c3e3845bb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 11 Nov 2005 03:03:41 +0000 Subject: r11661: Store the INFO3 in the PAC data into the netsamlogon_cache. Also remove the mem_ctx from the netsamlogon_cache_store() API. Guenther, what should we be doing with the other fields in the PAC_LOGON_INFO? (This used to be commit 8bead2d2825015fe41ba7d7401a12c06c29ea7f7) --- source3/libsmb/samlogon_cache.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index ceb7b7c35a..d0469a1a48 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -109,7 +109,7 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) username should be in UTF-8 format ***********************************************************************/ -BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USER_INFO_3 *user) +BOOL netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) { TDB_DATA data; fstring keystr; @@ -117,6 +117,7 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USE BOOL result = False; DOM_SID user_sid; time_t t = time(NULL); + TALLOC_CTX *mem_ctx; if (!netsamlogon_cache_init()) { @@ -142,6 +143,11 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USE /* Prepare data */ + if ( !(mem_ctx = TALLOC_P( NULL, int )) ) { + DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n")); + return False; + } + prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); if ( !prs_uint32( "timestamp", &ps, 0, (uint32*)&t ) ) @@ -157,6 +163,8 @@ BOOL netsamlogon_cache_store(TALLOC_CTX *mem_ctx, const char * username, NET_USE prs_mem_free( &ps ); } + + TALLOC_FREE( mem_ctx ); return result; } @@ -175,7 +183,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user uint32 t; if (!netsamlogon_cache_init()) { - DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); + DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n", NETSAMLOGON_TDB)); return False; } -- cgit From d2fff52b913e9ac192163fb615a59aaa3a247afb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 30 Nov 2005 17:29:33 +0000 Subject: r11975: Fix valgrind error -- bug 3291 (This used to be commit 9a6ce67fbf89ea7fc9eed72776dff4712ba67e2b) --- source3/libsmb/cliconnect.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b352d3572a..ac7d1b1650 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -163,6 +163,7 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) char *p; uint32 capabilities = cli_session_setup_capabilities(cli); + memset(cli->outbuf, '\0', smb_size); set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); -- cgit From 0af6dcacec1831bad1e901383a2c6458e1b0606f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Nov 2005 17:53:21 +0000 Subject: r11976: (Slightly modified) Volker fix for #3293. Use SMBecho instead of chkpath to keep a connection alive. Jeremy. (This used to be commit f1c88de7a28942b6aaa634551dde7a8af91f4de3) --- source3/libsmb/clientgen.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index bc64cc919b..6dc7386c03 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -481,6 +481,7 @@ BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) /**************************************************************************** Send a keepalive packet to the server ****************************************************************************/ + BOOL cli_send_keepalive(struct cli_state *cli) { if (cli->fd == -1) { @@ -495,3 +496,36 @@ BOOL cli_send_keepalive(struct cli_state *cli) } return True; } + +/**************************************************************************** + Send/receive a SMBecho command: ping the server +****************************************************************************/ + +BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) +{ + char *p; + + SMB_ASSERT(length < 1024); + + memset(cli->outbuf,'\0',smb_size); + set_message(cli->outbuf,1,length,True); + SCVAL(cli->outbuf,smb_com,SMBecho); + SSVAL(cli->outbuf,smb_tid,65535); + SSVAL(cli->outbuf,smb_vwv0,1); + cli_setup_packet(cli); + p = smb_buf(cli->outbuf); + memcpy(p, data, length); + p += length; + + cli_setup_bcc(cli, p); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + return False; + } + + if (cli_is_error(cli)) { + return False; + } + return True; +} -- cgit From d1f91f7c723733113b4e9792042101c80dfc064c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Dec 2005 06:46:46 +0000 Subject: r12043: It's amazing the warnings you find when compiling on a 64-bit box with gcc4 and -O6... Fix a bunch of C99 dereferencing type-punned pointer will break strict-aliasing rules errors. Also added prs_int32 (not uint32...) as it's needed in one place. Find places where prs_uint32 was being used to marshall/unmarshall a time_t (a big no no on 64-bits). More warning fixes to come. Thanks to Volker for nudging me to compile like this. Jeremy. (This used to be commit c65b752604f8f58abc4e7ae8514dc2c7f086271c) --- source3/libsmb/climessage.c | 2 +- source3/libsmb/samlogon_cache.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index f646096a4e..1aa659c1ba 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -85,7 +85,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) p = smb_buf(cli->outbuf); *p++ = 1; - if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **) &msgdos, True)) < 0 || !msgdos) { + if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **)(void *)&msgdos, True)) < 0 || !msgdos) { DEBUG(3,("Conversion failed, sending message in UNIX charset\n")); SSVAL(p, 0, len); p += 2; memcpy(p, msg, len); diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index d0469a1a48..ef60055cf4 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -150,8 +150,12 @@ BOOL netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - if ( !prs_uint32( "timestamp", &ps, 0, (uint32*)&t ) ) - return False; + { + uint32 ts; + if ( !prs_uint32( "timestamp", &ps, 0, &ts ) ) + return False; + t = (time_t)ts; + } if ( net_io_user_info3("", user, &ps, 0, 3, 0) ) { -- cgit From a54f9eddcea6497451dd6c720e9804ad5c6f3ad7 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 5 Dec 2005 23:30:40 +0000 Subject: r12080: r10673@cabra: derrell | 2005-12-05 13:22:34 -0500 Correct some memory and file descriptor leaks. This should fix bugs 3257, 3267 and 3273. (This used to be commit c5781c9cf5f1f8297e084fbe2c4a22257420a447) --- source3/libsmb/libsmbclient.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f180072a70..f482c9584f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -584,9 +584,25 @@ SMBCSRV *smbc_server(SMBCCTX *context, return NULL; } +#if 0 /* choice 1 */ + /* Look for a cached connection, using the provided authinfo */ srv = find_server(context, server, share, workgroup, username, password); + /* If we didn't find one... */ + if (! srv) + { + /* ... then see if there's one using anonymous login */ + fstring anonymous = ""; + srv = find_server(context, server, share, + workgroup, anonymous, password); + } +#else + /* Look for a cached connection */ + srv = find_server(context, server, share, + workgroup, username, password); +#endif + /* * If we found a connection and we're only allowed one share per * server... @@ -780,7 +796,11 @@ SMBCSRV *smbc_server(SMBCCTX *context, /* now add it to the cache (internal or external) */ /* Let the cache function set errno if it wants to */ errno = 0; +#if 0 /* choice 2 */ if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username_used)) { +#else + if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { +#endif int saved_errno = errno; DEBUG(3, (" Failed to add server to cache\n")); errno = saved_errno; @@ -2169,6 +2189,7 @@ list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *stat /* Found the end of the list. Remove it. */ dir->dir_end = dir_list; free(dir_list->next); + free(dirent); dir_list->next = NULL; break; } @@ -2337,7 +2358,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) * a single master browser. */ + ip_list = NULL; if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + + SAFE_FREE(ip_list); + if (!find_master_ip(workgroup, &server_addr.ip)) { errno = ENOENT; @@ -2383,9 +2408,16 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, (void *)dir)) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + continue; } } + + SAFE_FREE(ip_list); } else { /* * Server not an empty string ... Check the rest and see what -- cgit From 78631d38f11a631fe4added2b76deb60a3d835ab Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 5 Dec 2005 23:30:45 +0000 Subject: r12081: r10674@cabra: derrell | 2005-12-05 13:31:28 -0500 get rid of temporary #if 0 blocks (This used to be commit 376445c90b05c36206c87c974c13e5f9297f35eb) --- source3/libsmb/libsmbclient.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f482c9584f..9fda48a540 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -584,24 +584,9 @@ SMBCSRV *smbc_server(SMBCCTX *context, return NULL; } -#if 0 /* choice 1 */ - /* Look for a cached connection, using the provided authinfo */ - srv = find_server(context, server, share, - workgroup, username, password); - - /* If we didn't find one... */ - if (! srv) - { - /* ... then see if there's one using anonymous login */ - fstring anonymous = ""; - srv = find_server(context, server, share, - workgroup, anonymous, password); - } -#else /* Look for a cached connection */ srv = find_server(context, server, share, workgroup, username, password); -#endif /* * If we found a connection and we're only allowed one share per @@ -796,11 +781,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, /* now add it to the cache (internal or external) */ /* Let the cache function set errno if it wants to */ errno = 0; -#if 0 /* choice 2 */ - if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username_used)) { -#else if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { -#endif int saved_errno = errno; DEBUG(3, (" Failed to add server to cache\n")); errno = saved_errno; -- cgit From 44293df2aeaeccb1e2cca18bb7d61534a5e07b1a Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 6 Dec 2005 17:09:44 +0000 Subject: r12098: r10797@cabra: derrell | 2005-12-06 12:09:00 -0500 fixed another memory leak and reverted an (incorrect) fix from yesterday (This used to be commit 8a86d7bddc291da094d060fbe185f071ffdbddd8) --- source3/libsmb/libsmbclient.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 9fda48a540..e6906eb79a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -483,6 +483,8 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); context->callbacks.remove_cached_srv_fn(context, srv); + + SAFE_FREE(srv); return 0; } @@ -822,9 +824,9 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, SMBCSRV *ipc_srv=NULL; /* - * See if we've already created this special connection. Reference our - * "special" share name '*IPC$', which is an impossible real share name - * due to the leading asterisk. + * See if we've already created this special connection. Reference + * our "special" share name '*IPC$', which is an impossible real share + * name due to the leading asterisk. */ ipc_srv = find_server(context, server, "*IPC$", workgroup, username, password); @@ -2386,9 +2388,11 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) /* Now, list the stuff ... */ - if (!cli_NetServerEnum(&srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, + if (!cli_NetServerEnum(&srv->cli, + workgroup, + SV_TYPE_DOMAIN_ENUM, + list_unique_wg_fn, (void *)dir)) { - if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); -- cgit From 83b987befdbba857131102700d237728784b6f69 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Dec 2005 23:06:38 +0000 Subject: r12107: Move to a tdb-based wins database. At the moment we still use it as though it were an in-memory db and dump out to a flat file every 2 mins, but that can now change. Jeremy. (This used to be commit a342681792724c1ae8561ba8d352c4ee6e2a5332) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 164f85be7b..4d84d7bc49 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -331,7 +331,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) Useful for debugging messages. ******************************************************************/ -char *nmb_namestr(struct nmb_name *n) +char *nmb_namestr(const struct nmb_name *n) { static int i=0; static fstring ret[4]; -- cgit From e48ef5b9b1a2d4735d2316f0852c464df1299647 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 8 Dec 2005 03:41:19 +0000 Subject: r12118: r10805@cabra: derrell | 2005-12-07 22:34:55 -0500 first go at supporting long file names. seeems to work; requires more testing (This used to be commit 99fbe44ac569f218bd1b4d1026c18cc72f0a1f0e) --- source3/libsmb/libsmbclient.c | 113 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 101 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index e6906eb79a..28e8ab4d34 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -855,8 +855,10 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, return NULL; } - if(pol) { - pipe_hnd = cli_rpc_pipe_open_noauth(ipc_cli, PI_LSARPC, &nt_status); + if (pol) { + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_cli, + PI_LSARPC, + &nt_status); if (!pipe_hnd) { DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; @@ -864,14 +866,18 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, return NULL; } - /* Some systems don't support SEC_RIGHTS_MAXIMUM_ALLOWED, - but NT sends 0x2000000 so we might as well do it too. */ + /* + * Some systems don't support + * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 + * so we might as well do it too. + */ - nt_status = rpccli_lsa_open_policy(pipe_hnd, - ipc_cli->mem_ctx, - True, - GENERIC_EXECUTE_ACCESS, - pol); + nt_status = rpccli_lsa_open_policy( + pipe_hnd, + ipc_cli->mem_ctx, + True, + GENERIC_EXECUTE_ACCESS, + pol); if (!NT_STATUS_IS_OK(nt_status)) { errno = smbc_errno(context, ipc_cli); @@ -2236,6 +2242,83 @@ dir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state) } +static int +net_share_enum_rpc(struct cli_state *cli, + void (*fn)(const char *name, + uint32 type, + const char *comment, + void *state), + void *state) +{ + int i; + WERROR result; + NTSTATUS nt_status; + ENUM_HND enum_hnd; + uint32 info_level = 1; + uint32 preferred_len = 0xffffffff; + SRV_SHARE_INFO_CTR ctr; + fstring name = ""; + fstring comment = ""; + void *mem_ctx; + struct rpc_pipe_client *pipe_hnd; + + /* Open the server service pipe */ + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); + if (!pipe_hnd) { + DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); + return -1; + } + + /* Allocate a context for parsing and for the entries in "ctr" */ + mem_ctx = talloc_init("libsmbclient: net_share_enum_rpc"); + if (mem_ctx == NULL) { + DEBUG(0, ("out of memory for net_share_enum_rpc!\n")); + return -1; + } + + /* Issue the NetShareEnum RPC call and retrieve the response */ + init_enum_hnd(&enum_hnd, 0); + result = rpccli_srvsvc_net_share_enum(pipe_hnd, + mem_ctx, + info_level, + &ctr, + preferred_len, + &enum_hnd); + + /* Was it successful? */ + if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { + /* Nope. Go clean up. */ + goto done; + } + + /* For each returned entry... */ + for (i = 0; i < ctr.num_entries; i++) { + + /* pull out the share name */ + rpcstr_pull_unistr2_fstring( + name, &ctr.share.info1[i].info_1_str.uni_netname); + + /* pull out the share's comment */ + rpcstr_pull_unistr2_fstring( + comment, &ctr.share.info1[i].info_1_str.uni_remark); + + /* Add this share to the list */ + (*fn)(name, SMBC_FILE_SHARE, comment, state); + } + + /* We're done with the pipe */ + cli_rpc_pipe_close(pipe_hnd); + +done: + /* Free all memory which was allocated for this request */ + talloc_free(mem_ctx); + + /* Tell 'em if it worked */ + return W_ERROR_IS_OK(result) ? 0 : -1; +} + + + static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, options; @@ -2499,9 +2582,15 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) /* Now, list the servers ... */ - if (cli_RNetShareEnum(&srv->cli, list_fn, - (void *)dir) < 0) { - + if (net_share_enum_rpc( + &srv->cli, + list_fn, + (void *) dir) < 0 && + cli_RNetShareEnum( + &srv->cli, + list_fn, + (void *)dir) < 0) { + errno = cli_errno(&srv->cli); if (dir) { SAFE_FREE(dir->fname); -- cgit From 7bf8de2f02099705f4baddb2b581afa37bff9cb6 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 8 Dec 2005 03:44:40 +0000 Subject: r12119: r10812@cabra: derrell | 2005-12-07 22:44:26 -0500 sync to repository didn't work correctly...??? (This used to be commit 86ab4cf42b3bfe78239ee0b367bff9cfc5484107) --- source3/libsmb/libsmbclient.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 28e8ab4d34..32282cb6a6 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2476,11 +2476,6 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, (void *)dir)) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - continue; } } -- cgit From a48955306705ac7f045e3726d7097900550bebe3 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sun, 11 Dec 2005 04:21:34 +0000 Subject: r12173: doing some service control work * Add a few new error codes for disabled services * dump some more details about service status in 'net rpc service' * disable the WINS and NetLogon services if not configured in smb.conf Still trying to figure out how to disable the start button on the NetLogon and WINS services. (This used to be commit c0f54eeebc84ec9fab63c5b105511762bcc136be) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index dd0358f69a..253164963a 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -76,6 +76,7 @@ werror_code_struct dos_errs[] = { "WERR_REG_CORRUPT", WERR_REG_CORRUPT }, { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, + { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, { NULL, W_ERROR(0) } }; -- cgit From 7d2771e758d4e8ef0adb45e55775b524de4dba9a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 12 Dec 2005 22:07:36 +0000 Subject: r12203: Add the share path into the sharemode db. This involves revving the minor version number for libsmbsharemodes (we now have a new _ex interface that takes the share path as well as the filename). Needed for #3303. Some code written by SATOH Fumiyasu included in the changes to locking/locking.c. The smbstatus output is a bit of a mess and needs overhauling... Jeremy. (This used to be commit 9d93af713f8520ca506730dd32aa2b994937eaba) --- source3/libsmb/smb_share_modes.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 40ccf15f94..43f25cd378 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -255,11 +255,12 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, * Create an entry in the Samba share mode db. */ -int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, +int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, const struct smb_share_mode_entry *new_entry, - const char *filename) /* Must be abolute utf8 path. */ + const char *sharepath, /* Must be absolute utf8 path. */ + const char *filename) /* Must be relative utf8 path. */ { TDB_DATA db_data; TDB_DATA locking_key = get_locking_key(dev, ino); @@ -272,7 +273,9 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { /* We must create the entry. */ - db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) + strlen(filename) + 1); + db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) + + strlen(sharepath) + 1 + + strlen(filename) + 1); if (!db_data.dptr) { return -1; } @@ -281,11 +284,18 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, ld->u.s.delete_on_close = 0; shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); create_share_mode_entry(shares, new_entry); + memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry), + sharepath, + strlen(sharepath) + 1); + memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry) + + strlen(sharepath) + 1, filename, strlen(filename) + 1); - db_data.dsize = 2*sizeof(struct share_mode_entry) + strlen(filename) + 1; + db_data.dsize = 2*sizeof(struct share_mode_entry) + + strlen(sharepath) + 1 + + strlen(filename) + 1; if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) { free(db_data.dptr); return -1; @@ -336,6 +346,25 @@ int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, return 0; } +/* + * Create an entry in the Samba share mode db. Original interface - doesn't + * Distinguish between share path and filename. Fudge this by using a + * sharepath of / and a relative filename of (filename+1). + */ + +int smb_create_share_mode_entry(struct smbdb_ctx *db_ctx, + uint64_t dev, + uint64_t ino, + const struct smb_share_mode_entry *new_entry, + const char *filename) /* Must be absolute utf8 path. */ +{ + if (*filename != '/') { + abort(); + } + return smb_create_share_mode_entry_ex(db_ctx, dev, ino, new_entry, + "/", &filename[1]); +} + int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, -- cgit From 765daab643c2957297e71b26de515c05b04d244d Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 14 Dec 2005 04:00:58 +0000 Subject: r12225: r11729@cabra: derrell | 2005-12-13 22:59:45 -0500 1. Fix a crash bug which should have reared its ugly head ages ago, but for some reason, remained dormant until recently. The bug pertained to libsmbclient doing a structure assignment of a cli after having opened a pipe. The pipe open code makes a copy of the cli pointer that was passed to it. If the cli is later copied (and that cli pointer that was saved is no longer valid), the pipe code will cause a crash during shutdown or when the copied cli is closed. 2. The 'type' field in enumerated shares was not being set correctly with the new RPC-based mechanism for enumerating shares. (This used to be commit 62a02b8f2a1fcb66881a9c9636e0b27e3049c5a1) --- source3/libsmb/clientgen.c | 12 ++++--- source3/libsmb/libsmbclient.c | 73 +++++++++++++++++++++++++++---------------- 2 files changed, 53 insertions(+), 32 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 6dc7386c03..2f980adcf8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -358,11 +358,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) void cli_rpc_pipe_close(struct rpc_pipe_client *cli) { if (!cli_close(cli->cli, cli->fnum)) { - DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s " - "to machine %s. Error was %s\n", - cli->pipe_name, - cli->cli->desthost, - cli_errstr(cli->cli))); + DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s, " + "fnum 0x%x " + "to machine %s. Error was %s\n", + cli->pipe_name, + (int) cli->fnum, + cli->cli->desthost, + cli_errstr(cli->cli))); } if (cli->auth.cli_auth_data_free_func) { diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 32282cb6a6..ba57c03aba 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -82,7 +82,6 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { /* * Find an lsa pipe handle associated with a cli struct. */ - static struct rpc_pipe_client *find_lsa_pipe_hnd(struct cli_state *ipc_cli) { struct rpc_pipe_client *pipe_hnd; @@ -855,14 +854,27 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, return NULL; } + ipc_srv = SMB_MALLOC_P(SMBCSRV); + if (!ipc_srv) { + errno = ENOMEM; + cli_shutdown(ipc_cli); + return NULL; + } + + ZERO_STRUCTP(ipc_srv); + ipc_srv->cli = *ipc_cli; + + free(ipc_cli); + if (pol) { - pipe_hnd = cli_rpc_pipe_open_noauth(ipc_cli, + pipe_hnd = cli_rpc_pipe_open_noauth(&ipc_srv->cli, PI_LSARPC, &nt_status); if (!pipe_hnd) { DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; - cli_shutdown(ipc_cli); + cli_shutdown(&ipc_srv->cli); + free(ipc_srv); return NULL; } @@ -874,30 +886,18 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, nt_status = rpccli_lsa_open_policy( pipe_hnd, - ipc_cli->mem_ctx, + ipc_srv->cli.mem_ctx, True, GENERIC_EXECUTE_ACCESS, pol); if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, ipc_cli); - cli_shutdown(ipc_cli); + errno = smbc_errno(context, &ipc_srv->cli); + cli_shutdown(&ipc_srv->cli); return NULL; } } - ipc_srv = SMB_MALLOC_P(SMBCSRV); - if (!ipc_srv) { - errno = ENOMEM; - cli_shutdown(ipc_cli); - return NULL; - } - - ZERO_STRUCTP(ipc_srv); - ipc_srv->cli = *ipc_cli; - - free(ipc_cli); - /* now add it to the cache (internal or external) */ errno = 0; /* let cache function set errno if it likes */ @@ -2191,12 +2191,23 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) SMBCFILE *dir = (SMBCFILE *)state; int dirent_type; - /* We need to process the type a little ... */ - + /* + * We need to process the type a little ... + * + * Disk share = 0x00000000 + * Print share = 0x00000001 + * Comms share = 0x00000002 (obsolete?) + * IPC$ share = 0x00000003 + * + * administrative shares: + * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 + */ + if (dir->dir_type == SMBC_FILE_SHARE) { switch (type) { - case 0: /* Directory tree */ + case 0 | 0x80000000: + case 0: dirent_type = SMBC_FILE_SHARE; break; @@ -2208,6 +2219,7 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) dirent_type = SMBC_COMMS_SHARE; break; + case 3 | 0x80000000: case 3: dirent_type = SMBC_IPC_SHARE; break; @@ -2217,7 +2229,9 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) break; } } - else dirent_type = dir->dir_type; + else { + dirent_type = dir->dir_type; + } if (add_dirent(dir, name, comment, dirent_type) < 0) { @@ -2252,15 +2266,16 @@ net_share_enum_rpc(struct cli_state *cli, { int i; WERROR result; - NTSTATUS nt_status; ENUM_HND enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; + uint32 type; SRV_SHARE_INFO_CTR ctr; fstring name = ""; fstring comment = ""; void *mem_ctx; struct rpc_pipe_client *pipe_hnd; + NTSTATUS nt_status; /* Open the server service pipe */ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); @@ -2273,6 +2288,7 @@ net_share_enum_rpc(struct cli_state *cli, mem_ctx = talloc_init("libsmbclient: net_share_enum_rpc"); if (mem_ctx == NULL) { DEBUG(0, ("out of memory for net_share_enum_rpc!\n")); + cli_rpc_pipe_close(pipe_hnd); return -1; } @@ -2302,14 +2318,17 @@ net_share_enum_rpc(struct cli_state *cli, rpcstr_pull_unistr2_fstring( comment, &ctr.share.info1[i].info_1_str.uni_remark); + /* Get the type value */ + type = ctr.share.info1[i].info_1.type; + /* Add this share to the list */ - (*fn)(name, SMBC_FILE_SHARE, comment, state); + (*fn)(name, type, comment, state); } - /* We're done with the pipe */ - cli_rpc_pipe_close(pipe_hnd); - done: + /* Close the server service pipe */ + cli_rpc_pipe_close(pipe_hnd); + /* Free all memory which was allocated for this request */ talloc_free(mem_ctx); -- cgit From 103f72061705ec79f44aa9ec85af0f6468750ae1 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 14 Dec 2005 18:15:54 +0000 Subject: r12235: r11738@cabra: derrell | 2005-12-14 13:15:14 -0500 Ensure that when libsmbclient copies a cli, it prevents the cli from later being freed, by turning off the 'allocated' flag. Change a DEBUG message in pipe_open code from level 0 to level 1 since libsmbclient is now regularly attempting to open a pipe for share enumeration, and falling back to RAP if RPC is unavailable (e.g. win98). We don't want the debug message to display when the pipe open fails, under these normal circumstances. (This used to be commit 965025c057d9e00fb68ea0819e675fcf9ad2f819) --- source3/libsmb/libsmbclient.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ba57c03aba..15210664b0 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -774,6 +774,7 @@ SMBCSRV *smbc_server(SMBCCTX *context, ZERO_STRUCTP(srv); srv->cli = c; + srv->cli.allocated = False; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->no_pathinfo = False; srv->no_pathinfo2 = False; @@ -863,6 +864,7 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, ZERO_STRUCTP(ipc_srv); ipc_srv->cli = *ipc_cli; + ipc_srv->cli.allocated = False; free(ipc_cli); -- cgit From 76796e212c0f1dc7587be138daac9c4ef093db4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Dec 2005 00:10:59 +0000 Subject: r12275: Fix memory leak found by Mikhail Kshevetskiy and followed up by derrell@samba.org. Jeremy. (This used to be commit 5cab88f1444177129bb5521ccc4afd8869e9bf25) --- source3/libsmb/clilist.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e09a6514ad..252dafcfa8 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -271,6 +271,10 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; @@ -278,8 +282,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, continue; } - if (cli_is_error(cli) || !rdata || !rparam) + if (cli_is_error(cli) || !rdata || !rparam) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); break; + } if (total_received == -1) total_received = 0; @@ -297,8 +304,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, ff_lastname = SVAL(p,6); } - if (ff_searchcount == 0) + if (ff_searchcount == 0) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); break; + } /* point to the data bytes */ p = rdata; @@ -332,6 +342,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (!tdl) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); + SAFE_FREE(rdata); + SAFE_FREE(rparam); break; } else { dirlist = tdl; -- cgit From 56b20b83971f94b0692f7e6685b352a76f14ef38 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 25 Dec 2005 02:00:21 +0000 Subject: r12466: r12028@cabra: derrell | 2005-12-24 20:25:38 -0500 parse dates correctly. w_time and m_time were reversed. (This used to be commit 481abfbab40209e087c82eadc15c3697eae0ae5b) --- source3/libsmb/clirap.c | 10 +++++----- source3/libsmb/libsmbclient.c | 6 ++++-- 2 files changed, 9 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 172dea4090..6716971fe2 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -592,18 +592,18 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, if (!rdata || data_len < 22) { return False; } - + if (c_time) { *c_time = interpret_long_date(rdata+0); } if (a_time) { *a_time = interpret_long_date(rdata+8); } - if (m_time) { - *m_time = interpret_long_date(rdata+16); - } if (w_time) { - *w_time = interpret_long_date(rdata+24); + *w_time = interpret_long_date(rdata+16); + } + if (m_time) { + *m_time = interpret_long_date(rdata+24); } if (mode) { *mode = SVAL(rdata, 32); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 15210664b0..623977b39e 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1380,8 +1380,10 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, } if (!srv->no_pathinfo2 && - cli_qpathinfo2(targetcli, targetpath, c_time, a_time, m_time, NULL, - size, mode, ino)) return True; + cli_qpathinfo2(targetcli, targetpath, + c_time, a_time, m_time, NULL, size, mode, ino)) { + return True; + } /* if this is NT then don't bother with the getatr */ if (targetcli->capabilities & CAP_NT_SMBS) { -- cgit From 50a06f76ef3feed4eec032f83ce86e9e207e003d Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 25 Dec 2005 04:17:32 +0000 Subject: r12471: r12038@cabra: derrell | 2005-12-24 23:17:16 -0500 libsmbclient was not loading the global configuration file. This should fix 3336. (This used to be commit 6d7a9ce7a7060b9b397ae77b8b54d3cf25e50e5a) --- source3/libsmb/libsmbclient.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 623977b39e..635f280bee 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5673,6 +5673,11 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) /* Here we would open the smb.conf file if needed ... */ + if (!lp_load(dyn_CONFIGFILE, True, False, False)) { + DEBUG(5, ("Could not load config file: %s\n", + dyn_CONFIGFILE)); + } + load_interfaces(); /* Load the list of interfaces ... */ in_client = True; /* FIXME, make a param */ -- cgit From 3ec1852ae042b7bcc1b9ee58effb44bc49ffc415 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 25 Dec 2005 04:26:59 +0000 Subject: r12472: r12040@cabra: derrell | 2005-12-24 23:26:55 -0500 revert immediately previous change and fix problem correctly. Interfaces were being loaded before all configuration files had been read. *This* should fix byg 3336. (This used to be commit ded5fceef1e9086dcdaba1959f812810f04fe8bc) --- source3/libsmb/libsmbclient.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 635f280bee..d2d45a7228 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5673,13 +5673,6 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) /* Here we would open the smb.conf file if needed ... */ - if (!lp_load(dyn_CONFIGFILE, True, False, False)) { - DEBUG(5, ("Could not load config file: %s\n", - dyn_CONFIGFILE)); - } - - load_interfaces(); /* Load the list of interfaces ... */ - in_client = True; /* FIXME, make a param */ home = getenv("HOME"); @@ -5721,6 +5714,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) } } + load_interfaces(); /* Load the list of interfaces ... */ + reopen_logs(); /* Get logging working ... */ /* -- cgit From a0d20293393f30c99d6593bd1976f11810681f9b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 Dec 2005 10:27:45 +0000 Subject: r12476: Apply some const (This used to be commit a3f102f6c3ada10e74d72944e767b9b263fe83dd) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6340a9bdcd..cc481a066a 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -260,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) +DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; -- cgit From 44db82065acf46f3c35ac754974c983e168e3975 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 25 Dec 2005 21:46:58 +0000 Subject: r12485: r12044@cabra: derrell | 2005-12-25 16:46:47 -0500 When enumerating what could be a server name or a workgroup name, first check for an existing server structure. If none exists, then go through the previous determination of whether it's a serrver or a workgroup. This should avoid doing a NetBIOS name query each time, if we've already connected to the specified server. (While we're at it, clean up indenting and line length in this area of code.) (This used to be commit 85e4cab1d949f1ab9ce04b96de0b8d1c8113df67) --- source3/libsmb/libsmbclient.c | 160 +++++++++++++++++++++++------------------- 1 file changed, 87 insertions(+), 73 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index d2d45a7228..b81dd88424 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2509,10 +2509,10 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) * Server not an empty string ... Check the rest and see what * gives */ - if (share[0] == (char)0) { - - if (path[0] != (char)0) { /* Should not have empty share with path */ + if (*share == '\0') { + if (*path != '\0') { + /* Should not have empty share with path */ errno = EINVAL + 8197; if (dir) { SAFE_FREE(dir->fname); @@ -2522,12 +2522,28 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } - /* Check to see if <1D>, <1B>, or <20> translates */ - /* However, we check to see if is an IP address first */ + /* + * We don't know if is really a server name + * or is a workgroup/domain name. If we already have + * a server structure for it, we'll use it. + * Otherwise, check to see if <1D>, + * <1B>, or <20> translates. We check + * to see if is an IP address first. + */ + + /* See if we have an existing server */ + srv = smbc_server(context, server, "IPC$", + workgroup, user, password); + + /* + * If no existing server and not an IP addr, look for + * LMB or DMB + */ + if (!srv && + !is_ipaddress(server) && + (resolve_name(server, &rem_ip, 0x1d) || /* LMB */ + resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */ - if (!is_ipaddress(server) && /* Not an IP addr so check next */ - (resolve_name(server, &rem_ip, 0x1d) || /* Found LMB */ - resolve_name(server, &rem_ip, 0x1b) )) { /* Found DMB */ fstring buserver; dir->dir_type = SMBC_SERVER; @@ -2535,22 +2551,23 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) /* * Get the backup list ... */ + if (!name_status_find(server, 0, 0, + rem_ip, buserver)) { - - if (!name_status_find(server, 0, 0, rem_ip, buserver)) { - - DEBUG(0, ("Could not get name of local/domain master browser for server %s\n", server)); - errno = EPERM; /* FIXME, is this correct */ + DEBUG(0, ("Could not get name of " + "local/domain master browser " + "for server %s\n", server)); + errno = EPERM; return NULL; } /* - * Get a connection to IPC$ on the server if we do not already have one - */ - - srv = smbc_server(context, buserver, "IPC$", workgroup, user, password); - + * Get a connection to IPC$ on the server if + * we do not already have one + */ + srv = smbc_server(context, buserver, "IPC$", + workgroup, user, password); if (!srv) { DEBUG(0, ("got no contact to IPC$\n")); if (dir) { @@ -2564,8 +2581,8 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) dir->srv = srv; /* Now, list the servers ... */ - - if (!cli_NetServerEnum(&srv->cli, server, 0x0000FFFE, list_fn, + if (!cli_NetServerEnum(&srv->cli, server, + 0x0000FFFE, list_fn, (void *)dir)) { if (dir) { @@ -2573,75 +2590,72 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) SAFE_FREE(dir); } return NULL; - } - } - else { - - if (resolve_name(server, &rem_ip, 0x20)) { - - /* Now, list the shares ... */ - - dir->dir_type = SMBC_FILE_SHARE; - - srv = smbc_server(context, server, "IPC$", workgroup, user, password); - - if (!srv) { + } else if (srv || + (resolve_name(server, &rem_ip, 0x20))) { + + /* If we hadn't found the server, get one now */ + if (!srv) { + srv = smbc_server(context, server, + "IPC$", workgroup, + user, password); + } - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - return NULL; + if (!srv) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; - } + } - dir->srv = srv; + dir->dir_type = SMBC_FILE_SHARE; + dir->srv = srv; - /* Now, list the servers ... */ + /* List the shares ... */ - if (net_share_enum_rpc( - &srv->cli, - list_fn, - (void *) dir) < 0 && - cli_RNetShareEnum( - &srv->cli, - list_fn, - (void *)dir) < 0) { + if (net_share_enum_rpc( + &srv->cli, + list_fn, + (void *) dir) < 0 && + cli_RNetShareEnum( + &srv->cli, + list_fn, + (void *)dir) < 0) { - errno = cli_errno(&srv->cli); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - return NULL; - - } - - } - else { - - errno = ECONNREFUSED; /* Neither the workgroup nor server exists */ - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - return NULL; - - } + errno = cli_errno(&srv->cli); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; + } + } else { + /* Neither the workgroup nor server exists */ + errno = ECONNREFUSED; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + return NULL; } } - else { /* The server and share are specified ... work from there ... */ + else { + /* + * The server and share are specified ... work from + * there ... + */ pstring targetpath; struct cli_state *targetcli; - /* Well, we connect to the server and list the directory */ - + /* We connect to the server and list the directory */ dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, server, share, + workgroup, user, password); if (!srv) { -- cgit From 1d49a2956d3d4edbaccb9be36f00bb3859c7b4f3 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 29 Dec 2005 15:06:53 +0000 Subject: r12569: r12083@cabra: derrell | 2005-12-29 09:39:45 -0500 fix line length and make formatting/indentation more consistent (This used to be commit 3d45023368e651315ff5620345c755c103c91065) --- source3/libsmb/libsmbclient.c | 781 ++++++++++++++++++++++++++++-------------- 1 file changed, 526 insertions(+), 255 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b81dd88424..c4e36012f9 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -82,11 +82,15 @@ static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { /* * Find an lsa pipe handle associated with a cli struct. */ -static struct rpc_pipe_client *find_lsa_pipe_hnd(struct cli_state *ipc_cli) +static struct rpc_pipe_client * +find_lsa_pipe_hnd(struct cli_state *ipc_cli) { struct rpc_pipe_client *pipe_hnd; - for (pipe_hnd = ipc_cli->pipe_list; pipe_hnd; pipe_hnd = pipe_hnd->next) { + for (pipe_hnd = ipc_cli->pipe_list; + pipe_hnd; + pipe_hnd = pipe_hnd->next) { + if (pipe_hnd->pipe_idx == PI_LSARPC) { return pipe_hnd; } @@ -95,8 +99,14 @@ static struct rpc_pipe_client *find_lsa_pipe_hnd(struct cli_state *ipc_cli) return NULL; } -static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file); -static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence); +static int +smbc_close_ctx(SMBCCTX *context, + SMBCFILE *file); +static off_t +smbc_lseek_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t offset, + int whence); extern BOOL in_client; @@ -315,7 +325,9 @@ smbc_parse_path(SMBCCTX *context, if (*p == '/') { strncpy(server, context->workgroup, - (strlen(context->workgroup) < 16)?strlen(context->workgroup):16); + ((strlen(context->workgroup) < 16) + ? strlen(context->workgroup) + : 16)); return 0; } @@ -396,9 +408,15 @@ smbc_parse_path(SMBCCTX *context, /* * Verify that the options specified in a URL are valid */ -static int smbc_check_options(char *server, char *share, char *path, char *options) +static int +smbc_check_options(char *server, + char *share, + char *path, + char *options) { - DEBUG(4, ("smbc_check_options(): server='%s' share='%s' path='%s' options='%s'\n", server, share, path, options)); + DEBUG(4, ("smbc_check_options(): server='%s' share='%s' " + "path='%s' options='%s'\n", + server, share, path, options)); /* No options at all is always ok */ if (! *options) return 0; @@ -410,7 +428,9 @@ static int smbc_check_options(char *server, char *share, char *path, char *optio /* * Convert an SMB error into a UNIX error ... */ -static int smbc_errno(SMBCCTX *context, struct cli_state *c) +static int +smbc_errno(SMBCCTX *context, + struct cli_state *c) { int ret = cli_errno(c); @@ -441,7 +461,9 @@ static int smbc_errno(SMBCCTX *context, struct cli_state *c) * Also useable outside libsmbclient to enable external cache * to do some checks too. */ -int smbc_check_server(SMBCCTX * context, SMBCSRV * server) +static int +smbc_check_server(SMBCCTX * context, + SMBCSRV * server) { if ( send_keepalive(server->cli.fd) == False ) return 1; @@ -456,7 +478,9 @@ int smbc_check_server(SMBCCTX * context, SMBCSRV * server) * * Also useable outside libsmbclient */ -int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) +int +smbc_remove_unused_server(SMBCCTX * context, + SMBCSRV * srv) { SMBCFILE * file; @@ -469,7 +493,8 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) for (file = context->internal->_files; file; file=file->next) { if (file->srv == srv) { /* Still used */ - DEBUG(3, ("smbc_remove_usused_server: %p still used by %p.\n", + DEBUG(3, ("smbc_remove_usused_server: " + "%p still used by %p.\n", srv, file)); return 1; } @@ -488,12 +513,13 @@ int smbc_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) return 0; } -SMBCSRV *find_server(SMBCCTX *context, - const char *server, - const char *share, - fstring workgroup, - fstring username, - fstring password) +static SMBCSRV * +find_server(SMBCCTX *context, + const char *server, + const char *share, + fstring workgroup, + fstring username, + fstring password) { SMBCSRV *srv; int auth_called = 0; @@ -561,10 +587,13 @@ SMBCSRV *find_server(SMBCCTX *context, * info we need, unless the username and password were passed in. */ -SMBCSRV *smbc_server(SMBCCTX *context, - const char *server, const char *share, - fstring workgroup, fstring username, - fstring password) +static SMBCSRV * +smbc_server(SMBCCTX *context, + const char *server, + const char *share, + fstring workgroup, + fstring username, + fstring password) { SMBCSRV *srv=NULL; struct cli_state c; @@ -811,11 +840,14 @@ SMBCSRV *smbc_server(SMBCCTX *context, * Connect to a server for getting/setting attributes, possibly on an existing * connection. This works similarly to smbc_server(). */ -SMBCSRV *smbc_attr_server(SMBCCTX *context, - const char *server, const char *share, - fstring workgroup, - fstring username, fstring password, - POLICY_HND *pol) +static SMBCSRV * +smbc_attr_server(SMBCCTX *context, + const char *server, + const char *share, + fstring workgroup, + fstring username, + fstring password, + POLICY_HND *pol) { struct in_addr ip; struct cli_state *ipc_cli; @@ -927,11 +959,15 @@ SMBCSRV *smbc_attr_server(SMBCCTX *context, * Routine to open() a file ... */ -static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, mode_t mode) +static SMBCFILE * +smbc_open_ctx(SMBCCTX *context, + const char *fname, + int flags, + mode_t mode) { fstring server, share, user, password, workgroup; pstring path; - pstring targetpath; + pstring targetpath; struct cli_state *targetcli; SMBCSRV *srv = NULL; SMBCFILE *file = NULL; @@ -1088,7 +1124,10 @@ static SMBCFILE *smbc_open_ctx(SMBCCTX *context, const char *fname, int flags, m static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ -static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) +static SMBCFILE * +smbc_creat_ctx(SMBCCTX *context, + const char *path, + mode_t mode) { if (!context || !context->internal || @@ -1106,7 +1145,11 @@ static SMBCFILE *smbc_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) * Routine to read() a file ... */ -static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) +static ssize_t +smbc_read_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count) { int ret; fstring server, share, user, password; @@ -1163,7 +1206,8 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t } /*d_printf(">>>read: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path("", &file->srv->cli, path, + &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -1191,14 +1235,20 @@ static ssize_t smbc_read_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t * Routine to write() a file ... */ -static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_t count) +static ssize_t +smbc_write_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count) { int ret; - off_t offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ + off_t offset; fstring server, share, user, password; pstring path, targetpath; struct cli_state *targetcli; + offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ + if (!context || !context->internal || !context->internal->_initialized) { @@ -1236,7 +1286,8 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ } /*d_printf(">>>write: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path("", &file->srv->cli, path, + &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -1262,7 +1313,9 @@ static ssize_t smbc_write_ctx(SMBCCTX *context, SMBCFILE *file, void *buf, size_ * Routine to close() a file ... */ -static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) +static int +smbc_close_ctx(SMBCCTX *context, + SMBCFILE *file) { SMBCSRV *srv; fstring server, share, user, password; @@ -1304,7 +1357,8 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) } /*d_printf(">>>close: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path("", &file->srv->cli, path, + &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -1339,14 +1393,21 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) * Get info from an SMB server on a file. Use a qpathinfo call first * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo */ -static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, - uint16 *mode, SMB_OFF_T *size, - time_t *c_time, time_t *a_time, time_t *m_time, - SMB_INO_T *ino) +static BOOL +smbc_getatr(SMBCCTX * context, + SMBCSRV *srv, + char *path, + uint16 *mode, + SMB_OFF_T *size, + time_t *c_time, + time_t *a_time, + time_t *m_time, + SMB_INO_T *ino) { pstring fixedpath; pstring targetpath; struct cli_state *targetcli; + if (!context || !context->internal || !context->internal->_initialized) { @@ -1376,7 +1437,8 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, { pstring temppath; pstrcpy(temppath, targetpath); - cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath); + cli_dfs_make_full_path(targetpath, targetcli->desthost, + targetcli->share, temppath); } if (!srv->no_pathinfo2 && @@ -1415,9 +1477,10 @@ static BOOL smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, * * "mode" (attributes) parameter may be set to -1 if it is not to be set. */ -static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, - time_t c_time, time_t a_time, time_t m_time, - uint16 mode) +static BOOL +smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, + time_t c_time, time_t a_time, time_t m_time, + uint16 mode) { int fd; int ret; @@ -1544,7 +1607,9 @@ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * Routine to unlink() a file */ - static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) +static int +smbc_unlink_ctx(SMBCCTX *context, + const char *fname) { fstring server, share, user, password, workgroup; pstring path, targetpath; @@ -1640,12 +1705,27 @@ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * Routine to rename() a file */ -static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, - SMBCCTX *ncontext, const char *nname) +static int +smbc_rename_ctx(SMBCCTX *ocontext, + const char *oname, + SMBCCTX *ncontext, + const char *nname) { - fstring server1, share1, server2, share2, user1, user2, password1, password2, workgroup; - pstring path1, path2, targetpath1, targetpath2; - struct cli_state *targetcli1, *targetcli2; + fstring server1; + fstring share1; + fstring server2; + fstring share2; + fstring user1; + fstring user2; + fstring password1; + fstring password2; + fstring workgroup; + pstring path1; + pstring path2; + pstring targetpath1; + pstring targetpath2; + struct cli_state *targetcli1; + struct cli_state *targetcli2; SMBCSRV *srv = NULL; if (!ocontext || !ncontext || @@ -1698,8 +1778,9 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, } fstrcpy(workgroup, ocontext->workgroup); - /* HELP !!! Which workgroup should I use ? Or are they always the same -- Tom */ - srv = smbc_server(ocontext, server1, share1, workgroup, user1, password1); + + srv = smbc_server(ocontext, server1, share1, workgroup, + user1, password1); if (!srv) { return -1; @@ -1721,7 +1802,8 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, } /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ - if (strcmp(targetcli1->desthost, targetcli2->desthost) || strcmp(targetcli1->share, targetcli2->share)) + if (strcmp(targetcli1->desthost, targetcli2->desthost) || + strcmp(targetcli1->share, targetcli2->share)) { /* can't rename across file systems */ @@ -1750,7 +1832,11 @@ static int smbc_rename_ctx(SMBCCTX *ocontext, const char *oname, * A routine to lseek() a file */ -static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int whence) +static off_t +smbc_lseek_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t offset, + int whence) { SMB_OFF_T size; fstring server, share, user, password; @@ -1791,30 +1877,32 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int case SEEK_END: /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ if (smbc_parse_path(context, file->fname, - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + server, sizeof(server), + share, sizeof(share), + path, sizeof(path), + user, sizeof(user), + password, sizeof(password), + NULL, 0)) { + errno = EINVAL; return -1; } /*d_printf(">>>lseek: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path("", &file->srv->cli, path, + &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; } /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ - if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL, - NULL, NULL, NULL)) + if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, + &size, NULL, NULL, NULL, NULL, NULL)) { SMB_OFF_T b_size = size; - if (!cli_getattrE(targetcli, file->cli_fd, NULL, &b_size, NULL, NULL, - NULL)) + if (!cli_getattrE(targetcli, file->cli_fd, + NULL, &b_size, NULL, NULL, NULL)) { errno = EINVAL; return -1; @@ -1838,8 +1926,9 @@ static off_t smbc_lseek_ctx(SMBCCTX *context, SMBCFILE *file, off_t offset, int * Generate an inode number from file name for those things that need it */ -static -ino_t smbc_inode(SMBCCTX *context, const char *name) +static ino_t +smbc_inode(SMBCCTX *context, + const char *name) { if (!context || !context->internal || @@ -1860,9 +1949,12 @@ ino_t smbc_inode(SMBCCTX *context, const char *name) * fstat below. */ -static -int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, - SMB_OFF_T size, int mode) +static int +smbc_setup_stat(SMBCCTX *context, + struct stat *st, + char *fname, + SMB_OFF_T size, + int mode) { st->st_mode = 0; @@ -1906,12 +1998,21 @@ int smbc_setup_stat(SMBCCTX *context, struct stat *st, char *fname, * Routine to stat a file given a name */ -static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) +static int +smbc_stat_ctx(SMBCCTX *context, + const char *fname, + struct stat *st) { SMBCSRV *srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path; - time_t m_time = 0, a_time = 0, c_time = 0; + time_t m_time = 0; + time_t a_time = 0; + time_t c_time = 0; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; @@ -1979,13 +2080,22 @@ static int smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) * Routine to stat a file given an fd */ -static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) +static int +smbc_fstat_ctx(SMBCCTX *context, + SMBCFILE *file, + struct stat *st) { - time_t c_time, a_time, m_time; + time_t c_time; + time_t a_time; + time_t m_time; SMB_OFF_T size; uint16 mode; - fstring server, share, user, password; - pstring path, targetpath; + fstring server; + fstring share; + fstring user; + fstring password; + pstring path; + pstring targetpath; struct cli_state *targetcli; SMB_INO_T ino = 0; @@ -2023,17 +2133,18 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) } /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &file->srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path("", &file->srv->cli, path, + &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - if (!cli_qfileinfo(targetcli, file->cli_fd, - &mode, &size, &c_time, &a_time, &m_time, NULL, &ino)) { - if (!cli_getattrE(targetcli, file->cli_fd, - &mode, &size, &c_time, &a_time, &m_time)) { + if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, + &c_time, &a_time, &m_time, NULL, &ino)) { + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, + &c_time, &a_time, &m_time)) { errno = EINVAL; return -1; @@ -2058,7 +2169,8 @@ static int smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) * We accept the URL syntax explained in smbc_parse_path(), above. */ -static void smbc_remove_dir(SMBCFILE *dir) +static void +smbc_remove_dir(SMBCFILE *dir) { struct smbc_dir_list *d,*f; @@ -2076,7 +2188,11 @@ static void smbc_remove_dir(SMBCFILE *dir) } -static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint32 type) +static int +add_dirent(SMBCFILE *dir, + const char *name, + const char *comment, + uint32 type) { struct smbc_dirent *dirent; int size; @@ -2149,7 +2265,10 @@ static int add_dirent(SMBCFILE *dir, const char *name, const char *comment, uint } static void -list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *state) +list_unique_wg_fn(const char *name, + uint32 type, + const char *comment, + void *state) { SMBCFILE *dir = (SMBCFILE *)state; struct smbc_dir_list *dir_list; @@ -2190,7 +2309,10 @@ list_unique_wg_fn(const char *name, uint32 type, const char *comment, void *stat } static void -list_fn(const char *name, uint32 type, const char *comment, void *state) +list_fn(const char *name, + uint32 type, + const char *comment, + void *state) { SMBCFILE *dir = (SMBCFILE *)state; int dirent_type; @@ -2246,7 +2368,10 @@ list_fn(const char *name, uint32 type, const char *comment, void *state) } static void -dir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state) +dir_list_fn(const char *mnt, + file_info *finfo, + const char *mask, + void *state) { if (add_dirent((SMBCFILE *)state, finfo->name, "", @@ -2342,7 +2467,9 @@ done: -static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) +static SMBCFILE * +smbc_opendir_ctx(SMBCCTX *context, + const char *fname) { fstring server, share, user, password, options; pstring workgroup; @@ -2379,7 +2506,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) return NULL; } - DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' path='%s' options='%s'\n", fname, server, share, path, options)); + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' " + "path='%s' options='%s'\n", + fname, server, share, path, options)); /* Ensure the options are valid */ if (smbc_check_options(server, share, path, options)) { @@ -2463,9 +2592,12 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) } for (i = 0; i < count && i < max_lmb_count; i++) { - DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), inet_ntoa(ip_list[i].ip))); + DEBUG(99, ("Found master browser %d of %d: %s\n", + i+1, MAX(count, max_lmb_count), + inet_ntoa(ip_list[i].ip))); - cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info); + cli = get_ipc_connect_master_ip(&ip_list[i], + workgroup, &u_info); /* cli == NULL is the master browser refused to talk or could not be found */ if ( !cli ) @@ -2474,7 +2606,8 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) fstrcpy(server, cli->desthost); cli_shutdown(cli); - DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); + DEBUG(4, ("using workgroup %s %s\n", + workgroup, server)); /* * For each returned master browser IP address, get a @@ -2674,14 +2807,16 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) p = path + strlen(path); pstrcat(path, "\\*"); - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path("", &srv->cli, path, + &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return NULL; } - if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, - (void *)dir) < 0) { + if (cli_list(targetcli, targetpath, + aDIR | aSYSTEM | aHIDDEN, + dir_list_fn, (void *)dir) < 0) { if (dir) { SAFE_FREE(dir->fname); @@ -2725,7 +2860,9 @@ static SMBCFILE *smbc_opendir_ctx(SMBCCTX *context, const char *fname) * Routine to close a directory */ -static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) +static int +smbc_closedir_ctx(SMBCCTX *context, + SMBCFILE *dir) { if (!context || !context->internal || @@ -2757,10 +2894,11 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) } -static void smbc_readdir_internal(SMBCCTX * context, - struct smbc_dirent *dest, - struct smbc_dirent *src, - int max_namebuf_len) +static void +smbc_readdir_internal(SMBCCTX * context, + struct smbc_dirent *dest, + struct smbc_dirent *src, + int max_namebuf_len) { if (context->options.urlencode_readdir_entries) { @@ -2802,7 +2940,9 @@ static void smbc_readdir_internal(SMBCCTX * context, * Routine to get a directory entry */ -struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) +struct smbc_dirent * +smbc_readdir_ctx(SMBCCTX *context, + SMBCFILE *dir) { int maxlen; struct smbc_dirent *dirp, *dirent; @@ -2861,10 +3001,11 @@ struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir) * Routine to get directory entries */ -static int smbc_getdents_ctx(SMBCCTX *context, - SMBCFILE *dir, - struct smbc_dirent *dirp, - int count) +static int +smbc_getdents_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct smbc_dirent *dirp, + int count) { int rem = count; int reqd; @@ -2962,10 +3103,17 @@ static int smbc_getdents_ctx(SMBCCTX *context, * Routine to create a directory ... */ -static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) +static int +smbc_mkdir_ctx(SMBCCTX *context, + const char *fname, + mode_t mode) { SMBCSRV *srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path, targetpath; struct cli_state *targetcli; @@ -3034,23 +3182,35 @@ static int smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) static int smbc_rmdir_dirempty = True; -static void rmdir_list_fn(const char *mnt, file_info *finfo, const char *mask, void *state) +static void +rmdir_list_fn(const char *mnt, + file_info *finfo, + const char *mask, + void *state) { - - if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0) + if (strncmp(finfo->name, ".", 1) != 0 && + strncmp(finfo->name, "..", 2) != 0) { + smbc_rmdir_dirempty = False; - + } } /* * Routine to remove a directory */ -static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) +static int +smbc_rmdir_ctx(SMBCCTX *context, + const char *fname) { SMBCSRV *srv; - fstring server, share, user, password, workgroup; - pstring path, targetpath; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; + pstring path; + pstring targetpath; struct cli_state *targetcli; if (!context || !context->internal || @@ -3094,27 +3254,6 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) } - /* if (strncmp(srv->cli.dev, "IPC", 3) == 0) { - - mode = aDIR | aRONLY; - - } - else if (strncmp(srv->cli.dev, "LPT", 3) == 0) { - - if (strcmp(path, "\\") == 0) { - - mode = aDIR | aRONLY; - - } - else { - - mode = aRONLY; - smbc_stat_printjob(srv, path, &size, &m_time); - c_time = a_time = m_time; - - } - else { */ - /*d_printf(">>>rmdir: resolving %s\n", path);*/ if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) { @@ -3130,19 +3269,21 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) if (errno == EACCES) { /* Check if the dir empty or not */ - pstring lpath; /* Local storage to avoid buffer overflows */ + /* Local storage to avoid buffer overflows */ + pstring lpath; smbc_rmdir_dirempty = True; /* Make this so ... */ pstrcpy(lpath, targetpath); pstrcat(lpath, "\\*"); - if (cli_list(targetcli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn, - NULL) < 0) { + if (cli_list(targetcli, lpath, + aDIR | aSYSTEM | aHIDDEN, + rmdir_list_fn, NULL) < 0) { /* Fix errno to ignore latest error ... */ - - DEBUG(5, ("smbc_rmdir: cli_list returned an error: %d\n", + DEBUG(5, ("smbc_rmdir: " + "cli_list returned an error: %d\n", smbc_errno(context, targetcli))); errno = EACCES; @@ -3167,7 +3308,9 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) * Routine to return the current directory position */ -static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) +static off_t +smbc_telldir_ctx(SMBCCTX *context, + SMBCFILE *dir) { off_t ret_val; /* Squash warnings about cast */ @@ -3205,8 +3348,9 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) * A routine to run down the list and see if the entry is OK */ -struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, - struct smbc_dirent *dirent) +struct smbc_dir_list * +smbc_check_dir_ent(struct smbc_dir_list *list, + struct smbc_dirent *dirent) { /* Run down the list looking for what we want */ @@ -3235,7 +3379,10 @@ struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, * Routine to seek on a directory */ -static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) +static int +smbc_lseekdir_ctx(SMBCCTX *context, + SMBCFILE *dir, + off_t offset) { long int l_offset = offset; /* Handle problems of size */ struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; @@ -3285,7 +3432,10 @@ static int smbc_lseekdir_ctx(SMBCCTX *context, SMBCFILE *dir, off_t offset) * Routine to fstat a dir */ -static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) +static int +smbc_fstatdir_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct stat *st) { if (!context || !context->internal || @@ -3302,10 +3452,17 @@ static int smbc_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) } -int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) +static int +smbc_chmod_ctx(SMBCCTX *context, + const char *fname, + mode_t newmode) { SMBCSRV *srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path; uint16 mode; @@ -3362,10 +3519,17 @@ int smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) return 0; } -int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) +static int +smbc_utimes_ctx(SMBCCTX *context, + const char *fname, + struct timeval *tbuf) { SMBCSRV *srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path; time_t a_time; time_t m_time; @@ -3448,7 +3612,9 @@ int smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) computer running Windows NT 5.0" if denied ACEs do not appear before allowed ACEs. */ -static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2) +static int +ace_compare(SEC_ACE *ace1, + SEC_ACE *ace2) { if (sec_ace_equal(ace1, ace2)) return 0; @@ -3472,12 +3638,14 @@ static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2) } -static void sort_acl(SEC_ACL *the_acl) +static void +sort_acl(SEC_ACL *the_acl) { uint32 i; if (!the_acl) return; - qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), QSORT_CAST ace_compare); + qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), + QSORT_CAST ace_compare); for (i=1;inum_aces;) { if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) { @@ -3493,11 +3661,12 @@ static void sort_acl(SEC_ACL *the_acl) } /* convert a SID to a string, either numeric or username/group */ -static void convert_sid_to_string(struct cli_state *ipc_cli, - POLICY_HND *pol, - fstring str, - BOOL numeric, - DOM_SID *sid) +static void +convert_sid_to_string(struct cli_state *ipc_cli, + POLICY_HND *pol, + fstring str, + BOOL numeric, + DOM_SID *sid) { char **domains = NULL; char **names = NULL; @@ -3530,11 +3699,12 @@ static void convert_sid_to_string(struct cli_state *ipc_cli, } /* convert a string to a SID, either numeric or username/group */ -static BOOL convert_string_to_sid(struct cli_state *ipc_cli, - POLICY_HND *pol, - BOOL numeric, - DOM_SID *sid, - const char *str) +static BOOL +convert_string_to_sid(struct cli_state *ipc_cli, + POLICY_HND *pol, + BOOL numeric, + DOM_SID *sid, + const char *str) { uint32 *types = NULL; DOM_SID *sids = NULL; @@ -3569,16 +3739,19 @@ static BOOL convert_string_to_sid(struct cli_state *ipc_cli, /* parse an ACE in the same format as print_ace() */ -static BOOL parse_ace(struct cli_state *ipc_cli, - POLICY_HND *pol, - SEC_ACE *ace, - BOOL numeric, - char *str) +static BOOL +parse_ace(struct cli_state *ipc_cli, + POLICY_HND *pol, + SEC_ACE *ace, + BOOL numeric, + char *str) { char *p; const char *cp; fstring tok; - unsigned atype, aflags, amask; + unsigned int atype; + unsigned int aflags; + unsigned int amask; DOM_SID sid; SEC_ACCESS mask; const struct perm_value *v; @@ -3689,10 +3862,14 @@ static BOOL parse_ace(struct cli_state *ipc_cli, } /* add an ACE to a list of ACEs in a SEC_ACL */ -static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) +static BOOL +add_ace(SEC_ACL **the_acl, + SEC_ACE *ace, + TALLOC_CTX *ctx) { SEC_ACL *newacl; SEC_ACE *aces; + if (! *the_acl) { (*the_acl) = make_sec_acl(ctx, 3, 1, ace); return True; @@ -3701,7 +3878,8 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces); memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); - newacl = make_sec_acl(ctx,(*the_acl)->revision,1+(*the_acl)->num_aces, aces); + newacl = make_sec_acl(ctx, (*the_acl)->revision, + 1+(*the_acl)->num_aces, aces); SAFE_FREE(aces); (*the_acl) = newacl; return True; @@ -3709,17 +3887,19 @@ static BOOL add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) /* parse a ascii version of a security descriptor */ -static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx, - struct cli_state *ipc_cli, - POLICY_HND *pol, - BOOL numeric, - char *str) +static SEC_DESC * +sec_desc_parse(TALLOC_CTX *ctx, + struct cli_state *ipc_cli, + POLICY_HND *pol, + BOOL numeric, + char *str) { const char *p = str; fstring tok; SEC_DESC *ret; size_t sd_size; - DOM_SID *grp_sid=NULL, *owner_sid=NULL; + DOM_SID *grp_sid=NULL; + DOM_SID *owner_sid=NULL; SEC_ACL *dacl=NULL; int revision=1; @@ -3819,10 +3999,11 @@ static SEC_DESC *sec_desc_parse(TALLOC_CTX *ctx, /* Obtain the current dos attributes */ -static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, - TALLOC_CTX *ctx, - const char *filename, - SMBCSRV *srv) +static DOS_ATTR_DESC * +dos_attr_query(SMBCCTX *context, + TALLOC_CTX *ctx, + const char *filename, + SMBCSRV *srv) { time_t m_time = 0, a_time = 0, c_time = 0; SMB_OFF_T size = 0; @@ -3859,10 +4040,11 @@ static DOS_ATTR_DESC *dos_attr_query(SMBCCTX *context, /* parse a ascii version of a security descriptor */ -static void dos_attr_parse(SMBCCTX *context, - DOS_ATTR_DESC *dad, - SMBCSRV *srv, - char *str) +static void +dos_attr_parse(SMBCCTX *context, + DOS_ATTR_DESC *dad, + SMBCSRV *srv, + char *str) { const char *p = str; fstring tok; @@ -3905,9 +4087,16 @@ static void dos_attr_parse(SMBCCTX *context, Retrieve the acls for a file. *******************************************************/ -static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, - struct cli_state *ipc_cli, POLICY_HND *pol, - char *filename, char *attr_name, char *buf, int bufsize) +static int +cacl_get(SMBCCTX *context, + TALLOC_CTX *ctx, + SMBCSRV *srv, + struct cli_state *ipc_cli, + POLICY_HND *pol, + char *filename, + char *attr_name, + char *buf, + int bufsize) { uint32 i; int n = 0; @@ -3970,7 +4159,9 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, if (all || all_nt || all_dos) { /* Exclusions are delimited by '!' */ - for (; pExclude != NULL; pExclude = (p == NULL ? NULL : p + 1)) { + for (; + pExclude != NULL; + pExclude = (p == NULL ? NULL : p + 1)) { /* Find end of this exclusion name */ if ((p = strchr(pExclude, '!')) != NULL) @@ -4062,7 +4253,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, n = strlen(p); } else { n = snprintf(buf, bufsize, - "REVISION:%d", sd->revision); + "REVISION:%d", + sd->revision); } } else if (StrCaseCmp(name, "revision") == 0) { if (determine_size) { @@ -4166,7 +4358,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, } n = strlen(p); } else { - n = snprintf(buf, bufsize, "%s", sidstr); + n = snprintf(buf, bufsize, + "%s", sidstr); } } @@ -4213,9 +4406,9 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, ace->info.mask); } } else if ((StrnCaseCmp(name, "acl", 3) == 0 && - StrCaseCmp(name + 3, sidstr) == 0) || + StrCaseCmp(name+3, sidstr) == 0) || (StrnCaseCmp(name, "acl+", 4) == 0 && - StrCaseCmp(name + 4, sidstr) == 0)) { + StrCaseCmp(name+4, sidstr) == 0)) { if (determine_size) { p = talloc_asprintf( ctx, @@ -4320,7 +4513,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, } n = strlen(p); } else { - n = snprintf(buf, bufsize, "0x%x", mode); + n = snprintf(buf, bufsize, + "0x%x", mode); } } @@ -4401,7 +4595,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, } n = strlen(p); } else { - n = snprintf(buf, bufsize, "%lu", c_time); + n = snprintf(buf, bufsize, + "%lu", c_time); } } @@ -4438,7 +4633,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, } n = strlen(p); } else { - n = snprintf(buf, bufsize, "%lu", a_time); + n = snprintf(buf, bufsize, + "%lu", a_time); } } @@ -4475,7 +4671,8 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, } n = strlen(p); } else { - n = snprintf(buf, bufsize, "%lu", m_time); + n = snprintf(buf, bufsize, + "%lu", m_time); } } @@ -4548,10 +4745,15 @@ static int cacl_get(SMBCCTX *context, TALLOC_CTX *ctx, SMBCSRV *srv, /***************************************************** set the ACLs on a file given an ascii description *******************************************************/ -static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli, - struct cli_state *ipc_cli, POLICY_HND *pol, - const char *filename, const char *the_acl, - int mode, int flags) +static int +cacl_set(TALLOC_CTX *ctx, + struct cli_state *cli, + struct cli_state *ipc_cli, + POLICY_HND *pol, + const char *filename, + const char *the_acl, + int mode, + int flags) { int fnum; int err = 0; @@ -4626,7 +4828,8 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli, &old->dacl->ace[j])) { uint32 k; for (k=j; kdacl->num_aces-1;k++) { - old->dacl->ace[k] = old->dacl->ace[k+1]; + old->dacl->ace[k] = + old->dacl->ace[k+1]; } old->dacl->num_aces--; if (old->dacl->num_aces == 0) { @@ -4730,18 +4933,23 @@ static int cacl_set(TALLOC_CTX *ctx, struct cli_state *cli, } -int smbc_setxattr_ctx(SMBCCTX *context, - const char *fname, - const char *name, - const void *value, - size_t size, - int flags) +static int +smbc_setxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size, + int flags) { int ret; int ret2; SMBCSRV *srv; SMBCSRV *ipc_srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path; TALLOC_CTX *ctx; POLICY_HND pol; @@ -4762,7 +4970,8 @@ int smbc_setxattr_ctx(SMBCCTX *context, } - DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (const char*)value)); + DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", + fname, name, (int) size, (const char*)value)); if (smbc_parse_path(context, fname, server, sizeof(server), @@ -4806,7 +5015,8 @@ int smbc_setxattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.*+") == 0) { /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", name+7, (const char *) value); + talloc_asprintf(ctx, "%s:%s", + name+7, (const char *) value); if (! namevalue) { errno = ENOMEM; ret = -1; @@ -4867,7 +5077,8 @@ int smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value); + talloc_asprintf(ctx, "%s:%s", + name+19, (const char *) value); if (! ipc_srv) { ret = -1; /* errno set by smbc_server() */ @@ -4896,7 +5107,8 @@ int smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value); + talloc_asprintf(ctx, "%s:%s", + name+19, (const char *) value); if (! ipc_srv) { @@ -4922,7 +5134,8 @@ int smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", name+19, (const char *) value); + talloc_asprintf(ctx, "%s:%s", + name+19, (const char *) value); if (! ipc_srv) { /* errno set by smbc_server() */ @@ -4953,7 +5166,8 @@ int smbc_setxattr_ctx(SMBCCTX *context, dad = dos_attr_query(context, ctx, path, srv); if (dad) { char *namevalue = - talloc_asprintf(ctx, "%s:%s", name+16, (const char *) value); + talloc_asprintf(ctx, "%s:%s", + name+16, (const char *) value); if (! namevalue) { errno = ENOMEM; ret = -1; @@ -4989,16 +5203,21 @@ int smbc_setxattr_ctx(SMBCCTX *context, return -1; } -int smbc_getxattr_ctx(SMBCCTX *context, - const char *fname, - const char *name, - const void *value, - size_t size) +static int +smbc_getxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size) { int ret; SMBCSRV *srv; SMBCSRV *ipc_srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path; TALLOC_CTX *ctx; POLICY_HND pol; @@ -5103,14 +5322,19 @@ int smbc_getxattr_ctx(SMBCCTX *context, } -int smbc_removexattr_ctx(SMBCCTX *context, - const char *fname, - const char *name) +static int +smbc_removexattr_ctx(SMBCCTX *context, + const char *fname, + const char *name) { int ret; SMBCSRV *srv; SMBCSRV *ipc_srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path; TALLOC_CTX *ctx; POLICY_HND pol; @@ -5209,10 +5433,11 @@ int smbc_removexattr_ctx(SMBCCTX *context, return -1; } -int smbc_listxattr_ctx(SMBCCTX *context, - const char *fname, - char *list, - size_t size) +static int +smbc_listxattr_ctx(SMBCCTX *context, + const char *fname, + char *list, + size_t size) { /* * This isn't quite what listxattr() is supposed to do. This returns @@ -5258,9 +5483,14 @@ int smbc_listxattr_ctx(SMBCCTX *context, * Open a print file to be written to by other calls */ -static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) +static SMBCFILE * +smbc_open_print_job_ctx(SMBCCTX *context, + const char *fname) { - fstring server, share, user, password; + fstring server; + fstring share; + fstring user; + fstring password; pstring path; if (!context || !context->internal || @@ -5304,10 +5534,17 @@ static SMBCFILE *smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) * copy it to a print file on the share specified by printq. */ -static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_print, const char *printq) +static int +smbc_print_file_ctx(SMBCCTX *c_file, + const char *fname, + SMBCCTX *c_print, + const char *printq) { - SMBCFILE *fid1, *fid2; - int bytes, saverr, tot_bytes = 0; + SMBCFILE *fid1; + SMBCFILE *fid2; + int bytes; + int saverr; + int tot_bytes = 0; char buf[4096]; if (!c_file || !c_file->internal->_initialized || !c_print || @@ -5380,10 +5617,17 @@ static int smbc_print_file_ctx(SMBCCTX *c_file, const char *fname, SMBCCTX *c_pr * Routine to list print jobs on a printer share ... */ -static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn) +static int +smbc_list_print_jobs_ctx(SMBCCTX *context, + const char *fname, + smbc_list_print_job_fn fn) { SMBCSRV *srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path; if (!context || !context->internal || @@ -5426,7 +5670,8 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_li } - if (cli_print_queue(&srv->cli, (void (*)(struct print_job_info *))fn) < 0) { + if (cli_print_queue(&srv->cli, + (void (*)(struct print_job_info *))fn) < 0) { errno = smbc_errno(context, &srv->cli); return -1; @@ -5441,10 +5686,17 @@ static int smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_li * Delete a print job from a remote printer share */ -static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id) +static int +smbc_unlink_print_job_ctx(SMBCCTX *context, + const char *fname, + int id) { SMBCSRV *srv; - fstring server, share, user, password, workgroup; + fstring server; + fstring share; + fstring user; + fstring password; + fstring workgroup; pstring path; int err; @@ -5505,9 +5757,10 @@ static int smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id /* * Get a new empty handle to fill in with your own info */ -SMBCCTX * smbc_new_context(void) +SMBCCTX * +smbc_new_context(void) { - SMBCCTX * context; + SMBCCTX *context; context = SMB_MALLOC_P(SMBCCTX); if (!context) { @@ -5579,7 +5832,9 @@ SMBCCTX * smbc_new_context(void) * and thus you'll be leaking memory if not handled properly. * */ -int smbc_free_context(SMBCCTX * context, int shutdown_ctx) +int +smbc_free_context(SMBCCTX *context, + int shutdown_ctx) { if (!context) { errno = EBADF; @@ -5601,12 +5856,15 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) if (context->callbacks.purge_cached_fn(context)) { SMBCSRV * s; SMBCSRV * next; - DEBUG(1, ("Could not purge all servers, Nice way shutdown failed.\n")); + DEBUG(1, ("Could not purge all servers, " + "Nice way shutdown failed.\n")); s = context->internal->_servers; while (s) { - DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", s, s->cli.fd)); + DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", + s, s->cli.fd)); cli_shutdown(&s->cli); - context->callbacks.remove_cached_srv_fn(context, s); + context->callbacks.remove_cached_srv_fn(context, + s); next = s->next; DLIST_REMOVE(context->internal->_servers, s); SAFE_FREE(s); @@ -5618,17 +5876,20 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) else { /* This is the polite way */ if (context->callbacks.purge_cached_fn(context)) { - DEBUG(1, ("Could not purge all servers, free_context failed.\n")); + DEBUG(1, ("Could not purge all servers, " + "free_context failed.\n")); errno = EBUSY; return 1; } if (context->internal->_servers) { - DEBUG(1, ("Active servers in context, free_context failed.\n")); + DEBUG(1, ("Active servers in context, " + "free_context failed.\n")); errno = EBUSY; return 1; } if (context->internal->_files) { - DEBUG(1, ("Active files in context, free_context failed.\n")); + DEBUG(1, ("Active files in context, " + "free_context failed.\n")); errno = EBUSY; return 1; } @@ -5653,11 +5914,13 @@ int smbc_free_context(SMBCCTX * context, int shutdown_ctx) * valid values for info->debug from 0 to 100, * and insist that info->fn must be non-null. */ -SMBCCTX * smbc_init_context(SMBCCTX * context) +SMBCCTX * +smbc_init_context(SMBCCTX *context) { pstring conf; int pid; - char *user = NULL, *home = NULL; + char *user = NULL; + char *home = NULL; if (!context || !context->internal) { errno = EBADF; @@ -5669,7 +5932,9 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) return 0; } - if (!context->callbacks.auth_fn || context->debug < 0 || context->debug > 100) { + if (!context->callbacks.auth_fn || + context->debug < 0 || + context->debug > 100) { errno = EINVAL; return NULL; @@ -5677,7 +5942,10 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) } if (!smbc_initialized) { - /* Do some library wide intialisations the first time we get called */ + /* + * Do some library-wide intializations the first time we get + * called + */ BOOL conf_loaded = False; /* Set this to what the user wants */ @@ -5755,15 +6023,17 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) if (!context->netbios_name) { /* - * We try to get our netbios name from the config. If that fails we fall - * back on constructing our netbios name from our hostname etc + * We try to get our netbios name from the config. If that + * fails we fall back on constructing our netbios name from + * our hostname etc */ if (global_myname()) { context->netbios_name = SMB_STRDUP(global_myname()); } else { /* - * Hmmm, I want to get hostname as well, but I am too lazy for the moment + * Hmmm, I want to get hostname as well, but I am too + * lazy for the moment */ pid = sys_getpid(); context->netbios_name = SMB_MALLOC(17); @@ -5771,7 +6041,8 @@ SMBCCTX * smbc_init_context(SMBCCTX * context) errno = ENOMEM; return NULL; } - slprintf(context->netbios_name, 16, "smbc%s%d", context->user, pid); + slprintf(context->netbios_name, 16, + "smbc%s%d", context->user, pid); } } -- cgit From 7919fd0ec80e680d848dd6157b6a5d14fc42e9b6 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 29 Dec 2005 15:06:59 +0000 Subject: r12570: r12084@cabra: derrell | 2005-12-29 10:05:16 -0500 do not open connection when only looking for cached connection; also, fix crash caused by missing initialization following recent locale changes (This used to be commit 0070d816ab53eba047c009604d02f7e088290978) --- source3/libsmb/libsmbclient.c | 81 ++++++++++++++++++++++++++++++------------- 1 file changed, 56 insertions(+), 25 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c4e36012f9..8cfef769e5 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -589,6 +589,7 @@ find_server(SMBCCTX *context, static SMBCSRV * smbc_server(SMBCCTX *context, + BOOL connect_if_not_found, const char *server, const char *share, fstring workgroup, @@ -644,13 +645,18 @@ smbc_server(SMBCCTX *context, errno = smbc_errno(context, &srv->cli); cli_shutdown(&srv->cli); - context->callbacks.remove_cached_srv_fn(context, srv); + context->callbacks.remove_cached_srv_fn(context, + srv); srv = NULL; } - /* Regenerate the dev value since it's based on both server and share */ + /* + * Regenerate the dev value since it's based on both + * server and share + */ if (srv) { - srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); + srv->dev = (dev_t)(str_checksum(server) ^ + str_checksum(share)); } } } @@ -662,6 +668,12 @@ smbc_server(SMBCCTX *context, return srv; } + /* If we're not asked to connect when a connection doesn't exist... */ + if (! connect_if_not_found) { + /* ... then we're done here. */ + return NULL; + } + make_nmb_name(&calling, context->netbios_name, 0x0); make_nmb_name(&called , server, 0x20); @@ -1003,7 +1015,8 @@ smbc_open_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { @@ -1646,7 +1659,8 @@ smbc_unlink_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { @@ -1779,8 +1793,8 @@ smbc_rename_ctx(SMBCCTX *ocontext, fstrcpy(workgroup, ocontext->workgroup); - srv = smbc_server(ocontext, server1, share1, workgroup, - user1, password1); + srv = smbc_server(ocontext, True, + server1, share1, workgroup, user1, password1); if (!srv) { return -1; @@ -2049,7 +2063,8 @@ smbc_stat_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { return -1; /* errno set by smbc_server */ @@ -2616,8 +2631,8 @@ smbc_opendir_ctx(SMBCCTX *context, * workgroups/domains that it knows about. */ - srv = smbc_server(context, server, - "IPC$", workgroup, user, password); + srv = smbc_server(context, True, server, "IPC$", + workgroup, user, password); if (!srv) { continue; } @@ -2664,8 +2679,12 @@ smbc_opendir_ctx(SMBCCTX *context, * to see if is an IP address first. */ - /* See if we have an existing server */ - srv = smbc_server(context, server, "IPC$", + /* + * See if we have an existing server. Do not + * establish a connection if one does not already + * exist. + */ + srv = smbc_server(context, False, server, "IPC$", workgroup, user, password); /* @@ -2699,7 +2718,8 @@ smbc_opendir_ctx(SMBCCTX *context, * Get a connection to IPC$ on the server if * we do not already have one */ - srv = smbc_server(context, buserver, "IPC$", + srv = smbc_server(context, True, + buserver, "IPC$", workgroup, user, password); if (!srv) { DEBUG(0, ("got no contact to IPC$\n")); @@ -2729,8 +2749,9 @@ smbc_opendir_ctx(SMBCCTX *context, /* If we hadn't found the server, get one now */ if (!srv) { - srv = smbc_server(context, server, - "IPC$", workgroup, + srv = smbc_server(context, True, + server, "IPC$", + workgroup, user, password); } @@ -2787,7 +2808,7 @@ smbc_opendir_ctx(SMBCCTX *context, /* We connect to the server and list the directory */ dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(context, server, share, + srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { @@ -3149,7 +3170,8 @@ smbc_mkdir_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { @@ -3246,7 +3268,8 @@ smbc_rmdir_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { @@ -3498,7 +3521,8 @@ smbc_chmod_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { return -1; /* errno set by smbc_server */ @@ -3593,7 +3617,8 @@ smbc_utimes_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { return -1; /* errno set by smbc_server */ @@ -4988,7 +5013,8 @@ smbc_setxattr_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { return -1; /* errno set by smbc_server */ } @@ -5255,7 +5281,8 @@ smbc_getxattr_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { return -1; /* errno set by smbc_server */ } @@ -5371,7 +5398,8 @@ smbc_removexattr_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { return -1; /* errno set by smbc_server */ } @@ -5662,7 +5690,8 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { @@ -5732,7 +5761,8 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, server, share, workgroup, user, password); + srv = smbc_server(context, True, + server, share, workgroup, user, password); if (!srv) { @@ -5951,6 +5981,7 @@ smbc_init_context(SMBCCTX *context) /* Set this to what the user wants */ DEBUGLEVEL = context->debug; + load_case_tables(); setup_logging( "libsmbclient", True); /* Here we would open the smb.conf file if needed ... */ -- cgit From e13d0cb3ec89d83db8893341ca7ae24c07aad1fb Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 29 Dec 2005 16:26:06 +0000 Subject: r12576: r12115@cabra: derrell | 2005-12-29 11:16:03 -0500 bug (enhancement) #2651: add option to log debug messages to stderr instead of stdout (This used to be commit 4182eb99af5b343291a661a87d08edd91fd09a7a) --- source3/libsmb/libsmbclient.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 8cfef769e5..6eca3946d8 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5937,6 +5937,27 @@ smbc_free_context(SMBCCTX *context, } +/* + * Each time the context structure is changed, we have binary backward + * compatibility issues. Instead of modifying the public portions of the + * context structure to add new options, instead, we put them in the internal + * portion of the context structure and provide a set function for these new + * options. + */ +void +smbc_option_set(SMBCCTX *context, + char *option_name, + void *option_value) +{ + if (strcmp(option_name, "debug_stderr") == 0) { + /* + * Log to standard error instead of standard output. + */ + context->internal->_debug_stderr = True; + } +} + + /* * Initialise the library etc * @@ -5982,7 +6003,12 @@ smbc_init_context(SMBCCTX *context) DEBUGLEVEL = context->debug; load_case_tables(); - setup_logging( "libsmbclient", True); + + setup_logging("libsmbclient", True); + if (context->internal->_debug_stderr) { + dbf = x_stderr; + x_setbuf(x_stderr, NULL); + } /* Here we would open the smb.conf file if needed ... */ @@ -6099,7 +6125,7 @@ smbc_init_context(SMBCCTX *context) * FIXME: Should we check the function pointers here? */ - context->internal->_initialized = 1; + context->internal->_initialized = True; return context; } -- cgit From cbc97b4e5aee1fe6488ef316374b75a58b667ccc Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 29 Dec 2005 17:03:39 +0000 Subject: r12579: r12122@cabra: derrell | 2005-12-29 12:03:00 -0500 allow for arbitrary option value types (This used to be commit 64c8e32b6382e48bce5c1f18179e66ca765a70af) --- source3/libsmb/libsmbclient.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 6eca3946d8..51f94e42e3 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5947,14 +5947,22 @@ smbc_free_context(SMBCCTX *context, void smbc_option_set(SMBCCTX *context, char *option_name, - void *option_value) + ...) { + va_list args; + + va_start(args, option_name); + if (strcmp(option_name, "debug_stderr") == 0) { /* * Log to standard error instead of standard output. + * + * optional parameters: none (it can't be turned off once on) */ context->internal->_debug_stderr = True; } + + va_end(args); } -- cgit From 2b509f470d616c8df69e72ec04e25114d22af50f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Jan 2006 12:48:54 +0000 Subject: r12713: Remove use of uint8_t -> uint8. Jeremy. (This used to be commit 4473ac4ef9c86574fc49b1e67089b59b14b6d10d) --- source3/libsmb/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index f99e48a0b9..99f99f23f8 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -542,7 +542,7 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessi for (i=0,k=0; ilength; i += 8, k += 7) { - uint8_t bin[8], bout[8], key[7]; + uint8 bin[8], bout[8], key[7]; memset(bin, 0, 8); memcpy(bin, &in->data[i], MIN(8, in->length-i)); -- cgit From f396e2248ad36e4ac24792f6278366b0c737f8d7 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 7 Jan 2006 20:43:31 +0000 Subject: r12758: r12127@cabra: derrell | 2006-01-03 15:22:18 -0500 remove old superfluous comment and ifdef (This used to be commit ee7fcb43ad456929f1f005f47c52a4b4d46c5087) --- source3/libsmb/clilist.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 252dafcfa8..48780e28df 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -169,11 +169,7 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { -#if 1 - int max_matches = 1366; /* Match W2k - was 512. */ -#else - int max_matches = 512; -#endif + int max_matches = 1366; int info_level; char *p, *p2; pstring mask; -- cgit From 5f4a895cdde15ada0f4155a431cad5ea610740d9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Jan 2006 23:23:09 +0000 Subject: r12920: Fix for #3401 from Andrew Bartlett. Original fix from Yau Lam Yiu . Jeremy. (This used to be commit 4776101107923e425a153fe0457dbf61f4c99935) --- source3/libsmb/ntlmssp.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 0becc7fdee..6dd623047a 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -384,6 +384,11 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, void ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state) { + /* Nothing to weaken. We certainly don't want to 'extend' the length... */ + if (!ntlmssp_state->session_key.length < 8) { + return; + } + /* Key weakening not performed on the master key for NTLM2 and does not occour for NTLM1. Therefore we only need to do this for the LM_KEY. -- cgit From ae4a576f680f1c0507ec73f606154ff8ff36a1dd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 13 Jan 2006 23:54:12 +0000 Subject: r12922: Fix typo. Jeremy. (This used to be commit 1c32b352da270370e65d25939fdc56c2a415190f) --- source3/libsmb/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 6dd623047a..c891ede9bb 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -385,7 +385,7 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, void ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state) { /* Nothing to weaken. We certainly don't want to 'extend' the length... */ - if (!ntlmssp_state->session_key.length < 8) { + if (ntlmssp_state->session_key.length < 8) { return; } -- cgit From 90372e1e9372ccce8e08dbe3d816d8e69b62a4f5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Jan 2006 19:25:18 +0000 Subject: r13012: Fix #3421 - it turns out krb5_kt_get_entry() on MIT does an implicit open/read/close and blows away an open keytab handle - so make sure we use a new handle. Wonderful analysis from Luke helped fix this. Jeremy. (This used to be commit 9d2f2385ad68cbe11bdfb82b5f2d016626f6e679) --- source3/libsmb/clikrb5.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 67e9f539ad..6e87f73df1 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -767,7 +767,6 @@ static krb5_enctype get_enctype_from_ap_req(krb5_ap_req *ap_req) static krb5_error_code get_key_from_keytab(krb5_context context, - krb5_keytab keytab, krb5_const_principal server, krb5_enctype enctype, krb5_kvno kvno, @@ -775,13 +774,18 @@ get_key_from_keytab(krb5_context context, { krb5_keytab_entry entry; krb5_error_code ret; - krb5_keytab real_keytab; + krb5_keytab keytab; char *name = NULL; - if (keytab == NULL) { - krb5_kt_default(context, &real_keytab); - } else { - real_keytab = keytab; + /* We have to open a new keytab handle here, as MIT does + an implicit open/getnext/close on krb5_kt_get_entry. We + may be in the middle of a keytab enumeration when this is + called. JRA. */ + + ret = krb5_kt_default(context, &keytab); + if (ret) { + DEBUG(0,("get_key_from_keytab: failed to open keytab: %s\n", error_message(ret))); + return ret; } if ( DEBUGLEVEL >= 10 ) { @@ -792,7 +796,7 @@ get_key_from_keytab(krb5_context context, } ret = krb5_kt_get_entry(context, - real_keytab, + keytab, server, kvno, enctype, @@ -819,10 +823,7 @@ get_key_from_keytab(krb5_context context, smb_krb5_kt_free_entry(context, &entry); out: - if (keytab == NULL) { - krb5_kt_close(context, real_keytab); - } - + krb5_kt_close(context, keytab); return ret; } @@ -913,7 +914,6 @@ krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); } ret = get_key_from_keytab(context, - keytab, server, enctype, kvno, -- cgit From 2fd79d8bfc9e8855b2959a4bfa0ff9eb691399f8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Jan 2006 20:45:44 +0000 Subject: r13015: Make logic much clearer. From jpeach. Jeremy. (This used to be commit d9b6bdd84a16c8af44049748a0fc47844f597919) --- source3/libsmb/ntlmssp_sign.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index e41cd6437c..cc6323718b 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -139,7 +139,7 @@ NTSTATUS ntlmssp_sign_packet(NTLMSSP_STATE *ntlmssp_state, { NTSTATUS nt_status; - if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN) { + if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { DEBUG(3, ("NTLMSSP Signing not negotiated - cannot sign packet!\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -238,7 +238,7 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, { NTSTATUS nt_status; - if (!ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) { + if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n")); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 8a30b3226d97bd43549971a4708afa79432b6d25 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 18 Jan 2006 22:40:00 +0000 Subject: r13020: Prevent cli_krb5_get_ticket of getting into an infite loop. This whole area of code needs to be reworked later on. Guenther (This used to be commit 088abfcdd1d6b28409d4b2917bc2aeb5d371f675) --- source3/libsmb/clikrb5.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 6e87f73df1..e0dcefeb1d 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -456,6 +456,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_creds creds; krb5_data in_data; BOOL creds_ready = False; + int i = 0, maxtries = 3; retval = krb5_parse_name(context, principal, &server); if (retval) { @@ -479,7 +480,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, goto cleanup_creds; } - while(!creds_ready) { + while (!creds_ready && (i < maxtries)) { if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { DEBUG(1,("ads_krb5_mk_req: krb5_get_credentials failed for %s (%s)\n", @@ -497,6 +498,8 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, if (!ads_cleanup_expired_creds(context, ccache, credsp)) creds_ready = True; + + i++; } DEBUG(10,("ads_krb5_mk_req: Ticket (%s) in ccache (%s) is valid until: (%s - %u)\n", -- cgit From 7756059d38e5702b4ba51f71cefb2a4656244cf7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 24 Jan 2006 20:15:08 +0000 Subject: r13119: Fix for #1779 from William Jojo Jeremy. (This used to be commit 103cac7dd314117b15e27fd263a64beeb36ed6e6) --- source3/libsmb/clireadwrite.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 55e36b646b..a080bd3c64 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -49,8 +49,9 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv7,((size >> 16) & 1)); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - if (bigoffset) - SIVAL(cli->outbuf,smb_vwv10,(offset>>32) & 0xffffffff); + if (bigoffset) { + SIVAL(cli->outbuf,smb_vwv10,(((SMB_BIG_UINT)offset)>>32) & 0xffffffff); + } return cli_send_smb(cli); } @@ -302,8 +303,9 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, SSVAL(cli->outbuf,smb_vwv11, smb_buf(cli->outbuf) - smb_base(cli->outbuf)); - if (large_writex) - SIVAL(cli->outbuf,smb_vwv12,(offset>>32) & 0xffffffff); + if (large_writex) { + SIVAL(cli->outbuf,smb_vwv12,(((SMB_BIG_UINT)offset)>>32) & 0xffffffff); + } p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); memcpy(p, buf, size); -- cgit From 60bcd1bd77557c86a7b384add8ff9b6b48a6e32d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 25 Jan 2006 23:00:07 +0000 Subject: r13147: Raise creds_server_step fail log messages to debug level 2. These can happen in normal operation (I think - not 100% sure) and don't want to alarm admins. Jerry please add this to 3.0.21b. Jeremy. (This used to be commit 47178b1b5ad06905f345a0f6b6267701d8aefddb) --- source3/libsmb/credentials.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index edb242df7e..ad06cd9015 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -156,7 +156,7 @@ BOOL creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) { DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data))); DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data))); - DEBUG(0,("creds_server_check: credentials check failed.\n")); + DEBUG(2,("creds_server_check: credentials check failed.\n")); return False; } DEBUG(10,("creds_server_check: credentials check OK.\n")); -- cgit From f1022af07bbc72412d8fca7945a2c276fba88a7e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Jan 2006 02:35:08 +0000 Subject: r13176: Fix show-stopper bug for 3.0.21b where 4 leg NTLMSSP SPNEGO auth was not generating the correct auth header on the 4th packet. This may fix a lot of Windows client complaints and is essential for release. Jeremy. (This used to be commit 48dd8c732b890e3fd3d8e80ace765487601cfb26) --- source3/libsmb/spnego.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index 6cc4436a0c..f6a66200ba 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -341,4 +341,3 @@ BOOL free_spnego_data(SPNEGO_DATA *spnego) out: return ret; } - -- cgit From ba611cb0368629dd7b98c20ed88e9394be0c29e5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 28 Jan 2006 22:49:25 +0000 Subject: r13211: Fix remote password changing if password must change is set The problem was that the ntlmssp bind silently failed in that case, we have to do it anonymously. Or does anybody have a better idea? Give a better error message if something else is wrong with the account. Volker (This used to be commit 0e24c701ce3755d71de7fdccb9f4564b381bf996) --- source3/libsmb/passchange.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index b104a4678d..8b811b06ea 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -34,6 +34,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, struct in_addr ip; NTSTATUS result; + BOOL pass_must_change = False; *err_str = '\0'; @@ -73,6 +74,28 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, /* Given things like SMB signing, restrict anonymous and the like, try an authenticated connection first */ if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { + + result = cli_nt_error(&cli); + + if (!NT_STATUS_IS_OK(result)) { + + /* Password must change is the only valid error + * condition here from where we can proceed, the rest + * like account locked out or logon failure will lead + * to errors later anyway */ + + if (!NT_STATUS_EQUAL(result, + NT_STATUS_PASSWORD_MUST_CHANGE)) { + slprintf(err_str, err_str_len-1, "Could not " + "connect to machine %s: %s\n", + remote_machine, cli_errstr(&cli)); + cli_shutdown(&cli); + return False; + } + + pass_must_change = True; + } + /* * We should connect as the anonymous user here, in case * the server has "must change password" checked... @@ -100,13 +123,25 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, /* Try not to give the password away too easily */ - pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli, + if (!pass_must_change) { + pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY, "", /* what domain... ? */ user_name, old_passwd, &result); + } else { + /* + * If the user password must be changed the ntlmssp bind will + * fail the same way as the session setup above did. The + * difference ist that with a pipe bind we don't get a good + * error message, the result will be that the rpc call below + * will just fail. So we do it anonymously, there's no other + * way. + */ + pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result); + } if (!pipe_hnd) { if (lp_client_lanman_auth()) { -- cgit From 9c15bd311db76885b27f30ba92d885833f668550 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 28 Jan 2006 22:53:04 +0000 Subject: r13212: r12414@cabra: derrell | 2006-01-28 17:52:17 -0500 lp_load() could not be called multiple times to modify parameter settings based on reading from multiple configuration settings. Each time, it initialized all of the settings back to their defaults before reading the specified configuration file. This patch adds a parameter to lp_load() specifying whether the settings should be initialized. It does, however, still force the settings to be initialized the first time, even if the request was to not initialize them. (Not doing so could wreak havoc due to uninitialized values.) (This used to be commit f2a24de769d1b2266e576597c57a8e3b1e2a2b51) --- source3/libsmb/libsmbclient.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 51f94e42e3..fda619c529 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -6025,7 +6025,7 @@ smbc_init_context(SMBCCTX *context) home = getenv("HOME"); if (home) { slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - if (lp_load(conf, True, False, False)) { + if (lp_load(conf, True, False, False, True)) { conf_loaded = True; } else { DEBUG(5, ("Could not load config file: %s\n", @@ -6041,7 +6041,7 @@ smbc_init_context(SMBCCTX *context) * defaults ... */ - if (!lp_load(dyn_CONFIGFILE, True, False, False)) { + if (!lp_load(dyn_CONFIGFILE, True, False, False, False)) { DEBUG(5, ("Could not load config file: %s\n", dyn_CONFIGFILE)); } else if (home) { @@ -6052,7 +6052,7 @@ smbc_init_context(SMBCCTX *context) */ slprintf(conf, sizeof(conf), "%s/.smb/smb.conf.append", home); - if (!lp_load(conf, True, False, False)) { + if (!lp_load(conf, True, False, False, False)) { DEBUG(10, ("Could not append config file: " "%s\n", -- cgit From c9811b857a7d8407659180a7cc453cead589bb4f Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 29 Jan 2006 00:11:34 +0000 Subject: r13214: r12420@cabra: derrell | 2006-01-28 19:10:58 -0500 This should fix bug #3446. - The authentication domain provided an an SMB URL was being ignored. This patch fixes that. - There were a number of places where string copies were not being confirmed to be properly null-terminated. Now, all string copies in libsmbclient.c are properly null-terminated. (This used to be commit 5fbc2fbb461f02ad6c889de2ce9929c605a44e24) --- source3/libsmb/libsmbclient.c | 101 ++++++++++++++++++++++++------------------ 1 file changed, 57 insertions(+), 44 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index fda619c529..e992cbbfc4 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -181,7 +181,8 @@ smbc_urldecode(char *dest, char * src, size_t max_dest_len) *p = '\0'; - strncpy(dest, temp, max_dest_len); + strncpy(dest, temp, max_dest_len - 1); + dest[max_dest_len - 1] = '\0'; return err_count; } @@ -268,6 +269,7 @@ static const char *smbc_prefix = "smb:"; static int smbc_parse_path(SMBCCTX *context, const char *fname, + char *workgroup, int workgroup_len, char *server, int server_len, char *share, int share_len, char *path, int path_len, @@ -282,6 +284,16 @@ smbc_parse_path(SMBCCTX *context, int len; server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; + + /* + * Assume we wont find an authentication domain to parse, so default + * to the workgroup in the provided context. + */ + if (workgroup != NULL) { + strncpy(workgroup, context->workgroup, workgroup_len - 1); + workgroup[workgroup_len - 1] = '\0'; + } + if (options != NULL && options_len > 0) { options[0] = (char)0; } @@ -328,6 +340,7 @@ smbc_parse_path(SMBCCTX *context, ((strlen(context->workgroup) < 16) ? strlen(context->workgroup) : 16)); + server[server_len - 1] = '\0'; return 0; } @@ -369,11 +382,20 @@ smbc_parse_path(SMBCCTX *context, } - if (username[0]) - strncpy(user, username, user_len); /* FIXME, domain */ + if (domain[0] && workgroup) { + strncpy(workgroup, domain, workgroup_len - 1); + workgroup[workgroup_len - 1] = '\0'; + } - if (passwd[0]) - strncpy(password, passwd, password_len); + if (username[0]) { + strncpy(user, username, user_len - 1); + user[user_len - 1] = '\0'; + } + + if (passwd[0]) { + strncpy(password, passwd, password_len - 1); + password[password_len - 1] = '\0'; + } } @@ -1001,6 +1023,7 @@ smbc_open_ctx(SMBCCTX *context, } if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -1013,8 +1036,6 @@ smbc_open_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -1208,6 +1229,7 @@ smbc_read_ctx(SMBCCTX *context, /*d_printf(">>>read: parsing %s\n", file->fname);*/ if (smbc_parse_path(context, file->fname, + NULL, 0, server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -1288,6 +1310,7 @@ smbc_write_ctx(SMBCCTX *context, /*d_printf(">>>write: parsing %s\n", file->fname);*/ if (smbc_parse_path(context, file->fname, + NULL, 0, server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -1359,6 +1382,7 @@ smbc_close_ctx(SMBCCTX *context, /*d_printf(">>>close: parsing %s\n", file->fname);*/ if (smbc_parse_path(context, file->fname, + NULL, 0, server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -1645,6 +1669,7 @@ smbc_unlink_ctx(SMBCCTX *context, } if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -1657,8 +1682,6 @@ smbc_unlink_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -1762,6 +1785,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); smbc_parse_path(ocontext, oname, + workgroup, sizeof(workgroup), server1, sizeof(server1), share1, sizeof(share1), path1, sizeof(path1), @@ -1772,6 +1796,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, if (user1[0] == (char)0) fstrcpy(user1, ocontext->user); smbc_parse_path(ncontext, nname, + NULL, 0, server2, sizeof(server2), share2, sizeof(share2), path2, sizeof(path2), @@ -1791,8 +1816,6 @@ smbc_rename_ctx(SMBCCTX *ocontext, } - fstrcpy(workgroup, ocontext->workgroup); - srv = smbc_server(ocontext, True, server1, share1, workgroup, user1, password1); if (!srv) { @@ -1891,6 +1914,7 @@ smbc_lseek_ctx(SMBCCTX *context, case SEEK_END: /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ if (smbc_parse_path(context, file->fname, + NULL, 0, server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -2049,6 +2073,7 @@ smbc_stat_ctx(SMBCCTX *context, DEBUG(4, ("smbc_stat(%s)\n", fname)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -2061,8 +2086,6 @@ smbc_stat_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -2137,6 +2160,7 @@ smbc_fstat_ctx(SMBCCTX *context, /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ if (smbc_parse_path(context, file->fname, + NULL, 0, server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -2270,8 +2294,12 @@ add_dirent(SMBCFILE *dir, dirent->commentlen = comment_len; dirent->dirlen = size; + /* + * dirent->namelen + 1 includes the null (no null termination needed) + * Ditto for dirent->commentlen. + * The space for the two null bytes was allocated. + */ strncpy(dirent->name, (name?name:""), dirent->namelen + 1); - dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); @@ -2510,6 +2538,7 @@ smbc_opendir_ctx(SMBCCTX *context, } if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -2534,8 +2563,6 @@ smbc_opendir_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - pstrcpy(workgroup, context->workgroup); - dir = SMB_MALLOC_P(SMBCFILE); if (!dir) { @@ -2934,14 +2961,8 @@ smbc_readdir_internal(SMBCCTX * context, dest->comment = dest->name + dest->namelen + 1; /* Copy the comment */ - strncpy(dest->comment, src->comment, max_namebuf_len); - - /* Ensure the comment is null terminated */ - if (max_namebuf_len > src->commentlen) { - dest->comment[src->commentlen] = '\0'; - } else { - dest->comment[max_namebuf_len - 1] = '\0'; - } + strncpy(dest->comment, src->comment, max_namebuf_len - 1); + dest->comment[max_namebuf_len - 1] = '\0'; /* Save other fields */ dest->smbc_type = src->smbc_type; @@ -3156,6 +3177,7 @@ smbc_mkdir_ctx(SMBCCTX *context, DEBUG(4, ("smbc_mkdir(%s)\n", fname)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -3168,8 +3190,6 @@ smbc_mkdir_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -3253,6 +3273,7 @@ smbc_rmdir_ctx(SMBCCTX *context, DEBUG(4, ("smbc_rmdir(%s)\n", fname)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -3266,8 +3287,6 @@ smbc_rmdir_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -3507,6 +3526,7 @@ smbc_chmod_ctx(SMBCCTX *context, DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -3519,8 +3539,6 @@ smbc_chmod_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -3586,13 +3604,13 @@ smbc_utimes_ctx(SMBCCTX *context, char atimebuf[32]; char mtimebuf[32]; - strncpy(atimebuf, ctime(&a_time), sizeof(atimebuf)); + strncpy(atimebuf, ctime(&a_time), sizeof(atimebuf) - 1); atimebuf[sizeof(atimebuf) - 1] = '\0'; if ((p = strchr(atimebuf, '\n')) != NULL) { *p = '\0'; } - strncpy(mtimebuf, ctime(&m_time), sizeof(mtimebuf)); + strncpy(mtimebuf, ctime(&m_time), sizeof(mtimebuf) - 1); mtimebuf[sizeof(mtimebuf) - 1] = '\0'; if ((p = strchr(mtimebuf, '\n')) != NULL) { *p = '\0'; @@ -3603,6 +3621,7 @@ smbc_utimes_ctx(SMBCCTX *context, } if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -3615,8 +3634,6 @@ smbc_utimes_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -4999,6 +5016,7 @@ smbc_setxattr_ctx(SMBCCTX *context, fname, name, (int) size, (const char*)value)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -5011,8 +5029,6 @@ smbc_setxattr_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { @@ -5267,6 +5283,7 @@ smbc_getxattr_ctx(SMBCCTX *context, DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -5279,8 +5296,6 @@ smbc_getxattr_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { @@ -5384,6 +5399,7 @@ smbc_removexattr_ctx(SMBCCTX *context, DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -5396,8 +5412,6 @@ smbc_removexattr_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { @@ -5539,6 +5553,7 @@ smbc_open_print_job_ctx(SMBCCTX *context, DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); if (smbc_parse_path(context, fname, + NULL, 0, server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -5676,6 +5691,7 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -5688,8 +5704,6 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -5747,6 +5761,7 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); if (smbc_parse_path(context, fname, + workgroup, sizeof(workgroup), server, sizeof(server), share, sizeof(share), path, sizeof(path), @@ -5759,8 +5774,6 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, if (user[0] == (char)0) fstrcpy(user, context->user); - fstrcpy(workgroup, context->workgroup); - srv = smbc_server(context, True, server, share, workgroup, user, password); -- cgit From 7ed3868780f72e00687cbd056109ef85ea2ea092 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 29 Jan 2006 04:57:42 +0000 Subject: r13216: r12422@cabra: derrell | 2006-01-28 23:57:35 -0500 Fix cli_setpathinfo() to actually do what it's supposed to. Also, get rid of some apparently drug-induced code to deal with create time which isn't being manipulated anyway. (This used to be commit aa25dc1248b15e8e1b39cf8a98496e5aba475c4a) --- source3/libsmb/clirap.c | 34 +++++++++++++++++----------------- source3/libsmb/libsmbclient.c | 33 --------------------------------- 2 files changed, 17 insertions(+), 50 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 6716971fe2..58fa9c8dff 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -471,7 +471,6 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, char *rparam=NULL, *rdata=NULL; int count=8; BOOL ret; - void (*date_fn)(struct cli_state *, char *buf,int offset,time_t unixdate); char *p; memset(param, 0, sizeof(param)); @@ -480,7 +479,7 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, p = param; /* Add the information level */ - SSVAL(p, 0, SMB_INFO_STANDARD); + SSVAL(p, 0, SMB_FILE_BASIC_INFORMATION); /* Skip reserved */ p += 6; @@ -492,26 +491,27 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, p = data; - if (cli->win95) { - date_fn = cli_put_dos_date; - } else { - date_fn = cli_put_dos_date2; - } - - /* Add the create, last access, and modification times */ - (*date_fn)(cli, p, 0, c_time); - (*date_fn)(cli, p, 4, a_time); - (*date_fn)(cli, p, 8, m_time); - p += 12; + /* + * Add the create, last access, modification, and status change times + */ + + /* Don't set create time, at offset 0 */ + p += 8; - /* Skip DataSize and AllocationSize */ + put_long_date(p, a_time); + p += 8; + + put_long_date(p, m_time); + p += 8; + + put_long_date(p, c_time); p += 8; /* Add attributes */ - SSVAL(p, 0, mode); - p += 2; + SIVAL(p, 0, mode); + p += 4; - /* Add EA size (none) */ + /* Add padding */ SIVAL(p, 0, 0); p += 4; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index e992cbbfc4..44cb43c285 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1522,39 +1522,6 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, int fd; int ret; - /* - * Get the create time of the file (if not provided); we'll need it in - * the set call. - */ - if (! srv->no_pathinfo && c_time == 0) { - if (! cli_qpathinfo(&srv->cli, path, - &c_time, NULL, NULL, NULL, NULL)) { - /* qpathinfo not available */ - srv->no_pathinfo = True; - } else { - /* - * We got a creation time. Some OS versions don't - * return a valid create time, though. If we got an - * invalid time, start with the current time instead. - */ - if (c_time == 0 || c_time == (time_t) -1) { - c_time = time(NULL); - } - - /* - * We got a creation time. For sanity sake, since - * there is no POSIX function to set the create time - * of a file, if the existing create time is greater - * than either of access time or modification time, - * set create time to the smallest of those. This - * ensure that the create time of a file is never - * greater than its last access or modification time. - */ - if (c_time > a_time) c_time = a_time; - if (c_time > m_time) c_time = m_time; - } - } - /* * First, try setpathinfo (if qpathinfo succeeded), for it is the * modern function for "new code" to be using, and it works given a -- cgit From 4699d4741da8145b1a491eeafa4133133e194f94 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Jan 2006 20:20:17 +0000 Subject: r13238: Fix from Qiao Yang to ensure we always update the failed time when we are adding a failed connection. Jeremy. (This used to be commit 6f5af1dd413d07430ead9382422dda14acf3464d) --- source3/libsmb/conncache.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index fe863db422..2af4d57b80 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -105,10 +105,11 @@ void add_failed_connection_entry(const char *domain, const char *server, NTSTATU a domain, but maybe not a specific DC name. */ for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { - if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) - { + if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) { DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n", domain, server )); + /* Update the failed time. */ + fcc->lookup_time = time(NULL); return; } } -- cgit From 86c9bac4c31df1606e3758ec42672506dde26cc6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Feb 2006 04:14:07 +0000 Subject: r13274: Fix for bug #3467. Not a show stopper. jason qian was a *fantastic* help in tracking this down. Jeremy. (This used to be commit 9f4a9c70fa232047868e5d8a3f132a2dd6bfee82) --- source3/libsmb/smb_share_modes.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 43f25cd378..86071ee2e9 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -123,6 +123,7 @@ struct locking_data { struct { int num_share_mode_entries; BOOL delete_on_close; + BOOL initial_delete_on_close; } s; struct share_mode_entry dummy; /* Needed for alignment. */ } u; @@ -282,6 +283,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; ld->u.s.num_share_mode_entries = 1; ld->u.s.delete_on_close = 0; + ld->u.s.initial_delete_on_close = 0; shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); create_share_mode_entry(shares, new_entry); -- cgit From 855e02f1649992f05b685be96dfff4a9140170e9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 21:19:24 +0000 Subject: r13310: first round of server affinity patches for winbindd & net ads join (This used to be commit 6c3480f9aecc061660ad5c06347b8f1d3e11a330) --- source3/libsmb/cliconnect.c | 12 +- source3/libsmb/namequery.c | 323 +++++++++++++++++++++++++++--------------- source3/libsmb/namequery_dc.c | 28 ---- 3 files changed, 217 insertions(+), 146 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ac7d1b1650..7c15c8d19f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -865,14 +865,16 @@ BOOL cli_session_setup(struct cli_state *cli, DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status))); return False; } - return True; + } else { + /* otherwise do a NT1 style session setup */ + if ( !cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup) ) { + DEBUG(3,("cli_session_setup: NT1 session setup failed!\n")); + return False; + } } - /* otherwise do a NT1 style session setup */ + return True; - return cli_session_setup_nt1(cli, user, - pass, passlen, ntpass, ntpasslen, - workgroup); } /**************************************************************************** diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 28b89db908..0986e7f29a 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -24,6 +24,94 @@ /* nmbd.c sets this to True. */ BOOL global_in_nmbd = False; + +/**************************** + * SERVER AFFINITY ROUTINES * + ****************************/ + + /* Server affinity is the concept of preferring the last domain + controller with whom you had a successful conversation */ + +/**************************************************************************** +****************************************************************************/ +#define SAFKEY_FMT "SAF/DOMAIN/%s" +#define SAF_TTL 900 + +static char *saf_key(const char *domain) +{ + char *keystr; + + asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) ); + + return keystr; +} + +/**************************************************************************** +****************************************************************************/ + +BOOL saf_store( const char *domain, const char *servername ) +{ + char *key; + time_t expire; + BOOL ret = False; + + if ( !domain || !servername ) { + DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n")); + return False; + } + + if ( !gencache_init() ) + return False; + + key = saf_key( domain ); + expire = time( NULL ) + SAF_TTL; + + + DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%d]\n", + domain, servername, expire )); + + ret = gencache_set( key, servername, expire ); + + SAFE_FREE( key ); + + return ret; +} + +/**************************************************************************** +****************************************************************************/ + +char *saf_fetch( const char *domain ) +{ + char *server = NULL; + time_t timeout; + BOOL ret = False; + char *key = NULL; + + if ( !domain ) { + DEBUG(2,("saf_fetch: Empty domain name!\n")); + return NULL; + } + + if ( !gencache_init() ) + return False; + + key = saf_key( domain ); + + ret = gencache_get( key, &server, &timeout ); + + SAFE_FREE( key ); + + if ( !ret ) { + DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain )); + } else { + DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n", + server, domain )); + } + + return server; +} + + /**************************************************************************** Generate a random trn_id. ****************************************************************************/ @@ -1261,6 +1349,18 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only, int *ordered) { fstring resolve_order; + char *saf_servername; + pstring pserver; + const char *p; + char *port_str; + int port; + fstring name; + int num_addresses = 0; + int local_count, i, j; + struct ip_service *return_iplist = NULL; + struct ip_service *auto_ip_list = NULL; + BOOL done_auto_lookup = False; + int auto_count = 0; /* if we are restricted to solely using DNS for looking up a domain controller, make sure that host lookups @@ -1277,148 +1377,145 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, fstrcpy( resolve_order, "NULL" ); } - *ordered = False; - - /* If it's our domain then use the 'password server' parameter. */ - + + /* fetch the server we have affinity for. Add the + 'password server' list to a search for our domain controllers */ + + saf_servername = saf_fetch( domain ); + if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) { - const char *p; - char *pserver = lp_passwordserver(); /* UNIX charset. */ - char *port_str; - int port; - fstring name; - int num_addresses = 0; - int local_count, i, j; - struct ip_service *return_iplist = NULL; - struct ip_service *auto_ip_list = NULL; - BOOL done_auto_lookup = False; - int auto_count = 0; - + pstr_sprintf( pserver, "%s, %s", + saf_servername ? saf_servername : "", + lp_passwordserver() ); + } else { + pstr_sprintf( pserver, "%s, *", + saf_servername ? saf_servername : "" ); + } - if (!*pserver) - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); + SAFE_FREE( saf_servername ); - p = pserver; - - /* - * if '*' appears in the "password server" list then add - * an auto lookup to the list of manually configured - * DC's. If any DC is listed by name, then the list should be - * considered to be ordered - */ - - while (next_token(&p,name,LIST_SEP,sizeof(name))) { - if (strequal(name, "*")) { - if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) ) - num_addresses += auto_count; - done_auto_lookup = True; - DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); - } else { - num_addresses++; - } + /* if we are starting from scratch, just lookup DOMAIN<0x1c> */ + + if ( !*pserver ) { + DEBUG(10,("get_dc_list: no preferred domain controllers.\n")); + return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); + } + + DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver )); + + /* + * if '*' appears in the "password server" list then add + * an auto lookup to the list of manually configured + * DC's. If any DC is listed by name, then the list should be + * considered to be ordered + */ + + p = pserver; + while (next_token(&p,name,LIST_SEP,sizeof(name))) { + if (strequal(name, "*")) { + if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) ) + num_addresses += auto_count; + done_auto_lookup = True; + DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); + } else { + num_addresses++; } + } - /* if we have no addresses and haven't done the auto lookup, then - just return the list of DC's */ + /* if we have no addresses and haven't done the auto lookup, then + just return the list of DC's. Or maybe we just failed. */ - if ( (num_addresses == 0) && !done_auto_lookup ) { + if ( (num_addresses == 0) ) { + if ( !done_auto_lookup ) { return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); - } - - /* maybe we just failed? */ - - if ( num_addresses == 0 ) { - DEBUG(4,("get_dc_list: no servers found\n")); - return False; - } - - if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { - DEBUG(3,("get_dc_list: malloc fail !\n")); + } else { + DEBUG(4,("get_dc_list: no servers found\n")); return False; } + } + + if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { + DEBUG(3,("get_dc_list: malloc fail !\n")); + return False; + } - p = pserver; - local_count = 0; + p = pserver; + local_count = 0; - /* fill in the return list now with real IP's */ + /* fill in the return list now with real IP's */ - while ( (local_count= 4 ) { - DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, - *ordered ? "":"un")); - DEBUG(4,("get_dc_list: ")); - for ( i=0; i= 4 ) { + DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, + *ordered ? "":"un")); + DEBUG(4,("get_dc_list: ")); + for ( i=0; i Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clidfs.c | 22 ++++-- source3/libsmb/clientgen.c | 8 +- source3/libsmb/clikrb5.c | 171 +++++++++++++++++++++++++++++++++++++++--- source3/libsmb/clilist.c | 6 +- source3/libsmb/clispnego.c | 2 +- source3/libsmb/conncache.c | 36 +++++---- source3/libsmb/errormap.c | 15 ++++ source3/libsmb/gpo.c | 167 +++++++++++++++++++++++++++++++++++++++++ source3/libsmb/libsmbclient.c | 13 +--- source3/libsmb/passchange.c | 40 +++++----- 11 files changed, 418 insertions(+), 64 deletions(-) create mode 100644 source3/libsmb/gpo.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7c15c8d19f..6f32fb1b5d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -756,7 +756,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, int ret; use_in_memory_ccache(); - ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL, NULL); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL, NULL, NULL, False, 0); if (ret){ SAFE_FREE(principal); diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 51f21397f7..c5cf75783b 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -682,12 +682,15 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, CLIENT_DFS_REFERRAL *refs = NULL; size_t num_refs; uint16 consumed; - struct cli_state *cli_ipc; pstring fullpath; + BOOL res; + uint16 cnum; if ( !cli || !sharename ) return False; + cnum = cli->cnum; + /* special case. never check for a referral on the IPC$ share */ if ( strequal( sharename, "IPC$" ) ) @@ -699,12 +702,19 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, /* check for the referral */ - if ( !(cli_ipc = cli_cm_open( cli->desthost, "IPC$", False )) ) + if (!cli_send_tconX(cli, "IPC$", "IPC", NULL, 0)) { return False; - - if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed) - || !num_refs ) - { + } + + res = cli_dfs_get_referral(cli, fullpath, &refs, &num_refs, &consumed); + + if (!cli_tdis(cli)) { + return False; + } + + cli->cnum = cnum; + + if (!res || !num_refs ) { return False; } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2f980adcf8..55addd44a6 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -353,11 +353,14 @@ struct cli_state *cli_initialise(struct cli_state *cli) /**************************************************************************** External interface. Close an open named pipe over SMB. Free any authentication data. + Returns False if the cli_close call failed. ****************************************************************************/ -void cli_rpc_pipe_close(struct rpc_pipe_client *cli) +BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) { - if (!cli_close(cli->cli, cli->fnum)) { + BOOL ret = cli_close(cli->cli, cli->fnum); + + if (!ret) { DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s, " "fnum 0x%x " "to machine %s. Error was %s\n", @@ -376,6 +379,7 @@ void cli_rpc_pipe_close(struct rpc_pipe_client *cli) DLIST_REMOVE(cli->cli->pipe_list, cli); talloc_destroy(cli->mem_ctx); + return ret; } /**************************************************************************** diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e0dcefeb1d..55a705d7f0 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -409,9 +409,10 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, krb5_creds *credsp) { krb5_error_code retval; + const char *cc_type = krb5_cc_get_type(context, ccache); - DEBUG(3, ("Ticket in ccache[%s] expiration %s\n", - krb5_cc_default_name(context), + DEBUG(3, ("ads_cleanup_expired_creds: Ticket in ccache[%s:%s] expiration %s\n", + cc_type, krb5_cc_get_name(context, ccache), http_timestring(credsp->times.endtime))); /* we will probably need new tickets if the current ones @@ -425,11 +426,11 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, use memory ccaches, and a FILE one probably means that we're using creds obtained outside of our exectuable */ - if (StrCaseCmp(krb5_cc_get_type(context, ccache), "FILE") == 0) { - DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a FILE ccache\n")); + if (strequal(cc_type, "KCM") || strequal(cc_type, "FILE")) { + DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a %s ccache\n", cc_type)); return False; } - + retval = krb5_cc_remove_cred(context, ccache, 0, credsp); if (retval) { DEBUG(1, ("ads_cleanup_expired_creds: krb5_cc_remove_cred failed, err %s\n", @@ -467,7 +468,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, /* obtain ticket & session key */ ZERO_STRUCT(creds); if ((retval = krb5_copy_principal(context, server, &creds.server))) { - DEBUG(1,("krb5_copy_principal failed (%s)\n", + DEBUG(1,("ads_krb5_mk_req: krb5_copy_principal failed (%s)\n", error_message(retval))); goto cleanup_princ; } @@ -502,8 +503,8 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, i++; } - DEBUG(10,("ads_krb5_mk_req: Ticket (%s) in ccache (%s) is valid until: (%s - %u)\n", - principal, krb5_cc_default_name(context), + DEBUG(10,("ads_krb5_mk_req: Ticket (%s) in ccache (%s:%s) is valid until: (%s - %u)\n", + principal, krb5_cc_get_type(context, ccache), krb5_cc_get_name(context, ccache), http_timestring((unsigned)credsp->times.endtime), (unsigned)credsp->times.endtime)); @@ -530,7 +531,8 @@ cleanup_princ: get a kerberos5 ticket for the given service */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, + uint32 extra_ap_opts, const char *ccname) { krb5_error_code retval; krb5_data packet; @@ -544,7 +546,7 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, ENCTYPE_DES_CBC_MD5, ENCTYPE_DES_CBC_CRC, ENCTYPE_NULL}; - + initialize_krb5_error_table(); retval = krb5_init_context(&context); if (retval) { @@ -557,7 +559,8 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, krb5_set_real_time(context, time(NULL) + time_offset, 0); } - if ((retval = krb5_cc_default(context, &ccdef))) { + if ((retval = krb5_cc_resolve(context, ccname ? + ccname : krb5_cc_default_name(context), &ccdef))) { DEBUG(1,("cli_krb5_get_ticket: krb5_cc_default failed (%s)\n", error_message(retval))); goto failed; @@ -989,12 +992,156 @@ out: #else #error NO_SUITABLE_PRINCIPAL_COMPARE_FUNCTION #endif +} + + krb5_error_code smb_krb5_renew_ticket(const char *ccache_string, /* FILE:/tmp/krb5cc_0 */ + const char *client_string, /* gd@BER.SUSE.DE */ + const char *service_string, /* krbtgt/BER.SUSE.DE@BER.SUSE.DE */ + time_t *new_start_time) +{ + krb5_error_code ret; + krb5_context context = NULL; + krb5_ccache ccache = NULL; + krb5_principal client = NULL; + + initialize_krb5_error_table(); + ret = krb5_init_context(&context); + if (ret) { + goto done; + } + + if (!ccache_string) { + ccache_string = krb5_cc_default_name(context); + } + + DEBUG(10,("smb_krb5_renew_ticket: using %s as ccache\n", ccache_string)); + + /* FIXME: we should not fall back to defaults */ + ret = krb5_cc_resolve(context, CONST_DISCARD(char *, ccache_string), &ccache); + if (ret) { + goto done; + } + +#ifdef HAVE_KRB5_GET_RENEWED_CREDS /* MIT */ + { + krb5_creds creds; + + if (client_string) { + ret = krb5_parse_name(context, client_string, &client); + if (ret) { + goto done; + } + } else { + ret = krb5_cc_get_principal(context, ccache, &client); + if (ret) { + goto done; + } + } + + ret = krb5_get_renewed_creds(context, &creds, client, ccache, CONST_DISCARD(char *, service_string)); + if (ret) { + DEBUG(10,("smb_krb5_renew_ticket: krb5_get_kdc_cred failed: %s\n", error_message(ret))); + goto done; + } + + /* hm, doesn't that create a new one if the old one wasn't there? - Guenther */ + ret = krb5_cc_initialize(context, ccache, client); + if (ret) { + goto done; + } + + ret = krb5_cc_store_cred(context, ccache, &creds); + + if (new_start_time) { + *new_start_time = (time_t) creds.times.renew_till; + } + + krb5_free_cred_contents(context, &creds); + } +#elif defined(HAVE_KRB5_GET_KDC_CRED) /* Heimdal */ + { + krb5_kdc_flags flags; + krb5_creds creds_in; + krb5_realm *client_realm; + krb5_creds *creds; + + memset(&creds_in, 0, sizeof(creds_in)); + + if (client_string) { + ret = krb5_parse_name(context, client_string, &creds_in.client); + if (ret) { + goto done; + } + } else { + ret = krb5_cc_get_principal(context, ccache, &creds_in.client); + if (ret) { + goto done; + } + } + + if (service_string) { + ret = krb5_parse_name(context, service_string, &creds_in.server); + if (ret) { + goto done; + } + } else { + /* build tgt service by default */ + client_realm = krb5_princ_realm(context, client); + ret = krb5_make_principal(context, &creds_in.server, *client_realm, KRB5_TGS_NAME, *client_realm, NULL); + if (ret) { + goto done; + } + } + + flags.i = 0; + flags.b.renewable = flags.b.renew = True; + + ret = krb5_get_kdc_cred(context, ccache, flags, NULL, NULL, &creds_in, &creds); + if (ret) { + DEBUG(10,("smb_krb5_renew_ticket: krb5_get_kdc_cred failed: %s\n", error_message(ret))); + goto done; + } + + /* hm, doesn't that create a new one if the old one wasn't there? - Guenther */ + ret = krb5_cc_initialize(context, ccache, creds_in.client); + if (ret) { + goto done; + } + + ret = krb5_cc_store_cred(context, ccache, creds); + + if (new_start_time) { + *new_start_time = (time_t) creds->times.renew_till; + } + + krb5_free_cred_contents(context, &creds_in); + krb5_free_creds(context, creds); + } +#else +#error No suitable krb5 ticket renew function available +#endif + + +done: + if (client) { + krb5_free_principal(context, client); + } + if (context) { + krb5_free_context(context); + } + if (ccache) { + krb5_cc_close(context, ccache); + } + + return ret; + } #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, - DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) + DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, + const char *ccname) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return 1; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 48780e28df..252dafcfa8 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -169,7 +169,11 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { - int max_matches = 1366; +#if 1 + int max_matches = 1366; /* Match W2k - was 512. */ +#else + int max_matches = 512; +#endif int info_level; char *p, *p2; pstring mask; diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index cc481a066a..13bf1a866c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -333,7 +333,7 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, /* get a kerberos ticket for the service and extract the session key */ retval = cli_krb5_get_ticket(principal, time_offset, - &tkt, session_key_krb5, extra_ap_opts); + &tkt, session_key_krb5, extra_ap_opts, NULL); if (retval) return retval; diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index 2af4d57b80..49512d7a2e 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -25,8 +25,6 @@ #include "includes.h" -#define FAILED_CONNECTION_CACHE_TIMEOUT 30 /* Seconds between attempts */ - #define CONNCACHE_ADDR 1 #define CONNCACHE_NAME 2 @@ -44,10 +42,13 @@ struct failed_connection_cache { static struct failed_connection_cache *failed_connection_cache; /********************************************************************** - Check for a previously failed connection + Check for a previously failed connection. + failed_cache_timeout is an a absolute number of seconds after which + we should time this out. If failed_cache_timeout == 0 then time out + immediately. If failed_cache_timeout == -1 then never time out. **********************************************************************/ -NTSTATUS check_negative_conn_cache( const char *domain, const char *server ) +NTSTATUS check_negative_conn_cache_timeout( const char *domain, const char *server, unsigned int failed_cache_timeout ) { struct failed_connection_cache *fcc; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; @@ -59,22 +60,24 @@ NTSTATUS check_negative_conn_cache( const char *domain, const char *server ) for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { - if ( !(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller)) ) + if (!(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller))) { continue; /* no match; check the next entry */ + } /* we have a match so see if it is still current */ + if (failed_cache_timeout != (unsigned int)-1) { + if (failed_cache_timeout == 0 || + (time(NULL) - fcc->lookup_time) > (time_t)failed_cache_timeout) { + /* Cache entry has expired, delete it */ - if ((time(NULL) - fcc->lookup_time) > FAILED_CONNECTION_CACHE_TIMEOUT) - { - /* Cache entry has expired, delete it */ - - DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", - domain, server )); + DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", + domain, server )); - DLIST_REMOVE(failed_connection_cache, fcc); - SAFE_FREE(fcc); + DLIST_REMOVE(failed_connection_cache, fcc); + SAFE_FREE(fcc); - return NT_STATUS_OK; + return NT_STATUS_OK; + } } /* The timeout hasn't expired yet so return false */ @@ -90,6 +93,11 @@ NTSTATUS check_negative_conn_cache( const char *domain, const char *server ) return NT_STATUS_OK; } +NTSTATUS check_negative_conn_cache( const char *domain, const char *server) +{ + return check_negative_conn_cache_timeout(domain, server, FAILED_CONNECTION_CACHE_TIMEOUT); +} + /********************************************************************** Add an entry to the failed conneciton cache (aither a name of dotted decimal IP diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 3c0b13ad6f..f6b5af068a 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1411,6 +1411,13 @@ static const struct { {NT_STATUS(0x80000289), W_ERROR(0x48e)}, {NT_STATUS_OK, WERR_OK}}; +static const struct { + WERROR werror; + NTSTATUS ntstatus; +} werror_to_ntstatus_map[] = { + { W_ERROR(0x5), NT_STATUS_ACCESS_DENIED }, + { WERR_OK, NT_STATUS_OK } +}; /***************************************************************************** convert a dos eclas/ecode to a NT status32 code @@ -1460,6 +1467,14 @@ NTSTATUS werror_to_ntstatus(WERROR error) { int i; if (W_ERROR_IS_OK(error)) return NT_STATUS_OK; + + for (i=0; !W_ERROR_IS_OK(werror_to_ntstatus_map[i].werror); i++) { + if (W_ERROR_V(error) == + W_ERROR_V(werror_to_ntstatus_map[i].werror)) { + return werror_to_ntstatus_map[i].ntstatus; + } + } + for (i=0; NT_STATUS_V(ntstatus_to_werror_map[i].ntstatus); i++) { if (W_ERROR_V(error) == W_ERROR_V(ntstatus_to_werror_map[i].werror)) { diff --git a/source3/libsmb/gpo.c b/source3/libsmb/gpo.c new file mode 100644 index 0000000000..0257138ece --- /dev/null +++ b/source3/libsmb/gpo.c @@ -0,0 +1,167 @@ +/* + * Unix SMB/CIFS implementation. + * Group Policy Object Support + * Copyright (C) Guenther Deschner 2005 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +#define GPT_INI_SECTION_GENERAL "General" +#define GPT_INI_PARAMETER_VERSION "Version" +#define GPT_INI_PARAMETER_DISPLAYNAME "displayName" + +struct gpt_ini { + uint32 version; + const char *display_name; +}; + +static uint32 version; + +static BOOL do_section(const char *section) +{ + DEBUG(10,("do_section: %s\n", section)); + + return True; +} + +static BOOL do_parameter(const char *parameter, const char *value) +{ + DEBUG(10,("do_parameter: %s, %s\n", parameter, value)); + + if (strequal(parameter, GPT_INI_PARAMETER_VERSION)) { + version = atoi(value); + } + return True; +} + +NTSTATUS ads_gpo_get_sysvol_gpt_version(ADS_STRUCT *ads, + TALLOC_CTX *mem_ctx, + const char *filesyspath, + uint32 *sysvol_version) +{ + NTSTATUS status; + const char *path; + struct cli_state *cli; + int fnum; + fstring tok; + static int io_bufsize = 64512; + int read_size = io_bufsize; + char *data = NULL; + off_t start = 0; + off_t nread = 0; + int handle = 0; + const char *local_file; + + *sysvol_version = 0; + + next_token(&filesyspath, tok, "\\", sizeof(tok)); + next_token(&filesyspath, tok, "\\", sizeof(tok)); + + path = talloc_asprintf(mem_ctx, "\\%s\\gpt.ini", filesyspath); + if (path == NULL) { + return NT_STATUS_NO_MEMORY; + } + + local_file = talloc_asprintf(mem_ctx, "%s/%s", lock_path("gpo_cache"), "gpt.ini"); + if (local_file == NULL) { + return NT_STATUS_NO_MEMORY; + } + + /* FIXME: walk down the dfs tree instead */ + status = cli_full_connection(&cli, global_myname(), + ads->config.ldap_server_name, + NULL, 0, + "SYSVOL", "A:", + ads->auth.user_name, NULL, ads->auth.password, + CLI_FULL_CONNECTION_USE_KERBEROS, + Undefined, NULL); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + fnum = cli_open(cli, path, O_RDONLY, DENY_NONE); + if (fnum == -1) { + return NT_STATUS_NO_SUCH_FILE; + } + + + data = (char *)SMB_MALLOC(read_size); + if (data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + handle = sys_open(local_file, O_WRONLY|O_CREAT|O_TRUNC, 0644); + + if (handle == -1) { + return NT_STATUS_NO_SUCH_FILE; + } + + while (1) { + + int n = cli_read(cli, fnum, data, nread + start, read_size); + + if (n <= 0) + break; + + if (write(handle, data, n) != n) { + break; + } + + nread += n; + } + + cli_close(cli, fnum); + + if (!pm_process(local_file, do_section, do_parameter)) { + return NT_STATUS_INVALID_PARAMETER; + } + + *sysvol_version = version; + + SAFE_FREE(data); + + cli_shutdown(cli); + + return NT_STATUS_OK; +} + +/* + +perfectly parseable with pm_process() :)) + +[Unicode] +Unicode=yes +[System Access] +MinimumPasswordAge = 1 +MaximumPasswordAge = 42 +MinimumPasswordLength = 7 +PasswordComplexity = 1 +PasswordHistorySize = 24 +LockoutBadCount = 0 +RequireLogonToChangePassword = 0 +ForceLogoffWhenHourExpire = 0 +ClearTextPassword = 0 +[Kerberos Policy] +MaxTicketAge = 10 +MaxRenewAge = 7 +MaxServiceAge = 600 +MaxClockSkew = 5 +TicketValidateClient = 1 +[Version] +signature="$CHICAGO$" +Revision=1 +*/ diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 44cb43c285..03dbd71e93 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3734,7 +3734,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, } if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx, - pol, 1, &str, &sids, + pol, 1, &str, NULL, &sids, &types))) { result = False; goto done; @@ -5927,22 +5927,14 @@ smbc_free_context(SMBCCTX *context, void smbc_option_set(SMBCCTX *context, char *option_name, - ...) + void *option_value) { - va_list args; - - va_start(args, option_name); - if (strcmp(option_name, "debug_stderr") == 0) { /* * Log to standard error instead of standard output. - * - * optional parameters: none (it can't be turned off once on) */ context->internal->_debug_stderr = True; } - - va_end(args); } @@ -5991,6 +5983,7 @@ smbc_init_context(SMBCCTX *context) DEBUGLEVEL = context->debug; load_case_tables(); + setup_logging( "libsmbclient", True); setup_logging("libsmbclient", True); if (context->internal->_debug_stderr) { diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 8b811b06ea..673671d28d 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -24,7 +24,7 @@ Change a password on a remote machine using IPC calls. *************************************************************/ -BOOL remote_password_change(const char *remote_machine, const char *user_name, +NTSTATUS remote_password_change(const char *remote_machine, const char *user_name, const char *old_passwd, const char *new_passwd, char *err_str, size_t err_str_len) { @@ -41,7 +41,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, if(!resolve_name( remote_machine, &ip, 0x20)) { slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n", remote_machine ); - return False; + return NT_STATUS_UNSUCCESSFUL; } ZERO_STRUCT(cli); @@ -49,7 +49,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); - return False; + return NT_STATUS_UNSUCCESSFUL; } make_nmb_name(&calling, global_myname() , 0x0); @@ -59,7 +59,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); cli_shutdown(&cli); - return False; + return NT_STATUS_UNSUCCESSFUL; } cli.protocol = PROTOCOL_NT1; @@ -67,8 +67,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, if (!cli_negprot(&cli)) { slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); + result = cli_nt_error(&cli); cli_shutdown(&cli); - return False; + return result; } /* Given things like SMB signing, restrict anonymous and the like, @@ -90,7 +91,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, "connect to machine %s: %s\n", remote_machine, cli_errstr(&cli)); cli_shutdown(&cli); - return False; + return result; } pass_must_change = True; @@ -105,8 +106,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); + result = cli_nt_error(&cli); cli_shutdown(&cli); - return False; + return result; } cli_init_creds(&cli, "", "", NULL); @@ -117,8 +119,9 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine, cli_errstr(&cli) ); + result = cli_nt_error(&cli); cli_shutdown(&cli); - return False; + return result; } /* Try not to give the password away too easily */ @@ -149,16 +152,18 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", remote_machine, cli_errstr(&cli) ); + result = cli_nt_error(&cli); cli_shutdown(&cli); - return False; + return result; } } else { slprintf(err_str, err_str_len-1, "SAMR connection to machine %s failed. Error was %s, " "but LANMAN password changed are disabled\n", nt_errstr(result), remote_machine); + result = cli_nt_error(&cli); cli_shutdown(&cli); - return False; + return result; } } @@ -166,7 +171,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, new_passwd, old_passwd))) { /* Great - it all worked! */ cli_shutdown(&cli); - return True; + return NT_STATUS_OK; } else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { @@ -175,7 +180,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); cli_shutdown(&cli); - return False; + return result; } /* OK, that failed, so try again... */ @@ -197,7 +202,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, old_passwd)))) { /* Great - it all worked! */ cli_shutdown(&cli); - return True; + return NT_STATUS_OK; } else { if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { @@ -207,7 +212,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, "machine %s rejected the (anonymous) password change: Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); cli_shutdown(&cli); - return False; + return result; } /* We have failed to change the user's password, and we think the server @@ -219,20 +224,21 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name, /* SAMR failed, but the old LanMan protocol worked! */ cli_shutdown(&cli); - return True; + return NT_STATUS_OK; } slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", remote_machine, cli_errstr(&cli) ); + result = cli_nt_error(&cli); cli_shutdown(&cli); - return False; + return result; } else { slprintf(err_str, err_str_len-1, "SAMR connection to machine %s failed. Error was %s, " "but LANMAN password changed are disabled\n", nt_errstr(result), remote_machine); cli_shutdown(&cli); - return False; + return NT_STATUS_UNSUCCESSFUL; } } } -- cgit From 2268658171038ab7d8a5f722c5d3f7b273191f1c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 3 Feb 2006 23:31:56 +0000 Subject: r13322: Fix warning time_t != int. Jeremy. (This used to be commit 6196446a03abeb4100bac1721977488ae5843f42) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0986e7f29a..1520e6cec2 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -67,8 +67,8 @@ BOOL saf_store( const char *domain, const char *servername ) expire = time( NULL ) + SAF_TTL; - DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%d]\n", - domain, servername, expire )); + DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n", + domain, servername, (unsigned int)expire )); ret = gencache_set( key, servername, expire ); -- cgit From 40d3c7ebb22bae6f486e8c60c3bb0494d2d397d9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 4 Feb 2006 06:31:04 +0000 Subject: r13329: Fix libsmbsharemodes.so to work with the stored delete token. Less trouble than I thought plus it didn't need an interface change (thank goodness !). Jeremy. (This used to be commit dbe2572d1c713f46b0d1d0c405f88456c9336297) --- source3/libsmb/smb_share_modes.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 86071ee2e9..f7e7baf445 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -2,7 +2,7 @@ Samba share mode database library external interface library. Used by non-Samba products needing access to the Samba share mode db. - Copyright (C) Jeremy Allison 2005. + Copyright (C) Jeremy Allison 2005 - 2006 sharemodes_procid functions (C) Copyright (C) Volker Lendecke 2005 @@ -25,6 +25,11 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* + * Version 2 - interface changed to handle the token added for correct + * delete on close semantics. + */ + #include "includes.h" #include "smb_share_modes.h" @@ -115,9 +120,7 @@ int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, return tdb_chainunlock(db_ctx->smb_tdb, get_locking_key(dev, ino)); } -/* Internal structure of Samba share mode db. */ -/* FIXME ! This should be moved into a Samba include file. */ - +#if 0 struct locking_data { union { struct { @@ -132,12 +135,14 @@ struct locking_data { char file_name[]; */ }; +#endif /* * Check if an external smb_share_mode_entry and an internal share_mode entry match. */ -static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, const struct share_mode_entry *entry) +static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, + const struct share_mode_entry *entry) { return (sharemodes_procid_equal(&e_entry->pid, &entry->pid) && e_entry->file_id == (uint32_t)entry->share_file_id && @@ -153,7 +158,8 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, co * Create an internal Samba share_mode entry from an external smb_share_mode_entry. */ -static void create_share_mode_entry(struct share_mode_entry *out, const struct smb_share_mode_entry *in) +static void create_share_mode_entry(struct share_mode_entry *out, + const struct smb_share_mode_entry *in) { memset(out, '\0', sizeof(struct share_mode_entry)); @@ -281,9 +287,11 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, return -1; } ld = (struct locking_data *)db_data.dptr; + memset(ld, '\0', sizeof(struct locking_data)); ld->u.s.num_share_mode_entries = 1; ld->u.s.delete_on_close = 0; ld->u.s.initial_delete_on_close = 0; + ld->u.s.delete_token_size = 0; shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); create_share_mode_entry(shares, new_entry); @@ -328,7 +336,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)new_data_p; ld->u.s.num_share_mode_entries++; - /* Append the original filename */ + /* Append the original delete_token and filenames. */ memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(struct share_mode_entry)), db_data.dptr + ((orig_num_share_modes+1)*sizeof(struct share_mode_entry)), db_data.dsize - ((orig_num_share_modes+1) * sizeof(struct share_mode_entry))); @@ -378,9 +386,9 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, struct locking_data *ld = NULL; /* internal samba db state. */ struct share_mode_entry *shares = NULL; char *new_data_p = NULL; - size_t filename_size = 0; + size_t remaining_size = 0; size_t i, num_share_modes; - const char *fname_ptr = NULL; + const char *remaining_ptr = NULL; db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { @@ -440,13 +448,13 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, return tdb_delete(db_ctx->smb_tdb, locking_key); } - /* Copy the terminating filename. */ - fname_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(struct share_mode_entry)); - filename_size = db_data.dsize - (fname_ptr - db_data.dptr); + /* Copy any delete token plus the terminating filenames. */ + remaining_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(struct share_mode_entry)); + remaining_size = db_data.dsize - (remaining_ptr - db_data.dptr); memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)), - fname_ptr, - filename_size); + remaining_ptr, + remaining_size); free(db_data.dptr); @@ -456,7 +464,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; ld->u.s.num_share_mode_entries = num_share_modes; - db_data.dsize = ((num_share_modes+1)*sizeof(struct share_mode_entry)) + filename_size; + db_data.dsize = ((num_share_modes+1)*sizeof(struct share_mode_entry)) + remaining_size; if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { free(db_data.dptr); -- cgit From 7f5e36df8d3fcee507325c97aeea41cbbd870e0d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 4 Feb 2006 06:36:02 +0000 Subject: r13331: No I didn't have to change the interface version... Jeremy. (This used to be commit 2aed5b36409e05ac25b4492669f47d50be988f2c) --- source3/libsmb/smb_share_modes.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index f7e7baf445..090571b810 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -25,11 +25,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* - * Version 2 - interface changed to handle the token added for correct - * delete on close semantics. - */ - #include "includes.h" #include "smb_share_modes.h" @@ -120,23 +115,6 @@ int smb_unlock_share_mode_entry(struct smbdb_ctx *db_ctx, return tdb_chainunlock(db_ctx->smb_tdb, get_locking_key(dev, ino)); } -#if 0 -struct locking_data { - union { - struct { - int num_share_mode_entries; - BOOL delete_on_close; - BOOL initial_delete_on_close; - } s; - struct share_mode_entry dummy; /* Needed for alignment. */ - } u; - /* the following two entries are implicit - struct share_mode_entry modes[num_share_mode_entries]; - char file_name[]; - */ -}; -#endif - /* * Check if an external smb_share_mode_entry and an internal share_mode entry match. */ -- cgit From 86358fc10bb02bd3069736bedb120f52fa3f6494 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 8 Feb 2006 22:16:03 +0000 Subject: r13396: Add in userinfo26, re-enable userinfo25 - took the knowledge from Samba4 on how to decode the 532 byte password buffers. Getting closer to passing samba4 RPC-SCHANNEL test. Jeremy. (This used to be commit 205db6968a26c43dec64c14d8053d8e66807086f) --- source3/libsmb/smbencrypt.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 99f99f23f8..5bdd0acd3e 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -530,6 +530,25 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, return True; } +/*********************************************************** + Decode an arc4 encrypted password change buffer. +************************************************************/ + +void encode_or_decode_arc4_passwd_buffer(char pw_buf[532], const DATA_BLOB *psession_key) +{ + struct MD5Context tctx; + unsigned char key_out[16]; + + /* Confounder is last 16 bytes. */ + + MD5Init(&tctx); + MD5Update(&tctx, &pw_buf[516], 16); + MD5Update(&tctx, psession_key->data, psession_key->length); + MD5Final(key_out, &tctx); + /* arc4 with key_out. */ + SamOEMhash(pw_buf, key_out, 516); +} + /*********************************************************** Encrypt/Decrypt used for LSA secrets and trusted domain passwords. -- cgit From ad8b47a2ba4e81420bc2272e8438a727cc2223ee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Feb 2006 07:03:23 +0000 Subject: r13407: Change the credentials code to be more like the Samba4 structure, makes fixes much easier to port. Fix the size of dc->sess_key to be 16 bytes, not 8 bytes - only store 8 bytes in the inter-smbd store in secrets.tdb though. Should fix some uses of the dc->sess_key where we where assuming we could read 16 bytes. Jeremy. (This used to be commit 5b3c2e63c73fee8949108abe19ac7a448a033a7f) --- source3/libsmb/credentials.c | 97 ++++++++++++++++++-------------------------- source3/libsmb/smbdes.c | 36 +++++++++++++--- 2 files changed, 71 insertions(+), 62 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index ad06cd9015..795c30d12d 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -36,38 +36,52 @@ char *credstr(const uchar *cred) /**************************************************************************** - Setup the session key. - Input: 8 byte challenge block - 8 byte server challenge block - 16 byte md4 encrypted password - Output: - 16 byte session key (last 8 bytes zero). + Setup the session key and the client and server creds in dc. + Used by both client and server creds setup. ****************************************************************************/ -static void cred_create_session_key(const DOM_CHAL *clnt_chal_in, +static void creds_init_64(struct dcinfo *dc, + const DOM_CHAL *clnt_chal_in, const DOM_CHAL *srv_chal_in, - const uchar *pass_in, - uchar session_key_out[16]) + const char mach_pw[16]) { uint32 sum[2]; unsigned char sum2[8]; + /* Just in case this isn't already there */ + memcpy(dc->mach_pw, mach_pw, 16); + sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0); sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4); SIVAL(sum2,0,sum[0]); SIVAL(sum2,4,sum[1]); - cred_hash1(session_key_out, sum2, pass_in); - memset(&session_key_out[8], '\0', 8); + ZERO_STRUCT(dc->sess_key); - /* debug output */ - DEBUG(4,("cred_create_session_key\n")); + des_crypt128(dc->sess_key, sum2, dc->mach_pw); + /* debug output */ + DEBUG(5,("creds_init_64\n")); DEBUG(5,(" clnt_chal_in: %s\n", credstr(clnt_chal_in->data))); DEBUG(5,(" srv_chal_in : %s\n", credstr(srv_chal_in->data))); DEBUG(5,(" clnt+srv : %s\n", credstr(sum2))); - DEBUG(5,(" sess_key_out : %s\n", credstr(session_key_out))); + DEBUG(5,(" sess_key_out : %s\n", credstr(dc->sess_key))); + + /* Generate the next client and server creds. */ + + des_crypt112(dc->clnt_chal.data, /* output */ + clnt_chal_in->data, /* input */ + dc->sess_key, /* input */ + 1); + + des_crypt112(dc->srv_chal.data, /* output */ + srv_chal_in->data, /* input */ + dc->sess_key, /* input */ + 1); + + /* Seed is the client chal. */ + memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8); } /**************************************************************************** @@ -88,7 +102,7 @@ static void creds_step(struct dcinfo *dc) DEBUG(5,("\tseed+seq %s\n", credstr(time_chal.data) )); - cred_hash2(dc->clnt_chal.data, time_chal.data, dc->sess_key); + des_crypt112(dc->clnt_chal.data, time_chal.data, dc->sess_key, 1); DEBUG(5,("\tCLIENT %s\n", credstr(dc->clnt_chal.data) )); @@ -97,12 +111,11 @@ static void creds_step(struct dcinfo *dc) DEBUG(5,("\tseed+seq+1 %s\n", credstr(time_chal.data) )); - cred_hash2(dc->srv_chal.data, time_chal.data, dc->sess_key); + des_crypt112(dc->srv_chal.data, time_chal.data, dc->sess_key, 1); DEBUG(5,("\tSERVER %s\n", credstr(dc->srv_chal.data) )); } - /**************************************************************************** Create a server credential struct. ****************************************************************************/ @@ -117,29 +130,14 @@ void creds_server_init(struct dcinfo *dc, DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) )); dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16); - /* Just in case this isn't already there */ - memcpy(dc->mach_pw, mach_pw, 16); - - /* Generate the session key. */ - cred_create_session_key(clnt_chal, /* Stored client challenge. */ - srv_chal, /* Stored server challenge. */ - dc->mach_pw, /* input machine password. */ - dc->sess_key); /* output session key. */ + /* Generate the session key and the next client and server creds. */ + creds_init_64(dc, + clnt_chal, + srv_chal, + mach_pw); dump_data_pw("creds_server_init: session key", dc->sess_key, 16); - /* Generate the next client and server creds. */ - cred_hash2(dc->clnt_chal.data, /* output */ - clnt_chal->data, /* input */ - dc->sess_key); /* input */ - - cred_hash2(dc->srv_chal.data, /* output */ - srv_chal->data, /* input */ - dc->sess_key); /* input */ - - /* Seed is the client chal. */ - memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8); - DEBUG(10,("creds_server_init: clnt : %s\n", credstr(dc->clnt_chal.data) )); DEBUG(10,("creds_server_init: server : %s\n", credstr(dc->srv_chal.data) )); DEBUG(10,("creds_server_init: seed : %s\n", credstr(dc->seed_chal.data) )); @@ -214,29 +212,14 @@ void creds_client_init(struct dcinfo *dc, DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) )); dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16); - /* Just in case this isn't already there */ - memcpy(dc->mach_pw, mach_pw, 16); - - /* Generate the session key. */ - cred_create_session_key(clnt_chal, /* Stored client challenge. */ - srv_chal, /* Stored server challenge. */ - dc->mach_pw, /* input machine password. */ - dc->sess_key); /* output session key. */ + /* Generate the session key and the next client and server creds. */ + creds_init_64(dc, + clnt_chal, + srv_chal, + mach_pw); dump_data_pw("creds_client_init: session key", dc->sess_key, 16); - /* Generate the next client and server creds. */ - cred_hash2(dc->clnt_chal.data, /* output */ - clnt_chal->data, /* input */ - dc->sess_key); /* input */ - - cred_hash2(dc->srv_chal.data, /* output */ - srv_chal->data, /* input */ - dc->sess_key); /* input */ - - /* Seed is the client cred. */ - memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8); - DEBUG(10,("creds_client_init: clnt : %s\n", credstr(dc->clnt_chal.data) )); DEBUG(10,("creds_client_init: server : %s\n", credstr(dc->srv_chal.data) )); DEBUG(10,("creds_client_init: seed : %s\n", credstr(dc->seed_chal.data) )); diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 4378385f3f..ee43f4beee 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -258,7 +258,8 @@ static void dohash(char *out, char *in, char *key, int forw) permute(out, rl, perm6, 64); } -static void str_to_key(const unsigned char *str,unsigned char *key) +/* Convert a 7 byte string to an 8 byte key. */ +static void str_to_key(const unsigned char str[7], unsigned char key[8]) { int i; @@ -330,7 +331,8 @@ void E_old_pw_hash( unsigned char *p14, const unsigned char *in, unsigned char * des_crypt56(out+8, in+8, p14+7, 1); } -void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char *key) +/* forward des encryption with a 128 bit key */ +void des_crypt128(unsigned char out[8], const unsigned char in[8], const unsigned char key[16]) { unsigned char buf[8]; @@ -338,25 +340,49 @@ void cred_hash1(unsigned char *out, const unsigned char *in, const unsigned char des_crypt56(out, buf, key+9, 1); } -void cred_hash2(unsigned char *out, const unsigned char *in, const unsigned char *key) +/* forward des encryption with a 64 bit key */ +void des_crypt64(unsigned char out[8], const unsigned char in[8], const unsigned char key[8]) { unsigned char buf[8]; - static unsigned char key2[8]; + unsigned char key2[8]; + memset(key2,'\0',8); des_crypt56(buf, in, key, 1); key2[0] = key[7]; des_crypt56(out, buf, key2, 1); } +/* des encryption with a 112 bit (14 byte) key */ +/* Note that if the forw is 1, and key is actually 8 bytes of key, followed by 6 bytes of zeros, + this is identical to des_crypt64(). JRA. */ + +void des_crypt112(unsigned char out[8], const unsigned char in[8], const unsigned char key[14], int forw) +{ + unsigned char buf[8]; + des_crypt56(buf, in, key, forw); + des_crypt56(out, buf, key+7, forw); +} + void cred_hash3(unsigned char *out, const unsigned char *in, const unsigned char *key, int forw) { - static unsigned char key2[8]; + unsigned char key2[8]; + memset(key2,'\0',8); des_crypt56(out, in, key, forw); key2[0] = key[7]; des_crypt56(out + 8, in + 8, key2, forw); } +/* des encryption of a 16 byte lump of data with a 112 bit key */ +/* Note that if the key is actually 8 bytes of key, followed by 6 bytes of zeros, + this is identical to cred_hash3(). JRA. */ + +void des_crypt112_16(unsigned char out[16], unsigned char in[16], const unsigned char key[14], int forw) +{ + des_crypt56(out, in, key, forw); + des_crypt56(out + 8, in + 8, key+7, forw); +} + /***************************************************************** arc4 crypt/decrypt with a 16 byte key. *****************************************************************/ -- cgit From d672d8fd6bd2957f6177c809c77b3d2c1a2fddca Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 12 Feb 2006 16:44:30 +0000 Subject: r13473: Back port r13470, r13471, r13472 from Samba4. Thanks Andrew: ----------------------------------- Thanks to a report from VL: We were causing mayhem by weakening the keys at the wrong point in time. I think this is the correct place to do it. The session key for SMB signing, and the 'smb session key' (used for encrypting password sets) is never weakened. The session key used for bulk data encryption/signing is weakened. This also makes more sense, when we look at the NTLM2 code. Andrew Bartlett ----------------------------------- With more 'try all options' testing, I found this 'simple' but in the NTLM2 signing code. Andrew Bartlett ----------------------------------- After Volker's advise, try every combination of parameters. This isn't every parameter on NTLMSSP, but it is most of the important ones. This showed up that we had the '128bit && LM_KEY' case messed up. This isn't supported, so we must look instead at the 56 bit flag. Andrew Bartlett ----------------------------------- We should now try retesting with NT4. This should be standalone enough to port into a SAMBA_3_0_RELEASE branch fix. Jeremy. (This used to be commit b9b8cd1752aeab049983c1a6038edf2231ec10a4) --- source3/libsmb/ntlmssp.c | 43 ++++++++++++++++++++++++++----------------- source3/libsmb/ntlmssp_sign.c | 31 +++++++++++++++++++------------ 2 files changed, 45 insertions(+), 29 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index c891ede9bb..e1ef69aed9 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -72,6 +72,8 @@ void debug_ntlmssp_flags(uint32 neg_flags) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DATAGRAM_STYLE) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DATAGRAM_STYLE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) @@ -86,6 +88,10 @@ void debug_ntlmssp_flags(uint32 neg_flags) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_CHAL_ACCEPT_RESPONSE) + DEBUGADD(4, (" NTLMSSP_CHAL_ACCEPT_RESPONSE\n")); + if (neg_flags & NTLMSSP_CHAL_NON_NT_SESSION_KEY) + DEBUGADD(4, (" NTLMSSP_CHAL_NON_NT_SESSION_KEY\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) @@ -94,6 +100,8 @@ void debug_ntlmssp_flags(uint32 neg_flags) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_56) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_56\n")); } /** @@ -382,11 +390,16 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, by the client lanman auth/lanman auth parameters, it isn't too bad. */ -void ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state) +DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx) { + DATA_BLOB weakened_key = data_blob_talloc(mem_ctx, + ntlmssp_state->session_key.data, + ntlmssp_state->session_key.length); + /* Nothing to weaken. We certainly don't want to 'extend' the length... */ - if (ntlmssp_state->session_key.length < 8) { - return; + if (weakened_key.length < 16) { + /* perhaps there was no key? */ + return weakened_key; } /* Key weakening not performed on the master key for NTLM2 @@ -395,17 +408,19 @@ void ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state) */ if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { - ; - } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { - ntlmssp_state->session_key.data[7] = 0xa0; + /* LM key doesn't support 128 bit crypto, so this is + * the best we can do. If you negotiate 128 bit, but + * not 56, you end up with 40 bit... */ + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { + weakened_key.data[7] = 0xa0; } else { /* forty bits */ - ntlmssp_state->session_key.data[5] = 0xe5; - ntlmssp_state->session_key.data[6] = 0x38; - ntlmssp_state->session_key.data[7] = 0xb0; + weakened_key.data[5] = 0xe5; + weakened_key.data[6] = 0x38; + weakened_key.data[7] = 0xb0; } - ntlmssp_state->session_key.length = 8; + weakened_key.length = 8; } + return weakened_key; } /** @@ -775,9 +790,6 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = session_key; } - /* The client might need us to use a partial-strength session key */ - ntlmssp_weaken_keys(ntlmssp_state); - if (!NT_STATUS_IS_OK(nt_status)) { ntlmssp_state->session_key = data_blob(NULL, 0); } else if (ntlmssp_state->session_key.length) { @@ -1093,9 +1105,6 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->session_key = session_key; - /* The client might be using 56 or 40 bit weakened keys */ - ntlmssp_weaken_keys(ntlmssp_state); - ntlmssp_state->chal = challenge_blob; ntlmssp_state->lm_resp = lm_response; ntlmssp_state->nt_resp = nt_response; diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index cc6323718b..1cdb2d1e00 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -328,17 +328,22 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) { unsigned char p24[24]; ZERO_STRUCT(p24); + TALLOC_CTX *mem_ctx = talloc_init("weak_keys"); + + if (!mem_ctx) { + return NT_STATUS_NO_MEMORY; + } DEBUG(3, ("NTLMSSP Sign/Seal - Initialising with flags:\n")); debug_ntlmssp_flags(ntlmssp_state->neg_flags); - if (!ntlmssp_state->session_key.length) { + if (ntlmssp_state->session_key.length < 8) { + talloc_free(mem_ctx); DEBUG(3, ("NO session key, cannot intialise signing\n")); return NT_STATUS_NO_USER_SESSION_KEY; } - if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - { + if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { DATA_BLOB weak_session_key = ntlmssp_state->session_key; const char *send_sign_const; const char *send_seal_const; @@ -359,11 +364,8 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) recv_seal_const = CLI_SEAL; break; default: - send_sign_const = "unknown role"; - send_seal_const = "unknown role"; - recv_sign_const = "unknown role"; - recv_seal_const = "unknown role"; - break; + talloc_free(mem_ctx); + return NT_STATUS_INTERNAL_ERROR; } /** @@ -374,7 +376,7 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_128) { ; } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_56) { - weak_session_key.length = 6; + weak_session_key.length = 7; } else { /* forty bits */ weak_session_key.length = 5; } @@ -383,12 +385,13 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) weak_session_key.data, weak_session_key.length); - /* SEND */ + /* SEND: sign key */ calc_ntlmv2_key(ntlmssp_state->send_sign_key, ntlmssp_state->session_key, send_sign_const); dump_data_pw("NTLMSSP send sign key:\n", ntlmssp_state->send_sign_key, 16); + /* SEND: seal ARCFOUR pad */ calc_ntlmv2_key(ntlmssp_state->send_seal_key, weak_session_key, send_seal_const); dump_data_pw("NTLMSSP send seal key:\n", @@ -401,12 +404,13 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) ntlmssp_state->send_seal_arc4_state, sizeof(ntlmssp_state->send_seal_arc4_state)); - /* RECV */ + /* RECV: sign key */ calc_ntlmv2_key(ntlmssp_state->recv_sign_key, ntlmssp_state->session_key, recv_sign_const); dump_data_pw("NTLMSSP recv send sign key:\n", ntlmssp_state->recv_sign_key, 16); + /* RECV: seal ARCFOUR pad */ calc_ntlmv2_key(ntlmssp_state->recv_seal_key, weak_session_key, recv_seal_const); @@ -446,10 +450,12 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) weak_session_key.length); #endif + DATA_BLOB weak_session_key = ntlmssp_weaken_keys(ntlmssp_state, mem_ctx); + DEBUG(5, ("NTLMSSP Sign/Seal - using NTLM1\n")); smb_arc4_init(ntlmssp_state->ntlmv1_arc4_state, - ntlmssp_state->session_key.data, ntlmssp_state->session_key.length); + weak_session_key.data, weak_session_key.length); dump_data_pw("NTLMv1 arc4 state:\n", ntlmssp_state->ntlmv1_arc4_state, sizeof(ntlmssp_state->ntlmv1_arc4_state)); @@ -457,5 +463,6 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) ntlmssp_state->ntlmv1_seq_num = 0; } + talloc_free(mem_ctx); return NT_STATUS_OK; } -- cgit From 71247a2f0507d13fa37d5b3c7136e299995af877 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 12 Feb 2006 17:49:04 +0000 Subject: r13477: Fix code before declaration (This used to be commit c15f1d553f03ad1ed4e1d52b8e46c52202bc3a83) --- source3/libsmb/ntlmssp_sign.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 1cdb2d1e00..68d4b7aec7 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -327,9 +327,10 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) { unsigned char p24[24]; + TALLOC_CTX *mem_ctx; ZERO_STRUCT(p24); - TALLOC_CTX *mem_ctx = talloc_init("weak_keys"); + mem_ctx = talloc_init("weak_keys"); if (!mem_ctx) { return NT_STATUS_NO_MEMORY; } -- cgit From 3df82f57fcb97eedb53473bc719101e626c4de84 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Feb 2006 13:25:36 +0000 Subject: r13489: Fix #3496 from jason@ncac.gwu.edu. Variable set but never used. Jeremy. (This used to be commit 4204794cc7c5e2671259652879c33f539d26958c) --- source3/libsmb/ntlmssp_sign.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 68d4b7aec7..42ed0f9418 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -236,8 +236,6 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, uchar *whole_pdu, size_t pdu_length, DATA_BLOB *sig) { - NTSTATUS nt_status; - if (!(ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { DEBUG(3, ("NTLMSSP Sealing not negotiated - cannot seal packet!\n")); return NT_STATUS_INVALID_PARAMETER; @@ -254,10 +252,14 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, /* The order of these two operations matters - we must first seal the packet, then seal the sequence number - this is becouse the send_seal_hash is not constant, but is is rather updated with each iteration */ - nt_status = ntlmssp_make_packet_signature(ntlmssp_state, + NTSTATUS nt_status = ntlmssp_make_packet_signature(ntlmssp_state, data, length, whole_pdu, pdu_length, NTLMSSP_SEND, sig, False); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } + smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { smb_arc4_crypt(ntlmssp_state->send_seal_arc4_state, sig->data+4, 8); @@ -283,8 +285,6 @@ NTSTATUS ntlmssp_seal_packet(NTLMSSP_STATE *ntlmssp_state, smb_arc4_crypt(ntlmssp_state->ntlmv1_arc4_state, sig->data+4, sig->length-4); ntlmssp_state->ntlmv1_seq_num++; - - nt_status = NT_STATUS_OK; } dump_data_pw("ntlmssp signature\n", sig->data, sig->length); dump_data_pw("ntlmssp sealed data\n", data, length); -- cgit From c9b5c9b9412a208b105513c0194bd9654a3f1144 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 14 Feb 2006 12:35:56 +0000 Subject: r13495: Derell, I'm removing that double setup_logging(), just a typo. Guenther (This used to be commit c0d91f9d19b33995237847389e4c37e086938b9e) --- source3/libsmb/libsmbclient.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 03dbd71e93..649cd8b372 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5983,7 +5983,6 @@ smbc_init_context(SMBCCTX *context) DEBUGLEVEL = context->debug; load_case_tables(); - setup_logging( "libsmbclient", True); setup_logging("libsmbclient", True); if (context->internal->_debug_stderr) { -- cgit From 8189bb6e4c5a3cde757bb7823f51541c8940914b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Feb 2006 02:07:14 +0000 Subject: r13502: Fix error messages for usershares when smbd is not running. More generic error return cleanup in libsmb/ needs doing (everything returning NTSTATUS not BOOL). Jeremy (This used to be commit 654bb9853b450c5d509d182f67ec26ac320fd590) --- source3/libsmb/cliconnect.c | 13 ++++++++++--- source3/libsmb/nterr.c | 4 ++++ 2 files changed, 14 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6f32fb1b5d..4c6b890db0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1394,7 +1394,11 @@ again: DEBUG(1,("cli_start_connection: failed to connect to %s (%s)\n", nmb_namestr(&called), inet_ntoa(ip))); cli_shutdown(cli); - return NT_STATUS_UNSUCCESSFUL; + if (is_zero_ip(ip)) { + return NT_STATUS_BAD_NETWORK_NAME; + } else { + return NT_STATUS_CONNECTION_REFUSED; + } } if (retry) @@ -1412,7 +1416,7 @@ again: make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_BAD_NETWORK_NAME; } cli_setup_signing_state(cli, signing_state); @@ -1424,7 +1428,10 @@ again: if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); - nt_status = NT_STATUS_UNSUCCESSFUL; + nt_status = cli_nt_error(cli); + if (NT_STATUS_IS_OK(nt_status)) { + nt_status = NT_STATUS_UNSUCCESSFUL; + } cli_shutdown(cli); return nt_status; } diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 677c5d84c7..4f97379ee0 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -541,6 +541,8 @@ static nt_err_code_struct nt_errs[] = { NULL, NT_STATUS(0) } }; +/* These need sorting..... */ + nt_err_code_struct nt_err_desc[] = { { "Success", NT_STATUS_OK }, @@ -595,6 +597,8 @@ nt_err_code_struct nt_err_desc[] = { "Duplicate name on network", NT_STATUS_DUPLICATE_NAME }, { "Print queue is full", NT_STATUS_PRINT_QUEUE_FULL }, { "No print spool space available", NT_STATUS_NO_SPOOL_SPACE }, + { "The network name cannot be found", NT_STATUS_BAD_NETWORK_NAME }, + { "The connection was refused", NT_STATUS_CONNECTION_REFUSED }, { "Too many names", NT_STATUS_TOO_MANY_NAMES }, { "Too many sessions", NT_STATUS_TOO_MANY_SESSIONS }, { "Invalid server state", NT_STATUS_INVALID_SERVER_STATE }, -- cgit From 3e4cf56fa3f9d465d27dadaa6790bbcdea5d3cd9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Feb 2006 23:15:55 +0000 Subject: r13519: Fix the credentials chaining across netlogon pipe disconnects. I mean it this time :-). Jeremy. (This used to be commit 80f4868944d349015d2b64c2414b06466a8194aa) --- source3/libsmb/credentials.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 795c30d12d..5026f513ab 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -183,17 +183,30 @@ static void creds_reseed(struct dcinfo *dc) BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out) { - dc->sequence = received_cred->timestamp.time; + BOOL ret; + struct dcinfo tmp_dc = *dc; - creds_step(dc); + /* Do all operations on a temporary copy of the dc, + which we throw away if the checks fail. */ + + tmp_dc.sequence = received_cred->timestamp.time; + + creds_step(&tmp_dc); /* Create the outgoing credentials */ - cred_out->timestamp.time = dc->sequence + 1; - cred_out->challenge = dc->srv_chal; + cred_out->timestamp.time = tmp_dc.sequence + 1; + cred_out->challenge = tmp_dc.srv_chal; - creds_reseed(dc); + creds_reseed(&tmp_dc); - return creds_server_check(dc, &received_cred->challenge); + ret = creds_server_check(&tmp_dc, &received_cred->challenge); + if (!ret) { + return False; + } + + /* creds step succeeded - replace the current creds. */ + *dc = tmp_dc; + return True; } /**************************************************************************** -- cgit From 39a572e0106696e24540d9829812917635c1fd06 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 17 Feb 2006 04:22:32 +0000 Subject: r13539: Add 128 bit creds processing client and server. Thanks to Andrew Bartlett's Samba4 code. Jeremy. (This used to be commit a2fb436fc5dd536cfe860be93f55f9cb58139a0e) --- source3/libsmb/credentials.c | 88 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 79 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 5026f513ab..975f9bca49 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -25,7 +25,7 @@ Represent a credential as a string. ****************************************************************************/ -char *credstr(const uchar *cred) +char *credstr(const unsigned char *cred) { static fstring buf; slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", @@ -34,6 +34,58 @@ char *credstr(const uchar *cred) return buf; } +/**************************************************************************** + Setup the session key and the client and server creds in dc. + ADS-style 128 bit session keys. + Used by both client and server creds setup. +****************************************************************************/ + +static void creds_init_128(struct dcinfo *dc, + const DOM_CHAL *clnt_chal_in, + const DOM_CHAL *srv_chal_in, + const char mach_pw[16]) +{ + unsigned char zero[4], tmp[16]; + HMACMD5Context ctx; + struct MD5Context md5; + + /* Just in case this isn't already there */ + memcpy(dc->mach_pw, mach_pw, 16); + + ZERO_STRUCT(dc->sess_key); + + memset(zero, 0, sizeof(zero)); + + hmac_md5_init_rfc2104(mach_pw, 16, &ctx); + MD5Init(&md5); + MD5Update(&md5, zero, sizeof(zero)); + MD5Update(&md5, clnt_chal_in->data, 8); + MD5Update(&md5, srv_chal_in->data, 8); + MD5Final(tmp, &md5); + hmac_md5_update(tmp, sizeof(tmp), &ctx); + hmac_md5_final(dc->sess_key, &ctx); + + /* debug output */ + DEBUG(5,("creds_init_128\n")); + DEBUG(5,("\tclnt_chal_in: %s\n", credstr(clnt_chal_in->data))); + DEBUG(5,("\tsrv_chal_in : %s\n", credstr(srv_chal_in->data))); + dump_data_pw("\tsession_key ", (const unsigned char *)dc->sess_key, 16); + + /* Generate the next client and server creds. */ + + des_crypt112(dc->clnt_chal.data, /* output */ + clnt_chal_in->data, /* input */ + dc->sess_key, /* input */ + 1); + + des_crypt112(dc->srv_chal.data, /* output */ + srv_chal_in->data, /* input */ + dc->sess_key, /* input */ + 1); + + /* Seed is the client chal. */ + memcpy(dc->seed_chal.data, dc->clnt_chal.data, 8); +} /**************************************************************************** Setup the session key and the client and server creds in dc. @@ -63,10 +115,10 @@ static void creds_init_64(struct dcinfo *dc, /* debug output */ DEBUG(5,("creds_init_64\n")); - DEBUG(5,(" clnt_chal_in: %s\n", credstr(clnt_chal_in->data))); - DEBUG(5,(" srv_chal_in : %s\n", credstr(srv_chal_in->data))); - DEBUG(5,(" clnt+srv : %s\n", credstr(sum2))); - DEBUG(5,(" sess_key_out : %s\n", credstr(dc->sess_key))); + DEBUG(5,("\tclnt_chal_in: %s\n", credstr(clnt_chal_in->data))); + DEBUG(5,("\tsrv_chal_in : %s\n", credstr(srv_chal_in->data))); + DEBUG(5,("\tclnt+srv : %s\n", credstr(sum2))); + DEBUG(5,("\tsess_key_out : %s\n", credstr(dc->sess_key))); /* Generate the next client and server creds. */ @@ -120,21 +172,30 @@ static void creds_step(struct dcinfo *dc) Create a server credential struct. ****************************************************************************/ -void creds_server_init(struct dcinfo *dc, +void creds_server_init(uint32 neg_flags, + struct dcinfo *dc, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, const char mach_pw[16], DOM_CHAL *init_chal_out) { + DEBUG(10,("creds_server_init: neg_flags : %x\n", (unsigned int)neg_flags)); DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) )); DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) )); dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16); /* Generate the session key and the next client and server creds. */ - creds_init_64(dc, + if (neg_flags & NETLOGON_NEG_128BIT) { + creds_init_128(dc, clnt_chal, srv_chal, mach_pw); + } else { + creds_init_64(dc, + clnt_chal, + srv_chal, + mach_pw); + } dump_data_pw("creds_server_init: session key", dc->sess_key, 16); @@ -213,7 +274,8 @@ BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRE Create a client credential struct. ****************************************************************************/ -void creds_client_init(struct dcinfo *dc, +void creds_client_init(uint32 neg_flags, + struct dcinfo *dc, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, const unsigned char mach_pw[16], @@ -221,15 +283,23 @@ void creds_client_init(struct dcinfo *dc, { dc->sequence = time(NULL); + DEBUG(10,("creds_client_init: neg_flags : %x\n", (unsigned int)neg_flags)); DEBUG(10,("creds_client_init: client chal : %s\n", credstr(clnt_chal->data) )); DEBUG(10,("creds_client_init: server chal : %s\n", credstr(srv_chal->data) )); dump_data_pw("creds_client_init: machine pass", (const unsigned char *)mach_pw, 16); /* Generate the session key and the next client and server creds. */ - creds_init_64(dc, + if (neg_flags & NETLOGON_NEG_128BIT) { + creds_init_128(dc, + clnt_chal, + srv_chal, + mach_pw); + } else { + creds_init_64(dc, clnt_chal, srv_chal, mach_pw); + } dump_data_pw("creds_client_init: session key", dc->sess_key, 16); -- cgit From 9132acff082381b32961eb2b3244b8fedd4df218 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 18 Feb 2006 00:27:31 +0000 Subject: r13553: Fix all our warnings at -O6 on an x86_64 box. Jeremy. (This used to be commit ea82958349a57ef4b7ce9638eec5f1388b0fba2a) --- source3/libsmb/credentials.c | 8 ++++---- source3/libsmb/smbencrypt.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 975f9bca49..76fc5fc062 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -43,7 +43,7 @@ char *credstr(const unsigned char *cred) static void creds_init_128(struct dcinfo *dc, const DOM_CHAL *clnt_chal_in, const DOM_CHAL *srv_chal_in, - const char mach_pw[16]) + const unsigned char mach_pw[16]) { unsigned char zero[4], tmp[16]; HMACMD5Context ctx; @@ -95,7 +95,7 @@ static void creds_init_128(struct dcinfo *dc, static void creds_init_64(struct dcinfo *dc, const DOM_CHAL *clnt_chal_in, const DOM_CHAL *srv_chal_in, - const char mach_pw[16]) + const unsigned char mach_pw[16]) { uint32 sum[2]; unsigned char sum2[8]; @@ -176,13 +176,13 @@ void creds_server_init(uint32 neg_flags, struct dcinfo *dc, DOM_CHAL *clnt_chal, DOM_CHAL *srv_chal, - const char mach_pw[16], + const unsigned char mach_pw[16], DOM_CHAL *init_chal_out) { DEBUG(10,("creds_server_init: neg_flags : %x\n", (unsigned int)neg_flags)); DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) )); DEBUG(10,("creds_server_init: server chal : %s\n", credstr(srv_chal->data) )); - dump_data_pw("creds_server_init: machine pass", (const unsigned char *)mach_pw, 16); + dump_data_pw("creds_server_init: machine pass", mach_pw, 16); /* Generate the session key and the next client and server creds. */ if (neg_flags & NETLOGON_NEG_128BIT) { diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 5bdd0acd3e..ddfe696b48 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -534,7 +534,7 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, Decode an arc4 encrypted password change buffer. ************************************************************/ -void encode_or_decode_arc4_passwd_buffer(char pw_buf[532], const DATA_BLOB *psession_key) +void encode_or_decode_arc4_passwd_buffer(unsigned char pw_buf[532], const DATA_BLOB *psession_key) { struct MD5Context tctx; unsigned char key_out[16]; -- cgit From fb5362c069b5b6548478b2217a0519c56d856705 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 20 Feb 2006 17:59:58 +0000 Subject: r13571: Replace all calls to talloc_free() with thye TALLOC_FREE() macro which sets the freed pointer to NULL. (This used to be commit b65be8874a2efe5a4b167448960a4fcf6bd995e2) --- source3/libsmb/libsmbclient.c | 2 +- source3/libsmb/ntlmssp_sign.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 649cd8b372..7cbe4a639b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2469,7 +2469,7 @@ done: cli_rpc_pipe_close(pipe_hnd); /* Free all memory which was allocated for this request */ - talloc_free(mem_ctx); + TALLOC_FREE(mem_ctx); /* Tell 'em if it worked */ return W_ERROR_IS_OK(result) ? 0 : -1; diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 42ed0f9418..10921d56e7 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -339,7 +339,7 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) debug_ntlmssp_flags(ntlmssp_state->neg_flags); if (ntlmssp_state->session_key.length < 8) { - talloc_free(mem_ctx); + TALLOC_FREE(mem_ctx); DEBUG(3, ("NO session key, cannot intialise signing\n")); return NT_STATUS_NO_USER_SESSION_KEY; } @@ -365,7 +365,7 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) recv_seal_const = CLI_SEAL; break; default: - talloc_free(mem_ctx); + TALLOC_FREE(mem_ctx); return NT_STATUS_INTERNAL_ERROR; } @@ -464,6 +464,6 @@ NTSTATUS ntlmssp_sign_init(NTLMSSP_STATE *ntlmssp_state) ntlmssp_state->ntlmv1_seq_num = 0; } - talloc_free(mem_ctx); + TALLOC_FREE(mem_ctx); return NT_STATUS_OK; } -- cgit From 0d7f6d650dd3d2c77711d00ffb41e829bb49905f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Feb 2006 04:56:53 +0000 Subject: r13614: First part of the bugfix for #3510 - net join fails against server with schannel disabled. Second part will come tomorrow (fixing net_rpc_join_ok()). Jeremy. (This used to be commit 7de1ee18619bf99c5db45692e085d0646e52378f) --- source3/libsmb/clientgen.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 55addd44a6..83664b0b32 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -358,7 +358,13 @@ struct cli_state *cli_initialise(struct cli_state *cli) BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) { - BOOL ret = cli_close(cli->cli, cli->fnum); + BOOL ret; + + if (!cli) { + return False; + } + + ret = cli_close(cli->cli, cli->fnum); if (!ret) { DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s, " -- cgit From ffba826a17f0631d25d479c238d9a1bf5e9cf3e9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Feb 2006 05:05:09 +0000 Subject: r13664: Fix the cli_error codes to always detect a socket error. This code needs a tidyup and common code with libsmb/errormap.c merging. Should fix the winbindd crash Jerry found (I hope). Jeremy. (This used to be commit e81227d044fbe7c73c121e540ccafc7f6517c4ea) --- source3/libsmb/clierror.c | 146 +++++++++++++++++++++++++++++++++------------- 1 file changed, 107 insertions(+), 39 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 6938702e1e..9d7555a720 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -3,6 +3,7 @@ client error handling routines Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Jelmer Vernooij 2003 + Copyright (C) Jeremy Allison 2006 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -29,49 +30,73 @@ *******************************************************/ -static const struct -{ - int err; - const char *message; -} rap_errmap[] = -{ - {5, "RAP5: User has insufficient privilege" }, - {50, "RAP50: Not supported by server" }, - {65, "RAP65: Access denied" }, - {86, "RAP86: The specified password is invalid" }, - {2220, "RAP2220: Group does not exist" }, - {2221, "RAP2221: User does not exist" }, - {2226, "RAP2226: Operation only permitted on a Primary Domain Controller" }, - {2237, "RAP2237: User is not in group" }, - {2242, "RAP2242: The password of this user has expired." }, - {2243, "RAP2243: The password of this user cannot change." }, - {2244, "RAP2244: This password cannot be used now (password history conflict)." }, - {2245, "RAP2245: The password is shorter than required." }, - {2246, "RAP2246: The password of this user is too recent to change."}, - - /* these really shouldn't be here ... */ - {0x80, "Not listening on called name"}, - {0x81, "Not listening for calling name"}, - {0x82, "Called name not present"}, - {0x83, "Called name present, but insufficient resources"}, - - {0, NULL} +static const struct { + int err; + const char *message; +} rap_errmap[] = { + {5, "RAP5: User has insufficient privilege" }, + {50, "RAP50: Not supported by server" }, + {65, "RAP65: Access denied" }, + {86, "RAP86: The specified password is invalid" }, + {2220, "RAP2220: Group does not exist" }, + {2221, "RAP2221: User does not exist" }, + {2226, "RAP2226: Operation only permitted on a Primary Domain Controller" }, + {2237, "RAP2237: User is not in group" }, + {2242, "RAP2242: The password of this user has expired." }, + {2243, "RAP2243: The password of this user cannot change." }, + {2244, "RAP2244: This password cannot be used now (password history conflict)." }, + {2245, "RAP2245: The password is shorter than required." }, + {2246, "RAP2246: The password of this user is too recent to change."}, + + /* these really shouldn't be here ... */ + {0x80, "Not listening on called name"}, + {0x81, "Not listening for calling name"}, + {0x82, "Called name not present"}, + {0x83, "Called name present, but insufficient resources"}, + + {0, NULL} }; /**************************************************************************** - return a description of an SMB error + Return a description of an SMB error. ****************************************************************************/ + static const char *cli_smb_errstr(struct cli_state *cli) { return smb_dos_errstr(cli->inbuf); } +/**************************************************************************** + Convert a socket error into an NTSTATUS. +****************************************************************************/ + +static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli) +{ + switch(cli->smb_rw_error) { + case READ_TIMEOUT: + return NT_STATUS_IO_TIMEOUT; + case READ_EOF: + return NT_STATUS_END_OF_FILE; + /* What we shoud really do for read/write errors is convert from errno. */ + /* FIXME. JRA. */ + case READ_ERROR: + return NT_STATUS_INVALID_NETWORK_RESPONSE; + case WRITE_ERROR: + return NT_STATUS_UNEXPECTED_NETWORK_ERROR; + case READ_BAD_SIG: + return NT_STATUS_INVALID_PARAMETER; + default: + break; + } + return NT_STATUS_UNSUCCESSFUL; +} + /*************************************************************************** Return an error message - either an NT error, SMB error or a RAP error. Note some of the NT errors are actually warnings or "informational" errors in which case they can be safely ignored. ****************************************************************************/ - + const char *cli_errstr(struct cli_state *cli) { static fstring cli_error_message; @@ -145,11 +170,19 @@ const char *cli_errstr(struct cli_state *cli) } -/* Return the 32-bit NT status code from the last packet */ +/**************************************************************************** + Return the 32-bit NT status code from the last packet. +****************************************************************************/ + NTSTATUS cli_nt_error(struct cli_state *cli) { int flgs2 = SVAL(cli->inbuf,smb_flg2); + /* Deal with socket errors first. */ + if (cli->fd == -1 && cli->smb_rw_error) { + return cli_smb_rw_error_to_ntstatus(cli); + } + if (!(flgs2 & FLAGS2_32_BIT_ERROR_CODES)) { int e_class = CVAL(cli->inbuf,smb_rcls); int code = SVAL(cli->inbuf,smb_err); @@ -160,15 +193,27 @@ NTSTATUS cli_nt_error(struct cli_state *cli) } -/* Return the DOS error from the last packet - an error class and an error - code. */ +/**************************************************************************** + Return the DOS error from the last packet - an error class and an error + code. +****************************************************************************/ + void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) { int flgs2; char rcls; int code; - if(!cli->initialised) return; + if(!cli->initialised) { + return; + } + + /* Deal with socket errors first. */ + if (cli->fd == -1 && cli->smb_rw_error) { + NTSTATUS status = cli_smb_rw_error_to_ntstatus(cli); + ntstatus_to_dos( status, eclass, ecode); + return; + } flgs2 = SVAL(cli->inbuf,smb_flg2); @@ -185,6 +230,10 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) if (ecode) *ecode = code; } +/**************************************************************************** + The following mappings need tidying up and moving into libsmb/errormap.c... +****************************************************************************/ + /* Return a UNIX errno from a dos error class, error number tuple */ static int cli_errno_from_dos(uint8 eclass, uint32 num) @@ -327,6 +376,10 @@ static struct { {NT_STATUS(0), 0} }; +/**************************************************************************** + The following mappings need tidying up and moving into libsmb/errormap.c... +****************************************************************************/ + static int cli_errno_from_nt(NTSTATUS status) { int i; @@ -334,8 +387,9 @@ static int cli_errno_from_nt(NTSTATUS status) /* Status codes without this bit set are not errors */ - if (!(NT_STATUS_V(status) & 0xc0000000)) + if (!(NT_STATUS_V(status) & 0xc0000000)) { return 0; + } for (i=0;nt_errno_map[i].error;i++) { if (NT_STATUS_V(nt_errno_map[i].status) == @@ -351,7 +405,10 @@ static int cli_errno_from_nt(NTSTATUS status) int cli_errno(struct cli_state *cli) { - NTSTATUS status; + if (cli_is_nt_error(cli)) { + NTSTATUS status = cli_nt_error(cli); + return cli_errno_from_nt(status); + } if (cli_is_dos_error(cli)) { uint8 eclass; @@ -361,9 +418,8 @@ int cli_errno(struct cli_state *cli) return cli_errno_from_dos(eclass, ecode); } - status = cli_nt_error(cli); - - return cli_errno_from_nt(status); + /* for other cases */ + return EINVAL; } /* Return true if the last packet was in error */ @@ -372,8 +428,10 @@ BOOL cli_is_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; - if (cli->fd == -1 && cli->smb_rw_error != 0) + /* A socket error is always an error. */ + if (cli->fd == -1 && cli->smb_rw_error != 0) { return True; + } if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) { /* Return error is error bits are set */ @@ -393,6 +451,11 @@ BOOL cli_is_nt_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); + /* A socket error is always an NT error. */ + if (cli->fd == -1 && cli->smb_rw_error != 0) { + return True; + } + return cli_is_error(cli) && (flgs2 & FLAGS2_32_BIT_ERROR_CODES); } @@ -402,6 +465,11 @@ BOOL cli_is_dos_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); + /* A socket error is always a DOS error. */ + if (cli->fd == -1 && cli->smb_rw_error != 0) { + return True; + } + return cli_is_error(cli) && !(flgs2 & FLAGS2_32_BIT_ERROR_CODES); } -- cgit From f690a968e789da8a77338afbe5490b865c25cc99 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Feb 2006 05:47:19 +0000 Subject: r13669: Get rid of poor errno mapping table. Bounce through NTSTATUS instead. DO NOT MERGE FOR 3.0.21c PLEASE. Jeremy. (This used to be commit 3de0d9af6925e3dc0328c02c2a30127ea5c82a83) --- source3/libsmb/clierror.c | 45 ++++++--------------------------------------- 1 file changed, 6 insertions(+), 39 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 9d7555a720..b84a8ee70f 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -230,42 +230,6 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) if (ecode) *ecode = code; } -/**************************************************************************** - The following mappings need tidying up and moving into libsmb/errormap.c... -****************************************************************************/ - -/* Return a UNIX errno from a dos error class, error number tuple */ - -static int cli_errno_from_dos(uint8 eclass, uint32 num) -{ - if (eclass == ERRDOS) { - switch (num) { - case ERRbadfile: return ENOENT; - case ERRbadpath: return ENOTDIR; - case ERRnoaccess: return EACCES; - case ERRfilexists: return EEXIST; - case ERRrename: return EEXIST; - case ERRbadshare: return EBUSY; - case ERRlock: return EBUSY; - case ERRinvalidname: return ENOENT; - case ERRnosuchshare: return ENODEV; - } - } - - if (eclass == ERRSRV) { - switch (num) { - case ERRbadpw: return EPERM; - case ERRaccess: return EACCES; - case ERRnoresource: return ENOMEM; - case ERRinvdevice: return ENODEV; - case ERRinvnetname: return ENODEV; - } - } - - /* for other cases */ - return EINVAL; -} - /* Return a UNIX errno from a NT status code */ static struct { NTSTATUS status; @@ -405,9 +369,11 @@ static int cli_errno_from_nt(NTSTATUS status) int cli_errno(struct cli_state *cli) { + NTSTATUS status; + if (cli_is_nt_error(cli)) { - NTSTATUS status = cli_nt_error(cli); - return cli_errno_from_nt(status); + status = cli_nt_error(cli); + return cli_errno_from_nt(status); } if (cli_is_dos_error(cli)) { @@ -415,7 +381,8 @@ int cli_errno(struct cli_state *cli) uint32 ecode; cli_dos_error(cli, &eclass, &ecode); - return cli_errno_from_dos(eclass, ecode); + status = dos_to_ntstatus(eclass, ecode); + return cli_errno_from_nt(status); } /* for other cases */ -- cgit From 19b22b5c903cb08a8f9d2b0647c0ecca211e8cb9 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 24 Feb 2006 06:29:15 +0000 Subject: r13671: fix return value in (void)fn() (This used to be commit 249dba0386833803805a742aa6697cc75566f05c) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 83664b0b32..d0525d99b9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -361,7 +361,7 @@ BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) BOOL ret; if (!cli) { - return False; + return; } ret = cli_close(cli->cli, cli->fnum); -- cgit From a0ac1d5913ad182abe63d1076b775d1d6dac3365 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 24 Feb 2006 16:06:18 +0000 Subject: r13676: have to return a value from a non-void function (This used to be commit 70e7c9de9dee9317164c0f96a44827ae8b959254) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index d0525d99b9..83664b0b32 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -361,7 +361,7 @@ BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) BOOL ret; if (!cli) { - return; + return False; } ret = cli_close(cli->cli, cli->fnum); -- cgit From c52968b35b65920fafd569254a0a0aaff9508d11 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 1 Mar 2006 01:41:52 +0000 Subject: r13761: r13221@cabra: derrell | 2006-02-28 20:40:56 -0500 When only allowing one connection per server, the cache needs to track which share is currently connected, or we never know whether a tdis()/tcon() for the new share is required. (This used to be commit ad0a725ef5f68db442b3b217c5a852086eff9297) --- source3/libsmb/libsmb_cache.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index e6033faf50..14577146fd 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -156,6 +156,17 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, continue; } + + SAFE_FREE(srv->share_name); + srv->share_name = SMB_STRDUP(share); + if (!srv->share_name) { + /* Out of memory. */ + cli_shutdown(&srv->server->cli); + context->callbacks.remove_cached_srv_fn(context, srv->server); + continue; + } + + return srv->server; } } -- cgit From 3af5da2e7c8e9490feebfe61ff5f6d0f4ded8d88 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 1 Mar 2006 01:48:33 +0000 Subject: r13763: r13223@cabra: derrell | 2006-02-28 20:48:23 -0500 Add the missing comment about needing to save the new share name. (This used to be commit bb3b15e631c8dae7aaea303be18e086d63ee16d6) --- source3/libsmb/libsmb_cache.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 14577146fd..4fa395399e 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -156,7 +156,11 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, continue; } - + /* + * Save the new share name. We've + * disconnected from the old share, and are + * about to connect to the new one. + */ SAFE_FREE(srv->share_name); srv->share_name = SMB_STRDUP(share); if (!srv->share_name) { -- cgit From 42df51222baad37dd2717036900120655551cc3e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 6 Mar 2006 19:48:00 +0000 Subject: r13889: Fix resource leak on error path. Coverity bug CID #73. Jeremy. (This used to be commit 46e10980927f1dfa4a1995e778df880cf823cbdb) --- source3/libsmb/namequery.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1520e6cec2..6449de0e0e 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -960,6 +960,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, (*return_count)+1); if ((*return_iplist) == NULL) { + endlmhosts(fp); DEBUG(3,("resolve_lmhosts: malloc fail !\n")); return False; } -- cgit From 2d3946b8c4bb9ecf151df09775c0a5f23e80bd67 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 6 Mar 2006 20:16:51 +0000 Subject: r13893: Fix for Coverity issue CID #164. The first one that I don't think is a direct bug, but some code that needs clarification :-). Jeremy. (This used to be commit 61901a3f10de64a72b655d9aa884424a4fc88a44) --- source3/libsmb/namequery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6449de0e0e..f78c368eb8 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -572,6 +572,8 @@ struct in_addr *name_query(int fd,const char *name,int name_type, if (!tmp_ip_list) { DEBUG(0,("name_query: Realloc failed.\n")); SAFE_FREE(ip_list); + free_packet(p2); + return( NULL ); } ip_list = tmp_ip_list; -- cgit From 894358a8f3e338b339b6c37233edef794b312087 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Mar 2006 06:31:04 +0000 Subject: r13915: Fixed a very interesting class of realloc() bugs found by Coverity. realloc can return NULL in one of two cases - (1) the realloc failed, (2) realloc succeeded but the new size requested was zero, in which case this is identical to a free() call. The error paths dealing with these two cases should be different, but mostly weren't. Secondly the standard idiom for dealing with realloc when you know the new size is non-zero is the following : tmp = realloc(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } However, there were *many* *many* places in Samba where we were using the old (broken) idiom of : p = realloc(p, size) if (!p) { return error; } which will leak the memory pointed to by p on realloc fail. This commit (hopefully) fixes all these cases by moving to a standard idiom of : p = SMB_REALLOC(p, size) if (!p) { return error; } Where if the realloc returns null due to the realloc failing or size == 0 we *guarentee* that the storage pointed to by p has been freed. This allows me to remove a lot of code that was dealing with the standard (more verbose) method that required a tmp pointer. This is almost always what you want. When a realloc fails you never usually want the old memory, you want to free it and get into your error processing asap. For the 11 remaining cases where we really do need to keep the old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR, which can be used as follows : tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the pointer p, even on size == 0 or realloc fail. All this is done by a hidden extra argument to Realloc(), BOOL free_old_on_error which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR macros (and their array counterparts). It remains to be seen what this will do to our Coverity bug count :-). Jeremy. (This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0) --- source3/libsmb/asn1.c | 7 ++----- source3/libsmb/clilist.c | 17 ++++++----------- source3/libsmb/clireadwrite.c | 7 ++++++- source3/libsmb/clitrans.c | 28 ++++++++-------------------- source3/libsmb/namequery.c | 22 ++++++++-------------- source3/libsmb/spnego.c | 4 ++++ 6 files changed, 34 insertions(+), 51 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 0999840794..072fd30283 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -31,14 +31,11 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { - uint8 *newp; - newp = SMB_REALLOC(data->data, data->ofs+len); - if (!newp) { - SAFE_FREE(data->data); + data->data = SMB_REALLOC(data->data, data->ofs+len); + if (!data->data) { data->has_error = True; return False; } - data->data = newp; data->length = data->ofs+len; } memcpy(data->data + data->ofs, p, len); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 252dafcfa8..1bd30c36e3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -179,7 +179,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, pstring mask; file_info finfo; int i; - char *tdl, *dirlist = NULL; + char *dirlist = NULL; int dirlist_len = 0; int total_received = -1; BOOL First = True; @@ -338,15 +338,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* grab the data for later use */ /* and add them to the dirlist pool */ - tdl = SMB_REALLOC(dirlist,dirlist_len + data_len); + dirlist = SMB_REALLOC(dirlist,dirlist_len + data_len); - if (!tdl) { + if (!dirlist) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); SAFE_FREE(rdata); SAFE_FREE(rparam); break; - } else { - dirlist = tdl; } memcpy(dirlist+dirlist_len,p,data_len); @@ -421,7 +419,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; int num_received = 0; int i; - char *tdl, *dirlist = NULL; + char *dirlist = NULL; pstring mask; ZERO_ARRAY(status); @@ -466,14 +464,11 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, first = False; - tdl = SMB_REALLOC(dirlist,(num_received + received)*DIR_STRUCT_SIZE); - - if (!tdl) { + dirlist = SMB_REALLOC(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + if (!dirlist) { DEBUG(0,("cli_list_old: failed to expand dirlist")); - SAFE_FREE(dirlist); return 0; } - else dirlist = tdl; p = smb_buf(cli->inbuf) + 3; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index a080bd3c64..650822bf8e 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -262,9 +262,14 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, if (size > cli->bufsize) { cli->outbuf = SMB_REALLOC(cli->outbuf, size + 1024); + if (!cli->outbuf) { + return False; + } cli->inbuf = SMB_REALLOC(cli->inbuf, size + 1024); - if (cli->outbuf == NULL || cli->inbuf == NULL) + if (cli->inbuf == NULL) { + SAFE_FREE(cli->outbuf); return False; + } cli->bufsize = size + 1024; } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 5d3710b92e..8296f7e94c 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -169,8 +169,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, unsigned int total_param=0; unsigned int this_data,this_param; NTSTATUS status; - char *tdata; - char *tparam; *data_len = *param_len = 0; @@ -209,25 +207,21 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, /* allocate it */ if (total_data!=0) { - tdata = SMB_REALLOC(*data,total_data); - if (!tdata) { + *data = SMB_REALLOC(*data,total_data); + if (!(*data)) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); cli_signing_trans_stop(cli); return False; } - else - *data = tdata; } if (total_param!=0) { - tparam = SMB_REALLOC(*param,total_param); - if (!tparam) { + *param = SMB_REALLOC(*param,total_param); + if (!(*param)) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); cli_signing_trans_stop(cli); return False; } - else - *param = tparam; } for (;;) { @@ -476,8 +470,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, unsigned int this_data,this_param; uint8 eclass; uint32 ecode; - char *tdata; - char *tparam; *data_len = *param_len = 0; @@ -526,24 +518,20 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, /* allocate it */ if (total_data) { - tdata = SMB_REALLOC(*data,total_data); - if (!tdata) { + *data = SMB_REALLOC(*data,total_data); + if (!(*data)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); cli_signing_trans_stop(cli); return False; - } else { - *data = tdata; } } if (total_param) { - tparam = SMB_REALLOC(*param,total_param); - if (!tparam) { + *param = SMB_REALLOC(*param,total_param); + if (!(*param)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); cli_signing_trans_stop(cli); return False; - } else { - *param = tparam; } } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f78c368eb8..c721a9deff 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -501,7 +501,6 @@ struct in_addr *name_query(int fd,const char *name,int name_type, while (1) { struct timeval tval2; - struct in_addr *tmp_ip_list; GetTimeOfDay(&tval2); if (TvalDiff(&tval,&tval2) > retry_time) { @@ -566,27 +565,22 @@ struct in_addr *name_query(int fd,const char *name,int name_type, continue; } - tmp_ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr, + ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr, (*count) + nmb2->answers->rdlength/6 ); - if (!tmp_ip_list) { + if (!ip_list) { DEBUG(0,("name_query: Realloc failed.\n")); - SAFE_FREE(ip_list); free_packet(p2); return( NULL ); } - ip_list = tmp_ip_list; - - if (ip_list) { - DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); - for (i=0;ianswers->rdlength/6;i++) { - putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); - (*count)++; - } - DEBUGADD(2,(")\n")); + DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); + for (i=0;ianswers->rdlength/6;i++) { + putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); + DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); + (*count)++; } + DEBUGADD(2,(")\n")); found=True; retries=0; diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index f6a66200ba..a2839578ae 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -48,6 +48,10 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) char *p_oid = NULL; token->mechTypes = SMB_REALLOC_ARRAY(token->mechTypes, const char *, i + 2); + if (!token->mechTypes) { + asn1->has_error = True; + return False; + } asn1_read_OID(asn1, &p_oid); token->mechTypes[i] = p_oid; } -- cgit From 03b32953cf74178a8e591d46cbf932828cf9fd55 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 7 Mar 2006 20:44:12 +0000 Subject: r13987: Fix Coverity bug # 74. This tool is good... Thanks, Volker (This used to be commit 86f62484dd7db43e036d9edf29e459b8bd0e5fbe) --- source3/libsmb/namequery.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c721a9deff..1d40837f2b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1126,6 +1126,7 @@ BOOL internal_resolve_name(const char *name, int name_type, /* if it's in the form of an IP address then get the lib to interpret it */ if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){ DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); + SAFE_FREE(*return_iplist); return False; } } else { -- cgit From eae063e965a9ca81c887c2f80c85d85183d16a59 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 7 Mar 2006 21:03:48 +0000 Subject: r13991: Fix Coverity bug # 69 (This used to be commit 6dc79e6b12e221e9af85a1edf487b5fb5aae222b) --- source3/libsmb/samlogon_cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index ef60055cf4..cc1c6bd6b2 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -208,6 +208,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) { prs_mem_free( &ps ); + SAFE_FREE(user); return False; } -- cgit From 6491aed1ac91f3eb57bee52de511f684d9dc35e0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 8 Mar 2006 06:39:33 +0000 Subject: r14022: Fix Coverity bug # 92 (This used to be commit b824245c4e04353f0d3fd0ccf6bc5776a601daed) --- source3/libsmb/libsmb_cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 4fa395399e..5d948ea5e2 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -94,6 +94,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv, SAFE_FREE(srvcache->share_name); SAFE_FREE(srvcache->workgroup); SAFE_FREE(srvcache->username); + SAFE_FREE(srvcache); return 1; } -- cgit From 4d0795a21b6d097b5378b5b723f7eb06181d7962 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 10 Mar 2006 08:56:13 +0000 Subject: r14133: Fix Coverity bug # 140 (This used to be commit 5007f53eb54eddff3d13df929d78385d6b158057) --- source3/libsmb/clidfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index c5cf75783b..03cfd4dd40 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -585,11 +585,11 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha SMB_STRUCT_STAT sbuf; uint32 attributes; - *targetcli = NULL; - if ( !rootcli || !path || !targetcli ) return False; + *targetcli = NULL; + /* send a trans2_query_path_info to check for a referral */ clean_path( cleanpath, path ); -- cgit From ce53430263cd3d8f2bd4dc746ba6fa35a74834ed Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Fri, 10 Mar 2006 14:39:29 +0000 Subject: r14158: Fix coverity CID #147 -- do not dereference pointers before checking their existence (This used to be commit 6b52423033b2eccdfad1e91e9d59619664f570ac) --- source3/libsmb/libsmbclient.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 7cbe4a639b..7a390a83f2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1282,8 +1282,8 @@ smbc_write_ctx(SMBCCTX *context, pstring path, targetpath; struct cli_state *targetcli; - offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ - + /* First check all pointers before dereferencing them */ + if (!context || !context->internal || !context->internal->_initialized) { @@ -1308,6 +1308,8 @@ smbc_write_ctx(SMBCCTX *context, } + offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ + /*d_printf(">>>write: parsing %s\n", file->fname);*/ if (smbc_parse_path(context, file->fname, NULL, 0, -- cgit From 6c3519d0af8fa14eb8dce4bd7afa0dcff6c9ddfc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 11 Mar 2006 23:10:31 +0000 Subject: r14218: Fix Coverity Bug # 2 (This used to be commit 26377b63a3a3d2d5ed23bdbb5f22b70ec7d3fcad) --- source3/libsmb/clikrb5.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 55a705d7f0..da3ef6a0e4 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -898,7 +898,6 @@ krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); krb5_keyblock **keyblock) { krb5_error_code ret; - krb5_ap_req *ap_req = NULL; krb5_kvno kvno; krb5_enctype enctype; krb5_keyblock *local_keyblock; @@ -930,10 +929,6 @@ krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); } out: - if (ap_req) { - smb_krb5_free_ap_req(context, ap_req); - } - if (ret && local_keyblock != NULL) { krb5_free_keyblock(context, local_keyblock); } else { -- cgit From 2e42254291db98ebb29b987ec7ee0ce5ac20df88 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 12 Mar 2006 10:52:56 +0000 Subject: r14234: Fix Coverity bug # 93 (This used to be commit 8a8d9057d98b24710c98fa48df9d7f330a8ebdc0) --- source3/libsmb/libsmbclient.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 7a390a83f2..a18e9910aa 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5784,6 +5784,7 @@ smbc_new_context(void) context->internal = SMB_MALLOC_P(struct smbc_internal_data); if (!context->internal) { + SAFE_FREE(context); errno = ENOMEM; return NULL; } -- cgit From 21db43ab55ff80a7c0fd208deedfb7320cfea20e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 12 Mar 2006 10:57:42 +0000 Subject: r14235: Fix Coverity bug # 91 (This used to be commit 26d471c02c6ddff15836a3c0d30f9e37f018b66d) --- source3/libsmb/libsmbclient.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index a18e9910aa..75b2b37c06 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2594,6 +2594,10 @@ smbc_opendir_ctx(SMBCCTX *context, if (!find_master_ip(workgroup, &server_addr.ip)) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } errno = ENOENT; return NULL; } @@ -2705,6 +2709,10 @@ smbc_opendir_ctx(SMBCCTX *context, DEBUG(0, ("Could not get name of " "local/domain master browser " "for server %s\n", server)); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } errno = EPERM; return NULL; @@ -2828,6 +2836,10 @@ smbc_opendir_ctx(SMBCCTX *context, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } return NULL; } -- cgit From 6a8432833bb073c7fa91f9f4de1fe7a5cd8d0cec Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 12 Mar 2006 11:00:06 +0000 Subject: r14236: Fix Coverity bug # 90 (This used to be commit 019dff53f906a6eb7961a95089bff12361e31e57) --- source3/libsmb/libsmbclient.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 75b2b37c06..6b4ae9f4b7 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1070,6 +1070,7 @@ smbc_open_ctx(SMBCCTX *context, if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + SAFE_FREE(file); return NULL; } /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ -- cgit From 784cc042cb245786516333ae53cfde8fc9502a23 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 12 Mar 2006 17:18:26 +0000 Subject: r14241: Fix Coverity bug # 146 (This used to be commit 97789ec8fc4ae2d31f6dd554d9979abce186eb30) --- source3/libsmb/libsmbclient.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 6b4ae9f4b7..15355016d0 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1200,7 +1200,7 @@ smbc_read_ctx(SMBCCTX *context, * the call to cli_read() instead of file->offset fixes a problem * retrieving data at an offset greater than 4GB. */ - off_t offset = file->offset; + off_t offset; if (!context || !context->internal || !context->internal->_initialized) { @@ -1219,6 +1219,8 @@ smbc_read_ctx(SMBCCTX *context, } + offset = file->offset; + /* Check that the buffer exists ... */ if (buf == NULL) { -- cgit From 025041eba44452849f2d25f667b4c1fb6888c485 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 13 Mar 2006 01:42:40 +0000 Subject: r14279: Fix coverity #86, 87, 88, 89: Free grp_sid and owner_sid before returning. Also, only allow one group or owner. (This used to be commit 1043e0d90ccb3493417f7bf05b70bdf5513bb1a3) --- source3/libsmb/libsmbclient.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 15355016d0..4c013c4ed2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3922,7 +3922,7 @@ sec_desc_parse(TALLOC_CTX *ctx, { const char *p = str; fstring tok; - SEC_DESC *ret; + SEC_DESC *ret = NULL; size_t sd_size; DOM_SID *grp_sid=NULL; DOM_SID *owner_sid=NULL; @@ -3937,49 +3937,65 @@ sec_desc_parse(TALLOC_CTX *ctx, } if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { + if (owner_sid) { + DEBUG(5, ("OWNER specified more than once!\n")); + goto done; + } owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); if (!owner_sid || !convert_string_to_sid(ipc_cli, pol, numeric, owner_sid, tok+6)) { DEBUG(5, ("Failed to parse owner sid\n")); - return NULL; + goto done; } continue; } if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { + if (owner_sid) { + DEBUG(5, ("OWNER specified more than once!\n")); + goto done; + } owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); if (!owner_sid || !convert_string_to_sid(ipc_cli, pol, False, owner_sid, tok+7)) { DEBUG(5, ("Failed to parse owner sid\n")); - return NULL; + goto done; } continue; } if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { + if (grp_sid) { + DEBUG(5, ("GROUP specified more than once!\n")); + goto done; + } grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); if (!grp_sid || !convert_string_to_sid(ipc_cli, pol, numeric, grp_sid, tok+6)) { DEBUG(5, ("Failed to parse group sid\n")); - return NULL; + goto done; } continue; } if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { + if (grp_sid) { + DEBUG(5, ("GROUP specified more than once!\n")); + goto done; + } grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); if (!grp_sid || !convert_string_to_sid(ipc_cli, pol, False, grp_sid, tok+6)) { DEBUG(5, ("Failed to parse group sid\n")); - return NULL; + goto done; } continue; } @@ -3988,11 +4004,11 @@ sec_desc_parse(TALLOC_CTX *ctx, SEC_ACE ace; if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { DEBUG(5, ("Failed to parse ACL %s\n", tok)); - return NULL; + goto done; } if(!add_ace(&dacl, &ace, ctx)) { DEBUG(5, ("Failed to add ACL %s\n", tok)); - return NULL; + goto done; } continue; } @@ -4001,22 +4017,23 @@ sec_desc_parse(TALLOC_CTX *ctx, SEC_ACE ace; if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { DEBUG(5, ("Failed to parse ACL %s\n", tok)); - return NULL; + goto done; } if(!add_ace(&dacl, &ace, ctx)) { DEBUG(5, ("Failed to add ACL %s\n", tok)); - return NULL; + goto done; } continue; } DEBUG(5, ("Failed to parse security descriptor\n")); - return NULL; + goto done; } ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, owner_sid, grp_sid, NULL, dacl, &sd_size); + done: SAFE_FREE(grp_sid); SAFE_FREE(owner_sid); -- cgit From 846c4520ce102883825e3d2e1adba79a0b45a7d5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Mar 2006 23:48:13 +0000 Subject: r14355: Try and fix Coverity #158 by making the pointer aliasing clearer. This isn't a bug but a code clarification. Jeremy. (This used to be commit 7ada96a1cfb1e928b7dfde101ca250b20024243f) --- source3/libsmb/smb_signing.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index f0f2024e7b..52e4b1d04c 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -426,18 +426,20 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); static void simple_free_signing_context(struct smb_sign_info *si) { struct smb_basic_signing_context *data = si->signing_context; - struct outstanding_packet_lookup *list = data->outstanding_packet_list; + struct outstanding_packet_lookup *list; + struct outstanding_packet_lookup *next; - while (list) { - struct outstanding_packet_lookup *old_head = list; - DLIST_REMOVE(list, list); - SAFE_FREE(old_head); + for (list = data->outstanding_packet_list; list; list = next) { + next = list->next; + DLIST_REMOVE(data->outstanding_packet_list, list); + SAFE_FREE(list); } data_blob_free(&data->mac_key); - if (data->trans_info) + if (data->trans_info) { SAFE_FREE(data->trans_info); + } SAFE_FREE(si->signing_context); -- cgit From a48baaa9351c42a6a9998914e172475b7d3bbf7f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 15 Mar 2006 03:27:03 +0000 Subject: r14418: Try and fix Coverity #39 and #40 by making the implicit function contract explicit. Jeremy. (This used to be commit 6de5e9ae4628d384631db9b66e22d439a303b75c) --- source3/libsmb/libsmbclient.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 4c013c4ed2..b8070283da 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4826,11 +4826,19 @@ cacl_set(TALLOC_CTX *ctx, CONST_DISCARD(char *, the_acl)); if (!sd) { - errno = EINVAL; - return -1; + errno = EINVAL; + return -1; } } + /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller + that doesn't deref sd */ + + if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { + errno = EINVAL; + return -1; + } + /* The desired access below is the only one I could find that works with NT4, W2KP and Samba */ -- cgit From a17d276fa0164cd3f13c85a0ae02cc2a504d394d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 17 Mar 2006 10:22:13 +0000 Subject: r14506: Remove remaining references to a KCM credential cache type. Guenther (This used to be commit aae8f8ae7a79d06c74151186f3c2470bdec5687d) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index da3ef6a0e4..4943f67b77 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -426,7 +426,7 @@ static BOOL ads_cleanup_expired_creds(krb5_context context, use memory ccaches, and a FILE one probably means that we're using creds obtained outside of our exectuable */ - if (strequal(cc_type, "KCM") || strequal(cc_type, "FILE")) { + if (strequal(cc_type, "FILE")) { DEBUG(5, ("ads_cleanup_expired_creds: We do not remove creds from a %s ccache\n", cc_type)); return False; } -- cgit From 485a286a65d3b37f424f5701179f73c99eb9b5b9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 20 Mar 2006 19:05:44 +0000 Subject: r14585: Tighten argument list of kerberos_kinit_password again, kerberos_kinit_password_ext provides access to more options. Guenther (This used to be commit afc519530f94b420b305fc28f83c16db671d0d7f) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4c6b890db0..48885f19d8 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -756,7 +756,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, int ret; use_in_memory_ccache(); - ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL, NULL, NULL, False, 0); + ret = kerberos_kinit_password(user, pass, 0 /* no time correction for now */, NULL); if (ret){ SAFE_FREE(principal); -- cgit From 6e17934ee614f5f129b69898be7eceb09486a48f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 22 Mar 2006 14:41:07 +0000 Subject: r14643: Merge dcerpc_errstr from Samba 4. Might need to rework prs_dcerpc_status(). Guenther (This used to be commit 38b18f428ba941f4d9a14fa2de45cb0cd793a754) --- source3/libsmb/dcerpc_err.c | 110 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 source3/libsmb/dcerpc_err.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/dcerpc_err.c b/source3/libsmb/dcerpc_err.c new file mode 100644 index 0000000000..89db4aa699 --- /dev/null +++ b/source3/libsmb/dcerpc_err.c @@ -0,0 +1,110 @@ +/* + * Unix SMB/CIFS implementation. + * Copyright (C) Stefan Metzmacher 2004 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +struct dcerpc_fault_table { + const char *errstr; + uint32_t faultcode; +}; + +static const struct dcerpc_fault_table dcerpc_faults[] = +{ + { "DCERPC_FAULT_OP_RNG_ERROR", DCERPC_FAULT_OP_RNG_ERROR }, + { "DCERPC_FAULT_UNK_IF", DCERPC_FAULT_UNK_IF }, + { "DCERPC_FAULT_NDR", DCERPC_FAULT_NDR }, + { "DCERPC_FAULT_INVALID_TAG", DCERPC_FAULT_INVALID_TAG }, + { "DCERPC_FAULT_CONTEXT_MISMATCH", DCERPC_FAULT_CONTEXT_MISMATCH }, + { "DCERPC_FAULT_OTHER", DCERPC_FAULT_OTHER }, + { "DCERPC_FAULT_ACCESS_DENIED", DCERPC_FAULT_ACCESS_DENIED }, + + { NULL, 0} +}; + +const char *dcerpc_errstr(uint32 fault_code) +{ + static pstring msg; + int idx = 0; + + slprintf(msg, sizeof(msg), "DCERPC fault 0x%08x", fault_code); + + while (dcerpc_faults[idx].errstr != NULL) { + if (dcerpc_faults[idx].faultcode == fault_code) { + return dcerpc_faults[idx].errstr; + } + idx++; + } + + return msg; +} +/* + * Unix SMB/CIFS implementation. + * Copyright (C) Stefan Metzmacher 2004 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "includes.h" + +struct dcerpc_fault_table { + const char *errstr; + uint32_t faultcode; +}; + +static const struct dcerpc_fault_table dcerpc_faults[] = +{ + { "DCERPC_FAULT_OP_RNG_ERROR", DCERPC_FAULT_OP_RNG_ERROR }, + { "DCERPC_FAULT_UNK_IF", DCERPC_FAULT_UNK_IF }, + { "DCERPC_FAULT_NDR", DCERPC_FAULT_NDR }, + { "DCERPC_FAULT_INVALID_TAG", DCERPC_FAULT_INVALID_TAG }, + { "DCERPC_FAULT_CONTEXT_MISMATCH", DCERPC_FAULT_CONTEXT_MISMATCH }, + { "DCERPC_FAULT_OTHER", DCERPC_FAULT_OTHER }, + { "DCERPC_FAULT_ACCESS_DENIED", DCERPC_FAULT_ACCESS_DENIED }, + + { NULL, 0} +}; + +const char *dcerpc_errstr(uint32 fault_code) +{ + static pstring msg; + int idx = 0; + + slprintf(msg, sizeof(msg), "DCERPC fault 0x%08x", fault_code); + + while (dcerpc_faults[idx].errstr != NULL) { + if (dcerpc_faults[idx].faultcode == fault_code) { + return dcerpc_faults[idx].errstr; + } + idx++; + } + + return msg; +} -- cgit From fb62a719dcec7f046702bbe279e0886b399115ca Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 22 Mar 2006 14:58:54 +0000 Subject: r14645: No idea how this happened, fixing the build. Guenther (This used to be commit d45b9abb0ec7d943e9fb374d64385d6c540fffe2) --- source3/libsmb/dcerpc_err.c | 55 --------------------------------------------- 1 file changed, 55 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dcerpc_err.c b/source3/libsmb/dcerpc_err.c index 89db4aa699..7121ba396d 100644 --- a/source3/libsmb/dcerpc_err.c +++ b/source3/libsmb/dcerpc_err.c @@ -53,58 +53,3 @@ const char *dcerpc_errstr(uint32 fault_code) return msg; } -/* - * Unix SMB/CIFS implementation. - * Copyright (C) Stefan Metzmacher 2004 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -struct dcerpc_fault_table { - const char *errstr; - uint32_t faultcode; -}; - -static const struct dcerpc_fault_table dcerpc_faults[] = -{ - { "DCERPC_FAULT_OP_RNG_ERROR", DCERPC_FAULT_OP_RNG_ERROR }, - { "DCERPC_FAULT_UNK_IF", DCERPC_FAULT_UNK_IF }, - { "DCERPC_FAULT_NDR", DCERPC_FAULT_NDR }, - { "DCERPC_FAULT_INVALID_TAG", DCERPC_FAULT_INVALID_TAG }, - { "DCERPC_FAULT_CONTEXT_MISMATCH", DCERPC_FAULT_CONTEXT_MISMATCH }, - { "DCERPC_FAULT_OTHER", DCERPC_FAULT_OTHER }, - { "DCERPC_FAULT_ACCESS_DENIED", DCERPC_FAULT_ACCESS_DENIED }, - - { NULL, 0} -}; - -const char *dcerpc_errstr(uint32 fault_code) -{ - static pstring msg; - int idx = 0; - - slprintf(msg, sizeof(msg), "DCERPC fault 0x%08x", fault_code); - - while (dcerpc_faults[idx].errstr != NULL) { - if (dcerpc_faults[idx].faultcode == fault_code) { - return dcerpc_faults[idx].errstr; - } - idx++; - } - - return msg; -} -- cgit From e836508704dd964e22e8bfc0f8e9ec520a2c94f2 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 22 Mar 2006 22:05:19 +0000 Subject: r14664: r13868@cabra: derrell | 2006-03-22 17:04:30 -0500 Implement enhancement request 3505. Two additional features are added here. There is now a method of saving an opaque user data handle in the smbc_ context, and there is now a way to request that the context be passed to the authentication function. See examples/libsmbclient/testbrowse.c for an example of using these features. (This used to be commit 203b4911c16bd7e10198a6f0e63960f2813025ef) --- source3/libsmb/libsmbclient.c | 103 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 89 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b8070283da..2436cc9136 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -552,10 +552,21 @@ find_server(SMBCCTX *context, workgroup, username); if (!auth_called && !srv && (!username[0] || !password[0])) { - context->callbacks.auth_fn(server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); + if (context->internal->_auth_fn_with_context != NULL) { + context->internal->_auth_fn_with_context( + context, + server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + } else { + context->callbacks.auth_fn( + server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + } + /* * However, smbc_auth_fn may have picked up info relating to * an existing connection, so try for an existing connection @@ -657,10 +668,20 @@ smbc_server(SMBCCTX *context, */ if (srv->cli.cnum == (uint16) -1) { /* Ensure we have accurate auth info */ - context->callbacks.auth_fn(server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); + if (context->internal->_auth_fn_with_context != NULL) { + context->internal->_auth_fn_with_context( + context, + server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + } else { + context->callbacks.auth_fn( + server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + } if (! cli_send_tconX(&srv->cli, share, "?????", password, strlen(password)+1)) { @@ -901,10 +922,20 @@ smbc_attr_server(SMBCCTX *context, /* We didn't find a cached connection. Get the password */ if (*password == '\0') { /* ... then retrieve it now. */ - context->callbacks.auth_fn(server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); + if (context->internal->_auth_fn_with_context != NULL) { + context->internal->_auth_fn_with_context( + context, + server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + } else { + context->callbacks.auth_fn( + server, share, + workgroup, sizeof(fstring), + username, sizeof(fstring), + password, sizeof(fstring)); + } } zero_ip(&ip); @@ -5976,8 +6007,51 @@ smbc_option_set(SMBCCTX *context, /* * Log to standard error instead of standard output. */ - context->internal->_debug_stderr = True; + context->internal->_debug_stderr = + (option_value == NULL ? False : True); + } else if (strcmp(option_name, "auth_function") == 0) { + /* + * Use the new-style authentication function which includes + * the context. + */ + context->internal->_auth_fn_with_context = option_value; + } else if (strcmp(option_name, "user_data") == 0) { + /* + * Save a user data handle which may be retrieved by the user + * with smbc_option_get() + */ + context->internal->_user_data = option_value; + } +} + + +/* + * Retrieve the current value of an option + */ +void * +smbc_option_get(SMBCCTX *context, + char *option_name) +{ + if (strcmp(option_name, "debug_stderr") == 0) { + /* + * Log to standard error instead of standard output. + */ + return (void *) context->internal->_debug_stderr; + } else if (strcmp(option_name, "auth_function") == 0) { + /* + * Use the new-style authentication function which includes + * the context. + */ + return (void *) context->internal->_auth_fn_with_context; + } else if (strcmp(option_name, "user_data") == 0) { + /* + * Save a user data handle which may be retrieved by the user + * with smbc_option_get() + */ + return context->internal->_user_data; } + + return NULL; } @@ -6006,7 +6080,8 @@ smbc_init_context(SMBCCTX *context) return 0; } - if (!context->callbacks.auth_fn || + if ((!context->callbacks.auth_fn && + !context->internal->_auth_fn_with_context) || context->debug < 0 || context->debug > 100) { -- cgit From 22dbd67708f1651a2341d70ce576fac360affccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Apr 2006 15:33:04 +0000 Subject: r15018: Merge Volker's ipc/trans2/nttrans changes over into 3.0. Also merge the new POSIX lock code - this is not enabled unless -DDEVELOPER is defined. This doesn't yet map onto underlying system POSIX locks. Updates vfs to allow lock queries. Jeremy. (This used to be commit 08e52ead03304ff04229e1bfe544ff40e2564fc7) --- source3/libsmb/clifile.c | 105 ++++++++++++++++++- source3/libsmb/clitrans.c | 38 +------ source3/libsmb/errormap.c | 4 +- source3/libsmb/smb_signing.c | 234 +++---------------------------------------- 4 files changed, 124 insertions(+), 257 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 443f515665..80deb3a332 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -816,6 +816,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) send a lock with a specified locktype this is used for testing LOCKING_ANDX_CANCEL_LOCK ****************************************************************************/ + NTSTATUS cli_locktype(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout, unsigned char locktype) { @@ -863,11 +864,11 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, return cli_nt_error(cli); } - /**************************************************************************** Lock a file. note that timeout is in units of 2 milliseconds ****************************************************************************/ + BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout, enum brl_type lock_type) { @@ -1068,6 +1069,108 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ return True; } +/**************************************************************************** + Get/unlock a POSIX lock on a file - internal function. +****************************************************************************/ + +static BOOL cli_posix_lock_internal(struct cli_state *cli, int fnum, + SMB_BIG_UINT offset, SMB_BIG_UINT len, BOOL wait_lock, enum brl_type lock_type) +{ + unsigned int param_len = 4; + unsigned int data_len = POSIX_LOCK_DATA_SIZE; + uint16 setup = TRANSACT2_SETFILEINFO; + char param[4]; + unsigned char data[POSIX_LOCK_DATA_SIZE]; + char *rparam=NULL, *rdata=NULL; + int saved_timeout = cli->timeout; + + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_SET_POSIX_LOCK); + + switch (lock_type) { + case READ_LOCK: + SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_READ); + break; + case WRITE_LOCK: + SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_WRITE); + break; + case UNLOCK_LOCK: + SSVAL(data, POSIX_LOCK_TYPE_OFFSET, POSIX_LOCK_TYPE_UNLOCK); + break; + default: + return False; + } + + if (wait_lock) { + SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_WAIT); + cli->timeout = 0x7FFFFFFF; + } else { + SSVAL(data, POSIX_LOCK_FLAGS_OFFSET, POSIX_LOCK_FLAG_NOWAIT); + } + + SIVAL(data, POSIX_LOCK_PID_OFFSET, cli->pid); + SOFF_T(data, POSIX_LOCK_START_OFFSET, offset); + SOFF_T(data, POSIX_LOCK_LEN_OFFSET, len); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + cli->timeout = saved_timeout; + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + cli->timeout = saved_timeout; + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return False; + } + + cli->timeout = saved_timeout; + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + +/**************************************************************************** + POSIX Lock a file. +****************************************************************************/ + +BOOL cli_posix_lock(struct cli_state *cli, int fnum, + SMB_BIG_UINT offset, SMB_BIG_UINT len, + BOOL wait_lock, enum brl_type lock_type) +{ + if (lock_type != READ_LOCK || lock_type != WRITE_LOCK) { + return False; + } + return cli_posix_lock_internal(cli, fnum, offset, len, wait_lock, lock_type); +} + +/**************************************************************************** + POSIX Unlock a file. +****************************************************************************/ + +BOOL cli_posix_unlock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len) +{ + return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK); +} + +/**************************************************************************** + POSIX Get any lock covering a file. +****************************************************************************/ + +BOOL cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, SMB_BIG_UINT *plen) +{ + return True; +} /**************************************************************************** Do a SMBgetattrE call. diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 8296f7e94c..082da67bb8 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -153,7 +153,6 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, /* Note we're in a trans state. Save the sequence * numbers for replies. */ - cli_signing_trans_start(cli, mid); return(True); } @@ -173,7 +172,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *data_len = *param_len = 0; if (!cli_receive_smb(cli)) { - cli_signing_trans_stop(cli); return False; } @@ -184,7 +182,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); - cli_signing_trans_stop(cli); return(False); } @@ -197,7 +194,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, status = cli_nt_error(cli); if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) { - cli_signing_trans_stop(cli); return False; } @@ -210,7 +206,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *data = SMB_REALLOC(*data,total_data); if (!(*data)) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); - cli_signing_trans_stop(cli); return False; } } @@ -219,7 +214,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *param = SMB_REALLOC(*param,total_param); if (!(*param)) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); - cli_signing_trans_stop(cli); return False; } } @@ -231,7 +225,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_trans\n")); - cli_signing_trans_stop(cli); return False; } @@ -240,7 +233,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_trans\n")); - cli_signing_trans_stop(cli); return False; } @@ -253,7 +245,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); - cli_signing_trans_stop(cli); return False; } if (data_offset_in > cli->bufsize || @@ -261,7 +252,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); - cli_signing_trans_stop(cli); return False; } @@ -276,7 +266,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); - cli_signing_trans_stop(cli); return False; } if (param_offset_in > cli->bufsize || @@ -284,7 +273,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); - cli_signing_trans_stop(cli); return False; } @@ -297,7 +285,6 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, break; if (!cli_receive_smb(cli)) { - cli_signing_trans_stop(cli); return False; } @@ -308,11 +295,9 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); - cli_signing_trans_stop(cli); return(False); } if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { - cli_signing_trans_stop(cli); return(False); } @@ -326,8 +311,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, break; } - - cli_signing_trans_stop(cli); + return(True); } @@ -453,7 +437,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli, /* Note we're in a trans state. Save the sequence * numbers for replies. */ - cli_signing_trans_start(cli, mid); return(True); } @@ -474,7 +457,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, *data_len = *param_len = 0; if (!cli_receive_smb(cli)) { - cli_signing_trans_stop(cli); return False; } @@ -484,7 +466,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); - cli_signing_trans_stop(cli); return(False); } @@ -496,7 +477,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if (!(eclass == ERRDOS && ecode == ERRmoredata)) { - cli_signing_trans_stop(cli); return(False); } } @@ -507,7 +487,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (cli_is_nt_error(cli)) { if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_BUFFER_TOO_SMALL)) { - cli_signing_trans_stop(cli); return(False); } } @@ -521,7 +500,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, *data = SMB_REALLOC(*data,total_data); if (!(*data)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); - cli_signing_trans_stop(cli); return False; } } @@ -530,7 +508,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, *param = SMB_REALLOC(*param,total_param); if (!(*param)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); - cli_signing_trans_stop(cli); return False; } } @@ -542,7 +519,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); - cli_signing_trans_stop(cli); return False; } @@ -551,7 +527,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); - cli_signing_trans_stop(cli); return False; } @@ -564,7 +539,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); - cli_signing_trans_stop(cli); return False; } if (data_offset_in > cli->bufsize || @@ -572,7 +546,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); - cli_signing_trans_stop(cli); return False; } @@ -588,7 +561,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); - cli_signing_trans_stop(cli); return False; } if (param_offset_in > cli->bufsize || @@ -596,7 +568,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); - cli_signing_trans_stop(cli); return False; } @@ -610,7 +581,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, break; if (!cli_receive_smb(cli)) { - cli_signing_trans_stop(cli); return False; } @@ -620,13 +590,11 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); - cli_signing_trans_stop(cli); return(False); } if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if(!(eclass == ERRDOS && ecode == ERRmoredata)) { - cli_signing_trans_stop(cli); return(False); } } @@ -636,7 +604,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (cli_is_nt_error(cli)) { if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_BUFFER_TOO_SMALL)) { - cli_signing_trans_stop(cli); return(False); } } @@ -650,7 +617,6 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (total_data <= *data_len && total_param <= *param_len) break; } - - cli_signing_trans_stop(cli); + return(True); } diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index f6b5af068a..b3caa0a80c 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -407,7 +407,7 @@ static const struct { {ERRHRD, ERRgeneral, NT_STATUS_APP_INIT_FAILURE}, {ERRHRD, ERRgeneral, NT_STATUS_PAGEFILE_CREATE_FAILED}, {ERRHRD, ERRgeneral, NT_STATUS_NO_PAGEFILE}, - {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, + {ERRDOS, ERRunknownlevel, NT_STATUS_INVALID_LEVEL}, {ERRDOS, 86, NT_STATUS_WRONG_PASSWORD_CORE}, {ERRHRD, ERRgeneral, NT_STATUS_ILLEGAL_FLOAT_CONTEXT}, {ERRDOS, 109, NT_STATUS_PIPE_BROKEN}, @@ -680,7 +680,7 @@ static const struct { {ERRDOS, 121, NT_STATUS_IO_TIMEOUT}, {ERRDOS, 122, NT_STATUS_BUFFER_TOO_SMALL}, {ERRDOS, ERRinvalidname, NT_STATUS_OBJECT_NAME_INVALID}, - {ERRDOS, 124, NT_STATUS_INVALID_LEVEL}, + {ERRDOS, ERRunknownlevel, NT_STATUS_INVALID_LEVEL}, {ERRDOS, 126, NT_STATUS_DLL_NOT_FOUND}, {ERRDOS, 127, NT_STATUS_PROCEDURE_NOT_FOUND}, {ERRDOS, 145, NT_STATUS_DIRECTORY_NOT_EMPTY}, diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 52e4b1d04c..4ff74ca464 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -28,17 +28,9 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; }; -/* Store the data for an ongoing trans/trans2/nttrans operation. */ -struct trans_info_context { - uint16 mid; - uint32 send_seq_num; - uint32 reply_seq_num; -}; - struct smb_basic_signing_context { DATA_BLOB mac_key; uint32 send_seq_num; - struct trans_info_context *trans_info; struct outstanding_packet_lookup *outstanding_packet_list; }; @@ -315,7 +307,6 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; - uint32 send_seq_num; if (!si->doing_signing) return; @@ -330,12 +321,8 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* mark the packet as signed - BEFORE we sign it...*/ mark_packet_signed(outbuf); - if (data->trans_info) - send_seq_num = data->trans_info->send_seq_num; - else - send_seq_num = data->send_seq_num; - - simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_num, calc_md5_mac); + simple_packet_signature(data, (const unsigned char *)outbuf, + data->send_seq_num, calc_md5_mac); DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); dump_data(10, (const char *)calc_md5_mac, 8); @@ -345,13 +332,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - if (data->trans_info) - return; - - data->send_seq_num++; - store_sequence_for_reply(&data->outstanding_packet_list, - SVAL(outbuf,smb_mid), data->send_seq_num); - data->send_seq_num++; + data->send_seq_num += 2; } /*********************************************************** @@ -362,7 +343,6 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, { BOOL good; uint32 reply_seq_number; - uint32 saved_seq; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; @@ -376,17 +356,9 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, return False; } - if (data->trans_info) { - reply_seq_number = data->trans_info->reply_seq_num; - } else if (!get_sequence_for_reply(&data->outstanding_packet_list, - SVAL(inbuf, smb_mid), &reply_seq_number)) { - DEBUG(1, ("client_check_incoming_message: failed to get sequence number %u for reply.\n", - (unsigned int) SVAL(inbuf, smb_mid) )); - return False; - } - - saved_seq = reply_seq_number; - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); + reply_seq_number = data->send_seq_num - 1; + simple_packet_signature(data, (const unsigned char *)inbuf, + reply_seq_number, calc_md5_mac); server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); @@ -400,12 +372,11 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, #if 1 /* JRATEST */ { int i; - reply_seq_number -= 5; - for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); + for (i = -5; i < 5; i++) { + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac); if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ -We were expecting seq %u\n", reply_seq_number, saved_seq )); +We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); break; } } @@ -416,7 +387,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); dump_data(10, (const char *)server_sent_mac, 8); } - return signing_good(inbuf, si, good, saved_seq, must_be_ok); + return signing_good(inbuf, si, good, reply_seq_number, must_be_ok); } /*********************************************************** @@ -437,10 +408,6 @@ static void simple_free_signing_context(struct smb_sign_info *si) data_blob_free(&data->mac_key); - if (data->trans_info) { - SAFE_FREE(data->trans_info); - } - SAFE_FREE(si->signing_context); return; @@ -502,65 +469,6 @@ BOOL cli_simple_set_signing(struct cli_state *cli, return True; } -/*********************************************************** - Tell client code we are in a multiple trans reply state. - We call this after the last outgoing trans2 packet (which - has incremented the sequence numbers), so we must save the - current mid and sequence number -2. -************************************************************/ - -void cli_signing_trans_start(struct cli_state *cli, uint16 mid) -{ - struct smb_basic_signing_context *data = cli->sign_info.signing_context; - uint32 reply_seq_num; - - if (!cli->sign_info.doing_signing || !data) - return; - - data->trans_info = SMB_XMALLOC_P(struct trans_info_context); - ZERO_STRUCTP(data->trans_info); - - /* This ensures the sequence is pulled off the outstanding packet list */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, - mid, &reply_seq_num)) { - DEBUG(1, ("get_sequence_for_reply failed - did we enter the trans signing state without sending a packet?\n")); - return; - } - - data->trans_info->send_seq_num = reply_seq_num - 1; - data->trans_info->mid = mid; - data->trans_info->reply_seq_num = reply_seq_num; - - DEBUG(10,("cli_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ -data->send_seq_num = %u\n", - (unsigned int)data->trans_info->mid, - (unsigned int)data->trans_info->reply_seq_num, - (unsigned int)data->trans_info->send_seq_num, - (unsigned int)data->send_seq_num )); -} - -/*********************************************************** - Tell client code we are out of a multiple trans reply state. -************************************************************/ - -void cli_signing_trans_stop(struct cli_state *cli) -{ - struct smb_basic_signing_context *data = cli->sign_info.signing_context; - - if (!cli->sign_info.doing_signing || !data) - return; - - DEBUG(10,("cli_signing_trans_stop: freeing mid = %u, reply_seq_num = %u, send_seq_num = %u \ -data->send_seq_num = %u\n", - (unsigned int)data->trans_info->mid, - (unsigned int)data->trans_info->reply_seq_num, - (unsigned int)data->trans_info->send_seq_num, - (unsigned int)data->send_seq_num )); - - SAFE_FREE(data->trans_info); - data->trans_info = NULL; -} - /*********************************************************** SMB signing - TEMP implementation - calculate a MAC to send. ************************************************************/ @@ -659,8 +567,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; struct smb_basic_signing_context *data = si->signing_context; - uint32 send_seq_number = data->send_seq_num; - BOOL was_deferred_packet = False; + uint32 send_seq_number = data->send_seq_num-1; uint16 mid; if (!si->doing_signing) { @@ -680,13 +587,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) mid = SVAL(outbuf, smb_mid); /* See if this is a reply for a deferred packet. */ - was_deferred_packet = get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); - - if (data->trans_info && (data->trans_info->mid == mid)) { - /* This is a reply in a trans stream. Use the sequence - * number associated with the stream mid. */ - send_seq_number = data->trans_info->send_seq_num; - } + get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); @@ -697,36 +598,6 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote client actually verifies signatures...*/ - - /* Don't mess with the sequence number for a deferred packet. */ - if (was_deferred_packet) { - return; - } - - if (!data->trans_info) { - /* Always increment if not in a trans stream. */ - data->send_seq_num++; - } else if ((data->trans_info->send_seq_num == data->send_seq_num) || (data->trans_info->mid != mid)) { - /* Increment if this is the first reply in a trans stream or a - * packet that doesn't belong to this stream (different mid). */ - data->send_seq_num++; - } -} - -/*********************************************************** - Is an incoming packet an oplock break reply ? -************************************************************/ - -static BOOL is_oplock_break(char *inbuf) -{ - if (CVAL(inbuf,smb_com) != SMBlockingX) - return False; - - if (!(CVAL(inbuf,smb_vwv3) & LOCKING_ANDX_OPLOCK_RELEASE)) - return False; - - DEBUG(10,("is_oplock_break: Packet is oplock break\n")); - return True; } /*********************************************************** @@ -753,23 +624,8 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO mid = SVAL(inbuf, smb_mid); - /* Is this part of a trans stream ? */ - if (data->trans_info && (data->trans_info->mid == mid)) { - /* If so we don't increment the sequence. */ - reply_seq_number = data->trans_info->reply_seq_num; - } else { - /* We always increment the sequence number. */ - data->send_seq_num++; - - /* If we get an asynchronous oplock break reply and there - * isn't a reply pending we need to re-sync the sequence - * number. - */ - if (is_oplock_break(inbuf)) { - DEBUG(10,("srv_check_incoming_message: oplock break at seq num %u\n", data->send_seq_num)); - data->send_seq_num++; - } - } + /* We always increment the sequence number. */ + data->send_seq_num += 2; saved_seq = reply_seq_number; simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); @@ -885,9 +741,8 @@ void srv_defer_sign_response(uint16 mid) * Ensure we only store this mid reply once... */ - if (store_sequence_for_reply(&data->outstanding_packet_list, mid, data->send_seq_num)) { - data->send_seq_num++; - } + store_sequence_for_reply(&data->outstanding_packet_list, mid, + data->send_seq_num-1); } /*********************************************************** @@ -974,63 +829,6 @@ BOOL srv_signing_started(void) return True; } - -/*********************************************************** - Tell server code we are in a multiple trans reply state. -************************************************************/ - -void srv_signing_trans_start(uint16 mid) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) - return; - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - if (!data) - return; - - data->trans_info = SMB_XMALLOC_P(struct trans_info_context); - ZERO_STRUCTP(data->trans_info); - - data->trans_info->reply_seq_num = data->send_seq_num-1; - data->trans_info->mid = mid; - data->trans_info->send_seq_num = data->send_seq_num; - - DEBUG(10,("srv_signing_trans_start: storing mid = %u, reply_seq_num = %u, send_seq_num = %u \ -data->send_seq_num = %u\n", - (unsigned int)mid, - (unsigned int)data->trans_info->reply_seq_num, - (unsigned int)data->trans_info->send_seq_num, - (unsigned int)data->send_seq_num )); -} - -/*********************************************************** - Tell server code we are out of a multiple trans reply state. -************************************************************/ - -void srv_signing_trans_stop(void) -{ - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) - return; - - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - if (!data || !data->trans_info) - return; - - DEBUG(10,("srv_signing_trans_stop: removing mid = %u, reply_seq_num = %u, send_seq_num = %u \ -data->send_seq_num = %u\n", - (unsigned int)data->trans_info->mid, - (unsigned int)data->trans_info->reply_seq_num, - (unsigned int)data->trans_info->send_seq_num, - (unsigned int)data->send_seq_num )); - - SAFE_FREE(data->trans_info); - data->trans_info = NULL; -} - /*********************************************************** Turn on signing from this packet onwards. ************************************************************/ -- cgit From 41a35cfe940ceba7b89eec776ca78eec8eeb4a82 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Apr 2006 23:32:05 +0000 Subject: r15028: Fix logic error checking valid args to POSIX lock call. Jeremy. (This used to be commit 44b0d856ae867d1c407507dcf7940dd39f4f963a) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 80deb3a332..46ff8af6d5 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1148,7 +1148,7 @@ BOOL cli_posix_lock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len, BOOL wait_lock, enum brl_type lock_type) { - if (lock_type != READ_LOCK || lock_type != WRITE_LOCK) { + if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) { return False; } return cli_posix_lock_internal(cli, fnum, offset, len, wait_lock, lock_type); -- cgit From 0498f3b8890ec62eeb9275a6bf685a6c3d81fce5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Apr 2006 18:00:57 +0000 Subject: r15129: Separate out mechanism and policy for NTLMSSP auth/sign/seal. With this change (and setting lanman auth = no in smb.conf) we have *identical* NTLMSSP flags to W2K3 in SPNEGO auth. Jeremy (This used to be commit 93ca3eee55297eb7fdd38fca38103ce129987e2a) --- source3/libsmb/ntlmssp.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index e1ef69aed9..986fa8cce9 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -363,9 +363,6 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, if (!(neg_flags & NTLMSSP_NEGOTIATE_128)) { ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_128; - if (neg_flags & NTLMSSP_NEGOTIATE_56) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; - } } if (!(neg_flags & NTLMSSP_NEGOTIATE_56)) { @@ -376,10 +373,23 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_KEY_EXCH; } + if (!(neg_flags & NTLMSSP_NEGOTIATE_SIGN)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN; + } + + if (!(neg_flags & NTLMSSP_NEGOTIATE_SEAL)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SEAL; + } + + /* Woop Woop - unknown flag for Windows compatibility... + What does this really do ? JRA. */ + if (!(neg_flags & NTLMSSP_UNKNOWN_02000000)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_UNKNOWN_02000000; + } + if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { ntlmssp_state->neg_flags |= NTLMSSP_REQUEST_TARGET; } - } /** @@ -840,6 +850,8 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_56 | + NTLMSSP_UNKNOWN_02000000 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | -- cgit From 7b75d2c650cc8dfe8c9d5b9e396afce1cedb0645 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 22 Apr 2006 02:33:11 +0000 Subject: r15162: Patch for bug #3668. Windows has a bug with LARGE_READX where if you ask for exactly 64k bytes it returns 0. Jeremy. (This used to be commit dcef65acb5bc08ea4b61ef490a518b7e668ff2ee) --- source3/libsmb/cliconnect.c | 22 +++++++++++++++++++--- source3/libsmb/clireadwrite.c | 6 +++++- 2 files changed, 24 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 48885f19d8..6b5de6d143 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -199,6 +199,10 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); + if (strstr(cli->server_type, "Samba")) { + cli->is_samba = True; + } + fstrcpy(cli->user_name, ""); return True; @@ -263,6 +267,10 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); fstrcpy(cli->user_name, user); + if (strstr(cli->server_type, "Samba")) { + cli->is_samba = True; + } + return True; } @@ -408,6 +416,10 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), -1, STR_TERMINATE); p += clistr_pull(cli, cli->server_domain, p, sizeof(fstring), -1, STR_TERMINATE); + if (strstr(cli->server_type, "Samba")) { + cli->is_samba = True; + } + fstrcpy(cli->user_name, user); if (session_key.data) { @@ -873,6 +885,10 @@ BOOL cli_session_setup(struct cli_state *cli, } } + if (strstr(cli->server_type, "Samba")) { + cli->is_samba = True; + } + return True; } @@ -1159,9 +1175,9 @@ BOOL cli_negprot(struct cli_state *cli) if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) { SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); - cli->outbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); - cli->inbuf = (char *)SMB_MALLOC(CLI_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); - cli->bufsize = CLI_MAX_LARGE_READX_SIZE; + cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); + cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); + cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE; } } else if (cli->protocol >= PROTOCOL_LANMAN1) { diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 650822bf8e..883bc1260d 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -76,7 +76,11 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ */ if (cli->capabilities & CAP_LARGE_READX) { - readsize = CLI_MAX_LARGE_READX_SIZE; + if (cli->is_samba) { + readsize = CLI_SAMBA_MAX_LARGE_READX_SIZE; + } else { + readsize = CLI_WINDOWS_MAX_LARGE_READX_SIZE; + } } else { readsize = (cli->max_xmit - (smb_size+32)) & ~1023; } -- cgit From b68b05854ff5a7e75953462eba74f97753428ef1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Apr 2006 15:57:54 +0000 Subject: r15210: Add wrapper functions smb_krb5_parse_name, smb_krb5_unparse_name, smb_krb5_parse_name_norealm_conv that pull/push from unix charset to utf8 (which krb5 uses on the wire). This should fix issues when the unix charset is not compatible with or set to utf8. Jeremy. (This used to be commit 37ab42afbc9a79cf5b04ce6a1bf4060e9c961199) --- source3/libsmb/clikrb5.c | 93 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 4943f67b77..1f43b91e38 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -38,6 +38,78 @@ #define KRB5_KEY_DATA(k) ((k)->contents) #endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ +/************************************************************** + Wrappers around kerberos string functions that convert from + utf8 -> unix charset and vica versa. +**************************************************************/ + +/************************************************************** + krb5_parse_name that takes a UNIX charset. +**************************************************************/ + +krb5_error_code smb_krb5_parse_name(krb5_context context, + const char *name, /* in unix charset */ + krb5_principal *principal) +{ + krb5_error_code ret; + char *utf8_name; + + if (push_utf8_allocate(&utf8_name, name) == (size_t)-1) { + return ENOMEM; + } + + ret = krb5_parse_name(context, utf8_name, principal); + SAFE_FREE(utf8_name); + return ret; +} + +#ifdef HAVE_KRB5_PARSE_NAME_NOREALM +/************************************************************** + krb5_parse_name_norealm that takes a UNIX charset. +**************************************************************/ + +static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, + const char *name, /* in unix charset */ + krb5_principal *principal) +{ + krb5_error_code ret; + char *utf8_name; + + if (push_utf8_allocate(&utf8_name, name) == (size_t)-1) { + return ENOMEM; + } + + ret = krb5_parse_name_norealm(context, utf8_name, principal); + SAFE_FREE(utf8_name); + return ret; +} +#endif + +/************************************************************** + krb5_parse_name that returns a UNIX charset name. Must + be freed with normal free() call. +**************************************************************/ + +krb5_error_code smb_krb5_unparse_name(krb5_context context, + krb5_const_principal principal, + char **unix_name) +{ + krb5_error_code ret; + char *utf8_name; + + ret = krb5_unparse_name(context, principal, &utf8_name); + if (ret) { + return ret; + } + + if (pull_utf8_allocate(unix_name, utf8_name)==-1) { + krb5_free_unparsed_name(context, utf8_name); + return ENOMEM; + } + krb5_free_unparsed_name(context, utf8_name); + return 0; +} + #ifndef HAVE_KRB5_SET_REAL_TIME /* * This function is not in the Heimdal mainline. @@ -459,7 +531,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, BOOL creds_ready = False; int i = 0, maxtries = 3; - retval = krb5_parse_name(context, principal, &server); + retval = smb_krb5_parse_name(context, principal, &server); if (retval) { DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal)); return retval; @@ -795,10 +867,11 @@ get_key_from_keytab(krb5_context context, } if ( DEBUGLEVEL >= 10 ) { - krb5_unparse_name(context, server, &name); - DEBUG(10,("get_key_from_keytab: will look for kvno %d, enctype %d and name: %s\n", - kvno, enctype, name)); - krb5_free_unparsed_name(context, name); + if (smb_krb5_unparse_name(context, server, &name) == 0) { + DEBUG(10,("get_key_from_keytab: will look for kvno %d, enctype %d and name: %s\n", + kvno, enctype, name)); + SAFE_FREE(name); + } } ret = krb5_kt_get_entry(context, @@ -943,7 +1016,7 @@ out: krb5_principal *principal) { #ifdef HAVE_KRB5_PARSE_NAME_NOREALM - return krb5_parse_name_norealm(context, name, principal); + return smb_krb5_parse_name_norealm_conv(context, name, principal); #endif /* we are cheating here because parse_name will in fact set the realm. @@ -951,7 +1024,7 @@ out: * ignores the realm anyway when calling * smb_krb5_principal_compare_any_realm later - Guenther */ - return krb5_parse_name(context, name, principal); + return smb_krb5_parse_name(context, name, principal); } BOOL smb_krb5_principal_compare_any_realm(krb5_context context, @@ -1022,7 +1095,7 @@ out: krb5_creds creds; if (client_string) { - ret = krb5_parse_name(context, client_string, &client); + ret = smb_krb5_parse_name(context, client_string, &client); if (ret) { goto done; } @@ -1063,7 +1136,7 @@ out: memset(&creds_in, 0, sizeof(creds_in)); if (client_string) { - ret = krb5_parse_name(context, client_string, &creds_in.client); + ret = smb_krb5_parse_name(context, client_string, &creds_in.client); if (ret) { goto done; } @@ -1075,7 +1148,7 @@ out: } if (service_string) { - ret = krb5_parse_name(context, service_string, &creds_in.server); + ret = smb_krb5_parse_name(context, service_string, &creds_in.server); if (ret) { goto done; } -- cgit From ba52fd71dc6b4dcf42a0c2de5b2f1e1e316b1da4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Apr 2006 16:29:55 +0000 Subject: r15216: Fix the build for machines without krb5. Oops, sorry. Jeremy. (This used to be commit bea87e2df45c67cc75d91bd3ed1acc4c64a1c8ea) --- source3/libsmb/clikrb5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 1f43b91e38..d3da25760b 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -47,7 +47,7 @@ krb5_parse_name that takes a UNIX charset. **************************************************************/ -krb5_error_code smb_krb5_parse_name(krb5_context context, + krb5_error_code smb_krb5_parse_name(krb5_context context, const char *name, /* in unix charset */ krb5_principal *principal) { @@ -90,7 +90,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, be freed with normal free() call. **************************************************************/ -krb5_error_code smb_krb5_unparse_name(krb5_context context, + krb5_error_code smb_krb5_unparse_name(krb5_context context, krb5_const_principal principal, char **unix_name) { -- cgit From a1d47f3e999d2a13d77217239c12735a3ef74e29 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 25 Apr 2006 08:03:34 +0000 Subject: r15227: Fix a valgrind error. We are marshalling here, not unmarshalling. Jeremy, can you check this? This was part of your -O6 on 64bit sweep. Volker (This used to be commit 4fa5dbcc8dd1f150664e1241b22e3f048d816001) --- source3/libsmb/samlogon_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index cc1c6bd6b2..7a6d9a96ad 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -151,10 +151,9 @@ BOOL netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); { - uint32 ts; + uint32 ts = (uint32)t; if ( !prs_uint32( "timestamp", &ps, 0, &ts ) ) return False; - t = (time_t)ts; } if ( net_io_user_info3("", user, &ps, 0, 3, 0) ) -- cgit From 351e749246a278b60a7e18c1eeafdc8ec70efea2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 25 Apr 2006 12:24:25 +0000 Subject: r15240: Correctly disallow unauthorized access when logging on with the kerberized pam_winbind and workstation restrictions are in effect. The krb5 AS-REQ needs to add the host netbios-name in the address-list. We don't get the clear NT_STATUS_INVALID_WORKSTATION code back yet from the edata of the KRB_ERROR but the login at least fails when the local machine is not in the workstation list on the DC. Guenther (This used to be commit 8b2ba11508e2730aba074d7c095291fac2a62176) --- source3/libsmb/clikrb5.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/nmblib.c | 2 +- 2 files changed, 99 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index d3da25760b..40ffec6f53 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1205,6 +1205,104 @@ done: } + krb5_error_code smb_krb5_free_addresses(krb5_context context, smb_krb5_addresses *addr) +{ + krb5_error_code ret = 0; +#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ + krb5_free_addresses(context, addr->addrs); +#elif defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* Heimdal */ + ret = krb5_free_addresses(context, addr->addrs); + SAFE_FREE(addr->addrs); +#endif + SAFE_FREE(addr); + addr = NULL; + return ret; +} + + krb5_error_code smb_krb5_gen_netbios_krb5_address(smb_krb5_addresses **kerb_addr) +{ + krb5_error_code ret = 0; + nstring buf; +#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ + krb5_address **addrs = NULL; +#elif defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* Heimdal */ + krb5_addresses *addrs = NULL; +#endif + + *kerb_addr = (smb_krb5_addresses *)SMB_MALLOC(sizeof(smb_krb5_addresses)); + if (*kerb_addr == NULL) { + return ENOMEM; + } + + put_name(buf, global_myname(), ' ', 0x20); + +#if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ + { + int num_addr = 2; + + addrs = (krb5_address **)SMB_MALLOC(sizeof(krb5_address *) * num_addr); + if (addrs == NULL) { + return ENOMEM; + } + + memset(addrs, 0, sizeof(krb5_address *) * num_addr); + + addrs[0] = (krb5_address *)SMB_MALLOC(sizeof(krb5_address)); + if (addrs[0] == NULL) { + SAFE_FREE(addrs); + return ENOMEM; + } + + addrs[0]->magic = KV5M_ADDRESS; + addrs[0]->addrtype = KRB5_ADDR_NETBIOS; + addrs[0]->length = MAX_NETBIOSNAME_LEN; + addrs[0]->contents = (unsigned char *)SMB_MALLOC(addrs[0]->length); + if (addrs[0]->contents == NULL) { + SAFE_FREE(addrs[0]); + SAFE_FREE(addrs); + return ENOMEM; + } + + memcpy(addrs[0]->contents, buf, addrs[0]->length); + + addrs[1] = NULL; + } +#elif defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* Heimdal */ + { + addrs = (krb5_addresses *)SMB_MALLOC(sizeof(krb5_addresses)); + if (addrs == NULL) { + return ENOMEM; + } + + memset(addrs, 0, sizeof(krb5_addresses)); + + addrs->len = 1; + addrs->val = (krb5_address *)SMB_MALLOC(sizeof(krb5_address)); + if (addrs->val == NULL) { + SAFE_FREE(addrs); + return ENOMEM; + } + + addrs->val[0].addr_type = KRB5_ADDR_NETBIOS; + addrs->val[0].address.length = MAX_NETBIOSNAME_LEN; + addrs->val[0].address.data = (unsigned char *)SMB_MALLOC(addrs->val[0].address.length); + if (addrs->val[0].address.data == NULL) { + SAFE_FREE(addrs->val); + SAFE_FREE(addrs); + return ENOMEM; + } + + memcpy(addrs->val[0].address.data, buf, addrs->val[0].address.length); + } +#else +#error UNKNOWN_KRB5_ADDRESS_FORMAT +#endif + (*kerb_addr)->addrs = addrs; + + return ret; +} + + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4d84d7bc49..5280dfdbff 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -265,7 +265,7 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) [15 bytes name + padding][1 byte name type]. ****************************************************************************/ -static void put_name(char *dest, const char *name, int pad, unsigned int name_type) +void put_name(char *dest, const char *name, int pad, unsigned int name_type) { size_t len = strlen(name); -- cgit From 6f5effa730dde49ec30e03e3bc403990affe9f03 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 25 Apr 2006 12:53:38 +0000 Subject: r15243: Sorry for the breakage: * Fix the build without kerberos headers * Fix memleak in the krb5_address handling Guenther (This used to be commit 10e42117559d4bc6a34e41a94914bf6c65c3477f) --- source3/libsmb/clikrb5.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 40ffec6f53..e0d6b09d97 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1208,6 +1208,9 @@ done: krb5_error_code smb_krb5_free_addresses(krb5_context context, smb_krb5_addresses *addr) { krb5_error_code ret = 0; + if (addr == NULL) { + return ret; + } #if defined(HAVE_MAGIC_IN_KRB5_ADDRESS) && defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ krb5_free_addresses(context, addr->addrs); #elif defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* Heimdal */ @@ -1242,6 +1245,7 @@ done: addrs = (krb5_address **)SMB_MALLOC(sizeof(krb5_address *) * num_addr); if (addrs == NULL) { + SAFE_FREE(kerb_addr); return ENOMEM; } @@ -1250,6 +1254,7 @@ done: addrs[0] = (krb5_address *)SMB_MALLOC(sizeof(krb5_address)); if (addrs[0] == NULL) { SAFE_FREE(addrs); + SAFE_FREE(kerb_addr); return ENOMEM; } @@ -1260,6 +1265,7 @@ done: if (addrs[0]->contents == NULL) { SAFE_FREE(addrs[0]); SAFE_FREE(addrs); + SAFE_FREE(kerb_addr); return ENOMEM; } @@ -1271,6 +1277,7 @@ done: { addrs = (krb5_addresses *)SMB_MALLOC(sizeof(krb5_addresses)); if (addrs == NULL) { + SAFE_FREE(kerb_addr); return ENOMEM; } @@ -1280,6 +1287,7 @@ done: addrs->val = (krb5_address *)SMB_MALLOC(sizeof(krb5_address)); if (addrs->val == NULL) { SAFE_FREE(addrs); + SAFE_FREE(kerb_addr); return ENOMEM; } @@ -1289,6 +1297,7 @@ done: if (addrs->val[0].address.data == NULL) { SAFE_FREE(addrs->val); SAFE_FREE(addrs); + SAFE_FREE(kerb_addr); return ENOMEM; } -- cgit From af086da4ec19de83717820de85d8e672850ed4b2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 May 2006 19:24:48 +0000 Subject: r15462: replace the use of OpenLDAP's ldap_domain2hostlist() for locating AD DC's with out own DNS SRV queries. Testing on Linux and Solaris. (This used to be commit cf71f88a3cdcabf99c0798ef4cf8c978397a57eb) --- source3/libsmb/namequery.c | 51 ++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1d40837f2b..99a2e7ebdb 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1024,13 +1024,13 @@ static BOOL resolve_hosts(const char *name, int name_type, static BOOL resolve_ads(const char *name, int name_type, struct ip_service **return_iplist, int *return_count) { - #ifdef HAVE_ADS if ( name_type == 0x1c ) { int count, i = 0; - char *list = NULL; - const char *ptr; - pstring tok; + NTSTATUS status; + TALLOC_CTX *ctx; + struct dns_rr_srv *dcs = NULL; + int numdcs = 0; /* try to lookup the _ldap._tcp. if we are using ADS */ if ( lp_security() != SEC_ADS ) @@ -1039,25 +1039,31 @@ static BOOL resolve_ads(const char *name, int name_type, DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n", name)); - if (ldap_domain2hostlist(name, &list) != LDAP_SUCCESS) + if ( (ctx = talloc_init("resolve_ads")) == NULL ) { + DEBUG(0,("resolve_ads: talloc_init() failed!\n")); return False; - - count = count_chars(list, ' ') + 1; - if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) { - DEBUG(0,("resolve_hosts: malloc failed for %d entries\n", count )); + } + + status = ads_dns_query_dcs( ctx, name, &dcs, &numdcs ); + if ( !NT_STATUS_IS_OK( status ) ) { + return False; + } + + if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numdcs)) == NULL ) { + DEBUG(0,("resolve_ads: malloc failed for %d entries\n", count )); return False; } - ptr = list; - while (next_token(&ptr, tok, " ", sizeof(tok))) { - unsigned port = LDAP_PORT; - char *p = strchr(tok, ':'); - if (p) { - *p = 0; - port = atoi(p+1); - } - (*return_iplist)[i].ip = *interpret_addr2(tok); - (*return_iplist)[i].port = port; + i = 0; + while ( i < numdcs ) { + + /* use the IP address from the SRV structure if we have one */ + if ( is_zero_ip( dcs[i].ip ) ) + (*return_iplist)[i].ip = *interpret_addr2(dcs[i].hostname); + else + (*return_iplist)[i].ip = dcs[i].ip; + + (*return_iplist)[i].port = dcs[i].port; /* make sure it is a valid IP. I considered checking the negative connection cache, but this is the wrong place for it. Maybe only @@ -1067,11 +1073,12 @@ static BOOL resolve_ads(const char *name, int name_type, our DNS server doesn't know anything about the DC's -- jerry */ if ( is_zero_ip((*return_iplist)[i].ip) ) - continue; - + continue; + i++; } - SAFE_FREE(list); + + TALLOC_FREE( dcs ); *return_count = i; -- cgit From 2c029a8b96ae476f1d5c2abe14ee25f98a1513d8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 12 May 2006 15:17:35 +0000 Subject: r15543: New implementation of 'net ads join' to be more like Windows XP. The motivating factor is to not require more privileges for the user account than Windows does when joining a domain. The points of interest are * net_ads_join() uses same rpc mechanisms as net_rpc_join() * Enable CLDAP queries for filling in the majority of the ADS_STRUCT->config information * Remove ldap_initialized() from sam/idmap_ad.c and libads/ldap.c * Remove some unnecessary fields from ADS_STRUCT * Manually set the dNSHostName and servicePrincipalName attribute using the machine account after the join Thanks to Guenther and Simo for the review. Still to do: * Fix the userAccountControl for DES only systems * Set the userPrincipalName in order to support things like 'kinit -k' (although we might be able to just use the sAMAccountName instead) * Re-add support for pre-creating the machine account in a specific OU (This used to be commit 4c4ea7b20f44cd200cef8c7b389d51b72eccc39b) --- source3/libsmb/namequery.c | 97 +++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 53 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 99a2e7ebdb..1033a375c5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1024,70 +1024,62 @@ static BOOL resolve_hosts(const char *name, int name_type, static BOOL resolve_ads(const char *name, int name_type, struct ip_service **return_iplist, int *return_count) { -#ifdef HAVE_ADS - if ( name_type == 0x1c ) { - int count, i = 0; - NTSTATUS status; - TALLOC_CTX *ctx; - struct dns_rr_srv *dcs = NULL; - int numdcs = 0; + int count, i = 0; + NTSTATUS status; + TALLOC_CTX *ctx; + struct dns_rr_srv *dcs = NULL; + int numdcs = 0; + + if ( name_type != 0x1c ) + return False; - /* try to lookup the _ldap._tcp. if we are using ADS */ - if ( lp_security() != SEC_ADS ) - return False; + DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n", + name)); - DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n", - name)); - - if ( (ctx = talloc_init("resolve_ads")) == NULL ) { - DEBUG(0,("resolve_ads: talloc_init() failed!\n")); - return False; - } + if ( (ctx = talloc_init("resolve_ads")) == NULL ) { + DEBUG(0,("resolve_ads: talloc_init() failed!\n")); + return False; + } - status = ads_dns_query_dcs( ctx, name, &dcs, &numdcs ); - if ( !NT_STATUS_IS_OK( status ) ) { - return False; - } + status = ads_dns_query_dcs( ctx, name, &dcs, &numdcs ); + if ( !NT_STATUS_IS_OK( status ) ) { + return False; + } - if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numdcs)) == NULL ) { - DEBUG(0,("resolve_ads: malloc failed for %d entries\n", count )); - return False; - } + if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numdcs)) == NULL ) { + DEBUG(0,("resolve_ads: malloc failed for %d entries\n", count )); + return False; + } - i = 0; - while ( i < numdcs ) { + i = 0; + while ( i < numdcs ) { - /* use the IP address from the SRV structure if we have one */ - if ( is_zero_ip( dcs[i].ip ) ) - (*return_iplist)[i].ip = *interpret_addr2(dcs[i].hostname); - else - (*return_iplist)[i].ip = dcs[i].ip; + /* use the IP address from the SRV structure if we have one */ + if ( is_zero_ip( dcs[i].ip ) ) + (*return_iplist)[i].ip = *interpret_addr2(dcs[i].hostname); + else + (*return_iplist)[i].ip = dcs[i].ip; - (*return_iplist)[i].port = dcs[i].port; + (*return_iplist)[i].port = dcs[i].port; - /* make sure it is a valid IP. I considered checking the negative - connection cache, but this is the wrong place for it. Maybe only - as a hac. After think about it, if all of the IP addresses retuend - from DNS are dead, what hope does a netbios name lookup have? - The standard reason for falling back to netbios lookups is that - our DNS server doesn't know anything about the DC's -- jerry */ + /* make sure it is a valid IP. I considered checking the negative + connection cache, but this is the wrong place for it. Maybe only + as a hac. After think about it, if all of the IP addresses retuend + from DNS are dead, what hope does a netbios name lookup have? + The standard reason for falling back to netbios lookups is that + our DNS server doesn't know anything about the DC's -- jerry */ - if ( is_zero_ip((*return_iplist)[i].ip) ) - continue; + if ( is_zero_ip((*return_iplist)[i].ip) ) + continue; - i++; - } + i++; + } - TALLOC_FREE( dcs ); + TALLOC_FREE( dcs ); - *return_count = i; + *return_count = i; - return True; - } else -#endif /* HAVE_ADS */ - { - return False; - } + return True; } /******************************************************************* @@ -1178,8 +1170,7 @@ BOOL internal_resolve_name(const char *name, int name_type, } } else if(strequal( tok, "ads")) { /* deal with 0x1c names here. This will result in a - SRV record lookup for _ldap._tcp. if we - are using 'security = ads' */ + SRV record lookup */ if (resolve_ads(name, name_type, return_iplist, return_count)) { result = True; goto done; -- cgit From ee7b4b47cb590dc16ebdf3a40b360b0f0600aa84 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 May 2006 23:05:53 +0000 Subject: r15589: While trying to understand the vuid code I found that security=share is broken right now. r14112 broke it, in 3.0.22 register_vuid for security=share returns UID_FIELD_INVALID which in current 3_0 is turned into an error condition. This makes sure that we only call register_vuid if sec!=share and meanwhile also fixes a little memleak. Then I also found a crash in smbclient with sec=share and hostmsdfs=yes. There's another crash with sec=share when coming from w2k3, but I need sleep now. Someone (jerry,jra?) please review the sesssetup.c change. Thanks, Volker (This used to be commit 8059d0ae395604503cad3d9f197928305923e3f5) --- source3/libsmb/cliconnect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6b5de6d143..beabddc782 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -221,6 +221,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); + memset(cli->outbuf, '\0', smb_size); set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -937,7 +938,8 @@ BOOL cli_send_tconX(struct cli_state *cli, pass = ""; } - if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { + if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && + pass && *pass && passlen != 24) { if (!lp_client_lanman_auth()) { DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'" " is disabled\n")); -- cgit From f9480025b5192263084c601bdb8d15508a61409c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 May 2006 04:51:46 +0000 Subject: r15610: Fix Coverity #288 - possible null deref. Jeremy. (This used to be commit b108ab7b122cc607f31772614b221379403b211b) --- source3/libsmb/cliconnect.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index beabddc782..3bdd78560f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -922,6 +922,7 @@ BOOL cli_ulogoff(struct cli_state *cli) /**************************************************************************** Send a tconX. ****************************************************************************/ + BOOL cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { @@ -936,10 +937,13 @@ BOOL cli_send_tconX(struct cli_state *cli, if (cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) { passlen = 1; pass = ""; + } else if (!pass) { + DEBUG(1, ("Server not using user level security and no password supplied.\n")); + return False; } if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && - pass && *pass && passlen != 24) { + *pass && passlen != 24) { if (!lp_client_lanman_auth()) { DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'" " is disabled\n")); @@ -965,7 +969,9 @@ BOOL cli_send_tconX(struct cli_state *cli, passlen = clistr_push(cli, pword, pass, sizeof(pword), STR_TERMINATE); } else { - memcpy(pword, pass, passlen); + if (passlen) { + memcpy(pword, pass, passlen); + } } } @@ -980,7 +986,9 @@ BOOL cli_send_tconX(struct cli_state *cli, SSVAL(cli->outbuf,smb_vwv3,passlen); p = smb_buf(cli->outbuf); - memcpy(p,pword,passlen); + if (passlen) { + memcpy(p,pword,passlen); + } p += passlen; p += clistr_push(cli, p, fullshare, -1, STR_TERMINATE |STR_UPPER); p += clistr_push(cli, p, dev, -1, STR_TERMINATE |STR_UPPER | STR_ASCII); -- cgit From 39c7fe679ecc3035720091a856c18baa45cbcfae Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 15 May 2006 06:54:13 +0000 Subject: r15611: Remove used but uninitialised variable "count". (This used to be commit 71fd0d3de4a02b9a7b67914f6412f18ec0bb5e7a) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1033a375c5..0172ab9514 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1024,7 +1024,7 @@ static BOOL resolve_hosts(const char *name, int name_type, static BOOL resolve_ads(const char *name, int name_type, struct ip_service **return_iplist, int *return_count) { - int count, i = 0; + int i = 0; NTSTATUS status; TALLOC_CTX *ctx; struct dns_rr_srv *dcs = NULL; @@ -1047,7 +1047,7 @@ static BOOL resolve_ads(const char *name, int name_type, } if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numdcs)) == NULL ) { - DEBUG(0,("resolve_ads: malloc failed for %d entries\n", count )); + DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numdcs )); return False; } -- cgit From 78eac3e24bcd27254aaadff498f4d177cb2c1517 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 18 May 2006 04:33:43 +0000 Subject: r15681: fix segv in 'kinit && net ads join' (This used to be commit d77768cb237461b06119ee19f822b120623d77dd) --- source3/libsmb/cliconnect.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3bdd78560f..2400f6ff1d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1493,6 +1493,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, { NTSTATUS nt_status; struct cli_state *cli = NULL; + int pw_len = password ? strlen(password)+1 : 0; nt_status = cli_start_connection(&cli, my_name, dest_host, dest_ip, port, signing_state, flags, retry); @@ -1501,9 +1502,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return nt_status; } - if (!cli_session_setup(cli, user, password, strlen(password)+1, - password, strlen(password)+1, - domain)) { + if (!cli_session_setup(cli, user, password, pw_len, password, pw_len, domain)) { if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) && cli_session_setup(cli, "", "", 0, "", 0, domain)) { } else { @@ -1517,8 +1516,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, } if (service) { - if (!cli_send_tconX(cli, service, service_type, - password, strlen(password)+1)) { + if (!cli_send_tconX(cli, service, service_type, password, pw_len)) { nt_status = cli_nt_error(cli); DEBUG(1,("failed tcon_X with %s\n", nt_errstr(nt_status))); cli_shutdown(cli); -- cgit From 824ba94fbe2e25efdd63e15342e14f4a9e078357 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 20 May 2006 18:30:09 +0000 Subject: r15755: Fix Coverity bug # 294. Apparently password can be NULL, but cli_session_setup derefences it. Volker (This used to be commit b013b6908d22cfd38fcc56a9cb2ca675d75996d1) --- source3/libsmb/cliconnect.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2400f6ff1d..7f5b5d7fa5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1495,6 +1495,10 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct cli_state *cli = NULL; int pw_len = password ? strlen(password)+1 : 0; + if (password == NULL) { + password = ""; + } + nt_status = cli_start_connection(&cli, my_name, dest_host, dest_ip, port, signing_state, flags, retry); -- cgit From 61d2dfcd30a0602c94e84dda7fe56b671934e66b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Jun 2006 00:52:11 +0000 Subject: r15997: Fix bug in OS/2 Warp - it doesn't set the ff_last offset correctly when doing info level 1 directory scans. Thanks to Guenter Kukkukk for reporting this problem and testing the fix. Jeremy. (This used to be commit 65d4dfbd6045a4e3f9eaf520c70ef29ff7ddee82) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 1bd30c36e3..9ab05d2b4a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -330,7 +330,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } } - if (ff_lastname > 0) { + if (ff_searchcount > 0) { pstrcpy(mask, finfo.name); } else { pstrcpy(mask,""); -- cgit From 3ea740f5e5265103eacec2979c6c535eed30e346 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Jun 2006 18:32:25 +0000 Subject: r16156: Fix storing NULL in the wrong place. Klocwork id's 127 and 128. Volker (This used to be commit 7674a4f8361d3f3b649245118b82d8a074a2760e) --- source3/libsmb/clispnego.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 13bf1a866c..e87e9f0c7c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -140,7 +140,7 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data,ASN1_CONTEXT(0)); asn1_start_tag(&data,ASN1_SEQUENCE(0)); - for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS-1; i++) { char *oid_str = NULL; asn1_read_OID(&data,&oid_str); OIDs[i] = oid_str; @@ -229,7 +229,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_start_tag(&data, ASN1_SEQUENCE(0)); - for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS-1; i++) { char *oid_str = NULL; asn1_read_OID(&data,&oid_str); OIDs[i] = oid_str; -- cgit From 92db75b4a25823cf6882681267418a71d3cdb8c9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Jun 2006 18:15:03 +0000 Subject: r16202: Fix Klocwork #3. Strange - was already fixed in HEAD. Jeremy. (This used to be commit 319f80bbf0455cfaf80eab51313a56db4ed04ac5) --- source3/libsmb/asn1.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 072fd30283..86a2845192 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -268,17 +268,22 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) } if (!asn1_read_uint8(data, &b)) { + SAFE_FREE(nesting); return False; } if (b & 0x80) { int n = b & 0x7f; - if (!asn1_read_uint8(data, &b)) + if (!asn1_read_uint8(data, &b)) { + SAFE_FREE(nesting); return False; + } nesting->taglen = b; while (n > 1) { - if (!asn1_read_uint8(data, &b)) + if (!asn1_read_uint8(data, &b)) { + SAFE_FREE(nesting); return False; + } nesting->taglen = (nesting->taglen << 8) | b; n--; } -- cgit From 069397c63ead319d5e237fa1ce16714bb86fc7f7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Jun 2006 21:01:08 +0000 Subject: r16207: Ensure we don't allocate an OID string unless we know we don't have an error. Klocwork #6. Jeremy. (This used to be commit 2c1a2d7b40e7ef353461f97f5c69c2079b5670ab) --- source3/libsmb/asn1.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 86a2845192..8c986c9588 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -340,7 +340,11 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) pstring oid_str; fstring el; - if (!asn1_start_tag(data, ASN1_OID)) return False; + *OID = NULL; + + if (!asn1_start_tag(data, ASN1_OID)) { + return False; + } asn1_read_uint8(data, &b); oid_str[0] = 0; @@ -361,7 +365,9 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) asn1_end_tag(data); - *OID = SMB_STRDUP(oid_str); + if (!data->has_error) { + *OID = SMB_STRDUP(oid_str); + } return !data->has_error; } @@ -371,7 +377,9 @@ BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) { char *id; - if (!asn1_read_OID(data, &id)) return False; + if (!asn1_read_OID(data, &id)) { + return False; + } if (strcmp(id, OID) != 0) { data->has_error = True; -- cgit From fdced4467f6108eb848ffe79b9604134487c543c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 15 Jun 2006 10:48:53 +0000 Subject: r16249: Fix Klokwork ID 130 (This used to be commit 09586824f6568fb3305e3e59ba6bc8f5f632fb56) --- source3/libsmb/clidfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 03cfd4dd40..298f4d1b54 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -415,7 +415,7 @@ static void clean_path( pstring clean, const char *path ) /* strip a trailing backslash */ len = strlen( newpath ); - if ( newpath[len-1] == '\\' ) + if ( (len > 0) && (newpath[len-1] == '\\') ) newpath[len-1] = '\0'; pstrcpy( clean, newpath ); -- cgit From e030a9e9dcda36edee475aa9fd8772f9f74b3552 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Jun 2006 21:25:57 +0000 Subject: r16268: Add TCP fallback for our implementation of the CHANGEPW kpasswd calls. This patch is mainly based on the work of Todd Stecher and has been reviewed by Jeremy. I sucessfully tested and valgrinded it with MIT 1.4.3, 1.3.5, Heimdal 0.7.2 and 0.6.1rc3. Guenther (This used to be commit 535d03cbe8b021e9aa6d74b62d81b867c494c957) --- source3/libsmb/clikrb5.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index e0d6b09d97..f1815b3e8f 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1310,7 +1310,64 @@ done: return ret; } - + +void smb_krb5_free_error(krb5_context context, krb5_error *krberror) +{ +#ifdef HAVE_KRB5_FREE_ERROR_CONTENTS /* Heimdal */ + krb5_free_error_contents(context, krberror); +#else /* MIT */ + krb5_free_error(context, krberror); +#endif +} + +krb5_error_code handle_krberror_packet(krb5_context context, + krb5_data *packet) +{ + krb5_error_code ret; + BOOL got_error_code = False; + + DEBUG(10,("handle_krberror_packet: got error packet\n")); + +#ifdef HAVE_E_DATA_POINTER_IN_KRB5_ERROR /* Heimdal */ + { + krb5_error krberror; + + if ((ret = krb5_rd_error(context, packet, &krberror))) { + DEBUG(10,("handle_krberror_packet: krb5_rd_error failed with: %s\n", + error_message(ret))); + return ret; + } + + if (krberror.e_data == NULL || krberror.e_data->data == NULL) { + ret = (krb5_error_code) krberror.error_code; + got_error_code = True; + } + + smb_krb5_free_error(context, &krberror); + } +#else /* MIT */ + { + krb5_error *krberror; + + if ((ret = krb5_rd_error(context, packet, &krberror))) { + DEBUG(10,("handle_krberror_packet: krb5_rd_error failed with: %s\n", + error_message(ret))); + return ret; + } + + if (krberror->e_data.data == NULL) { + ret = ERROR_TABLE_BASE_krb5 + (krb5_error_code) krberror->error; + got_error_code = True; + } + smb_krb5_free_error(context, krberror); + } +#endif + if (got_error_code) { + DEBUG(5,("handle_krberror_packet: got KERBERR from kpasswd: %s (%d)\n", + error_message(ret), ret)); + } + return ret; +} #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -- cgit From 9e7377e81f61b2a3e4b8ff4cc5cd926e25ddacf3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 Jun 2006 21:45:10 +0000 Subject: r16269: Fix the build. Guenther (This used to be commit 546710d58c07acdaa175caa48cec4d3f2bc657ad) --- source3/libsmb/clikrb5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index f1815b3e8f..abb3843bac 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1311,7 +1311,7 @@ done: return ret; } -void smb_krb5_free_error(krb5_context context, krb5_error *krberror) + void smb_krb5_free_error(krb5_context context, krb5_error *krberror) { #ifdef HAVE_KRB5_FREE_ERROR_CONTENTS /* Heimdal */ krb5_free_error_contents(context, krberror); @@ -1320,8 +1320,8 @@ void smb_krb5_free_error(krb5_context context, krb5_error *krberror) #endif } -krb5_error_code handle_krberror_packet(krb5_context context, - krb5_data *packet) + krb5_error_code handle_krberror_packet(krb5_context context, + krb5_data *packet) { krb5_error_code ret; BOOL got_error_code = False; -- cgit From 0eb9bd176eb1f7f22d4c4bcdca95d2ea11b2b154 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 02:23:02 +0000 Subject: r16287: Use intptr_t to return an integer of an unknown type cast to void *. Jeremy. (This used to be commit e24361ecddef8a48a42a356775b93ce5c4027fae) --- source3/libsmb/libsmbclient.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2436cc9136..4ea0ab6eb6 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -6036,7 +6036,11 @@ smbc_option_get(SMBCCTX *context, /* * Log to standard error instead of standard output. */ +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->internal->_debug_stderr; +#else return (void *) context->internal->_debug_stderr; +#endif } else if (strcmp(option_name, "auth_function") == 0) { /* * Use the new-style authentication function which includes -- cgit From 3a8bf11ae341c34db61ef35cbdba6ff835940c79 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 22:25:17 +0000 Subject: r16306: Error handling in this asn1 code *sucks*. Fix a generic class of memory leak bugs on error found by Klocwork (#123). Many of these functions didn't free allocated memory on error exit. Jeremy. (This used to be commit 8ef11a7c6de74024b7d535d959db2d462662a86f) --- source3/libsmb/asn1.c | 20 +++++++++++++++----- source3/libsmb/clispnego.c | 27 ++++++++++++++++++++++++--- 2 files changed, 39 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 8c986c9588..544ee78d40 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -393,20 +393,30 @@ BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) { int len; - if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) return False; + char *str; + + *s = NULL; + + if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) { + return False; + } len = asn1_tag_remaining(data); if (len < 0) { data->has_error = True; return False; } - *s = SMB_MALLOC(len+1); - if (! *s) { + str = SMB_MALLOC(len+1); + if (!str) { data->has_error = True; return False; } - asn1_read(data, *s, len); - (*s)[len] = 0; + asn1_read(data, str, len); + str[len] = 0; asn1_end_tag(data); + + if (!data->has_error) { + *s = str; + } return !data->has_error; } diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e87e9f0c7c..3dad37d9e1 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -163,11 +163,18 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_end_tag(&data); ret = !data.has_error; + if (data.has_error) { + int j; + SAFE_FREE(principal); + for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { + SAFE_FREE(OIDs[j]); + } + } + asn1_free(&data); return ret; } - /* generate a negTokenTarg packet given a list of OIDs and a security blob */ @@ -212,7 +219,6 @@ DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) return ret; } - /* parse a negTokenTarg packet giving a list of OIDs and a security blob */ @@ -248,6 +254,11 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_end_tag(&data); if (data.has_error) { + int j; + data_blob_free(secblob); + for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { + SAFE_FREE(OIDs[j]); + } DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data.ofs)); asn1_free(&data); return False; @@ -313,6 +324,10 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) ret = !data.has_error; + if (data.has_error) { + data_blob_free(ticket); + } + asn1_free(&data); return ret; @@ -390,6 +405,12 @@ BOOL spnego_parse_challenge(const DATA_BLOB blob, asn1_end_tag(&data); ret = !data.has_error; + + if (data.has_error) { + data_blob_free(chal1); + data_blob_free(chal2); + } + asn1_free(&data); return ret; } @@ -438,6 +459,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) if (data.has_error) { DEBUG(3,("spnego_parse_auth failed at %d\n", (int)data.ofs)); + data_blob_free(auth); asn1_free(&data); return False; } @@ -537,4 +559,3 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, asn1_free(&data); return True; } - -- cgit From f40e9fcc5b75fdd272a8de17c560cdc5b3e68694 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Jun 2006 17:23:54 +0000 Subject: r16356: Helping derrell out. Jeremy. Only set the DFS capability flag if the share is a DFS root. Fixes bug 3814. (This used to be commit 6193f1170819096ea8a646e5a456f627df83872d) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 83664b0b32..f5116234c8 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -198,7 +198,7 @@ void cli_setup_packet(struct cli_state *cli) flags2 = FLAGS2_LONG_PATH_COMPONENTS; if (cli->capabilities & CAP_UNICODE) flags2 |= FLAGS2_UNICODE_STRINGS; - if (cli->capabilities & CAP_DFS) + if ((cli->capabilities & CAP_DFS) && cli->dfsroot) flags2 |= FLAGS2_DFS_PATHNAMES; if (cli->capabilities & CAP_STATUS32) flags2 |= FLAGS2_32_BIT_ERROR_CODES; -- cgit From e7fc37cf0f4bd2c0f25865fb07d1bff27b239130 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 19 Jun 2006 19:07:39 +0000 Subject: r16360: Fix Klocwork ID 136 520 521 522 523 542 574 575 576 607 in net_rpc.c: 715 716 732 734 735 736 737 738 739 749 in net_rpc_audit.c: 754 755 756 in net_rpc_join.c: 757 in net_rpc_registry: 766 767 in net_rpc_samsync.c: 771 773 in net_sam.c: 797 798 Volker (This used to be commit 3df0bf7d6050fd7c9ace72487d4f74d92e30a584) --- source3/libsmb/clidfs.c | 9 ++++++--- source3/libsmb/libsmb_compat.c | 16 ++++++++++++++++ source3/libsmb/libsmbclient.c | 4 +++- 3 files changed, 25 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 298f4d1b54..e564bc4295 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -652,9 +652,12 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha fullpath[consumed/2] = '\0'; dos_clean_name( fullpath ); - ppath = strchr_m( fullpath, '\\' ); - ppath = strchr_m( ppath+1, '\\' ); - ppath = strchr_m( ppath+1, '\\' ); + if ((ppath = strchr_m( fullpath, '\\' )) == NULL) + return False; + if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) + return False; + if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) + return False; ppath++; pstr_sprintf( newmount, "%s\\%s", mountpt, ppath ); diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 5699e153bb..cfd5948e26 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -341,6 +341,10 @@ int smbc_fsetxattr(int fd, int flags) { SMBCFILE * file = find_fd(fd); + if (file == NULL) { + errno = EBADF; + return -1; + } return statcont->setxattr(statcont, file->fname, name, value, size, flags); } @@ -367,6 +371,10 @@ int smbc_fgetxattr(int fd, size_t size) { SMBCFILE * file = find_fd(fd); + if (file == NULL) { + errno = EBADF; + return -1; + } return statcont->getxattr(statcont, file->fname, name, value, size); } @@ -386,6 +394,10 @@ int smbc_fremovexattr(int fd, const char *name) { SMBCFILE * file = find_fd(fd); + if (file == NULL) { + errno = EBADF; + return -1; + } return statcont->removexattr(statcont, file->fname, name); } @@ -408,6 +420,10 @@ int smbc_flistxattr(int fd, size_t size) { SMBCFILE * file = find_fd(fd); + if (file == NULL) { + errno = EBADF; + return -1; + } return statcont->listxattr(statcont, file->fname, list, size); } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 4ea0ab6eb6..98264dfa86 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3932,7 +3932,9 @@ add_ace(SEC_ACL **the_acl, return True; } - aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces); + if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { + return False; + } memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); newacl = make_sec_acl(ctx, (*the_acl)->revision, -- cgit From 3d672717e084f7a26ef60321d614a686dd803dbd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 19 Jun 2006 20:00:51 +0000 Subject: r16363: Fix Klocwork ID 981 1652 Volker (This used to be commit ce1d8423ef7cd86fc64200002fde707bca621d44) --- source3/libsmb/trusts_util.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 9d94c1d00a..55108bf72f 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -86,7 +86,11 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m /* Create a random machine account password */ str = generate_random_str(DEFAULT_TRUST_ACCOUNT_PASSWORD_LENGTH); - new_trust_passwd = talloc_strdup(mem_ctx, str); + + if ((new_trust_passwd = talloc_strdup(mem_ctx, str)) == NULL) { + DEBUG(0, ("talloc_strdup failed\n")); + return NT_STATUS_NO_MEMORY; + } E_md4hash(new_trust_passwd, new_trust_passwd_hash); -- cgit From 54ea3c23e3bfd25008198e85fdcc1f48b0325eab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Jun 2006 02:31:12 +0000 Subject: r16435: Add in the uid info that Jerry needs into the share_mode struct. Allows us to know the unix uid of the opener of the file/directory. Needed for info level queries on open files. Jeremy. (This used to be commit d929323d6f513902381369d77bcd7b714346d713) --- source3/libsmb/smb_share_modes.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 090571b810..34ede9df29 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -149,6 +149,7 @@ static void create_share_mode_entry(struct share_mode_entry *out, out->access_mask = in->access_mask; out->dev = (SMB_DEV_T)in->dev; out->inode = (SMB_INO_T)in->ino; + out->uid = (uint32)geteuid(); } /* -- cgit From 20286e5c036fab3621b81cd72a40c9640a60fc20 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 22 Jun 2006 08:52:01 +0000 Subject: r16458: Increase debuglevel of cli_rpc_pipe_close(). Guenther (This used to be commit 840ac23ec007df445892d851144d6458c4e06a6b) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index f5116234c8..8342df0f1d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -367,7 +367,7 @@ BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) ret = cli_close(cli->cli, cli->fnum); if (!ret) { - DEBUG(0,("cli_rpc_pipe_close: cli_close failed on pipe %s, " + DEBUG(1,("cli_rpc_pipe_close: cli_close failed on pipe %s, " "fnum 0x%x " "to machine %s. Error was %s\n", cli->pipe_name, -- cgit From fe28eb2e411f3fd6b1b0d46ee0e5344592d7e49c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Jun 2006 00:15:00 +0000 Subject: r16541: Fix #3862 reported by jason@ncac.gwu.edu. Jeremy. (This used to be commit 09e11dcb2304eec9656e76c24921c82f4a870914) --- source3/libsmb/clilist.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 9ab05d2b4a..e18bb185d5 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -185,7 +185,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, BOOL First = True; int ff_searchcount=0; int ff_eos=0; - int ff_lastname=0; int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; @@ -297,11 +296,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, ff_dir_handle = SVAL(p,0); ff_searchcount = SVAL(p,2); ff_eos = SVAL(p,4); - ff_lastname = SVAL(p,8); } else { ff_searchcount = SVAL(p,0); ff_eos = SVAL(p,2); - ff_lastname = SVAL(p,6); } if (ff_searchcount == 0) { -- cgit From 9718506d35ca14c5233b613c647609bf2589f38b Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 27 Jun 2006 02:30:58 +0000 Subject: r16550: Fix bug 3866. Thanks for the report! Although I've never met a computer or compiler that produced pointers to functions which are a different size than pointers to data, I suppose they probably exist. Assigning a pointer to a function is technically illegal in C anyway. Change casts of the option_value based on the option_name to use of variable argument lists. For binary compatibility, I've maintained but deprecated the old behavior of debug_stderr (which expected to be passed a NULL or non-NULL pointer) and added a new option debug_to_stderr which properly expects a boolean (int) parameter. Derrell (This used to be commit c1b4c510530ca3118d1eccb9615a8cad732c7373) --- source3/libsmb/libsmbclient.c | 47 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 98264dfa86..7f41103e4f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -236,7 +236,7 @@ smbc_urlencode(char * dest, char * src, int max_dest_len) * * * We accept: - * smb://[[[domain;]user[:password@]]server[/share[/path[/file]]]][?options] + * smb://[[[domain;]user[:password]@]server[/share[/path[/file]]]][?options] * * Meaning of URLs: * @@ -6003,27 +6003,62 @@ smbc_free_context(SMBCCTX *context, void smbc_option_set(SMBCCTX *context, char *option_name, - void *option_value) + ... /* option_value */) { - if (strcmp(option_name, "debug_stderr") == 0) { + va_list ap; + union { + BOOL b; + smbc_get_auth_data_with_context_fn auth_fn; + void *v; + } option_value; + + va_start(ap, option_name); + + if (strcmp(option_name, "debug_to_stderr") == 0) { /* * Log to standard error instead of standard output. */ + option_value.b = (BOOL) va_arg(ap, int); + context->internal->_debug_stderr = option_value.b; + + } else if (strcmp(option_name, "debug_to_stderr") == 0) { + /* + * Log to standard error instead of standard output. + * + * This function used to take a third parameter, + * void *option_value. Since it was a void* and we needed to + * pass a boolean, a boolean value was cast to void* to be + * passed in. Now that we're using a va_list to retrieve the + * parameters, the casting kludge is unnecessary. + * + * WARNING: DO NOT USE THIS OPTION. + * This option is retained for backward compatibility. New + * applications should use "debug_to_stderr" and properly pass + * in a boolean (int) value. + */ + option_value.v = va_arg(ap, void *); context->internal->_debug_stderr = - (option_value == NULL ? False : True); + (option_value.v == NULL ? False : True); + } else if (strcmp(option_name, "auth_function") == 0) { /* * Use the new-style authentication function which includes * the context. */ - context->internal->_auth_fn_with_context = option_value; + option_value.auth_fn = + va_arg(ap, smbc_get_auth_data_with_context_fn); + context->internal->_auth_fn_with_context = + option_value.auth_fn; } else if (strcmp(option_name, "user_data") == 0) { /* * Save a user data handle which may be retrieved by the user * with smbc_option_get() */ - context->internal->_user_data = option_value; + option_value.v = va_arg(ap, void *); + context->internal->_user_data = option_value.v; } + + va_end(ap); } -- cgit From 9220a7bb7ba0468113deae3c033504ab4ff31eb2 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 27 Jun 2006 03:07:02 +0000 Subject: r16552: Fix bug 3849. Added a next_token_no_ltrim() function which does not strip leading separator characters. The new function is used only where really necessary, even though it could reasonably be used in many more places, to avoid superfluous code changes. Derrell (This used to be commit d90061aa933f7d8c81973918657dd72cbc88bab5) --- source3/libsmb/libsmbclient.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 7f41103e4f..240be50879 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -359,19 +359,19 @@ smbc_parse_path(SMBCCTX *context, pstring username, passwd, domain; const char *u = userinfo; - next_token(&p, userinfo, "@", sizeof(fstring)); + next_token_no_ltrim(&p, userinfo, "@", sizeof(fstring)); username[0] = passwd[0] = domain[0] = 0; if (strchr_m(u, ';')) { - next_token(&u, domain, ";", sizeof(fstring)); + next_token_no_ltrim(&u, domain, ";", sizeof(fstring)); } if (strchr_m(u, ':')) { - next_token(&u, username, ":", sizeof(fstring)); + next_token_no_ltrim(&u, username, ":", sizeof(fstring)); pstrcpy(passwd, u); -- cgit From d1014c1cdfce116741ddd6eccd65b69530ce0b84 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 00:50:14 +0000 Subject: r16582: Fix Klocwork #1997 and all generic class of problems where we don't correctly check the return from memdup. Jeremy. (This used to be commit ce14daf51c7ee2f9c68c77f7f4674e6f0e35c9ca) --- source3/libsmb/clirap.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 58fa9c8dff..26f22f2131 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -848,6 +848,12 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd } *poutdata = memdup(rdata, data_len); + if (!*poutdata) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return False; + } + *poutlen = data_len; SAFE_FREE(rdata); -- cgit From 95a81a33513517c25476286453c89ab1884e9919 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 04:27:43 +0000 Subject: r16606: Klocwork #1990. Malloc the correct size. Jeremy. (This used to be commit d1a1c4e092877a6ea0f98eed2a37a96d42c36323) --- source3/libsmb/clirap2.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index a327bae317..147683689d 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -211,11 +211,20 @@ int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) +WORDSIZE /* info level */ +WORDSIZE]; /* reserved word */ - char data[1024]; - /* offset into data of free format strings. Will be updated */ /* by PUTSTRINGP macro and end up with total data length. */ int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE; + char *data; + size_t data_size; + + /* Allocate data. */ + data_size = MAX(soffset + strlen(grinfo->comment) + 1, 1024); + + data = SMB_MALLOC(data_size); + if (!data) { + DEBUG (1, ("Malloc fail\n")); + return -1; + } /* now send a SMBtrans command with api WGroupAdd */ @@ -253,6 +262,7 @@ int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) DEBUG(4,("NetGroupAdd failed\n")); } + SAFE_FREE(data); SAFE_FREE(rparam); SAFE_FREE(rdata); -- cgit From 9e13d35092a9b2caee3448bd9f11c1b82dd9d6d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 17:58:47 +0000 Subject: r16630: Fix bug #3881, reported by jason@ncac.gwu.edu. Jeremy. (This used to be commit ec0a47b94c12b64d351ca8e6bdd467578528f3da) --- source3/libsmb/smb_signing.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 4ff74ca464..d68f161e23 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -612,7 +612,6 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO uint32 saved_seq; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; - uint mid; if (!si->doing_signing) return True; @@ -622,8 +621,6 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO return False; } - mid = SVAL(inbuf, smb_mid); - /* We always increment the sequence number. */ data->send_seq_num += 2; -- cgit From 2b8abc030b1eca43f7c0c05dc96eebeb6c492030 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Jun 2006 21:30:21 +0000 Subject: r16644: Fix bug #3887 reported by jason@ncac.gwu.edu by converting the lookup_XX functions to correctly return SID_NAME_TYPE enums. Jeremy. (This used to be commit ee2b2d96b60c668e37592c79e86c2fd851e15f69) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 240be50879..ca2624305e 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3727,7 +3727,7 @@ convert_sid_to_string(struct cli_state *ipc_cli, { char **domains = NULL; char **names = NULL; - uint32 *types = NULL; + enum SID_NAME_USE *types = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); sid_to_string(str, sid); @@ -3763,7 +3763,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, DOM_SID *sid, const char *str) { - uint32 *types = NULL; + enum SID_NAME_USE *types = NULL; DOM_SID *sids = NULL; BOOL result = True; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); -- cgit From d0b0ed90ebc0ed5d4b8c07c8362753df34a00ef9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Jun 2006 21:30:58 +0000 Subject: r16696: Fix the multiple-outstanding write and trans client signing bug. Jeremy. (This used to be commit 3b7fbe856cea7cbb5bf91844f94f221be0a2c627) --- source3/libsmb/smb_signing.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d68f161e23..68c259ba03 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -332,7 +332,22 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) /* cli->outbuf[smb_ss_field+2]=0; Uncomment this to test if the remote server actually verifies signatures...*/ - data->send_seq_num += 2; + /* Instead of re-introducing the trans_info_conect we + used to have here, we use the fact that during a + SMBtrans/SMBtrans2/SMBnttrans send that the mid stays + constant. This means that calling store_sequence_for_reply() + will return False for all trans secondaries, as the mid is already + on the stored sequence list. As the send_seqence_number must + remain constant for all primary+secondary trans sends, we + only increment the send sequence number when we successfully + add a new entry to the outstanding sequence list. This means + I can isolate the fix here rather than re-adding the trans + signing on/off calls in libsmb/clitrans2.c JRA. + */ + + if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) { + data->send_seq_num += 2; + } } /*********************************************************** @@ -356,7 +371,12 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, return False; } - reply_seq_number = data->send_seq_num - 1; + if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { + DEBUG(1, ("client_check_incoming_message: received message " + "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) )); + return False; + } + simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/libsmb/cliconnect.c | 39 ++++---- source3/libsmb/clidfs.c | 5 +- source3/libsmb/clientgen.c | 40 ++------ source3/libsmb/clikrb5.c | 2 +- source3/libsmb/clirap2.c | 2 +- source3/libsmb/libsmb_cache.c | 8 +- source3/libsmb/libsmbclient.c | 224 +++++++++++++++++++++--------------------- source3/libsmb/passchange.c | 108 ++++++++++---------- source3/libsmb/trusts_util.c | 2 +- 9 files changed, 210 insertions(+), 220 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7f5b5d7fa5..4c3c4f4565 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1394,8 +1394,9 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, if (!my_name) my_name = global_myname(); - if (!(cli = cli_initialise(NULL))) + if (!(cli = cli_initialise())) { return NT_STATUS_NO_MEMORY; + } make_nmb_name(&calling, my_name, 0x0); make_nmb_name(&called , dest_host, 0x20); @@ -1495,6 +1496,8 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, struct cli_state *cli = NULL; int pw_len = password ? strlen(password)+1 : 0; + *output_cli = NULL; + if (password == NULL) { password = ""; } @@ -1513,8 +1516,9 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, nt_status = cli_nt_error(cli); DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) + if (NT_STATUS_IS_OK(nt_status)) { nt_status = NT_STATUS_UNSUCCESSFUL; + } return nt_status; } } @@ -1541,7 +1545,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. ****************************************************************************/ -BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, const char *desthost, +BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost, struct in_addr *pdest_ip) { struct nmb_name calling, called; @@ -1553,12 +1557,13 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, * then use *SMBSERVER immediately. */ - if(is_ipaddress(desthost)) + if(is_ipaddress(desthost)) { make_nmb_name(&called, "*SMBSERVER", 0x20); - else + } else { make_nmb_name(&called, desthost, 0x20); + } - if (!cli_session_request(cli, &calling, &called)) { + if (!cli_session_request(*ppcli, &calling, &called)) { struct nmb_name smbservername; make_nmb_name(&smbservername , "*SMBSERVER", 0x20); @@ -1575,23 +1580,23 @@ BOOL attempt_netbios_session_request(struct cli_state *cli, const char *srchost, */ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER \ -with error %s.\n", desthost, cli_errstr(cli) )); +with error %s.\n", desthost, cli_errstr(*ppcli) )); return False; } - /* - * We need to close the connection here but can't call cli_shutdown as - * will free an allocated cli struct. cli_close_connection was invented - * for this purpose. JRA. Based on work by "Kim R. Pedersen" . - */ + /* Try again... */ + cli_shutdown(*ppcli); - cli_close_connection(cli); + *ppcli = cli_initialise(); + if (!*ppcli) { + /* Out of memory... */ + return False; + } - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, pdest_ip) || - !cli_session_request(cli, &calling, &smbservername)) { + if (!cli_connect(*ppcli, desthost, pdest_ip) || + !cli_session_request(*ppcli, &calling, &smbservername)) { DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ -name *SMBSERVER with error %s\n", desthost, cli_errstr(cli) )); +name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) )); return False; } } diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e564bc4295..4280b0628e 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -51,7 +51,7 @@ static struct client_connection *connections; static struct cli_state *do_connect( const char *server, const char *share, BOOL show_sessetup ) { - struct cli_state *c; + struct cli_state *c = NULL; struct nmb_name called, calling; const char *server_n; struct in_addr ip; @@ -83,7 +83,7 @@ static struct cli_state *do_connect( const char *server, const char *share, ip = dest_ip; /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) || + if (!(c=cli_initialise()) || (cli_set_port(c, port) != port) || !cli_connect(c, server_n, &ip)) { d_printf("Connection to %s failed\n", server_n); return NULL; @@ -99,6 +99,7 @@ static struct cli_state *do_connect( const char *server, const char *share, d_printf("session request to %s failed (%s)\n", called.name, cli_errstr(c)); cli_shutdown(c); + c = NULL; if ((p=strchr_m(called.name, '.'))) { *p = 0; goto again; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8342df0f1d..4608d40d46 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -255,12 +255,12 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) } /**************************************************************************** - Initialise a client structure. + Initialise a client structure. Always returns a malloc'ed struct. ****************************************************************************/ -struct cli_state *cli_initialise(struct cli_state *cli) +struct cli_state *cli_initialise(void) { - BOOL alloced_cli = False; + struct cli_state *cli = NULL; /* Check the effective uid - make sure we are not setuid */ if (is_setuid_root()) { @@ -268,17 +268,11 @@ struct cli_state *cli_initialise(struct cli_state *cli) return NULL; } + cli = SMB_MALLOC_P(struct cli_state); if (!cli) { - cli = SMB_MALLOC_P(struct cli_state); - if (!cli) - return NULL; - ZERO_STRUCTP(cli); - alloced_cli = True; + return NULL; } - if (cli->initialised) - cli_close_connection(cli); - ZERO_STRUCTP(cli); cli->port = 0; @@ -333,7 +327,6 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli_null_set_signing(cli); cli->initialised = 1; - cli->allocated = alloced_cli; return cli; @@ -343,10 +336,7 @@ struct cli_state *cli_initialise(struct cli_state *cli) SAFE_FREE(cli->inbuf); SAFE_FREE(cli->outbuf); - - if (alloced_cli) - SAFE_FREE(cli); - + SAFE_FREE(cli); return NULL; } @@ -403,10 +393,10 @@ void cli_nt_pipes_close(struct cli_state *cli) } /**************************************************************************** - Close a client connection and free the memory without destroying cli itself. + Shutdown a client structure. ****************************************************************************/ -void cli_close_connection(struct cli_state *cli) +void cli_shutdown(struct cli_state *cli) { cli_nt_pipes_close(cli); @@ -443,20 +433,8 @@ void cli_close_connection(struct cli_state *cli) } cli->fd = -1; cli->smb_rw_error = 0; -} -/**************************************************************************** - Shutdown a client structure. -****************************************************************************/ - -void cli_shutdown(struct cli_state *cli) -{ - BOOL allocated = cli->allocated; - cli_close_connection(cli); - ZERO_STRUCTP(cli); - if (allocated) { - free(cli); - } + SAFE_FREE(cli); } /**************************************************************************** diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index abb3843bac..d40fc31dc4 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -112,7 +112,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, #ifndef HAVE_KRB5_SET_REAL_TIME /* - * This function is not in the Heimdal mainline. + * Thir function is not in the Heimdal mainline. */ krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) { diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 147683689d..3c23310f66 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -220,7 +220,7 @@ int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) /* Allocate data. */ data_size = MAX(soffset + strlen(grinfo->comment) + 1, 1024); - data = SMB_MALLOC(data_size); + data = SMB_MALLOC_ARRAY(char, data_size); if (!data) { DEBUG (1, ("Malloc fail\n")); return -1; diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 5d948ea5e2..8c4fd7c89f 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -150,9 +150,10 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, * doesn't match the requested share, so * disconnect from the current share. */ - if (! cli_tdis(&srv->server->cli)) { + if (! cli_tdis(srv->server->cli)) { /* Sigh. Couldn't disconnect. */ - cli_shutdown(&srv->server->cli); + cli_shutdown(srv->server->cli); + srv->server->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv->server); continue; } @@ -166,7 +167,8 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, srv->share_name = SMB_STRDUP(share); if (!srv->share_name) { /* Out of memory. */ - cli_shutdown(&srv->server->cli); + cli_shutdown(srv->server->cli); + srv->server->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv->server); continue; } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ca2624305e..db788f46e9 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -487,7 +487,7 @@ static int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - if ( send_keepalive(server->cli.fd) == False ) + if ( send_keepalive(server->cli->fd) == False ) return 1; /* connection is ok */ @@ -524,7 +524,8 @@ smbc_remove_unused_server(SMBCCTX * context, DLIST_REMOVE(context->internal->_servers, srv); - cli_shutdown(&srv->cli); + cli_shutdown(srv->cli); + srv->cli = NULL; DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); @@ -630,7 +631,7 @@ smbc_server(SMBCCTX *context, fstring password) { SMBCSRV *srv=NULL; - struct cli_state c; + struct cli_state *c; struct nmb_name called, calling; const char *server_n = server; pstring ipenv; @@ -666,7 +667,7 @@ smbc_server(SMBCCTX *context, * disconnect if the requested share is not the same as the * one that was already connected. */ - if (srv->cli.cnum == (uint16) -1) { + if (srv->cli->cnum == (uint16) -1) { /* Ensure we have accurate auth info */ if (context->internal->_auth_fn_with_context != NULL) { context->internal->_auth_fn_with_context( @@ -683,11 +684,12 @@ smbc_server(SMBCCTX *context, password, sizeof(fstring)); } - if (! cli_send_tconX(&srv->cli, share, "?????", + if (! cli_send_tconX(srv->cli, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(context, &srv->cli); - cli_shutdown(&srv->cli); + errno = smbc_errno(context, srv->cli); + cli_shutdown(srv->cli); + srv->cli = NULL; context->callbacks.remove_cached_srv_fn(context, srv); srv = NULL; @@ -730,19 +732,19 @@ smbc_server(SMBCCTX *context, zero_ip(&ip); /* have to open a new connection */ - if (!cli_initialise(&c)) { + if ((c = cli_initialise()) == NULL) { errno = ENOMEM; return NULL; } if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { - c.use_kerberos = True; + c->use_kerberos = True; } if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { - c.fallback_after_kerberos = True; + c->fallback_after_kerberos = True; } - c.timeout = context->timeout; + c->timeout = context->timeout; /* * Force use of port 139 for first try if share is $IPC, empty, or @@ -756,49 +758,47 @@ smbc_server(SMBCCTX *context, port_try_next = 139; } - c.port = port_try_first; + c->port = port_try_first; - if (!cli_connect(&c, server_n, &ip)) { + if (!cli_connect(c, server_n, &ip)) { /* First connection attempt failed. Try alternate port. */ - c.port = port_try_next; + c->port = port_try_next; - if (!cli_connect(&c, server_n, &ip)) { - cli_shutdown(&c); + if (!cli_connect(c, server_n, &ip)) { + cli_shutdown(c); errno = ETIMEDOUT; return NULL; } } - if (!cli_session_request(&c, &calling, &called)) { - cli_shutdown(&c); + if (!cli_session_request(c, &calling, &called)) { + cli_shutdown(c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; - } - else { /* Try one more time, but ensure we don't loop */ - - /* Only try this if server is an IP address ... */ - - if (is_ipaddress(server) && !tried_reverse) { - fstring remote_name; - struct in_addr rem_ip; + } else { /* Try one more time, but ensure we don't loop */ - if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { - DEBUG(4, ("Could not convert IP address %s to struct in_addr\n", server)); - errno = ETIMEDOUT; - return NULL; - } + /* Only try this if server is an IP address ... */ - tried_reverse++; /* Yuck */ + if (is_ipaddress(server) && !tried_reverse) { + fstring remote_name; + struct in_addr rem_ip; - if (name_status_find("*", 0, 0, rem_ip, remote_name)) { - make_nmb_name(&called, remote_name, 0x20); - goto again; - } + if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { + DEBUG(4, ("Could not convert IP address " + "%s to struct in_addr\n", server)); + errno = ETIMEDOUT; + return NULL; + } + tried_reverse++; /* Yuck */ - } + if (name_status_find("*", 0, 0, rem_ip, remote_name)) { + make_nmb_name(&called, remote_name, 0x20); + goto again; + } + } } errno = ETIMEDOUT; return NULL; @@ -806,15 +806,15 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" session request ok\n")); - if (!cli_negprot(&c)) { - cli_shutdown(&c); + if (!cli_negprot(c)) { + cli_shutdown(c); errno = ETIMEDOUT; return NULL; } username_used = username; - if (!cli_session_setup(&c, username_used, + if (!cli_session_setup(c, username_used, password, strlen(password), password, strlen(password), workgroup)) { @@ -823,12 +823,12 @@ smbc_server(SMBCCTX *context, username_used = ""; if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || - !cli_session_setup(&c, username_used, + !cli_session_setup(c, username_used, password, 1, password, 0, workgroup)) { - cli_shutdown(&c); + cli_shutdown(c); errno = EPERM; return NULL; } @@ -836,10 +836,10 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" session setup ok\n")); - if (!cli_send_tconX(&c, share, "?????", + if (!cli_send_tconX(c, share, "?????", password, strlen(password)+1)) { - errno = smbc_errno(context, &c); - cli_shutdown(&c); + errno = smbc_errno(context, c); + cli_shutdown(c); return NULL; } @@ -858,7 +858,6 @@ smbc_server(SMBCCTX *context, ZERO_STRUCTP(srv); srv->cli = c; - srv->cli.allocated = False; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->no_pathinfo = False; srv->no_pathinfo2 = False; @@ -884,8 +883,10 @@ smbc_server(SMBCCTX *context, return srv; failed: - cli_shutdown(&c); - if (!srv) return NULL; + cli_shutdown(c); + if (!srv) { + return NULL; + } SAFE_FREE(srv); return NULL; @@ -960,19 +961,16 @@ smbc_attr_server(SMBCCTX *context, } ZERO_STRUCTP(ipc_srv); - ipc_srv->cli = *ipc_cli; - ipc_srv->cli.allocated = False; - - free(ipc_cli); + ipc_srv->cli = ipc_cli; if (pol) { - pipe_hnd = cli_rpc_pipe_open_noauth(&ipc_srv->cli, + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, PI_LSARPC, &nt_status); if (!pipe_hnd) { DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; - cli_shutdown(&ipc_srv->cli); + cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } @@ -985,14 +983,14 @@ smbc_attr_server(SMBCCTX *context, nt_status = rpccli_lsa_open_policy( pipe_hnd, - ipc_srv->cli.mem_ctx, + ipc_srv->cli->mem_ctx, True, GENERIC_EXECUTE_ACCESS, pol); if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, &ipc_srv->cli); - cli_shutdown(&ipc_srv->cli); + errno = smbc_errno(context, ipc_srv->cli); + cli_shutdown(ipc_srv->cli); return NULL; } } @@ -1009,7 +1007,7 @@ smbc_attr_server(SMBCCTX *context, if (errno == 0) { errno = ENOMEM; } - cli_shutdown(&ipc_srv->cli); + cli_shutdown(ipc_srv->cli); free(ipc_srv); return NULL; } @@ -1098,7 +1096,7 @@ smbc_open_ctx(SMBCCTX *context, ZERO_STRUCTP(file); /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); @@ -1172,7 +1170,7 @@ smbc_open_ctx(SMBCCTX *context, if (fd == -1) { int eno = 0; - eno = smbc_errno(context, &srv->cli); + eno = smbc_errno(context, srv->cli); file = context->opendir(context, fname); if (!file) errno = eno; return file; @@ -1275,7 +1273,7 @@ smbc_read_ctx(SMBCCTX *context, } /*d_printf(">>>read: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1358,7 +1356,7 @@ smbc_write_ctx(SMBCCTX *context, } /*d_printf(">>>write: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1430,7 +1428,7 @@ smbc_close_ctx(SMBCCTX *context, } /*d_printf(">>>close: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -1500,7 +1498,7 @@ smbc_getatr(SMBCCTX * context, } DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - if (!cli_resolve_path( "", &srv->cli, fixedpath, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, fixedpath, &targetcli, targetpath)) { d_printf("Couldn't resolve %s\n", path); return False; @@ -1565,7 +1563,7 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * attributes manipulated. */ if (srv->no_pathinfo || - ! cli_setpathinfo(&srv->cli, path, c_time, a_time, m_time, mode)) { + ! cli_setpathinfo(srv->cli, path, c_time, a_time, m_time, mode)) { /* * setpathinfo is not supported; go to plan B. @@ -1581,9 +1579,9 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, srv->no_pathinfo = True; /* Open the file */ - if ((fd = cli_open(&srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } @@ -1592,7 +1590,7 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * We'll need it in the set call */ if (c_time == 0) { - ret = cli_getattrE(&srv->cli, fd, + ret = cli_getattrE(srv->cli, fd, NULL, NULL, &c_time, NULL, NULL); } else { @@ -1619,9 +1617,9 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, if (c_time > m_time) c_time = m_time; /* Set the new attributes */ - ret = cli_setattrE(&srv->cli, fd, + ret = cli_setattrE(srv->cli, fd, c_time, a_time, m_time); - cli_close(&srv->cli, fd); + cli_close(srv->cli, fd); } /* @@ -1631,11 +1629,11 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * seems to work on win98. */ if (ret && mode != (uint16) -1) { - ret = cli_setatr(&srv->cli, path, mode, 0); + ret = cli_setatr(srv->cli, path, mode, 0); } if (! ret) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return False; } } @@ -1695,7 +1693,7 @@ smbc_unlink_ctx(SMBCCTX *context, } /*d_printf(">>>unlink: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -1828,14 +1826,14 @@ smbc_rename_ctx(SMBCCTX *ocontext, } /*d_printf(">>>rename: resolving %s\n", path1);*/ - if (!cli_resolve_path( "", &srv->cli, path1, &targetcli1, targetpath1)) + if (!cli_resolve_path( "", srv->cli, path1, &targetcli1, targetpath1)) { d_printf("Could not resolve %s\n", path1); return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ /*d_printf(">>>rename: resolving %s\n", path2);*/ - if (!cli_resolve_path( "", &srv->cli, path2, &targetcli2, targetpath2)) + if (!cli_resolve_path( "", srv->cli, path2, &targetcli2, targetpath2)) { d_printf("Could not resolve %s\n", path2); return -1; @@ -1930,7 +1928,7 @@ smbc_lseek_ctx(SMBCCTX *context, } /*d_printf(">>>lseek: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -2099,7 +2097,7 @@ smbc_stat_ctx(SMBCCTX *context, if (!smbc_getatr(context, srv, path, &mode, &size, &c_time, &a_time, &m_time, &ino)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } @@ -2175,7 +2173,7 @@ smbc_fstat_ctx(SMBCCTX *context, } /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path("", &file->srv->cli, path, + if (!cli_resolve_path("", file->srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -2676,7 +2674,7 @@ smbc_opendir_ctx(SMBCCTX *context, /* Now, list the stuff ... */ - if (!cli_NetServerEnum(&srv->cli, + if (!cli_NetServerEnum(srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, list_unique_wg_fn, @@ -2772,7 +2770,7 @@ smbc_opendir_ctx(SMBCCTX *context, dir->srv = srv; /* Now, list the servers ... */ - if (!cli_NetServerEnum(&srv->cli, server, + if (!cli_NetServerEnum(srv->cli, server, 0x0000FFFE, list_fn, (void *)dir)) { @@ -2808,15 +2806,15 @@ smbc_opendir_ctx(SMBCCTX *context, /* List the shares ... */ if (net_share_enum_rpc( - &srv->cli, + srv->cli, list_fn, (void *) dir) < 0 && cli_RNetShareEnum( - &srv->cli, + srv->cli, list_fn, (void *)dir) < 0) { - errno = cli_errno(&srv->cli); + errno = cli_errno(srv->cli); if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -2866,7 +2864,7 @@ smbc_opendir_ctx(SMBCCTX *context, p = path + strlen(path); pstrcat(path, "\\*"); - if (!cli_resolve_path("", &srv->cli, path, + if (!cli_resolve_path("", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); @@ -3215,7 +3213,7 @@ smbc_mkdir_ctx(SMBCCTX *context, } /*d_printf(">>>mkdir: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -3312,7 +3310,7 @@ smbc_rmdir_ctx(SMBCCTX *context, } /*d_printf(">>>rmdir: resolving %s\n", path);*/ - if (!cli_resolve_path( "", &srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); return -1; @@ -3568,8 +3566,8 @@ smbc_chmod_ctx(SMBCCTX *context, if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - if (!cli_setatr(&srv->cli, path, mode, 0)) { - errno = smbc_errno(context, &srv->cli); + if (!cli_setatr(srv->cli, path, mode, 0)) { + errno = smbc_errno(context, srv->cli); return -1; } @@ -4098,7 +4096,7 @@ dos_attr_query(SMBCCTX *context, &mode, &size, &c_time, &a_time, &m_time, &inode)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); return NULL; @@ -4206,7 +4204,7 @@ cacl_get(SMBCCTX *context, SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; - struct cli_state *cli = &srv->cli; + struct cli_state *cli = srv->cli; /* Copy name so we can strip off exclusions (if any are specified) */ strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); @@ -4551,7 +4549,7 @@ cacl_get(SMBCCTX *context, if (!smbc_getatr(context, srv, filename, &mode, &size, &c_time, &a_time, &m_time, &ino)) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } @@ -5108,8 +5106,8 @@ smbc_setxattr_ctx(SMBCCTX *context, } if (ipc_srv) { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, (*namevalue == '*' ? SMBC_XATTR_MODE_SET @@ -5171,8 +5169,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, (*namevalue == '*' ? SMBC_XATTR_MODE_SET @@ -5202,8 +5200,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } talloc_destroy(ctx); @@ -5229,8 +5227,8 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } talloc_destroy(ctx); @@ -5388,12 +5386,12 @@ smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, ctx, srv, - ipc_srv == NULL ? NULL : &ipc_srv->cli, + ipc_srv == NULL ? NULL : ipc_srv->cli, &pol, path, CONST_DISCARD(char *, name), CONST_DISCARD(char *, value), size); if (ret < 0 && errno == 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); } talloc_destroy(ctx); return ret; @@ -5484,8 +5482,8 @@ smbc_removexattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { /* Yup. */ - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); talloc_destroy(ctx); return ret; @@ -5504,8 +5502,8 @@ smbc_removexattr_ctx(SMBCCTX *context, StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { /* Yup. */ - ret = cacl_set(ctx, &srv->cli, - &ipc_srv->cli, &pol, path, + ret = cacl_set(ctx, srv->cli, + ipc_srv->cli, &pol, path, name + 19, SMBC_XATTR_MODE_REMOVE, 0); talloc_destroy(ctx); return ret; @@ -5755,10 +5753,10 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, } - if (cli_print_queue(&srv->cli, + if (cli_print_queue(srv->cli, (void (*)(struct print_job_info *))fn) < 0) { - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); return -1; } @@ -5825,10 +5823,10 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, } - if ((err = cli_printjob_del(&srv->cli, id)) != 0) { + if ((err = cli_printjob_del(srv->cli, id)) != 0) { if (err < 0) - errno = smbc_errno(context, &srv->cli); + errno = smbc_errno(context, srv->cli); else if (err == ERRnosuchprintjob) errno = EINVAL; return -1; @@ -5947,8 +5945,8 @@ smbc_free_context(SMBCCTX *context, s = context->internal->_servers; while (s) { DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", - s, s->cli.fd)); - cli_shutdown(&s->cli); + s, s->cli->fd)); + cli_shutdown(s->cli); context->callbacks.remove_cached_srv_fn(context, s); next = s->next; @@ -6074,9 +6072,9 @@ smbc_option_get(SMBCCTX *context, * Log to standard error instead of standard output. */ #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->_debug_stderr; + return (void *) (intptr_t) context->internal->_debug_stderr; #else - return (void *) context->internal->_debug_stderr; + return (void *) context->internal->_debug_stderr; #endif } else if (strcmp(option_name, "auth_function") == 0) { /* diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 673671d28d..0d3dcf4d75 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -29,7 +29,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam char *err_str, size_t err_str_len) { struct nmb_name calling, called; - struct cli_state cli; + struct cli_state *cli; struct rpc_pipe_client *pipe_hnd; struct in_addr ip; @@ -44,39 +44,45 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam return NT_STATUS_UNSUCCESSFUL; } - ZERO_STRUCT(cli); - - if (!cli_initialise(&cli) || !cli_connect(&cli, remote_machine, &ip)) { + cli = cli_initialise(); + if (!cli) { + return NT_STATUS_NO_MEMORY; + } + + if (!cli_connect(cli, remote_machine, &ip)) { slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - return NT_STATUS_UNSUCCESSFUL; + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); + return result; } make_nmb_name(&calling, global_myname() , 0x0); make_nmb_name(&called , remote_machine, 0x20); - if (!cli_session_request(&cli, &calling, &called)) { + if (!cli_session_request(cli, &calling, &called)) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - cli_shutdown(&cli); - return NT_STATUS_UNSUCCESSFUL; + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); + return result; } - cli.protocol = PROTOCOL_NT1; + cli->protocol = PROTOCOL_NT1; - if (!cli_negprot(&cli)) { + if (!cli_negprot(cli)) { slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } /* Given things like SMB signing, restrict anonymous and the like, try an authenticated connection first */ - if (!cli_session_setup(&cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { + if (!cli_session_setup(cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { - result = cli_nt_error(&cli); + result = cli_nt_error(cli); if (!NT_STATUS_IS_OK(result)) { @@ -89,8 +95,8 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam NT_STATUS_PASSWORD_MUST_CHANGE)) { slprintf(err_str, err_str_len-1, "Could not " "connect to machine %s: %s\n", - remote_machine, cli_errstr(&cli)); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli)); + cli_shutdown(cli); return result; } @@ -103,31 +109,31 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam * Thanks to for this fix. */ - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + if (!cli_session_setup(cli, "", "", 0, "", 0, "")) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } - cli_init_creds(&cli, "", "", NULL); + cli_init_creds(cli, "", "", NULL); } else { - cli_init_creds(&cli, user_name, "", old_passwd); + cli_init_creds(cli, user_name, "", old_passwd); } - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } /* Try not to give the password away too easily */ if (!pass_must_change) { - pipe_hnd = cli_rpc_pipe_open_ntlmssp(&cli, + pipe_hnd = cli_rpc_pipe_open_ntlmssp(cli, PI_SAMR, PIPE_AUTH_LEVEL_PRIVACY, "", /* what domain... ? */ @@ -143,17 +149,17 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam * will just fail. So we do it anonymously, there's no other * way. */ - pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result); + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); } if (!pipe_hnd) { if (lp_client_lanman_auth()) { /* Use the old RAP method. */ - if (!cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } } else { @@ -161,16 +167,16 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam "SAMR connection to machine %s failed. Error was %s, " "but LANMAN password changed are disabled\n", nt_errstr(result), remote_machine); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } } - if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli.mem_ctx, user_name, + if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli->mem_ctx, user_name, new_passwd, old_passwd))) { /* Great - it all worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) @@ -179,7 +185,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); - cli_shutdown(&cli); + cli_shutdown(cli); return result; } @@ -187,21 +193,21 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_rpc_pipe_close(pipe_hnd); /* Try anonymous NTLMSSP... */ - cli_init_creds(&cli, "", "", NULL); + cli_init_creds(cli, "", "", NULL); result = NT_STATUS_UNSUCCESSFUL; /* OK, this is ugly, but... try an anonymous pipe. */ - pipe_hnd = cli_rpc_pipe_open_noauth(&cli, PI_SAMR, &result); + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); if ( pipe_hnd && (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, - cli.mem_ctx, + cli->mem_ctx, user_name, new_passwd, old_passwd)))) { /* Great - it all worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } else { if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) @@ -211,7 +217,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam slprintf(err_str, err_str_len-1, "machine %s rejected the (anonymous) password change: Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); - cli_shutdown(&cli); + cli_shutdown(cli); return result; } @@ -220,24 +226,24 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (lp_client_lanman_auth()) { /* Use the old RAP method. */ - if (cli_oem_change_password(&cli, user_name, new_passwd, old_passwd)) { + if (cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { /* SAMR failed, but the old LanMan protocol worked! */ - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_OK; } slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", - remote_machine, cli_errstr(&cli) ); - result = cli_nt_error(&cli); - cli_shutdown(&cli); + remote_machine, cli_errstr(cli) ); + result = cli_nt_error(cli); + cli_shutdown(cli); return result; } else { slprintf(err_str, err_str_len-1, "SAMR connection to machine %s failed. Error was %s, " "but LANMAN password changed are disabled\n", nt_errstr(result), remote_machine); - cli_shutdown(&cli); + cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; } } diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 55108bf72f..e4061883eb 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -99,7 +99,7 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", - timestring(False))); + current_timestring(False))); /* * Return the result of trying to write the new password * back into the trust account file. -- cgit From 6dfccad5645ef0b459d5904ce48550f72acf8d37 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 11 Jul 2006 21:23:44 +0000 Subject: r16960: Some warnings from host "opi" (This used to be commit 083ef11cc9be8f1299f233bde194173e092e2c3c) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index d40fc31dc4..f0169eb91e 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -682,7 +682,7 @@ failed: else err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); if (err == 0 && skey != NULL) { - DEBUG(10, ("Got KRB5 session key of length %d\n", KRB5_KEY_LENGTH(skey))); + DEBUG(10, ("Got KRB5 session key of length %d\n", (int)KRB5_KEY_LENGTH(skey))); *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); -- cgit From 760671b0e2b5b169a6563783c3c10f3031bb7c9e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Jul 2006 00:21:14 +0000 Subject: r16962: Add a few utility fns into client. Allow POSIX capabilities to be selected. Jeremy. (This used to be commit 2d8d4bd77bac6f5e7865657e12affd8b94aa85c3) --- source3/libsmb/clifsinfo.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 2874ee6ca1..c6aa6a70a0 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -79,6 +79,59 @@ cleanup: return ret; } +/**************************************************************************** + Set UNIX extensions capabilities. +****************************************************************************/ + +BOOL cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, uint16 minor, + uint32 caplow, uint32 caphigh) +{ + BOOL ret = False; + uint16 setup; + char param[4]; + char data[12]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + + setup = TRANSACT2_SETFSINFO; + + SSVAL(param,0,0); + SSVAL(param,2,SMB_SET_CIFS_UNIX_INFO); + + SSVAL(data,0,major); + SSVAL(data,2,minor); + SIVAL(data,4,caplow); + SIVAL(data,8,caphigh); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 4, 0, + data, 12, 560)) { + goto cleanup; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + goto cleanup; + } + + if (cli_is_error(cli)) { + ret = False; + goto cleanup; + } else { + ret = True; + } + +cleanup: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return ret; +} + BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) { BOOL ret = False; -- cgit From 5fe140babcbec90ddcbd9a6517c3f5e76844a9e9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Jul 2006 10:55:24 +0000 Subject: r17060: Some c++ warnings (This used to be commit 2e7afa9e19b117d7a8ce1238c1b9b80ececec729) --- source3/libsmb/asn1.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 544ee78d40..dd22051ae7 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -31,7 +31,8 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { - data->data = SMB_REALLOC(data->data, data->ofs+len); + data->data = SMB_REALLOC_ARRAY(data->data, unsigned char, + data->ofs+len); if (!data->data) { data->has_error = True; return False; @@ -213,7 +214,7 @@ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) { ZERO_STRUCTP(data); - data->data = memdup(blob.data, blob.length); + data->data = (unsigned char *)memdup(blob.data, blob.length); if (!data->data) { data->has_error = True; return False; @@ -405,7 +406,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) data->has_error = True; return False; } - str = SMB_MALLOC(len+1); + str = SMB_MALLOC_ARRAY(char, len+1); if (!str) { data->has_error = True; return False; -- cgit From f2faf11204e3ef0bc6a92554761cb0f0ac2a1103 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 19 Jul 2006 00:13:01 +0000 Subject: r17124: fixed a bug which caused resolve_ads() to spin forever if one of the DCs isn't resolvable in DNS. The fix is to leave that DC out of the returned list of DCs. I think the original code intended that anyway, just didn't quite get it right ('i' wasn't incremented in that code path, so the loop didn't terminate) (This used to be commit d7ec9f3cc0439e9e0f4c98988b14ae2155d931b9) --- source3/libsmb/namequery.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0172ab9514..f6dbe3c548 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1051,16 +1051,18 @@ static BOOL resolve_ads(const char *name, int name_type, return False; } - i = 0; - while ( i < numdcs ) { + *return_count = 0; + + for (i=0;iip = *interpret_addr2(dcs[i].hostname); else - (*return_iplist)[i].ip = dcs[i].ip; + r->ip = dcs[i].ip; - (*return_iplist)[i].port = dcs[i].port; + r->port = dcs[i].port; /* make sure it is a valid IP. I considered checking the negative connection cache, but this is the wrong place for it. Maybe only @@ -1069,15 +1071,11 @@ static BOOL resolve_ads(const char *name, int name_type, The standard reason for falling back to netbios lookups is that our DNS server doesn't know anything about the DC's -- jerry */ - if ( is_zero_ip((*return_iplist)[i].ip) ) - continue; - - i++; + if ( ! is_zero_ip(r->ip) ) + (*return_count)++; } TALLOC_FREE( dcs ); - - *return_count = i; return True; } -- cgit From bd8556c8dd5664067d4113f30e20ab2e3a11fc3b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 20 Jul 2006 20:23:04 +0000 Subject: r17162: Fix typo small typos noticed by Paul Green. (This used to be commit 1a5874588686fb4ece9be70059ff75b975ed2bd5) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index f0169eb91e..fc9dd690b3 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -112,7 +112,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, #ifndef HAVE_KRB5_SET_REAL_TIME /* - * Thir function is not in the Heimdal mainline. + * This function is not in the Heimdal mainline. */ krb5_error_code krb5_set_real_time(krb5_context context, int32_t seconds, int32_t microseconds) { -- cgit From fe348fdb28624428269bffeb1ff796ec3857ff66 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Jul 2006 05:02:38 +0000 Subject: r17216: From Kai Blin : A patch to make ntlm_auth recognize three new commands in ntlmssp-client-1 and squid-2.5-ntlmssp: The commands are the following: Command: SF Reply: OK Description: Takes feature request flags similar to samba4's gensec_want_feature() call. So far, only NTLMSSP_FEATURE_SESSION_KEY, NTLMSSP_FEATURE_SIGN and NTLMSSP_FEATURE_SEAL are implemented, using the same values as the corresponding GENSEC_FEATURE_* flags in samba4. Command: GF Reply: GF Description: Returns the negotiated flags. Command: GK Reply: GK Description: Returns the negotiated session key. (These commands assist a wine project to use ntlm_auth for signing and sealing of bulk data). Andrew Bartlett (This used to be commit bd3e06a0e4435f1c48fa3b7862333efe273119ee) --- source3/libsmb/cliconnect.c | 1 + source3/libsmb/ntlmssp.c | 50 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4c3c4f4565..d547bb3854 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -599,6 +599,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) { return nt_status; } + ntlmssp_want_feature(ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, user))) { return nt_status; diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 986fa8cce9..a6fb3b426b 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -210,6 +210,50 @@ NTSTATUS ntlmssp_store_response(NTLMSSP_STATE *ntlmssp_state, return NT_STATUS_OK; } +/** + * Request features for the NTLMSSP negotiation + * + * @param ntlmssp_state NTLMSSP state + * @param feature_list List of space seperated features requested from NTLMSSP. + */ +void ntlmssp_want_feature_list(NTLMSSP_STATE *ntlmssp_state, char *feature_list) +{ + /* + * We need to set this to allow a later SetPassword + * via the SAMR pipe to succeed. Strange.... We could + * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. + */ + if (in_list("NTLMSSP_FEATURE_SESSION_KEY", feature_list, True)) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (in_list("NTLMSSP_FEATURE_SIGN", feature_list, True)) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if(in_list("NTLMSSP_FEATURE_SEAL", feature_list, True)) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } +} + +/** + * Request a feature for the NTLMSSP negotiation + * + * @param ntlmssp_state NTLMSSP state + * @param feature Bit flag specifying the requested feature + */ +void ntlmssp_want_feature(NTLMSSP_STATE *ntlmssp_state, uint32 feature) +{ + /* As per JRA's comment above */ + if (feature & NTLMSSP_FEATURE_SESSION_KEY) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (feature & NTLMSSP_FEATURE_SIGN) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN; + } + if (feature & NTLMSSP_FEATURE_SEAL) { + ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL; + } +} + /** * Next state function for the NTLMSSP state machine * @@ -1163,12 +1207,6 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | - /* - * We need to set this to allow a later SetPassword - * via the SAMR pipe to succeed. Strange.... We could - * also add NTLMSSP_NEGOTIATE_SEAL here. JRA. - * */ - NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_REQUEST_TARGET; return NT_STATUS_OK; -- cgit From 74cd692d9b34ef8344a36d3b01bd24fa9108d9b6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 25 Jul 2006 16:48:08 +0000 Subject: r17234: Fix error mappings for EQUOTA and ENOBUFS. Based on an idea from Shlomi Yaakobovich . Jeremy. (This used to be commit 9c440925f879d1e4ef99d04e2dfbe41077869204) --- source3/libsmb/errormap.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index b3caa0a80c..a5e922fd5c 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -779,7 +779,11 @@ static const struct { {ERRHRD, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, {ERRHRD, ERRwrongdisk, NT_STATUS_WRONG_VOLUME}, {ERRHRD, 38, NT_STATUS_END_OF_FILE}, +#if defined(WITH_QUOTAS) && defined(EDQUOT) + {ERRHRD, ERRdiskfull, NT_STATUS_QUOTA_EXCEEDED}, +#else {ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL}, +#endif {ERRHRD, 50, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, {ERRHRD, 51, NT_STATUS_REMOTE_NOT_LISTENING}, {ERRHRD, 52, NT_STATUS_DUPLICATE_NAME}, @@ -1522,7 +1526,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, { EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS }, #ifdef EDQUOT - { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, + { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_QUOTA_EXCEEDED }, #endif #ifdef ENOTEMPTY { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, @@ -1538,6 +1542,9 @@ const struct unix_error_map unix_dos_nt_errmap[] = { #endif #ifdef EFBIG { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, +#endif +#ifdef ENOBUFS + { ENOBUFS, ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES }, #endif { 0, 0, 0, NT_STATUS_OK } }; -- cgit From 8f93665bb5db57e3725487373e68a476a8e31d6d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Jul 2006 17:24:54 +0000 Subject: r17262: After messages from Metze and traces from Karolin Seeger, turns out that EDQUOTA must map to NT_STATUS_DISK_FULL for Windows apps to work correctly. My mistake. Jeremy. (This used to be commit de1e3f7a7ae9e8a41b45130e2cdfc22f43cf53b5) --- source3/libsmb/errormap.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index a5e922fd5c..cb5e8311ca 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -779,11 +779,7 @@ static const struct { {ERRHRD, ERRlock, NT_STATUS_FILE_LOCK_CONFLICT}, {ERRHRD, ERRwrongdisk, NT_STATUS_WRONG_VOLUME}, {ERRHRD, 38, NT_STATUS_END_OF_FILE}, -#if defined(WITH_QUOTAS) && defined(EDQUOT) - {ERRHRD, ERRdiskfull, NT_STATUS_QUOTA_EXCEEDED}, -#else {ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL}, -#endif {ERRHRD, 50, NT_STATUS_CTL_FILE_NOT_SUPPORTED}, {ERRHRD, 51, NT_STATUS_REMOTE_NOT_LISTENING}, {ERRHRD, 52, NT_STATUS_DUPLICATE_NAME}, @@ -1526,7 +1522,7 @@ const struct unix_error_map unix_dos_nt_errmap[] = { { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, { EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS }, #ifdef EDQUOT - { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_QUOTA_EXCEEDED }, + { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, /* Windows apps need this, not NT_STATUS_QUOTA_EXCEEDED */ #endif #ifdef ENOTEMPTY { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, -- cgit From 9d9c90f31a2e92ed6d6d9f247add7388a67a2a0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jul 2006 20:35:00 +0000 Subject: r17291: Fix memory leaks on early exit path. Jeremy. (This used to be commit deaac5bd463e5b8fd0b9915b553fdac3a4271293) --- source3/libsmb/clidfs.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 4280b0628e..0135881021 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -713,12 +713,14 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, res = cli_dfs_get_referral(cli, fullpath, &refs, &num_refs, &consumed); if (!cli_tdis(cli)) { + SAFE_FREE( refs ); return False; } cli->cnum = cnum; if (!res || !num_refs ) { + SAFE_FREE( refs ); return False; } @@ -726,8 +728,10 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, /* check that this is not a self-referral */ - if ( strequal( cli->desthost, newserver ) && strequal( sharename, newshare ) ) + if ( strequal( cli->desthost, newserver ) && strequal( sharename, newshare ) ) { + SAFE_FREE( refs ); return False; + } SAFE_FREE( refs ); -- cgit From 321b0a3a63b40f779c71d476fdc5a840d2ced665 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Jul 2006 21:23:53 +0000 Subject: r17292: Try and fix bug #3967 - signing problems on trans calls introduced by signing code simplification. Please test if you've seen signing problems with 3.0.23a. Jeremy. (This used to be commit f462daf02c12cfba634f92e681eb23a09e7d0acf) --- source3/libsmb/clitrans.c | 101 ++++++++++++++++++++++++++----------------- source3/libsmb/smb_signing.c | 69 +++++++++++++++++++++++++++-- 2 files changed, 127 insertions(+), 43 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 082da67bb8..4f9f21b848 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -95,9 +95,14 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, return False; } + /* Note we're in a trans state. Save the sequence + * numbers for replies. */ + client_set_trans_sign_state_on(cli, mid); + if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { + client_set_trans_sign_state_off(cli, mid); return(False); } @@ -139,6 +144,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { + client_set_trans_sign_state_off(cli, mid); return False; } @@ -150,9 +156,6 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, } } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - return(True); } @@ -168,6 +171,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, unsigned int total_param=0; unsigned int this_data,this_param; NTSTATUS status; + BOOL ret = False; *data_len = *param_len = 0; @@ -182,7 +186,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); - return(False); + return False; } /* @@ -194,7 +198,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, status = cli_nt_error(cli); if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) { - return False; + goto out; } /* parse out the lengths */ @@ -206,7 +210,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *data = SMB_REALLOC(*data,total_data); if (!(*data)) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); - return False; + goto out; } } @@ -214,7 +218,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *param = SMB_REALLOC(*param,total_param); if (!(*param)) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); - return False; + goto out; } } @@ -225,7 +229,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_trans\n")); - return False; + goto out; } if (this_data + *data_len < this_data || @@ -233,7 +237,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_trans\n")); - return False; + goto out; } if (this_data) { @@ -245,14 +249,14 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); - return False; + goto out; } if (data_offset_in > cli->bufsize || data_offset_in + this_data > cli->bufsize || data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_trans\n")); - return False; + goto out; } memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); @@ -266,14 +270,14 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); - return False; + goto out; } if (param_offset_in > cli->bufsize || param_offset_in + this_param > cli->bufsize || param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_trans\n")); - return False; + goto out; } memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); @@ -281,11 +285,13 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, *data_len += this_data; *param_len += this_param; - if (total_data <= *data_len && total_param <= *param_len) + if (total_data <= *data_len && total_param <= *param_len) { + ret = True; break; + } if (!cli_receive_smb(cli)) { - return False; + goto out; } show_msg(cli->inbuf); @@ -295,10 +301,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); - return(False); + goto out; } if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { - return(False); + goto out; } /* parse out the total lengths again - they can shrink! */ @@ -307,12 +313,16 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, if (SVAL(cli->inbuf,smb_tprcnt) < total_param) total_param = SVAL(cli->inbuf,smb_tprcnt); - if (total_data <= *data_len && total_param <= *param_len) + if (total_data <= *data_len && total_param <= *param_len) { + ret = True; break; - + } } - return(True); + out: + + client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); + return ret; } /**************************************************************************** @@ -379,9 +389,14 @@ BOOL cli_send_nt_trans(struct cli_state *cli, return False; } + /* Note we're in a trans state. Save the sequence + * numbers for replies. */ + client_set_trans_sign_state_on(cli, mid); + if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { + client_set_trans_sign_state_off(cli, mid); return(False); } @@ -423,6 +438,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { + client_set_trans_sign_state_off(cli, mid); return False; } @@ -434,9 +450,6 @@ BOOL cli_send_nt_trans(struct cli_state *cli, } } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - return(True); } @@ -453,6 +466,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, unsigned int this_data,this_param; uint8 eclass; uint32 ecode; + BOOL ret = False; *data_len = *param_len = 0; @@ -477,7 +491,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if (!(eclass == ERRDOS && ecode == ERRmoredata)) { - return(False); + goto out; } } @@ -487,7 +501,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (cli_is_nt_error(cli)) { if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_BUFFER_TOO_SMALL)) { - return(False); + goto out; } } @@ -500,7 +514,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, *data = SMB_REALLOC(*data,total_data); if (!(*data)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); - return False; + goto out; } } @@ -508,7 +522,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, *param = SMB_REALLOC(*param,total_param); if (!(*param)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); - return False; + goto out; } } @@ -519,7 +533,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (this_data + *data_len > total_data || this_param + *param_len > total_param) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); - return False; + goto out; } if (this_data + *data_len < this_data || @@ -527,7 +541,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, this_param + *param_len < this_param || this_param + *param_len < *param_len) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); - return False; + goto out; } if (this_data) { @@ -539,14 +553,14 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, data_offset_out + this_data < data_offset_out || data_offset_out + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); - return False; + goto out; } if (data_offset_in > cli->bufsize || data_offset_in + this_data > cli->bufsize || data_offset_in + this_data < data_offset_in || data_offset_in + this_data < this_data) { DEBUG(1,("Data overflow in cli_receive_nt_trans\n")); - return False; + goto out; } memcpy(*data + data_offset_out, smb_base(cli->inbuf) + data_offset_in, this_data); @@ -561,14 +575,14 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, param_offset_out + this_param < param_offset_out || param_offset_out + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); - return False; + goto out; } if (param_offset_in > cli->bufsize || param_offset_in + this_param > cli->bufsize || param_offset_in + this_param < param_offset_in || param_offset_in + this_param < this_param) { DEBUG(1,("Param overflow in cli_receive_nt_trans\n")); - return False; + goto out; } memcpy(*param + param_offset_out, smb_base(cli->inbuf) + param_offset_in, this_param); @@ -577,11 +591,13 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, *data_len += this_data; *param_len += this_param; - if (total_data <= *data_len && total_param <= *param_len) + if (total_data <= *data_len && total_param <= *param_len) { + ret = True; break; + } if (!cli_receive_smb(cli)) { - return False; + goto out; } show_msg(cli->inbuf); @@ -590,12 +606,12 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); - return(False); + goto out; } if (cli_is_dos_error(cli)) { cli_dos_error(cli, &eclass, &ecode); if(!(eclass == ERRDOS && ecode == ERRmoredata)) { - return(False); + goto out; } } /* @@ -604,7 +620,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (cli_is_nt_error(cli)) { if (!NT_STATUS_EQUAL(cli_nt_error(cli), NT_STATUS_BUFFER_TOO_SMALL)) { - return(False); + goto out; } } @@ -614,9 +630,14 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); - if (total_data <= *data_len && total_param <= *param_len) + if (total_data <= *data_len && total_param <= *param_len) { + ret = True; break; + } } - return(True); + out: + + client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); + return ret; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 68c259ba03..fd5d8bf06f 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -23,9 +23,10 @@ /* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ struct outstanding_packet_lookup { + struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; - struct outstanding_packet_lookup *prev, *next; + BOOL can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -51,6 +52,7 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, t->mid = mid; t->reply_seq_num = reply_seq_num; + t->can_delete = True; /* * Add to the *start* of the list not the end of the list. @@ -77,8 +79,23 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, *reply_seq_num = t->reply_seq_num; DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - DLIST_REMOVE(*list, t); - SAFE_FREE(t); + if (t->can_delete) { + DLIST_REMOVE(*list, t); + SAFE_FREE(t); + } + return True; + } + } + return False; +} + +static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, BOOL can_delete_entry) +{ + struct outstanding_packet_lookup *t; + + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + t->can_delete = can_delete_entry; return True; } } @@ -579,6 +596,52 @@ BOOL cli_check_sign_mac(struct cli_state *cli) return True; } +/*********************************************************** + Enter trans/trans2/nttrans state. +************************************************************/ + +BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) +{ + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { + return False; + } + + return True; +} + +/*********************************************************** + Leave trans/trans2/nttrans state. +************************************************************/ + +BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) +{ + uint32 reply_seq_num; + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { + return False; + } + + /* Now delete the stored mid entry. */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { + return False; + } + + return True; +} + /*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ -- cgit From 02eea79624c85fb5ce6c3ffefe2d27e40c5ff97f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Jul 2006 03:53:39 +0000 Subject: r17333: Some C++ warnings (This used to be commit be9aaffdaccae06c8c035eaf31862e34b7cfbe38) --- source3/libsmb/clifile.c | 4 ++-- source3/libsmb/clilist.c | 5 +++-- source3/libsmb/clirap.c | 2 +- source3/libsmb/clireadwrite.c | 4 ++-- source3/libsmb/clistr.c | 4 ++-- source3/libsmb/clitrans.c | 8 ++++---- source3/libsmb/libsmbclient.c | 8 ++++---- source3/libsmb/smb_signing.c | 15 ++++++++++----- 8 files changed, 28 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 46ff8af6d5..9beafc55fb 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1509,7 +1509,7 @@ static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigne if (ea_namelen == 0 && ea_len == 0) { data_len = 4; - data = SMB_MALLOC(data_len); + data = (char *)SMB_MALLOC(data_len); if (!data) { return False; } @@ -1517,7 +1517,7 @@ static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigne SIVAL(p,0,data_len); } else { data_len = 4 + 4 + ea_namelen + 1 + ea_len; - data = SMB_MALLOC(data_len); + data = (char *)SMB_MALLOC(data_len); if (!data) { return False; } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e18bb185d5..a006c47ae0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -335,7 +335,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* grab the data for later use */ /* and add them to the dirlist pool */ - dirlist = SMB_REALLOC(dirlist,dirlist_len + data_len); + dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len); if (!dirlist) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); @@ -461,7 +461,8 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, first = False; - dirlist = SMB_REALLOC(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + dirlist = (char *)SMB_REALLOC( + dirlist,(num_received + received)*DIR_STRUCT_SIZE); if (!dirlist) { DEBUG(0,("cli_list_old: failed to expand dirlist")); return 0; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 26f22f2131..a33baed536 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -847,7 +847,7 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd return False; } - *poutdata = memdup(rdata, data_len); + *poutdata = (char *)memdup(rdata, data_len); if (!*poutdata) { SAFE_FREE(rdata); SAFE_FREE(rparam); diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 883bc1260d..02fa804f41 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -265,11 +265,11 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, BOOL large_writex = False; if (size > cli->bufsize) { - cli->outbuf = SMB_REALLOC(cli->outbuf, size + 1024); + cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024); if (!cli->outbuf) { return False; } - cli->inbuf = SMB_REALLOC(cli->inbuf, size + 1024); + cli->inbuf = (char *)SMB_REALLOC(cli->inbuf, size + 1024); if (cli->inbuf == NULL) { SAFE_FREE(cli->outbuf); return False; diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index c61445c073..6191f99ea9 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -49,10 +49,10 @@ size_t clistr_pull_fn(const char *function, unsigned int line, size_t clistr_align_out(struct cli_state *cli, const void *p, int flags) { - return align_string(cli->outbuf, p, flags); + return align_string(cli->outbuf, (const char *)p, flags); } size_t clistr_align_in(struct cli_state *cli, const void *p, int flags) { - return align_string(cli->inbuf, p, flags); + return align_string(cli->inbuf, (const char *)p, flags); } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 4f9f21b848..27207e72e2 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -207,7 +207,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, /* allocate it */ if (total_data!=0) { - *data = SMB_REALLOC(*data,total_data); + *data = (char *)SMB_REALLOC(*data,total_data); if (!(*data)) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); goto out; @@ -215,7 +215,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, } if (total_param!=0) { - *param = SMB_REALLOC(*param,total_param); + *param = (char *)SMB_REALLOC(*param,total_param); if (!(*param)) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); goto out; @@ -511,7 +511,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, /* allocate it */ if (total_data) { - *data = SMB_REALLOC(*data,total_data); + *data = (char *)SMB_REALLOC(*data,total_data); if (!(*data)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); goto out; @@ -519,7 +519,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, } if (total_param) { - *param = SMB_REALLOC(*param,total_param); + *param = (char *)SMB_REALLOC(*param,total_param); if (!(*param)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); goto out; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index db788f46e9..c64c3dfb39 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1281,7 +1281,7 @@ smbc_read_ctx(SMBCCTX *context, } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - ret = cli_read(targetcli, file->cli_fd, buf, offset, count); + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); if (ret < 0) { @@ -1365,7 +1365,7 @@ smbc_write_ctx(SMBCCTX *context, /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - ret = cli_write(targetcli, file->cli_fd, 0, buf, offset, count); + ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); if (ret <= 0) { @@ -2246,7 +2246,7 @@ add_dirent(SMBCFILE *dir, size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; - dirent = SMB_MALLOC(size); + dirent = (struct smbc_dirent *)SMB_MALLOC(size); if (!dirent) { @@ -6230,7 +6230,7 @@ smbc_init_context(SMBCCTX *context) * lazy for the moment */ pid = sys_getpid(); - context->netbios_name = SMB_MALLOC(17); + context->netbios_name = (char *)SMB_MALLOC(17); if (!context->netbios_name) { errno = ENOMEM; return NULL; diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index fd5d8bf06f..e000d539b4 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -323,7 +323,8 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; if (!si->doing_signing) return; @@ -378,7 +379,8 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; if (!si->doing_signing) return True; @@ -433,7 +435,8 @@ We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); static void simple_free_signing_context(struct smb_sign_info *si) { - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; struct outstanding_packet_lookup *list; struct outstanding_packet_lookup *next; @@ -649,7 +652,8 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) { unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; uint32 send_seq_number = data->send_seq_num-1; uint16 mid; @@ -690,7 +694,8 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) { BOOL good; - struct smb_basic_signing_context *data = si->signing_context; + struct smb_basic_signing_context *data = + (struct smb_basic_signing_context *)si->signing_context; uint32 reply_seq_number = data->send_seq_num; uint32 saved_seq; unsigned char calc_md5_mac[16]; -- cgit From 467ec2a32bac08468855a5a28a7d6e25b26904d5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 1 Aug 2006 12:45:12 +0000 Subject: r17363: Some C++ warnings (This used to be commit fd82f185a2e0f94bfb75f4eee072556ad94bf27d) --- source3/libsmb/smb_share_modes.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 34ede9df29..54477c4524 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -259,9 +259,10 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { /* We must create the entry. */ - db_data.dptr = malloc((2*sizeof(struct share_mode_entry)) + - strlen(sharepath) + 1 + - strlen(filename) + 1); + db_data.dptr = (char *)malloc( + (2*sizeof(struct share_mode_entry)) + + strlen(sharepath) + 1 + + strlen(filename) + 1); if (!db_data.dptr) { return -1; } @@ -294,7 +295,8 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, } /* Entry exists, we must add a new entry. */ - new_data_p = malloc(db_data.dsize + sizeof(struct share_mode_entry)); + new_data_p = (char *)malloc( + db_data.dsize + sizeof(struct share_mode_entry)); if (!new_data_p) { free(db_data.dptr); return -1; @@ -391,7 +393,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* More than one - allocate a new record minus the one we'll delete. */ - new_data_p = malloc(db_data.dsize - sizeof(struct share_mode_entry)); + new_data_p = (char *)malloc( + db_data.dsize - sizeof(struct share_mode_entry)); if (!new_data_p) { free(db_data.dptr); return -1; -- cgit From a8627a857630033cca700916d90456c837726ff4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Aug 2006 20:05:37 +0000 Subject: r17431: Fix bug #4003, reported by dale-keyword-samba.c7b741@codefu.org. NTcancel doesn't send a reply, so in this case the signing sequence number is only incremented by 1, not 2. Jeremy. (This used to be commit 85841a01987e653a085af00c7c437145686a332b) --- source3/libsmb/smb_signing.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index e000d539b4..e277137e9b 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -852,6 +852,9 @@ void srv_cancel_sign_response(uint16 mid) while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) ; + + /* cancel doesn't send a reply so doesn't burn a sequence number. */ + data->send_seq_num -= 1; } /*********************************************************** -- cgit From 3fc9b7e626e196b9692f1a29cde246355f608499 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 Aug 2006 14:18:15 +0000 Subject: r17556: Remove duplicate entries. Thanks to Michael Adam Volker (This used to be commit ea83001d3ed0b5da67cf367c17fdef662bc01681) --- source3/libsmb/nterr.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 4f97379ee0..15072f70d3 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -572,7 +572,6 @@ nt_err_code_struct nt_err_desc[] = { "Unexpected information received", NT_STATUS_INVALID_PARAMETER }, { "Memory allocation error", NT_STATUS_NO_MEMORY }, { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, - { "Account locked out", NT_STATUS_ACCOUNT_LOCKED_OUT }, { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE }, { "Not implemented", NT_STATUS_NOT_IMPLEMENTED }, { "Invalid information class", NT_STATUS_INVALID_INFO_CLASS }, @@ -583,7 +582,6 @@ nt_err_code_struct nt_err_desc[] = { "No memory", NT_STATUS_NO_MEMORY }, { "Buffer too small", NT_STATUS_BUFFER_TOO_SMALL }, { "Revision mismatch", NT_STATUS_REVISION_MISMATCH }, - { "No logon servers", NT_STATUS_NO_LOGON_SERVERS }, { "No such logon session", NT_STATUS_NO_SUCH_LOGON_SESSION }, { "No such privilege", NT_STATUS_NO_SUCH_PRIVILEGE }, { "Procedure not found", NT_STATUS_PROCEDURE_NOT_FOUND }, -- cgit From b29915d6113264bdce243005d29a1af9a8b69bde Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 Aug 2006 17:14:16 +0000 Subject: r17571: Change the return code of cli_session_setup from BOOL to NTSTATUS Volker (This used to be commit 94817a8ef53589011bc4ead4e17807a101acf5c9) --- source3/libsmb/cliconnect.c | 65 +++++++++++++++++++++++++------------------ source3/libsmb/clidfs.c | 11 ++++---- source3/libsmb/libsmbclient.c | 16 +++++------ source3/libsmb/passchange.c | 39 +++++++++++++------------- 4 files changed, 71 insertions(+), 60 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d547bb3854..ae00dc5489 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -802,11 +802,11 @@ ntlmssp: password is in plaintext, the same should be done. ****************************************************************************/ -BOOL cli_session_setup(struct cli_state *cli, - const char *user, - const char *pass, int passlen, - const char *ntpass, int ntpasslen, - const char *workgroup) +NTSTATUS cli_session_setup(struct cli_state *cli, + const char *user, + const char *pass, int passlen, + const char *ntpass, int ntpasslen, + const char *workgroup) { char *p; fstring user2; @@ -820,8 +820,9 @@ BOOL cli_session_setup(struct cli_state *cli, workgroup = user2; } - if (cli->protocol < PROTOCOL_LANMAN1) - return True; + if (cli->protocol < PROTOCOL_LANMAN1) { + return NT_STATUS_OK; + } /* now work out what sort of session setup we are going to do. I have split this into separate functions to make the @@ -833,31 +834,34 @@ BOOL cli_session_setup(struct cli_state *cli, if (!lp_client_lanman_auth() && passlen != 24 && (*pass)) { DEBUG(1, ("Server requested LM password but 'client lanman auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && !lp_client_plaintext_auth() && (*pass)) { DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } - return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup); + return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup) ? + NT_STATUS_OK : cli_nt_error(cli); } /* if no user is supplied then we have to do an anonymous connection. passwords are ignored */ if (!user || !*user) - return cli_session_setup_guest(cli); + return cli_session_setup_guest(cli) ? + NT_STATUS_OK : cli_nt_error(cli); /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) - return cli_session_setup_plaintext(cli, user, "", workgroup); + return cli_session_setup_plaintext(cli, user, "", workgroup) ? + NT_STATUS_OK : cli_nt_error(cli); /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ @@ -866,9 +870,10 @@ BOOL cli_session_setup(struct cli_state *cli, if (!lp_client_plaintext_auth() && (*pass)) { DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" " is disabled\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } - return cli_session_setup_plaintext(cli, user, pass, workgroup); + return cli_session_setup_plaintext(cli, user, pass, workgroup) ? + NT_STATUS_OK : cli_nt_error(cli); } /* if the server supports extended security then use SPNEGO */ @@ -877,13 +882,13 @@ BOOL cli_session_setup(struct cli_state *cli, ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup); if (!ADS_ERR_OK(status)) { DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status))); - return False; + return ads_ntstatus(status); } } else { /* otherwise do a NT1 style session setup */ if ( !cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup) ) { DEBUG(3,("cli_session_setup: NT1 session setup failed!\n")); - return False; + return cli_nt_error(cli); } } @@ -891,7 +896,7 @@ BOOL cli_session_setup(struct cli_state *cli, cli->is_samba = True; } - return True; + return NT_STATUS_OK; } @@ -1510,20 +1515,26 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return nt_status; } - if (!cli_session_setup(cli, user, password, pw_len, password, pw_len, domain)) { - if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK) - && cli_session_setup(cli, "", "", 0, "", 0, domain)) { - } else { - nt_status = cli_nt_error(cli); - DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); + nt_status = cli_session_setup(cli, user, password, pw_len, password, + pw_len, domain); + if (!NT_STATUS_IS_OK(nt_status)) { + + if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK)) { + DEBUG(1,("failed session setup with %s\n", + nt_errstr(nt_status))); cli_shutdown(cli); - if (NT_STATUS_IS_OK(nt_status)) { - nt_status = NT_STATUS_UNSUCCESSFUL; - } return nt_status; } - } + nt_status = cli_session_setup(cli, "", "", 0, "", 0, domain); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("anonymous failed session setup with %s\n", + nt_errstr(nt_status))); + cli_shutdown(cli); + return nt_status; + } + } + if (service) { if (!cli_send_tconX(cli, service, service_type, password, pw_len)) { nt_status = cli_nt_error(cli); diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 0135881021..916e4cefc6 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -127,13 +127,14 @@ static struct cli_state *do_connect( const char *server, const char *share, } } - if (!cli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - lp_workgroup())) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username, + password, strlen(password), + password, strlen(password), + lp_workgroup()))) { /* if a password was not supplied then try again with a null username */ if (password[0] || !username[0] || use_kerberos || - !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) { + !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, + lp_workgroup()))) { d_printf("session setup failed: %s\n", cli_errstr(c)); if (NT_STATUS_V(cli_nt_error(c)) == NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c64c3dfb39..d9267e72bd 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -814,19 +814,19 @@ smbc_server(SMBCCTX *context, username_used = username; - if (!cli_session_setup(c, username_used, - password, strlen(password), - password, strlen(password), - workgroup)) { + if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, + password, strlen(password), + password, strlen(password), + workgroup))) { /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || - !cli_session_setup(c, username_used, - password, 1, - password, 0, - workgroup)) { + !NT_STATUS_IS_OK(cli_session_setup(c, username_used, + password, 1, + password, 0, + workgroup))) { cli_shutdown(c); errno = EPERM; diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 0d3dcf4d75..e400819743 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -80,39 +80,38 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam /* Given things like SMB signing, restrict anonymous and the like, try an authenticated connection first */ - if (!cli_session_setup(cli, user_name, old_passwd, strlen(old_passwd)+1, old_passwd, strlen(old_passwd)+1, "")) { + result = cli_session_setup(cli, user_name, + old_passwd, strlen(old_passwd)+1, + old_passwd, strlen(old_passwd)+1, ""); - result = cli_nt_error(cli); - - if (!NT_STATUS_IS_OK(result)) { - - /* Password must change is the only valid error - * condition here from where we can proceed, the rest - * like account locked out or logon failure will lead - * to errors later anyway */ + if (!NT_STATUS_IS_OK(result)) { - if (!NT_STATUS_EQUAL(result, - NT_STATUS_PASSWORD_MUST_CHANGE)) { - slprintf(err_str, err_str_len-1, "Could not " - "connect to machine %s: %s\n", - remote_machine, cli_errstr(cli)); - cli_shutdown(cli); - return result; - } + /* Password must change is the only valid error condition here + * from where we can proceed, the rest like account locked out + * or logon failure will lead to errors later anyway */ - pass_must_change = True; + if (!NT_STATUS_EQUAL(result, + NT_STATUS_PASSWORD_MUST_CHANGE)) { + slprintf(err_str, err_str_len-1, "Could not " + "connect to machine %s: %s\n", + remote_machine, cli_errstr(cli)); + cli_shutdown(cli); + return result; } + pass_must_change = True; + /* * We should connect as the anonymous user here, in case * the server has "must change password" checked... * Thanks to for this fix. */ - if (!cli_session_setup(cli, "", "", 0, "", 0, "")) { + result = cli_session_setup(cli, "", "", 0, "", 0, ""); + + if (!NT_STATUS_IS_OK(result)) { slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", remote_machine, cli_errstr(cli) ); - result = cli_nt_error(cli); cli_shutdown(cli); return result; } -- cgit From aa2138ed5badedc5754978b61db1042617857690 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 17 Aug 2006 10:01:48 +0000 Subject: r17583: Change internal cli_session_setup functions to NTSTATUS. Volker (This used to be commit 990da03f0940371d20f89c145b7ebdbe8e9bf4c4) --- source3/libsmb/cliconnect.c | 103 ++++++++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 47 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ae00dc5489..3e4b6f0545 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -55,16 +55,19 @@ static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_ Do an old lanman2 style session setup. ****************************************************************************/ -static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, - const char *pass, size_t passlen, const char *workgroup) +static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, + const char *user, + const char *pass, size_t passlen, + const char *workgroup) { DATA_BLOB session_key = data_blob(NULL, 0); DATA_BLOB lm_response = data_blob(NULL, 0); fstring pword; char *p; - if (passlen > sizeof(pword)-1) - return False; + if (passlen > sizeof(pword)-1) { + return NT_STATUS_INVALID_PARAMETER; + } /* LANMAN servers predate NT status codes and Unicode and ignore those smb flags so we must disable the corresponding default capabilities @@ -82,7 +85,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, lm_response = data_blob(NULL, 24); if (!SMBencrypt(pass, cli->secblob.data,(uchar *)lm_response.data)) { DEBUG(1, ("Password is > 14 chars in length, and is therefore incompatible with Lanman authentication\n")); - return False; + return NT_STATUS_ACCESS_DENIED; } } else if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && passlen == 24) { /* Encrypted mode needed, and encrypted password supplied. */ @@ -115,14 +118,15 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } /* use the returned vuid from now on */ cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -133,7 +137,7 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, const char *user, cli_set_session_key(cli, session_key); } - return True; + return NT_STATUS_OK; } /**************************************************************************** @@ -158,7 +162,7 @@ static uint32 cli_session_setup_capabilities(struct cli_state *cli) Do a NT1 guest session setup. ****************************************************************************/ -static BOOL cli_session_setup_guest(struct cli_state *cli) +static NTSTATUS cli_session_setup_guest(struct cli_state *cli) { char *p; uint32 capabilities = cli_session_setup_capabilities(cli); @@ -183,14 +187,15 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) p += clistr_push(cli, p, "Samba", -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } cli->vuid = SVAL(cli->inbuf,smb_uid); @@ -205,15 +210,16 @@ static BOOL cli_session_setup_guest(struct cli_state *cli) fstrcpy(cli->user_name, ""); - return True; + return NT_STATUS_OK; } /**************************************************************************** Do a NT1 plaintext session setup. ****************************************************************************/ -static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, - const char *pass, const char *workgroup) +static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, + const char *user, const char *pass, + const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; @@ -252,14 +258,15 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, p += clistr_push(cli, p, lanman, -1, STR_TERMINATE); cli_setup_bcc(cli, p); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { + return cli_nt_error(cli); + } show_msg(cli->inbuf); - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return cli_nt_error(cli); + } cli->vuid = SVAL(cli->inbuf,smb_uid); p = smb_buf(cli->inbuf); @@ -272,7 +279,7 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, cli->is_samba = True; } - return True; + return NT_STATUS_OK; } /**************************************************************************** @@ -285,16 +292,16 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, const char *user, @param workgroup The user's domain. ****************************************************************************/ -static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, - const char *pass, size_t passlen, - const char *ntpass, size_t ntpasslen, - const char *workgroup) +static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, + const char *pass, size_t passlen, + const char *ntpass, size_t ntpasslen, + const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); DATA_BLOB lm_response = data_blob(NULL, 0); DATA_BLOB nt_response = data_blob(NULL, 0); DATA_BLOB session_key = data_blob(NULL, 0); - BOOL ret = False; + NTSTATUS result; char *p; if (passlen == 0) { @@ -316,7 +323,7 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, &lm_response, &nt_response, &session_key)) { data_blob_free(&names_blob); data_blob_free(&server_chal); - return False; + return NT_STATUS_ACCESS_DENIED; } data_blob_free(&names_blob); data_blob_free(&server_chal); @@ -398,14 +405,14 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, cli_setup_bcc(cli, p); if (!cli_send_smb(cli) || !cli_receive_smb(cli)) { - ret = False; + result = cli_nt_error(cli); goto end; } /* show_msg(cli->inbuf); */ if (cli_is_error(cli)) { - ret = False; + result = cli_nt_error(cli); goto end; } @@ -428,12 +435,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, const char *user, cli_set_session_key(cli, session_key); } - ret = True; + result = NT_STATUS_OK; end: data_blob_free(&lm_response); data_blob_free(&nt_response); data_blob_free(&session_key); - return ret; + return result; } /**************************************************************************** @@ -844,24 +851,22 @@ NTSTATUS cli_session_setup(struct cli_state *cli, return NT_STATUS_ACCESS_DENIED; } - return cli_session_setup_lanman2(cli, user, pass, passlen, workgroup) ? - NT_STATUS_OK : cli_nt_error(cli); + return cli_session_setup_lanman2(cli, user, pass, passlen, + workgroup); } /* if no user is supplied then we have to do an anonymous connection. passwords are ignored */ if (!user || !*user) - return cli_session_setup_guest(cli) ? - NT_STATUS_OK : cli_nt_error(cli); + return cli_session_setup_guest(cli); /* if the server is share level then send a plaintext null password at this point. The password is sent in the tree connect */ if ((cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL) == 0) - return cli_session_setup_plaintext(cli, user, "", workgroup) ? - NT_STATUS_OK : cli_nt_error(cli); + return cli_session_setup_plaintext(cli, user, "", workgroup); /* if the server doesn't support encryption then we have to use plaintext. The second password is ignored */ @@ -872,8 +877,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, " is disabled\n")); return NT_STATUS_ACCESS_DENIED; } - return cli_session_setup_plaintext(cli, user, pass, workgroup) ? - NT_STATUS_OK : cli_nt_error(cli); + return cli_session_setup_plaintext(cli, user, pass, workgroup); } /* if the server supports extended security then use SPNEGO */ @@ -885,10 +889,15 @@ NTSTATUS cli_session_setup(struct cli_state *cli, return ads_ntstatus(status); } } else { + NTSTATUS status; + /* otherwise do a NT1 style session setup */ - if ( !cli_session_setup_nt1(cli, user, pass, passlen, ntpass, ntpasslen, workgroup) ) { - DEBUG(3,("cli_session_setup: NT1 session setup failed!\n")); - return cli_nt_error(cli); + status = cli_session_setup_nt1(cli, user, pass, passlen, + ntpass, ntpasslen, workgroup); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3,("cli_session_setup: NT1 session setup " + "failed: %s\n", nt_errstr(status))); + return status; } } -- cgit From b4f39f4a9ed432d7bd687527b36d5ec93397d2b2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Aug 2006 19:49:54 +0000 Subject: r17595: Fix from Ben Winslow to allow client smb signing to be correctly turned off. Jeremy. (This used to be commit 61f052b0a67b8a05b5d925bf8bbad73369ac03bd) --- source3/libsmb/smb_signing.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index e277137e9b..a2df0cc38a 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -108,6 +108,10 @@ static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list static BOOL cli_set_smb_signing_common(struct cli_state *cli) { + if (!cli->sign_info.allow_smb_signing) { + return False; + } + if (!cli->sign_info.negotiated_smb_signing && !cli->sign_info.mandatory_signing) { return False; -- cgit From 41a4496b20e510dc47fe2b816196cef6fe937cea Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 18 Aug 2006 15:10:46 +0000 Subject: r17606: Introduce krb5_to_ntstatus. Thanks to Michael Adam Volker (This used to be commit 6e641c90b8f52a822a83701cdf305c60416d7f0c) --- source3/libsmb/errormap.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index cb5e8311ca..7758246929 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1566,3 +1566,40 @@ NTSTATUS map_nt_error_from_unix(int unix_error) /* Default return */ return NT_STATUS_ACCESS_DENIED; } + +#ifdef HAVE_KRB5 +/********************************************************************* + Map a krb5 error code to an NT error code +*********************************************************************/ + +struct krb5_error_map { + int krb5_error; + NTSTATUS nt_error; +}; + +const struct krb5_error_map krb5_nt_errmap[] = { + { KRB5KDC_ERR_PREAUTH_FAILED, NT_STATUS_LOGON_FAILURE }, + { KRB5_KDC_UNREACH, NT_STATUS_NO_LOGON_SERVERS }, + { KRB5KRB_AP_ERR_SKEW, NT_STATUS_TIME_DIFFERENCE_AT_DC }, + /* not sure if this mapping is appropriate */ + { KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, NT_STATUS_NO_TRUST_SAM_ACCOUNT }, + { KRB5KDC_ERR_NONE, NT_STATUS_OK }, + /* end of array flag - not used as error code... */ + { 0, NT_STATUS_OK } +}; + +NTSTATUS krb5_to_ntstatus(int error) +{ + int i = 0; + + while (krb5_nt_errmap[i].krb5_error != 0) { + if (krb5_nt_errmap[i].krb5_error == error) { + return krb5_nt_errmap[i].nt_error; + } + i++; + } + + return NT_STATUS_ACCESS_DENIED; +} +#endif + -- cgit From ffa590854ab5f2563c3398ae9ae3182e6abe3f82 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 19 Aug 2006 20:42:04 +0000 Subject: r17612: Modify NTLMSSP session code so that it doesn't store a copy of the plaintext password, only the NT and LM hashes (all it needs). Fix smbencrypt to expose hash verions of plaintext function. Andrew Bartlett, you might want to look at this for gensec. This should make it easier for winbindd to store cached credentials without having to store plaintext passwords in an NTLM-only environment (non krb5). Jeremy. (This used to be commit 629faa530f0422755823644f1c23bea74830912f) --- source3/libsmb/ntlmssp.c | 56 ++++++++++++++++++++++--------------- source3/libsmb/smbencrypt.c | 68 +++++++++++++++++++++++++++++++++------------ 2 files changed, 84 insertions(+), 40 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index a6fb3b426b..fd639ffd9f 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -155,18 +155,37 @@ NTSTATUS ntlmssp_set_username(NTLMSSP_STATE *ntlmssp_state, const char *user) } /** - * Set a password on an NTLMSSP context - ensures it is talloc()ed + * Store NT and LM hashes on an NTLMSSP context - ensures they are talloc()ed + * + */ +NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state, + const unsigned char lm_hash[16], + const unsigned char nt_hash[16]) +{ + ntlmssp_state->lm_hash = TALLOC_MEMDUP(ntlmssp_state->mem_ctx, lm_hash, 16); + ntlmssp_state->nt_hash = TALLOC_MEMDUP(ntlmssp_state->mem_ctx, nt_hash, 16); + if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} + +/** + * Converts a password to the hashes on an NTLMSSP context. * */ NTSTATUS ntlmssp_set_password(NTLMSSP_STATE *ntlmssp_state, const char *password) { if (!password) { - ntlmssp_state->password = NULL; + ntlmssp_state->lm_hash = NULL; + ntlmssp_state->nt_hash = NULL; } else { - ntlmssp_state->password = talloc_strdup(ntlmssp_state->mem_ctx, password); - if (!ntlmssp_state->password) { - return NT_STATUS_NO_MEMORY; - } + unsigned char lm_hash[16]; + unsigned char nt_hash[16]; + + E_deshash(password, lm_hash); + E_md4hash(password, nt_hash); + return ntlmssp_set_hashes(ntlmssp_state, lm_hash, nt_hash); } return NT_STATUS_OK; } @@ -1029,7 +1048,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, return NT_STATUS_INVALID_PARAMETER; } - if (!ntlmssp_state->password) { + if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) { static const uchar zeros[16]; /* do nothing - blobs are zero length */ @@ -1049,9 +1068,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, /* TODO: if the remote server is standalone, then we should replace 'domain' with the server name as supplied above */ - if (!SMBNTLMv2encrypt(ntlmssp_state->user, + if (!SMBNTLMv2encrypt_hash(ntlmssp_state->user, ntlmssp_state->domain, - ntlmssp_state->password, &challenge_blob, + ntlmssp_state->nt_hash, &challenge_blob, &struct_blob, &lm_response, &nt_response, &session_key)) { data_blob_free(&challenge_blob); @@ -1060,11 +1079,9 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { struct MD5Context md5_session_nonce_ctx; - uchar nt_hash[16]; uchar session_nonce[16]; uchar session_nonce_hash[16]; uchar user_session_key[16]; - E_md4hash(ntlmssp_state->password, nt_hash); lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); generate_random_buffer(lm_response.data, 8); @@ -1083,40 +1100,35 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, dump_data(5, (const char *)session_nonce_hash, 8); nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); - SMBNTencrypt(ntlmssp_state->password, + SMBNTencrypt_hash(ntlmssp_state->nt_hash, session_nonce_hash, nt_response.data); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); - SMBsesskeygen_ntv1(nt_hash, NULL, user_session_key); + SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, user_session_key); hmac_md5(user_session_key, session_nonce, sizeof(session_nonce), session_key.data); dump_data_pw("NTLM2 session key:\n", session_key.data, session_key.length); } else { - uchar lm_hash[16]; - uchar nt_hash[16]; - E_deshash(ntlmssp_state->password, lm_hash); - E_md4hash(ntlmssp_state->password, nt_hash); - /* lanman auth is insecure, it may be disabled */ if (lp_client_lanman_auth()) { lm_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); - SMBencrypt(ntlmssp_state->password,challenge_blob.data, + SMBencrypt_hash(ntlmssp_state->lm_hash,challenge_blob.data, lm_response.data); } nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); - SMBNTencrypt(ntlmssp_state->password,challenge_blob.data, + SMBNTencrypt_hash(ntlmssp_state->nt_hash,challenge_blob.data, nt_response.data); session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); if ((ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) && lp_client_lanman_auth()) { - SMBsesskeygen_lm_sess_key(lm_hash, lm_response.data, + SMBsesskeygen_lm_sess_key(ntlmssp_state->lm_hash, lm_response.data, session_key.data); dump_data_pw("LM session key\n", session_key.data, session_key.length); } else { - SMBsesskeygen_ntv1(nt_hash, NULL, session_key.data); + SMBsesskeygen_ntv1(ntlmssp_state->nt_hash, NULL, session_key.data); dump_data_pw("NT session key:\n", session_key.data, session_key.length); } } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ddfe696b48..96c086d680 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -25,30 +25,38 @@ #include "includes.h" #include "byteorder.h" -/* - This implements the X/Open SMB password encryption - It takes a password ('unix' string), a 8 byte "crypt key" - and puts 24 bytes of encrypted password into p24 - - Returns False if password must have been truncated to create LM hash -*/ -BOOL SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) +void SMBencrypt_hash(const uchar lm_hash[16], const uchar *c8, uchar p24[24]) { - BOOL ret; uchar p21[21]; memset(p21,'\0',21); - ret = E_deshash(passwd, p21); + memcpy(p21, lm_hash, 16); SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD - DEBUG(100,("SMBencrypt: lm#, challenge, response\n")); + DEBUG(100,("SMBencrypt_hash: lm#, challenge, response\n")); dump_data(100, (const char *)p21, 16); dump_data(100, (const char *)c8, 8); dump_data(100, (const char *)p24, 24); #endif +} +/* + This implements the X/Open SMB password encryption + It takes a password ('unix' string), a 8 byte "crypt key" + and puts 24 bytes of encrypted password into p24 + + Returns False if password must have been truncated to create LM hash +*/ + +BOOL SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) +{ + BOOL ret; + uchar lm_hash[16]; + + ret = E_deshash(passwd, lm_hash); + SMBencrypt_hash(lm_hash, c8, p24); return ret; } @@ -237,15 +245,14 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p } -/* Does the NT MD4 hash then des encryption. */ +/* Does the des encryption. */ -void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) +void SMBNTencrypt_hash(const uchar nt_hash[16], uchar *c8, uchar *p24) { uchar p21[21]; memset(p21,'\0',21); - - E_md4hash(passwd, p21); + memcpy(p21, nt_hash, 16); SMBOWFencrypt(p21, c8, p24); #ifdef DEBUG_PASSWORD @@ -256,6 +263,15 @@ void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) #endif } +/* Does the NT MD4 hash then des encryption. Plaintext version of the above. */ + +void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24) +{ + uchar nt_hash[16]; + E_md4hash(passwd, nt_hash); + SMBNTencrypt_hash(nt_hash, c8, p24); +} + /* Does the md5 encryption from the Key Response for NTLMv2. */ void SMBOWFencrypt_ntv2(const uchar kr[16], const DATA_BLOB *srv_chal, @@ -416,15 +432,13 @@ static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16], return final_response; } -BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, +BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_hash[16], const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, DATA_BLOB *user_session_key) { - uchar nt_hash[16]; uchar ntlm_v2_hash[16]; - E_md4hash(password, nt_hash); /* We don't use the NT# directly. Instead we use it mashed up with the username and domain. @@ -455,6 +469,24 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password return True; } +/* Plaintext version of the above. */ + +BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, + const DATA_BLOB *server_chal, + const DATA_BLOB *names_blob, + DATA_BLOB *lm_response, DATA_BLOB *nt_response, + DATA_BLOB *user_session_key) +{ + uchar nt_hash[16]; + E_md4hash(password, nt_hash); + + return SMBNTLMv2encrypt_hash(user, domain, nt_hash, + server_chal, + names_blob, + lm_response, nt_response, + user_session_key); +} + /*********************************************************** encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. -- cgit From 711982340390f5dae8b3778d28fc0f4733e25221 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Aug 2006 17:08:37 +0000 Subject: r17620: Fix two C++ Warnings and a memleak (This used to be commit d7246284e0117f7a97b3cbb80ff45b532559bf63) --- source3/libsmb/ntlmssp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index fd639ffd9f..70fcd24e76 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -162,9 +162,13 @@ NTSTATUS ntlmssp_set_hashes(NTLMSSP_STATE *ntlmssp_state, const unsigned char lm_hash[16], const unsigned char nt_hash[16]) { - ntlmssp_state->lm_hash = TALLOC_MEMDUP(ntlmssp_state->mem_ctx, lm_hash, 16); - ntlmssp_state->nt_hash = TALLOC_MEMDUP(ntlmssp_state->mem_ctx, nt_hash, 16); + ntlmssp_state->lm_hash = (unsigned char *) + TALLOC_MEMDUP(ntlmssp_state->mem_ctx, lm_hash, 16); + ntlmssp_state->nt_hash = (unsigned char *) + TALLOC_MEMDUP(ntlmssp_state->mem_ctx, nt_hash, 16); if (!ntlmssp_state->lm_hash || !ntlmssp_state->nt_hash) { + TALLOC_FREE(ntlmssp_state->lm_hash); + TALLOC_FREE(ntlmssp_state->nt_hash); return NT_STATUS_NO_MEMORY; } return NT_STATUS_OK; -- cgit From 232569c1f1a93bf0291c6e02569857a7a001c3dd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 21 Aug 2006 21:25:17 +0000 Subject: r17672: remove duplicate description on NT_STATUS_INVALID_PARAMETER (from Michael Adam ) (This used to be commit 7b51e27d026f2511edcde054f0d2deb9932d2fe8) --- source3/libsmb/nterr.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 15072f70d3..c247d818c1 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -569,7 +569,6 @@ nt_err_code_struct nt_err_desc[] = { "Invalid workstation", NT_STATUS_INVALID_WORKSTATION }, { "Password expired", NT_STATUS_PASSWORD_EXPIRED }, { "Account disabled", NT_STATUS_ACCOUNT_DISABLED }, - { "Unexpected information received", NT_STATUS_INVALID_PARAMETER }, { "Memory allocation error", NT_STATUS_NO_MEMORY }, { "No domain controllers located", NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND }, { "Named pipe not available", NT_STATUS_PIPE_NOT_AVAILABLE }, -- cgit From 58247fea05a7420d8eafa0b8ea03944e9422cb6c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 22 Aug 2006 00:36:31 +0000 Subject: r17677: There is no need for a 2nd krb5_to_nt_status function, is there? Michael Adam/Volker, please check. Guenther (This used to be commit d0feb85781f69325ee70aff98370cfac037c4cc2) --- source3/libsmb/errormap.c | 37 ------------------------------------- 1 file changed, 37 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 7758246929..cb5e8311ca 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1566,40 +1566,3 @@ NTSTATUS map_nt_error_from_unix(int unix_error) /* Default return */ return NT_STATUS_ACCESS_DENIED; } - -#ifdef HAVE_KRB5 -/********************************************************************* - Map a krb5 error code to an NT error code -*********************************************************************/ - -struct krb5_error_map { - int krb5_error; - NTSTATUS nt_error; -}; - -const struct krb5_error_map krb5_nt_errmap[] = { - { KRB5KDC_ERR_PREAUTH_FAILED, NT_STATUS_LOGON_FAILURE }, - { KRB5_KDC_UNREACH, NT_STATUS_NO_LOGON_SERVERS }, - { KRB5KRB_AP_ERR_SKEW, NT_STATUS_TIME_DIFFERENCE_AT_DC }, - /* not sure if this mapping is appropriate */ - { KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN, NT_STATUS_NO_TRUST_SAM_ACCOUNT }, - { KRB5KDC_ERR_NONE, NT_STATUS_OK }, - /* end of array flag - not used as error code... */ - { 0, NT_STATUS_OK } -}; - -NTSTATUS krb5_to_ntstatus(int error) -{ - int i = 0; - - while (krb5_nt_errmap[i].krb5_error != 0) { - if (krb5_nt_errmap[i].krb5_error == error) { - return krb5_nt_errmap[i].nt_error; - } - i++; - } - - return NT_STATUS_ACCESS_DENIED; -} -#endif - -- cgit From fddeed8adba8004e4bb5678e07461382f6a5124b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Aug 2006 21:04:47 +0000 Subject: r17760: The DNS SRV lookup already sorts by priority and weight so don't use the generic IP list sort in get_sorted_dc_list(). (This used to be commit 03a767539d5b09ebd6564c0c9157de2a6e0e6b89) --- source3/libsmb/namequery.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f6dbe3c548..0bd8bc7cb2 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1356,6 +1356,9 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, BOOL done_auto_lookup = False; int auto_count = 0; + *ordered = False; + + /* if we are restricted to solely using DNS for looking up a domain controller, make sure that host lookups are enabled for the 'name resolve order'. If host lookups @@ -1365,14 +1368,17 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, fstrcpy( resolve_order, lp_name_resolve_order() ); strlower_m( resolve_order ); if ( ads_only ) { - if ( strstr( resolve_order, "host" ) ) + if ( strstr( resolve_order, "host" ) ) { fstrcpy( resolve_order, "ads" ); + + /* DNS SRV lookups used by the ads resolver + are already sorted by priority and weight */ + *ordered = True; + } else fstrcpy( resolve_order, "NULL" ); } - *ordered = False; - /* fetch the server we have affinity for. Add the 'password server' list to a search for our domain controllers */ -- cgit From aee6b5942a3418b9d9a9a73fa33c21d5e4e18df8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Aug 2006 22:33:50 +0000 Subject: r17761: Handle times consistently across all client utils. Fixes bugs reported in libsmbclient. Jeremy. (This used to be commit 42a417fb75313b093948602c3be8e2f386048b5f) --- source3/libsmb/clilist.c | 18 ++--------------- source3/libsmb/clirap.c | 47 ++++++++++++++++++++++--------------------- source3/libsmb/libsmbclient.c | 4 ++-- 3 files changed, 28 insertions(+), 41 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a006c47ae0..b022a107d0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -94,27 +94,13 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f } p += 4; /* fileindex */ - /* these dates appear to arrive in a - weird way. It seems to be localtime - plus the serverzone given in the - initial connect. This is GMT when - DST is not in effect and one hour - from GMT otherwise. Can this really - be right?? - - I suppose this could be called - kludge-GMT. Is is the GMT you get - by using the current DST setting on - a different localtime. It will be - cheap to calculate, I suppose, as - no DST tables will be needed */ - - finfo->ctime = interpret_long_date(p); + /* Offset zero is "create time", not "change time". */ p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; + finfo->ctime = interpret_long_date(p); p += 8; finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index a33baed536..1227b26b2f 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -553,9 +553,10 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, /**************************************************************************** send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ + BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_OFF_T *size, uint16 *mode, + time_t *create_time, time_t *access_time, time_t *write_time, + time_t *change_time, SMB_OFF_T *size, uint16 *mode, SMB_INO_T *ino) { unsigned int data_len = 0; @@ -593,17 +594,17 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, return False; } - if (c_time) { - *c_time = interpret_long_date(rdata+0); + if (create_time) { + *create_time = interpret_long_date(rdata+0); } - if (a_time) { - *a_time = interpret_long_date(rdata+8); + if (access_time) { + *access_time = interpret_long_date(rdata+8); } - if (w_time) { - *w_time = interpret_long_date(rdata+16); + if (write_time) { + *write_time = interpret_long_date(rdata+16); } - if (m_time) { - *m_time = interpret_long_date(rdata+24); + if (change_time) { + *change_time = interpret_long_date(rdata+24); } if (mode) { *mode = SVAL(rdata, 32); @@ -669,8 +670,8 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, uint16 *mode, SMB_OFF_T *size, - time_t *c_time, time_t *a_time, time_t *m_time, - time_t *w_time, SMB_INO_T *ino) + time_t *create_time, time_t *access_time, time_t *write_time, + time_t *change_time, SMB_INO_T *ino) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -708,17 +709,17 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return False; } - if (c_time) { - *c_time = interpret_long_date(rdata+0) - cli->serverzone; + if (create_time) { + *create_time = interpret_long_date(rdata+0); } - if (a_time) { - *a_time = interpret_long_date(rdata+8) - cli->serverzone; + if (access_time) { + *access_time = interpret_long_date(rdata+8); } - if (m_time) { - *m_time = interpret_long_date(rdata+16) - cli->serverzone; + if (write_time) { + *write_time = interpret_long_date(rdata+16); } - if (w_time) { - *w_time = interpret_long_date(rdata+24) - cli->serverzone; + if (change_time) { + *change_time = interpret_long_date(rdata+24); } if (mode) { *mode = SVAL(rdata, 32); @@ -793,9 +794,9 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, return False; } - sbuf->st_atime = interpret_long_date( rdata+8 ); - sbuf->st_mtime = interpret_long_date( rdata+16 ); - sbuf->st_ctime = interpret_long_date( rdata+24 ); + sbuf->st_atime = interpret_long_date( rdata+8 ); /* Access time. */ + sbuf->st_mtime = interpret_long_date( rdata+16 ); /* Write time. */ + sbuf->st_ctime = interpret_long_date( rdata+24 ); /* Change time. */ *attributes = IVAL( rdata, 32 ); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index d9267e72bd..abeb66b373 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1514,7 +1514,7 @@ smbc_getatr(SMBCCTX * context, if (!srv->no_pathinfo2 && cli_qpathinfo2(targetcli, targetpath, - c_time, a_time, m_time, NULL, size, mode, ino)) { + NULL, a_time, m_time, c_time, size, mode, ino)) { return True; } @@ -2182,7 +2182,7 @@ smbc_fstat_ctx(SMBCCTX *context, /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, - &c_time, &a_time, &m_time, NULL, &ino)) { + NULL, &a_time, &m_time, &c_time, &ino)) { if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, &c_time, &a_time, &m_time)) { -- cgit From 8cac7c139908eff0124a4a6f9d25f3b3fe10a254 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Aug 2006 12:13:57 +0000 Subject: r17795: Finally track down the "ads_connect: Interrupted system call" error. Fix our DNS SRV lookup code to deal with multi-homed hosts. We were noly remembering one IP address per host from the Additional records section in the SRV response which could have been an unreachable address. (This used to be commit 899179d2b9fba13cc6f4dab6efc3c22e44e062bc) --- source3/libsmb/namequery.c | 48 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 34 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0bd8bc7cb2..14dfd50829 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1024,11 +1024,12 @@ static BOOL resolve_hosts(const char *name, int name_type, static BOOL resolve_ads(const char *name, int name_type, struct ip_service **return_iplist, int *return_count) { - int i = 0; + int i, j; NTSTATUS status; TALLOC_CTX *ctx; struct dns_rr_srv *dcs = NULL; int numdcs = 0; + int numaddrs = 0; if ( name_type != 0x1c ) return False; @@ -1045,24 +1046,44 @@ static BOOL resolve_ads(const char *name, int name_type, if ( !NT_STATUS_IS_OK( status ) ) { return False; } + + for (i=0;iip = *interpret_addr2(dcs[i].hostname); - else - r->ip = dcs[i].ip; - r->port = dcs[i].port; + + /* If we don't have an IP list for a name, lookup it up */ + + if ( !dcs[i].ips ) { + r->ip = *interpret_addr2(dcs[i].hostname); + i++; + j = 0; + } else { + /* use the IP addresses from the SRV sresponse */ + + if ( j >= dcs[i].num_ips ) { + i++; + j = 0; + continue; + } + + r->ip = dcs[i].ips[j]; + j++; + } /* make sure it is a valid IP. I considered checking the negative connection cache, but this is the wrong place for it. Maybe only @@ -1358,7 +1379,6 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, *ordered = False; - /* if we are restricted to solely using DNS for looking up a domain controller, make sure that host lookups are enabled for the 'name resolve order'. If host lookups @@ -1374,9 +1394,9 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, /* DNS SRV lookups used by the ads resolver are already sorted by priority and weight */ *ordered = True; + } else { + fstrcpy( resolve_order, "NULL" ); } - else - fstrcpy( resolve_order, "NULL" ); } /* fetch the server we have affinity for. Add the -- cgit From a64925ddff467a47f7adfac4b1b977ddc0c7f4ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Aug 2006 16:44:00 +0000 Subject: r17800: Start using struct timespec internally for file times on the wire. This allows us to go to nsec resolution for systems that support it. It should also now be easy to add a correct "create time" (birth time) for systems that support it (*BSD). I'll be watching the build farm closely after this one for breakage :-). Jeremy. (This used to be commit 425280a1d23f97ef0b0be77462386d619f47b21d) --- source3/libsmb/cliconnect.c | 4 ++- source3/libsmb/clifile.c | 7 ++-- source3/libsmb/clifsinfo.c | 4 ++- source3/libsmb/clilist.c | 24 +++++++------ source3/libsmb/clirap.c | 14 ++++---- source3/libsmb/libsmbclient.c | 84 ++++++++++++++++++++++++------------------- 6 files changed, 77 insertions(+), 60 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3e4b6f0545..0e179416dc 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1149,6 +1149,7 @@ BOOL cli_negprot(struct cli_state *cli) } if (cli->protocol >= PROTOCOL_NT1) { + struct timespec ts; /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1); @@ -1157,7 +1158,8 @@ BOOL cli_negprot(struct cli_state *cli) cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1); cli->serverzone *= 60; /* this time arrives in real GMT */ - cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1); + ts = interpret_long_date(cli->inbuf+smb_vwv11+1); + cli->servertime = ts.tv_sec; cli->secblob = data_blob(smb_buf(cli->inbuf),smb_buflen(cli->inbuf)); cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1); if (cli->capabilities & CAP_RAW_MODE) { diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 9beafc55fb..fb07dae427 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -266,9 +266,10 @@ BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu /* assume 512 byte blocks */ sbuf->st_blocks /= 512; #endif - sbuf->st_ctime = interpret_long_date(rdata + 16); /* time of last change */ - sbuf->st_atime = interpret_long_date(rdata + 24); /* time of last access */ - sbuf->st_mtime = interpret_long_date(rdata + 32); /* time of last modification */ + set_ctimespec(sbuf, interpret_long_date(rdata + 16)); /* time of last change */ + set_atimespec(sbuf, interpret_long_date(rdata + 24)); /* time of last access */ + set_mtimespec(sbuf, interpret_long_date(rdata + 32)); /* time of last modification */ + sbuf->st_uid = (uid_t) IVAL(rdata,40); /* user ID of owner */ sbuf->st_gid = (gid_t) IVAL(rdata,48); /* group ID of owner */ sbuf->st_mode |= unix_filetype_from_wire(IVAL(rdata, 56)); diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index c6aa6a70a0..9c3b6e3aed 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -282,7 +282,9 @@ BOOL cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 * } if (pdate) { - *pdate = interpret_long_date(rdata); + struct timespec ts; + ts = interpret_long_date(rdata); + *pdate = ts.tv_sec; } if (pserial_number) { *pserial_number = IVAL(rdata,8); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index b022a107d0..18c058f9df 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -49,9 +49,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = cli_make_unix_date2(cli, p+4); - finfo->atime = cli_make_unix_date2(cli, p+8); - finfo->mtime = cli_make_unix_date2(cli, p+12); + finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); + finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); + finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); @@ -70,9 +70,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 2: /* this is what OS/2 uses mostly */ /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = cli_make_unix_date2(cli, p+4); - finfo->atime = cli_make_unix_date2(cli, p+8); - finfo->mtime = cli_make_unix_date2(cli, p+12); + finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); + finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); + finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); @@ -96,11 +96,11 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f /* Offset zero is "create time", not "change time". */ p += 8; - finfo->atime = interpret_long_date(p); + finfo->atime_ts = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); + finfo->mtime_ts = interpret_long_date(p); p += 8; - finfo->ctime = interpret_long_date(p); + finfo->ctime_ts = interpret_long_date(p); p += 8; finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; @@ -373,8 +373,10 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mode = CVAL(p,21); /* this date is converted to GMT by make_unix_date */ - finfo->ctime = cli_make_unix_date(cli, p+22); - finfo->mtime = finfo->atime = finfo->ctime; + finfo->ctime_ts.tv_sec = cli_make_unix_date(cli, p+22); + finfo->ctime_ts.tv_nsec = 0; + finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec; + finfo->mtime_ts.tv_nsec = finfo->atime_ts.tv_nsec = 0; finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 1227b26b2f..677c8f1fc3 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -555,8 +555,8 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - time_t *create_time, time_t *access_time, time_t *write_time, - time_t *change_time, SMB_OFF_T *size, uint16 *mode, + struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, + struct timespec *change_time, SMB_OFF_T *size, uint16 *mode, SMB_INO_T *ino) { unsigned int data_len = 0; @@ -670,8 +670,8 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, uint16 *mode, SMB_OFF_T *size, - time_t *create_time, time_t *access_time, time_t *write_time, - time_t *change_time, SMB_INO_T *ino) + struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, + struct timespec *change_time, SMB_INO_T *ino) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -794,9 +794,9 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, return False; } - sbuf->st_atime = interpret_long_date( rdata+8 ); /* Access time. */ - sbuf->st_mtime = interpret_long_date( rdata+16 ); /* Write time. */ - sbuf->st_ctime = interpret_long_date( rdata+24 ); /* Change time. */ + set_atimespec(sbuf, interpret_long_date( rdata+8 )); /* Access time. */ + set_mtimespec(sbuf, interpret_long_date( rdata+16 )); /* Write time. */ + set_ctimespec(sbuf, interpret_long_date( rdata+24 )); /* Change time. */ *attributes = IVAL( rdata, 32 ); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index abeb66b373..2656bd0f04 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1470,14 +1470,15 @@ smbc_getatr(SMBCCTX * context, char *path, uint16 *mode, SMB_OFF_T *size, - time_t *c_time, - time_t *a_time, - time_t *m_time, + struct timespec *c_time_ts, + struct timespec *a_time_ts, + struct timespec *m_time_ts, SMB_INO_T *ino) { pstring fixedpath; pstring targetpath; struct cli_state *targetcli; + time_t m_time; if (!context || !context->internal || !context->internal->_initialized) { @@ -1514,7 +1515,7 @@ smbc_getatr(SMBCCTX * context, if (!srv->no_pathinfo2 && cli_qpathinfo2(targetcli, targetpath, - NULL, a_time, m_time, c_time, size, mode, ino)) { + NULL, a_time_ts, m_time_ts, c_time_ts, size, mode, ino)) { return True; } @@ -1524,10 +1525,11 @@ smbc_getatr(SMBCCTX * context, return False; } - if (cli_getatr(targetcli, targetpath, mode, size, m_time)) { - if (m_time != NULL) { - if (a_time != NULL) *a_time = *m_time; - if (c_time != NULL) *c_time = *m_time; + if (cli_getatr(targetcli, targetpath, mode, size, &m_time)) { + if (m_time_ts != NULL) { + *m_time_ts = convert_time_t_to_timespec(m_time); + if (a_time_ts != NULL) *a_time_ts = *m_time_ts; + if (c_time_ts != NULL) *c_time_ts = *m_time_ts; } srv->no_pathinfo2 = True; return True; @@ -1709,11 +1711,11 @@ smbc_unlink_ctx(SMBCCTX *context, int saverr = errno; SMB_OFF_T size = 0; uint16 mode = 0; - time_t m_time = 0, a_time = 0, c_time = 0; + struct timespec m_time_ts, a_time_ts, c_time_ts; SMB_INO_T ino = 0; if (!smbc_getatr(context, srv, path, &mode, &size, - &c_time, &a_time, &m_time, &ino)) { + &c_time_ts, &a_time_ts, &m_time_ts, &ino)) { /* Hmmm, bad error ... What? */ @@ -2049,9 +2051,9 @@ smbc_stat_ctx(SMBCCTX *context, fstring password; fstring workgroup; pstring path; - time_t m_time = 0; - time_t a_time = 0; - time_t c_time = 0; + struct timespec m_time_ts; + struct timespec a_time_ts; + struct timespec c_time_ts; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; @@ -2095,7 +2097,7 @@ smbc_stat_ctx(SMBCCTX *context, } if (!smbc_getatr(context, srv, path, &mode, &size, - &c_time, &a_time, &m_time, &ino)) { + &c_time_ts, &a_time_ts, &m_time_ts, &ino)) { errno = smbc_errno(context, srv->cli); return -1; @@ -2106,9 +2108,9 @@ smbc_stat_ctx(SMBCCTX *context, smbc_setup_stat(context, st, path, size, mode); - st->st_atime = a_time; - st->st_ctime = c_time; - st->st_mtime = m_time; + set_atimespec(st, a_time_ts); + set_ctimespec(st, c_time_ts); + set_mtimespec(st, m_time_ts); st->st_dev = srv->dev; return 0; @@ -2124,9 +2126,9 @@ smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) { - time_t c_time; - time_t a_time; - time_t m_time; + struct timespec c_time_ts; + struct timespec a_time_ts; + struct timespec m_time_ts; SMB_OFF_T size; uint16 mode; fstring server; @@ -2182,22 +2184,26 @@ smbc_fstat_ctx(SMBCCTX *context, /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, - NULL, &a_time, &m_time, &c_time, &ino)) { - if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, - &c_time, &a_time, &m_time)) { + NULL, &a_time_ts, &m_time_ts, &c_time_ts, &ino)) { + time_t c_time, a_time, m_time; + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, + &c_time, &a_time, &m_time)) { - errno = EINVAL; - return -1; - } + errno = EINVAL; + return -1; + } + c_time_ts = convert_time_t_to_timespec(c_time); + a_time_ts = convert_time_t_to_timespec(a_time); + m_time_ts = convert_time_t_to_timespec(m_time); } st->st_ino = ino; smbc_setup_stat(context, st, file->fname, size, mode); - st->st_atime = a_time; - st->st_ctime = c_time; - st->st_mtime = m_time; + set_atimespec(st, a_time_ts); + set_ctimespec(st, c_time_ts); + set_mtimespec(st, m_time_ts); st->st_dev = file->srv->dev; return 0; @@ -4079,7 +4085,7 @@ dos_attr_query(SMBCCTX *context, const char *filename, SMBCSRV *srv) { - time_t m_time = 0, a_time = 0, c_time = 0; + struct timespec m_time_ts, a_time_ts, c_time_ts; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T inode = 0; @@ -4094,7 +4100,7 @@ dos_attr_query(SMBCCTX *context, /* Obtain the DOS attributes */ if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename), &mode, &size, - &c_time, &a_time, &m_time, &inode)) { + &c_time_ts, &a_time_ts, &m_time_ts, &inode)) { errno = smbc_errno(context, srv->cli); DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); @@ -4104,9 +4110,9 @@ dos_attr_query(SMBCCTX *context, ret->mode = mode; ret->size = size; - ret->a_time = a_time; - ret->c_time = c_time; - ret->m_time = m_time; + ret->a_time = convert_timespec_to_time_t(a_time_ts); + ret->c_time = convert_timespec_to_time_t(c_time_ts); + ret->m_time = convert_timespec_to_time_t(m_time_ts); ret->inode = inode; return ret; @@ -4200,7 +4206,8 @@ cacl_get(SMBCCTX *context, char *name; char *pExclude; char *p; - time_t m_time = 0, a_time = 0, c_time = 0; + struct timespec m_time_ts, a_time_ts, c_time_ts; + time_t m_time = (time_t)0, a_time = (time_t)0, c_time = (time_t)0; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; @@ -4547,13 +4554,16 @@ cacl_get(SMBCCTX *context, /* Obtain the DOS attributes */ if (!smbc_getatr(context, srv, filename, &mode, &size, - &c_time, &a_time, &m_time, &ino)) { + &c_time_ts, &a_time_ts, &m_time_ts, &ino)) { errno = smbc_errno(context, srv->cli); return -1; } - + c_time = convert_timespec_to_time_t(c_time_ts); + a_time = convert_timespec_to_time_t(a_time_ts); + m_time = convert_timespec_to_time_t(m_time_ts); + if (! exclude_dos_mode) { if (all || all_dos) { if (determine_size) { -- cgit From 4bbb995e8dab284b4deaa2e2ee38eb329305d1c2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Aug 2006 17:24:31 +0000 Subject: r17854: Steal the LDAP in NTSTATUS trick from Samba4 Thanks to Michael Adam Volker (This used to be commit 91878f9b6fbe5187fb7d0464008ea0abe7f11a73) --- source3/libsmb/nterr.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index c247d818c1..507bb60da4 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -650,11 +650,14 @@ const char *nt_errstr(NTSTATUS nt_code) static pstring msg; int idx = 0; + if (NT_STATUS_TYPE(nt_code) == NT_STATUS_TYPE_LDAP) { + return ldap_err2string(NT_STATUS_LDAP_CODE(nt_code)); + } + slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); while (nt_errs[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_errs[idx].nt_errcode) == - NT_STATUS_V(nt_code)) { + if (NT_STATUS_EQUAL(nt_errs[idx].nt_errcode, nt_code)) { return nt_errs[idx].nt_errstr; } idx++; -- cgit From cb3e14d5a2fe03439fcfa628b0e95dc2501bbd52 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 27 Aug 2006 17:36:17 +0000 Subject: r17855: Fix the build on systems without LDAP (This used to be commit 2e9f5c520a843ad22088388d155a172a63c140d5) --- source3/libsmb/nterr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 507bb60da4..e874b80473 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -650,9 +650,11 @@ const char *nt_errstr(NTSTATUS nt_code) static pstring msg; int idx = 0; +#ifdef HAVE_LDAP if (NT_STATUS_TYPE(nt_code) == NT_STATUS_TYPE_LDAP) { return ldap_err2string(NT_STATUS_LDAP_CODE(nt_code)); } +#endif slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); -- cgit From 6ee700bd65ea12bf172fce42adf332f6e30ab626 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Aug 2006 01:56:17 +0000 Subject: r17863: Fix unneeded NULL check on pointer parameters causing the Stanford checker to flag null deref. Jeremy. (This used to be commit b7fc023e9025127855fab71002d556e5f84e00b4) --- source3/libsmb/clierror.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index b84a8ee70f..44573bd29b 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -201,8 +201,6 @@ NTSTATUS cli_nt_error(struct cli_state *cli) void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) { int flgs2; - char rcls; - int code; if(!cli->initialised) { return; @@ -223,11 +221,8 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) return; } - rcls = CVAL(cli->inbuf,smb_rcls); - code = SVAL(cli->inbuf,smb_err); - - if (eclass) *eclass = rcls; - if (ecode) *ecode = code; + *eclass = CVAL(cli->inbuf,smb_rcls); + *ecode = SVAL(cli->inbuf,smb_err); } /* Return a UNIX errno from a NT status code */ -- cgit From 41d1f322f856c3e10d03c65a21c12e108338df8a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Aug 2006 05:10:56 +0000 Subject: r17874: Fix possible null deref found by Stanford checker. Jeremy. (This used to be commit 2894310cc8cddaec2a67f1af0ab62cc559283e77) --- source3/libsmb/namecache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index e3e7ac4e3c..ec8a1900d8 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -178,14 +178,14 @@ BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis char *key, *value; time_t timeout; - *num_names = 0; - /* exit now if null pointers were passed as they're required further */ if (!ip_list || !num_names) return False; if (!gencache_init()) return False; + *num_names = 0; + /* * Use gencache interface - lookup the key */ -- cgit From c52b3fb89f29110d2c2026a540e5dd39826bb799 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 28 Aug 2006 09:19:30 +0000 Subject: r17881: Another microstep towards better error reporting: Make get_sorted_dc_list return NTSTATUS. If we want to differentiate different name resolution problems we might want to introduce yet another error class for Samba-internal errors. Things like no route to host to the WINS server, a DNS server explicitly said host not found etc might be worth passing up. Because we can not stash everything into the existing NT_STATUS codes, what about a Samba-specific error class like NT_STATUS_DOS and NT_STATUS_LDAP? Volker (This used to be commit 60a166f0347170dff38554bed46193ce1226c8c1) --- source3/libsmb/namequery.c | 38 ++++++++++++++++++++++++++------------ source3/libsmb/namequery_dc.c | 3 ++- 2 files changed, 28 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 14dfd50829..62f21d94c7 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1360,8 +1360,8 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) a domain. *********************************************************/ -static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, - int *count, BOOL ads_only, int *ordered) +static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, + int *count, BOOL ads_only, int *ordered) { fstring resolve_order; char *saf_servername; @@ -1419,7 +1419,14 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, if ( !*pserver ) { DEBUG(10,("get_dc_list: no preferred domain controllers.\n")); - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); + /* TODO: change return type of internal_resolve_name to + * NTSTATUS */ + if (internal_resolve_name(domain, 0x1C, ip_list, count, + resolve_order)) { + return NT_STATUS_OK; + } else { + return NT_STATUS_NO_LOGON_SERVERS; + } } DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver )); @@ -1434,7 +1441,8 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, p = pserver; while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) { - if ( internal_resolve_name(domain, 0x1C, &auto_ip_list, &auto_count, resolve_order) ) + if (internal_resolve_name(domain, 0x1C, &auto_ip_list, + &auto_count, resolve_order)) num_addresses += auto_count; done_auto_lookup = True; DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); @@ -1448,16 +1456,20 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, if ( (num_addresses == 0) ) { if ( !done_auto_lookup ) { - return internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order); + if (internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order)) { + return NT_STATUS_OK; + } else { + return NT_STATUS_NO_LOGON_SERVERS; + } } else { DEBUG(4,("get_dc_list: no servers found\n")); - return False; + return NT_STATUS_NO_LOGON_SERVERS; } } if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { DEBUG(3,("get_dc_list: malloc fail !\n")); - return False; + return NT_STATUS_NO_MEMORY; } p = pserver; @@ -1535,22 +1547,24 @@ static BOOL get_dc_list(const char *domain, struct ip_service **ip_list, *ip_list = return_iplist; *count = local_count; - return (*count != 0); + return ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS ); } /********************************************************************* Small wrapper function to get the DC list and sort it if neccessary. *********************************************************************/ -BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) +NTSTATUS get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) { BOOL ordered; + NTSTATUS status; DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", (ads_only ? "ads" : lp_name_resolve_order()))); - if ( !get_dc_list(domain, ip_list, count, ads_only, &ordered) ) { - return False; + status = get_dc_list(domain, ip_list, count, ads_only, &ordered); + if (!NT_STATUS_IS_OK(status)) { + return status; } /* only sort if we don't already have an ordered list */ @@ -1558,5 +1572,5 @@ BOOL get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *c sort_ip_list2( *ip_list, *count ); } - return True; + return NT_STATUS_OK; } diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index b9a593bf2a..4afd04a98f 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -81,7 +81,8 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip /* get a list of all domain controllers */ - if ( !get_sorted_dc_list(domain, &ip_list, &count, False) ) { + if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, &ip_list, &count, + False))) { DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); return False; } -- cgit From a08ca7a0a00df371601e14099bfdba46de81b74d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Aug 2006 00:56:08 +0000 Subject: r17900: Fix from Michael Adam - make internal_resolve_name do what it's supposed to. Jeremy. (This used to be commit 4b7387a054bfc1587e0b9b7088f420a5bcf0bad9) --- source3/libsmb/namequery.c | 124 ++++++++++++++++++++++----------------------- 1 file changed, 62 insertions(+), 62 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 62f21d94c7..dcb7dbf070 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1172,86 +1172,86 @@ BOOL internal_resolve_name(const char *name, int name_type, pstrcpy(name_resolve_list, lp_name_resolve_order()); } else { pstrcpy(name_resolve_list, resolve_order); + } - if ( !name_resolve_list[0] ) { - ptr = "host"; - } else { - ptr = name_resolve_list; - } + if ( !name_resolve_list[0] ) { + ptr = "host"; + } else { + ptr = name_resolve_list; + } - /* iterate through the name resolution backends */ + /* iterate through the name resolution backends */ - while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { - if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (resolve_hosts(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "ads")) { - /* deal with 0x1c names here. This will result in a - SRV record lookup */ - if (resolve_ads(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "lmhosts")) { - if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "wins")) { - /* don't resolve 1D via WINS */ - if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else if(strequal( tok, "bcast")) { - if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { - result = True; - goto done; - } - } else { - DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); + while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { + if((strequal(tok, "host") || strequal(tok, "hosts"))) { + if (resolve_hosts(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "ads")) { + /* deal with 0x1c names here. This will result in a + SRV record lookup */ + if (resolve_ads(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "lmhosts")) { + if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { + result = True; + goto done; } + } else if(strequal( tok, "wins")) { + /* don't resolve 1D via WINS */ + if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else if(strequal( tok, "bcast")) { + if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { + result = True; + goto done; + } + } else { + DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); } + } - /* All of the resolve_* functions above have returned false. */ + /* All of the resolve_* functions above have returned false. */ - SAFE_FREE(*return_iplist); - *return_count = 0; + SAFE_FREE(*return_iplist); + *return_count = 0; - return False; + return False; done: - /* Remove duplicate entries. Some queries, notably #1c (domain - controllers) return the PDC in iplist[0] and then all domain - controllers including the PDC in iplist[1..n]. Iterating over - the iplist when the PDC is down will cause two sets of timeouts. */ + /* Remove duplicate entries. Some queries, notably #1c (domain + controllers) return the PDC in iplist[0] and then all domain + controllers including the PDC in iplist[1..n]. Iterating over + the iplist when the PDC is down will cause two sets of timeouts. */ - if ( *return_count ) { - *return_count = remove_duplicate_addrs2( *return_iplist, *return_count ); - } + if ( *return_count ) { + *return_count = remove_duplicate_addrs2( *return_iplist, *return_count ); + } - /* Save in name cache */ - if ( DEBUGLEVEL >= 100 ) { - for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) - DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name, - name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); - } + /* Save in name cache */ + if ( DEBUGLEVEL >= 100 ) { + for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) + DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name, + name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); + } - namecache_store(name, name_type, *return_count, *return_iplist); + namecache_store(name, name_type, *return_count, *return_iplist); - /* Display some debugging info */ + /* Display some debugging info */ - if ( DEBUGLEVEL >= 10 ) { - DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count)); + if ( DEBUGLEVEL >= 10 ) { + DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count)); - for (i = 0; i < *return_count; i++) { - DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); - } - DEBUG(10, ("\n")); + for (i = 0; i < *return_count; i++) { + DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); } + DEBUG(10, ("\n")); } return result; -- cgit From ed132d87ced2f9b09eb0b81ac1aa29b4a5e29eb8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Aug 2006 01:11:02 +0000 Subject: r17902: Fix possible null deref caught by Stanford checker. Jeremy. (This used to be commit e8b0649fe167c3446eb6121ed666254fdf53aa58) --- source3/libsmb/clifile.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index fb07dae427..3cf8cae320 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1613,7 +1613,9 @@ static BOOL cli_get_ea_list(struct cli_state *cli, struct ea_struct *ea_list; *pnum_eas = 0; - *pea_list = NULL; + if (pea_list) { + *pea_list = NULL; + } if (!cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -- cgit From 2abab7ee6d04a62017d99578c274244a1cdd27b2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Aug 2006 04:40:03 +0000 Subject: r17928: Implement the basic store for CLDAP sitename support when looking up DC's. On every CLDAP call store the returned client sitename (if present, delete store if not) in gencache with infinate timeout. On AD DNS DC lookup, try looking for sitename DC's first, only try generic if sitename DNS lookup failed. I still haven't figured out yet how to ensure we fetch the sitename with a CLDAP query before doing the generic DC list lookup. This code is difficult to understand. I'll do some experiments and backtraces tomorrow to try and work out where to force a CLDAP site query first. Jeremy. (This used to be commit ab3f0c5b1e9c5fd192c5514cbe9451b938f9cd5d) --- source3/libsmb/namequery.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index dcb7dbf070..4c361a3716 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -111,7 +111,6 @@ char *saf_fetch( const char *domain ) return server; } - /**************************************************************************** Generate a random trn_id. ****************************************************************************/ @@ -1044,6 +1043,7 @@ static BOOL resolve_ads(const char *name, int name_type, status = ads_dns_query_dcs( ctx, name, &dcs, &numdcs ); if ( !NT_STATUS_IS_OK( status ) ) { + talloc_destroy(ctx); return False; } @@ -1053,6 +1053,7 @@ static BOOL resolve_ads(const char *name, int name_type, if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, numaddrs)) == NULL ) { DEBUG(0,("resolve_ads: malloc failed for %d entries\n", numaddrs )); + talloc_destroy(ctx); return False; } @@ -1096,8 +1097,7 @@ static BOOL resolve_ads(const char *name, int name_type, (*return_count)++; } - TALLOC_FREE( dcs ); - + talloc_destroy(ctx); return True; } -- cgit From 7b7ce43b40888af7d2663e77d8a9e83c383c6b2d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Aug 2006 05:52:31 +0000 Subject: r17929: Ok, I think I finally figured out where to put the code to redo the CLDAP query to restrict DC DNS lookups to the sitename. Jerry, please check to stop me going insane :-). Jeremy. (This used to be commit 8d22cc111579c57aec65be8884b41564b79b133a) --- source3/libsmb/namequery_dc.c | 54 +++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 4afd04a98f..b4ea90fde0 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -26,34 +26,65 @@ #include "includes.h" /************************************************************************** - Find the name and IP address for a server in he realm/domain + Find the name and IP address for a server in the realm/domain *************************************************************************/ -static BOOL ads_dc_name(const char *domain, const char *realm, struct in_addr *dc_ip, fstring srv_name) +static BOOL ads_dc_name(const char *domain, + const char *realm, + struct in_addr *dc_ip, + fstring srv_name) { ADS_STRUCT *ads; + char *sitename = sitename_fetch(); + int i; if (!realm && strequal(domain, lp_workgroup())) realm = lp_realm(); - ads = ads_init(realm, domain, NULL); - if (!ads) - return False; + /* Try this 3 times then give up. */ + for( i =0 ; i < 3; i++) { + ads = ads_init(realm, domain, NULL); + if (!ads) { + SAFE_FREE(sitename); + return False; + } - DEBUG(4,("ads_dc_name: domain=%s\n", domain)); + DEBUG(4,("ads_dc_name: domain=%s\n", domain)); #ifdef HAVE_ADS - /* we don't need to bind, just connect */ - ads->auth.flags |= ADS_AUTH_NO_BIND; - - ads_connect(ads); + /* we don't need to bind, just connect */ + ads->auth.flags |= ADS_AUTH_NO_BIND; + ads_connect(ads); #endif - if (!ads->config.realm) { + if (!ads->config.realm) { + SAFE_FREE(sitename); + ads_destroy(&ads); + return False; + } + + /* Now we've found a server, see if our sitename + has changed. If so, we need to re-do the query + to ensure we only find servers in our site. */ + + if (!sitename_changed(sitename)) { + break; + } + + ads_destroy(&ads); + } + + + if (i == 3) { + DEBUG(1,("ads_dc_name: sitename (now %s) keeps changing ???\n", + sitename)); + SAFE_FREE(sitename); ads_destroy(&ads); return False; } + SAFE_FREE(sitename); + fstrcpy(srv_name, ads->config.ldap_server_name); strupper_m(srv_name); *dc_ip = ads->ldap_ip; @@ -157,4 +188,3 @@ BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct return ret; } - -- cgit From bc28b5c7008e5df45fbd6bf413d8177e8ba7c367 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Aug 2006 16:02:08 +0000 Subject: r17933: Don't print a NULL sitename. Jeremy. (This used to be commit 2829dbc3e01d967887e25d1bcacb1d538fc11e59) --- source3/libsmb/namequery_dc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index b4ea90fde0..ed71a9816a 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -76,8 +76,8 @@ static BOOL ads_dc_name(const char *domain, if (i == 3) { - DEBUG(1,("ads_dc_name: sitename (now %s) keeps changing ???\n", - sitename)); + DEBUG(1,("ads_dc_name: sitename (now \"%s\") keeps changing ???\n", + sitename ? sitename : "")); SAFE_FREE(sitename); ads_destroy(&ads); return False; -- cgit From 6fada7a82aa67e7b80ff003bd527092da68542c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 01:20:21 +0000 Subject: r17943: The horror, the horror. Add KDC site support by writing out a custom krb5.conf file containing the KDC I need. This may suck.... Needs some testing :-). Jeremy. (This used to be commit d500e1f96d92dfcc6292c448d1b399195f762d89) --- source3/libsmb/namequery_dc.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index ed71a9816a..4099cc9dd8 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -38,8 +38,9 @@ static BOOL ads_dc_name(const char *domain, char *sitename = sitename_fetch(); int i; - if (!realm && strequal(domain, lp_workgroup())) + if (!realm && strequal(domain, lp_workgroup())) { realm = lp_realm(); + } /* Try this 3 times then give up. */ for( i =0 ; i < 3; i++) { @@ -64,22 +65,34 @@ static BOOL ads_dc_name(const char *domain, } /* Now we've found a server, see if our sitename - has changed. If so, we need to re-do the query + has changed. If so, we need to re-do the DNS query to ensure we only find servers in our site. */ - if (!sitename_changed(sitename)) { - break; + if (sitename_changed(sitename)) { + SAFE_FREE(sitename); + sitename = sitename_fetch(); + ads_destroy(&ads); + continue; } - ads_destroy(&ads); - } +#ifdef HAVE_KRB5 + if ((ads->config.flags & ADS_KDC) && sitename) { + /* We're going to use this KDC for this realm/domain. + If we are using sites, then force the krb5 libs + to use this KDC. */ + create_local_private_krb5_conf_for_domain(realm, + domain, + ads->ldap_ip); + } +#endif + break; + } if (i == 3) { DEBUG(1,("ads_dc_name: sitename (now \"%s\") keeps changing ???\n", sitename ? sitename : "")); SAFE_FREE(sitename); - ads_destroy(&ads); return False; } -- cgit From 2fcd113f5507f643fcf80d5a9770ce72aa121ba8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 Aug 2006 04:14:08 +0000 Subject: r17945: Store the server and client sitenames in the ADS struct so we can see when they match - only create the ugly krb5 hack when they do. Jeremy. (This used to be commit 9be4ecf24b6b5dacf4c2891bddb072fa7543753f) --- source3/libsmb/namequery_dc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 4099cc9dd8..cf01fb269e 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -68,7 +68,7 @@ static BOOL ads_dc_name(const char *domain, has changed. If so, we need to re-do the DNS query to ensure we only find servers in our site. */ - if (sitename_changed(sitename)) { + if (stored_sitename_changed(sitename)) { SAFE_FREE(sitename); sitename = sitename_fetch(); ads_destroy(&ads); @@ -76,7 +76,7 @@ static BOOL ads_dc_name(const char *domain, } #ifdef HAVE_KRB5 - if ((ads->config.flags & ADS_KDC) && sitename) { + if ((ads->config.flags & ADS_KDC) && ads_sitename_match(ads)) { /* We're going to use this KDC for this realm/domain. If we are using sites, then force the krb5 libs to use this KDC. */ -- cgit From 1e5996387aa0ace20134b4b53e0663a158fffa32 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 31 Aug 2006 20:37:16 +0000 Subject: r17976: Fix typo (This used to be commit 410d6b9de2ad059fe239c6f155e80a81952ed701) --- source3/libsmb/ntlmssp_sign.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 10921d56e7..5642be42a3 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -307,7 +307,7 @@ NTSTATUS ntlmssp_unseal_packet(NTLMSSP_STATE *ntlmssp_state, return NT_STATUS_NO_USER_SESSION_KEY; } - DEBUG(10,("ntlmssp_unseal_data: seal\n")); + DEBUG(10,("ntlmssp_unseal_packet: seal\n")); dump_data_pw("ntlmssp sealed data\n", data, length); if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { -- cgit From 27e37eab987d0618c5dd19446369aad59a588dd6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 31 Aug 2006 20:45:29 +0000 Subject: r17977: To be honest, I have NO idea whatsoever what this does, but it fixes what I have been able to reproduce with smbtorture4 for bug number 4059. It's too late here now to check with W2k native, I'll do that tomorrow or over the weekend. I'll then also check in a samba4 torture test to walk this from now on. Abartlet, can you do me a favor and look over this? It is a 1:1 copy of the corresponding Samba4 code. Thanks, Volker (This used to be commit fb5ebab873ba5196f35a9801ab2e21811b0fa8a0) --- source3/libsmb/ntlmssp.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 70fcd24e76..6a44809f9e 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -816,13 +816,14 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); - dump_data_pw("LM session key:\n", session_key.data, session_key.length); } else { - /* use the key unmodified - it's - * probably a NULL key from the guest - * login */ - session_key = lm_session_key; + static const uint8 zeros[24] = { 0, }; + SMBsesskeygen_lm_sess_key( + lm_session_key.data, zeros, + session_key.data); } + dump_data_pw("LM session key:\n", session_key.data, + session_key.length); } else { DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); session_key = data_blob(NULL, 0); -- cgit From bd5fca847a33ddef7d73ad8c6932ee2f6685054a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Sep 2006 19:18:49 +0000 Subject: r18005: The ntlmssp fix is not correct yet, working on it (This used to be commit 3e4da5541c24b3c3c5104fc5120a9be8a2f9ae69) --- source3/libsmb/ntlmssp.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 6a44809f9e..70fcd24e76 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -816,14 +816,13 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); + dump_data_pw("LM session key:\n", session_key.data, session_key.length); } else { - static const uint8 zeros[24] = { 0, }; - SMBsesskeygen_lm_sess_key( - lm_session_key.data, zeros, - session_key.data); + /* use the key unmodified - it's + * probably a NULL key from the guest + * login */ + session_key = lm_session_key; } - dump_data_pw("LM session key:\n", session_key.data, - session_key.length); } else { DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); session_key = data_blob(NULL, 0); -- cgit From 0f1bc28744d8c7cae2fe2774b50fc4336408a74d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 19:27:44 +0000 Subject: r18006: Actually a smaller change than it looks. Leverage the get_dc_list code to get the _kerberos. names for site support. This way we don't depend on one KDC to do ticket refresh. Even though we know it's up when we add it, it may go down when we're trying to refresh. Jeremy. (This used to be commit 77fe2a3d7418012a8dbfb6aaeb2a8dd57c6e1a5d) --- source3/libsmb/namecache.c | 8 ++++++ source3/libsmb/namequery.c | 65 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 66 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index ec8a1900d8..afbd807198 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -126,6 +126,10 @@ BOOL namecache_store(const char *name, int name_type, */ if (!gencache_init()) return False; + if (name_type > 255) { + return False; /* Don't store non-real name types. */ + } + if ( DEBUGLEVEL >= 5 ) { DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", num_names, num_names == 1 ? "": "es", name, name_type)); @@ -184,6 +188,10 @@ BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis if (!gencache_init()) return False; + if (name_type > 255) { + return False; /* Don't fetch non-real name types. */ + } + *num_names = 0; /* diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 4c361a3716..af3ac319cc 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1030,7 +1030,7 @@ static BOOL resolve_ads(const char *name, int name_type, int numdcs = 0; int numaddrs = 0; - if ( name_type != 0x1c ) + if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE)) return False; DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n", @@ -1040,8 +1040,12 @@ static BOOL resolve_ads(const char *name, int name_type, DEBUG(0,("resolve_ads: talloc_init() failed!\n")); return False; } - - status = ads_dns_query_dcs( ctx, name, &dcs, &numdcs ); + + if (name_type == KDC_NAME_TYPE) { + status = ads_dns_query_kdcs(ctx, name, &dcs, &numdcs); + } else { + status = ads_dns_query_dcs(ctx, name, &dcs, &numdcs); + } if ( !NT_STATUS_IS_OK( status ) ) { talloc_destroy(ctx); return False; @@ -1188,6 +1192,13 @@ BOOL internal_resolve_name(const char *name, int name_type, result = True; goto done; } + } else if(strequal( tok, "kdc")) { + /* deal with KDC_NAME_TYPE names here. This will result in a + SRV record lookup */ + if (resolve_ads(name, KDC_NAME_TYPE, return_iplist, return_count)) { + result = True; + goto done; + } } else if(strequal( tok, "ads")) { /* deal with 0x1c names here. This will result in a SRV record lookup */ @@ -1355,13 +1366,17 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) return True; } +/* Private enum type for lookups. */ + +enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY }; + /******************************************************** Get the IP address list of the domain controllers for a domain. *********************************************************/ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, - int *count, BOOL ads_only, int *ordered) + int *count, enum dc_lookup_type lookup_type, int *ordered) { fstring resolve_order; char *saf_servername; @@ -1387,7 +1402,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, fstrcpy( resolve_order, lp_name_resolve_order() ); strlower_m( resolve_order ); - if ( ads_only ) { + if ( lookup_type == DC_ADS_ONLY) { if ( strstr( resolve_order, "host" ) ) { fstrcpy( resolve_order, "ads" ); @@ -1397,6 +1412,11 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, } else { fstrcpy( resolve_order, "NULL" ); } + } else if (lookup_type == DC_KDC_ONLY) { + /* DNS SRV lookups used by the ads/kdc resolver + are already sorted by priority and weight */ + *ordered = True; + fstrcpy( resolve_order, "kdc" ); } /* fetch the server we have affinity for. Add the @@ -1558,11 +1578,16 @@ NTSTATUS get_sorted_dc_list( const char *domain, struct ip_service **ip_list, in { BOOL ordered; NTSTATUS status; - + enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP; + DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", (ads_only ? "ads" : lp_name_resolve_order()))); - status = get_dc_list(domain, ip_list, count, ads_only, &ordered); + if (ads_only) { + lookup_type = DC_ADS_ONLY; + } + + status = get_dc_list(domain, ip_list, count, lookup_type, &ordered); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1574,3 +1599,29 @@ NTSTATUS get_sorted_dc_list( const char *domain, struct ip_service **ip_list, in return NT_STATUS_OK; } + +/********************************************************************* + Get the KDC list - re-use all the logic in get_dc_list. +*********************************************************************/ + +NTSTATUS get_kdc_list( const char *realm, struct ip_service **ip_list, int *count) +{ + BOOL ordered; + NTSTATUS status; + + *count = 0; + *ip_list = NULL; + + status = get_dc_list(realm, ip_list, count, DC_KDC_ONLY, &ordered); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* only sort if we don't already have an ordered list */ + if ( !ordered ) { + sort_ip_list2( *ip_list, *count ); + } + + return NT_STATUS_OK; +} -- cgit From 380c4183ee765c01c9ad3054764437434ee6c61f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Sep 2006 20:17:05 +0000 Subject: r18007: Ensure we don't namecache KDC entries with port 88 as a generic DC (that should be the LDAP port). Jeremy. (This used to be commit f16b41c3c92b1af5cf25d8d244b1f551573cb076) --- source3/libsmb/namequery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index af3ac319cc..5cd09fd04f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1197,6 +1197,8 @@ BOOL internal_resolve_name(const char *name, int name_type, SRV record lookup */ if (resolve_ads(name, KDC_NAME_TYPE, return_iplist, return_count)) { result = True; + /* Ensure we don't namecache this with the KDC port. */ + name_type = KDC_NAME_TYPE; goto done; } } else if(strequal( tok, "ads")) { -- cgit From b7a5e3de1eac86bd460aed341ec17a01f4b82e5f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Sep 2006 21:41:28 +0000 Subject: r18008: Ok, same fix as before. But this time also allocate the session key. This had worked in one test, no idea what memory I've overwritten that time. This time it survives the unpatched w2k password change. Volker (This used to be commit bf7bf8e4e9a279fe3ef1e9ff655b12f65c3c3e67) --- source3/libsmb/ntlmssp.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 70fcd24e76..d017bdb76c 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -813,16 +813,25 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, if (lm_session_key.data && lm_session_key.length >= 8) { if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) { session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16); + if (session_key.data == NULL) { + return NT_STATUS_NO_MEMORY; + } SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data, session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); - dump_data_pw("LM session key:\n", session_key.data, session_key.length); } else { - /* use the key unmodified - it's - * probably a NULL key from the guest - * login */ - session_key = lm_session_key; + static const uint8 zeros[24] = { 0, }; + session_key = data_blob_talloc( + ntlmssp_state->mem_ctx, NULL, 16); + if (session_key.data == NULL) { + return NT_STATUS_NO_MEMORY; + } + SMBsesskeygen_lm_sess_key( + lm_session_key.data, zeros, + session_key.data); } + dump_data_pw("LM session key:\n", session_key.data, + session_key.length); } else { DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); session_key = data_blob(NULL, 0); -- cgit From 5e44fc4cd47108245c567b9e676a5d8c09787d96 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 2 Sep 2006 21:47:56 +0000 Subject: r18009: Fixes bug 4026. This completes the work Jeremy began last week, disambiguating the meaning of c_time. (In POSIX terminology, c_time means "status Change time", not "create time".) All uses of c_time, a_time and m_time have now been replaced with change_time, access_time, and write_time, and when creation time is intended, create_time is used. Additionally, the capability of setting and retrieving the create time have been added to the smbc_setxattr() and smbc_getxattr() functions. An example of setting all four times can be seen with the program examples/libsmbclient/testacl with the following command line similar to: testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt' The -f option turns on the new mode which uses full time names in the attribute specification (e.g. ACCESS_TIME vs A_TIME). (This used to be commit 8e119b64f1d92026dda855d904be09912a40601c) --- source3/libsmb/clifile.c | 32 ++- source3/libsmb/clirap.c | 44 ++-- source3/libsmb/libsmbclient.c | 576 ++++++++++++++++++++++++++++++------------ 3 files changed, 465 insertions(+), 187 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 3cf8cae320..ad84ec0324 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1179,7 +1179,9 @@ BOOL cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, S BOOL cli_getattrE(struct cli_state *cli, int fd, uint16 *attr, SMB_OFF_T *size, - time_t *c_time, time_t *a_time, time_t *m_time) + time_t *change_time, + time_t *access_time, + time_t *write_time) { memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -1209,16 +1211,16 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, *attr = SVAL(cli->inbuf,smb_vwv10); } - if (c_time) { - *c_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv0); + if (change_time) { + *change_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv0); } - if (a_time) { - *a_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv2); + if (access_time) { + *access_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv2); } - if (m_time) { - *m_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv4); + if (write_time) { + *write_time = cli_make_unix_date2(cli, cli->inbuf+smb_vwv4); } return True; @@ -1229,7 +1231,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, ****************************************************************************/ BOOL cli_getatr(struct cli_state *cli, const char *fname, - uint16 *attr, SMB_OFF_T *size, time_t *t) + uint16 *attr, SMB_OFF_T *size, time_t *write_time) { char *p; @@ -1261,8 +1263,8 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, *size = IVAL(cli->inbuf, smb_vwv3); } - if (t) { - *t = cli_make_unix_date3(cli, cli->inbuf+smb_vwv1); + if (write_time) { + *write_time = cli_make_unix_date3(cli, cli->inbuf+smb_vwv1); } if (attr) { @@ -1278,7 +1280,9 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, ****************************************************************************/ BOOL cli_setattrE(struct cli_state *cli, int fd, - time_t c_time, time_t a_time, time_t m_time) + time_t change_time, + time_t access_time, + time_t write_time) { char *p; @@ -1293,9 +1297,9 @@ BOOL cli_setattrE(struct cli_state *cli, int fd, cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0, fd); - cli_put_dos_date2(cli, cli->outbuf,smb_vwv1, c_time); - cli_put_dos_date2(cli, cli->outbuf,smb_vwv3, a_time); - cli_put_dos_date2(cli, cli->outbuf,smb_vwv5, m_time); + cli_put_dos_date2(cli, cli->outbuf,smb_vwv1, change_time); + cli_put_dos_date2(cli, cli->outbuf,smb_vwv3, access_time); + cli_put_dos_date2(cli, cli->outbuf,smb_vwv5, write_time); p = smb_buf(cli->outbuf); *p++ = 4; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 677c8f1fc3..caa23b59d9 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -379,7 +379,9 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char send a qpathinfo call ****************************************************************************/ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *c_time, time_t *a_time, time_t *m_time, + time_t *change_time, + time_t *access_time, + time_t *write_time, SMB_OFF_T *size, uint16 *mode) { unsigned int data_len = 0; @@ -434,14 +436,14 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, date_fn = cli_make_unix_date2; } - if (c_time) { - *c_time = date_fn(cli, rdata+0); + if (change_time) { + *change_time = date_fn(cli, rdata+0); } - if (a_time) { - *a_time = date_fn(cli, rdata+4); + if (access_time) { + *access_time = date_fn(cli, rdata+4); } - if (m_time) { - *m_time = date_fn(cli, rdata+8); + if (write_time) { + *write_time = date_fn(cli, rdata+8); } if (size) { *size = IVAL(rdata, 12); @@ -460,7 +462,11 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, send a setpathinfo call ****************************************************************************/ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, - time_t c_time, time_t a_time, time_t m_time, uint16 mode) + time_t create_time, + time_t access_time, + time_t write_time, + time_t change_time, + uint16 mode) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -495,16 +501,16 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, * Add the create, last access, modification, and status change times */ - /* Don't set create time, at offset 0 */ + put_long_date(p, create_time); p += 8; - put_long_date(p, a_time); + put_long_date(p, access_time); p += 8; - put_long_date(p, m_time); + put_long_date(p, write_time); p += 8; - put_long_date(p, c_time); + put_long_date(p, change_time); p += 8; /* Add attributes */ @@ -555,8 +561,11 @@ send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, - struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, - struct timespec *change_time, SMB_OFF_T *size, uint16 *mode, + struct timespec *create_time, + struct timespec *access_time, + struct timespec *write_time, + struct timespec *change_time, + SMB_OFF_T *size, uint16 *mode, SMB_INO_T *ino) { unsigned int data_len = 0; @@ -670,8 +679,11 @@ send a qfileinfo call ****************************************************************************/ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, uint16 *mode, SMB_OFF_T *size, - struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, - struct timespec *change_time, SMB_INO_T *ino) + struct timespec *create_time, + struct timespec *access_time, + struct timespec *write_time, + struct timespec *change_time, + SMB_INO_T *ino) { unsigned int data_len = 0; unsigned int param_len = 0; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2656bd0f04..c74e18b13c 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -33,9 +33,10 @@ typedef struct DOS_ATTR_DESC { int mode; SMB_OFF_T size; - time_t a_time; - time_t c_time; - time_t m_time; + time_t create_time; + time_t access_time; + time_t write_time; + time_t change_time; SMB_INO_T inode; } DOS_ATTR_DESC; @@ -1470,15 +1471,16 @@ smbc_getatr(SMBCCTX * context, char *path, uint16 *mode, SMB_OFF_T *size, - struct timespec *c_time_ts, - struct timespec *a_time_ts, - struct timespec *m_time_ts, + struct timespec *create_time_ts, + struct timespec *access_time_ts, + struct timespec *write_time_ts, + struct timespec *change_time_ts, SMB_INO_T *ino) { pstring fixedpath; pstring targetpath; struct cli_state *targetcli; - time_t m_time; + time_t write_time; if (!context || !context->internal || !context->internal->_initialized) { @@ -1515,7 +1517,11 @@ smbc_getatr(SMBCCTX * context, if (!srv->no_pathinfo2 && cli_qpathinfo2(targetcli, targetpath, - NULL, a_time_ts, m_time_ts, c_time_ts, size, mode, ino)) { + create_time_ts, + access_time_ts, + write_time_ts, + change_time_ts, + size, mode, ino)) { return True; } @@ -1525,12 +1531,28 @@ smbc_getatr(SMBCCTX * context, return False; } - if (cli_getatr(targetcli, targetpath, mode, size, &m_time)) { - if (m_time_ts != NULL) { - *m_time_ts = convert_time_t_to_timespec(m_time); - if (a_time_ts != NULL) *a_time_ts = *m_time_ts; - if (c_time_ts != NULL) *c_time_ts = *m_time_ts; + if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { + + struct timespec w_time_ts; + + w_time_ts = convert_time_t_to_timespec(write_time); + + if (write_time_ts != NULL) { + *write_time_ts = w_time_ts; + } + + if (create_time_ts != NULL) { + *create_time_ts = w_time_ts; + } + + if (access_time_ts != NULL) { + *access_time_ts = w_time_ts; } + + if (change_time_ts != NULL) { + *change_time_ts = w_time_ts; + } + srv->no_pathinfo2 = True; return True; } @@ -1552,7 +1574,10 @@ smbc_getatr(SMBCCTX * context, */ static BOOL smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, - time_t c_time, time_t a_time, time_t m_time, + time_t create_time, + time_t access_time, + time_t write_time, + time_t change_time, uint16 mode) { int fd; @@ -1565,7 +1590,12 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * attributes manipulated. */ if (srv->no_pathinfo || - ! cli_setpathinfo(srv->cli, path, c_time, a_time, m_time, mode)) { + ! cli_setpathinfo(srv->cli, path, + create_time, + access_time, + write_time, + change_time, + mode)) { /* * setpathinfo is not supported; go to plan B. @@ -1587,42 +1617,14 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, return -1; } - /* - * Get the creat time of the file (if it wasn't provided). - * We'll need it in the set call - */ - if (c_time == 0) { - ret = cli_getattrE(srv->cli, fd, - NULL, NULL, - &c_time, NULL, NULL); - } else { - ret = True; - } - - /* If we got create time, set times */ - if (ret) { - /* Some OS versions don't support create time */ - if (c_time == 0 || c_time == -1) { - c_time = time(NULL); - } + /* Set the new attributes */ + ret = cli_setattrE(srv->cli, fd, + change_time, + access_time, + write_time); - /* - * For sanity sake, since there is no POSIX function - * to set the create time of a file, if the existing - * create time is greater than either of access time - * or modification time, set create time to the - * smallest of those. This ensure that the create - * time of a file is never greater than its last - * access or modification time. - */ - if (c_time > a_time) c_time = a_time; - if (c_time > m_time) c_time = m_time; - - /* Set the new attributes */ - ret = cli_setattrE(srv->cli, fd, - c_time, a_time, m_time); - cli_close(srv->cli, fd); - } + /* Close the file */ + cli_close(srv->cli, fd); /* * Unfortunately, setattrE() doesn't have a provision for @@ -1711,11 +1713,17 @@ smbc_unlink_ctx(SMBCCTX *context, int saverr = errno; SMB_OFF_T size = 0; uint16 mode = 0; - struct timespec m_time_ts, a_time_ts, c_time_ts; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; SMB_INO_T ino = 0; if (!smbc_getatr(context, srv, path, &mode, &size, - &c_time_ts, &a_time_ts, &m_time_ts, &ino)) { + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { /* Hmmm, bad error ... What? */ @@ -2051,9 +2059,9 @@ smbc_stat_ctx(SMBCCTX *context, fstring password; fstring workgroup; pstring path; - struct timespec m_time_ts; - struct timespec a_time_ts; - struct timespec c_time_ts; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; @@ -2097,7 +2105,11 @@ smbc_stat_ctx(SMBCCTX *context, } if (!smbc_getatr(context, srv, path, &mode, &size, - &c_time_ts, &a_time_ts, &m_time_ts, &ino)) { + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { errno = smbc_errno(context, srv->cli); return -1; @@ -2108,9 +2120,9 @@ smbc_stat_ctx(SMBCCTX *context, smbc_setup_stat(context, st, path, size, mode); - set_atimespec(st, a_time_ts); - set_ctimespec(st, c_time_ts); - set_mtimespec(st, m_time_ts); + set_atimespec(st, access_time_ts); + set_ctimespec(st, change_time_ts); + set_mtimespec(st, write_time_ts); st->st_dev = srv->dev; return 0; @@ -2126,9 +2138,9 @@ smbc_fstat_ctx(SMBCCTX *context, SMBCFILE *file, struct stat *st) { - struct timespec c_time_ts; - struct timespec a_time_ts; - struct timespec m_time_ts; + struct timespec change_time_ts; + struct timespec access_time_ts; + struct timespec write_time_ts; SMB_OFF_T size; uint16 mode; fstring server; @@ -2184,26 +2196,33 @@ smbc_fstat_ctx(SMBCCTX *context, /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, - NULL, &a_time_ts, &m_time_ts, &c_time_ts, &ino)) { - time_t c_time, a_time, m_time; + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + + time_t change_time, access_time, write_time; + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, - &c_time, &a_time, &m_time)) { + &change_time, &access_time, &write_time)) { errno = EINVAL; return -1; } - c_time_ts = convert_time_t_to_timespec(c_time); - a_time_ts = convert_time_t_to_timespec(a_time); - m_time_ts = convert_time_t_to_timespec(m_time); + + change_time_ts = convert_time_t_to_timespec(change_time); + access_time_ts = convert_time_t_to_timespec(access_time); + write_time_ts = convert_time_t_to_timespec(write_time); } st->st_ino = ino; smbc_setup_stat(context, st, file->fname, size, mode); - set_atimespec(st, a_time_ts); - set_ctimespec(st, c_time_ts); - set_mtimespec(st, m_time_ts); + set_atimespec(st, access_time_ts); + set_ctimespec(st, change_time_ts); + set_mtimespec(st, write_time_ts); st->st_dev = file->srv->dev; return 0; @@ -2902,7 +2921,7 @@ smbc_opendir_ctx(SMBCCTX *context, if (smbc_getatr(context, srv, path, &mode, NULL, - NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL) && ! IS_DOS_DIR(mode)) { @@ -3592,8 +3611,8 @@ smbc_utimes_ctx(SMBCCTX *context, fstring password; fstring workgroup; pstring path; - time_t a_time; - time_t m_time; + time_t access_time; + time_t write_time; if (!context || !context->internal || !context->internal->_initialized) { @@ -3611,10 +3630,10 @@ smbc_utimes_ctx(SMBCCTX *context, } if (tbuf == NULL) { - a_time = m_time = time(NULL); + access_time = write_time = time(NULL); } else { - a_time = tbuf[0].tv_sec; - m_time = tbuf[1].tv_sec; + access_time = tbuf[0].tv_sec; + write_time = tbuf[1].tv_sec; } if (DEBUGLVL(4)) @@ -3623,13 +3642,13 @@ smbc_utimes_ctx(SMBCCTX *context, char atimebuf[32]; char mtimebuf[32]; - strncpy(atimebuf, ctime(&a_time), sizeof(atimebuf) - 1); + strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1); atimebuf[sizeof(atimebuf) - 1] = '\0'; if ((p = strchr(atimebuf, '\n')) != NULL) { *p = '\0'; } - strncpy(mtimebuf, ctime(&m_time), sizeof(mtimebuf) - 1); + strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1); mtimebuf[sizeof(mtimebuf) - 1] = '\0'; if ((p = strchr(mtimebuf, '\n')) != NULL) { *p = '\0'; @@ -3660,7 +3679,8 @@ smbc_utimes_ctx(SMBCCTX *context, return -1; /* errno set by smbc_server */ } - if (!smbc_setatr(context, srv, path, 0, a_time, m_time, 0)) { + if (!smbc_setatr(context, srv, path, + 0, access_time, write_time, 0, 0)) { return -1; /* errno set by smbc_setatr */ } @@ -4085,7 +4105,10 @@ dos_attr_query(SMBCCTX *context, const char *filename, SMBCSRV *srv) { - struct timespec m_time_ts, a_time_ts, c_time_ts; + struct timespec create_time_ts; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T inode = 0; @@ -4100,7 +4123,11 @@ dos_attr_query(SMBCCTX *context, /* Obtain the DOS attributes */ if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename), &mode, &size, - &c_time_ts, &a_time_ts, &m_time_ts, &inode)) { + &create_time_ts, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &inode)) { errno = smbc_errno(context, srv->cli); DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); @@ -4110,9 +4137,10 @@ dos_attr_query(SMBCCTX *context, ret->mode = mode; ret->size = size; - ret->a_time = convert_timespec_to_time_t(a_time_ts); - ret->c_time = convert_timespec_to_time_t(c_time_ts); - ret->m_time = convert_timespec_to_time_t(m_time_ts); + ret->create_time = convert_timespec_to_time_t(create_time_ts); + ret->access_time = convert_timespec_to_time_t(access_time_ts); + ret->write_time = convert_timespec_to_time_t(write_time_ts); + ret->change_time = convert_timespec_to_time_t(change_time_ts); ret->inode = inode; return ret; @@ -4126,8 +4154,40 @@ dos_attr_parse(SMBCCTX *context, SMBCSRV *srv, char *str) { - const char *p = str; + int n; + const char *p = str; fstring tok; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + + /* Determine whether to use old-style or new-style attribute names */ + if (context->internal->_full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "CREATE_TIME"; + attr_strings.access_time_attr = "ACCESS_TIME"; + attr_strings.write_time_attr = "WRITE_TIME"; + attr_strings.change_time_attr = "CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "A_TIME"; + attr_strings.write_time_attr = "M_TIME"; + attr_strings.change_time_attr = "C_TIME"; + } + + /* if this is to set the entire ACL... */ + if (*str == '*') { + /* ... then increment past the first colon if there is one */ + if ((p = strchr(str, ':')) != NULL) { + ++p; + } else { + p = str; + } + } while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) { @@ -4141,18 +4201,28 @@ dos_attr_parse(SMBCCTX *context, continue; } - if (StrnCaseCmp(tok, "A_TIME:", 7) == 0) { - dad->a_time = (time_t)strtol(tok+7, NULL, 10); + n = strlen(attr_strings.access_time_attr); + if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { + dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } - if (StrnCaseCmp(tok, "C_TIME:", 7) == 0) { - dad->c_time = (time_t)strtol(tok+7, NULL, 10); + n = strlen(attr_strings.change_time_attr); + if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { + dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } - if (StrnCaseCmp(tok, "M_TIME:", 7) == 0) { - dad->m_time = (time_t)strtol(tok+7, NULL, 10); + n = strlen(attr_strings.write_time_attr); + if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { + dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); + continue; + } + + n = strlen(attr_strings.create_time_attr); + if (attr_strings.create_time_attr != NULL && + StrnCaseCmp(tok, attr_strings.create_time_attr, n) == 0) { + dad->create_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } @@ -4193,9 +4263,10 @@ cacl_get(SMBCCTX *context, BOOL exclude_nt_acl = False; BOOL exclude_dos_mode = False; BOOL exclude_dos_size = False; - BOOL exclude_dos_ctime = False; - BOOL exclude_dos_atime = False; - BOOL exclude_dos_mtime = False; + BOOL exclude_dos_create_time = False; + BOOL exclude_dos_access_time = False; + BOOL exclude_dos_write_time = False; + BOOL exclude_dos_change_time = False; BOOL exclude_dos_inode = False; BOOL numeric = True; BOOL determine_size = (bufsize == 0); @@ -4206,12 +4277,55 @@ cacl_get(SMBCCTX *context, char *name; char *pExclude; char *p; - struct timespec m_time_ts, a_time_ts, c_time_ts; - time_t m_time = (time_t)0, a_time = (time_t)0, c_time = (time_t)0; + struct timespec create_time_ts; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + time_t create_time = (time_t)0; + time_t write_time = (time_t)0; + time_t access_time = (time_t)0; + time_t change_time = (time_t)0; SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; struct cli_state *cli = srv->cli; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } excl_attr_strings; + + /* Determine whether to use old-style or new-style attribute names */ + if (context->internal->_full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "CREATE_TIME"; + attr_strings.access_time_attr = "ACCESS_TIME"; + attr_strings.write_time_attr = "WRITE_TIME"; + attr_strings.change_time_attr = "CHANGE_TIME"; + + excl_attr_strings.create_time_attr = "CREATE_TIME"; + excl_attr_strings.access_time_attr = "ACCESS_TIME"; + excl_attr_strings.write_time_attr = "WRITE_TIME"; + excl_attr_strings.change_time_attr = "CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "A_TIME"; + attr_strings.write_time_attr = "M_TIME"; + attr_strings.change_time_attr = "C_TIME"; + + excl_attr_strings.create_time_attr = NULL; + excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; + excl_attr_strings.write_time_attr = "dos_attr.M_TIME"; + excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; + } /* Copy name so we can strip off exclusions (if any are specified) */ strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); @@ -4269,14 +4383,22 @@ cacl_get(SMBCCTX *context, else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) { exclude_dos_size = True; } - else if (StrCaseCmp(pExclude, "dos_attr.c_time") == 0) { - exclude_dos_ctime = True; + else if (excl_attr_strings.create_time_attr != NULL && + StrCaseCmp(pExclude, + excl_attr_strings.change_time_attr) == 0) { + exclude_dos_create_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.access_time_attr) == 0) { + exclude_dos_access_time = True; } - else if (StrCaseCmp(pExclude, "dos_attr.a_time") == 0) { - exclude_dos_atime = True; + else if (StrCaseCmp(pExclude, + excl_attr_strings.write_time_attr) == 0) { + exclude_dos_write_time = True; } - else if (StrCaseCmp(pExclude, "dos_attr.m_time") == 0) { - exclude_dos_mtime = True; + else if (StrCaseCmp(pExclude, + excl_attr_strings.change_time_attr) == 0) { + exclude_dos_change_time = True; } else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { exclude_dos_inode = True; @@ -4554,15 +4676,21 @@ cacl_get(SMBCCTX *context, /* Obtain the DOS attributes */ if (!smbc_getatr(context, srv, filename, &mode, &size, - &c_time_ts, &a_time_ts, &m_time_ts, &ino)) { + &create_time_ts, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { errno = smbc_errno(context, srv->cli); return -1; } - c_time = convert_timespec_to_time_t(c_time_ts); - a_time = convert_timespec_to_time_t(a_time_ts); - m_time = convert_timespec_to_time_t(m_time_ts); + + create_time = convert_timespec_to_time_t(create_time_ts); + access_time = convert_timespec_to_time_t(access_time_ts); + write_time = convert_timespec_to_time_t(write_time_ts); + change_time = convert_timespec_to_time_t(change_time_ts); if (! exclude_dos_mode) { if (all || all_dos) { @@ -4655,12 +4783,55 @@ cacl_get(SMBCCTX *context, bufsize -= n; } - if (! exclude_dos_ctime) { + if (! exclude_dos_create_time && + attr_strings.create_time_attr != NULL) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.create_time_attr, + create_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.create_time_attr, + create_time); + } + } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", create_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", create_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + } + + if (! exclude_dos_access_time) { if (all || all_dos) { if (determine_size) { p = talloc_asprintf(ctx, - ",C_TIME:%lu", - c_time); + ",%s:%lu", + attr_strings.access_time_attr, + access_time); if (!p) { errno = ENOMEM; return -1; @@ -4668,11 +4839,13 @@ cacl_get(SMBCCTX *context, n = strlen(p); } else { n = snprintf(buf, bufsize, - ",C_TIME:%lu", c_time); + ",%s:%lu", + attr_strings.access_time_attr, + access_time); } - } else if (StrCaseCmp(name, "c_time") == 0) { + } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { if (determine_size) { - p = talloc_asprintf(ctx, "%lu", c_time); + p = talloc_asprintf(ctx, "%lu", access_time); if (!p) { errno = ENOMEM; return -1; @@ -4680,7 +4853,7 @@ cacl_get(SMBCCTX *context, n = strlen(p); } else { n = snprintf(buf, bufsize, - "%lu", c_time); + "%lu", access_time); } } @@ -4693,12 +4866,13 @@ cacl_get(SMBCCTX *context, bufsize -= n; } - if (! exclude_dos_atime) { + if (! exclude_dos_write_time) { if (all || all_dos) { if (determine_size) { p = talloc_asprintf(ctx, - ",A_TIME:%lu", - a_time); + ",%s:%lu", + attr_strings.write_time_attr, + write_time); if (!p) { errno = ENOMEM; return -1; @@ -4706,11 +4880,13 @@ cacl_get(SMBCCTX *context, n = strlen(p); } else { n = snprintf(buf, bufsize, - ",A_TIME:%lu", a_time); + ",%s:%lu", + attr_strings.write_time_attr, + write_time); } - } else if (StrCaseCmp(name, "a_time") == 0) { + } else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) { if (determine_size) { - p = talloc_asprintf(ctx, "%lu", a_time); + p = talloc_asprintf(ctx, "%lu", write_time); if (!p) { errno = ENOMEM; return -1; @@ -4718,7 +4894,7 @@ cacl_get(SMBCCTX *context, n = strlen(p); } else { n = snprintf(buf, bufsize, - "%lu", a_time); + "%lu", write_time); } } @@ -4731,12 +4907,13 @@ cacl_get(SMBCCTX *context, bufsize -= n; } - if (! exclude_dos_mtime) { + if (! exclude_dos_change_time) { if (all || all_dos) { if (determine_size) { p = talloc_asprintf(ctx, - ",M_TIME:%lu", - m_time); + ",%s:%lu", + attr_strings.change_time_attr, + change_time); if (!p) { errno = ENOMEM; return -1; @@ -4744,11 +4921,13 @@ cacl_get(SMBCCTX *context, n = strlen(p); } else { n = snprintf(buf, bufsize, - ",M_TIME:%lu", m_time); + ",%s:%lu", + attr_strings.change_time_attr, + change_time); } - } else if (StrCaseCmp(name, "m_time") == 0) { + } else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) { if (determine_size) { - p = talloc_asprintf(ctx, "%lu", m_time); + p = talloc_asprintf(ctx, "%lu", change_time); if (!p) { errno = ENOMEM; return -1; @@ -4756,7 +4935,7 @@ cacl_get(SMBCCTX *context, n = strlen(p); } else { n = snprintf(buf, bufsize, - "%lu", m_time); + "%lu", change_time); } } @@ -5046,6 +5225,12 @@ smbc_setxattr_ctx(SMBCCTX *context, TALLOC_CTX *ctx; POLICY_HND pol; DOS_ATTR_DESC *dad; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; if (!context || !context->internal || !context->internal->_initialized) { @@ -5135,9 +5320,10 @@ smbc_setxattr_ctx(SMBCCTX *context, /* Set the new DOS attributes */ if (! smbc_setatr(context, srv, path, - dad->c_time, - dad->a_time, - dad->m_time, + dad->create_time, + dad->access_time, + dad->write_time, + dad->change_time, dad->mode)) { /* cause failure if NT failed too */ @@ -5245,14 +5431,31 @@ smbc_setxattr_ctx(SMBCCTX *context, return ret; } + /* Determine whether to use old-style or new-style attribute names */ + if (context->internal->_full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; + attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; + attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; + attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "system.dos_attr.A_TIME"; + attr_strings.write_time_attr = "system.dos_attr.M_TIME"; + attr_strings.change_time_attr = "system.dos_attr.C_TIME"; + } + /* * Are they asking to set a DOS attribute? */ if (StrCaseCmp(name, "system.dos_attr.*") == 0 || StrCaseCmp(name, "system.dos_attr.mode") == 0 || - StrCaseCmp(name, "system.dos_attr.c_time") == 0 || - StrCaseCmp(name, "system.dos_attr.a_time") == 0 || - StrCaseCmp(name, "system.dos_attr.m_time") == 0) { + (attr_strings.create_time_attr != NULL && + StrCaseCmp(name, attr_strings.create_time_attr) == 0) || + StrCaseCmp(name, attr_strings.access_time_attr) == 0 || + StrCaseCmp(name, attr_strings.write_time_attr) == 0 || + StrCaseCmp(name, attr_strings.change_time_attr) == 0) { /* get a DOS Attribute Descriptor with current attributes */ dad = dos_attr_query(context, ctx, path, srv); @@ -5269,9 +5472,10 @@ smbc_setxattr_ctx(SMBCCTX *context, /* Set the new DOS attributes */ ret2 = smbc_setatr(context, srv, path, - dad->c_time, - dad->a_time, - dad->m_time, + dad->create_time, + dad->access_time, + dad->write_time, + dad->change_time, dad->mode); /* ret2 has True (success) / False (failure) */ @@ -5313,6 +5517,12 @@ smbc_getxattr_ctx(SMBCCTX *context, pstring path; TALLOC_CTX *ctx; POLICY_HND pol; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; if (!context || !context->internal || @@ -5369,6 +5579,21 @@ smbc_getxattr_ctx(SMBCCTX *context, return -1; } + /* Determine whether to use old-style or new-style attribute names */ + if (context->internal->_full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; + attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; + attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; + attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "system.dos_attr.A_TIME"; + attr_strings.write_time_attr = "system.dos_attr.M_TIME"; + attr_strings.change_time_attr = "system.dos_attr.C_TIME"; + } + /* Are they requesting a supported attribute? */ if (StrCaseCmp(name, "system.*") == 0 || StrnCaseCmp(name, "system.*!", 9) == 0 || @@ -5389,9 +5614,11 @@ smbc_getxattr_ctx(SMBCCTX *context, StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 || StrCaseCmp(name, "system.dos_attr.mode") == 0 || StrCaseCmp(name, "system.dos_attr.size") == 0 || - StrCaseCmp(name, "system.dos_attr.c_time") == 0 || - StrCaseCmp(name, "system.dos_attr.a_time") == 0 || - StrCaseCmp(name, "system.dos_attr.m_time") == 0 || + (attr_strings.create_time_attr != NULL && + StrCaseCmp(name, attr_strings.create_time_attr) == 0) || + StrCaseCmp(name, attr_strings.access_time_attr) == 0 || + StrCaseCmp(name, attr_strings.write_time_attr) == 0 || + StrCaseCmp(name, attr_strings.change_time_attr) == 0 || StrCaseCmp(name, "system.dos_attr.inode") == 0) { /* Yup. */ @@ -5536,7 +5763,7 @@ smbc_listxattr_ctx(SMBCCTX *context, * the complete set of attribute names, always, rather than only those * attribute names which actually exist for a file. Hmmm... */ - const char supported[] = + const char supported_old[] = "system.*\0" "system.*+\0" "system.nt_sec_desc.revision\0" @@ -5555,6 +5782,33 @@ smbc_listxattr_ctx(SMBCCTX *context, "system.dos_attr.a_time\0" "system.dos_attr.m_time\0" ; + const char supported_new[] = + "system.*\0" + "system.*+\0" + "system.nt_sec_desc.revision\0" + "system.nt_sec_desc.owner\0" + "system.nt_sec_desc.owner+\0" + "system.nt_sec_desc.group\0" + "system.nt_sec_desc.group+\0" + "system.nt_sec_desc.acl.*\0" + "system.nt_sec_desc.acl\0" + "system.nt_sec_desc.acl+\0" + "system.nt_sec_desc.*\0" + "system.nt_sec_desc.*+\0" + "system.dos_attr.*\0" + "system.dos_attr.mode\0" + "system.dos_attr.create_time\0" + "system.dos_attr.access_time\0" + "system.dos_attr.write_time\0" + "system.dos_attr.change_time\0" + ; + const char * supported; + + if (context->internal->_full_time_names) { + supported = supported_new; + } else { + supported = supported_old; + } if (size == 0) { return sizeof(supported); @@ -6029,24 +6283,17 @@ smbc_option_set(SMBCCTX *context, option_value.b = (BOOL) va_arg(ap, int); context->internal->_debug_stderr = option_value.b; - } else if (strcmp(option_name, "debug_to_stderr") == 0) { + } else if (strcmp(option_name, "full_time_names") == 0) { /* - * Log to standard error instead of standard output. - * - * This function used to take a third parameter, - * void *option_value. Since it was a void* and we needed to - * pass a boolean, a boolean value was cast to void* to be - * passed in. Now that we're using a va_list to retrieve the - * parameters, the casting kludge is unnecessary. - * - * WARNING: DO NOT USE THIS OPTION. - * This option is retained for backward compatibility. New - * applications should use "debug_to_stderr" and properly pass - * in a boolean (int) value. + * Use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also + * setting/getting CREATE_TIME which was previously + * unimplemented. (Note that the old C_TIME was supposed to + * be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) */ - option_value.v = va_arg(ap, void *); - context->internal->_debug_stderr = - (option_value.v == NULL ? False : True); + option_value.b = (BOOL) va_arg(ap, int); + context->internal->_full_time_names = option_value.b; } else if (strcmp(option_name, "auth_function") == 0) { /* @@ -6086,6 +6333,21 @@ smbc_option_get(SMBCCTX *context, #else return (void *) context->internal->_debug_stderr; #endif + } else if (strcmp(option_name, "full_time_names") == 0) { + /* + * Use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also + * setting/getting CREATE_TIME which was previously + * unimplemented. (Note that the old C_TIME was supposed to + * be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->internal->_full_time_names; +#else + return (void *) context->internal->_full_time_names; +#endif + } else if (strcmp(option_name, "auth_function") == 0) { /* * Use the new-style authentication function which includes -- cgit From 40665edf5e6043ad5a8f46731a79ec1d5835b62a Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 3 Sep 2006 00:50:34 +0000 Subject: r18011: Should fix bug 3835. Jeremy: requires your eyes... If the remote connection timed out while cli_list() was retrieving its list of files, the error was not returned to the user, e.g. via smbc_opendir(), so the user didn't have a way to know to set the timeout longer and try again. This problem would occur when a very large directory is being read with a too-small timeout on the cli. Jeremy, although there were a couple of areas that needed to be handled, I needed to make one change that you should bless, in libsmb/clientgen.c. It was setting cli->smb_rw_error = smb_read_error; but smb_read_error is zero, so this had no effect. I'm now doing cli->smb_rw_error = READ_TIMEOUT; instead, and according to the OP, these (cumulative) changes (in a slightly different form) solve the problem. Please confirm this smb_rw_error change will have no other adverse effects that you can see. Derrell (This used to be commit fa664b24b829f973156486896575c1007b6d7b01) --- source3/libsmb/clientgen.c | 5 ++--- source3/libsmb/clilist.c | 15 +++++++++++---- source3/libsmb/libsmbclient.c | 32 ++++++++++++++++++++++++++++---- 3 files changed, 41 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 4608d40d46..3a84a5bd4d 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -79,7 +79,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { - extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -107,9 +106,9 @@ BOOL cli_receive_smb(struct cli_state *cli) } /* If the server is not responding, note that now */ - if (!ret) { - cli->smb_rw_error = smb_read_error; + DEBUG(0, ("Receiving SMB: Server stopped responding\n")); + cli->smb_rw_error = READ_TIMEOUT; close(cli->fd); cli->fd = -1; return ret; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 18c058f9df..22cb5930c2 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -349,10 +349,17 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mnt = cli_cm_get_mntpoint( cli ); - for (p=dirlist,i=0;iinternal || @@ -2908,9 +2910,9 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } - errno = smbc_errno(context, targetcli); + saved_errno = smbc_errno(context, targetcli); - if (errno == EINVAL) { + if (saved_errno == EINVAL) { /* * See if they asked to opendir something * other than a directory. If so, the @@ -2926,12 +2928,34 @@ smbc_opendir_ctx(SMBCCTX *context, ! IS_DOS_DIR(mode)) { /* It is. Correct the error value */ - errno = ENOTDIR; + saved_errno = ENOTDIR; } } - return NULL; + /* + * If there was an error and the server is no + * good any more... + */ + cb = &context->callbacks; + if (cli_is_error(targetcli) && + cb->check_server_fn(context, srv)) { + + /* ... then remove it. */ + if (cb->remove_unused_server_fn(context, + srv)) { + /* + * We could not remove the server + * completely, remove it from the + * cache so we will not get it + * again. It will be removed when the + * last file/dir is closed. + */ + cb->remove_cached_srv_fn(context, srv); + } + } + errno = saved_errno; + return NULL; } } -- cgit From 44c1504c032ffa0f0b9cc2333fa0e3a05a03bf48 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 3 Sep 2006 01:37:26 +0000 Subject: r18012: Should fix bug 4018. NetApp filers expect paths in Open AndX Request to have a leading slash. Windows clients send the leading slash, so we should too. (This used to be commit fc5b6e4bd8a67994b0c56d1223c74d064164420f) --- source3/libsmb/libsmbclient.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 101cc02211..95a9da8487 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -414,7 +414,15 @@ smbc_parse_path(SMBCCTX *context, } - safe_strcpy(path, p, path_len - 1); + /* + * Prepend a leading slash if there's a file path, as required by + * NetApp filers. + */ + *path = '\0'; + if (*p != '\0') { + *path = '/'; + safe_strcpy(path + 1, p, path_len - 2); + } all_string_sub(path, "/", "\\", 0); -- cgit From 315f4162111d210d0f65123c8c7fe7084a12121c Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 3 Sep 2006 02:10:24 +0000 Subject: r18013: Fix for "bug" (enhancement) 3684. Provide a new option to specify the share mode to be used when opening a file. (This used to be commit 9b6fee5f6f60638ed80fdedcce4b3d29b091f7aa) --- source3/libsmb/libsmbclient.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 95a9da8487..f89c03274a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1120,7 +1120,8 @@ smbc_open_ctx(SMBCCTX *context, cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath); } - if ((fd = cli_open(targetcli, targetpath, flags, DENY_NONE)) < 0) { + if ((fd = cli_open(targetcli, targetpath, flags, + context->internal->_share_mode)) < 0) { /* Handle the error ... */ @@ -6166,6 +6167,8 @@ smbc_new_context(void) context->options.browse_max_lmb_count = 3; /* # LMBs to query */ context->options.urlencode_readdir_entries = False;/* backward compat */ context->options.one_share_per_server = False;/* backward compat */ + context->internal->_share_mode = SMBC_SHAREMODE_DENY_NONE; + /* backward compat */ context->open = smbc_open_ctx; context->creat = smbc_creat_ctx; @@ -6301,6 +6304,7 @@ smbc_option_set(SMBCCTX *context, { va_list ap; union { + int i; BOOL b; smbc_get_auth_data_with_context_fn auth_fn; void *v; @@ -6327,6 +6331,15 @@ smbc_option_set(SMBCCTX *context, option_value.b = (BOOL) va_arg(ap, int); context->internal->_full_time_names = option_value.b; + } else if (strcmp(option_name, "open_share_mode") == 0) { + /* + * The share mode to use for files opened with + * smbc_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE. + */ + option_value.i = va_arg(ap, int); + context->internal->_share_mode = + (smbc_share_mode) option_value.i; + } else if (strcmp(option_name, "auth_function") == 0) { /* * Use the new-style authentication function which includes -- cgit From 6fc90da054e06ac4f9db673e237faed6ccc88207 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 3 Sep 2006 02:28:22 +0000 Subject: r18014: revert a possibly unnecessary change (This used to be commit 9c93abf25e391348fe3864fca0079f231b89467c) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3a84a5bd4d..24851961d0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -79,6 +79,7 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { + extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ @@ -108,7 +109,7 @@ BOOL cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (!ret) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); - cli->smb_rw_error = READ_TIMEOUT; + cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; return ret; -- cgit From 6655e1e997fa96408ce257f1c96773db4551f69f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Sep 2006 09:51:47 +0000 Subject: r18029: More C++ stuff (This used to be commit 089b51e28cc5e3674e4edf5464c7a15673c5ec0f) --- source3/libsmb/ntlm_check.c | 2 +- source3/libsmb/ntlmssp.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index 212bc19767..e1fc92e344 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -183,7 +183,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) { - static const unsigned char zeros[8]; + static const unsigned char zeros[8] = { 0, }; if (nt_pw == NULL) { DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", username)); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index d017bdb76c..c1852a1187 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -1062,7 +1062,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) { - static const uchar zeros[16]; + static const uchar zeros[16] = { 0, }; /* do nothing - blobs are zero length */ /* session key is all zeros */ -- cgit From f8a17bd8bdbb52b200671e7ed52ffd982419f3f6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Sep 2006 19:47:48 +0000 Subject: r18047: More C++ stuff (This used to be commit 86f4ca84f2df2aa8977eb24828e3aa840dda7201) --- source3/libsmb/smbdes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index ee43f4beee..8168eee207 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -172,7 +172,7 @@ static void concat(char *out, char *in1, char *in2, int l1, int l2) *out++ = *in2++; } -static void xor(char *out, char *in1, char *in2, int n) +static void x_or(char *out, char *in1, char *in2, int n) { int i; for (i=0;i Date: Thu, 7 Sep 2006 03:44:05 +0000 Subject: r18199: Allow winbindd to delete a saf_ entry if it knows it can't talk to it. Jeremy. (This used to be commit 7385a076f8fd351472d37d9363304948e88f9f99) --- source3/libsmb/namequery.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 5cd09fd04f..aeeeb3372c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -77,6 +77,30 @@ BOOL saf_store( const char *domain, const char *servername ) return ret; } +BOOL saf_delete( const char *domain, const char *servername ) +{ + char *key; + BOOL ret = False; + + if ( !domain || !servername ) { + DEBUG(2,("saf_delete: Refusing to store empty domain or servername!\n")); + return False; + } + + if ( !gencache_init() ) + return False; + + key = saf_key(domain); + ret = gencache_del(key); + + if (ret) { + DEBUG(10,("saf_delete: domain = [%s], server = [%s]\n", + domain, servername)); + } + SAFE_FREE( key ); + return ret; +} + /**************************************************************************** ****************************************************************************/ -- cgit From 2b27c93a9a8471693d7dcb5fdbe8afe65b22ff66 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 8 Sep 2006 14:28:06 +0000 Subject: r18271: Big change: * autogenerate lsa ndr code * rename 'enum SID_NAME_USE' to 'enum lsa_SidType' * merge a log more security descriptor functions from gen_ndr/ndr_security.c in SAMBA_4_0 The most embarassing thing is the "#define strlen_m strlen" We need a real implementation in SAMBA_3_0 which I'll work on after this code is in. (This used to be commit 3da9f80c28b1e75ef6d46d38fbb81ade6b9fa951) --- source3/libsmb/libsmbclient.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f89c03274a..7b4e216961 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3784,7 +3784,7 @@ convert_sid_to_string(struct cli_state *ipc_cli, { char **domains = NULL; char **names = NULL; - enum SID_NAME_USE *types = NULL; + enum lsa_SidType *types = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); sid_to_string(str, sid); @@ -3820,7 +3820,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, DOM_SID *sid, const char *str) { - enum SID_NAME_USE *types = NULL; + enum lsa_SidType *types = NULL; DOM_SID *sids = NULL; BOOL result = True; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); -- cgit From eab60e2bb13e0197f3771ab6d60da48a72fb311d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 9 Sep 2006 21:40:47 +0000 Subject: r18312: Change gencache_get slightly: Delete expired keys, and only strdup the value if a valid entry was found. The newer calls got the latter one wrong, change the older calls. Volker (This used to be commit 554e68887bc84510690226c9b07a872e7a282abe) --- source3/libsmb/namecache.c | 4 ---- source3/libsmb/trustdom_cache.c | 1 - 2 files changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index afbd807198..bd4b3caeb7 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -201,9 +201,7 @@ BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); - gencache_del(key); SAFE_FREE(key); - SAFE_FREE(value); return False; } else { DEBUG(5, ("name %s#%02X found.\n", name, name_type)); @@ -314,9 +312,7 @@ BOOL namecache_status_fetch(const char *keyname, int keyname_type, if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key)); - gencache_del(key); SAFE_FREE(key); - SAFE_FREE(value); return False; } else { DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", key, value )); diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 8c5fb4d907..fa35f8d423 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -183,7 +183,6 @@ BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for trusted domain %s found.\n", name)); SAFE_FREE(key); - SAFE_FREE(value); return False; } else { SAFE_FREE(key); -- cgit From 041e49d19604e5e0688abd02869eebabf8c585b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Sep 2006 16:37:13 +0000 Subject: r18533: Ensure we clear out the failed connection cache for an entire domain when going back online. Jeremy. (This used to be commit c7e4c8d0b4d109ec67d4424dd446b74b55246c72) --- source3/libsmb/conncache.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index 49512d7a2e..b8ddcb2ba9 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -162,3 +162,31 @@ void flush_negative_conn_cache( void ) } } + +/**************************************************************************** + Remove all negative entries for a domain. Used when going to online state in + winbindd. +****************************************************************************/ + +void flush_negative_conn_cache_for_domain(const char *domain) +{ + struct failed_connection_cache *fcc; + + fcc = failed_connection_cache; + + while (fcc) { + struct failed_connection_cache *fcc_next; + + fcc_next = fcc->next; + + if (strequal(fcc->domain_name, domain)) { + DEBUG(10,("flush_negative_conn_cache_for_domain: removed server %s " + " from failed cache for domain %s\n", + fcc->controller, domain)); + DLIST_REMOVE(failed_connection_cache, fcc); + free(fcc); + } + + fcc = fcc_next; + } +} -- cgit From 258a465e20e007a30043220367d17ecfc87b4f90 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 18 Sep 2006 07:52:16 +0000 Subject: r18605: sync dlinklist.h with samba4, that means DLIST_ADD_END() and DLIST_DEMOTE() now take the type of the tmp pointer not the tmp pointer itself anymore. metze (This used to be commit 2f58645b7094e81dff3734f11aa183ea2ab53d2d) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0e179416dc..cdc22293cb 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1423,7 +1423,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, return NT_STATUS_UNSUCCESSFUL; } - cli_set_timeout(cli, 10000); /* 10 seconds. */ + cli_set_timeout(cli, 30000); /* 10 seconds. */ if (dest_ip) ip = *dest_ip; -- cgit From 6b07596a0f2599a6b39a03af381f12556ca590b6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 18 Sep 2006 15:20:33 +0000 Subject: r18613: Metze, in your DLINKLIST commit you changed this from 10 seconds to 30 seconds. I don't think you meant to do this.... Jeremy. (This used to be commit dd1691cf81492cfecc7f015ba201b78e2588db90) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cdc22293cb..0e179416dc 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1423,7 +1423,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, return NT_STATUS_UNSUCCESSFUL; } - cli_set_timeout(cli, 30000); /* 10 seconds. */ + cli_set_timeout(cli, 10000); /* 10 seconds. */ if (dest_ip) ip = *dest_ip; -- cgit From 4db7642caa99c1b054322a8971c4b673556487ce Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 20 Sep 2006 22:23:12 +0000 Subject: r18745: Use the Samba4 data structures for security descriptors and security descriptor buffers. Make security access masks simply a uint32 rather than a structure with a uint32 in it. (This used to be commit b41c52b9db5fc4a553b20a7a5a051a4afced9366) --- source3/libsmb/clisecdesc.c | 6 ++--- source3/libsmb/libsmbclient.c | 60 +++++++++++++++++++++---------------------- 2 files changed, 33 insertions(+), 33 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 2475743479..e55be48e94 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -107,11 +107,11 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) SIVAL(param, 0, fnum); - if (sd->off_dacl) + if (sd->dacl) sec_info |= DACL_SECURITY_INFORMATION; - if (sd->off_owner_sid) + if (sd->owner_sid) sec_info |= OWNER_SECURITY_INFORMATION; - if (sd->off_grp_sid) + if (sd->group_sid) sec_info |= GROUP_SECURITY_INFORMATION; SSVAL(param, 4, sec_info); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 7b4e216961..15a1ad3055 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3742,8 +3742,8 @@ ace_compare(SEC_ACE *ace1, if (ace1->flags != ace2->flags) return ace1->flags - ace2->flags; - if (ace1->info.mask != ace2->info.mask) - return ace1->info.mask - ace2->info.mask; + if (ace1->access_mask != ace2->access_mask) + return ace1->access_mask - ace2->access_mask; if (ace1->size != ace2->size) return ace1->size - ace2->size; @@ -3758,14 +3758,14 @@ sort_acl(SEC_ACL *the_acl) uint32 i; if (!the_acl) return; - qsort(the_acl->ace, the_acl->num_aces, sizeof(the_acl->ace[0]), + qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), QSORT_CAST ace_compare); for (i=1;inum_aces;) { - if (sec_ace_equal(&the_acl->ace[i-1], &the_acl->ace[i])) { + if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { int j; for (j=i; jnum_aces-1; j++) { - the_acl->ace[j] = the_acl->ace[j+1]; + the_acl->aces[j] = the_acl->aces[j+1]; } the_acl->num_aces--; } else { @@ -3970,7 +3970,7 @@ parse_ace(struct cli_state *ipc_cli, } done: - mask.mask = amask; + mask = amask; init_sec_ace(ace, &sid, atype, mask, aflags); return True; } @@ -3992,7 +3992,7 @@ add_ace(SEC_ACL **the_acl, if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { return False; } - memcpy(aces, (*the_acl)->ace, (*the_acl)->num_aces * sizeof(SEC_ACE)); + memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); newacl = make_sec_acl(ctx, (*the_acl)->revision, 1+(*the_acl)->num_aces, aces); @@ -4564,10 +4564,10 @@ cacl_get(SMBCCTX *context, } if (! exclude_nt_group) { - if (sd->grp_sid) { + if (sd->group_sid) { convert_sid_to_string(ipc_cli, pol, sidstr, numeric, - sd->grp_sid); + sd->group_sid); } else { fstrcpy(sidstr, ""); } @@ -4612,7 +4612,7 @@ cacl_get(SMBCCTX *context, /* Add aces to value buffer */ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { - SEC_ACE *ace = &sd->dacl->ace[i]; + SEC_ACE *ace = &sd->dacl->aces[i]; convert_sid_to_string(ipc_cli, pol, sidstr, numeric, &ace->trustee); @@ -4626,7 +4626,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4639,7 +4639,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } else if ((StrnCaseCmp(name, "acl", 3) == 0 && StrCaseCmp(name+3, sidstr) == 0) || @@ -4651,7 +4651,7 @@ cacl_get(SMBCCTX *context, "%d/%d/0x%08x", ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4662,7 +4662,7 @@ cacl_get(SMBCCTX *context, "%d/%d/0x%08x", ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } else if (all_nt_acls) { if (determine_size) { @@ -4673,7 +4673,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); if (!p) { errno = ENOMEM; return -1; @@ -4686,7 +4686,7 @@ cacl_get(SMBCCTX *context, sidstr, ace->type, ace->flags, - ace->info.mask); + ace->access_mask); } } if (n > bufsize) { @@ -5117,9 +5117,9 @@ cacl_set(TALLOC_CTX *ctx, switch (mode) { case SMBC_XATTR_MODE_REMOVE_ALL: old->dacl->num_aces = 0; - SAFE_FREE(old->dacl->ace); + SAFE_FREE(old->dacl->aces); SAFE_FREE(old->dacl); - old->off_dacl = 0; + old->dacl = NULL; dacl = old->dacl; break; @@ -5128,18 +5128,18 @@ cacl_set(TALLOC_CTX *ctx, BOOL found = False; for (j=0;old->dacl && jdacl->num_aces;j++) { - if (sec_ace_equal(&sd->dacl->ace[i], - &old->dacl->ace[j])) { + if (sec_ace_equal(&sd->dacl->aces[i], + &old->dacl->aces[j])) { uint32 k; for (k=j; kdacl->num_aces-1;k++) { - old->dacl->ace[k] = - old->dacl->ace[k+1]; + old->dacl->aces[k] = + old->dacl->aces[k+1]; } old->dacl->num_aces--; if (old->dacl->num_aces == 0) { - SAFE_FREE(old->dacl->ace); + SAFE_FREE(old->dacl->aces); SAFE_FREE(old->dacl); - old->off_dacl = 0; + old->dacl = NULL; } found = True; dacl = old->dacl; @@ -5160,14 +5160,14 @@ cacl_set(TALLOC_CTX *ctx, BOOL found = False; for (j=0;old->dacl && jdacl->num_aces;j++) { - if (sid_equal(&sd->dacl->ace[i].trustee, - &old->dacl->ace[j].trustee)) { + if (sid_equal(&sd->dacl->aces[i].trustee, + &old->dacl->aces[j].trustee)) { if (!(flags & SMBC_XATTR_FLAG_CREATE)) { err = EEXIST; ret = -1; goto failed; } - old->dacl->ace[j] = sd->dacl->ace[i]; + old->dacl->aces[j] = sd->dacl->aces[i]; ret = -1; found = True; } @@ -5180,7 +5180,7 @@ cacl_set(TALLOC_CTX *ctx, } for (i=0;sd->dacl && idacl->num_aces;i++) { - add_ace(&old->dacl, &sd->dacl->ace[i], ctx); + add_ace(&old->dacl, &sd->dacl->aces[i], ctx); } } dacl = old->dacl; @@ -5189,7 +5189,7 @@ cacl_set(TALLOC_CTX *ctx, case SMBC_XATTR_MODE_SET: old = sd; owner_sid = old->owner_sid; - grp_sid = old->grp_sid; + grp_sid = old->group_sid; dacl = old->dacl; break; @@ -5198,7 +5198,7 @@ cacl_set(TALLOC_CTX *ctx, break; case SMBC_XATTR_MODE_CHGRP: - grp_sid = sd->grp_sid; + grp_sid = sd->group_sid; break; } -- cgit From 7ba2554d88a187ca1f4f40014363fdf9de2223a0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 21 Sep 2006 23:57:32 +0000 Subject: r18802: Use the pidl-generated code for the srvsvc interface, both client and server code. This has had some basic testing. I'll do more during the next couple of days and hopefully also make RPC-SRVSVC from Samba4 pass against it. (This used to be commit ef10672399c4b82700dc431b4d93431ffdd42d98) --- source3/libsmb/libsmbclient.c | 35 +++++++++++++---------------------- 1 file changed, 13 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 15a1ad3055..2af72d670f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2473,15 +2473,13 @@ net_share_enum_rpc(struct cli_state *cli, { int i; WERROR result; - ENUM_HND enum_hnd; + uint32 enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; - uint32 type; - SRV_SHARE_INFO_CTR ctr; - fstring name = ""; - fstring comment = ""; + union srvsvc_NetShareCtr ctr; void *mem_ctx; struct rpc_pipe_client *pipe_hnd; + uint32 numentries; NTSTATUS nt_status; /* Open the server service pipe */ @@ -2500,36 +2498,29 @@ net_share_enum_rpc(struct cli_state *cli, } /* Issue the NetShareEnum RPC call and retrieve the response */ - init_enum_hnd(&enum_hnd, 0); - result = rpccli_srvsvc_net_share_enum(pipe_hnd, + enum_hnd = 0; + result = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, - info_level, + NULL, + &info_level, &ctr, preferred_len, + &numentries, &enum_hnd); /* Was it successful? */ - if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { + if (!W_ERROR_IS_OK(result) || numentries == 0) { /* Nope. Go clean up. */ goto done; } /* For each returned entry... */ - for (i = 0; i < ctr.num_entries; i++) { - - /* pull out the share name */ - rpcstr_pull_unistr2_fstring( - name, &ctr.share.info1[i].info_1_str.uni_netname); - - /* pull out the share's comment */ - rpcstr_pull_unistr2_fstring( - comment, &ctr.share.info1[i].info_1_str.uni_remark); - - /* Get the type value */ - type = ctr.share.info1[i].info_1.type; + for (i = 0; i < numentries; i++) { /* Add this share to the list */ - (*fn)(name, type, comment, state); + (*fn)(ctr.ctr1->array[i].name, + ctr.ctr1->array[i].type, + ctr.ctr1->array[i].comment, state); } done: -- cgit From a6bb76765aa9759ab8869968bacbd3c5104a9db8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Sep 2006 09:34:25 +0000 Subject: r18819: Fix build without LDAP. Guenther (This used to be commit a0aedee1c90af163210dd459603dd5dffb73e132) --- source3/libsmb/gpo.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/gpo.c b/source3/libsmb/gpo.c index 0257138ece..6be2ce2f79 100644 --- a/source3/libsmb/gpo.c +++ b/source3/libsmb/gpo.c @@ -20,6 +20,8 @@ #include "includes.h" +#ifdef HAVE_LDAP + #define GPT_INI_SECTION_GENERAL "General" #define GPT_INI_PARAMETER_VERSION "Version" #define GPT_INI_PARAMETER_DISPLAYNAME "displayName" @@ -165,3 +167,5 @@ TicketValidateClient = 1 signature="$CHICAGO$" Revision=1 */ + +#endif /* HAVE_LDAP */ -- cgit From 96f2a97e011b195c5d445fd8baa0bdcfa03ec174 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 23 Sep 2006 21:41:41 +0000 Subject: r18858: arrgh! - since HAVE_IMMEDIATE_STRUCTURES were last enabled the code can no longer handle it (at least with gcc 4.1.2). Disable it until investigated and fixed properly. (This used to be commit c8670b33b490daeaff987c21fcb0ec601a91d54e) --- source3/libsmb/clierror.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 44573bd29b..01c42bd36a 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -226,7 +226,7 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) } /* Return a UNIX errno from a NT status code */ -static struct { +struct { NTSTATUS status; int error; } nt_errno_map[] = { -- cgit From 0c3194816b513e3743ddcacd1eca2b683ca39b88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 24 Sep 2006 02:32:34 +0000 Subject: r18865: fixed some of the most obvious NTSTATUS/WERROR mixups in Samba3. It still doesn't compile with immediate structures and the NTSTATUS/WERROR separation, as there are still several places where the two error types are mixed up. I haven't fixed those as they require decisions about the rpcclient code that I really don't want to get into (the error handling there is a mess) So samba3 compiles now, but only becaise HAVE_IMMEDIATE_STRUCTURES is not used (look for HAVE_IMMEDIATE_STRUCTURES_XX_DISABLED) (This used to be commit 8438a6a7d4506d395c8b4bd0e99f9c100e5e3c4e) --- source3/libsmb/clierror.c | 2 +- source3/libsmb/libsmbclient.c | 6 +++--- source3/libsmb/nterr.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 01c42bd36a..fcedc3bdab 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -226,7 +226,7 @@ void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *ecode) } /* Return a UNIX errno from a NT status code */ -struct { +static const struct { NTSTATUS status; int error; } nt_errno_map[] = { diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2af72d670f..6be7dbe8d6 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2472,7 +2472,7 @@ net_share_enum_rpc(struct cli_state *cli, void *state) { int i; - WERROR result; + NTSTATUS result; uint32 enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; @@ -2509,7 +2509,7 @@ net_share_enum_rpc(struct cli_state *cli, &enum_hnd); /* Was it successful? */ - if (!W_ERROR_IS_OK(result) || numentries == 0) { + if (!NT_STATUS_IS_OK(result) || numentries == 0) { /* Nope. Go clean up. */ goto done; } @@ -2531,7 +2531,7 @@ done: TALLOC_FREE(mem_ctx); /* Tell 'em if it worked */ - return W_ERROR_IS_OK(result) ? 0 : -1; + return NT_STATUS_IS_OK(result) ? 0 : -1; } diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index e874b80473..2e4b1106af 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -28,7 +28,7 @@ typedef const struct NTSTATUS nt_errcode; } nt_err_code_struct; -static nt_err_code_struct nt_errs[] = +static const nt_err_code_struct nt_errs[] = { { "NT_STATUS_OK", NT_STATUS_OK }, { "NT_STATUS_UNSUCCESSFUL", NT_STATUS_UNSUCCESSFUL }, -- cgit From 147fc86a947623e20bc85e797cb48371a54a0b77 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Sep 2006 05:06:42 +0000 Subject: r18891: Fix "double const" warning from host opi (This used to be commit 47c19811ae2282259f523a0d41a08d84de74cbda) --- source3/libsmb/nterr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 2e4b1106af..db522556e4 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -22,7 +22,7 @@ #include "includes.h" -typedef const struct +typedef struct { const char *nt_errstr; NTSTATUS nt_errcode; -- cgit From b6b9898a0710585751eab45a0d16a61a4cff208a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Sep 2006 23:31:53 +0000 Subject: r18966: this bug affects Samba3 too. I'm actually surprised nobody has reported that Samba3 on Solaris Sparc with the native compiler can't join Windows domains. If it worked we were just lucky. I suspect it just didn't work. (This used to be commit 9df1e7d98973ac1ec6ba25d528591216e568f2f3) --- source3/libsmb/smbencrypt.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 96c086d680..5f7b5b1809 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -496,6 +496,9 @@ BOOL encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags) uchar new_pw[512]; size_t new_pw_len; + /* the incoming buffer can be any alignment. */ + string_flags |= STR_NOALIGN; + new_pw_len = push_string(NULL, new_pw, password, sizeof(new_pw), string_flags); @@ -526,6 +529,9 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, { int byte_len=0; + /* the incoming buffer can be any alignment. */ + string_flags |= STR_NOALIGN; + /* Warning !!! : This function is called from some rpc call. The password IN the buffer may be a UNICODE string. -- cgit From b80cbfc20e0d0ede84531a37e187274ba04e822c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 Sep 2006 03:21:49 +0000 Subject: r18969: Fix typo. Guenther (This used to be commit 31f21282cd5fb27c867615790e7fd27df4cd4c0e) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0e179416dc..6e6f7a5ebe 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1530,7 +1530,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, pw_len, domain); if (!NT_STATUS_IS_OK(nt_status)) { - if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK)) { + if (!(flags & CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK)) { DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status))); cli_shutdown(cli); @@ -1688,7 +1688,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", user_info->username, lp_workgroup(), user_info->password, - CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK, Undefined, NULL); + CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return cli; -- cgit From 73f4ac012aaebfe4f778f6971ce59049c242be7b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 Sep 2006 21:33:54 +0000 Subject: r18982: Move the gpo related functions to "libgpo". Guenther (This used to be commit 1308a842716bc3bd1a9853b9b206dc7308a8c1dd) --- source3/libsmb/gpo.c | 171 --------------------------------------------------- 1 file changed, 171 deletions(-) delete mode 100644 source3/libsmb/gpo.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/gpo.c b/source3/libsmb/gpo.c deleted file mode 100644 index 6be2ce2f79..0000000000 --- a/source3/libsmb/gpo.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * Group Policy Object Support - * Copyright (C) Guenther Deschner 2005 - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -#ifdef HAVE_LDAP - -#define GPT_INI_SECTION_GENERAL "General" -#define GPT_INI_PARAMETER_VERSION "Version" -#define GPT_INI_PARAMETER_DISPLAYNAME "displayName" - -struct gpt_ini { - uint32 version; - const char *display_name; -}; - -static uint32 version; - -static BOOL do_section(const char *section) -{ - DEBUG(10,("do_section: %s\n", section)); - - return True; -} - -static BOOL do_parameter(const char *parameter, const char *value) -{ - DEBUG(10,("do_parameter: %s, %s\n", parameter, value)); - - if (strequal(parameter, GPT_INI_PARAMETER_VERSION)) { - version = atoi(value); - } - return True; -} - -NTSTATUS ads_gpo_get_sysvol_gpt_version(ADS_STRUCT *ads, - TALLOC_CTX *mem_ctx, - const char *filesyspath, - uint32 *sysvol_version) -{ - NTSTATUS status; - const char *path; - struct cli_state *cli; - int fnum; - fstring tok; - static int io_bufsize = 64512; - int read_size = io_bufsize; - char *data = NULL; - off_t start = 0; - off_t nread = 0; - int handle = 0; - const char *local_file; - - *sysvol_version = 0; - - next_token(&filesyspath, tok, "\\", sizeof(tok)); - next_token(&filesyspath, tok, "\\", sizeof(tok)); - - path = talloc_asprintf(mem_ctx, "\\%s\\gpt.ini", filesyspath); - if (path == NULL) { - return NT_STATUS_NO_MEMORY; - } - - local_file = talloc_asprintf(mem_ctx, "%s/%s", lock_path("gpo_cache"), "gpt.ini"); - if (local_file == NULL) { - return NT_STATUS_NO_MEMORY; - } - - /* FIXME: walk down the dfs tree instead */ - status = cli_full_connection(&cli, global_myname(), - ads->config.ldap_server_name, - NULL, 0, - "SYSVOL", "A:", - ads->auth.user_name, NULL, ads->auth.password, - CLI_FULL_CONNECTION_USE_KERBEROS, - Undefined, NULL); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - fnum = cli_open(cli, path, O_RDONLY, DENY_NONE); - if (fnum == -1) { - return NT_STATUS_NO_SUCH_FILE; - } - - - data = (char *)SMB_MALLOC(read_size); - if (data == NULL) { - return NT_STATUS_NO_MEMORY; - } - - handle = sys_open(local_file, O_WRONLY|O_CREAT|O_TRUNC, 0644); - - if (handle == -1) { - return NT_STATUS_NO_SUCH_FILE; - } - - while (1) { - - int n = cli_read(cli, fnum, data, nread + start, read_size); - - if (n <= 0) - break; - - if (write(handle, data, n) != n) { - break; - } - - nread += n; - } - - cli_close(cli, fnum); - - if (!pm_process(local_file, do_section, do_parameter)) { - return NT_STATUS_INVALID_PARAMETER; - } - - *sysvol_version = version; - - SAFE_FREE(data); - - cli_shutdown(cli); - - return NT_STATUS_OK; -} - -/* - -perfectly parseable with pm_process() :)) - -[Unicode] -Unicode=yes -[System Access] -MinimumPasswordAge = 1 -MaximumPasswordAge = 42 -MinimumPasswordLength = 7 -PasswordComplexity = 1 -PasswordHistorySize = 24 -LockoutBadCount = 0 -RequireLogonToChangePassword = 0 -ForceLogoffWhenHourExpire = 0 -ClearTextPassword = 0 -[Kerberos Policy] -MaxTicketAge = 10 -MaxRenewAge = 7 -MaxServiceAge = 600 -MaxClockSkew = 5 -TicketValidateClient = 1 -[Version] -signature="$CHICAGO$" -Revision=1 -*/ - -#endif /* HAVE_LDAP */ -- cgit From a3a082b24836e50755e2086eeb35a4fee8dac17c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 2 Oct 2006 11:03:53 +0000 Subject: r19037: Fix a segfault (This used to be commit 1c18ebe67500a59d4bf08c7e2e2c2af416bfa084) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 3dad37d9e1..fedf7e5c6e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -165,7 +165,7 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, ret = !data.has_error; if (data.has_error) { int j; - SAFE_FREE(principal); + SAFE_FREE(*principal); for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { SAFE_FREE(OIDs[j]); } -- cgit From eb00981fc363a104d43dba75a8d18cc02421bbf8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 2 Oct 2006 12:54:49 +0000 Subject: r19041: Make us connect to Vista RC1. Apparently metze had done the same patch some weeks ago. We have some work before us, when in AD mode Vista sends "not_defined_in_RFC4178@please_ignore" as the principal..... Volker (This used to be commit af85d8ec02b36b765ceadf0a342c7eda2410034b) --- source3/libsmb/cliconnect.c | 15 ++++++++++++++- source3/libsmb/clispnego.c | 17 ++++++++++------- 2 files changed, 24 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6e6f7a5ebe..983d9012f0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -762,7 +762,20 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, #endif free(OIDs[i]); } - DEBUG(3,("got principal=%s\n", principal)); + + DEBUG(3,("got principal=%s\n", principal ? principal : "")); + + if (got_kerberos_mechanism && (principal == NULL)) { + /* + * It is WRONG to depend on the principal sent in the negprot + * reply, but right now we do it. So for safety (don't + * segfault later) disable Kerberos when no principal was + * sent. -- VL + */ + DEBUG(1, ("Kerberos mech was offered, but no principal was sent\n")); + DEBUGADD(1, ("Disabling Kerberos\n")); + cli->use_kerberos = False; + } fstrcpy(cli->user_name, user); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index fedf7e5c6e..a01c009b6e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -149,13 +149,16 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_end_tag(&data); asn1_end_tag(&data); - asn1_start_tag(&data, ASN1_CONTEXT(3)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(&data,principal); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_end_tag(&data); + *principal = NULL; + if (asn1_tag_remaining(&data) > 0) { + asn1_start_tag(&data, ASN1_CONTEXT(3)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_GeneralString(&data,principal); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + } asn1_end_tag(&data); asn1_end_tag(&data); -- cgit From 4295292734c144275bb6e256677f678ae7023fb4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 2 Oct 2006 13:09:42 +0000 Subject: r19042: Fix the non-krb5 build. This needs sooo severe cleanup ... :-) Volker (This used to be commit b601fc42cb289366b7c522f41aa4c66920006890) --- source3/libsmb/cliconnect.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 983d9012f0..070717caef 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -765,6 +765,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, DEBUG(3,("got principal=%s\n", principal ? principal : "")); +#ifdef HAVE_KRB5 if (got_kerberos_mechanism && (principal == NULL)) { /* * It is WRONG to depend on the principal sent in the negprot @@ -776,6 +777,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, DEBUGADD(1, ("Disabling Kerberos\n")); cli->use_kerberos = False; } +#endif fstrcpy(cli->user_name, user); -- cgit From bc2a760498a2b3c918ac3823fe275fc273d98071 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 2 Oct 2006 13:30:05 +0000 Subject: r19043: There's no point in #ifdef'ing the detection whether we were offered KRB5 in SPNEGO, as long as we don't make use of it without krb libs. Makes the code a bit simpler. Volker (This used to be commit 23549e6c082e92e45ced4eee215bcc0094b2a88b) --- source3/libsmb/cliconnect.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 070717caef..81188b004f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -723,9 +723,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, char *principal; char *OIDs[ASN1_MAX_OIDS]; int i; -#ifdef HAVE_KRB5 BOOL got_kerberos_mechanism = False; -#endif DATA_BLOB blob; DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); @@ -754,18 +752,15 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, /* make sure the server understands kerberos */ for (i=0;OIDs[i];i++) { DEBUG(3,("got OID=%s\n", OIDs[i])); -#ifdef HAVE_KRB5 if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || strcmp(OIDs[i], OID_KERBEROS5) == 0) { got_kerberos_mechanism = True; } -#endif free(OIDs[i]); } DEBUG(3,("got principal=%s\n", principal ? principal : "")); -#ifdef HAVE_KRB5 if (got_kerberos_mechanism && (principal == NULL)) { /* * It is WRONG to depend on the principal sent in the negprot @@ -773,11 +768,10 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, * segfault later) disable Kerberos when no principal was * sent. -- VL */ - DEBUG(1, ("Kerberos mech was offered, but no principal was sent\n")); - DEBUGADD(1, ("Disabling Kerberos\n")); + DEBUG(1, ("Kerberos mech was offered, but no principal was " + "sent, disabling Kerberos\n")); cli->use_kerberos = False; } -#endif fstrcpy(cli->user_name, user); -- cgit From 8cd27dc1c33650561325ec5ea108949919e0bb26 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 4 Oct 2006 19:09:32 +0000 Subject: r19070: If there's an error in the data struct, there's no point to continue with asn1_pop_tag. Volker (This used to be commit d18e9f1da9a22aa16860aa2a91e7c788d28d3314) --- source3/libsmb/asn1.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index dd22051ae7..937e063c62 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -74,6 +74,10 @@ BOOL asn1_pop_tag(ASN1_DATA *data) struct nesting *nesting; size_t len; + if (data->has_error) { + return False; + } + nesting = data->nesting; if (!nesting) { -- cgit From e0b6961ac5b501f51bd004a392c606e3ef308fee Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 7 Oct 2006 05:23:56 +0000 Subject: r19160: Add new WERR codes seen by working with NETLOGON getdcname. Guenther (This used to be commit 78b0124a6e7051da2df3157f02593f06f7f31a1b) --- source3/libsmb/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 253164963a..8628db3abc 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -67,6 +67,8 @@ werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, + { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, + { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, -- cgit From cfed7a5a71aab48b1d5b758df318b991a95592a5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 9 Oct 2006 07:17:37 +0000 Subject: r19184: W2k3 returns its name for the GetServerInfo RAP call. Do the same. Implement 'net rap server name'. Volker (This used to be commit 919385ed2a2a07e848bc0baaac9ed3d1964d4386) --- source3/libsmb/clirap2.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 3c23310f66..d6a44f4ea2 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1414,6 +1414,62 @@ BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype) return(res == 0 || res == ERRmoredata); } +BOOL cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, + char **servername) +{ + char *rparam = NULL; + char *rdata = NULL; + unsigned int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_WserverGetInfo_REQ) /* req string */ + +sizeof(RAP_SERVER_INFO_L1) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + BOOL res = False; + fstring tmp; + + /* send a SMBtrans command with api NetServerGetInfo */ + p = make_header(param, RAP_WserverGetInfo, + RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1); + PUTWORD(p, 1); /* info level */ + PUTWORD(p, CLI_BUFFER_SIZE); + + if (!cli_api(cli, + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + goto failed; + } + + if (GETRES(rparam) != 0) { + goto failed; + } + + if (rdrcnt < 16) { + DEBUG(10, ("invalid data count %d, expected >= 16\n", rdrcnt)); + goto failed; + } + + if (pull_ascii(tmp, rdata, sizeof(tmp)-1, 16, STR_TERMINATE) == -1) { + DEBUG(10, ("pull_ascii failed\n")); + goto failed; + } + + if (!(*servername = talloc_strdup(mem_ctx, tmp))) { + DEBUG(1, ("talloc_strdup failed\n")); + goto failed; + } + + res = True; + + failed: + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return res; +} /************************************************************************* * -- cgit From 2db5ed7fa5b07ce28daf44d56bf07c131af90d02 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 11 Oct 2006 00:33:48 +0000 Subject: r19231: I encountered a WinXP/Home system which, acting as the master browser for its workgroup, decided periodically to stop sending recognized responses to a NetServerEnum2 request for the workgroup. Instead of returning the list of servers (only itself; nothing else in the workgroup), it returns a status code of 8 which is unsupported by samba3, samba4, and ethereal. The code for this request assumed that if an unexpected status code was received, the connection had a problem, i.e. that cli_errno() would show a problem. That turns out not to be the case. This patch changes the behavior so tha any time a response is received and cli_errno() == 0, we continue processing the reply and base our response on the returned count (zero). The pre-existing code then converts this count=0 into an ENOENT errno which can be properly handled by the application (whereas an error return with errno=0 can't be). This packet dump has only 2 frames. Sorry about the text version but it's most easily attached to this log message. I also have it saved as .pcap if anyone wants it. Derrell No. Time Source Destination Protocol Info 1 14:31:59.802668 192.168.1.106 192.168.1.100 LANMAN NetServerEnum2 Request, Server, SQL Server, Domain Controller, Backup Controller, Time Source, Apple Server, Novell Server, Domain Member Server, Print Queue Server, Dialin Server, Xenix Server, NT Workstation, Windows for Workgroups, Unknown server type:14, NT Server Frame 1 (196 bytes on wire, 196 bytes captured) Arrival Time: Oct 10, 2006 14:31:59.802668000 Time delta from previous packet: 0.000000000 seconds Time since reference or first frame: 0.000000000 seconds Frame Number: 1 Packet Length: 196 bytes Capture Length: 196 bytes Protocols in frame: eth:ip:tcp:nbss:smb Ethernet II, Src: IntelCor_4a:47:bb (00:13:20:4a:47:bb), Dst: Micro-St_74:16:e7 (00:0c:76:74:16:e7) Destination: Micro-St_74:16:e7 (00:0c:76:74:16:e7) Source: IntelCor_4a:47:bb (00:13:20:4a:47:bb) Type: IP (0x0800) Internet Protocol, Src: 192.168.1.106 (192.168.1.106), Dst: 192.168.1.100 (192.168.1.100) Version: 4 Header length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00) 0000 00.. = Differentiated Services Codepoint: Default (0x00) .... ..0. = ECN-Capable Transport (ECT): 0 .... ...0 = ECN-CE: 0 Total Length: 182 Identification: 0xb838 (47160) Flags: 0x04 (Don't Fragment) 0... = Reserved bit: Not set .1.. = Don't fragment: Set ..0. = More fragments: Not set Fragment offset: 0 Time to live: 64 Protocol: TCP (0x06) Header checksum: 0xfdea [correct] Good: True Bad : False Source: 192.168.1.106 (192.168.1.106) Destination: 192.168.1.100 (192.168.1.100) Transmission Control Protocol, Src Port: 44932 (44932), Dst Port: netbios-ssn (139), Seq: 851982066, Ack: 1274726157, Len: 130 Source port: 44932 (44932) Destination port: netbios-ssn (139) Sequence number: 851982066 Next sequence number: 851982196 Acknowledgement number: 1274726157 Header length: 32 bytes Flags: 0x0018 (PSH, ACK) 0... .... = Congestion Window Reduced (CWR): Not set .0.. .... = ECN-Echo: Not set ..0. .... = Urgent: Not set ...1 .... = Acknowledgment: Set .... 1... = Push: Set .... .0.. = Reset: Not set .... ..0. = Syn: Not set .... ...0 = Fin: Not set Window size: 6432 Checksum: 0xb4e0 [correct] Options: (12 bytes) NOP NOP Time stamp: tsval 1184074739, tsecr 11576161 NetBIOS Session Service Message Type: Session message Flags: 0x00 .... ...0 = Add 0 to length Length: 126 SMB (Server Message Block Protocol) SMB Header Server Component: SMB Response in: 2 SMB Command: Trans (0x25) NT Status: STATUS_SUCCESS (0x00000000) Flags: 0x08 0... .... = Request/Response: Message is a request to the server .0.. .... = Notify: Notify client only on open ..0. .... = Oplocks: OpLock not requested/granted ...0 .... = Canonicalized Pathnames: Pathnames are not canonicalized .... 1... = Case Sensitivity: Path names are caseless .... ..0. = Receive Buffer Posted: Receive buffer has not been posted .... ...0 = Lock and Read: Lock&Read, Write&Unlock are not supported Flags2: 0xc801 1... .... .... .... = Unicode Strings: Strings are Unicode .1.. .... .... .... = Error Code Type: Error codes are NT error codes ..0. .... .... .... = Execute-only Reads: Don't permit reads if execute-only ...0 .... .... .... = Dfs: Don't resolve pathnames with Dfs .... 1... .... .... = Extended Security Negotiation: Extended security negotiation is supported .... .... .0.. .... = Long Names Used: Path names in request are not long file names .... .... .... .0.. = Security Signatures: Security signatures are not supported .... .... .... ..0. = Extended Attributes: Extended attributes are not supported .... .... .... ...1 = Long Names Allowed: Long file names are allowed in the response Process ID High: 0 Signature: 0000000000000000 Reserved: 0000 Tree ID: 2048 Process ID: 12967 User ID: 2048 Multiplex ID: 6 Trans Request (0x25) Word Count (WCT): 14 Total Parameter Count: 36 Total Data Count: 0 Max Parameter Count: 8 Max Data Count: 65535 Max Setup Count: 0 Reserved: 00 Flags: 0x0000 .... .... .... ..0. = One Way Transaction: Two way transaction .... .... .... ...0 = Disconnect TID: Do NOT disconnect TID Timeout: Return immediately (0) Reserved: 0000 Parameter Count: 36 Parameter Offset: 90 Data Count: 0 Data Offset: 126 Setup Count: 0 Reserved: 00 Byte Count (BCC): 63 Transaction Name: \PIPE\LANMAN SMB Pipe Protocol Microsoft Windows Lanman Remote API Protocol Function Code: NetServerEnum2 (104) Parameter Descriptor: WrLehDz Return Descriptor: B16BBDz Detail Level: 1 Receive Buffer Length: 65535 Server Type: 0x0000fffe .... .... .... .... .... .... .... ...0 = Workstation: This is NOT a Workstation .... .... .... .... .... .... .... ..1. = Server: This is a Server .... .... .... .... .... .... .... .1.. = SQL: This is an SQL server .... .... .... .... .... .... .... 1... = Domain Controller: This is a Domain Controller .... .... .... .... .... .... ...1 .... = Backup Controller: This is a Backup Controller .... .... .... .... .... .... ..1. .... = Time Source: This is a Time Source .... .... .... .... .... .... .1.. .... = Apple: This is an Apple host .... .... .... .... .... .... 1... .... = Novell: This is a Novell server .... .... .... .... .... ...1 .... .... = Member: This is a Domain Member server .... .... .... .... .... ..1. .... .... = Print: This is a Print Queue server .... .... .... .... .... .1.. .... .... = Dialin: This is a Dialin server .... .... .... .... .... 1... .... .... = Xenix: This is a Xenix server .... .... .... .... ...1 .... .... .... = NT Workstation: This is an NT Workstation .... .... .... .... ..1. .... .... .... = WfW: This is a WfW host .... .... .... .... 1... .... .... .... = NT Server: This is an NT Server .... .... .... ...0 .... .... .... .... = Potential Browser: This is NOT a Potential Browser .... .... .... ..0. .... .... .... .... = Backup Browser: This is NOT a Backup Browser .... .... .... .0.. .... .... .... .... = Master Browser: This is NOT a Master Browser .... .... .... 0... .... .... .... .... = Domain Master Browser: This is NOT a Domain Master Browser .... .... ...0 .... .... .... .... .... = OSF: This is NOT an OSF host .... .... ..0. .... .... .... .... .... = VMS: This is NOT a VMS host .... .... .0.. .... .... .... .... .... = Windows 95+: This is NOT a Windows 95 or above host .0.. .... .... .... .... .... .... .... = Local: This is NOT a local list only request 0... .... .... .... .... .... .... .... = Domain Enum: This is NOT a Domain Enum request Enumeration Domain: WORKGROUP No. Time Source Destination Protocol Info 2 14:31:59.803918 192.168.1.100 192.168.1.106 LANMAN NetServerEnum2 Response Frame 2 (134 bytes on wire, 134 bytes captured) Arrival Time: Oct 10, 2006 14:31:59.803918000 Time delta from previous packet: 0.001250000 seconds Time since reference or first frame: 0.001250000 seconds Frame Number: 2 Packet Length: 134 bytes Capture Length: 134 bytes Protocols in frame: eth:ip:tcp:nbss:smb Ethernet II, Src: Micro-St_74:16:e7 (00:0c:76:74:16:e7), Dst: IntelCor_4a:47:bb (00:13:20:4a:47:bb) Destination: IntelCor_4a:47:bb (00:13:20:4a:47:bb) Source: Micro-St_74:16:e7 (00:0c:76:74:16:e7) Type: IP (0x0800) Internet Protocol, Src: 192.168.1.100 (192.168.1.100), Dst: 192.168.1.106 (192.168.1.106) Version: 4 Header length: 20 bytes Differentiated Services Field: 0x00 (DSCP 0x00: Default; ECN: 0x00) 0000 00.. = Differentiated Services Codepoint: Default (0x00) .... ..0. = ECN-Capable Transport (ECT): 0 .... ...0 = ECN-CE: 0 Total Length: 120 Identification: 0xea10 (59920) Flags: 0x04 (Don't Fragment) 0... = Reserved bit: Not set .1.. = Don't fragment: Set ..0. = More fragments: Not set Fragment offset: 0 Time to live: 128 Protocol: TCP (0x06) Header checksum: 0x8c50 [correct] Good: True Bad : False Source: 192.168.1.100 (192.168.1.100) Destination: 192.168.1.106 (192.168.1.106) Transmission Control Protocol, Src Port: netbios-ssn (139), Dst Port: 44932 (44932), Seq: 1274726157, Ack: 851982196, Len: 68 Source port: netbios-ssn (139) Destination port: 44932 (44932) Sequence number: 1274726157 Next sequence number: 1274726225 Acknowledgement number: 851982196 Header length: 32 bytes Flags: 0x0018 (PSH, ACK) 0... .... = Congestion Window Reduced (CWR): Not set .0.. .... = ECN-Echo: Not set ..0. .... = Urgent: Not set ...1 .... = Acknowledgment: Set .... 1... = Push: Set .... .0.. = Reset: Not set .... ..0. = Syn: Not set .... ...0 = Fin: Not set Window size: 64606 Checksum: 0x1e0d [correct] Options: (12 bytes) NOP NOP Time stamp: tsval 11576161, tsecr 1184074739 NetBIOS Session Service Message Type: Session message Flags: 0x00 .... ...0 = Add 0 to length Length: 64 SMB (Server Message Block Protocol) SMB Header Server Component: SMB Response to: 1 Time from request: 0.001250000 seconds SMB Command: Trans (0x25) NT Status: STATUS_SUCCESS (0x00000000) Flags: 0x88 1... .... = Request/Response: Message is a response to the client/redirector .0.. .... = Notify: Notify client only on open ..0. .... = Oplocks: OpLock not requested/granted ...0 .... = Canonicalized Pathnames: Pathnames are not canonicalized .... 1... = Case Sensitivity: Path names are caseless .... ..0. = Receive Buffer Posted: Receive buffer has not been posted .... ...0 = Lock and Read: Lock&Read, Write&Unlock are not supported Flags2: 0xc801 1... .... .... .... = Unicode Strings: Strings are Unicode .1.. .... .... .... = Error Code Type: Error codes are NT error codes ..0. .... .... .... = Execute-only Reads: Don't permit reads if execute-only ...0 .... .... .... = Dfs: Don't resolve pathnames with Dfs .... 1... .... .... = Extended Security Negotiation: Extended security negotiation is supported .... .... .0.. .... = Long Names Used: Path names in request are not long file names .... .... .... .0.. = Security Signatures: Security signatures are not supported .... .... .... ..0. = Extended Attributes: Extended attributes are not supported .... .... .... ...1 = Long Names Allowed: Long file names are allowed in the response Process ID High: 0 Signature: 0000000000000000 Reserved: 0000 Tree ID: 2048 Process ID: 12967 User ID: 2048 Multiplex ID: 6 Trans Response (0x25) Word Count (WCT): 10 Total Parameter Count: 8 Total Data Count: 0 Reserved: 0000 Parameter Count: 8 Parameter Offset: 56 Parameter Displacement: 0 Data Count: 0 Data Offset: 64 Data Displacement: 0 Setup Count: 0 Reserved: 00 Byte Count (BCC): 9 Padding: 00 SMB Pipe Protocol Microsoft Windows Lanman Remote API Protocol Function Code: NetServerEnum2 (104) Status: Unknown (8) Convert: 0 Entry Count: 0 Available Entries: 0 (This used to be commit 88fa5ac7347cbae92abe17da8d3af00e85110c43) --- source3/libsmb/clirap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index caa23b59d9..61cdd79f36 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -244,7 +244,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, )) { int res = rparam? SVAL(rparam,0) : -1; - if (res == 0 || res == ERRmoredata) { + if (res == 0 || res == ERRmoredata || + (res != -1 && cli_errno(cli) == 0)) { int i; int converter=SVAL(rparam,2); -- cgit From bbefb74bca851ebdc9679d9c95494236b66ebccf Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 11 Oct 2006 09:15:11 +0000 Subject: r19237: fix typo metze (This used to be commit d91041d4b6973fd9779d355cd6f9634e207b7653) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index fc9dd690b3..44713784f4 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -956,7 +956,7 @@ krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); smb_krb5_free_ap_req(context, ap_req); } #else -#error UNKOWN_KRB5_AP_REQ_DECODING_FUNCTION +#error UNKNOWN_KRB5_AP_REQ_DECODING_FUNCTION #endif return ret; } -- cgit From 06ea7f144ac092a659532e790e92fcd10ef3eeaa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 11 Oct 2006 12:29:04 +0000 Subject: r19243: Fix debug statement. Guenther (This used to be commit 4b9d79147ae81fb701abf02dc046076f606443b6) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index aeeeb3372c..44932066b9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1057,7 +1057,7 @@ static BOOL resolve_ads(const char *name, int name_type, if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE)) return False; - DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n", + DEBUG(5,("resolve_ads: Attempting to resolve DC's for %s using DNS\n", name)); if ( (ctx = talloc_init("resolve_ads")) == NULL ) { -- cgit From 37be6913fefcd9988f6c15a7b24a0a3429851ea6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Oct 2006 18:54:40 +0000 Subject: r19249: Attempt to fix a site lookup bug found by Guenther. - "The problem is, with a fresh system, we don't know our sitename, therefor we do a stupid DNS query for all DCs. The reply we get is a round-robin list of all 21 DCs, we just pick the first, contact that and safe that INET.COM#1C query in the name cache for later use... What we need to do if we don't yet know our sitename, is to contact to any DC, get the CLDAP reply to tell us in which site we are, then flush the namecache and requery DNS including the sitename" Implement the flushing of the #1C entries for a given NetBIOS name/realm when looking up the site value. Jeremy. (This used to be commit b2d1e44f59d32c91b1d48eacd1a158ba7b65762d) --- source3/libsmb/namecache.c | 32 ++++++++++++++++++++++++++++++++ source3/libsmb/namequery_dc.c | 3 +++ 2 files changed, 35 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index bd4b3caeb7..02956fa137 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -142,6 +142,10 @@ BOOL namecache_store(const char *name, int name_type, } key = namecache_key(name, name_type); + if (!key) { + return False; + } + expiry = time(NULL) + lp_name_cache_timeout(); /* @@ -198,6 +202,9 @@ BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis * Use gencache interface - lookup the key */ key = namecache_key(name, name_type); + if (!key) { + return False; + } if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); @@ -218,6 +225,31 @@ BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis return *num_names > 0; /* true only if some ip has been fetched */ } +/** + * Remove a namecache entry. Needed for site support. + * + **/ + +BOOL namecache_delete(const char *name, int name_type) +{ + BOOL ret; + char *key; + + if (!gencache_init()) + return False; + + if (name_type > 255) { + return False; /* Don't fetch non-real name types. */ + } + + key = namecache_key(name, name_type); + if (!key) { + return False; + } + ret = gencache_del(key); + SAFE_FREE(key); + return ret; +} /** * Delete single namecache entry. Look at the diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index cf01fb269e..5280118ab8 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -72,6 +72,9 @@ static BOOL ads_dc_name(const char *domain, SAFE_FREE(sitename); sitename = sitename_fetch(); ads_destroy(&ads); + /* Ensure we don't cache the DC we just connected to. */ + namecache_delete(realm, 0x1C); + namecache_delete(domain, 0x1C); continue; } -- cgit From c7864f3d53a59fd823fa2e3bf79edd1d735a15ed Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 11 Oct 2006 19:51:52 +0000 Subject: r19250: Fixes bug 4156. The protocol negotiation string "LANMAN2.1" was not listed in the set of negotiatiable possibilities, so non-optimal negotiation was taking place. (This used to be commit a0dfa60fc5146ea6af0b88d91e030a4ec3d7f01e) --- source3/libsmb/cliconnect.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 81188b004f..f29449cfb2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -33,6 +33,7 @@ static const struct { {PROTOCOL_LANMAN1,"LANMAN1.0"}, {PROTOCOL_LANMAN2,"LM1.2X002"}, {PROTOCOL_LANMAN2,"DOS LANMAN2.1"}, + {PROTOCOL_LANMAN2,"LANMAN2.1"}, {PROTOCOL_LANMAN2,"Samba"}, {PROTOCOL_NT1,"NT LANMAN 1.0"}, {PROTOCOL_NT1,"NT LM 0.12"}, -- cgit From 876be25055e0cc6f2c18ddfc377151b2ca68a54f Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 13 Oct 2006 23:43:27 +0000 Subject: r19270: Stop depending on internal MIT symbols. These are private on MacOS x, so we can't get at them even if we wanted to. Kerberos experts, please take a look to make sure I've done the right thing! (This used to be commit 9b8e179fcc1fb877e8601bfd242ee1fd615b554c) --- source3/libsmb/clikrb5.c | 103 ++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 47 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 44713784f4..2415b28160 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -130,12 +130,34 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, } #endif -#if defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) && !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) +#if !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) + +#if defined(HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES) + +/* With MIT kerberos, we should use krb5_set_default_tgs_enctypes in preference + * to krb5_set_default_tgs_ktypes. See + * http://lists.samba.org/archive/samba-technical/2006-July/048271.html + * + * If the MIT libraries are not exporting internal symbols, we will end up in + * this branch, which is correct. Otherwise we will continue to use the + * internal symbol + */ + krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) +{ + return krb5_set_default_tgs_enctypes(ctx, enc); +} + +#elif defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) + +/* Heimdal */ krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) { return krb5_set_default_in_tkt_etypes(ctx, enc); } -#endif + +#endif /* HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES */ + +#endif /* HAVE_KRB5_SET_DEFAULT_TGS_KTYPES */ #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* HEIMDAL */ @@ -239,18 +261,6 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, #error UNKNOWN_GET_ENCTYPES_FUNCTIONS #endif - void free_kerberos_etypes(krb5_context context, - krb5_enctype *enctypes) -{ -#if defined(HAVE_KRB5_FREE_KTYPES) - krb5_free_ktypes(context, enctypes); - return; -#else - SAFE_FREE(enctypes); - return; -#endif -} - #if defined(HAVE_KRB5_AUTH_CON_SETKEY) && !defined(HAVE_KRB5_AUTH_CON_SETUSERUSERKEY) krb5_error_code krb5_auth_con_setuseruserkey(krb5_context context, krb5_auth_context auth_context, @@ -373,6 +383,14 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ } #if !defined(HAVE_KRB5_LOCATE_KDC) + +/* krb5_locate_kdc is an internal MIT symbol. MIT are not yet willing to commit + * to a public interface for this functionality, so we have to be able to live + * without it if the MIT libraries are hiding their internal symbols. + */ + +#if defined(KRB5_KRBHST_INIT) +/* Heimdal */ krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) { krb5_krbhst_handle hnd; @@ -431,7 +449,19 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ *addr_pp = sa; return 0; } -#endif + +#else /* ! defined(KRB5_KRBHST_INIT) */ + + krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, + struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + DEBUG(0, ("unable to explicitly locate the KDC on this platform\n")); + return KRB5_KDC_UNREACH; +} + +#endif /* KRB5_KRBHST_INIT */ + +#endif /* HAVE_KRB5_LOCATE_KDC */ #if !defined(HAVE_KRB5_FREE_UNPARSED_NAME) void krb5_free_unparsed_name(krb5_context context, char *val) @@ -906,31 +936,16 @@ out: return ret; } - void smb_krb5_free_ap_req(krb5_context context, - krb5_ap_req *ap_req) -{ -#ifdef HAVE_KRB5_FREE_AP_REQ /* MIT */ - krb5_free_ap_req(context, ap_req); -#elif defined(HAVE_FREE_AP_REQ) /* Heimdal */ - free_AP_REQ(ap_req); -#else -#error UNKNOWN_KRB5_AP_REQ_FREE_FUNCTION -#endif -} - /* Prototypes */ -#if defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */ -krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); -#endif krb5_error_code smb_krb5_get_keyinfo_from_ap_req(krb5_context context, const krb5_data *inbuf, krb5_kvno *kvno, krb5_enctype *enctype) { - krb5_error_code ret; #ifdef HAVE_KRB5_DECODE_AP_REQ /* Heimdal */ { + krb5_error_code ret; krb5_ap_req ap_req; ret = krb5_decode_ap_req(context, inbuf, &ap_req); @@ -941,24 +956,13 @@ krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); *enctype = get_enctype_from_ap_req(&ap_req); smb_krb5_free_ap_req(context, &ap_req); + free_AP_REQ(ap_req); + return 0; } -#elif defined(HAVE_DECODE_KRB5_AP_REQ) /* MIT */ - { - krb5_ap_req *ap_req = NULL; - - ret = decode_krb5_ap_req(inbuf, &ap_req); - if (ret) - return ret; - - *kvno = get_kvno_from_ap_req(ap_req); - *enctype = get_enctype_from_ap_req(ap_req); - - smb_krb5_free_ap_req(context, ap_req); - } -#else -#error UNKNOWN_KRB5_AP_REQ_DECODING_FUNCTION #endif - return ret; + + /* Possibly not an appropriate error code. */ + return KRB5KDC_ERR_BADOPTION; } krb5_error_code krb5_rd_req_return_keyblock_from_keytab(krb5_context context, @@ -986,10 +990,15 @@ krb5_error_code decode_krb5_ap_req(const krb5_data *code, krb5_ap_req **rep); return ret; } +#ifdef KRB5_TICKET_HAS_KEYINFO + enctype = (*ticket)->enc_part.enctype; + kvno = (*ticket)->enc_part.kvno; +#else ret = smb_krb5_get_keyinfo_from_ap_req(context, inbuf, &kvno, &enctype); if (ret) { return ret; } +#endif ret = get_key_from_keytab(context, server, -- cgit From 6ec00affb66cdbffb29d50c67379a5155beb6a9e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sun, 15 Oct 2006 15:14:04 +0000 Subject: r19291: this should fix the build on heimdal systems metze (This used to be commit 785ab128c4d630819f141ede8bcf5fc0c705aebb) --- source3/libsmb/clikrb5.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2415b28160..a40d684d2c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -955,7 +955,6 @@ out: *kvno = get_kvno_from_ap_req(&ap_req); *enctype = get_enctype_from_ap_req(&ap_req); - smb_krb5_free_ap_req(context, &ap_req); free_AP_REQ(ap_req); return 0; } -- cgit From 257c5c095b60e10323692cd9595a616499a12ed8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Oct 2006 12:06:17 +0000 Subject: r19368: Use WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE whereever the winbindd tdb is opened. Guenther (This used to be commit 49e9e1a3e7f6ac1a9cf584c88f3c640ca9d15554) --- source3/libsmb/samlogon_cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 7a6d9a96ad..b242d0ef55 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -67,7 +67,8 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ if (!tdb) { - tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000, + tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), + WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, TDB_DEFAULT, O_RDWR, 0600); if (!tdb) { DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n")); -- cgit From 74bb9cb3bd71e3e8c8fbe5bd9905e475ed288dd1 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 17 Oct 2006 15:57:00 +0000 Subject: r19374: fix the build with heimdal metze (This used to be commit a813c7595541e31dfa77915d80235de4402bfeca) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index a40d684d2c..02897265e2 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -955,7 +955,7 @@ out: *kvno = get_kvno_from_ap_req(&ap_req); *enctype = get_enctype_from_ap_req(&ap_req); - free_AP_REQ(ap_req); + free_AP_REQ(&ap_req); return 0; } #endif -- cgit From a2dfdfbf86e51273713f2082ce92831f7fcec455 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 19 Oct 2006 21:47:11 +0000 Subject: r19416: Fix some c++ warnings. Guenther (This used to be commit b076c39b6ac87a078feae30a4384c881c46e81ac) --- source3/libsmb/clikrb5.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 02897265e2..14b5285e45 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -216,7 +216,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, return ret; } - ret = krb5_string_to_key_salt(context, enctype, password->data, salt, key); + ret = krb5_string_to_key_salt(context, enctype, (const char *)password->data, salt, key); krb5_free_salt(context, salt); return ret; } @@ -735,7 +735,7 @@ failed: static krb5_data kdata; kdata.data = (char *)krb5_principal_get_comp_string(context, principal, i); - kdata.length = strlen(kdata.data); + kdata.length = strlen((const char *)kdata.data); return &kdata; } #endif -- cgit From 37ffa791393adb6b92ac98d0ad03676db11fa6e9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 23 Oct 2006 20:13:53 +0000 Subject: r19469: Another user of NetShareEnum (This used to be commit 3a1be1626c1e285da70a8fd688a494eb633eee2f) --- source3/libsmb/libsmbclient.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 6be7dbe8d6..75c66d2e72 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2476,6 +2476,7 @@ net_share_enum_rpc(struct cli_state *cli, uint32 enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; + struct srvsvc_NetShareCtr1 ctr1; union srvsvc_NetShareCtr ctr; void *mem_ctx; struct rpc_pipe_client *pipe_hnd; @@ -2497,6 +2498,9 @@ net_share_enum_rpc(struct cli_state *cli, return -1; } + ZERO_STRUCT(ctr1); + ctr.ctr1 = &ctr1; + /* Issue the NetShareEnum RPC call and retrieve the response */ enum_hnd = 0; result = rpccli_srvsvc_NetShareEnum(pipe_hnd, -- cgit From f8fc3f9158aa7560fb81ff450327db1fb7c69cc0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 6 Nov 2006 19:21:44 +0000 Subject: r19577: Fix from Nils Nordman for bug #4085. Thanks ! Jeremy. (This used to be commit 3b5ab8ab8296339ad0e62d8564d706b5a446dcf3) --- source3/libsmb/passchange.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index e400819743..5b4b0896c0 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -86,12 +86,13 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (!NT_STATUS_IS_OK(result)) { - /* Password must change is the only valid error condition here - * from where we can proceed, the rest like account locked out - * or logon failure will lead to errors later anyway */ + /* Password must change or Password expired are the only valid + * error conditions here from where we can proceed, the rest like + * account locked out or logon failure will lead to errors later + * anyway */ - if (!NT_STATUS_EQUAL(result, - NT_STATUS_PASSWORD_MUST_CHANGE)) { + if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) && + !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) { slprintf(err_str, err_str_len-1, "Could not " "connect to machine %s: %s\n", remote_machine, cli_errstr(cli)); -- cgit From 61a38bd4b83b7f72b479e84daa5ea89164a92f85 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Nov 2006 12:42:50 +0000 Subject: r19651: Fix interesting bug with the automatic site coverage in Active Directory: When having DC-less sites, AD assigns DCs from other sites to that site that does not have it's own DC. The most reliable way for us to identify the nearest DC - in that and all other cases - is the closest_dc flag in the CLDAP reply. Guenther (This used to be commit ff004f7284cb047e738ba3d3ad6602e8aa84e883) --- source3/libsmb/namequery_dc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 5280118ab8..ceb8bbd7e6 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -79,7 +79,7 @@ static BOOL ads_dc_name(const char *domain, } #ifdef HAVE_KRB5 - if ((ads->config.flags & ADS_KDC) && ads_sitename_match(ads)) { + if ((ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) { /* We're going to use this KDC for this realm/domain. If we are using sites, then force the krb5 libs to use this KDC. */ -- cgit From c9567f2f221cd19f455cff207feec9efe2171632 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 10 Nov 2006 13:46:19 +0000 Subject: r19652: Trying to track down which caller tries to store a 0 length domain name in the affinity cache (which happens all the time here). Guenther (This used to be commit 45d6d300767d5b99aff332bdfb0a8f464fd103e0) --- source3/libsmb/namequery.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 44932066b9..555d88fdc8 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -59,6 +59,11 @@ BOOL saf_store( const char *domain, const char *servername ) DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n")); return False; } + + if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) { + DEBUG(0,("saf_store: refusing to store 0 length domain or servername!\n")); + return False; + } if ( !gencache_init() ) return False; @@ -111,7 +116,7 @@ char *saf_fetch( const char *domain ) BOOL ret = False; char *key = NULL; - if ( !domain ) { + if ( !domain || strlen(domain) == 0) { DEBUG(2,("saf_fetch: Empty domain name!\n")); return NULL; } -- cgit From 58406b0d1c1d2d95e559d188450af79d44a1f2f3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 11 Nov 2006 00:23:44 +0000 Subject: r19659: Fix bug #4187. Possible crash in signing on/off code. Jeremy. (This used to be commit 78c1c43523d787825bdb6d52e128bf0af5eccaae) --- source3/libsmb/smb_signing.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index a2df0cc38a..df74b2db36 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -616,6 +616,10 @@ BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) return True; } + if (!data) { + return False; + } + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { return False; } @@ -637,6 +641,10 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) return True; } + if (!data) { + return False; + } + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { return False; } -- cgit From 8fa0a80b498f2681fc9a4f5e6ab5522ee599f224 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 16 Nov 2006 23:48:46 +0000 Subject: r19754: * When using a krb5 session setup, we don't fill in the server_name string the clis_state struct. So call saf_store() after we have the short domain name in the lsa_query_inof_policy code. * Remove unused server string in saf_delete() (This used to be commit 3eddae2f2080f8dafec883cb9ffa2e578c242607) --- source3/libsmb/namequery.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 555d88fdc8..c232ad4938 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -15,8 +15,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "includes.h" @@ -24,7 +23,6 @@ /* nmbd.c sets this to True. */ BOOL global_in_nmbd = False; - /**************************** * SERVER AFFINITY ROUTINES * ****************************/ @@ -82,13 +80,13 @@ BOOL saf_store( const char *domain, const char *servername ) return ret; } -BOOL saf_delete( const char *domain, const char *servername ) +BOOL saf_delete( const char *domain ) { char *key; BOOL ret = False; - if ( !domain || !servername ) { - DEBUG(2,("saf_delete: Refusing to store empty domain or servername!\n")); + if ( !domain ) { + DEBUG(2,("saf_delete: Refusing to delete empty domain\n")); return False; } @@ -99,10 +97,11 @@ BOOL saf_delete( const char *domain, const char *servername ) ret = gencache_del(key); if (ret) { - DEBUG(10,("saf_delete: domain = [%s], server = [%s]\n", - domain, servername)); + DEBUG(10,("saf_delete: domain = [%s]\n", domain )); } + SAFE_FREE( key ); + return ret; } -- cgit From 01367cdfd03d2412904c57807e1ff3c62696d05f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 19 Nov 2006 18:57:52 +0000 Subject: r19797: Convert the remaining pipes to the "new" unique out ptr handling (This used to be commit bc4e0a388a2859d2ddcfb8f07920f3b121a37894) --- source3/libsmb/libsmbclient.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 75c66d2e72..c7f17d3d01 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2474,6 +2474,7 @@ net_share_enum_rpc(struct cli_state *cli, int i; NTSTATUS result; uint32 enum_hnd; + uint32 *penum_hnd = &enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; struct srvsvc_NetShareCtr1 ctr1; @@ -2503,14 +2504,9 @@ net_share_enum_rpc(struct cli_state *cli, /* Issue the NetShareEnum RPC call and retrieve the response */ enum_hnd = 0; - result = rpccli_srvsvc_NetShareEnum(pipe_hnd, - mem_ctx, - NULL, - &info_level, - &ctr, - preferred_len, - &numentries, - &enum_hnd); + result = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL, + &info_level, &ctr, preferred_len, + &numentries, &penum_hnd); /* Was it successful? */ if (!NT_STATUS_IS_OK(result) || numentries == 0) { -- cgit From fb1430d6c93fe25d1f14c62cb82c05c02d12333f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Nov 2006 18:51:49 +0000 Subject: r19936: Patch from Kai Blin to match Windows NTLMSSP flags. Jeremy. (This used to be commit 786318f84bef76c6acffa1ddf7cdba947509fbac) --- source3/libsmb/ntlmssp.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index c1852a1187..2f919b3f76 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -420,8 +420,8 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_LM_KEY; } - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) { - ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + if (!(neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } if (!(neg_flags & NTLMSSP_NEGOTIATE_NTLM2)) { @@ -928,6 +928,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56 | NTLMSSP_UNKNOWN_02000000 | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | @@ -1229,6 +1230,7 @@ NTSTATUS ntlmssp_client_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | + NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2 | NTLMSSP_NEGOTIATE_KEY_EXCH | -- cgit From e6467907eda25a7aea3b8fa75754ab6b6e06272a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 28 Nov 2006 21:11:20 +0000 Subject: r19939: ,fix compile warning about unused functions when not using heimdal (This used to be commit f53983079bc285ad8ced8fc4dd40df66fad13718) --- source3/libsmb/clikrb5.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 14b5285e45..4092b4b2b9 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -852,6 +852,7 @@ failed: #endif } +#ifdef HAVE_KRB5_DECODE_AP_REQ /* Heimdal */ static int get_kvno_from_ap_req(krb5_ap_req *ap_req) { #ifdef HAVE_TICKET_POINTER_IN_KRB5_AP_REQ /* MIT */ @@ -872,6 +873,7 @@ static krb5_enctype get_enctype_from_ap_req(krb5_ap_req *ap_req) return ap_req->ticket->enc_part.enctype; #endif } +#endif /* HAVE_KRB5_DECODE_AP_REQ */ static krb5_error_code get_key_from_keytab(krb5_context context, -- cgit From 791f48f167de339c8ae371e5c80706511fd10018 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 12 Dec 2006 17:38:42 +0000 Subject: r20124: clean up nested extern declaration warnings (This used to be commit ac3eb7813e33b9a2e78c9158433f7ed62c3b62bb) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 24851961d0..68ecb131b1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -20,6 +20,8 @@ #include "includes.h" +extern int smb_read_error; + /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -79,7 +81,6 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) BOOL cli_receive_smb(struct cli_state *cli) { - extern int smb_read_error; BOOL ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ -- cgit From e59e787b4868acffad49b6264e319d585643d5ab Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Wed, 20 Dec 2006 01:10:04 +0000 Subject: r20269: merge -r20264:20267 from SAMBA_3_0_24 more no previous prototype warnings (This used to be commit 41be182f78762372ae13759ede5d2bd40a71d7f5) --- source3/libsmb/libsmb_cache.c | 3 +++ source3/libsmb/libsmbclient.c | 3 +++ source3/libsmb/smb_share_modes.c | 4 ++++ 3 files changed, 10 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 8c4fd7c89f..fdde7acaf8 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -26,6 +26,9 @@ #include "include/libsmbclient.h" #include "../include/libsmb_internal.h" + +int smbc_default_cache_functions(SMBCCTX * context); + /* * Structure we use if internal caching mechanism is used * nothing fancy here. diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c7f17d3d01..0f0e0b834f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -26,6 +26,9 @@ #include "include/libsmb_internal.h" +struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir); +struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, + struct smbc_dirent *dirent); /* * DOS Attribute values (used internally) diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 54477c4524..b62240ce50 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -33,6 +33,10 @@ #undef malloc #endif +int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev, + uint64_t ino, const struct smb_share_mode_entry *new_entry, + const char *sharepath, const char *filename); + static BOOL sharemodes_procid_equal(const struct process_id *p1, const struct process_id *p2) { return (p1->pid == p2->pid); -- cgit From eeb14fcc94ef4c1452e7842c7c2e2532d0915556 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 21 Dec 2006 00:43:21 +0000 Subject: r20296: If we're going to overwrite krb5.conf only do it for our primary domain. Jeremy. (This used to be commit 61d31ce0089fe906d052c971321ce99fede0e240) --- source3/libsmb/namequery_dc.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index ceb8bbd7e6..375d39a5fd 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -25,6 +25,24 @@ #include "includes.h" +/********************************************************************** + Is this our primary domain ? +**********************************************************************/ + +#ifdef HAVE_KRB5 +static BOOL is_our_primary_domain(const char *domain) +{ + int role = lp_server_role(); + + if ((role == ROLE_DOMAIN_MEMBER) && strequal(lp_workgroup(), domain)) { + return True; + } else if (strequal(get_global_sam_name(), domain)) { + return True; + } + return False; +} +#endif + /************************************************************************** Find the name and IP address for a server in the realm/domain *************************************************************************/ @@ -79,7 +97,7 @@ static BOOL ads_dc_name(const char *domain, } #ifdef HAVE_KRB5 - if ((ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) { + if (is_our_primary_domain(domain) && (ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) { /* We're going to use this KDC for this realm/domain. If we are using sites, then force the krb5 libs to use this KDC. */ -- cgit From fb93332b301652c25b4c152b027f53fe3282fb73 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 23 Dec 2006 16:47:50 +0000 Subject: r20333: Fix a couple of Coverity errors in one run, this was a potential NULL dereference (This used to be commit f9edfffeb5aa1fe0700c17cd1c8141c906080188) --- source3/libsmb/libsmbclient.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 0f0e0b834f..d9a39b1249 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4246,11 +4246,14 @@ dos_attr_parse(SMBCCTX *context, continue; } - n = strlen(attr_strings.create_time_attr); - if (attr_strings.create_time_attr != NULL && - StrnCaseCmp(tok, attr_strings.create_time_attr, n) == 0) { - dad->create_time = (time_t)strtol(tok+n+1, NULL, 10); - continue; + if (attr_strings.create_time_attr != NULL) { + n = strlen(attr_strings.create_time_attr); + if (StrnCaseCmp(tok, attr_strings.create_time_attr, + n) == 0) { + dad->create_time = (time_t)strtol(tok+n+1, + NULL, 10); + continue; + } } if (StrnCaseCmp(tok, "INODE:", 6) == 0) { -- cgit From 76cdf68ee9f4982f1b847023818641cf4603dfd1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Dec 2006 09:18:06 +0000 Subject: r20403: Cleaning out my Samba 3.0 tree: As discussed with jerry at the CIFS conf: overriding the administrator's wishes from the krb5.conf has only every given me segfaults. We suggest leaving this up to the defaults from the libraries anyway. Andrew Bartlett (This used to be commit 0b72c04906b1c25e80b217a8f34fd3a8e756b9ca) --- source3/libsmb/clikrb5.c | 42 ------------------------------------------ 1 file changed, 42 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 4092b4b2b9..0df45f1b4d 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -130,35 +130,6 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, } #endif -#if !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) - -#if defined(HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES) - -/* With MIT kerberos, we should use krb5_set_default_tgs_enctypes in preference - * to krb5_set_default_tgs_ktypes. See - * http://lists.samba.org/archive/samba-technical/2006-July/048271.html - * - * If the MIT libraries are not exporting internal symbols, we will end up in - * this branch, which is correct. Otherwise we will continue to use the - * internal symbol - */ - krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) -{ - return krb5_set_default_tgs_enctypes(ctx, enc); -} - -#elif defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) - -/* Heimdal */ - krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) -{ - return krb5_set_default_in_tkt_etypes(ctx, enc); -} - -#endif /* HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES */ - -#endif /* HAVE_KRB5_SET_DEFAULT_TGS_KTYPES */ - #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* HEIMDAL */ void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) @@ -641,13 +612,6 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, krb5_context context = NULL; krb5_ccache ccdef = NULL; krb5_auth_context auth_context = NULL; - krb5_enctype enc_types[] = { -#ifdef ENCTYPE_ARCFOUR_HMAC - ENCTYPE_ARCFOUR_HMAC, -#endif - ENCTYPE_DES_CBC_MD5, - ENCTYPE_DES_CBC_CRC, - ENCTYPE_NULL}; initialize_krb5_error_table(); retval = krb5_init_context(&context); @@ -668,12 +632,6 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, goto failed; } - if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { - DEBUG(1,("cli_krb5_get_ticket: krb5_set_default_tgs_ktypes failed (%s)\n", - error_message(retval))); - goto failed; - } - if ((retval = ads_krb5_mk_req(context, &auth_context, AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts, -- cgit From 3ab9f619d822cd39cc23d0cdca04eb483e026ee8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 8 Jan 2007 08:05:49 +0000 Subject: r20603: Slightly simplify logic (This used to be commit e4dea0e64747912da899e846b944c24804772259) --- source3/libsmb/namequery.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c232ad4938..13d3517cdd 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1505,16 +1505,16 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, just return the list of DC's. Or maybe we just failed. */ if ( (num_addresses == 0) ) { - if ( !done_auto_lookup ) { - if (internal_resolve_name(domain, 0x1C, ip_list, count, resolve_order)) { - return NT_STATUS_OK; - } else { - return NT_STATUS_NO_LOGON_SERVERS; - } - } else { + if ( done_auto_lookup ) { DEBUG(4,("get_dc_list: no servers found\n")); return NT_STATUS_NO_LOGON_SERVERS; } + if (internal_resolve_name(domain, 0x1C, ip_list, count, + resolve_order)) { + return NT_STATUS_OK; + } else { + return NT_STATUS_NO_LOGON_SERVERS; + } } if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { -- cgit From 395d304f225a855a7c032dd18c12e9fd0b1a284c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 8 Jan 2007 08:09:29 +0000 Subject: r20604: Fix two memleaks, Coverity ID 337, merge to 3_0_24 (This used to be commit 44f9d25a9026df29fcaae8723ef52b1d3101628b) --- source3/libsmb/namequery.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 13d3517cdd..065bb810c5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1507,6 +1507,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, if ( (num_addresses == 0) ) { if ( done_auto_lookup ) { DEBUG(4,("get_dc_list: no servers found\n")); + SAFE_FREE(auto_ip_list); return NT_STATUS_NO_LOGON_SERVERS; } if (internal_resolve_name(domain, 0x1C, ip_list, count, @@ -1519,6 +1520,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { DEBUG(3,("get_dc_list: malloc fail !\n")); + SAFE_FREE(auto_ip_list); return NT_STATUS_NO_MEMORY; } -- cgit From fc8605735470df188a2915b6109c1c01a20bc6ac Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 11 Jan 2007 23:10:16 +0000 Subject: r20690: fix a bug that causes smbd to 'hang' intermittently. The problem occurs like this: 1) running smbd as a domain member without winbindd 2) client1 connects, during auth smbd-1 calls update_trustdom_cache() 3) smbd-1 takes the trustdom cache timestamp lock, then starts enumerate_domain_trusts 4) enumerate_domain_trusts hangs for some unknown reason 5) other clients connect, all block waiting for read lock on trustdom cache 6) samba is now hung The problem is the lock, and really its just trying to avoid a race where the cure is worse than the problem. A race in updating the trutdom cache is not a big issue. So I've just removed the lock. It is still an open question why enumerate_domain_trusts() can hang. Unfortunately I've not in a position to get a sniff at the site that is affected. I suspect a full fix will involve ensuring that all the rpc code paths have appropriate timeouts. (This used to be commit ab8d41053347a5b342ed5b59a0b0dd4983ca91e6) --- source3/libsmb/trustdom_cache.c | 45 ++++++++++++----------------------------- 1 file changed, 13 insertions(+), 32 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index fa35f8d423..dc0b5010a2 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -250,24 +250,6 @@ BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout ) } -/******************************************************************* - lock the timestamp entry in the trustdom_cache -*******************************************************************/ - -BOOL trustdom_cache_lock_timestamp( void ) -{ - return gencache_lock_entry( TDOMTSKEY ) != -1; -} - -/******************************************************************* - unlock the timestamp entry in the trustdom_cache -*******************************************************************/ - -void trustdom_cache_unlock_timestamp( void ) -{ - gencache_unlock_entry( TDOMTSKEY ); -} - /** * Delete single trustdom entry. Look at the * gencache_iterate definition. @@ -314,8 +296,7 @@ void update_trustdom_cache( void ) time_t now = time(NULL); int i; - /* get the timestamp. We have to initialise it if the last timestamp == 0 */ - + /* get the timestamp. We have to initialise it if the last timestamp == 0 */ if ( (last_check = trustdom_cache_fetch_timestamp()) == 0 ) trustdom_cache_store_timestamp(0, now+TRUSTDOM_UPDATE_INTERVAL); @@ -325,11 +306,12 @@ void update_trustdom_cache( void ) DEBUG(10,("update_trustdom_cache: not time to update trustdom_cache yet\n")); return; } + + /* note that we don't lock the timestamp. This prevents this + smbd from blocking all other smbd daemons while we + enumerate the trusted domains */ + trustdom_cache_store_timestamp(now, now+TRUSTDOM_UPDATE_INTERVAL); - /* lock the timestamp */ - if ( !trustdom_cache_lock_timestamp() ) - return; - if ( !(mem_ctx = talloc_init("update_trustdom_cache")) ) { DEBUG(0,("update_trustdom_cache: talloc_init() failed!\n")); goto done; @@ -338,20 +320,19 @@ void update_trustdom_cache( void ) /* get the domains and store them */ if ( enumerate_domain_trusts(mem_ctx, lp_workgroup(), &domain_names, - &num_domains, &dom_sids) ) - { + &num_domains, &dom_sids)) { for ( i=0; i Date: Sat, 13 Jan 2007 22:26:46 +0000 Subject: r20744: Fix the build (I missed some chkpth -> checkpath renames). Jeremy. (This used to be commit 89b7a0630de0bd95a56263b36d433b4e73517a70) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ad84ec0324..2ebd960d81 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1372,7 +1372,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); - SCVAL(cli->outbuf,smb_com,SMBchkpth); + SCVAL(cli->outbuf,smb_com,SMBcheckpath); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); -- cgit From 62e11c4f1748d98f479110c8c0e656a8f65dca4d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 16 Jan 2007 15:42:03 +0000 Subject: r20832: Remove extra pointers previously added to unique [out] pointers. Instead, add [ref] pointers where necessary (top-level [ref] pointers, by spec, don't appear on the wire). This brings us closer to the DCE/RPC standard again. (This used to be commit 580f2a7197b1bc9db14a643fdd112b40ef37aaef) --- source3/libsmb/libsmbclient.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index d9a39b1249..4778274ca9 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2477,7 +2477,6 @@ net_share_enum_rpc(struct cli_state *cli, int i; NTSTATUS result; uint32 enum_hnd; - uint32 *penum_hnd = &enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; struct srvsvc_NetShareCtr1 ctr1; @@ -2509,7 +2508,7 @@ net_share_enum_rpc(struct cli_state *cli, enum_hnd = 0; result = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL, &info_level, &ctr, preferred_len, - &numentries, &penum_hnd); + &numentries, &enum_hnd); /* Was it successful? */ if (!NT_STATUS_IS_OK(result) || numentries == 0) { -- cgit From bfd099e148ed97394bc858e746a1a998a71ac43c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Jan 2007 18:25:35 +0000 Subject: r20857: Silence gives assent :-). Checking in the fix for site support in a network where many DC's are down. I heard via Volker there is still a bug w.r.t the wrong site being chosen with trusted domains but we'll have to layer that fix on top of this. Gd - complain if this doesn't work for you. Jeremy. (This used to be commit 97e248f89ac6548274f03f2ae7583a255da5ddb3) --- source3/libsmb/namequery.c | 58 +++++++++++++++++++++++++++---------------- source3/libsmb/namequery_dc.c | 3 ++- 2 files changed, 38 insertions(+), 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 065bb810c5..6ebc26b8cb 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -384,7 +384,7 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) compare 2 ldap IPs by nearness to our interfaces - used in qsort *******************************************************************/ -static int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2) +int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2) { int result; @@ -1049,6 +1049,7 @@ static BOOL resolve_hosts(const char *name, int name_type, *********************************************************/ static BOOL resolve_ads(const char *name, int name_type, + const char *sitename, struct ip_service **return_iplist, int *return_count) { int i, j; @@ -1070,9 +1071,9 @@ static BOOL resolve_ads(const char *name, int name_type, } if (name_type == KDC_NAME_TYPE) { - status = ads_dns_query_kdcs(ctx, name, &dcs, &numdcs); + status = ads_dns_query_kdcs(ctx, name, sitename, &dcs, &numdcs); } else { - status = ads_dns_query_dcs(ctx, name, &dcs, &numdcs); + status = ads_dns_query_dcs(ctx, name, sitename, &dcs, &numdcs); } if ( !NT_STATUS_IS_OK( status ) ) { talloc_destroy(ctx); @@ -1145,6 +1146,7 @@ static BOOL resolve_ads(const char *name, int name_type, **********************************************************************/ BOOL internal_resolve_name(const char *name, int name_type, + const char *sitename, struct ip_service **return_iplist, int *return_count, const char *resolve_order) { @@ -1160,7 +1162,8 @@ BOOL internal_resolve_name(const char *name, int name_type, *return_iplist = NULL; *return_count = 0; - DEBUG(10, ("internal_resolve_name: looking up %s#%x\n", name, name_type)); + DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n", + name, name_type, sitename ? sitename : NULL)); if (allzeros || allones || is_address) { @@ -1223,7 +1226,7 @@ BOOL internal_resolve_name(const char *name, int name_type, } else if(strequal( tok, "kdc")) { /* deal with KDC_NAME_TYPE names here. This will result in a SRV record lookup */ - if (resolve_ads(name, KDC_NAME_TYPE, return_iplist, return_count)) { + if (resolve_ads(name, KDC_NAME_TYPE, sitename, return_iplist, return_count)) { result = True; /* Ensure we don't namecache this with the KDC port. */ name_type = KDC_NAME_TYPE; @@ -1232,7 +1235,7 @@ BOOL internal_resolve_name(const char *name, int name_type, } else if(strequal( tok, "ads")) { /* deal with 0x1c names here. This will result in a SRV record lookup */ - if (resolve_ads(name, name_type, return_iplist, return_count)) { + if (resolve_ads(name, name_type, sitename, return_iplist, return_count)) { result = True; goto done; } @@ -1308,14 +1311,16 @@ BOOL internal_resolve_name(const char *name, int name_type, BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) { struct ip_service *ip_list = NULL; + char *sitename = sitename_fetch(); int count = 0; if (is_ipaddress(name)) { *return_ip = *interpret_addr2(name); + SAFE_FREE(sitename); return True; } - if (internal_resolve_name(name, name_type, &ip_list, &count, lp_name_resolve_order())) { + if (internal_resolve_name(name, name_type, sitename, &ip_list, &count, lp_name_resolve_order())) { int i; /* only return valid addresses for TCP connections */ @@ -1327,12 +1332,14 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) { *return_ip = ip_list[i].ip; SAFE_FREE(ip_list); + SAFE_FREE(sitename); return True; } } } SAFE_FREE(ip_list); + SAFE_FREE(sitename); return False; } @@ -1350,12 +1357,12 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) return False; } - if (internal_resolve_name(group, 0x1D, &ip_list, &count, lp_name_resolve_order())) { + if (internal_resolve_name(group, 0x1D, NULL, &ip_list, &count, lp_name_resolve_order())) { *master_ip = ip_list[0].ip; SAFE_FREE(ip_list); return True; } - if(internal_resolve_name(group, 0x1B, &ip_list, &count, lp_name_resolve_order())) { + if(internal_resolve_name(group, 0x1B, NULL, &ip_list, &count, lp_name_resolve_order())) { *master_ip = ip_list[0].ip; SAFE_FREE(ip_list); return True; @@ -1372,15 +1379,19 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) BOOL get_pdc_ip(const char *domain, struct in_addr *ip) { - struct ip_service *ip_list; - int count; + char *sitename = sitename_fetch(); + struct ip_service *ip_list = NULL; + int count = 0; /* Look up #1B name */ - if (!internal_resolve_name(domain, 0x1b, &ip_list, &count, lp_name_resolve_order())) { + if (!internal_resolve_name(domain, 0x1b, sitename, &ip_list, &count, lp_name_resolve_order())) { + SAFE_FREE(sitename); return False; } + SAFE_FREE(sitename); + /* if we get more than 1 IP back we have to assume it is a multi-homed PDC and not a mess up */ @@ -1405,7 +1416,7 @@ enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY }; a domain. *********************************************************/ -static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, +static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list, int *count, enum dc_lookup_type lookup_type, int *ordered) { fstring resolve_order; @@ -1452,7 +1463,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, /* fetch the server we have affinity for. Add the 'password server' list to a search for our domain controllers */ - saf_servername = saf_fetch( domain ); + saf_servername = saf_fetch( domain); if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) { pstr_sprintf( pserver, "%s, %s", @@ -1471,7 +1482,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, DEBUG(10,("get_dc_list: no preferred domain controllers.\n")); /* TODO: change return type of internal_resolve_name to * NTSTATUS */ - if (internal_resolve_name(domain, 0x1C, ip_list, count, + if (internal_resolve_name(domain, 0x1C, sitename, ip_list, count, resolve_order)) { return NT_STATUS_OK; } else { @@ -1491,7 +1502,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, p = pserver; while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) { - if (internal_resolve_name(domain, 0x1C, &auto_ip_list, + if (internal_resolve_name(domain, 0x1C, sitename, &auto_ip_list, &auto_count, resolve_order)) num_addresses += auto_count; done_auto_lookup = True; @@ -1510,7 +1521,7 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, SAFE_FREE(auto_ip_list); return NT_STATUS_NO_LOGON_SERVERS; } - if (internal_resolve_name(domain, 0x1C, ip_list, count, + if (internal_resolve_name(domain, 0x1C, sitename, ip_list, count, resolve_order)) { return NT_STATUS_OK; } else { @@ -1606,20 +1617,23 @@ static NTSTATUS get_dc_list(const char *domain, struct ip_service **ip_list, Small wrapper function to get the DC list and sort it if neccessary. *********************************************************************/ -NTSTATUS get_sorted_dc_list( const char *domain, struct ip_service **ip_list, int *count, BOOL ads_only ) +NTSTATUS get_sorted_dc_list( const char *domain, const char *sitename, struct ip_service **ip_list, int *count, BOOL ads_only ) { BOOL ordered; NTSTATUS status; enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP; - DEBUG(8,("get_sorted_dc_list: attempting lookup using [%s]\n", + DEBUG(8,("get_sorted_dc_list: attempting lookup for name %s (sitename %s) " + "using [%s]\n", + domain, + sitename ? sitename : "NULL", (ads_only ? "ads" : lp_name_resolve_order()))); if (ads_only) { lookup_type = DC_ADS_ONLY; } - status = get_dc_list(domain, ip_list, count, lookup_type, &ordered); + status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -1636,7 +1650,7 @@ NTSTATUS get_sorted_dc_list( const char *domain, struct ip_service **ip_list, in Get the KDC list - re-use all the logic in get_dc_list. *********************************************************************/ -NTSTATUS get_kdc_list( const char *realm, struct ip_service **ip_list, int *count) +NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_service **ip_list, int *count) { BOOL ordered; NTSTATUS status; @@ -1644,7 +1658,7 @@ NTSTATUS get_kdc_list( const char *realm, struct ip_service **ip_list, int *coun *count = 0; *ip_list = NULL; - status = get_dc_list(realm, ip_list, count, DC_KDC_ONLY, &ordered); + status = get_dc_list(realm, sitename, ip_list, count, DC_KDC_ONLY, &ordered); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 375d39a5fd..a240510b77 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -104,6 +104,7 @@ static BOOL ads_dc_name(const char *domain, create_local_private_krb5_conf_for_domain(realm, domain, + sitename, ads->ldap_ip); } #endif @@ -146,7 +147,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip /* get a list of all domain controllers */ - if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, &ip_list, &count, + if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count, False))) { DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); return False; -- cgit From e65d9b45986dd659b96ed022a739b08dd45799e6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 17 Jan 2007 19:14:34 +0000 Subject: r20861: We only use sitespecific DNS lookups when looking for DCs or KDCs, not for a PDC. Guenther (This used to be commit 0944c7861004bee2a9d0ac787f022f5bf1d181ac) --- source3/libsmb/namequery.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6ebc26b8cb..1f32d3bc37 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1379,19 +1379,15 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) BOOL get_pdc_ip(const char *domain, struct in_addr *ip) { - char *sitename = sitename_fetch(); struct ip_service *ip_list = NULL; int count = 0; /* Look up #1B name */ - if (!internal_resolve_name(domain, 0x1b, sitename, &ip_list, &count, lp_name_resolve_order())) { - SAFE_FREE(sitename); + if (!internal_resolve_name(domain, 0x1b, NULL, &ip_list, &count, lp_name_resolve_order())) { return False; } - SAFE_FREE(sitename); - /* if we get more than 1 IP back we have to assume it is a multi-homed PDC and not a mess up */ -- cgit From e9c294b926c0b831fd936194342ec0564f935798 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 18 Jan 2007 09:58:57 +0000 Subject: r20874: We need to distinguish client sitenames per realm. We were overwriting the stored client sitename with the sitename from each sucessfull CLDAP connection. Guenther (This used to be commit 6a13e878b5d299cb3b3d7cb33ee0d51089d9228d) --- source3/libsmb/namequery.c | 2 +- source3/libsmb/namequery_dc.c | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 1f32d3bc37..cbd94ff567 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1311,7 +1311,7 @@ BOOL internal_resolve_name(const char *name, int name_type, BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) { struct ip_service *ip_list = NULL; - char *sitename = sitename_fetch(); + char *sitename = sitename_fetch(lp_realm()); /* wild guess */ int count = 0; if (is_ipaddress(name)) { diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index a240510b77..110b9986b7 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -53,13 +53,15 @@ static BOOL ads_dc_name(const char *domain, fstring srv_name) { ADS_STRUCT *ads; - char *sitename = sitename_fetch(); + char *sitename; int i; if (!realm && strequal(domain, lp_workgroup())) { realm = lp_realm(); } + sitename = sitename_fetch(realm); + /* Try this 3 times then give up. */ for( i =0 ; i < 3; i++) { ads = ads_init(realm, domain, NULL); @@ -86,9 +88,9 @@ static BOOL ads_dc_name(const char *domain, has changed. If so, we need to re-do the DNS query to ensure we only find servers in our site. */ - if (stored_sitename_changed(sitename)) { + if (stored_sitename_changed(realm, sitename)) { SAFE_FREE(sitename); - sitename = sitename_fetch(); + sitename = sitename_fetch(realm); ads_destroy(&ads); /* Ensure we don't cache the DC we just connected to. */ namecache_delete(realm, 0x1C); -- cgit From c9a14ea19f812d86266bfa9e6ce8b32f7b4ff19f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Jan 2007 21:51:52 +0000 Subject: r20883: W00t! I now understand how "delete on close" really works - even with the strange "initial delete on close" semantics. The "initial delete on close" flag isn't committed to the share mode db until the handle is closed, and is discarded if any real "delete on close" was set. This allows me to remove the "initial_delete_on_close" flag from the share db, and move it into a BOOL in files_struct. Warning ! You must do a make clean after this. Cope with the wrinkle in directory delete on close which is done differently from files. We now pass all Samba4 smbtortute BASE-DELETE tests except for the one checking that files can't be created in a directory which has the delete on close set (possibly expensive to fix). Jeremy. (This used to be commit f2df77a1497958c1ea791f1d2f4446b5fc3389b3) --- source3/libsmb/smb_share_modes.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index b62240ce50..b8c7a7e66b 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -274,7 +274,6 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, memset(ld, '\0', sizeof(struct locking_data)); ld->u.s.num_share_mode_entries = 1; ld->u.s.delete_on_close = 0; - ld->u.s.initial_delete_on_close = 0; ld->u.s.delete_token_size = 0; shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); create_share_mode_entry(shares, new_entry); -- cgit From 594ab518a581f3728c82bdb9cf563e5fa449c0e1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 29 Jan 2007 21:15:25 +0000 Subject: r21046: Backing out svn r20403 (Andrew's krb5 ticket cleanup as this is causing the WRONG_PASSWORD error in the SetUserInfo() call during net ads join). We are now back to always list RC4-HMAC first if supported by the krb5 libraries. (This used to be commit 4fb57bce87588ac4898588ea4988eadff3a7f435) --- source3/libsmb/clikrb5.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 0df45f1b4d..4092b4b2b9 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -130,6 +130,35 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, } #endif +#if !defined(HAVE_KRB5_SET_DEFAULT_TGS_KTYPES) + +#if defined(HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES) + +/* With MIT kerberos, we should use krb5_set_default_tgs_enctypes in preference + * to krb5_set_default_tgs_ktypes. See + * http://lists.samba.org/archive/samba-technical/2006-July/048271.html + * + * If the MIT libraries are not exporting internal symbols, we will end up in + * this branch, which is correct. Otherwise we will continue to use the + * internal symbol + */ + krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) +{ + return krb5_set_default_tgs_enctypes(ctx, enc); +} + +#elif defined(HAVE_KRB5_SET_DEFAULT_IN_TKT_ETYPES) + +/* Heimdal */ + krb5_error_code krb5_set_default_tgs_ktypes(krb5_context ctx, const krb5_enctype *enc) +{ + return krb5_set_default_in_tkt_etypes(ctx, enc); +} + +#endif /* HAVE_KRB5_SET_DEFAULT_TGS_ENCTYPES */ + +#endif /* HAVE_KRB5_SET_DEFAULT_TGS_KTYPES */ + #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* HEIMDAL */ void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) @@ -612,6 +641,13 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, krb5_context context = NULL; krb5_ccache ccdef = NULL; krb5_auth_context auth_context = NULL; + krb5_enctype enc_types[] = { +#ifdef ENCTYPE_ARCFOUR_HMAC + ENCTYPE_ARCFOUR_HMAC, +#endif + ENCTYPE_DES_CBC_MD5, + ENCTYPE_DES_CBC_CRC, + ENCTYPE_NULL}; initialize_krb5_error_table(); retval = krb5_init_context(&context); @@ -632,6 +668,12 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, goto failed; } + if ((retval = krb5_set_default_tgs_ktypes(context, enc_types))) { + DEBUG(1,("cli_krb5_get_ticket: krb5_set_default_tgs_ktypes failed (%s)\n", + error_message(retval))); + goto failed; + } + if ((retval = ads_krb5_mk_req(context, &auth_context, AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts, -- cgit From 1898eaddb805e86d0c36bd289e7fa61d7bbd4810 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 1 Feb 2007 15:10:13 +0000 Subject: r21110: Fix kinit with Heimdal (Bug #4226). Guenther (This used to be commit ea38e1f8362d75e7ac058a7c4aa06f1ca92ec108) --- source3/libsmb/clikrb5.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 4092b4b2b9..305139e1f4 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1379,6 +1379,32 @@ done: return ret; } +#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC + krb5_error_code krb5_get_init_creds_opt_alloc(krb5_context context, krb5_get_init_creds_opt **opt) +{ + krb5_get_init_creds_opt *my_opt; + + *opt = NULL; + + if ((my_opt = SMB_MALLOC(sizeof(krb5_get_init_creds_opt))) == NULL) { + return ENOMEM; + } + + krb5_get_init_creds_opt_init(my_opt); + + *opt = my_opt; + return 0; +} +#endif + +#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE + void krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opt) +{ + SAFE_FREE(opt); + opt = NULL; +} +#endif + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, -- cgit From 69d8c5ae5f1319e3c9430aa7d6d09ca2a62ba10a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Feb 2007 19:29:07 +0000 Subject: r21115: notify_internal.c needs to remove the table entry if a process has crashed. So it needs the specific error message. Make messages.c return NTSTATUS and specificially NT_STATUS_INVALID_HANDLE if sending to a non-existent process. Volker (This used to be commit 3f620d181da0c356c8ffbdb5b380ccab3645a972) --- source3/libsmb/clidgram.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index dfb613238f..a983f485ab 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -101,8 +101,9 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot, DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip))); - return message_send_pid(pid_to_procid(nmbd_pid), MSG_SEND_PACKET, &p, sizeof(p), - False); + return NT_STATUS_IS_OK(message_send_pid(pid_to_procid(nmbd_pid), + MSG_SEND_PACKET, &p, sizeof(p), + False)); } /* -- cgit From 7bcf281c9ca60e0d2caea33cdc5a18a33e4d6145 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 3 Feb 2007 17:13:58 +0000 Subject: r21132: - Fixes bug 4366. Documentation for smbc_utimes() was incorrect. - Should fix bug 4115 (but needs confirmation from OP). If the kerberos use flag is set in the context, then also pass it to smbc_attr_server for use by cli_full_connection() - Should fix bug 4309 (but needs confirmation from OP). We no longer send a keepalive packet unconditionally. Instead, we assume (yes, possibly incorrectly, but it's the best guess we can make) that if the connection is on port 139, it's netbios and otherwise, it isn't. If netbios is in use, we send a keepalive packet. Otherwise, we check that the connection is alive using getpeername(). (This used to be commit 2f9be59c10ef991a51cc858ab594187b5ca61382) --- source3/libsmb/libsmbclient.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 4778274ca9..48f6c3a9c2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -499,8 +499,30 @@ static int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - if ( send_keepalive(server->cli->fd) == False ) - return 1; + int size; + struct sockaddr addr; + + /* + * Although the use of port 139 is not a guarantee that we're using + * netbios, we assume so. We don't want to send a keepalive packet if + * not netbios because it's not valid, and Vista, at least, + * disconnects the client on such a request. + */ + if (server->cli->port == 139) { + /* Assuming netbios. Send a keepalive packet */ + if ( send_keepalive(server->cli->fd) == False ) { + return 1; + } + } else { + /* + * Assuming not netbios. Try a different method to detect if + * the connection is still alive. + */ + size = sizeof(addr); + if (getpeername(server->cli->fd, &addr, &size) == -1) { + return 1; + } + } /* connection is ok */ return 0; @@ -917,6 +939,7 @@ smbc_attr_server(SMBCCTX *context, fstring password, POLICY_HND *pol) { + int flags; struct in_addr ip; struct cli_state *ipc_cli; struct rpc_pipe_client *pipe_hnd; @@ -951,12 +974,17 @@ smbc_attr_server(SMBCCTX *context, } } + flags = 0; + if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { + flags |= CLI_FULL_CONNECTION_USE_KERBEROS; + } + zero_ip(&ip); nt_status = cli_full_connection(&ipc_cli, global_myname(), server, &ip, 0, "IPC$", "?????", username, workgroup, - password, 0, + password, flags, Undefined, NULL); if (! NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("cli_full_connection failed! (%s)\n", -- cgit From 7b3f62e057ff29bb3359398aa2cfbd12f3d7bcdc Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 3 Feb 2007 17:20:53 +0000 Subject: r21133: - Apply patch from ages ago, which should allow following \\server\share\path DFS referrals. This doesn't appear to break anything in the non-DFS case, but I don't have an environment to test DFS referrals. Need confirmation from OP that this solves the problem. (This used to be commit e479a9c094fa42354aad7aa76a712bf67d3d4d45) --- source3/libsmb/clidfs.c | 37 +++++++++++++++++++++++++++---------- 1 file changed, 27 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 916e4cefc6..93ac2ae58b 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -354,13 +354,13 @@ void cli_cm_set_dest_ip(struct in_addr ip ) have_ip = True; } -/******************************************************************** - split a dfs path into the server and share name components -********************************************************************/ +/********************************************************************** + split a dfs path into the server, share name, and extrapath components +**********************************************************************/ -static void split_dfs_path( const char *nodepath, fstring server, fstring share ) +static void split_dfs_path( const char *nodepath, fstring server, fstring share, fstring extrapath ) { - char *p; + char *p, *q; pstring path; pstrcpy( path, nodepath ); @@ -368,7 +368,7 @@ static void split_dfs_path( const char *nodepath, fstring server, fstring share if ( path[0] != '\\' ) return; - p = strrchr_m( path, '\\' ); + p = strchr_m( path + 1, '\\' ); if ( !p ) return; @@ -376,6 +376,16 @@ static void split_dfs_path( const char *nodepath, fstring server, fstring share *p = '\0'; p++; + /* Look for any extra/deep path */ + q = strchr_m(p, '\\'); + if (q != NULL) { + *q = '\0'; + q++; + fstrcpy( extrapath, q ); + } else { + fstrcpy( extrapath, '\0' ); + } + fstrcpy( share, p ); fstrcpy( server, &path[1] ); } @@ -576,13 +586,13 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha size_t num_refs; uint16 consumed; struct cli_state *cli_ipc; - pstring fullpath, cleanpath; + pstring fullpath, cleanpath, extrapath; int pathlen; fstring server, share; struct cli_state *newcli; pstring newpath; pstring newmount; - char *ppath; + char *ppath, *temppath = NULL; SMB_STRUCT_STAT sbuf; uint32 attributes; @@ -637,8 +647,14 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha consumed = MIN(pathlen, consumed ); pstrcpy( targetpath, &fullpath[consumed/2] ); - split_dfs_path( refs[0].dfspath, server, share ); + split_dfs_path( refs[0].dfspath, server, share, extrapath ); SAFE_FREE( refs ); + + if (strlen(extrapath) > 0) { + string_append(&temppath, extrapath); + string_append(&temppath, targetpath); + pstrcpy( targetpath, temppath ); + } /* open the connection to the target path */ @@ -690,6 +706,7 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, pstring fullpath; BOOL res; uint16 cnum; + fstring newextrapath; if ( !cli || !sharename ) return False; @@ -725,7 +742,7 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, return False; } - split_dfs_path( refs[0].dfspath, newserver, newshare ); + split_dfs_path( refs[0].dfspath, newserver, newshare, newextrapath ); /* check that this is not a self-referral */ -- cgit From 7a5fa7f12ec439ef5a4af29aa86498f799b6b9a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Feb 2007 21:05:34 +0000 Subject: r21191: Add in the POSIX open/mkdir/unlink calls. Move more error code returns to NTSTATUS. Client test code to follow... See if this passes the build-farm before I add it into 3.0.25. Jeremy. (This used to be commit 83dbbdff345fa9e427c9579183f4380004bf3dd7) --- source3/libsmb/smb_share_modes.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index b8c7a7e66b..4c49ecb7bd 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -154,6 +154,7 @@ static void create_share_mode_entry(struct share_mode_entry *out, out->dev = (SMB_DEV_T)in->dev; out->inode = (SMB_INO_T)in->ino; out->uid = (uint32)geteuid(); + out->flags = 0; } /* -- cgit From e6ce37679f121672802ea69e21d16ea360364389 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 8 Feb 2007 14:55:21 +0000 Subject: r21239: if the workgroup name is longer than 16 chars we get garbage in the string server_len is usually 256 (fstring). Correctly terminate saving the lenght (This used to be commit e7e44554bf7c61020e2c5c652e3f8f37a296d3aa) --- source3/libsmb/libsmbclient.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 48f6c3a9c2..b3c873145f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -339,14 +339,15 @@ smbc_parse_path(SMBCCTX *context, goto decoding; if (*p == '/') { + int wl = strlen(context->workgroup); - strncpy(server, context->workgroup, - ((strlen(context->workgroup) < 16) - ? strlen(context->workgroup) - : 16)); - server[server_len - 1] = '\0'; + if (wl > 16) { + wl = 16; + } + + strncpy(server, context->workgroup, wl); + server[wl] = '\0'; return 0; - } /* -- cgit From 69cee2a3ec4f39aab83a8cbf55307df182bf3065 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 Feb 2007 17:02:39 +0000 Subject: r21240: Fix longstanding Bug #4009. For the winbind cached ADS LDAP connection handling (ads_cached_connection()) we were (incorrectly) assuming that the service ticket lifetime equaled the tgt lifetime. For setups where the service ticket just lives 10 minutes, we were leaving hundreds of LDAP connections in CLOSE_WAIT state, until we fail to service entirely with "Too many open files". Also sequence_number() in winbindd_ads.c needs to delete the cached LDAP connection after the ads_do_search_retry() has failed to submit the search request (although the bind succeeded (returning an expired service ticket that we cannot delete from the memory cred cache - this will get fixed later)). Guenther (This used to be commit 7e1a84b7226fb8dcd5d34c64a3478a6d886a9a91) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clikrb5.c | 20 +++++++++++++++----- source3/libsmb/clispnego.c | 6 ++++-- 3 files changed, 20 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f29449cfb2..2742d70194 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -554,7 +554,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * DEBUG(2,("Doing kerberos session setup\n")); /* generate the encapsulated kerberos5 ticket */ - rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0); + rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL); if (rc) { DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc))); diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 305139e1f4..f06a19b345 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -551,7 +551,8 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, const krb5_flags ap_req_options, const char *principal, krb5_ccache ccache, - krb5_data *outbuf) + krb5_data *outbuf, + time_t *expire_time) { krb5_error_code retval; krb5_principal server; @@ -584,6 +585,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, } while (!creds_ready && (i < maxtries)) { + if ((retval = krb5_get_credentials(context, 0, ccache, &creds, &credsp))) { DEBUG(1,("ads_krb5_mk_req: krb5_get_credentials failed for %s (%s)\n", @@ -599,8 +601,9 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_set_real_time(context, t + time_offset + 1, 0); } - if (!ads_cleanup_expired_creds(context, ccache, credsp)) + if (!ads_cleanup_expired_creds(context, ccache, credsp)) { creds_ready = True; + } i++; } @@ -610,6 +613,10 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, http_timestring((unsigned)credsp->times.endtime), (unsigned)credsp->times.endtime)); + if (expire_time) { + *expire_time = (time_t)credsp->times.endtime; + } + in_data.length = 0; retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); @@ -634,7 +641,9 @@ cleanup_princ: */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, - uint32 extra_ap_opts, const char *ccname) + uint32 extra_ap_opts, const char *ccname, + time_t *tgs_expire) + { krb5_error_code retval; krb5_data packet; @@ -678,7 +687,8 @@ int cli_krb5_get_ticket(const char *principal, time_t time_offset, &auth_context, AP_OPTS_USE_SUBKEY | (krb5_flags)extra_ap_opts, principal, - ccdef, &packet))) { + ccdef, &packet, + tgs_expire))) { goto failed; } @@ -1409,7 +1419,7 @@ done: /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, DATA_BLOB *ticket, DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, - const char *ccname) + const char *ccname, time_t *tgs_expire) { DEBUG(0,("NO KERBEROS SUPPORT\n")); return 1; diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a01c009b6e..6aca217e25 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -343,7 +343,8 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) */ int spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *targ, - DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) + DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, + time_t *expire_time) { int retval; DATA_BLOB tkt, tkt_wrapped; @@ -351,7 +352,8 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, /* get a kerberos ticket for the service and extract the session key */ retval = cli_krb5_get_ticket(principal, time_offset, - &tkt, session_key_krb5, extra_ap_opts, NULL); + &tkt, session_key_krb5, extra_ap_opts, NULL, + expire_time); if (retval) return retval; -- cgit From f77bdcf6c71a9d0274d96298b136300d5bb05bb1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Feb 2007 06:22:20 +0000 Subject: r21460: Fix for server-side processing of SPNEGO auth fragmented into "max xmit" size security blob chunks. Bug #4400. Needs limits adding, and also a client-side version. Jeremy. (This used to be commit aa69f2481aafee5dccc3783b8a6e23ca4eb0dbfa) --- source3/libsmb/asn1.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 937e063c62..6ebe9ab62c 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -23,6 +23,14 @@ /* free an asn1 structure */ void asn1_free(ASN1_DATA *data) { + struct nesting *nesting = data->nesting; + + while (nesting) { + struct nesting *nnext = nesting->next; + free(nesting); + nesting = nnext; + }; + data->nesting = NULL; SAFE_FREE(data->data); } -- cgit From 3e12cf85ace31638d2dd924cc202c9d2f31f7890 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Feb 2007 00:35:58 +0000 Subject: r21576: Patch based on work from Todd Stecher to allow client to fragment large SPNEGO blobs (large krb5 tickets). Tested against W2K3R2. Should fix bug #4400. Jeremy. (This used to be commit b81c5c6adce51cec06df0e993534064b20666a8e) --- source3/libsmb/cliconnect.c | 90 +++++++++++++++++++++++++++++++++++++-------- source3/libsmb/clierror.c | 9 +++++ 2 files changed, 83 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2742d70194..886f19b3df 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -517,19 +517,78 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) } #ifdef HAVE_KRB5 - /**************************************************************************** Send a extended security session setup blob, returning a reply blob. ****************************************************************************/ -static DATA_BLOB cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob) +#define MAX_SESSION_SECURITY_BLOB 4000 + +/* The following is calculated from : + * (smb_size-4) = 35 + * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() ) + * (strlen("Unix") + 1 + strlen("Samba") + 1) * 2 = 22 (unicode strings at + * end of packet. + */ + +#define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22) + +static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_BLOB session_key_krb5) { - DATA_BLOB blob2 = data_blob(NULL, 0); - if (!cli_session_setup_blob_send(cli, blob)) { - return blob2; + int32 remaining = blob.length; + int32 cur = 0; + DATA_BLOB send_blob = data_blob(NULL, 0); + int32 max_blob_size = 0; + + if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) { + DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small " + "(was %u, need minimum %u)\n", + (unsigned int)cli->max_xmit, + BASE_SESSSETUP_BLOB_PACKET_SIZE)); + cli_set_nt_error(cli, NT_STATUS_INVALID_PARAMETER); + return False; } - - return cli_session_setup_blob_receive(cli); + + max_blob_size = cli->max_xmit - BASE_SESSSETUP_BLOB_PACKET_SIZE; + + while ( remaining > 0) { + if (remaining >= max_blob_size) { + send_blob.length = max_blob_size; + remaining -= max_blob_size; + } else { + DATA_BLOB null_blob = data_blob(NULL, 0); + + send_blob.length = remaining; + remaining = 0; + + /* This is the last packet in the sequence - turn signing on. */ + cli_simple_set_signing(cli, session_key_krb5, null_blob); + } + + send_blob.data = &blob.data[cur]; + cur += send_blob.length; + + DEBUG(10, ("cli_session_setup_blob: Remaining (%u) sending (%u) current (%u)\n", + (unsigned int)remaining, + (unsigned int)send_blob.length, + (unsigned int)cur )); + + if (!cli_session_setup_blob_send(cli, send_blob)) { + DEBUG(0, ("cli_session_setup_blob: send failed\n")); + return False; + } + + cli_session_setup_blob_receive(cli); + + if (cli_is_error(cli) && + !NT_STATUS_EQUAL( cli_get_nt_error(cli), + NT_STATUS_MORE_PROCESSING_REQUIRED)) { + DEBUG(0, ("cli_session_setup_blob: recieve failed (%s)\n", + nt_errstr(cli_get_nt_error(cli)) )); + return False; + } + } + + return True; } /**************************************************************************** @@ -546,9 +605,8 @@ static void use_in_memory_ccache(void) { static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char *principal, const char *workgroup) { - DATA_BLOB blob2, negTokenTarg; + DATA_BLOB negTokenTarg; DATA_BLOB session_key_krb5; - DATA_BLOB null_blob = data_blob(NULL, 0); int rc; DEBUG(2,("Doing kerberos session setup\n")); @@ -557,7 +615,8 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * rc = spnego_gen_negTokenTarg(principal, 0, &negTokenTarg, &session_key_krb5, 0, NULL); if (rc) { - DEBUG(1, ("spnego_gen_negTokenTarg failed: %s\n", error_message(rc))); + DEBUG(1, ("cli_session_setup_kerberos: spnego_gen_negTokenTarg failed: %s\n", + error_message(rc))); return ADS_ERROR_KRB5(rc); } @@ -565,12 +624,11 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * file_save("negTokenTarg.dat", negTokenTarg.data, negTokenTarg.length); #endif - cli_simple_set_signing(cli, session_key_krb5, null_blob); - - blob2 = cli_session_setup_blob(cli, negTokenTarg); - - /* we don't need this blob for kerberos */ - data_blob_free(&blob2); + if (!cli_session_setup_blob(cli, negTokenTarg, session_key_krb5)) { + data_blob_free(&negTokenTarg); + data_blob_free(&session_key_krb5); + ADS_ERROR_NT(cli_nt_error(cli)); + } cli_set_session_key(cli, session_key_krb5); diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index fcedc3bdab..f85fc5c552 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -451,3 +451,12 @@ NTSTATUS cli_get_nt_error(struct cli_state *cli) return NT_STATUS_UNSUCCESSFUL; } } + +/* Push an error code into the inbuf to be returned on the next + * query. */ + +void cli_set_nt_error(struct cli_state *cli, NTSTATUS status) +{ + SSVAL(cli->inbuf,smb_flg2, SVAL(cli->inbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); + SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); +} -- cgit From 1aa730ef968dac9c27b1f00668d28e71b5c38b72 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Feb 2007 00:38:49 +0000 Subject: r21577: Remove unneeded #define (part of earlier patch that was removed). Jeremy. (This used to be commit 645b0438dde0dad26e950b3184cc412d3d87560a) --- source3/libsmb/cliconnect.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 886f19b3df..e2213c1fcd 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -521,8 +521,6 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) Send a extended security session setup blob, returning a reply blob. ****************************************************************************/ -#define MAX_SESSION_SECURITY_BLOB 4000 - /* The following is calculated from : * (smb_size-4) = 35 * (smb_wcnt * 2) = 24 (smb_wcnt == 12 in cli_session_setup_blob_send() ) -- cgit From 84d2ceb1df5bfeb179f9eede602496aea353e5ec Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 28 Feb 2007 09:04:05 +0000 Subject: r21581: Add an error code I just got (This used to be commit 5ef0286b56b368abd4da2cbe3d826a3438f3acc3) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index db522556e4..35ebc3d339 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -533,6 +533,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, + { "NT_STATUS_DS_NO_MORE_RIDS", NT_STATUS_DS_NO_MORE_RIDS }, { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, -- cgit From fd5cf34e26215911664c6218ff7e7577e9aa5cd3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Feb 2007 22:29:14 +0000 Subject: r21604: I got this wrong also in libsmb :-(. Jeremy. (This used to be commit 4a04555e23b5fa53fbeb5b65a7c83cff1b0f9640) --- source3/libsmb/clifile.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 2ebd960d81..a559664fb3 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -330,6 +330,8 @@ static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna p += clistr_push(cli, p, fname, -1, STR_TERMINATE); param_len = PTR_DIFF(p, param); + memset(data, 0xff, 40); /* Set all sizes/times to no change. */ + SIVAL(data,40,uid); SIVAL(data,48,gid); SIVAL(data,84,mode); -- cgit From 8e00e9d7a6114089fc176bc3446c6c97a01543d6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Mar 2007 02:43:33 +0000 Subject: r21609: Fix memory leaks in error code paths (and one in winbindd_group.c). Patch from Zack Kirsch . Jeremy. (This used to be commit df07a662e32367a52c1e8473475423db2ff5bc51) --- source3/libsmb/cliquota.c | 2 ++ source3/libsmb/doserr.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 25c36c214f..5627d28bb5 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -323,11 +323,13 @@ BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { DEBUG(0,("talloc_zero() failed\n")); + talloc_destroy(mem_ctx); return (-1); } if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { DEBUG(0,("talloc_zero() failed\n")); + talloc_destroy(mem_ctx); return (-1); } diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 8628db3abc..414c2d4916 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -68,6 +68,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, + { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, @@ -83,8 +84,9 @@ werror_code_struct dos_errs[] = }; /***************************************************************************** - returns a DOS error message. not amazingly helpful, but better than a number. + Returns a DOS error message. not amazingly helpful, but better than a number. *****************************************************************************/ + const char *dos_errstr(WERROR werror) { static pstring msg; -- cgit From c75f0c6126cd0f028bd02e767e052702c1848b99 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Mar 2007 21:05:29 +0000 Subject: r21639: Add in implementations of POSIX open/mkdir/unlink/rmdir. Jeremy. (This used to be commit 6457d66b9a04c421fc43e131c825c7555c16a1ea) --- source3/libsmb/clifile.c | 176 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 176 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a559664fb3..1f547ee305 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1766,3 +1766,179 @@ BOOL cli_get_ea_list_fnum(struct cli_state *cli, int fnum, return cli_get_ea_list(cli, setup, param, 6, ctx, pnum_eas, pea_list); } + +/**************************************************************************** + Convert open "flags" arg to uint32 on wire. +****************************************************************************/ + +static uint32 open_flags_to_wire(int flags) +{ + int open_mode = flags & O_ACCMODE; + uint32 ret = 0; + + switch (open_mode) { + case O_WRONLY: + ret |= SMB_O_WRONLY; + break; + case O_RDWR: + ret |= SMB_O_RDWR; + break; + case O_RDONLY: + default: + ret |= SMB_O_RDONLY; + break; + } + + if (flags & O_CREAT) { + ret |= SMB_O_CREAT; + } + if (flags & O_EXCL) { + ret |= SMB_O_EXCL; + } + if (flags & O_TRUNC) { + ret |= SMB_O_TRUNC; + } + if (flags & O_SYNC) { + ret |= SMB_O_SYNC; + } + if (flags & O_APPEND) { + ret |= SMB_O_APPEND; + } + if (flags & O_DIRECT) { + ret |= SMB_O_DIRECT; + } + if (flags & O_DIRECTORY) { + ret |= SMB_O_DIRECTORY; + } + return ret; +} + +/**************************************************************************** + Open a file - POSIX semantics. Returns fnum. Doesn't request oplock. +****************************************************************************/ + +int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t mode) +{ + unsigned int data_len = 0; + unsigned int param_len = 0; + uint16 setup = TRANSACT2_SETPATHINFO; + char param[sizeof(pstring)+6]; + char data[14]; + char *rparam=NULL, *rdata=NULL; + char *p; + int fnum = -1; + + memset(param, 0, sizeof(param)); + SSVAL(param,0, SMB_POSIX_PATH_OPEN); + p = ¶m[6]; + + p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + /* Convert flags to wire_open_mode. */ + + p = data; + SIVAL(p,0,0); /* No oplock. */ + SIVAL(p,4,open_flags_to_wire(flags)); + SIVAL(p,8,unix_perms_to_wire(mode)); + SSVAL(p,12,SMB_NO_INFO_LEVEL_RETURNED); /* No info level returned. */ + + data_len = 14; + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + return -1; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return -1; + } + + fnum = SVAL(rdata,2); + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return fnum; +} + +/**************************************************************************** + mkdir - POSIX semantics. +****************************************************************************/ + +int cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode) +{ + return (cli_posix_open(cli, fname, O_CREAT|O_DIRECTORY, mode) == -1) ? -1 : 0; +} + +/**************************************************************************** + unlink or rmdir - POSIX semantics. +****************************************************************************/ + +static BOOL cli_posix_unlink_internal(struct cli_state *cli, const char *fname, BOOL is_dir) +{ + unsigned int data_len = 0; + unsigned int param_len = 0; + uint16 setup = TRANSACT2_SETPATHINFO; + char param[sizeof(pstring)+6]; + char data[2]; + char *rparam=NULL, *rdata=NULL; + char *p; + + memset(param, 0, sizeof(param)); + SSVAL(param,0, SMB_POSIX_PATH_UNLINK); + p = ¶m[6]; + + p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); + param_len = PTR_DIFF(p, param); + + SSVAL(data, 0, is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET : + SMB_POSIX_UNLINK_FILE_TARGET); + data_len = 2; + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return False; + } + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + +/**************************************************************************** + unlink - POSIX semantics. +****************************************************************************/ + +BOOL cli_posix_unlink(struct cli_state *cli, const char *fname) +{ + return cli_posix_unlink_internal(cli, fname, False); +} + +/**************************************************************************** + rmdir - POSIX semantics. +****************************************************************************/ + +int cli_posix_rmdir(struct cli_state *cli, const char *fname) +{ + return cli_posix_unlink_internal(cli, fname, True); +} -- cgit From cc294350f99f5ce27b11704555f1a4d62d83cacc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Mar 2007 21:36:05 +0000 Subject: r21640: Fix the build for broken platoforms without O_DIRECT or O_DIRECTORY. Jeremy. (This used to be commit 6a0f6fde0a19bfb4af4c7fa6f29d7015e884d86e) --- source3/libsmb/clifile.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 1f547ee305..ebace8f963 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1804,12 +1804,16 @@ static uint32 open_flags_to_wire(int flags) if (flags & O_APPEND) { ret |= SMB_O_APPEND; } +#if defined(O_DIRECT) if (flags & O_DIRECT) { ret |= SMB_O_DIRECT; } +#endif +#if defined(O_DIRECTORY) if (flags & O_DIRECTORY) { ret |= SMB_O_DIRECTORY; } +#endif return ret; } @@ -1875,7 +1879,12 @@ int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t m int cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode) { +#if defined(O_DIRECTORY) return (cli_posix_open(cli, fname, O_CREAT|O_DIRECTORY, mode) == -1) ? -1 : 0; +#else + cli_set_nt_error(cli, NT_STATUS_NOT_IMPLEMENTED); + return -1; +#endif } /**************************************************************************** -- cgit From 6b8e85866e761752fe87023285ad0294f362bd0d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Mar 2007 22:15:30 +0000 Subject: r21643: Put the correct bits on the wire for posix_mkdir. We're not yet deleting open files on unlink. Investigating... Jeremy. (This used to be commit 334b34f131578c2a889caa90aa2425f41883cafd) --- source3/libsmb/clifile.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ebace8f963..6d7a7dfb6f 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1783,8 +1783,8 @@ static uint32 open_flags_to_wire(int flags) case O_RDWR: ret |= SMB_O_RDWR; break; - case O_RDONLY: default: + case O_RDONLY: ret |= SMB_O_RDONLY; break; } @@ -1811,6 +1811,7 @@ static uint32 open_flags_to_wire(int flags) #endif #if defined(O_DIRECTORY) if (flags & O_DIRECTORY) { + ret &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY); ret |= SMB_O_DIRECTORY; } #endif -- cgit From ea3e890130cbc328ae5c405883c37ae0422e69a2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 1 Mar 2007 22:44:02 +0000 Subject: r21644: Allow mkdir on platforms with no O_DIRECTORY. Add proper debug to all possible setfilepathinfo functions. Jeremy. (This used to be commit 3c47a5ef258d536504759a02f6d84c0ab0af7224) --- source3/libsmb/clifile.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 6d7a7dfb6f..a8f214c771 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1822,7 +1822,7 @@ static uint32 open_flags_to_wire(int flags) Open a file - POSIX semantics. Returns fnum. Doesn't request oplock. ****************************************************************************/ -int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t mode) +static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int flags, mode_t mode, BOOL is_dir) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -1832,6 +1832,7 @@ int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t m char *rparam=NULL, *rdata=NULL; char *p; int fnum = -1; + uint32 wire_flags = open_flags_to_wire(flags); memset(param, 0, sizeof(param)); SSVAL(param,0, SMB_POSIX_PATH_OPEN); @@ -1840,11 +1841,14 @@ int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t m p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); - /* Convert flags to wire_open_mode. */ + if (is_dir) { + wire_flags &= ~(SMB_O_RDONLY|SMB_O_RDWR|SMB_O_WRONLY); + wire_flags |= SMB_O_DIRECTORY; + } p = data; SIVAL(p,0,0); /* No oplock. */ - SIVAL(p,4,open_flags_to_wire(flags)); + SIVAL(p,4,wire_flags); SIVAL(p,8,unix_perms_to_wire(mode)); SSVAL(p,12,SMB_NO_INFO_LEVEL_RETURNED); /* No info level returned. */ @@ -1874,18 +1878,22 @@ int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t m return fnum; } +/**************************************************************************** + open - POSIX semantics. +****************************************************************************/ + +int cli_posix_open(struct cli_state *cli, const char *fname, int flags, mode_t mode) +{ + return cli_posix_open_internal(cli, fname, flags, mode, False); +} + /**************************************************************************** mkdir - POSIX semantics. ****************************************************************************/ int cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode) { -#if defined(O_DIRECTORY) - return (cli_posix_open(cli, fname, O_CREAT|O_DIRECTORY, mode) == -1) ? -1 : 0; -#else - cli_set_nt_error(cli, NT_STATUS_NOT_IMPLEMENTED); - return -1; -#endif + return (cli_posix_open_internal(cli, fname, O_CREAT, mode, True) == -1) ? -1 : 0; } /**************************************************************************** -- cgit From a4bffe0559a7fb47a530d2020f0371a12b6a1d1e Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Mon, 5 Mar 2007 17:02:20 +0000 Subject: r21703: fix build when O_SYNC not defined (This used to be commit 73b7a25ba8a2f7471c07a912da8b6968b41b4f1d) --- source3/libsmb/clifile.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a8f214c771..ac468e0aee 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1798,9 +1798,11 @@ static uint32 open_flags_to_wire(int flags) if (flags & O_TRUNC) { ret |= SMB_O_TRUNC; } +#if defined(O_SYNC) if (flags & O_SYNC) { ret |= SMB_O_SYNC; } +#endif /* O_SYNC */ if (flags & O_APPEND) { ret |= SMB_O_APPEND; } -- cgit From b81b6b31c5da2d4aade3120ea436a0433fbf025f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Mar 2007 19:45:22 +0000 Subject: r21750: Sync up with SAMBA_3_0_25. Only client changes are in libsmbclient right now. Jeremy. (This used to be commit 6dd5f0ef0fe3a673081e16e656ca579bf50457ff) --- source3/libsmb/clifile.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ac468e0aee..76eddd3f63 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -496,7 +496,7 @@ BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *f Delete a file. ****************************************************************************/ -BOOL cli_unlink(struct cli_state *cli, const char *fname) +BOOL cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs) { char *p; @@ -509,7 +509,7 @@ BOOL cli_unlink(struct cli_state *cli, const char *fname) SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv0, attrs); p = smb_buf(cli->outbuf); *p++ = 4; @@ -528,6 +528,15 @@ BOOL cli_unlink(struct cli_state *cli, const char *fname) return True; } +/**************************************************************************** + Delete a file. +****************************************************************************/ + +BOOL cli_unlink(struct cli_state *cli, const char *fname) +{ + return cli_unlink_full(cli, fname, aSYSTEM | aHIDDEN); +} + /**************************************************************************** Create a directory. ****************************************************************************/ -- cgit From aab1dd4ddbe45c625a6e4502cecd20da5762739b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 7 Mar 2007 22:29:21 +0000 Subject: r21755: Memory leak fixes from Zack Kirsch . Jeremy. (This used to be commit 02d08ca0be8c374e30c3c0e665853fa9e57f043a) --- source3/libsmb/cliconnect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e2213c1fcd..0f09747dbf 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -693,8 +693,6 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use DEBUG(3, ("Failed to send NTLMSSP/SPNEGO blob to server!\n")); nt_status = NT_STATUS_UNSUCCESSFUL; } else { - data_blob_free(&msg1); - blob = cli_session_setup_blob_receive(cli); nt_status = cli_nt_error(cli); @@ -706,6 +704,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use } } } + data_blob_free(&msg1); } if (!blob.length) { @@ -736,6 +735,8 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use turn++; } while (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)); + data_blob_free(&blob_in); + if (NT_STATUS_IS_OK(nt_status)) { DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, -- cgit From 540911001d1bf25d9534b72b90a32fc7e5efc4b0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Mar 2007 23:54:57 +0000 Subject: r21768: Fix the client dfs code such that smbclient can process deep dfs links (ie. links that go to non root parts of a share). Make the directory handling conanonical in POSIX and Windows pathname processing. dfs should not be fully working in client tools. Please bug me if not. Jeremy. (This used to be commit 1c9e10569cd97ee41de39f9f012bea4e4c932b5d) --- source3/libsmb/clidfs.c | 71 ++++++++++++++++++++++++++++++++----------- source3/libsmb/clilist.c | 10 ++---- source3/libsmb/clirap.c | 16 +++------- source3/libsmb/libsmbclient.c | 15 --------- 4 files changed, 62 insertions(+), 50 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 93ac2ae58b..e2cfd12114 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -3,6 +3,7 @@ client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Gerald (Jerry) Carter 2004 + Copyright (C) Jeremy Allison 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -21,6 +22,16 @@ #include "includes.h" +/******************************************************************** + Important point. + + DFS paths are of the form \server\share\ (the \ characters + are not C escaped here). + + - but if we're using POSIX paths then may contain + '/' separators, not '\\' separators. So cope with '\\' or '/' + as a separator when looking at the pathname part.... JRA. +********************************************************************/ struct client_connection { struct client_connection *prev, *next; @@ -194,7 +205,7 @@ static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) if ( p ) { pstrcpy( p->mount, mnt ); - dos_clean_name( p->mount ); + clean_name( p->mount ); } } @@ -427,7 +438,7 @@ static void clean_path( pstring clean, const char *path ) /* strip a trailing backslash */ len = strlen( newpath ); - if ( (len > 0) && (newpath[len-1] == '\\') ) + if ( (len > 0) && (newpath[len-1] == '\\' || newpath[len-1] == '/') ) newpath[len-1] = '\0'; pstrcpy( clean, newpath ); @@ -462,7 +473,7 @@ BOOL cli_dfs_make_full_path( pstring path, const char *server, const char *share } directory = dir; - if ( *directory == '\\' ) + if ( *directory == '\\' || *directory == '/' ) directory++; pstr_sprintf( path, "\\%s\\%s\\%s", server, sharename, directory ); @@ -597,8 +608,9 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha SMB_STRUCT_STAT sbuf; uint32 attributes; - if ( !rootcli || !path || !targetcli ) + if ( !rootcli || !path || !targetcli ) { return False; + } *targetcli = NULL; @@ -609,7 +621,7 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* don't bother continuing if this is not a dfs root */ - if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, cleanpath, &sbuf, &attributes ) ) { + if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, fullpath, &sbuf, &attributes ) ) { *targetcli = rootcli; pstrcpy( targetpath, path ); return True; @@ -620,22 +632,23 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha if ( cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND) ) { *targetcli = rootcli; pstrcpy( targetpath, path ); - return True; + goto done; } /* we got an error, check for DFS referral */ - if ( !cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED) ) + if ( !cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED)) { return False; + } /* check for the referral */ - if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) ) + if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) ) { return False; + } if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed) - || !num_refs ) - { + || !num_refs ) { return False; } @@ -669,13 +682,28 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* trim off the \server\share\ */ fullpath[consumed/2] = '\0'; - dos_clean_name( fullpath ); - if ((ppath = strchr_m( fullpath, '\\' )) == NULL) - return False; - if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) + clean_name( fullpath ); + if ((ppath = strchr_m( fullpath, '\\' )) == NULL) { return False; - if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) + } + if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) { return False; + } + { + char *p1, *p2; + + /* Last component can be '\\' or '/' posix path. */ + + p1 = strchr_m( ppath+1, '\\' ); + p2 = strchr_m( ppath+1, '/' ); + + ppath = MAX(p1,p2); + + if (ppath == NULL) { + return False; + } + } + ppath++; pstr_sprintf( newmount, "%s\\%s", mountpt, ppath ); @@ -684,13 +712,22 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* check for another dfs referral, note that we are not checking for loops here */ - if ( !strequal( targetpath, "\\" ) ) { + if ( !strequal( targetpath, "\\" ) && !strequal( targetpath, "/")) { if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) { *targetcli = newcli; pstrcpy( targetpath, newpath ); } } + done: + + /* If returning True ensure we return a dfs root full path. */ + if ( (*targetcli)->dfsroot ) { + pstrcpy( fullpath, targetpath ); + cli_dfs_make_full_path( targetpath, (*targetcli)->desthost, + (*targetcli)->share, fullpath); + } + return True; } @@ -736,7 +773,7 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, } cli->cnum = cnum; - + if (!res || !num_refs ) { SAFE_FREE( refs ); return False; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 22cb5930c2..3e76cd4775 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -44,6 +44,7 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f *p_resume_key = 0; } memcpy(finfo,&def_finfo,sizeof(*finfo)); + finfo->cli = cli; switch (level) { case 1: /* OS/2 understands this */ @@ -185,13 +186,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; - /* when getting a directory listing from a 2k dfs root share, - we have to include the full path (\server\share\mask) here */ - - if ( cli->dfsroot ) - pstr_sprintf( mask, "\\%s\\%s\\%s", cli->desthost, cli->share, Mask ); - else - pstrcpy(mask,Mask); + pstrcpy(mask,Mask); while (ff_eos == 0) { loop_count++; @@ -377,6 +372,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi *finfo = def_finfo; + finfo->cli = cli; finfo->mode = CVAL(p,21); /* this date is converted to GMT by make_unix_date */ diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 61cdd79f36..ba4305dd0a 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -749,10 +749,10 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, return True; } - /**************************************************************************** -send a qpathinfo BASIC_INFO call + Send a qpathinfo BASIC_INFO call. ****************************************************************************/ + BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf, uint32 *attributes ) { @@ -765,18 +765,12 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, pstring path; int len; - /* send full paths to dfs root shares */ - - if ( cli->dfsroot ) - pstr_sprintf(path, "\\%s\\%s\\%s", cli->desthost, cli->share, name ); - else - pstrcpy( path, name ); - + pstrcpy( path, name ); /* cleanup */ len = strlen( path ); - if ( path[len] == '\\' ) - path[len] = '\0'; + if ( path[len-1] == '\\' || path[len-1] == '/') + path[len-1] = '\0'; p = param; memset(p, 0, 6); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b3c873145f..e8929c1589 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1145,13 +1145,6 @@ smbc_open_ctx(SMBCCTX *context, } /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ - if ( targetcli->dfsroot ) - { - pstring temppath; - pstrcpy(temppath, targetpath); - cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath); - } - if ((fd = cli_open(targetcli, targetpath, flags, context->internal->_share_mode)) < 0) { @@ -1548,14 +1541,6 @@ smbc_getatr(SMBCCTX * context, return False; } - if ( targetcli->dfsroot ) - { - pstring temppath; - pstrcpy(temppath, targetpath); - cli_dfs_make_full_path(targetpath, targetcli->desthost, - targetcli->share, temppath); - } - if (!srv->no_pathinfo2 && cli_qpathinfo2(targetcli, targetpath, create_time_ts, -- cgit From 257d2e0d2a6cd4c2ea62399ec97ada46dd8c395c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Mar 2007 18:33:16 +0000 Subject: r21777: As Stevef requested and the Apple guys agreed, make mode_t in posix_open/posix_mkdir -> 8 bytes to match the SET_UNIX_INFO_BASIC call. Steve is updating the Wikki. Jeremy. (This used to be commit 2f1c95ac7718c1d2a75367ba712edd6b57069432) --- source3/libsmb/clifile.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 76eddd3f63..ce2081a81e 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1839,7 +1839,7 @@ static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; char param[sizeof(pstring)+6]; - char data[14]; + char data[18]; char *rparam=NULL, *rdata=NULL; char *p; int fnum = -1; @@ -1861,9 +1861,10 @@ static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int SIVAL(p,0,0); /* No oplock. */ SIVAL(p,4,wire_flags); SIVAL(p,8,unix_perms_to_wire(mode)); - SSVAL(p,12,SMB_NO_INFO_LEVEL_RETURNED); /* No info level returned. */ + SIVAL(p,12,0); /* Top bits of perms currently undefined. */ + SSVAL(p,16,SMB_NO_INFO_LEVEL_RETURNED); /* No info level returned. */ - data_len = 14; + data_len = 18; if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -- cgit From 3adeb4274250ec4420d9d874b07d8e688a354402 Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 9 Mar 2007 18:51:48 +0000 Subject: r21778: Wrap calls to krb5_get_init_creds_opt_free to handle the different calling convention in the latest MIT changes. Apparantly Heimdal is also changing to this calling convention. (This used to be commit c29c69d2df377fabb88a78e6f5237de106d5c2c5) --- source3/libsmb/clikrb5.c | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index f06a19b345..43dfddda47 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1389,9 +1389,14 @@ done: return ret; } -#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC - krb5_error_code krb5_get_init_creds_opt_alloc(krb5_context context, krb5_get_init_creds_opt **opt) + krb5_error_code smb_krb5_get_init_creds_opt_alloc(krb5_context context, + krb5_get_init_creds_opt **opt) { +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC + /* Heimdal or modern MIT version */ + return krb5_get_init_creds_opt_alloc(context, opt); +#else + /* Historical MIT version */ krb5_get_init_creds_opt *my_opt; *opt = NULL; @@ -1404,16 +1409,28 @@ done: *opt = my_opt; return 0; +#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC */ } -#endif -#ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE - void krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opt) + void smb_krb5_get_init_creds_opt_free(krb5_context context, + krb5_get_init_creds_opt *opt) { +#ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE + +#ifdef KRB5_CREDS_OPT_FREE_REQUIRES_CONTEXT + /* Modern MIT version */ + krb5_get_init_creds_opt_free(context, opt); +#else + /* Heimdal version */ + krb5_get_init_creds_opt_free(opt); +#endif + +#else /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */ + /* Historical MIT version */ SAFE_FREE(opt); opt = NULL; +#endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */ } -#endif #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ -- cgit From 24cdd7c73389c9eed981313973df2c3595222781 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 12 Mar 2007 17:55:24 +0000 Subject: r21800: Check-in the DFS rewrite. I am still testing this but it works from smbclient and Windows, and I am promising to support and fix both client and server code moving forward. Still need to test the RPC admin support but I haven't changed that code. Jeremy. (This used to be commit 7a7862c01d07796ef206b255c676ad7dc2cc42fc) --- source3/libsmb/clidfs.c | 288 +++++++++++++++++++++++++----------------------- 1 file changed, 148 insertions(+), 140 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e2cfd12114..4009b98b41 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -25,7 +25,7 @@ /******************************************************************** Important point. - DFS paths are of the form \server\share\ (the \ characters + DFS paths are *always* of the form \server\share\ (the \ characters are not C escaped here). - but if we're using POSIX paths then may contain @@ -205,14 +205,14 @@ static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) if ( p ) { pstrcpy( p->mount, mnt ); - clean_name( p->mount ); + clean_name(p->mount); } } /**************************************************************************** ****************************************************************************/ -const char * cli_cm_get_mntpoint( struct cli_state *c ) +const char *cli_cm_get_mntpoint( struct cli_state *c ) { struct client_connection *p; int i; @@ -232,8 +232,9 @@ const char * cli_cm_get_mntpoint( struct cli_state *c ) Add a new connection to the list ********************************************************************/ -static struct cli_state* cli_cm_connect( const char *server, const char *share, - BOOL show_hdr ) +static struct cli_state *cli_cm_connect( const char *server, + const char *share, + BOOL show_hdr) { struct client_connection *node; @@ -258,7 +259,7 @@ static struct cli_state* cli_cm_connect( const char *server, const char *share, Return a connection to a server. ********************************************************************/ -static struct cli_state* cli_cm_find( const char *server, const char *share ) +static struct cli_state *cli_cm_find( const char *server, const char *share ) { struct client_connection *p; @@ -275,7 +276,9 @@ static struct cli_state* cli_cm_find( const char *server, const char *share ) global variable as a side-effect (but only if the connection is successful). ****************************************************************************/ -struct cli_state* cli_cm_open( const char *server, const char *share, BOOL show_hdr ) +struct cli_state *cli_cm_open(const char *server, + const char *share, + BOOL show_hdr) { struct cli_state *c; @@ -283,8 +286,9 @@ struct cli_state* cli_cm_open( const char *server, const char *share, BOOL show_ c = cli_cm_find( server, share ); - if ( !c ) - c = cli_cm_connect( server, share, show_hdr ); + if ( !c ) { + c = cli_cm_connect(server, share, show_hdr); + } return c; } @@ -306,7 +310,6 @@ void cli_cm_shutdown( void ) } connections = NULL; - return; } @@ -369,20 +372,21 @@ void cli_cm_set_dest_ip(struct in_addr ip ) split a dfs path into the server, share name, and extrapath components **********************************************************************/ -static void split_dfs_path( const char *nodepath, fstring server, fstring share, fstring extrapath ) +static void split_dfs_path( const char *nodepath, fstring server, fstring share, pstring extrapath ) { char *p, *q; pstring path; pstrcpy( path, nodepath ); - if ( path[0] != '\\' ) + if ( path[0] != '\\' ) { return; + } p = strchr_m( path + 1, '\\' ); - - if ( !p ) + if ( !p ) { return; + } *p = '\0'; p++; @@ -392,9 +396,9 @@ static void split_dfs_path( const char *nodepath, fstring server, fstring share, if (q != NULL) { *q = '\0'; q++; - fstrcpy( extrapath, q ); + pstrcpy( extrapath, q ); } else { - fstrcpy( extrapath, '\0' ); + pstrcpy( extrapath, '\0' ); } fstrcpy( share, p ); @@ -402,83 +406,66 @@ static void split_dfs_path( const char *nodepath, fstring server, fstring share, } /**************************************************************************** - return the original path truncated at the first wildcard character - (also strips trailing \'s). Trust the caller to provide a NULL + Return the original path truncated at the directory component before + the first wildcard character. Trust the caller to provide a NULL terminated string ****************************************************************************/ -static void clean_path( pstring clean, const char *path ) +static void clean_path(const char *path, pstring path_out) { - int len; - char *p; - pstring newpath; + size_t len; + char *p1, *p2, *p; - pstrcpy( newpath, path ); - p = newpath; - - while ( p ) { - /* first check for '*' */ - - p = strrchr_m( newpath, '*' ); - if ( p ) { - *p = '\0'; - p = newpath; - continue; + /* No absolute paths. */ + while (IS_DIRECTORY_SEP(*path)) { + path++; + } + + pstrcpy(path_out, path); + + p1 = strchr_m(path_out, '*'); + p2 = strchr_m(path_out, '?'); + + if (p1 || p2) { + if (p1 && p2) { + p = MIN(p1,p2); + } else if (!p1) { + p = p2; + } else { + p = p1; } - - /* first check for '?' */ - - p = strrchr_m( newpath, '?' ); - if ( p ) { + *p = '\0'; + + /* Now go back to the start of this component. */ + p1 = strrchr_m(path_out, '/'); + p2 = strrchr_m(path_out, '\\'); + p = MAX(p1,p2); + if (p) { *p = '\0'; - p = newpath; } } - - /* strip a trailing backslash */ - - len = strlen( newpath ); - if ( (len > 0) && (newpath[len-1] == '\\' || newpath[len-1] == '/') ) - newpath[len-1] = '\0'; - - pstrcpy( clean, newpath ); + + /* Strip any trailing separator */ + + len = strlen(path_out); + if ( (len > 0) && IS_DIRECTORY_SEP(path_out[len-1])) { + path_out[len-1] = '\0'; + } } /**************************************************************************** ****************************************************************************/ -BOOL cli_dfs_make_full_path( pstring path, const char *server, const char *share, - const char *dir ) +static void cli_dfs_make_full_path( struct cli_state *cli, + const char *dir, + pstring path_out) { - pstring servicename; - char *sharename; - const char *directory; - - - /* make a copy so we don't modify the global string 'service' */ - - pstrcpy(servicename, share); - sharename = servicename; - - if (*sharename == '\\') { - - server = sharename+2; - sharename = strchr_m(server,'\\'); - - if (!sharename) - return False; - - *sharename = 0; - sharename++; + /* Ensure the extrapath doesn't start with a separator. */ + while (IS_DIRECTORY_SEP(*dir)) { + dir++; } - directory = dir; - if ( *directory == '\\' || *directory == '/' ) - directory++; - - pstr_sprintf( path, "\\%s\\%s\\%s", server, sharename, directory ); - - return True; + pstr_sprintf( path_out, "\\%s\\%s\\%s", cli->desthost, cli->share, dir); } /******************************************************************** @@ -504,9 +491,11 @@ static BOOL cli_dfs_check_error( struct cli_state *cli, NTSTATUS status ) get the dfs referral link ********************************************************************/ -BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, - CLIENT_DFS_REFERRAL**refs, size_t *num_refs, - uint16 *consumed) +BOOL cli_dfs_get_referral( struct cli_state *cli, + const char *path, + CLIENT_DFS_REFERRAL**refs, + size_t *num_refs, + uint16 *consumed) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -550,10 +539,9 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, uint16 ref_size; int i; uint16 node_offset; - - + referrals = SMB_XMALLOC_ARRAY( CLIENT_DFS_REFERRAL, num_referrals ); - + /* start at the referrals array */ p = rdata+8; @@ -575,7 +563,6 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, p += ref_size; } - } *num_refs = num_referrals; @@ -587,17 +574,21 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, const char *path, return True; } + /******************************************************************** ********************************************************************/ -BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const char *path, - struct cli_state **targetcli, pstring targetpath ) +BOOL cli_resolve_path( const char *mountpt, + struct cli_state *rootcli, + const char *path, + struct cli_state **targetcli, + pstring targetpath) { CLIENT_DFS_REFERRAL *refs = NULL; size_t num_refs; uint16 consumed; struct cli_state *cli_ipc; - pstring fullpath, cleanpath, extrapath; + pstring dfs_path, cleanpath, extrapath; int pathlen; fstring server, share; struct cli_state *newcli; @@ -612,22 +603,29 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha return False; } - *targetcli = NULL; - - /* send a trans2_query_path_info to check for a referral */ - - clean_path( cleanpath, path ); - cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, cleanpath ); + /* Don't do anything if this is not a DFS root. */ - /* don't bother continuing if this is not a dfs root */ - - if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, fullpath, &sbuf, &attributes ) ) { + if ( !rootcli->dfsroot) { *targetcli = rootcli; pstrcpy( targetpath, path ); return True; } - /* special case where client asked for a path that does not exist */ + *targetcli = NULL; + + /* Send a trans2_query_path_info to check for a referral. */ + + clean_path(path, cleanpath); + cli_dfs_make_full_path(rootcli, cleanpath, dfs_path ); + + if (cli_qpathinfo_basic( rootcli, dfs_path, &sbuf, &attributes ) ) { + /* This is an ordinary path, just return it. */ + *targetcli = rootcli; + pstrcpy( targetpath, path ); + goto done; + } + + /* Special case where client asked for a path that does not exist */ if ( cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND) ) { *targetcli = rootcli; @@ -635,87 +633,97 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha goto done; } - /* we got an error, check for DFS referral */ - + /* We got an error, check for DFS referral. */ + if ( !cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED)) { return False; } - /* check for the referral */ + /* Check for the referral. */ if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) ) { return False; } - if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed) + if ( !cli_dfs_get_referral(cli_ipc, dfs_path, &refs, &num_refs, &consumed) || !num_refs ) { return False; } - /* just store the first referral for now - Make sure to recreate the original string including any wildcards */ - - cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); - pathlen = strlen( fullpath )*2; - consumed = MIN(pathlen, consumed ); - pstrcpy( targetpath, &fullpath[consumed/2] ); + /* Just store the first referral for now. */ split_dfs_path( refs[0].dfspath, server, share, extrapath ); - SAFE_FREE( refs ); + SAFE_FREE(refs); - if (strlen(extrapath) > 0) { - string_append(&temppath, extrapath); - string_append(&temppath, targetpath); - pstrcpy( targetpath, temppath ); - } + /* Make sure to recreate the original string including any wildcards. */ - /* open the connection to the target path */ + cli_dfs_make_full_path( rootcli, path, dfs_path); + pathlen = strlen( dfs_path )*2; + consumed = MIN(pathlen, consumed ); + pstrcpy( targetpath, &dfs_path[consumed/2] ); + dfs_path[consumed/2] = '\0'; + + /* + * targetpath is now the unconsumed part of the path. + * dfs_path is now the consumed part of the path (in \server\share\path format). + */ + + /* Open the connection to the target server & share */ if ( (*targetcli = cli_cm_open(server, share, False)) == NULL ) { - d_printf("Unable to follow dfs referral [//%s/%s]\n", + d_printf("Unable to follow dfs referral [\\%s\\%s]\n", server, share ); - return False; } + if (strlen(extrapath) > 0) { + string_append(&temppath, extrapath); + string_append(&temppath, targetpath); + pstrcpy( targetpath, temppath ); + } + /* parse out the consumed mount path */ /* trim off the \server\share\ */ - fullpath[consumed/2] = '\0'; - clean_name( fullpath ); - if ((ppath = strchr_m( fullpath, '\\' )) == NULL) { + ppath = dfs_path; + + if (*ppath != '\\') { + d_printf("cli_resolve_path: dfs_path (%s) not in correct format.\n", + dfs_path ); return False; } - if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) { + + ppath++; /* Now pointing at start of server name. */ + + if ((ppath = strchr_m( dfs_path, '\\' )) == NULL) { return False; } - { - char *p1, *p2; - - /* Last component can be '\\' or '/' posix path. */ - p1 = strchr_m( ppath+1, '\\' ); - p2 = strchr_m( ppath+1, '/' ); + ppath++; /* Now pointing at start of share name. */ - ppath = MAX(p1,p2); - - if (ppath == NULL) { - return False; - } + if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) { + return False; } - ppath++; - + ppath++; /* Now pointing at path component. */ + pstr_sprintf( newmount, "%s\\%s", mountpt, ppath ); + cli_cm_set_mntpoint( *targetcli, newmount ); - /* check for another dfs referral, note that we are not - checking for loops here */ + /* Check for another dfs referral, note that we are not + checking for loops here. */ if ( !strequal( targetpath, "\\" ) && !strequal( targetpath, "/")) { if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) { + /* + * When cli_resolve_path returns true here it's always + * returning the complete path in newpath, so we're done + * here. + */ *targetcli = newcli; pstrcpy( targetpath, newpath ); + return True; } } @@ -723,9 +731,8 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* If returning True ensure we return a dfs root full path. */ if ( (*targetcli)->dfsroot ) { - pstrcpy( fullpath, targetpath ); - cli_dfs_make_full_path( targetpath, (*targetcli)->desthost, - (*targetcli)->share, fullpath); + pstrcpy(dfs_path, targetpath ); + cli_dfs_make_full_path( *targetcli, dfs_path, targetpath); } return True; @@ -743,7 +750,7 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, pstring fullpath; BOOL res; uint16 cnum; - fstring newextrapath; + pstring newextrapath; if ( !cli || !sharename ) return False; @@ -752,8 +759,9 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, /* special case. never check for a referral on the IPC$ share */ - if ( strequal( sharename, "IPC$" ) ) + if ( strequal( sharename, "IPC$" ) ) { return False; + } /* send a trans2_query_path_info to check for a referral */ -- cgit From aa6055debd078504f6a7ed861443b02672fc9067 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 13 Mar 2007 16:13:24 +0000 Subject: r21823: Let secrets_store_machine_password() also store the account name. Not used yet, the next step will be a secrets_fetch_machine_account() function that also pulls the account name to be used in the appropriate places. Volker (This used to be commit f94e5af72e282f70ca5454cdf3aed510b747eb93) --- source3/libsmb/trusts_util.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index e4061883eb..3460f2c47c 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -104,7 +104,10 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m * Return the result of trying to write the new password * back into the trust account file. */ - if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) { + if (!secrets_store_machine_password(new_trust_passwd, + global_myname(), + domain, + sec_channel_type)) { nt_status = NT_STATUS_UNSUCCESSFUL; } } -- cgit From f56da0890f645c4cecac7c60f67573e1f609fd4f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 13 Mar 2007 20:53:38 +0000 Subject: r21831: Back out r21823 for a while, this is going into a bzr tree first. Volker (This used to be commit fd0ee6722ddfcb64b5cc9c699375524ae3d8709b) --- source3/libsmb/trusts_util.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 3460f2c47c..e4061883eb 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -104,10 +104,7 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m * Return the result of trying to write the new password * back into the trust account file. */ - if (!secrets_store_machine_password(new_trust_passwd, - global_myname(), - domain, - sec_channel_type)) { + if (!secrets_store_machine_password(new_trust_passwd, domain, sec_channel_type)) { nt_status = NT_STATUS_UNSUCCESSFUL; } } -- cgit From edccfc91928c323f18febb7b90e41e0ddbfd8c7c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 19:18:18 +0000 Subject: r21845: Refactor the sessionsetupX code a little to allow us to return a NT_STATUS_TIME_DIFFERENCE_AT_DC error to a client when there's clock skew. Will help people debug this. Prepare us for being able to return the correct sessionsetupX "NT_STATUS_MORE_PROCESSING_REQUIRED" error with associated krb5 clock skew error to allow clients to re-sync time with us when we're eventually able to be a KDC. Jeremy. (This used to be commit c426340fc79a6b446033433b8de599130adffe28) --- source3/libsmb/clikrb5.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 43dfddda47..659197214f 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -75,6 +75,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, krb5_error_code ret; char *utf8_name; + *principal = NULL; if (push_utf8_allocate(&utf8_name, name) == (size_t)-1) { return ENOMEM; } @@ -97,6 +98,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, krb5_error_code ret; char *utf8_name; + *unix_name = NULL; ret = krb5_unparse_name(context, principal, &utf8_name); if (ret) { return ret; @@ -1430,6 +1432,37 @@ done: SAFE_FREE(opt); opt = NULL; #endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */ +} + + krb5_error_code smb_krb5_mk_error(krb5_context context, + krb5_error_code error_code, + const krb5_principal server, + krb5_data *reply) +{ +#ifdef HAVE_SHORT_KRB5_MK_ERROR_INTERFACE /* MIT */ + /* + * The MIT interface is *terrible*. + * We have to construct this ourselves... + */ + krb5_error e; + + memset(&e, 0, sizeof(e)); + krb5_us_timeofday(context, &e.stime, &e.susec); + e.server = server; + e.error = error_code - krb5_err_base; + + return krb5_mk_error(context, &e, reply); +#else /* Heimdal. */ + return krb5_mk_error(context, + error_code, + NULL, + NULL, /* e_data */ + NULL, + server, + NULL, + NULL, + reply); +#endif } #else /* HAVE_KRB5 */ -- cgit From ca256664aa4b65902b01ddf83564b7602560bd08 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Mar 2007 20:45:27 +0000 Subject: r21846: Try and fix the Darwin build which seems to have a strange krb5. Jeremy. (This used to be commit 1e32b44bfcf7676b3a9f208054fa853e7066eafc) --- source3/libsmb/clikrb5.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 659197214f..fa93bed63d 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1449,7 +1449,13 @@ done: memset(&e, 0, sizeof(e)); krb5_us_timeofday(context, &e.stime, &e.susec); e.server = server; +#if defined(krb5_err_base) e.error = error_code - krb5_err_base; +#elif defined(ERROR_TABLE_BASE_krb5) + e.error = error_code - ERROR_TABLE_BASE_krb5; +#else + e.error = error_code; /* Almost certainly wrong, but what can we do... ? */ +#endif return krb5_mk_error(context, &e, reply); #else /* Heimdal. */ -- cgit From c2fd7de44e7ba8a7d93110a6f579878697ceaa8d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Mar 2007 00:15:18 +0000 Subject: r21864: Reformatting. Jeremy. (This used to be commit f18e87ba6b6a3f4c16777cb5b6bf93a656800247) --- source3/libsmb/clirap.c | 184 ++++++++++++++++++++++++------------------------ 1 file changed, 92 insertions(+), 92 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index ba4305dd0a..05dc36e91c 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -21,10 +21,10 @@ #include "includes.h" - /**************************************************************************** -Call a remote api on an arbitrary pipe. takes param, data and setup buffers. + Call a remote api on an arbitrary pipe. takes param, data and setup buffers. ****************************************************************************/ + BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, @@ -32,28 +32,29 @@ BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, char **rparam, uint32 *rparam_count, char **rdata, uint32 *rdata_count) { - cli_send_trans(cli, SMBtrans, + cli_send_trans(cli, SMBtrans, pipe_name, 0,0, /* fid, flags */ setup, setup_count, max_setup_count, params, param_count, max_param_count, data, data_count, max_data_count); - return (cli_receive_trans(cli, SMBtrans, + return (cli_receive_trans(cli, SMBtrans, rparam, (unsigned int *)rparam_count, rdata, (unsigned int *)rdata_count)); } /**************************************************************************** -call a remote api + Call a remote api ****************************************************************************/ + BOOL cli_api(struct cli_state *cli, char *param, int prcnt, int mprcnt, char *data, int drcnt, int mdrcnt, char **rparam, unsigned int *rprcnt, char **rdata, unsigned int *rdrcnt) { - cli_send_trans(cli,SMBtrans, + cli_send_trans(cli,SMBtrans, PIPE_LANMAN, /* Name */ 0,0, /* fid, flags */ NULL,0,0, /* Setup, length, max */ @@ -61,15 +62,15 @@ BOOL cli_api(struct cli_state *cli, data, drcnt, mdrcnt /* Data, length, max */ ); - return (cli_receive_trans(cli,SMBtrans, + return (cli_receive_trans(cli,SMBtrans, rparam, rprcnt, rdata, rdrcnt)); } - /**************************************************************************** -perform a NetWkstaUserLogon + Perform a NetWkstaUserLogon. ****************************************************************************/ + BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) { char *rparam = NULL; @@ -129,8 +130,9 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) } /**************************************************************************** -call a NetShareEnum - try and browse available connections on a host + Call a NetShareEnum - try and browse available connections on a host. ****************************************************************************/ + int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, const char *, void *), void *state) { char *rparam = NULL; @@ -196,14 +198,14 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co return count; } - /**************************************************************************** -call a NetServerEnum for the specified workgroup and servertype mask. This -function then calls the specified callback function for each name returned. + Call a NetServerEnum for the specified workgroup and servertype mask. This + function then calls the specified callback function for each name returned. -The callback function takes 4 arguments: the machine name, the server type, -the comment and a state pointer. + The callback function takes 4 arguments: the machine name, the server type, + the comment and a state pointer. ****************************************************************************/ + BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, void (*fn)(const char *, uint32, const char *, void *), void *state) @@ -286,99 +288,99 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, return(count > 0); } - - /**************************************************************************** -Send a SamOEMChangePassword command + Send a SamOEMChangePassword command. ****************************************************************************/ + BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password) { - pstring param; - unsigned char data[532]; - char *p = param; - unsigned char old_pw_hash[16]; - unsigned char new_pw_hash[16]; - unsigned int data_len; - unsigned int param_len = 0; - char *rparam = NULL; - char *rdata = NULL; - unsigned int rprcnt, rdrcnt; - - if (strlen(user) >= sizeof(fstring)-1) { - DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); - return False; - } - - SSVAL(p,0,214); /* SamOEMChangePassword command. */ - p += 2; - pstrcpy_base(p, "zsT", param); - p = skip_string(p,1); - pstrcpy_base(p, "B516B16", param); - p = skip_string(p,1); - pstrcpy_base(p,user, param); - p = skip_string(p,1); - SSVAL(p,0,532); - p += 2; - - param_len = PTR_DIFF(p,param); - - /* - * Get the Lanman hash of the old password, we - * use this as the key to make_oem_passwd_hash(). - */ - E_deshash(old_password, old_pw_hash); - - encode_pw_buffer(data, new_password, STR_ASCII); + pstring param; + unsigned char data[532]; + char *p = param; + unsigned char old_pw_hash[16]; + unsigned char new_pw_hash[16]; + unsigned int data_len; + unsigned int param_len = 0; + char *rparam = NULL; + char *rdata = NULL; + unsigned int rprcnt, rdrcnt; + + if (strlen(user) >= sizeof(fstring)-1) { + DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user)); + return False; + } + + SSVAL(p,0,214); /* SamOEMChangePassword command. */ + p += 2; + pstrcpy_base(p, "zsT", param); + p = skip_string(p,1); + pstrcpy_base(p, "B516B16", param); + p = skip_string(p,1); + pstrcpy_base(p,user, param); + p = skip_string(p,1); + SSVAL(p,0,532); + p += 2; + + param_len = PTR_DIFF(p,param); + + /* + * Get the Lanman hash of the old password, we + * use this as the key to make_oem_passwd_hash(). + */ + E_deshash(old_password, old_pw_hash); + + encode_pw_buffer(data, new_password, STR_ASCII); #ifdef DEBUG_PASSWORD - DEBUG(100,("make_oem_passwd_hash\n")); - dump_data(100, (char *)data, 516); + DEBUG(100,("make_oem_passwd_hash\n")); + dump_data(100, (char *)data, 516); #endif - SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); + SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); - /* - * Now place the old password hash in the data. - */ - E_deshash(new_password, new_pw_hash); + /* + * Now place the old password hash in the data. + */ + E_deshash(new_password, new_pw_hash); - E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); + E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); - data_len = 532; + data_len = 532; - if (cli_send_trans(cli,SMBtrans, + if (cli_send_trans(cli,SMBtrans, PIPE_LANMAN, /* name */ 0,0, /* fid, flags */ NULL,0,0, /* setup, length, max */ param,param_len,2, /* param, length, max */ (char *)data,data_len,0 /* data, length, max */ ) == False) { - DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", - user )); - return False; - } + DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n", + user )); + return False; + } - if (!cli_receive_trans(cli,SMBtrans, + if (!cli_receive_trans(cli,SMBtrans, &rparam, &rprcnt, &rdata, &rdrcnt)) { - DEBUG(0,("cli_oem_change_password: Failed to recieve reply to password change for user %s\n", - user )); - return False; - } + DEBUG(0,("cli_oem_change_password: Failed to recieve reply to password change for user %s\n", + user )); + return False; + } - if (rparam) - cli->rap_error = SVAL(rparam,0); + if (rparam) { + cli->rap_error = SVAL(rparam,0); + } - SAFE_FREE(rparam); - SAFE_FREE(rdata); + SAFE_FREE(rparam); + SAFE_FREE(rdata); - return (cli->rap_error == 0); + return (cli->rap_error == 0); } - /**************************************************************************** -send a qpathinfo call + Send a qpathinfo call. ****************************************************************************/ + BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *change_time, time_t *access_time, @@ -458,10 +460,10 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, return True; } - /**************************************************************************** -send a setpathinfo call + Send a setpathinfo call. ****************************************************************************/ + BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, time_t create_time, time_t access_time, @@ -556,9 +558,8 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, return True; } - /**************************************************************************** -send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level + Send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level. ****************************************************************************/ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, @@ -631,10 +632,10 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, return True; } - /**************************************************************************** -send a qfileinfo QUERY_FILE_NAME_INFO call + Send a qfileinfo QUERY_FILE_NAME_INFO call. ****************************************************************************/ + BOOL cli_qfilename(struct cli_state *cli, int fnum, pstring name) { @@ -674,10 +675,10 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum, return True; } - /**************************************************************************** -send a qfileinfo call + Send a qfileinfo call. ****************************************************************************/ + BOOL cli_qfileinfo(struct cli_state *cli, int fnum, uint16 *mode, SMB_OFF_T *size, struct timespec *create_time, @@ -814,7 +815,7 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, } /**************************************************************************** -send a qfileinfo call + Send a qfileinfo call. ****************************************************************************/ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen) @@ -869,11 +870,10 @@ BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd return True; } - - /**************************************************************************** -send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call + Send a qpathinfo SMB_QUERY_FILE_ALT_NAME_INFO call. ****************************************************************************/ + NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstring alt_name) { unsigned int data_len = 0; -- cgit From ecd496f06654e8316260c9a6ddab5e473f9cc452 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 17 Mar 2007 00:32:54 +0000 Subject: r21865: Add in the stubs for SMB transport encryption. Will flesh these out as I implement. Don't add to SAMBA_3_0_25, this is experimental code. NFSv4 you're now officially on notice... :-). Jeremy. (This used to be commit 5bfe638f2172e272741997100ee5ae8ff280494d) --- source3/libsmb/clientgen.c | 36 +++++++++++++++++++++++++++++++----- source3/libsmb/clierror.c | 5 +++++ source3/libsmb/smb_seal.c | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 5 deletions(-) create mode 100644 source3/libsmb/smb_seal.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 68ecb131b1..cdf36d9b9c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -54,9 +54,13 @@ int cli_set_port(struct cli_state *cli, int port) should never go into a blocking read. ****************************************************************************/ -static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) +static BOOL client_receive_smb(struct cli_state *cli) { BOOL ret; + NTSTATUS status; + int fd = cli->fd; + char *buffer = cli->inbuf; + unsigned int timeout = cli->timeout; for(;;) { ret = receive_smb_raw(fd, buffer, timeout); @@ -71,6 +75,15 @@ static BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout) if(CVAL(buffer,0) != SMBkeepalive) break; } + status = cli_decrypt_message(cli); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", + nt_errstr(status))); + cli->smb_rw_error = READ_BAD_DECRYPT; + close(cli->fd); + cli->fd = -1; + return False; + } show_msg(buffer); return ret; } @@ -88,7 +101,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return False; again: - ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout); + ret = client_receive_smb(cli); if (ret) { /* it might be an oplock break request */ @@ -132,7 +145,7 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); ret = write_data(fd,buf,len); - + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); if(ret <= 0) DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", @@ -147,16 +160,28 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) BOOL cli_send_smb(struct cli_state *cli) { + NTSTATUS status; size_t len; size_t nwritten=0; ssize_t ret; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) + if (cli->fd == -1) { return False; + } cli_calculate_sign_mac(cli); + status = cli_encrypt_message(cli); + if (!NT_STATUS_IS_OK(status)) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; + DEBUG(0,("Error in encrypting client message. Error %s\n", + nt_errstr(status) )); + return False; + } + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { @@ -173,8 +198,9 @@ BOOL cli_send_smb(struct cli_state *cli) } /* Increment the mid so we can tell between responses. */ cli->mid++; - if (!cli->mid) + if (!cli->mid) { cli->mid++; + } return True; } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index f85fc5c552..4b222c9015 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -84,6 +84,7 @@ static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli) case WRITE_ERROR: return NT_STATUS_UNEXPECTED_NETWORK_ERROR; case READ_BAD_SIG: + case READ_BAD_DECRYPT: return NT_STATUS_INVALID_PARAMETER; default: break; @@ -133,6 +134,10 @@ const char *cli_errstr(struct cli_state *cli) slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Server packet had invalid SMB signature!"); break; + case READ_BAD_DECRYPT: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Server packet could not be decrypted !"); + break; default: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Unknown error code %d\n", cli->smb_rw_error ); diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c new file mode 100644 index 0000000000..eb35fc05f9 --- /dev/null +++ b/source3/libsmb/smb_seal.c @@ -0,0 +1,41 @@ +/* + Unix SMB/CIFS implementation. + SMB Transport encryption (sealing) code. + Copyright (C) Jeremy Allison 2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +NTSTATUS cli_decrypt_message(struct cli_state *cli) +{ + return NT_STATUS_OK; +} + +NTSTATUS cli_encrypt_message(struct cli_state *cli) +{ + return NT_STATUS_OK; +} + +NTSTATUS srv_decrypt_buffer(char *buffer) +{ + return NT_STATUS_OK; +} + +NTSTATUS srv_encrypt_buffer(char *buffer) +{ + return NT_STATUS_OK; +} -- cgit From c48b610b516b72edd6232235a6f83d388f5a0552 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Mar 2007 20:39:58 +0000 Subject: r21876: Start adding in the seal implementation - prototype code for the server side enc. (doesn't break anything). I'll keep updating this until I've got NTLM seal working on both client and server, then add in the gss level seal. Jeremy. (This used to be commit 530ac29abf23e920baa549e7cec55199edd8bd74) --- source3/libsmb/smb_seal.c | 178 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index eb35fc05f9..90efa05f0b 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -30,12 +30,186 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli) return NT_STATUS_OK; } -NTSTATUS srv_decrypt_buffer(char *buffer) +/* Server state if we're encrypting SMBs. If NULL then enc is off. */ + +static struct smb_trans_enc_state *srv_trans_enc_state; + +/****************************************************************************** + Is server encryption on ? +******************************************************************************/ + +BOOL srv_encryption_on(void) +{ + return srv_trans_enc_state != NULL; +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void srv_free_buffer(char *buf_out) { + if (!srv_trans_enc_state) { + return; + } + + if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { + SAFE_FREE(buf_out); + return; + } + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + /* gss-api free buffer.... */ +#endif +} + +/****************************************************************************** + gss-api decrypt an incoming buffer. +******************************************************************************/ + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +static NTSTATUS srv_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) +{ + return NT_STATUS_NOT_SUPPORTED; +} +#endif + +/****************************************************************************** + NTLM decrypt an incoming buffer. +******************************************************************************/ + +static NTSTATUS srv_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +{ + NTSTATUS status; + size_t orig_len = smb_len(buf); + size_t new_len = orig_len - NTLMSSP_SIG_SIZE; + DATA_BLOB sig; + + if (orig_len < 8 + NTLMSSP_SIG_SIZE) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* Save off the signature. */ + sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE); + + status = ntlmssp_unseal_packet(ntlmssp_state, + (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ + new_len - 8, + (unsigned char *)buf, + new_len, + &sig); + + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&sig); + return status; + } + /* Reset the length. */ + smb_setlen(buf, new_len); return NT_STATUS_OK; } -NTSTATUS srv_encrypt_buffer(char *buffer) +/****************************************************************************** + Decrypt an incoming buffer. +******************************************************************************/ + +NTSTATUS srv_decrypt_buffer(char *buf) { + if (!srv_trans_enc_state) { + /* Not decrypting. */ + return NT_STATUS_OK; + } + if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { + return srv_ntlm_decrypt_buffer(srv_trans_enc_state->ntlmssp_state, buf); + } else { +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + return srv_gss_decrypt_buffer(srv_trans_enc_state->context_handle, buf); +#else + return NT_STATUS_NOT_SUPPORTED; +#endif + } +} + +/****************************************************************************** + gss-api encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) +{ + return NT_STATUS_NOT_SUPPORTED; +} +#endif + +/****************************************************************************** + NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. +******************************************************************************/ + +static NTSTATUS srv_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) +{ + NTSTATUS status; + char *buf_out; + size_t orig_len = smb_len(buf); + size_t new_len = orig_len + NTLMSSP_SIG_SIZE; + DATA_BLOB sig; + + *ppbuf_out = NULL; + + if (orig_len < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* + * We know smb_len can't return a value > 128k, so no int overflow + * check needed. + */ + + /* Copy the original buffer. */ + + buf_out = SMB_XMALLOC_ARRAY(char, new_len); + memcpy(buf_out, buf, orig_len); + /* Last 16 bytes undefined here... */ + + smb_setlen(buf_out, new_len); + + sig = data_blob(NULL, NTLMSSP_SIG_SIZE); + + status = ntlmssp_seal_packet(ntlmssp_state, + (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ + orig_len - 8, + (unsigned char *)buf_out, + orig_len, + &sig); + + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&sig); + SAFE_FREE(buf_out); + return status; + } + + memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE); + *ppbuf_out = buf_out; return NT_STATUS_OK; } + +/****************************************************************************** + Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) +{ + if (!srv_trans_enc_state) { + /* Not encrypting. */ + *buf_out = buffer; + return NT_STATUS_OK; + } + + if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { + return srv_ntlm_encrypt_buffer(srv_trans_enc_state->ntlmssp_state, buffer, buf_out); + } else { +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + return srv_gss_encrypt_buffer(srv_trans_enc_state->context_handle, buffer, buf_out); +#else + return NT_STATUS_NOT_SUPPORTED; +#endif + } +} -- cgit From 7ccf45684a1f83d7d48a4227aa56c53081d68283 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Mar 2007 22:45:35 +0000 Subject: r21880: Make client and server calls into encryption code symetrical, depending on encryption context pointer. Jeremy. (This used to be commit d3f3ced6c8a03d971143baf878158d671dfcbc3b) --- source3/libsmb/clientgen.c | 13 +- source3/libsmb/smb_seal.c | 299 ++++++++++++++++++++++++++++++++------------- 2 files changed, 221 insertions(+), 91 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index cdf36d9b9c..52ffdc24e7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -164,6 +164,7 @@ BOOL cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) { @@ -172,7 +173,7 @@ BOOL cli_send_smb(struct cli_state *cli) cli_calculate_sign_mac(cli); - status = cli_encrypt_message(cli); + status = cli_encrypt_message(cli, &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); cli->fd = -1; @@ -182,11 +183,12 @@ BOOL cli_send_smb(struct cli_state *cli) return False; } - len = smb_len(cli->outbuf) + 4; + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { + cli_free_enc_buffer(cli, buf_out); close(cli->fd); cli->fd = -1; cli->smb_rw_error = WRITE_ERROR; @@ -196,6 +198,9 @@ BOOL cli_send_smb(struct cli_state *cli) } nwritten += ret; } + + cli_free_enc_buffer(cli, buf_out); + /* Increment the mid so we can tell between responses. */ cli->mid++; if (!cli->mid) { @@ -447,6 +452,8 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->inbuf); cli_free_signing_context(cli); + cli_free_encryption_context(cli); + data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 90efa05f0b..2d1201ae7e 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -20,65 +20,22 @@ #include "includes.h" -NTSTATUS cli_decrypt_message(struct cli_state *cli) -{ - return NT_STATUS_OK; -} - -NTSTATUS cli_encrypt_message(struct cli_state *cli) -{ - return NT_STATUS_OK; -} - -/* Server state if we're encrypting SMBs. If NULL then enc is off. */ - -static struct smb_trans_enc_state *srv_trans_enc_state; - /****************************************************************************** - Is server encryption on ? + Generic code for client and server. + Is encryption turned on ? ******************************************************************************/ -BOOL srv_encryption_on(void) +static BOOL internal_encryption_on(struct smb_trans_enc_state *es) { - return srv_trans_enc_state != NULL; + return ((es != NULL) && es->enc_on); } /****************************************************************************** - Free an encryption-allocated buffer. -******************************************************************************/ - -void srv_free_buffer(char *buf_out) -{ - if (!srv_trans_enc_state) { - return; - } - - if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { - SAFE_FREE(buf_out); - return; - } - -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - /* gss-api free buffer.... */ -#endif -} - -/****************************************************************************** - gss-api decrypt an incoming buffer. -******************************************************************************/ - -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -static NTSTATUS srv_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) -{ - return NT_STATUS_NOT_SUPPORTED; -} -#endif - -/****************************************************************************** + Generic code for client and server. NTLM decrypt an incoming buffer. ******************************************************************************/ -static NTSTATUS srv_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +static NTSTATUS internal_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) { NTSTATUS status; size_t orig_len = smb_len(buf); @@ -109,42 +66,11 @@ static NTSTATUS srv_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) } /****************************************************************************** - Decrypt an incoming buffer. -******************************************************************************/ - -NTSTATUS srv_decrypt_buffer(char *buf) -{ - if (!srv_trans_enc_state) { - /* Not decrypting. */ - return NT_STATUS_OK; - } - if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return srv_ntlm_decrypt_buffer(srv_trans_enc_state->ntlmssp_state, buf); - } else { -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return srv_gss_decrypt_buffer(srv_trans_enc_state->context_handle, buf); -#else - return NT_STATUS_NOT_SUPPORTED; -#endif - } -} - -/****************************************************************************** - gss-api encrypt an outgoing buffer. Return the encrypted pointer in buf_out. -******************************************************************************/ - -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) -{ - return NT_STATUS_NOT_SUPPORTED; -} -#endif - -/****************************************************************************** + Generic code for client and server. NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. ******************************************************************************/ -static NTSTATUS srv_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) +static NTSTATUS internal_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) { NTSTATUS status; char *buf_out; @@ -192,24 +118,221 @@ static NTSTATUS srv_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, } /****************************************************************************** - Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. + Generic code for client and server. + gss-api decrypt an incoming buffer. ******************************************************************************/ -NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +static NTSTATUS internal_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) +{ + return NT_STATUS_NOT_SUPPORTED; +} +#endif + +/****************************************************************************** + Generic code for client and server. + gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. +******************************************************************************/ + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) { - if (!srv_trans_enc_state) { + return NT_STATUS_NOT_SUPPORTED; +} +#endif + +/****************************************************************************** + Generic code for client and server. + Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. +******************************************************************************/ + +static NTSTATUS internal_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) +{ + if (!internal_encryption_on(es)) { /* Not encrypting. */ *buf_out = buffer; return NT_STATUS_OK; } - if (srv_trans_enc_state->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return srv_ntlm_encrypt_buffer(srv_trans_enc_state->ntlmssp_state, buffer, buf_out); + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + return internal_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); } else { #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return srv_gss_encrypt_buffer(srv_trans_enc_state->context_handle, buffer, buf_out); + return internal_gss_encrypt_buffer(es->context_handle, buffer, buf_out); #else return NT_STATUS_NOT_SUPPORTED; #endif } } + +/****************************************************************************** + Generic code for client and server. + Decrypt an incoming SMB buffer. Replaces the data within it. + New data must be less than or equal to the current length. +******************************************************************************/ + +static NTSTATUS internal_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) +{ + if (!internal_encryption_on(es)) { + /* Not decrypting. */ + return NT_STATUS_OK; + } + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + return internal_ntlm_decrypt_buffer(es->ntlmssp_state, buf); + } else { +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + return internal_gss_decrypt_buffer(es->context_handle, buf); +#else + return NT_STATUS_NOT_SUPPORTED; +#endif + } +} + +/****************************************************************************** + Shutdown an encryption state. +******************************************************************************/ + +static void internal_free_encryption_context(struct smb_trans_enc_state **pp_es) +{ + struct smb_trans_enc_state *es = *pp_es; + + if (es == NULL) { + return; + } + + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + ntlmssp_end(&es->ntlmssp_state); + } +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { + /* Free the gss context handle. */ + } +#endif + SAFE_FREE(es); + *pp_es = NULL; +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +static void internal_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) +{ + if (!internal_encryption_on(es)) { + return; + } + + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + SAFE_FREE(buf); + return; + } + +#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) + /* gss-api free buffer.... */ +#endif +} + +/****************************************************************************** + Client side encryption. +******************************************************************************/ + +/****************************************************************************** + Is client encryption on ? +******************************************************************************/ + +BOOL cli_encryption_on(struct cli_state *cli) +{ + return internal_encryption_on(cli->trans_enc_state); +} + +/****************************************************************************** + Shutdown a client encryption state. +******************************************************************************/ + +void cli_free_encryption_context(struct cli_state *cli) +{ + return internal_free_encryption_context(&cli->trans_enc_state); +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void cli_free_enc_buffer(struct cli_state *cli, char *buf) +{ + return internal_free_enc_buffer(cli->trans_enc_state, buf); +} + +/****************************************************************************** + Decrypt an incoming buffer. +******************************************************************************/ + +NTSTATUS cli_decrypt_message(struct cli_state *cli) +{ + return internal_decrypt_buffer(cli->trans_enc_state, cli->inbuf); +} + +/****************************************************************************** + Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) +{ + return internal_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); +} + +/****************************************************************************** + Server side encryption. +******************************************************************************/ + +/****************************************************************************** + Global server state. +******************************************************************************/ + +static struct smb_trans_enc_state *partial_srv_trans_enc_state; +static struct smb_trans_enc_state *srv_trans_enc_state; + +/****************************************************************************** + Is server encryption on ? +******************************************************************************/ + +BOOL srv_encryption_on(void) +{ + return internal_encryption_on(srv_trans_enc_state); +} + +/****************************************************************************** + Shutdown a server encryption state. +******************************************************************************/ + +void srv_free_encryption_context(void) +{ + return internal_free_encryption_context(&srv_trans_enc_state); +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void srv_free_enc_buffer(char *buf) +{ + return internal_free_enc_buffer(srv_trans_enc_state, buf); +} + +/****************************************************************************** + Decrypt an incoming buffer. +******************************************************************************/ + +NTSTATUS srv_decrypt_buffer(char *buf) +{ + return internal_decrypt_buffer(srv_trans_enc_state, buf); +} + +/****************************************************************************** + Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) +{ + return internal_encrypt_buffer(srv_trans_enc_state, buffer, buf_out); +} -- cgit From 296dcbac5897ad208c890720d3356a3ddc5f7794 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Mar 2007 01:17:47 +0000 Subject: r21882: The server part of the code has to use an AUTH_NTLMSSP struct, not just an NTLMSSP - grr. This complicates the re-use of common client and server code but I think I've got it right. Not turned on of valgrinded yet, but you can see it start to take shape ! Jeremy. (This used to be commit 60fc9c0aedf42dcd9df2ef9f1df07eaf3bca9bce) --- source3/libsmb/smb_seal.c | 102 +++++++++++----------------------------------- 1 file changed, 24 insertions(+), 78 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 2d1201ae7e..10b9d8fdcb 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -25,7 +25,7 @@ Is encryption turned on ? ******************************************************************************/ -static BOOL internal_encryption_on(struct smb_trans_enc_state *es) +BOOL common_encryption_on(struct smb_trans_enc_state *es) { return ((es != NULL) && es->enc_on); } @@ -35,7 +35,7 @@ static BOOL internal_encryption_on(struct smb_trans_enc_state *es) NTLM decrypt an incoming buffer. ******************************************************************************/ -static NTSTATUS internal_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) { NTSTATUS status; size_t orig_len = smb_len(buf); @@ -70,7 +70,7 @@ static NTSTATUS internal_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. ******************************************************************************/ -static NTSTATUS internal_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) +NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) { NTSTATUS status; char *buf_out; @@ -123,7 +123,7 @@ static NTSTATUS internal_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char ******************************************************************************/ #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -static NTSTATUS internal_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) +NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) { return NT_STATUS_NOT_SUPPORTED; } @@ -135,7 +135,7 @@ static NTSTATUS internal_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *b ******************************************************************************/ #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) +NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) { return NT_STATUS_NOT_SUPPORTED; } @@ -146,19 +146,19 @@ static NTSTATUS srv_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, c Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. ******************************************************************************/ -static NTSTATUS internal_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) +NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) { - if (!internal_encryption_on(es)) { + if (!common_encryption_on(es)) { /* Not encrypting. */ *buf_out = buffer; return NT_STATUS_OK; } if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return internal_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); + return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); } else { #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return internal_gss_encrypt_buffer(es->context_handle, buffer, buf_out); + return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out); #else return NT_STATUS_NOT_SUPPORTED; #endif @@ -171,17 +171,17 @@ static NTSTATUS internal_encrypt_buffer(struct smb_trans_enc_state *es, char *bu New data must be less than or equal to the current length. ******************************************************************************/ -static NTSTATUS internal_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) +NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) { - if (!internal_encryption_on(es)) { + if (!common_encryption_on(es)) { /* Not decrypting. */ return NT_STATUS_OK; } if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return internal_ntlm_decrypt_buffer(es->ntlmssp_state, buf); + return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); } else { #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return internal_gss_decrypt_buffer(es->context_handle, buf); + return common_gss_decrypt_buffer(es->context_handle, buf); #else return NT_STATUS_NOT_SUPPORTED; #endif @@ -192,7 +192,7 @@ static NTSTATUS internal_decrypt_buffer(struct smb_trans_enc_state *es, char *bu Shutdown an encryption state. ******************************************************************************/ -static void internal_free_encryption_context(struct smb_trans_enc_state **pp_es) +void common_free_encryption_state(struct smb_trans_enc_state **pp_es) { struct smb_trans_enc_state *es = *pp_es; @@ -201,7 +201,9 @@ static void internal_free_encryption_context(struct smb_trans_enc_state **pp_es) } if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - ntlmssp_end(&es->ntlmssp_state); + if (es->ntlmssp_state) { + ntlmssp_end(&es->ntlmssp_state); + } } #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { @@ -216,9 +218,9 @@ static void internal_free_encryption_context(struct smb_trans_enc_state **pp_es) Free an encryption-allocated buffer. ******************************************************************************/ -static void internal_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) +void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) { - if (!internal_encryption_on(es)) { + if (!common_encryption_on(es)) { return; } @@ -242,7 +244,7 @@ static void internal_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) BOOL cli_encryption_on(struct cli_state *cli) { - return internal_encryption_on(cli->trans_enc_state); + return common_encryption_on(cli->trans_enc_state); } /****************************************************************************** @@ -251,7 +253,7 @@ BOOL cli_encryption_on(struct cli_state *cli) void cli_free_encryption_context(struct cli_state *cli) { - return internal_free_encryption_context(&cli->trans_enc_state); + return common_free_encryption_state(&cli->trans_enc_state); } /****************************************************************************** @@ -260,7 +262,7 @@ void cli_free_encryption_context(struct cli_state *cli) void cli_free_enc_buffer(struct cli_state *cli, char *buf) { - return internal_free_enc_buffer(cli->trans_enc_state, buf); + return common_free_enc_buffer(cli->trans_enc_state, buf); } /****************************************************************************** @@ -269,7 +271,7 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf) NTSTATUS cli_decrypt_message(struct cli_state *cli) { - return internal_decrypt_buffer(cli->trans_enc_state, cli->inbuf); + return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); } /****************************************************************************** @@ -278,61 +280,5 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { - return internal_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); -} - -/****************************************************************************** - Server side encryption. -******************************************************************************/ - -/****************************************************************************** - Global server state. -******************************************************************************/ - -static struct smb_trans_enc_state *partial_srv_trans_enc_state; -static struct smb_trans_enc_state *srv_trans_enc_state; - -/****************************************************************************** - Is server encryption on ? -******************************************************************************/ - -BOOL srv_encryption_on(void) -{ - return internal_encryption_on(srv_trans_enc_state); -} - -/****************************************************************************** - Shutdown a server encryption state. -******************************************************************************/ - -void srv_free_encryption_context(void) -{ - return internal_free_encryption_context(&srv_trans_enc_state); -} - -/****************************************************************************** - Free an encryption-allocated buffer. -******************************************************************************/ - -void srv_free_enc_buffer(char *buf) -{ - return internal_free_enc_buffer(srv_trans_enc_state, buf); -} - -/****************************************************************************** - Decrypt an incoming buffer. -******************************************************************************/ - -NTSTATUS srv_decrypt_buffer(char *buf) -{ - return internal_decrypt_buffer(srv_trans_enc_state, buf); -} - -/****************************************************************************** - Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. -******************************************************************************/ - -NTSTATUS srv_encrypt_buffer(char *buffer, char **buf_out) -{ - return internal_encrypt_buffer(srv_trans_enc_state, buffer, buf_out); + return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); } -- cgit From efbdda540a5e0e4d8dff15b0a5891e38244c2c61 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Mar 2007 02:20:16 +0000 Subject: r21883: Try and fix the build by removing the prototypes for functions that take a gss context handle in includes.h Jeremy. (This used to be commit 638b03242d4a6b1df2477dad19240ed61a14a5a3) --- source3/libsmb/smb_seal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 10b9d8fdcb..e7b3e8f024 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -123,7 +123,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) + NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) { return NT_STATUS_NOT_SUPPORTED; } @@ -135,7 +135,7 @@ NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) ******************************************************************************/ #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) -NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) + NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) { return NT_STATUS_NOT_SUPPORTED; } -- cgit From f1ffc96a245892ab64c802e3abcf39b94fa4efe3 Mon Sep 17 00:00:00 2001 From: Rafal Szczesniak Date: Tue, 20 Mar 2007 21:21:04 +0000 Subject: r21893: Update comments so they actually reflect reality... rafal (This used to be commit 8f313061a4cbc69d8dd17aa282d79d07a9275242) --- source3/libsmb/trustdom_cache.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index dc0b5010a2..57fcc1b248 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -99,7 +99,7 @@ static char* trustdom_cache_key(const char* name) /** * Store trusted domain in gencache as the domain name (key) - * and ip address of domain controller (value) + * and trusted domain's SID (value) * * @param name trusted domain name * @param alt_name alternative trusted domain name (used in ADS domains) @@ -152,7 +152,7 @@ BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, /** - * Fetch trusted domain's dc from the gencache. + * Fetch trusted domain's SID from the gencache. * This routine can also be used to check whether given * domain is currently trusted one. * @@ -189,7 +189,7 @@ BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) DEBUG(5, ("trusted domain %s found (%s)\n", name, value)); } - /* convert ip string representation into in_addr structure */ + /* convert sid string representation into DOM_SID structure */ if(! string_to_sid(sid, value)) { sid = NULL; SAFE_FREE(value); -- cgit From 6b0dcfa62d23980351e852eec05123c0a9823f1d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Mar 2007 22:01:02 +0000 Subject: r21894: Some refactoring of server side encryption context. Support "raw" NTLM auth (no spnego). Jeremy. (This used to be commit 6b5ff7bd591b4f65e2eb767928db50ddf445f09a) --- source3/libsmb/cliconnect.c | 3 +-- source3/libsmb/smb_seal.c | 12 ++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 0f09747dbf..3970731b45 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -763,7 +763,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use } } - /* we have a reference conter on ntlmssp_state, if we are signing + /* we have a reference counter on ntlmssp_state, if we are signing then the state will be kept by the signing engine */ ntlmssp_end(&ntlmssp_state); @@ -973,7 +973,6 @@ NTSTATUS cli_session_setup(struct cli_state *cli, } return NT_STATUS_OK; - } /**************************************************************************** diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index e7b3e8f024..06662e53fb 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -282,3 +282,15 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); } + +/****************************************************************************** + Start a raw ntlmssp encryption. +******************************************************************************/ + +NTSTATUS cli_ntlm_smb_encryption_on(struct cli_state *cli, + const char *user, + const char *pass, + const char *workgroup) +{ + +} -- cgit From 071db6fdbff694681fa1793ee678a9a0af3e266a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 00:25:08 +0000 Subject: r21897: Add in a basic raw NTLM encrypt request. Now for testing. Jeremy. (This used to be commit 783a7b3085a155d9652cd725bf2960cd272cb554) --- source3/libsmb/clifsinfo.c | 113 +++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/smb_seal.c | 24 ++++----- source3/libsmb/smb_signing.c | 38 +++++++++++++-- 3 files changed, 159 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 9c3b6e3aed..52e12a38e3 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -302,3 +302,116 @@ cleanup: return ret; } + +/****************************************************************************** + Send/receive the request encryption blob. +******************************************************************************/ + +static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out) +{ + uint16 setup; + char param[2]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + NTSTATUS status = NT_STATUS_OK; + + setup = TRANSACT2_SETFSINFO; + + SSVAL(param,0,SMB_REQUEST_TRANSPORT_ENCRYPTION); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 2, 0, + (char *)in->data, in->length, CLI_BUFFER_SIZE)) { + status = cli_nt_error(cli); + goto out; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + status = cli_nt_error(cli); + goto out; + } + + if (cli_is_error(cli)) { + status = cli_nt_error(cli); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto out; + } + } + + *out = data_blob(rdata, rdata_count); + + out: + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return status; +} + +/****************************************************************************** + Start a raw ntlmssp encryption. +******************************************************************************/ + +NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, + const char *user, + const char *pass, + const char *domain) +{ + DATA_BLOB blob_in = data_blob(NULL, 0); + DATA_BLOB blob_out = data_blob(NULL, 0); + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + struct smb_trans_enc_state *es = NULL; + + es = SMB_MALLOC_P(struct smb_trans_enc_state); + if (!es) { + return NT_STATUS_NO_MEMORY; + } + ZERO_STRUCTP(es); + es->smb_enc_type = SMB_TRANS_ENC_NTLM; + status = ntlmssp_client_start(&es->ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + ntlmssp_want_feature(es->ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); + es->ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL); + + if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->ntlmssp_state, user))) { + goto fail; + } + if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->ntlmssp_state, domain))) { + goto fail; + } + if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->ntlmssp_state, pass))) { + goto fail; + } + + do { + status = ntlmssp_update(es->ntlmssp_state, blob_in, &blob_out); + data_blob_free(&blob_in); + if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) { + status = enc_blob_send_receive(cli, &blob_out, &blob_in); + } + data_blob_free(&blob_out); + } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); + + data_blob_free(&blob_in); + + if (NT_STATUS_IS_OK(status)) { + /* Replace the old state, if any. */ + if (cli->trans_enc_state) { + common_free_encryption_state(&cli->trans_enc_state); + } + cli->trans_enc_state = es; + cli->trans_enc_state->enc_on = True; + } + + fail: + + common_free_encryption_state(&es); + return status; +} diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 06662e53fb..a509438f07 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -154,6 +154,12 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha return NT_STATUS_OK; } + /* Ignore session keepalives. */ + if(CVAL(buffer,0) == SMBkeepalive) { + *buf_out = buffer; + return NT_STATUS_OK; + } + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); } else { @@ -177,6 +183,12 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) /* Not decrypting. */ return NT_STATUS_OK; } + + /* Ignore session keepalives. */ + if(CVAL(buf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); } else { @@ -282,15 +294,3 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); } - -/****************************************************************************** - Start a raw ntlmssp encryption. -******************************************************************************/ - -NTSTATUS cli_ntlm_smb_encryption_on(struct cli_state *cli, - const char *user, - const char *pass, - const char *workgroup) -{ - -} diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index df74b2db36..66a15e9408 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -585,7 +585,9 @@ void cli_free_signing_context(struct cli_state *cli) void cli_calculate_sign_mac(struct cli_state *cli) { - cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); + if (!cli_encryption_on(cli)) { + cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); + } } /** @@ -596,6 +598,9 @@ void cli_calculate_sign_mac(struct cli_state *cli) BOOL cli_check_sign_mac(struct cli_state *cli) { + if (cli_encryption_on(cli)) { + return True; + } if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; @@ -612,6 +617,9 @@ BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + if (cli_encryption_on(cli)) { + return True; + } if (!si->doing_signing) { return True; } @@ -637,6 +645,9 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + if (cli_encryption_on(cli)) { + return True; + } if (!si->doing_signing) { return True; } @@ -798,8 +809,18 @@ BOOL srv_oplock_set_signing(BOOL onoff) BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) { /* Check if it's a session keepalive. */ - if(CVAL(inbuf,0) == SMBkeepalive) + if(CVAL(inbuf,0) == SMBkeepalive) { return True; + } + + /* + * If we have an encrypted transport + * don't sign - we're already doing that. + */ + + if (srv_encryption_on()) { + return True; + } return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); } @@ -811,9 +832,18 @@ BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) void srv_calculate_sign_mac(char *outbuf) { /* Check if it's a session keepalive. */ - /* JRA Paranioa test - do we ever generate these in the server ? */ - if(CVAL(outbuf,0) == SMBkeepalive) + if(CVAL(outbuf,0) == SMBkeepalive) { return; + } + + /* + * If we have an encrypted transport + * don't check sign - we're already doing that. + */ + + if (srv_encryption_on()) { + return; + } srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } -- cgit From a828b56884a1385823cdb1d186860a1e1466fca7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 00:44:15 +0000 Subject: r21898: Added test command, fixed first valgrind bugs. Now to investigate why it doesn't work :-). Jeremy. (This used to be commit 73f7c6cef8371ad63eb1dc3e79bfc78503dbd7a4) --- source3/libsmb/clifsinfo.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 52e12a38e3..0bd1e124ea 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -310,20 +310,21 @@ cleanup: static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out) { uint16 setup; - char param[2]; + char param[4]; char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; NTSTATUS status = NT_STATUS_OK; setup = TRANSACT2_SETFSINFO; - SSVAL(param,0,SMB_REQUEST_TRANSPORT_ENCRYPTION); + SSVAL(param,0,0); + SSVAL(param,2,SMB_REQUEST_TRANSPORT_ENCRYPTION); if (!cli_send_trans(cli, SMBtrans2, NULL, 0, 0, &setup, 1, 0, - param, 2, 0, + param, 4, 0, (char *)in->data, in->length, CLI_BUFFER_SIZE)) { status = cli_nt_error(cli); goto out; -- cgit From 7e55a6e6c77f5ddabbb3c4b1d7739ef60d6d30b6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 00:56:40 +0000 Subject: r21899: At least we're getting to stage 2 of the blob exchange. Still not working but closer. Jeremy. (This used to be commit 2fde5c703d2390bc6685f34713dc996e69732f1a) --- source3/libsmb/clitrans.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 27207e72e2..33fddae202 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -194,11 +194,15 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, * to a trans call. This is not an error and should not * be treated as such. Note that STATUS_NO_MORE_FILES is * returned when a trans2 findfirst/next finishes. + * When setting up an encrypted transport we can also + * see NT_STATUS_MORE_PROCESSING_REQUIRED here. */ status = cli_nt_error(cli); - if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) { - goto out; + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) { + goto out; + } } /* parse out the lengths */ @@ -303,8 +307,10 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, CVAL(cli->inbuf,smb_com))); goto out; } - if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { - goto out; + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + if (NT_STATUS_IS_ERR(cli_nt_error(cli))) { + goto out; + } } /* parse out the total lengths again - they can shrink! */ -- cgit From 9874b3bfa7f7e7de0e389ea84dbff4a824520bc2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 01:32:01 +0000 Subject: r21902: Don't free the thing you're trying to set in the cli state. Jeremy. (This used to be commit 1639366561bd63d7023c54f811e2f87dcbbd0a31) --- source3/libsmb/clifsinfo.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 0bd1e124ea..8e994dd67b 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -409,6 +409,7 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, } cli->trans_enc_state = es; cli->trans_enc_state->enc_on = True; + es = NULL; } fail: -- cgit From 6aff12a9f6c33b61fe9ab89d703677a3202185db Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 02:02:09 +0000 Subject: r21903: Get the length calculations right (I always forget the 4 byte length isn't included in the length :-). We now have working NTLMSSP transport encryption with sign+seal. W00t! Jeremy. (This used to be commit d34584cb5c53c194693ce7236020ab83f60cd235) --- source3/libsmb/smb_seal.c | 34 ++++++++++++++++++---------------- 1 file changed, 18 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index a509438f07..bf7f337a97 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -38,30 +38,33 @@ BOOL common_encryption_on(struct smb_trans_enc_state *es) NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) { NTSTATUS status; - size_t orig_len = smb_len(buf); - size_t new_len = orig_len - NTLMSSP_SIG_SIZE; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ DATA_BLOB sig; - if (orig_len < 8 + NTLMSSP_SIG_SIZE) { + if (buf_len < 8 + NTLMSSP_SIG_SIZE) { return NT_STATUS_BUFFER_TOO_SMALL; } + /* Adjust for the signature. */ + buf_len -= NTLMSSP_SIG_SIZE; + /* Save off the signature. */ - sig = data_blob(buf+orig_len-NTLMSSP_SIG_SIZE, NTLMSSP_SIG_SIZE); + sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE); status = ntlmssp_unseal_packet(ntlmssp_state, (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ - new_len - 8, + buf_len - 8, (unsigned char *)buf, - new_len, + buf_len, &sig); if (!NT_STATUS_IS_OK(status)) { data_blob_free(&sig); return status; } + /* Reset the length. */ - smb_setlen(buf, new_len); + smb_setlen(buf, smb_len(buf) - NTLMSSP_SIG_SIZE); return NT_STATUS_OK; } @@ -74,13 +77,12 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha { NTSTATUS status; char *buf_out; - size_t orig_len = smb_len(buf); - size_t new_len = orig_len + NTLMSSP_SIG_SIZE; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ DATA_BLOB sig; *ppbuf_out = NULL; - if (orig_len < 8) { + if (buf_len < 8) { return NT_STATUS_BUFFER_TOO_SMALL; } @@ -91,19 +93,19 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha /* Copy the original buffer. */ - buf_out = SMB_XMALLOC_ARRAY(char, new_len); - memcpy(buf_out, buf, orig_len); + buf_out = SMB_XMALLOC_ARRAY(char, buf_len + NTLMSSP_SIG_SIZE); + memcpy(buf_out, buf, buf_len); /* Last 16 bytes undefined here... */ - smb_setlen(buf_out, new_len); + smb_setlen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE); sig = data_blob(NULL, NTLMSSP_SIG_SIZE); status = ntlmssp_seal_packet(ntlmssp_state, (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ - orig_len - 8, + buf_len - 8, (unsigned char *)buf_out, - orig_len, + buf_len, &sig); if (!NT_STATUS_IS_OK(status)) { @@ -112,7 +114,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha return status; } - memcpy(buf_out+orig_len, sig.data, NTLMSSP_SIG_SIZE); + memcpy(buf_out+buf_len, sig.data, NTLMSSP_SIG_SIZE); *ppbuf_out = buf_out; return NT_STATUS_OK; } -- cgit From d8bb69515b49808b791585d69a50c5237614b1ad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 17:13:35 +0000 Subject: r21912: There's no point checksumming the packet length this already has to be right. This makes the signed+sealed area the same as it will be with gss calls. Now to go implement them. Jeremy. (This used to be commit 80810af7d1137b3ddd3073581d5ec99fadaa81a5) --- source3/libsmb/smb_seal.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index bf7f337a97..7a27f88a2e 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -54,8 +54,8 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) status = ntlmssp_unseal_packet(ntlmssp_state, (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ buf_len - 8, - (unsigned char *)buf, - buf_len, + (unsigned char *)buf + 8, + buf_len - 8, &sig); if (!NT_STATUS_IS_OK(status)) { @@ -104,8 +104,8 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha status = ntlmssp_seal_packet(ntlmssp_state, (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ buf_len - 8, - (unsigned char *)buf_out, - buf_len, + (unsigned char *)buf_out + 8, + buf_len - 8, &sig); if (!NT_STATUS_IS_OK(status)) { -- cgit From 56c777882f0e9fc64e69290db8f6db5fe90225fd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 18:33:13 +0000 Subject: r21916: Fix couple of "return" calls on void functions. Ensure we ignore reqests to free keepalive buffers as we only copied these. Jeremy. (This used to be commit a184bdbe3c7bf0c44a8141898bfcb9971a332312) --- source3/libsmb/smb_seal.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 7a27f88a2e..9ea3a10350 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -238,6 +238,14 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) return; } + /* We know this is an smb buffer, and we + * didn't malloc, only copy, for a keepalive, + * so ignore session keepalives. */ + + if(CVAL(buf,0) == SMBkeepalive) { + return; + } + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { SAFE_FREE(buf); return; @@ -267,7 +275,7 @@ BOOL cli_encryption_on(struct cli_state *cli) void cli_free_encryption_context(struct cli_state *cli) { - return common_free_encryption_state(&cli->trans_enc_state); + common_free_encryption_state(&cli->trans_enc_state); } /****************************************************************************** @@ -276,7 +284,7 @@ void cli_free_encryption_context(struct cli_state *cli) void cli_free_enc_buffer(struct cli_state *cli, char *buf) { - return common_free_enc_buffer(cli->trans_enc_state, buf); + common_free_enc_buffer(cli->trans_enc_state, buf); } /****************************************************************************** -- cgit From 42238c78bb8820a21cfb08fc29a5109ee1a62bab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 19:15:14 +0000 Subject: r21917: Start to do the gss versions of sign+seal. Jeremy. (This used to be commit a226645353a40047b72de1b96c3a7676a2bf1034) --- source3/libsmb/smb_seal.c | 97 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 77 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 9ea3a10350..f16c1402a2 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -124,7 +124,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha gss-api decrypt an incoming buffer. ******************************************************************************/ -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) { return NT_STATUS_NOT_SUPPORTED; @@ -136,10 +136,65 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. ******************************************************************************/ -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out) +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **ppbuf_out) { - return NT_STATUS_NOT_SUPPORTED; + OM_uint32 ret = 0; + OM_uint32 minor = 0; + int flags_got = 0; + gss_buffer_desc in_buf, out_buf; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + + *ppbuf_out = NULL; + + if (buf_len < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + in_buf.value = buf + 8; + in_buf.length = buf_len - 8; + + ret = gss_wrap(&minor, + context_handle, + True, /* we want sign+seal. */ + GSS_C_QOP_DEFAULT, + &in_buf, + &flags_got, /* did we get sign+seal ? */ + &out_buf); + + if (ret != GSS_S_COMPLETE) { + /* Um - no mapping for gss-errs to NTSTATUS yet. */ + return NT_STATUS_UNSUCCESSFUL; + } + + if (!flags_got) { + /* Sign+seal not supported. */ + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_NOT_SUPPORTED; + } + + /* Ya see - this is why I *hate* gss-api. I don't + * want to have to malloc another buffer of the + * same size + 8 bytes just to get a continuous + * header + buffer, but gss won't let me pass in + * a pre-allocated buffer. Bastards (and you know + * who you are....). I might fix this by + * going to "encrypt_and_send" passing in a file + * descriptor and doing scatter-gather write with + * TCP cork on Linux. But I shouldn't have to + * bother :-*(. JRA. + */ + + *ppbuf_out = SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */ + if (!*ppbuf_out) { + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_NO_MEMORY; + } + + smb_setlen(*ppbuf_out, out_buf.length + 8); + memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_OK; } #endif @@ -162,14 +217,15 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha return NT_STATUS_OK; } - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); - } else { -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out); -#else - return NT_STATUS_NOT_SUPPORTED; + switch (es->smb_enc_type) { + case SMB_TRANS_ENC_NTLM: + return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + case SMB_TRANS_ENC_GSS: + return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out); #endif + default: + return NT_STATUS_NOT_SUPPORTED; } } @@ -191,14 +247,15 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) return NT_STATUS_OK; } - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); - } else { -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) - return common_gss_decrypt_buffer(es->context_handle, buf); -#else - return NT_STATUS_NOT_SUPPORTED; + switch (es->smb_enc_type) { + case SMB_TRANS_ENC_NTLM: + return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + case SMB_TRANS_ENC_GSS: + return common_gss_decrypt_buffer(es->context_handle, buf); #endif + default: + return NT_STATUS_NOT_SUPPORTED; } } @@ -219,7 +276,7 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es) ntlmssp_end(&es->ntlmssp_state); } } -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { /* Free the gss context handle. */ } @@ -251,7 +308,7 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) return; } -#if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5) +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) /* gss-api free buffer.... */ #endif } -- cgit From 8c395be5e514a28f13608a462c0c0e8417e21160 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Mar 2007 23:49:57 +0000 Subject: r21922: Fixed the build by rather horrid means. I really need to restructure libsmb/smb_signing.c so it isn't in the base libs path but lives in libsmb instead (like smb_seal.c does). Jeremy. (This used to be commit 1b828f051d0782201f697de15ff973bd6b097d5b) --- source3/libsmb/cliconnect.c | 20 +++++++-------- source3/libsmb/clientgen.c | 58 +++++++++++++++++++++++--------------------- source3/libsmb/smb_seal.c | 5 +++- source3/libsmb/smb_signing.c | 31 +---------------------- 4 files changed, 46 insertions(+), 68 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3970731b45..15dac093da 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -742,25 +742,25 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length); DATA_BLOB null_blob = data_blob(NULL, 0); - BOOL res; fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); - res = cli_simple_set_signing(cli, key, null_blob); + if (!cli_encryption_on(cli)) { + BOOL res = cli_simple_set_signing(cli, key, null_blob); - data_blob_free(&key); - - if (res) { + if (res) { - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli); + /* 'resign' the last message, so we get the right sequence numbers + for checking the first reply from the server */ + cli_calculate_sign_mac(cli); - if (!cli_check_sign_mac(cli)) { - nt_status = NT_STATUS_ACCESS_DENIED; + if (!cli_check_sign_mac(cli)) { + nt_status = NT_STATUS_ACCESS_DENIED; + } } } + data_blob_free(&key); } /* we have a reference counter on ntlmssp_state, if we are signing diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 52ffdc24e7..1aa0ddcc10 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -57,7 +57,6 @@ int cli_set_port(struct cli_state *cli, int port) static BOOL client_receive_smb(struct cli_state *cli) { BOOL ret; - NTSTATUS status; int fd = cli->fd; char *buffer = cli->inbuf; unsigned int timeout = cli->timeout; @@ -75,14 +74,16 @@ static BOOL client_receive_smb(struct cli_state *cli) if(CVAL(buffer,0) != SMBkeepalive) break; } - status = cli_decrypt_message(cli); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", - nt_errstr(status))); - cli->smb_rw_error = READ_BAD_DECRYPT; - close(cli->fd); - cli->fd = -1; - return False; + if (cli_encryption_on(cli)) { + NTSTATUS status = cli_decrypt_message(cli); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", + nt_errstr(status))); + cli->smb_rw_error = READ_BAD_DECRYPT; + close(cli->fd); + cli->fd = -1; + return False; + } } show_msg(buffer); return ret; @@ -129,13 +130,15 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_check_sign_mac(cli)) { - DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); - cli->smb_rw_error = READ_BAD_SIG; - close(cli->fd); - cli->fd = -1; - return False; - }; + if (!cli_encryption_on(cli)) { + if (!cli_check_sign_mac(cli)) { + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); + cli->smb_rw_error = READ_BAD_SIG; + close(cli->fd); + cli->fd = -1; + return False; + } + } return True; } @@ -160,7 +163,6 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) BOOL cli_send_smb(struct cli_state *cli) { - NTSTATUS status; size_t len; size_t nwritten=0; ssize_t ret; @@ -171,16 +173,18 @@ BOOL cli_send_smb(struct cli_state *cli) return False; } - cli_calculate_sign_mac(cli); - - status = cli_encrypt_message(cli, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; - DEBUG(0,("Error in encrypting client message. Error %s\n", - nt_errstr(status) )); - return False; + if (cli_encryption_on(cli)) { + NTSTATUS status = cli_encrypt_message(cli, &buf_out); + if (!NT_STATUS_IS_OK(status)) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; + DEBUG(0,("Error in encrypting client message. Error %s\n", + nt_errstr(status) )); + return False; + } + } else { + cli_calculate_sign_mac(cli); } len = smb_len(buf_out) + 4; diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index f16c1402a2..d08b27e7cd 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -163,8 +163,11 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha &out_buf); if (ret != GSS_S_COMPLETE) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); + DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", + ads_errstr(adss) )); /* Um - no mapping for gss-errs to NTSTATUS yet. */ - return NT_STATUS_UNSUCCESSFUL; + return ads_ntstatus(adss); } if (!flags_got) { diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 66a15e9408..0395208986 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -585,9 +585,7 @@ void cli_free_signing_context(struct cli_state *cli) void cli_calculate_sign_mac(struct cli_state *cli) { - if (!cli_encryption_on(cli)) { - cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); - } + cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); } /** @@ -598,9 +596,6 @@ void cli_calculate_sign_mac(struct cli_state *cli) BOOL cli_check_sign_mac(struct cli_state *cli) { - if (cli_encryption_on(cli)) { - return True; - } if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; @@ -617,9 +612,6 @@ BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - if (cli_encryption_on(cli)) { - return True; - } if (!si->doing_signing) { return True; } @@ -645,9 +637,6 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - if (cli_encryption_on(cli)) { - return True; - } if (!si->doing_signing) { return True; } @@ -813,15 +802,6 @@ BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) return True; } - /* - * If we have an encrypted transport - * don't sign - we're already doing that. - */ - - if (srv_encryption_on()) { - return True; - } - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); } @@ -836,15 +816,6 @@ void srv_calculate_sign_mac(char *outbuf) return; } - /* - * If we have an encrypted transport - * don't check sign - we're already doing that. - */ - - if (srv_encryption_on()) { - return; - } - srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); } -- cgit From 5a025d845a73c4ce5ebc0496b1257bb89ef401e6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Mar 2007 00:08:22 +0000 Subject: r21923: Add in the gss decrypt. Jeremy. (This used to be commit 00f58951b4cace06e51e7eb404605c7f3d366f38) --- source3/libsmb/smb_seal.c | 48 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index d08b27e7cd..63fa49046a 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -121,13 +121,54 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha /****************************************************************************** Generic code for client and server. - gss-api decrypt an incoming buffer. + gss-api decrypt an incoming buffer. We insist that the size of the + unwrapped buffer must be smaller or identical to the incoming buffer. ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) { - return NT_STATUS_NOT_SUPPORTED; + OM_uint32 ret = 0; + OM_uint32 minor = 0; + int flags_got = 0; + gss_buffer_desc in_buf, out_buf; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + + if (buf_len < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + in_buf.value = buf + 8; + in_buf.length = buf_len - 8; + + ret = gss_unwrap(&minor, + context_handle, + &in_buf, + &out_buf, + &flags_got, /* did we get sign+seal ? */ + (gss_qop_t *) NULL); + + if (ret != GSS_S_COMPLETE) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); + DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", + ads_errstr(adss) )); + /* Um - no mapping for gss-errs to NTSTATUS yet. */ + return ads_ntstatus(adss); + } + + if (out_buf.length > in_buf.length) { + DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap size (%u) too large (%u) !\n", + (unsigned int)out_buf.length, + (unsigned int)in_buf.length )); + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_INVALID_PARAMETER; + } + + memcpy(buf + 8, out_buf.value, out_buf.length); + smb_setlen(buf, out_buf.length + 4); + + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_OK; } #endif @@ -194,8 +235,9 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha return NT_STATUS_NO_MEMORY; } - smb_setlen(*ppbuf_out, out_buf.length + 8); memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); + smb_setlen(*ppbuf_out, out_buf.length + 4); + gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; } -- cgit From f93d75c932e7a48da8bcd589d7505bf5445b89df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Mar 2007 02:24:12 +0000 Subject: r21926: Fix missing enum specifier pointed out by Don McCall @ HP. Thanks Don ! Jeremy. (This used to be commit 662344d1ec3593689de7602afa518ed98e10dc37) --- source3/libsmb/clifsinfo.c | 14 +++++++------- source3/libsmb/smb_seal.c | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 8e994dd67b..92537ed317 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -373,26 +373,26 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, } ZERO_STRUCTP(es); es->smb_enc_type = SMB_TRANS_ENC_NTLM; - status = ntlmssp_client_start(&es->ntlmssp_state); + status = ntlmssp_client_start(&es->s.ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { goto fail; } - ntlmssp_want_feature(es->ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); - es->ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL); + ntlmssp_want_feature(es->s.ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); + es->s.ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL); - if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->ntlmssp_state, user))) { + if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->s.ntlmssp_state, user))) { goto fail; } - if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->ntlmssp_state, domain))) { + if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->s.ntlmssp_state, domain))) { goto fail; } - if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->ntlmssp_state, pass))) { + if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->s.ntlmssp_state, pass))) { goto fail; } do { - status = ntlmssp_update(es->ntlmssp_state, blob_in, &blob_out); + status = ntlmssp_update(es->s.ntlmssp_state, blob_in, &blob_out); data_blob_free(&blob_in); if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) { status = enc_blob_send_receive(cli, &blob_out, &blob_in); diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 63fa49046a..95012d629e 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -264,10 +264,10 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha switch (es->smb_enc_type) { case SMB_TRANS_ENC_NTLM: - return common_ntlm_encrypt_buffer(es->ntlmssp_state, buffer, buf_out); + return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, buffer, buf_out); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_encrypt_buffer(es->context_handle, buffer, buf_out); + return common_gss_encrypt_buffer(es->s.context_handle, buffer, buf_out); #endif default: return NT_STATUS_NOT_SUPPORTED; @@ -294,10 +294,10 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) switch (es->smb_enc_type) { case SMB_TRANS_ENC_NTLM: - return common_ntlm_decrypt_buffer(es->ntlmssp_state, buf); + return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_decrypt_buffer(es->context_handle, buf); + return common_gss_decrypt_buffer(es->s.context_handle, buf); #endif default: return NT_STATUS_NOT_SUPPORTED; @@ -317,8 +317,8 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es) } if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - if (es->ntlmssp_state) { - ntlmssp_end(&es->ntlmssp_state); + if (es->s.ntlmssp_state) { + ntlmssp_end(&es->s.ntlmssp_state); } } #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) -- cgit From 00320f7a5828b491e09eb65226f72b174fd69eb0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Mar 2007 17:37:01 +0000 Subject: r21932: fix compiler warning. maybe also for 3.0.25 metze (This used to be commit 844dac912cb549b0524571df80fbaa7f2d9c36c2) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index e8929c1589..7a197f57f8 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -500,7 +500,7 @@ static int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - int size; + size_t size; struct sockaddr addr; /* -- cgit From d506caf2b586e8fe06d38d17658f12400e3cccc5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Mar 2007 19:41:17 +0000 Subject: r21939: Fix missing initialization that broke the build farm. Thanks to Metze for the heads up. Jeremy. (This used to be commit bb3623be3f2b0686b2b2e671e3e7bd9978f6ed9b) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1aa0ddcc10..a3873a47fe 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -166,7 +166,7 @@ BOOL cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; - char *buf_out; + char *buf_out = cli->outbuf; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) { -- cgit From b3646bd809fc7688145d3e4a7b90fb8a64979a48 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 23 Mar 2007 17:00:00 +0000 Subject: r21947: Fix the equivalent of memcpy(x, x, 16). Found by valgrind on the build farm. Jeremy. (This used to be commit 6eed92dfd4da1f9979831bec8e0dcdee33fb53b4) --- source3/libsmb/credentials.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 76fc5fc062..3243719d5c 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -101,7 +101,9 @@ static void creds_init_64(struct dcinfo *dc, unsigned char sum2[8]; /* Just in case this isn't already there */ - memcpy(dc->mach_pw, mach_pw, 16); + if (dc->mach_pw != mach_pw) { + memcpy(dc->mach_pw, mach_pw, 16); + } sum[0] = IVAL(clnt_chal_in->data, 0) + IVAL(srv_chal_in->data, 0); sum[1] = IVAL(clnt_chal_in->data, 4) + IVAL(srv_chal_in->data, 4); -- cgit From 3adeddcc4a948ec230db7ea4a6b0d3f1640ff3a6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 00:00:50 +0000 Subject: r21967: Add conversion from gss errors to nt status. Jeremy (This used to be commit 8ba138efd097b08dcfe98f99b67c77579babf250) --- source3/libsmb/errormap.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index cb5e8311ca..a78b0af81a 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -4,6 +4,7 @@ * Copyright (C) Andrew Tridgell 2001 * Copyright (C) Andrew Bartlett 2001 * Copyright (C) Tim Potter 2000 + * Copyright (C) Jeremy Allison 2007 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1566,3 +1567,104 @@ NTSTATUS map_nt_error_from_unix(int unix_error) /* Default return */ return NT_STATUS_ACCESS_DENIED; } + +#if defined(HAVE_GSSAPI) +/******************************************************************************* + Map between gssapi errors and NT status. I made these up :-(. JRA. +*******************************************************************************/ + +static const struct { + unsigned long gss_err; + NTSTATUS ntstatus; +} gss_to_ntstatus_errormap[] = { +#if defined(GSS_S_CALL_INACCESSIBLE_READ) + {GSS_S_CALL_INACCESSIBLE_READ, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_CALL_INACCESSIBLE_WRITE) + {GSS_S_CALL_INACCESSIBLE_WRITE, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_CALL_BAD_STRUCTURE) + {GSS_S_CALL_BAD_STRUCTURE, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_MECH) + {GSS_S_BAD_MECH, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_NAME) + {GSS_S_BAD_NAME, NT_STATUS_INVALID_ACCOUNT_NAME}, +#endif +#if defined(GSS_S_BAD_NAMETYPE) + {GSS_S_BAD_NAMETYPE, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_BINDINGS) + {GSS_S_BAD_BINDINGS, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_STATUS) + {GSS_S_BAD_STATUS, NT_STATUS_UNSUCCESSFUL}, +#endif +#if defined(GSS_S_BAD_SIG) + {GSS_S_BAD_SIG, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_NO_CRED) + {GSS_S_NO_CRED, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_NO_CONTEXT) + {GSS_S_NO_CONTEXT, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_DEFECTIVE_TOKEN) + {GSS_S_DEFECTIVE_TOKEN, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_DEFECTIVE_CREDENTIAL) + {GSS_S_DEFECTIVE_CREDENTIAL, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_CREDENTIALS_EXPIRED) + {GSS_S_CREDENTIALS_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, +#endif +#if defined(GSS_S_CONTEXT_EXPIRED) + {GSS_S_CONTEXT_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, +#endif +#if defined(GSS_S_BAD_QOP) + {GSS_S_BAD_QOP, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_UNAUTHORIZED) + {GSS_S_UNAUTHORIZED, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_UNAVAILABLE) + {GSS_S_UNAVAILABLE, NT_STATUS_UNSUCCESSFUL}, +#endif +#if defined(GSS_S_BAD_NAMETYPE) + {GSS_S_DUPLICATE_ELEMENT, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_NAMETYPE) + {GSS_S_NAME_NOT_MN, NT_STATUS_INVALID_PARAMETER}, +#endif + { 0, NT_STATUS_OK } +}; + +/********************************************************************* + Map an NT error code from a gssapi error code. +*********************************************************************/ + +NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor) +{ + int i = 0; + + if (gss_maj == GSS_S_COMPLETE) { + return NT_STATUS_OK; + } + + if (gss_maj == GSS_S_FAILURE) { + return map_nt_error_from_unix((int)minor); + } + + /* Look through list */ + while(gss_to_ntstatus_errormap[i].gss_err != 0) { + if (gss_to_ntstatus_errormap[i].gss_err == gss_maj) { + return gss_to_ntstatus_errormap[i].ntstatus; + } + i++; + } + + /* Default return */ + return NT_STATUS_ACCESS_DENIED; +} +#endif -- cgit From 8b63654c2e63448cc21505d7996e1a4805e391df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 00:50:53 +0000 Subject: r21969: Start working on the gss-side of the server negotiation. Jeremy. (This used to be commit fbc569b530104679e47fe743963eb0c4384de6ae) --- source3/libsmb/smb_seal.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 95012d629e..f0e79b404c 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -126,8 +126,9 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf) + NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) { + gss_ctx_id_t gss_ctx = gss_state->gss_ctx; OM_uint32 ret = 0; OM_uint32 minor = 0; int flags_got = 0; @@ -142,7 +143,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha in_buf.length = buf_len - 8; ret = gss_unwrap(&minor, - context_handle, + gss_ctx, &in_buf, &out_buf, &flags_got, /* did we get sign+seal ? */ @@ -178,8 +179,9 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **ppbuf_out) + NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf, char **ppbuf_out) { + gss_ctx_id_t gss_ctx = gss_state->gss_ctx; OM_uint32 ret = 0; OM_uint32 minor = 0; int flags_got = 0; @@ -196,7 +198,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha in_buf.length = buf_len - 8; ret = gss_wrap(&minor, - context_handle, + gss_ctx, True, /* we want sign+seal. */ GSS_C_QOP_DEFAULT, &in_buf, @@ -267,7 +269,7 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, buffer, buf_out); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_encrypt_buffer(es->s.context_handle, buffer, buf_out); + return common_gss_encrypt_buffer(es->s.gss_state, buffer, buf_out); #endif default: return NT_STATUS_NOT_SUPPORTED; @@ -297,13 +299,29 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_decrypt_buffer(es->s.context_handle, buf); + return common_gss_decrypt_buffer(es->s.gss_state, buf); #endif default: return NT_STATUS_NOT_SUPPORTED; } } +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) +/****************************************************************************** + Shutdown a gss encryption state. +******************************************************************************/ + +static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state) +{ + OM_uint32 minor = 0; + struct smb_tran_enc_state_gss *gss_state = *pp_gss_state; + + gss_release_cred(&minor, &gss_state->creds); + gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); + SAFE_FREE(*pp_gss_state); +} +#endif + /****************************************************************************** Shutdown an encryption state. ******************************************************************************/ @@ -324,6 +342,9 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es) #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { /* Free the gss context handle. */ + if (es->s.gss_state) { + common_free_gss_state(&es->s.gss_state); + } } #endif SAFE_FREE(es); -- cgit From 1c98e62118df05dd87ee71711b20280faeed9053 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Tue, 27 Mar 2007 09:30:40 +0000 Subject: r21975: if we use the _bystring() version when storing, we should use it on fetch too... metze (This used to be commit d105723f063d617ef9f8394e7921749b21f1d755) --- source3/libsmb/samlogon_cache.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index b242d0ef55..270ad27deb 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -181,7 +181,7 @@ BOOL netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) { NET_USER_INFO_3 *user = NULL; - TDB_DATA data, key; + TDB_DATA data; prs_struct ps; fstring keystr; uint32 t; @@ -194,9 +194,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user /* Prepare key as DOMAIN-SID/USER-RID string */ slprintf(keystr, sizeof(keystr), "%s", sid_string_static(user_sid)); DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); - key.dptr = keystr; - key.dsize = strlen(keystr)+1; - data = tdb_fetch( netsamlogon_tdb, key ); + data = tdb_fetch_bystring( netsamlogon_tdb, keystr ); if ( data.dptr ) { -- cgit From 34dac35e48ca0c03d2744d9925566665285eb973 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 18:04:36 +0000 Subject: r21990: Stop messing with the signing engine just because we're encrypted. This will make further changes and spec much more clear. Jeremy. (This used to be commit ffa3a5c508a494d22e8ee3ada424a6517ddf8923) --- source3/libsmb/cliconnect.c | 20 ++++++++++---------- source3/libsmb/clientgen.c | 20 ++++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 15dac093da..3970731b45 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -742,25 +742,25 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length); DATA_BLOB null_blob = data_blob(NULL, 0); + BOOL res; fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); - if (!cli_encryption_on(cli)) { - BOOL res = cli_simple_set_signing(cli, key, null_blob); + res = cli_simple_set_signing(cli, key, null_blob); - if (res) { + data_blob_free(&key); + + if (res) { - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli); + /* 'resign' the last message, so we get the right sequence numbers + for checking the first reply from the server */ + cli_calculate_sign_mac(cli); - if (!cli_check_sign_mac(cli)) { - nt_status = NT_STATUS_ACCESS_DENIED; - } + if (!cli_check_sign_mac(cli)) { + nt_status = NT_STATUS_ACCESS_DENIED; } } - data_blob_free(&key); } /* we have a reference counter on ntlmssp_state, if we are signing diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a3873a47fe..92fc72fd5c 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -74,6 +74,7 @@ static BOOL client_receive_smb(struct cli_state *cli) if(CVAL(buffer,0) != SMBkeepalive) break; } + if (cli_encryption_on(cli)) { NTSTATUS status = cli_decrypt_message(cli); if (!NT_STATUS_IS_OK(status)) { @@ -130,15 +131,14 @@ BOOL cli_receive_smb(struct cli_state *cli) return ret; } - if (!cli_encryption_on(cli)) { - if (!cli_check_sign_mac(cli)) { - DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); - cli->smb_rw_error = READ_BAD_SIG; - close(cli->fd); - cli->fd = -1; - return False; - } + if (!cli_check_sign_mac(cli)) { + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); + cli->smb_rw_error = READ_BAD_SIG; + close(cli->fd); + cli->fd = -1; + return False; } + return True; } @@ -173,6 +173,8 @@ BOOL cli_send_smb(struct cli_state *cli) return False; } + cli_calculate_sign_mac(cli); + if (cli_encryption_on(cli)) { NTSTATUS status = cli_encrypt_message(cli, &buf_out); if (!NT_STATUS_IS_OK(status)) { @@ -183,8 +185,6 @@ BOOL cli_send_smb(struct cli_state *cli) nt_errstr(status) )); return False; } - } else { - cli_calculate_sign_mac(cli); } len = smb_len(buf_out) + 4; -- cgit From 4a66d0e232271968ba96da50274428916a393975 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 21:13:31 +0000 Subject: r21991: I hate Steve French :-). Add support for encryption contexts.... Jeremy. (This used to be commit ae8f3649f773b8a8dcb55921536d038d3475322e) --- source3/libsmb/clientgen.c | 7 ++- source3/libsmb/clifsinfo.c | 10 +++- source3/libsmb/smb_seal.c | 111 +++++++++++++++++++++++++++++++++------------ 3 files changed, 95 insertions(+), 33 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 92fc72fd5c..fc88f7f1e2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -167,6 +167,7 @@ BOOL cli_send_smb(struct cli_state *cli) size_t nwritten=0; ssize_t ret; char *buf_out = cli->outbuf; + BOOL enc_on = cli_encryption_on(cli); /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) { @@ -175,7 +176,7 @@ BOOL cli_send_smb(struct cli_state *cli) cli_calculate_sign_mac(cli); - if (cli_encryption_on(cli)) { + if (enc_on) { NTSTATUS status = cli_encrypt_message(cli, &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); @@ -192,7 +193,9 @@ BOOL cli_send_smb(struct cli_state *cli) while (nwritten < len) { ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { - cli_free_enc_buffer(cli, buf_out); + if (enc_on) { + cli_free_enc_buffer(cli, buf_out); + } close(cli->fd); cli->fd = -1; cli->smb_rw_error = WRITE_ERROR; diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 92537ed317..149af32574 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -307,7 +307,7 @@ cleanup: Send/receive the request encryption blob. ******************************************************************************/ -static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out) +static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out, DATA_BLOB *param_out) { uint16 setup; char param[4]; @@ -345,6 +345,7 @@ static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA } *out = data_blob(rdata, rdata_count); + *param_out = data_blob(rparam, rparam_count); out: @@ -364,6 +365,7 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, { DATA_BLOB blob_in = data_blob(NULL, 0); DATA_BLOB blob_out = data_blob(NULL, 0); + DATA_BLOB param_out = data_blob(NULL, 0); NTSTATUS status = NT_STATUS_UNSUCCESSFUL; struct smb_trans_enc_state *es = NULL; @@ -394,8 +396,12 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, do { status = ntlmssp_update(es->s.ntlmssp_state, blob_in, &blob_out); data_blob_free(&blob_in); + data_blob_free(¶m_out); if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) { - status = enc_blob_send_receive(cli, &blob_out, &blob_in); + status = enc_blob_send_receive(cli, &blob_out, &blob_in, ¶m_out); + } + if (param_out.length == 2) { + es->enc_ctx_num = SVAL(param_out.data, 0); } data_blob_free(&blob_out); } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index f0e79b404c..c80b7f0a90 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -20,6 +20,27 @@ #include "includes.h" +/****************************************************************************** + Pull out the encryption context for this packet. 0 means global context. +******************************************************************************/ + +NTSTATUS get_enc_ctx_num(char *buf, uint16 *p_enc_ctx_num) +{ + if (smb_len(buf) < 8) { + return NT_STATUS_INVALID_BUFFER_SIZE; + } + + if (buf[4] == (char)0xFF && buf[5] == 'S') { + if (buf [6] == 'M' && buf[7] == 'B') { + /* Not an encrypted buffer. */ + return NT_STATUS_NOT_FOUND; + } + *p_enc_ctx_num = SVAL(buf,6); + return NT_STATUS_OK; + } + return NT_STATUS_INVALID_NETWORK_RESPONSE; +} + /****************************************************************************** Generic code for client and server. Is encryption turned on ? @@ -52,7 +73,7 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE); status = ntlmssp_unseal_packet(ntlmssp_state, - (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ + (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' */ buf_len - 8, (unsigned char *)buf + 8, buf_len - 8, @@ -73,7 +94,10 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. ******************************************************************************/ -NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, char **ppbuf_out) +NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, + uint16 enc_ctx_num, + char *buf, + char **ppbuf_out) { NTSTATUS status; char *buf_out; @@ -97,12 +121,12 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha memcpy(buf_out, buf, buf_len); /* Last 16 bytes undefined here... */ - smb_setlen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE); + smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); sig = data_blob(NULL, NTLMSSP_SIG_SIZE); status = ntlmssp_seal_packet(ntlmssp_state, - (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' 'M' 'B' */ + (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' */ buf_len - 8, (unsigned char *)buf_out + 8, buf_len - 8, @@ -126,7 +150,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) +NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) { gss_ctx_id_t gss_ctx = gss_state->gss_ctx; OM_uint32 ret = 0; @@ -179,7 +203,10 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf, char **ppbuf_out) +NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, + uint16 enc_ctx_num, + char *buf, + char **ppbuf_out) { gss_ctx_id_t gss_ctx = gss_state->gss_ctx; OM_uint32 ret = 0; @@ -238,7 +265,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha } memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); - smb_setlen(*ppbuf_out, out_buf.length + 4); + smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; @@ -258,18 +285,12 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha return NT_STATUS_OK; } - /* Ignore session keepalives. */ - if(CVAL(buffer,0) == SMBkeepalive) { - *buf_out = buffer; - return NT_STATUS_OK; - } - switch (es->smb_enc_type) { case SMB_TRANS_ENC_NTLM: - return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, buffer, buf_out); + return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, es->enc_ctx_num, buffer, buf_out); #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) case SMB_TRANS_ENC_GSS: - return common_gss_encrypt_buffer(es->s.gss_state, buffer, buf_out); + return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out); #endif default: return NT_STATUS_NOT_SUPPORTED; @@ -289,11 +310,6 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) return NT_STATUS_OK; } - /* Ignore session keepalives. */ - if(CVAL(buf,0) == SMBkeepalive) { - return NT_STATUS_OK; - } - switch (es->smb_enc_type) { case SMB_TRANS_ENC_NTLM: return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); @@ -361,21 +377,19 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) return; } - /* We know this is an smb buffer, and we - * didn't malloc, only copy, for a keepalive, - * so ignore session keepalives. */ - - if(CVAL(buf,0) == SMBkeepalive) { - return; - } - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { SAFE_FREE(buf); return; } #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - /* gss-api free buffer.... */ + if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { + OM_uint32 min; + gss_buffer_desc rel_buf; + rel_buf.value = buf; + rel_buf.length = smb_len(buf) + 4; + gss_release_buffer(&min, &rel_buf); + } #endif } @@ -389,6 +403,9 @@ void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) BOOL cli_encryption_on(struct cli_state *cli) { + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ return common_encryption_on(cli->trans_enc_state); } @@ -407,6 +424,17 @@ void cli_free_encryption_context(struct cli_state *cli) void cli_free_enc_buffer(struct cli_state *cli, char *buf) { + /* We know this is an smb buffer, and we + * didn't malloc, only copy, for a keepalive, + * so ignore session keepalives. */ + + if(CVAL(buf,0) == SMBkeepalive) { + return; + } + + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ common_free_enc_buffer(cli->trans_enc_state, buf); } @@ -416,6 +444,23 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf) NTSTATUS cli_decrypt_message(struct cli_state *cli) { + NTSTATUS status; + uint16 enc_ctx_num; + + /* Ignore session keepalives. */ + if(CVAL(cli->inbuf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + + status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { + return NT_STATUS_INVALID_HANDLE; + } + return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); } @@ -425,5 +470,13 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { + /* Ignore session keepalives. */ + if(CVAL(cli->inbuf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); } -- cgit From 0eab4311946c312795ec5c03c25a340ef0bfc624 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 21:55:43 +0000 Subject: r21992: Fix keepalive processing when encryption turned on. Jeremy. (This used to be commit 8f113ad1918dcd2746ec527ceb79a2a7baa1d415) --- source3/libsmb/clientgen.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index fc88f7f1e2..b3c38f39ae 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -48,13 +48,13 @@ int cli_set_port(struct cli_state *cli, int port) *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. The timeout is in milliseconds - This is exactly the same as receive_smb except that it never returns + This is exactly the same as receive_smb except that it can be set to never return a session keepalive packet (just as receive_smb used to do). receive_smb was changed to return keepalives as the oplock processing means this call should never go into a blocking read. ****************************************************************************/ -static BOOL client_receive_smb(struct cli_state *cli) +static BOOL client_receive_smb(struct cli_state *cli, BOOL eat_keepalives) { BOOL ret; int fd = cli->fd; @@ -71,8 +71,10 @@ static BOOL client_receive_smb(struct cli_state *cli) } /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) - break; + if (eat_keepalives && (CVAL(buffer,0) == SMBkeepalive)) { + continue; + } + break; } if (cli_encryption_on(cli)) { @@ -94,7 +96,7 @@ static BOOL client_receive_smb(struct cli_state *cli) Recv an smb. ****************************************************************************/ -BOOL cli_receive_smb(struct cli_state *cli) +BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) { BOOL ret; @@ -103,7 +105,7 @@ BOOL cli_receive_smb(struct cli_state *cli) return False; again: - ret = client_receive_smb(cli); + ret = client_receive_smb(cli, eat_keepalives); if (ret) { /* it might be an oplock break request */ @@ -142,6 +144,24 @@ BOOL cli_receive_smb(struct cli_state *cli) return True; } +/**************************************************************************** + Recv an smb - eat keepalives. +****************************************************************************/ + +BOOL cli_receive_smb(struct cli_state *cli) +{ + return cli_receive_smb_internal(cli, True); +} + +/**************************************************************************** + Recv an smb - return keepalives. +****************************************************************************/ + +BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) +{ + return cli_receive_smb_internal(cli, False); +} + static ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; -- cgit From 208367f4d1869843d024a06313a965455b9ee3be Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 22:27:06 +0000 Subject: r21993: Don't let keepalives interferece with sign or seal in the client code. Jeremy. (This used to be commit 3e901389feedadd64c6ba712ab09cdfb497a9e0a) --- source3/libsmb/clientgen.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b3c38f39ae..95d7cdadd7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -106,6 +106,11 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) again: ret = client_receive_smb(cli, eat_keepalives); + + if (!eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { + /* Give back the keepalive. */ + return True; + } if (ret) { /* it might be an oplock break request */ -- cgit From 3215c09a8147e7df111e4e0817091285cd7240cb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2007 22:37:42 +0000 Subject: r21994: Ignore keepalives in the correct buffer (out not in :-). Jeremy. (This used to be commit 9785528ddf26c4943e8bdfcf7694314a52218520) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/smb_seal.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 95d7cdadd7..e4712d2f65 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -107,7 +107,7 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) again: ret = client_receive_smb(cli, eat_keepalives); - if (!eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { + if (ret && !eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { /* Give back the keepalive. */ return True; } diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index c80b7f0a90..ed2c66013e 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -471,7 +471,7 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { /* Ignore session keepalives. */ - if(CVAL(cli->inbuf,0) == SMBkeepalive) { + if(CVAL(cli->outbuf,0) == SMBkeepalive) { return NT_STATUS_OK; } -- cgit From e9157961d6c89318de4c7ff5a700aed640d91d92 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Mar 2007 01:11:27 +0000 Subject: r21997: Implement the server side of gss seal negotiate. Jeremy. (This used to be commit 6b923acfee59e39eea69e9e9a00f1f6118ed4270) --- source3/libsmb/smb_seal.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index ed2c66013e..891673ed15 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -332,8 +332,12 @@ static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state) OM_uint32 minor = 0; struct smb_tran_enc_state_gss *gss_state = *pp_gss_state; - gss_release_cred(&minor, &gss_state->creds); - gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); + if (gss_state->creds != GSS_C_NO_CREDENTIAL) { + gss_release_cred(&minor, &gss_state->creds); + } + if (gss_state->gss_ctx != GSS_C_NO_CONTEXT) { + gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); + } SAFE_FREE(*pp_gss_state); } #endif -- cgit From cece5a62ae564a8f7f4eeb0e2376e04ff041bdd9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 28 Mar 2007 10:00:42 +0000 Subject: r21998: Fix tdb keynames in netsamlogon_clear_cached_user(). No point in deleting U/DOMAIN/RID and UG/DOMAIN/RID keys if we only store U/SID and UG/SID keys :-) Next we need to verify the need of calling netsamlogon_clear_cached_user() at all. Guenther (This used to be commit 78d13f14672b65c2d4798ce94322e945334eea62) --- source3/libsmb/samlogon_cache.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 270ad27deb..e82ee8dbb8 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -59,9 +59,10 @@ BOOL netsamlogon_cache_shutdown(void) ***********************************************************************/ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) { - fstring domain; TDB_DATA key; BOOL got_tdb = False; + DOM_SID sid; + fstring key_str, sid_string; /* We may need to call this function from smbd which will not have winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ @@ -77,29 +78,24 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) got_tdb = True; } - unistr2_to_ascii(domain, &user->uni_logon_dom, sizeof(domain) - 1); + sid_copy(&sid, &user->dom_sid.sid); + sid_append_rid(&sid, user->user_rid); - /* Clear U/DOMAIN/RID cache entry */ + /* Clear U/SID cache entry */ - asprintf(&key.dptr, "U/%s/%d", domain, user->user_rid); - key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */ + fstr_sprintf(key_str, "U/%s", sid_to_string(sid_string, &sid)); - DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); - - tdb_delete(tdb, key); + DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str)); - SAFE_FREE(key.dptr); + tdb_delete(tdb, string_tdb_data(key_str)); - /* Clear UG/DOMAIN/RID cache entry */ + /* Clear UG/SID cache entry */ - asprintf(&key.dptr, "UG/%s/%d", domain, user->user_rid); - key.dsize = strlen(key.dptr) - 1; /* keys are not NULL terminated */ + fstr_sprintf(key_str, "UG/%s", sid_to_string(sid_string, &sid)); DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); - tdb_delete(tdb, key); - - SAFE_FREE(key.dptr); + tdb_delete(tdb, string_tdb_data(key_str)); if (got_tdb) tdb_close(tdb); -- cgit From 56ba44766854ed7cda265bdaf85913f2a1008282 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 28 Mar 2007 13:34:59 +0000 Subject: r22001: change prototype of dump_data(), so that it takes unsigned char * now, which matches what samba4 has. also fix all the callers to prevent compiler warnings metze (This used to be commit fa322f0cc9c26a9537ba3f0a7d4e4a25941317e7) --- source3/libsmb/clirap.c | 2 +- source3/libsmb/ntlm_check.c | 18 ++++++++-------- source3/libsmb/ntlmssp.c | 12 +++++------ source3/libsmb/ntlmssp_sign.c | 8 +++---- source3/libsmb/smb_signing.c | 20 ++++++++--------- source3/libsmb/smbencrypt.c | 50 +++++++++++++++++++++---------------------- 6 files changed, 55 insertions(+), 55 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 05dc36e91c..4be03e16f0 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -334,7 +334,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char #ifdef DEBUG_PASSWORD DEBUG(100,("make_oem_passwd_hash\n")); - dump_data(100, (char *)data, 516); + dump_data(100, data, 516); #endif SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index e1fc92e344..1ce5d5e424 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -65,13 +65,13 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, #ifdef DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, (const char *)part_passwd, 16); + dump_data(100, part_passwd, 16); DEBUGADD(100,("Password from client was |\n")); - dump_data(100, (const char *)nt_response->data, nt_response->length); + dump_data(100, nt_response->data, nt_response->length); DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, (const char *)sec_blob->data, sec_blob->length); + dump_data(100, sec_blob->data, sec_blob->length); DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, (const char *)p24, 24); + dump_data(100, p24, 24); #endif return (memcmp(p24, nt_response->data, 24) == 0); } @@ -136,15 +136,15 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, #if DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |\n")); - dump_data(100, (const char *)part_passwd, 16); + dump_data(100, part_passwd, 16); DEBUGADD(100,("Password from client was |\n")); - dump_data(100, (const char *)ntv2_response->data, ntv2_response->length); + dump_data(100, ntv2_response->data, ntv2_response->length); DEBUGADD(100,("Variable data from client was |\n")); - dump_data(100, (const char *)client_key_data.data, client_key_data.length); + dump_data(100, client_key_data.data, client_key_data.length); DEBUGADD(100,("Given challenge was |\n")); - dump_data(100, (const char *)sec_blob->data, sec_blob->length); + dump_data(100, sec_blob->data, sec_blob->length); DEBUGADD(100,("Value from encryption was |\n")); - dump_data(100, (const char *)value_from_encryption, 16); + dump_data(100, value_from_encryption, 16); #endif data_blob_clear_free(&client_key_data); res = (memcmp(value_from_encryption, client_response, 16) == 0); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 2f919b3f76..2bc2183add 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -325,7 +325,7 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, "NTLMSSP", &ntlmssp_command)) { DEBUG(1, ("Failed to parse NTLMSSP packet, could not extract NTLMSSP command\n")); - dump_data(2, (const char *)input.data, input.length); + dump_data(2, input.data, input.length); return NT_STATUS_INVALID_PARAMETER; } } @@ -531,7 +531,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, &neg_flags)) { DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n", (unsigned int)request.length)); - dump_data(2, (const char *)request.data, request.length); + dump_data(2, request.data, request.length); return NT_STATUS_INVALID_PARAMETER; } debug_ntlmssp_flags(neg_flags); @@ -695,7 +695,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, &user, &workstation)) { DEBUG(1, ("ntlmssp_server_auth: failed to parse NTLMSSP (tried both formats):\n")); - dump_data(2, (const char *)request.data, request.length); + dump_data(2, request.data, request.length); SAFE_FREE(domain); SAFE_FREE(user); SAFE_FREE(workstation); @@ -1008,7 +1008,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, &server_domain_blob, &chal_flags)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#1)\n")); - dump_data(2, (const char *)reply.data, reply.length); + dump_data(2, reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } @@ -1049,7 +1049,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, &unkn1, &unkn2, &struct_blob)) { DEBUG(1, ("Failed to parse the NTLMSSP Challenge: (#2)\n")); - dump_data(2, (const char *)reply.data, reply.length); + dump_data(2, reply.data, reply.length); return NT_STATUS_INVALID_PARAMETER; } @@ -1111,7 +1111,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, DEBUG(5, ("NTLMSSP challenge set by NTLM2\n")); DEBUG(5, ("challenge is: \n")); - dump_data(5, (const char *)session_nonce_hash, 8); + dump_data(5, session_nonce_hash, 8); nt_response = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 24); SMBNTencrypt_hash(ntlmssp_state->nt_hash, diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 5642be42a3..a30535e2de 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -196,10 +196,10 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, if (local_sig.length != sig->length || memcmp(local_sig.data, sig->data, sig->length) != 0) { DEBUG(5, ("BAD SIG NTLM2: wanted signature of\n")); - dump_data(5, (const char *)local_sig.data, local_sig.length); + dump_data(5, local_sig.data, local_sig.length); DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, (const char *)sig->data, sig->length); + dump_data(5, sig->data, sig->length); DEBUG(0, ("NTLMSSP NTLM2 packet check failed due to invalid signature!\n")); data_blob_free(&local_sig); @@ -209,10 +209,10 @@ NTSTATUS ntlmssp_check_packet(NTLMSSP_STATE *ntlmssp_state, if (local_sig.length != sig->length || memcmp(local_sig.data + 8, sig->data + 8, sig->length - 8) != 0) { DEBUG(5, ("BAD SIG NTLM1: wanted signature of\n")); - dump_data(5, (const char *)local_sig.data, local_sig.length); + dump_data(5, local_sig.data, local_sig.length); DEBUG(5, ("BAD SIG: got signature of\n")); - dump_data(5, (const char *)sig->data, sig->length); + dump_data(5, sig->data, sig->length); DEBUG(0, ("NTLMSSP NTLM1 packet check failed due to invalid signature!\n")); data_blob_free(&local_sig); diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 0395208986..d3384ce365 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -347,7 +347,7 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) data->send_seq_num, calc_md5_mac); DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); - dump_data(10, (const char *)calc_md5_mac, 8); + dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -408,10 +408,10 @@ static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, if (!good) { DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); - dump_data(5, (const char *)calc_md5_mac, 8); + dump_data(5, calc_md5_mac, 8); DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); - dump_data(5, (const char *)server_sent_mac, 8); + dump_data(5, server_sent_mac, 8); #if 1 /* JRATEST */ { int i; @@ -428,7 +428,7 @@ We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); } else { DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(10, (const char *)server_sent_mac, 8); + dump_data(10, server_sent_mac, 8); } return signing_good(inbuf, si, good, reply_seq_number, must_be_ok); } @@ -488,12 +488,12 @@ BOOL cli_simple_set_signing(struct cli_state *cli, memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, (const char *)user_session_key.data, user_session_key.length); + dump_data(10, user_session_key.data, user_session_key.length); if (response.length) { memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); DEBUG(10, ("cli_simple_set_signing: response_data\n")); - dump_data(10, (const char *)response.data, response.length); + dump_data(10, response.data, response.length); } else { DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); } @@ -691,7 +691,7 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); - dump_data(10, (const char *)calc_md5_mac, 8); + dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); @@ -735,11 +735,11 @@ static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BO if (saved_seq) { DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", (unsigned int)saved_seq)); - dump_data(5, (const char *)calc_md5_mac, 8); + dump_data(5, calc_md5_mac, 8); DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(5, (const char *)server_sent_mac, 8); + dump_data(5, server_sent_mac, 8); } #if 1 /* JRATEST */ @@ -759,7 +759,7 @@ We were expecting seq %u\n", reply_seq_number, saved_seq )); } else { DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); - dump_data(10, (const char *)server_sent_mac, 8); + dump_data(10, server_sent_mac, 8); } return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 5f7b5b1809..ad833374f3 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -36,9 +36,9 @@ void SMBencrypt_hash(const uchar lm_hash[16], const uchar *c8, uchar p24[24]) #ifdef DEBUG_PASSWORD DEBUG(100,("SMBencrypt_hash: lm#, challenge, response\n")); - dump_data(100, (const char *)p21, 16); - dump_data(100, (const char *)c8, 8); - dump_data(100, (const char *)p24, 24); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); #endif } @@ -146,16 +146,16 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n")); - dump_data(120, pwd, strlen(pwd)); - dump_data(100, (char *)nt_p16, 16); + dump_data(120, (uint8 *)pwd, strlen(pwd)); + dump_data(100, nt_p16, 16); #endif E_deshash(pwd, (uchar *)p16); #ifdef DEBUG_PASSWORD DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n")); - dump_data(120, pwd, strlen(pwd)); - dump_data(100, (char *)p16, 16); + dump_data(120, (uint8 *)pwd, strlen(pwd)); + dump_data(100, p16, 16); #endif } @@ -204,10 +204,10 @@ BOOL ntv2_owf_gen(const uchar owf[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("ntv2_owf_gen: user, domain, owfkey, kr\n")); - dump_data(100, (const char *)user, user_byte_len); - dump_data(100, (const char *)domain, domain_byte_len); - dump_data(100, (const char *)owf, 16); - dump_data(100, (const char *)kr_buf, 16); + dump_data(100, (uint8 *)user, user_byte_len); + dump_data(100, (uint8 *)domain, domain_byte_len); + dump_data(100, (uint8 *)owf, 16); + dump_data(100, (uint8 *)kr_buf, 16); #endif SAFE_FREE(user); @@ -238,9 +238,9 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p E_P24(p21, ntlmchalresp, p24); #ifdef DEBUG_PASSWORD DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n")); - dump_data(100, (char *)p21, 21); - dump_data(100, (const char *)ntlmchalresp, 8); - dump_data(100, (char *)p24, 24); + dump_data(100, p21, 21); + dump_data(100, ntlmchalresp, 8); + dump_data(100, p24, 24); #endif } @@ -257,9 +257,9 @@ void SMBNTencrypt_hash(const uchar nt_hash[16], uchar *c8, uchar *p24) #ifdef DEBUG_PASSWORD DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n")); - dump_data(100, (char *)p21, 16); - dump_data(100, (char *)c8, 8); - dump_data(100, (char *)p24, 24); + dump_data(100, p21, 16); + dump_data(100, c8, 8); + dump_data(100, p24, 24); #endif } @@ -287,9 +287,9 @@ void SMBOWFencrypt_ntv2(const uchar kr[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n")); - dump_data(100, (const char *)srv_chal->data, srv_chal->length); - dump_data(100, (const char *)cli_chal->data, cli_chal->length); - dump_data(100, (const char *)resp_buf, 16); + dump_data(100, srv_chal->data, srv_chal->length); + dump_data(100, cli_chal->data, cli_chal->length); + dump_data(100, resp_buf, 16); #endif } @@ -306,7 +306,7 @@ void SMBsesskeygen_ntv2(const uchar kr[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_ntv2:\n")); - dump_data(100, (const char *)sess_key, 16); + dump_data(100, sess_key, 16); #endif } @@ -320,7 +320,7 @@ void SMBsesskeygen_ntv1(const uchar kr[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_ntv1:\n")); - dump_data(100, (const char *)sess_key, 16); + dump_data(100, sess_key, 16); #endif } @@ -340,7 +340,7 @@ void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], #ifdef DEBUG_PASSWORD DEBUG(100, ("SMBsesskeygen_lmv1_jerry:\n")); - dump_data(100, (const char *)sess_key, 16); + dump_data(100, sess_key, 16); #endif } @@ -544,7 +544,7 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, byte_len = IVAL(in_buffer, 512); #ifdef DEBUG_PASSWORD - dump_data(100, (const char *)in_buffer, 516); + dump_data(100, in_buffer, 516); #endif /* Password cannot be longer than the size of the password buffer */ @@ -560,7 +560,7 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (const char *)new_pwrd, *new_pw_len); + dump_data(100, (uint8 *)new_pwrd, *new_pw_len); DEBUG(100,("multibyte len:%d\n", *new_pw_len)); DEBUG(100,("original char len:%d\n", byte_len/2)); #endif -- cgit From 71b8fdff85559213f5b880946cc918777c2389cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Mar 2007 19:47:59 +0000 Subject: r22003: Fix from Jiri.Sasek@Sun.COM to wrap our krb5_locate_kdc call as smb_krb5_locate_kdc to prevent incorrect linking and crashes on Solaris. Jeremy. (This used to be commit 7d30737c8d851505e81a60443baf9a8c7e523472) --- source3/libsmb/clikrb5.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index fa93bed63d..7043a26408 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -393,7 +393,7 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ #if defined(KRB5_KRBHST_INIT) /* Heimdal */ - krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) + krb5_error_code smb_krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) { krb5_krbhst_handle hnd; krb5_krbhst_info *hinfo; @@ -407,7 +407,7 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ rc = krb5_krbhst_init(ctx, realm->data, KRB5_KRBHST_KDC, &hnd); if (rc) { - DEBUG(0, ("krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); + DEBUG(0, ("smb_krb5_locate_kdc: krb5_krbhst_init failed (%s)\n", error_message(rc))); return rc; } @@ -417,14 +417,14 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ krb5_krbhst_reset(ctx, hnd); if (!num_kdcs) { - DEBUG(0, ("krb5_locate_kdc: zero kdcs found !\n")); + DEBUG(0, ("smb_krb5_locate_kdc: zero kdcs found !\n")); krb5_krbhst_free(ctx, hnd); return -1; } sa = SMB_MALLOC_ARRAY( struct sockaddr, num_kdcs ); if (!sa) { - DEBUG(0, ("krb5_locate_kdc: malloc failed\n")); + DEBUG(0, ("smb_krb5_locate_kdc: malloc failed\n")); krb5_krbhst_free(ctx, hnd); naddrs = 0; return -1; @@ -454,7 +454,7 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ #else /* ! defined(KRB5_KRBHST_INIT) */ - krb5_error_code krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, + krb5_error_code smb_krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, struct sockaddr **addr_pp, int *naddrs, int get_masters) { DEBUG(0, ("unable to explicitly locate the KDC on this platform\n")); @@ -463,6 +463,14 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ #endif /* KRB5_KRBHST_INIT */ +#else /* ! HAVE_KRB5_LOCATE_KDC */ + + krb5_error_code smb_krb5_locate_kdc(krb5_context ctx, const krb5_data *realm, + struct sockaddr **addr_pp, int *naddrs, int get_masters) +{ + return krb5_locate_kdc(ctx, realm, addr_pp, naddrs, get_masters); +} + #endif /* HAVE_KRB5_LOCATE_KDC */ #if !defined(HAVE_KRB5_FREE_UNPARSED_NAME) -- cgit From bc2b6436d0f5f3e9ffdfaeb7f1b32996a83d5478 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 29 Mar 2007 09:35:51 +0000 Subject: r22009: change TDB_DATA from char * to unsigned char * and fix all compiler warnings in the users metze (This used to be commit 3a28443079c141a6ce8182c65b56ca210e34f37f) --- source3/libsmb/samlogon_cache.c | 4 ++-- source3/libsmb/smb_share_modes.c | 14 +++++++------- source3/libsmb/unexpected.c | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index e82ee8dbb8..61dddb62fd 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -156,7 +156,7 @@ BOOL netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) if ( net_io_user_info3("", user, &ps, 0, 3, 0) ) { data.dsize = prs_offset( &ps ); - data.dptr = prs_data_p( &ps ); + data.dptr = (uint8 *)prs_data_p( &ps ); if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) result = True; @@ -198,7 +198,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user return NULL; prs_init( &ps, 0, mem_ctx, UNMARSHALL ); - prs_give_memory( &ps, data.dptr, data.dsize, True ); + prs_give_memory( &ps, (char *)data.dptr, data.dsize, True ); if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) { prs_mem_free( &ps ); diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 4c49ecb7bd..e98de5e264 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -96,7 +96,7 @@ static TDB_DATA get_locking_key(uint64_t dev, uint64_t ino) memset(&lk, '\0', sizeof(struct locking_key)); lk.dev = (SMB_DEV_T)dev; lk.inode = (SMB_INO_T)ino; - ld.dptr = (char *)&lk; + ld.dptr = (uint8 *)&lk; ld.dsize = sizeof(lk); return ld; } @@ -258,13 +258,13 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, int orig_num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ struct share_mode_entry *shares = NULL; - char *new_data_p = NULL; + uint8 *new_data_p = NULL; size_t new_data_size = 0; db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { /* We must create the entry. */ - db_data.dptr = (char *)malloc( + db_data.dptr = (uint8 *)malloc( (2*sizeof(struct share_mode_entry)) + strlen(sharepath) + 1 + strlen(filename) + 1); @@ -299,7 +299,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, } /* Entry exists, we must add a new entry. */ - new_data_p = (char *)malloc( + new_data_p = (uint8 *)malloc( db_data.dsize + sizeof(struct share_mode_entry)); if (!new_data_p) { free(db_data.dptr); @@ -370,10 +370,10 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, int orig_num_share_modes = 0; struct locking_data *ld = NULL; /* internal samba db state. */ struct share_mode_entry *shares = NULL; - char *new_data_p = NULL; + uint8 *new_data_p = NULL; size_t remaining_size = 0; size_t i, num_share_modes; - const char *remaining_ptr = NULL; + const uint8 *remaining_ptr = NULL; db_data = tdb_fetch(db_ctx->smb_tdb, locking_key); if (!db_data.dptr) { @@ -397,7 +397,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* More than one - allocate a new record minus the one we'll delete. */ - new_data_p = (char *)malloc( + new_data_p = (uint8 *)malloc( db_data.dsize - sizeof(struct share_mode_entry)); if (!new_data_p) { free(db_data.dptr); diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 97d6071e71..5aee16e4c6 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -63,9 +63,9 @@ void unexpected_packet(struct packet_struct *p) key.timestamp = p->timestamp; key.count = count++; - kbuf.dptr = (char *)&key; + kbuf.dptr = (uint8_t *)&key; kbuf.dsize = sizeof(key); - dbuf.dptr = buf; + dbuf.dptr = (uint8_t *)buf; dbuf.dsize = len; tdb_store(tdbd, kbuf, dbuf, TDB_REPLACE); @@ -124,7 +124,7 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void if (key.packet_type != match_type) return 0; - p = parse_packet(dbuf.dptr, dbuf.dsize, match_type); + p = parse_packet((char *)dbuf.dptr, dbuf.dsize, match_type); if ((match_type == NMB_PACKET && p->packet.nmb.header.name_trn_id == match_id) || -- cgit From 1ff60ed7bc75991449900670bc3e6b5b91c9003d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Mar 2007 22:12:28 +0000 Subject: r22012: Ensure we use the same technique to pull the share mode data out that locking/locking.c does. Jeremy. (This used to be commit 1fec4da6d6267289bf93f930de4cb5e21c450e15) --- source3/libsmb/smb_share_modes.c | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index e98de5e264..f78eaf8ca5 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -200,7 +200,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, memset(list, '\0', num_share_modes * sizeof(struct smb_share_mode_entry)); - shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); + shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); list_num = 0; for (i = 0; i < num_share_modes; i++) { @@ -265,7 +265,8 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, if (!db_data.dptr) { /* We must create the entry. */ db_data.dptr = (uint8 *)malloc( - (2*sizeof(struct share_mode_entry)) + + sizeof(struct locking_data) + + sizeof(struct share_mode_entry) + strlen(sharepath) + 1 + strlen(filename) + 1); if (!db_data.dptr) { @@ -276,18 +277,18 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, ld->u.s.num_share_mode_entries = 1; ld->u.s.delete_on_close = 0; ld->u.s.delete_token_size = 0; - shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); + shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); create_share_mode_entry(shares, new_entry); - memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry), + memcpy(db_data.dptr + sizeof(struct locking_data) + sizeof(struct share_mode_entry), sharepath, strlen(sharepath) + 1); - memcpy(db_data.dptr + 2*sizeof(struct share_mode_entry) + + memcpy(db_data.dptr + sizeof(struct locking_data) + sizeof(struct share_mode_entry) + strlen(sharepath) + 1, filename, strlen(filename) + 1); - db_data.dsize = 2*sizeof(struct share_mode_entry) + + db_data.dsize = sizeof(struct locking_data) + sizeof(struct share_mode_entry) + strlen(sharepath) + 1 + strlen(filename) + 1; if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_INSERT) == -1) { @@ -310,11 +311,11 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, orig_num_share_modes = ld->u.s.num_share_mode_entries; /* Copy the original data. */ - memcpy(new_data_p, db_data.dptr, (orig_num_share_modes+1)*sizeof(struct share_mode_entry)); + memcpy(new_data_p, db_data.dptr, sizeof(struct locking_data) + (orig_num_share_modes * sizeof(struct share_mode_entry))); /* Add in the new share mode */ - shares = (struct share_mode_entry *)(new_data_p + - ((orig_num_share_modes+1)*sizeof(struct share_mode_entry))); + shares = (struct share_mode_entry *)(new_data_p + sizeof(struct locking_data) + + (orig_num_share_modes * sizeof(struct share_mode_entry))); create_share_mode_entry(shares, new_entry); @@ -322,9 +323,9 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, ld->u.s.num_share_mode_entries++; /* Append the original delete_token and filenames. */ - memcpy(new_data_p + ((ld->u.s.num_share_mode_entries+1)*sizeof(struct share_mode_entry)), - db_data.dptr + ((orig_num_share_modes+1)*sizeof(struct share_mode_entry)), - db_data.dsize - ((orig_num_share_modes+1) * sizeof(struct share_mode_entry))); + memcpy(new_data_p + sizeof(struct locking_data) + (ld->u.s.num_share_mode_entries * sizeof(struct share_mode_entry)), + db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes * sizeof(struct share_mode_entry)), + db_data.dsize - sizeof(struct locking_data) - (orig_num_share_modes * sizeof(struct share_mode_entry))); new_data_size = db_data.dsize + sizeof(struct share_mode_entry); @@ -382,7 +383,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; orig_num_share_modes = ld->u.s.num_share_mode_entries; - shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); + shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); if (orig_num_share_modes == 1) { /* Only one entry - better be ours... */ @@ -405,7 +406,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* Copy the header. */ - memcpy(new_data_p, db_data.dptr, sizeof(struct share_mode_entry)); + memcpy(new_data_p, db_data.dptr, sizeof(struct locking_data)); num_share_modes = 0; for (i = 0; i < orig_num_share_modes; i++) { @@ -421,7 +422,8 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, continue; /* This is our delete taget. */ } - memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)), + memcpy(new_data_p + sizeof(struct locking_data) + + (num_share_modes * sizeof(struct share_mode_entry)), share, sizeof(struct share_mode_entry) ); num_share_modes++; @@ -435,10 +437,10 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, } /* Copy any delete token plus the terminating filenames. */ - remaining_ptr = db_data.dptr + ((orig_num_share_modes+1) * sizeof(struct share_mode_entry)); + remaining_ptr = db_data.dptr + sizeof(struct locking_data) + (orig_num_share_modes * sizeof(struct share_mode_entry)); remaining_size = db_data.dsize - (remaining_ptr - db_data.dptr); - memcpy(new_data_p + ((num_share_modes+1)*sizeof(struct share_mode_entry)), + memcpy(new_data_p + sizeof(struct locking_data) + (num_share_modes * sizeof(struct share_mode_entry)), remaining_ptr, remaining_size); @@ -450,7 +452,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; ld->u.s.num_share_mode_entries = num_share_modes; - db_data.dsize = ((num_share_modes+1)*sizeof(struct share_mode_entry)) + remaining_size; + db_data.dsize = sizeof(struct locking_data) + (num_share_modes * sizeof(struct share_mode_entry)) + remaining_size; if (tdb_store(db_ctx->smb_tdb, locking_key, db_data, TDB_REPLACE) == -1) { free(db_data.dptr); @@ -481,7 +483,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, ld = (struct locking_data *)db_data.dptr; num_share_modes = ld->u.s.num_share_mode_entries; - shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct share_mode_entry)); + shares = (struct share_mode_entry *)(db_data.dptr + sizeof(struct locking_data)); for (i = 0; i < num_share_modes; i++) { struct share_mode_entry *share = &shares[i]; -- cgit From b0bcb483697249123f92f5ac477c98b579135887 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Mar 2007 22:19:51 +0000 Subject: r22013: Move to SSPI framing (sig first in NTLM). Jeremy (This used to be commit 22eaed76f01ea9d0184dcaf57adca23abc6330b9) --- source3/libsmb/smb_seal.c | 64 ++++++++++++++++++++++++++++------------------- 1 file changed, 38 insertions(+), 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 891673ed15..fac451a6c5 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -30,13 +30,15 @@ NTSTATUS get_enc_ctx_num(char *buf, uint16 *p_enc_ctx_num) return NT_STATUS_INVALID_BUFFER_SIZE; } - if (buf[4] == (char)0xFF && buf[5] == 'S') { - if (buf [6] == 'M' && buf[7] == 'B') { + if (buf[4] == (char)0xFF) { + if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') { /* Not an encrypted buffer. */ return NT_STATUS_NOT_FOUND; } - *p_enc_ctx_num = SVAL(buf,6); - return NT_STATUS_OK; + if (buf[5] == 'E') { + *p_enc_ctx_num = SVAL(buf,6); + return NT_STATUS_OK; + } } return NT_STATUS_INVALID_NETWORK_RESPONSE; } @@ -54,44 +56,55 @@ BOOL common_encryption_on(struct smb_trans_enc_state *es) /****************************************************************************** Generic code for client and server. NTLM decrypt an incoming buffer. + Abartlett tells me that SSPI puts the signature first before the encrypted + output, so cope with the same for compatibility. ******************************************************************************/ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) { NTSTATUS status; size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + size_t data_len; + char *inbuf; DATA_BLOB sig; if (buf_len < 8 + NTLMSSP_SIG_SIZE) { return NT_STATUS_BUFFER_TOO_SMALL; } + inbuf = smb_xmemdup(buf, buf_len); + /* Adjust for the signature. */ - buf_len -= NTLMSSP_SIG_SIZE; + data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; - /* Save off the signature. */ - sig = data_blob(buf+buf_len, NTLMSSP_SIG_SIZE); + /* Point at the signature. */ + sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE); status = ntlmssp_unseal_packet(ntlmssp_state, - (unsigned char *)buf + 8, /* 4 byte len + 0xFF 'S' */ - buf_len - 8, - (unsigned char *)buf + 8, - buf_len - 8, + (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' */ + data_len, + (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, + data_len, &sig); if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&sig); + SAFE_FREE(inbuf); return status; } + memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); + SAFE_FREE(inbuf); + /* Reset the length. */ - smb_setlen(buf, smb_len(buf) - NTLMSSP_SIG_SIZE); + smb_setlen(buf, data_len + 4); return NT_STATUS_OK; } /****************************************************************************** Generic code for client and server. NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. + Abartlett tells me that SSPI puts the signature first before the encrypted + output, so do the same for compatibility. ******************************************************************************/ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, @@ -101,12 +114,12 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, { NTSTATUS status; char *buf_out; - size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */ DATA_BLOB sig; *ppbuf_out = NULL; - if (buf_len < 8) { + if (data_len == 0) { return NT_STATUS_BUFFER_TOO_SMALL; } @@ -115,21 +128,21 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, * check needed. */ - /* Copy the original buffer. */ + buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len); + + /* Copy the data from the original buffer. */ - buf_out = SMB_XMALLOC_ARRAY(char, buf_len + NTLMSSP_SIG_SIZE); - memcpy(buf_out, buf, buf_len); - /* Last 16 bytes undefined here... */ + memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len); smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); sig = data_blob(NULL, NTLMSSP_SIG_SIZE); status = ntlmssp_seal_packet(ntlmssp_state, - (unsigned char *)buf_out + 8, /* 4 byte len + 0xFF 'S' */ - buf_len - 8, - (unsigned char *)buf_out + 8, - buf_len - 8, + (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' */ + data_len, + (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, + data_len, &sig); if (!NT_STATUS_IS_OK(status)) { @@ -138,7 +151,8 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, return status; } - memcpy(buf_out+buf_len, sig.data, NTLMSSP_SIG_SIZE); + /* First 16 data bytes are signature for SSPI compatibility. */ + memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); *ppbuf_out = buf_out; return NT_STATUS_OK; } @@ -195,14 +209,12 @@ NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, cha gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; } -#endif /****************************************************************************** Generic code for client and server. gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. ******************************************************************************/ -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, uint16 enc_ctx_num, char *buf, -- cgit From 261c004d7bf85de945a1a3956c1d8f15075bc224 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Mar 2007 22:25:08 +0000 Subject: r22014: Make us pass RANDOMIPC test again :-(. This is an ugly check-in, but I've no option. Jeremy. (This used to be commit c3a565081d70b209a4f9e6e8f1859bf7194a5f74) --- source3/libsmb/clidgram.c | 5 ++++- source3/libsmb/cliprint.c | 12 ++++++------ source3/libsmb/clirap.c | 18 +++++++++--------- source3/libsmb/clirap2.c | 4 ++-- 4 files changed, 21 insertions(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index a983f485ab..b6a9cfb31a 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -85,7 +85,10 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot, SSVAL(ptr,smb_vwv16,2); p2 = smb_buf(ptr); fstrcpy(p2,mailslot); - p2 = skip_string(p2,1); + p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2,1); + if (!p2) { + return False; + } memcpy(p2,buf,len); p2 += len; diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 5798e94554..e33a3564eb 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -64,16 +64,16 @@ int cli_print_queue(struct cli_state *cli, SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ p += 2; pstrcpy_base(p,"zWrLeh", param); /* parameter description? */ - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */ - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); pstrcpy_base(p,cli->share, param); /* name of queue */ - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ SSVAL(p,2,1000); /* size of bytes of returned data buffer */ p += 4; pstrcpy_base(p,"", param); /* subformat */ - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); @@ -133,9 +133,9 @@ int cli_printjob_del(struct cli_state *cli, int job) SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; pstrcpy_base(p,"W", param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); pstrcpy_base(p,"", param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); SSVAL(p,0,job); p += 2; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 4be03e16f0..3fc95e8429 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -86,9 +86,9 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) SSVAL(p,0,132); /* api number */ p += 2; pstrcpy_base(p,"OOWb54WrLh",param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); SSVAL(p,0,1); p += 2; pstrcpy_base(p,user,param); @@ -147,9 +147,9 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co SSVAL(p,0,0); /* api number */ p += 2; pstrcpy_base(p,"WrLeh",param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); pstrcpy_base(p,"B13BWz",param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); SSVAL(p,0,1); /* * Win2k needs a *smaller* buffer than 0xFFFF here - @@ -225,11 +225,11 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SSVAL(p,0,0x68); /* api number */ p += 2; pstrcpy_base(p,"WrLehDz", param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); pstrcpy_base(p,"B16BBDz", param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); SSVAL(p,0,uLevel); SSVAL(p,2,CLI_BUFFER_SIZE); p += 4; @@ -314,11 +314,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; pstrcpy_base(p, "zsT", param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); pstrcpy_base(p, "B516B16", param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); pstrcpy_base(p,user, param); - p = skip_string(p,1); + p = skip_string(param,sizeof(param),p,1); SSVAL(p,0,532); p += 2; diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index d6a44f4ea2..9ab8997871 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -91,7 +91,7 @@ /* put string s at p with max len n and increment p past string */ #define PUTSTRING(p,s,n) do {\ push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\ - p = skip_string(p,1);\ + p = push_skip_string(p,1);\ } while(0) /* put string s and p, using fixed len l, and increment p by l */ #define PUTSTRINGF(p,s,l) do {\ @@ -111,7 +111,7 @@ /* get asciiz string s from p, increment p past string */ #define GETSTRING(p,s) do {\ pull_ascii_pstring(s,p);\ - p = skip_string(p,1);\ + p = push_skip_string(p,1);\ } while(0) /* get fixed length l string s from p, increment p by l */ #define GETSTRINGF(p,s,l) do {\ -- cgit From 44ca85a506043e9d1b3ac2e66b0ae17d2d0b92da Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Mar 2007 23:23:45 +0000 Subject: r22016: Try and fix the build - move things out of proto.h Jeremy. (This used to be commit 29933600cff458f6599e4604f9e861cd20fc8e38) --- source3/libsmb/smb_seal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index fac451a6c5..836bd0a38f 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -164,7 +164,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, ******************************************************************************/ #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) -NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) +static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) { gss_ctx_id_t gss_ctx = gss_state->gss_ctx; OM_uint32 ret = 0; @@ -215,7 +215,7 @@ NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, cha gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. ******************************************************************************/ -NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, +static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, uint16 enc_ctx_num, char *buf, char **ppbuf_out) -- cgit From 0a2cc569a1803f459f7db77d03e6e90ae30aa35d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 2 Apr 2007 20:10:21 +0000 Subject: r22045: As Volker noticed, skip_string's last argument is redundent. Remove it. Jeremy. (This used to be commit 140881cfbb59ce4a699b5900efe02bf315be7bd5) --- source3/libsmb/clidgram.c | 2 +- source3/libsmb/cliprint.c | 12 ++++++------ source3/libsmb/clirap.c | 18 +++++++++--------- source3/libsmb/clirap2.c | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index b6a9cfb31a..83ea81ddf1 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -85,7 +85,7 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot, SSVAL(ptr,smb_vwv16,2); p2 = smb_buf(ptr); fstrcpy(p2,mailslot); - p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2,1); + p2 = skip_string(ptr,MAX_DGRAM_SIZE,p2); if (!p2) { return False; } diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index e33a3564eb..cb04e0ddcc 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -64,16 +64,16 @@ int cli_print_queue(struct cli_state *cli, SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ p += 2; pstrcpy_base(p,"zWrLeh", param); /* parameter description? */ - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */ - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); pstrcpy_base(p,cli->share, param); /* name of queue */ - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ SSVAL(p,2,1000); /* size of bytes of returned data buffer */ p += 4; pstrcpy_base(p,"", param); /* subformat */ - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); @@ -133,9 +133,9 @@ int cli_printjob_del(struct cli_state *cli, int job) SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; pstrcpy_base(p,"W", param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); pstrcpy_base(p,"", param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); SSVAL(p,0,job); p += 2; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 3fc95e8429..5891120323 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -86,9 +86,9 @@ BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) SSVAL(p,0,132); /* api number */ p += 2; pstrcpy_base(p,"OOWb54WrLh",param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); SSVAL(p,0,1); p += 2; pstrcpy_base(p,user,param); @@ -147,9 +147,9 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co SSVAL(p,0,0); /* api number */ p += 2; pstrcpy_base(p,"WrLeh",param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); pstrcpy_base(p,"B13BWz",param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); SSVAL(p,0,1); /* * Win2k needs a *smaller* buffer than 0xFFFF here - @@ -225,11 +225,11 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SSVAL(p,0,0x68); /* api number */ p += 2; pstrcpy_base(p,"WrLehDz", param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); pstrcpy_base(p,"B16BBDz", param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); SSVAL(p,0,uLevel); SSVAL(p,2,CLI_BUFFER_SIZE); p += 4; @@ -314,11 +314,11 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; pstrcpy_base(p, "zsT", param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); pstrcpy_base(p, "B516B16", param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); pstrcpy_base(p,user, param); - p = skip_string(param,sizeof(param),p,1); + p = skip_string(param,sizeof(param),p); SSVAL(p,0,532); p += 2; diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 9ab8997871..1730626066 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -91,7 +91,7 @@ /* put string s at p with max len n and increment p past string */ #define PUTSTRING(p,s,n) do {\ push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\ - p = push_skip_string(p,1);\ + p = push_skip_string(p);\ } while(0) /* put string s and p, using fixed len l, and increment p by l */ #define PUTSTRINGF(p,s,l) do {\ @@ -111,7 +111,7 @@ /* get asciiz string s from p, increment p past string */ #define GETSTRING(p,s) do {\ pull_ascii_pstring(s,p);\ - p = push_skip_string(p,1);\ + p = push_skip_string(p);\ } while(0) /* get fixed length l string s from p, increment p by l */ #define GETSTRINGF(p,s,l) do {\ -- cgit From bcab9254cc65e72dcb885aac8faec095143587e9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Apr 2007 11:13:25 +0000 Subject: r22091: Fix an uninitialized variable warning (This used to be commit a6e1e39f1dcd9ebcb5db199fd152a861b9be929b) --- source3/libsmb/samlogon_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 61dddb62fd..3edbbaa2c1 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -59,7 +59,6 @@ BOOL netsamlogon_cache_shutdown(void) ***********************************************************************/ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) { - TDB_DATA key; BOOL got_tdb = False; DOM_SID sid; fstring key_str, sid_string; @@ -93,7 +92,7 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) fstr_sprintf(key_str, "UG/%s", sid_to_string(sid_string, &sid)); - DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key.dptr)); + DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str)); tdb_delete(tdb, string_tdb_data(key_str)); -- cgit From eceb926df94063e91c5abc96f52a1bc7b45ce290 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Apr 2007 12:30:23 +0000 Subject: r22092: - make spnego_parse_auth_response() more generic and not specific for NTLMSSP - it's possible that the server sends a mechOID and authdata if negResult != SPNEGO_NEG_RESULT_INCOMPLETE, but we still force the mechOID to be present if negResult == SPNEGO_NEG_RESULT_INCOMPLETE metze (This used to be commit e9f2aa22f90208a5e530ef3b68664151960a0a22) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clispnego.c | 23 +++++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3970731b45..3b9c477b26 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -722,7 +722,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use } data_blob_free(&tmp_blob); } else { - if (!spnego_parse_auth_response(blob, nt_status, + if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP, &blob_in)) { DEBUG(3,("Failed to parse auth response\n")); if (NT_STATUS_IS_OK(nt_status) diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6aca217e25..0c4217c417 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -518,9 +518,10 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, } /* - parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords + parse a SPNEGO auth packet. This contains the encrypted passwords */ -BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, +BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, + const char *mechOID, DATA_BLOB *auth) { ASN1_DATA data; @@ -541,14 +542,20 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, asn1_check_enumerated(&data, negResult); asn1_end_tag(&data); - if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + *auth = data_blob(NULL,0); + + if (asn1_tag_remaining(&data)) { asn1_start_tag(&data,ASN1_CONTEXT(1)); - asn1_check_OID(&data, OID_NTLMSSP); - asn1_end_tag(&data); - - asn1_start_tag(&data,ASN1_CONTEXT(2)); - asn1_read_OctetString(&data, auth); + asn1_check_OID(&data, mechOID); asn1_end_tag(&data); + + if (asn1_tag_remaining(&data)) { + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_OctetString(&data, auth); + asn1_end_tag(&data); + } + } else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + data.has_error = 1; } asn1_end_tag(&data); -- cgit From 14ac7712f3fd78ecb5f84b8b8e5e7fd6cb469671 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Apr 2007 12:36:10 +0000 Subject: r22093: send also the correct OID_KERBEROS5 not only the broken OID_KERBEROS_OLD one. metze (This used to be commit 294c69334fce1cbb74ae9eb5a06e17b397f994df) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 0c4217c417..d2494cac86 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -348,7 +348,7 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, { int retval; DATA_BLOB tkt, tkt_wrapped; - const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; + const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service and extract the session key */ retval = cli_krb5_get_ticket(principal, time_offset, -- cgit From bca29ddbba62320204ac9eb098cdaac9a6b03d80 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 7 Apr 2007 05:49:24 +0000 Subject: r22122: Start to fix csc issue with Vista. Make smbd support the extended 7 word response for tconX rather than the 3 word one we supported previously. Jeremy. (This used to be commit 137953226a2d691259e7e84d6ae0dc24755e5a3a) --- source3/libsmb/cliconnect.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 3b9c477b26..dff098cd01 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1064,6 +1064,7 @@ BOOL cli_send_tconX(struct cli_state *cli, cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,TCONX_FLAG_EXTENDED_RESPONSE); SSVAL(cli->outbuf,smb_vwv3,passlen); p = smb_buf(cli->outbuf); -- cgit From 4e0a6bd9a7a66989dc53d2682c06451afb32199e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Apr 2007 18:12:25 +0000 Subject: r22154: Make struct smbdb_ctx an opaque pointer so users of the API don't need to have tdb.h. Jeremy. (This used to be commit 512542c90a78006bda3470eed7fb6d3f6e708eed) --- source3/libsmb/smb_share_modes.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index f78eaf8ca5..53f99d0f50 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -28,6 +28,11 @@ #include "includes.h" #include "smb_share_modes.h" +/* Database context handle. */ +struct smbdb_ctx { + TDB_CONTEXT *smb_tdb; +}; + /* Remove the paranoid malloc checker. */ #ifdef malloc #undef malloc -- cgit From 282018a366dec480597c08df310a7826c079b692 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 14 Apr 2007 00:53:38 +0000 Subject: r22212: Cope with signature errors on sessionsetupX logins where the server just reflects our signature back to us. Allow the upper layer to see the real error. Jeremy. (This used to be commit 6cf0b93b1d8cb97dc665e14ace94a259def67724) --- source3/libsmb/clientgen.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e4712d2f65..de575e83a2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -139,6 +139,26 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) } if (!cli_check_sign_mac(cli)) { + /* + * If we get a signature failure in sessionsetup, then + * the server sometimes just reflects the sent signature + * back to us. Detect this and allow the upper layer to + * retrieve the correct Windows error message. + */ + if (CVAL(cli->outbuf,smb_com) == SMBsesssetupX && + (smb_len(cli->inbuf) > (smb_ss_field + 8 - 4)) && + (SVAL(cli->inbuf,smb_flg2) & FLAGS2_SMB_SECURITY_SIGNATURES) && + memcmp(&cli->outbuf[smb_ss_field],&cli->inbuf[smb_ss_field],8) == 0 && + cli_is_error(cli)) { + + /* + * Reflected signature on login error. + * Set bad sig but don't close fd. + */ + cli->smb_rw_error = READ_BAD_SIG; + return True; + } + DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = READ_BAD_SIG; close(cli->fd); -- cgit From 9812a7e32e515315302d3040a4145592640de7f7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Apr 2007 00:34:10 +0000 Subject: r22327: Finish the gss-spnego part of the seal code. Now for testing.... Jeremy. (This used to be commit 1c1f5360b67792f14b50835a2c5a4d4ac68aca8f) --- source3/libsmb/clifsinfo.c | 185 ++++++++++++++++++++++++++++++++++++++++++++- source3/libsmb/errormap.c | 4 + 2 files changed, 185 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 149af32574..be988a433f 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. FS info functions Copyright (C) Stefan (metze) Metzmacher 2003 + Copyright (C) Jeremy Allison 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -354,6 +355,22 @@ static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA return status; } +/****************************************************************************** + Make a client state struct. +******************************************************************************/ + +static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type smb_enc_type) +{ + struct smb_trans_enc_state *es = NULL; + es = SMB_MALLOC_P(struct smb_trans_enc_state); + if (!es) { + return NULL; + } + ZERO_STRUCTP(es); + es->smb_enc_type = smb_enc_type; + return es; +} + /****************************************************************************** Start a raw ntlmssp encryption. ******************************************************************************/ @@ -367,14 +384,11 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, DATA_BLOB blob_out = data_blob(NULL, 0); DATA_BLOB param_out = data_blob(NULL, 0); NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - struct smb_trans_enc_state *es = NULL; + struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_NTLM); - es = SMB_MALLOC_P(struct smb_trans_enc_state); if (!es) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(es); - es->smb_enc_type = SMB_TRANS_ENC_NTLM; status = ntlmssp_client_start(&es->s.ntlmssp_state); if (!NT_STATUS_IS_OK(status)) { goto fail; @@ -423,3 +437,166 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, common_free_encryption_state(&es); return status; } + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + +#ifndef SMB_GSS_REQUIRED_FLAGS +#define SMB_GSS_REQUIRED_FLAGS (GSS_C_CONF_FLAG|GSS_C_INTEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG) +#endif + +/****************************************************************************** + Get client gss blob to send to a server. +******************************************************************************/ + +static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, + const char *service, + const char *host, + NTSTATUS status_in, + DATA_BLOB spnego_blob_in, + DATA_BLOB *p_blob_out) +{ + const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, NULL}; + OM_uint32 ret; + OM_uint32 min; + gss_name_t srv_name; + gss_buffer_desc input_name; + gss_buffer_desc *p_tok_in; + gss_buffer_desc tok_out, tok_in; + DATA_BLOB blob_out = data_blob(NULL, 0); + DATA_BLOB blob_in = data_blob(NULL, 0); + char *host_princ_s = NULL; + OM_uint32 ret_flags = 0; + NTSTATUS status = NT_STATUS_OK; + + memset(&tok_out, '\0', sizeof(tok_out)); + + /* Get a ticket for the service@host */ + asprintf(&host_princ_s, "%s@%s", service, host); + if (host_princ_s == NULL) { + return NT_STATUS_NO_MEMORY; + } + + input_name.value = host_princ_s; + input_name.length = strlen(host_princ_s) + 1; + + ret = gss_import_name(&min, + &input_name, + GSS_C_NT_HOSTBASED_SERVICE, + &srv_name); + + if (ret != GSS_S_COMPLETE) { + SAFE_FREE(host_princ_s); + return map_nt_error_from_gss(ret, min); + } + + if (spnego_blob_in.length == 0) { + p_tok_in = GSS_C_NO_BUFFER; + } else { + /* Remove the SPNEGO wrapper */ + if (!spnego_parse_auth_response(spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) { + status = NT_STATUS_UNSUCCESSFUL; + goto fail; + } + tok_in.value = blob_in.data; + tok_in.length = blob_in.length; + p_tok_in = &tok_in; + } + + ret = gss_init_sec_context(&min, + GSS_C_NO_CREDENTIAL, /* Use our default cred. */ + &es->s.gss_state->gss_ctx, + srv_name, + GSS_C_NO_OID, /* default OID. */ + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, + GSS_C_INDEFINITE, /* requested ticket lifetime. */ + NULL, /* no channel bindings */ + p_tok_in, + NULL, /* ignore mech type */ + &tok_out, + &ret_flags, + NULL); /* ignore time_rec */ + + status = map_nt_error_from_gss(ret, min); + if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto fail; + } + + if ((ret_flags & SMB_GSS_REQUIRED_FLAGS) != SMB_GSS_REQUIRED_FLAGS) { + status = NT_STATUS_ACCESS_DENIED; + } + + blob_out = data_blob(tok_out.value, tok_out.length); + + /* Wrap in an SPNEGO wrapper */ + *p_blob_out = gen_negTokenTarg(krb_mechs, blob_out); + + fail: + + data_blob_free(&blob_out); + data_blob_free(&blob_in); + SAFE_FREE(host_princ_s); + gss_release_name(&min, &srv_name); + if (tok_out.value) { + gss_release_buffer(&min, &tok_out); + } + return status; +} + +/****************************************************************************** + Start a SPNEGO gssapi encryption context. +******************************************************************************/ + +NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) +{ + DATA_BLOB blob_recv = data_blob(NULL, 0); + DATA_BLOB blob_send = data_blob(NULL, 0); + DATA_BLOB param_out = data_blob(NULL, 0); + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + fstring fqdn; + const char *servicename; + struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_GSS); + + if (!es) { + return NT_STATUS_NO_MEMORY; + } + + name_to_fqdn(fqdn, cli->desthost); + strlower_m(fqdn); + + servicename = "cifs"; + status = make_cli_gss_blob(es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); + if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { + servicename = "host"; + status = make_cli_gss_blob(es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); + if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto fail; + } + } + + do { + data_blob_free(&blob_recv); + status = enc_blob_send_receive(cli, &blob_send, &blob_recv, ¶m_out); + if (param_out.length == 2) { + es->enc_ctx_num = SVAL(param_out.data, 0); + } + data_blob_free(&blob_send); + status = make_cli_gss_blob(es, servicename, fqdn, status, blob_recv, &blob_send); + } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); + data_blob_free(&blob_recv); + + if (NT_STATUS_IS_OK(status)) { + /* Replace the old state, if any. */ + if (cli->trans_enc_state) { + common_free_encryption_state(&cli->trans_enc_state); + } + cli->trans_enc_state = es; + cli->trans_enc_state->enc_on = True; + es = NULL; + } + + fail: + + common_free_encryption_state(&es); + return status; +} +#endif diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index a78b0af81a..97bef001fb 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1652,6 +1652,10 @@ NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor) return NT_STATUS_OK; } + if (gss_maj == GSS_S_CONTINUE_NEEDED) { + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } + if (gss_maj == GSS_S_FAILURE) { return map_nt_error_from_unix((int)minor); } -- cgit From 8e1b82e7ac13b596af0d33a81fa5deba39c671d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Apr 2007 21:56:18 +0000 Subject: r22344: Correctly create sub-struct for GSS encryption. Jeremy. (This used to be commit 197c90ec78545e7e3c03ff5787839ca134f3036a) --- source3/libsmb/clifsinfo.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index be988a433f..1ec1aea5af 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -368,6 +368,21 @@ static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type sm } ZERO_STRUCTP(es); es->smb_enc_type = smb_enc_type; + + if (smb_enc_type == SMB_TRANS_ENC_GSS) { +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss); + if (!es->s.gss_state) { + SAFE_FREE(es); + return NULL; + } + ZERO_STRUCTP(es->s.gss_state); +#else + DEBUG(0,("make_cli_enc_state: no krb5 compiled.\n"); + SAFE_FREE(es); + return NULL; +#endif + } return es; } -- cgit From 093bcd7df946f16e7ab682facd3c3c268e4e4cf2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Apr 2007 22:02:30 +0000 Subject: r22345: Only use new krb5 OID. Jeremy. (This used to be commit 1a46d2dcb930f433457877e143f5a602b6b9091e) --- source3/libsmb/clifsinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 1ec1aea5af..9d8b08b373 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -470,7 +470,7 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, DATA_BLOB spnego_blob_in, DATA_BLOB *p_blob_out) { - const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, NULL}; + const char *krb_mechs[] = {OID_KERBEROS5, NULL}; OM_uint32 ret; OM_uint32 min; gss_name_t srv_name; -- cgit From c5fb215efb757b0ed9a7010a0e44253c8e219aae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 18 Apr 2007 22:34:23 +0000 Subject: r22349: Fix missing ) in #else path. Jeremy. (This used to be commit 0f5680adcfb4f1636ba5a5c3ba9684f9fde8476a) --- source3/libsmb/clifsinfo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 9d8b08b373..4924bfdba0 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -378,7 +378,7 @@ static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type sm } ZERO_STRUCTP(es->s.gss_state); #else - DEBUG(0,("make_cli_enc_state: no krb5 compiled.\n"); + DEBUG(0,("make_cli_enc_state: no krb5 compiled.\n")); SAFE_FREE(es); return NULL; #endif -- cgit From 383cc1fa1c472bacd2dc77b05e8c90dc82f3bbde Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 00:45:01 +0000 Subject: r22353: Fix bad #ifdefs. Jeremy. (This used to be commit 9173c846b11c587e04a70ede387cd4a15173e4f2) --- source3/libsmb/errormap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 97bef001fb..33b75eece0 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1631,10 +1631,10 @@ static const struct { #if defined(GSS_S_UNAVAILABLE) {GSS_S_UNAVAILABLE, NT_STATUS_UNSUCCESSFUL}, #endif -#if defined(GSS_S_BAD_NAMETYPE) +#if defined(GSS_S_DUPLICATE_ELEMENT) {GSS_S_DUPLICATE_ELEMENT, NT_STATUS_INVALID_PARAMETER}, #endif -#if defined(GSS_S_BAD_NAMETYPE) +#if defined(GSS_S_NAME_NOT_MN) {GSS_S_NAME_NOT_MN, NT_STATUS_INVALID_PARAMETER}, #endif { 0, NT_STATUS_OK } -- cgit From f7fc540d848d5f5950f4adf921b5972be2eb81a4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 00:51:18 +0000 Subject: r22354: Make client select krb5 encrpyt if krb5 already on. Jeremy. (This used to be commit 7b89a5de57cd5fed814eda95e44dcc345f380fb2) --- source3/libsmb/clifsinfo.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 4924bfdba0..e46456abb1 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -614,4 +614,9 @@ NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) common_free_encryption_state(&es); return status; } +#else +NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) +{ + return NT_STATUS_NOT_SUPPORTED; +} #endif -- cgit From e8d19d5e1aa6a101300879e94faacc8c4b3509a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 01:20:37 +0000 Subject: r22355: Ensure we get good debug messages from gss_XX calls. Jeremy. (This used to be commit fe36fc79ddd4f2f2c88204055fca60a193586234) --- source3/libsmb/clifsinfo.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index e46456abb1..a7bdeecca9 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -533,6 +533,9 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, status = map_nt_error_from_gss(ret, min); if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, min); + DEBUG(10,("make_cli_gss_blob: gss_init_sec_context failed with %s\n", + ads_errstr(adss))); goto fail; } -- cgit From 5cee3be0140a7acbd3b75a4d7aa0fbaff8c12960 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 01:26:38 +0000 Subject: r22358: Use gss error to NTSTATUS mapping function for errors. Jeremy. (This used to be commit 11fa0ca9e21d478a4b79b8ca1e92936b26b03fe0) --- source3/libsmb/smb_seal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 836bd0a38f..19092bd8c8 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -191,8 +191,7 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", ads_errstr(adss) )); - /* Um - no mapping for gss-errs to NTSTATUS yet. */ - return ads_ntstatus(adss); + return map_nt_error_from_gss(ret, minor); } if (out_buf.length > in_buf.length) { @@ -248,8 +247,7 @@ static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_sta ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", ads_errstr(adss) )); - /* Um - no mapping for gss-errs to NTSTATUS yet. */ - return ads_ntstatus(adss); + return map_nt_error_from_gss(ret, minor); } if (!flags_got) { -- cgit From f2da00aadcf3a47d9f6a0662c97c36be32172c1a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 19 Apr 2007 08:45:29 +0000 Subject: r22362: fix the build on othersystems metze (This used to be commit 68a681038ca60c83784321979c595def9e74ed41) --- source3/libsmb/clifsinfo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index a7bdeecca9..0bc4f7f2f2 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -483,6 +483,9 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, OM_uint32 ret_flags = 0; NTSTATUS status = NT_STATUS_OK; + gss_OID_desc nt_hostbased_service = + {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")}; + memset(&tok_out, '\0', sizeof(tok_out)); /* Get a ticket for the service@host */ @@ -496,7 +499,7 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, ret = gss_import_name(&min, &input_name, - GSS_C_NT_HOSTBASED_SERVICE, + &nt_hostbased_service, &srv_name); if (ret != GSS_S_COMPLETE) { -- cgit From dc90cd89a7fef3b0a744ef1873193cf2c9d75cad Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 20:50:49 +0000 Subject: r22389: Start preparing for multiple encryption contexts in the server. Allow server to reflect back to calling client the encryption context that was sent. Jeremy. (This used to be commit b49e90335d1e589916b5ab4992e3c4a2d221ca7e) --- source3/libsmb/smb_seal.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 19092bd8c8..2e3e2f4ce3 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -93,10 +93,11 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) } memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); - SAFE_FREE(inbuf); /* Reset the length. */ - smb_setlen(buf, data_len + 4); + smb_setlen(buf, data_len + 4, inbuf); + + SAFE_FREE(inbuf); return NT_STATUS_OK; } @@ -203,7 +204,7 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta } memcpy(buf + 8, out_buf.value, out_buf.length); - smb_setlen(buf, out_buf.length + 4); + smb_setlen(buf, out_buf.length + 4, out_buf.value); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; -- cgit From 0829e1ad1c3646efecf50729f493b9ee72ef0517 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 22:40:32 +0000 Subject: r22391: Looks bigger than it is. Make "inbuf" available to all callers of smb_setlen (via set_message() calls). This will allow the server to reflect back the correct encryption context. Jeremy. (This used to be commit 2d80a96120a5fe2fe726f00746d36d85044c4bdb) --- source3/libsmb/cliconnect.c | 22 +++++++++++----------- source3/libsmb/clidgram.c | 2 +- source3/libsmb/clientgen.c | 4 ++-- source3/libsmb/clifile.c | 44 +++++++++++++++++++++---------------------- source3/libsmb/clilist.c | 4 ++-- source3/libsmb/climessage.c | 6 +++--- source3/libsmb/clioplock.c | 2 +- source3/libsmb/cliprint.c | 4 ++-- source3/libsmb/clireadwrite.c | 10 +++++----- source3/libsmb/clitrans.c | 8 ++++---- source3/libsmb/smb_seal.c | 4 ++-- 11 files changed, 55 insertions(+), 55 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index dff098cd01..cc2a7304be 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -99,7 +99,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,10, 0, True); + set_message(NULL,cli->outbuf,10, 0, True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -169,7 +169,7 @@ static NTSTATUS cli_session_setup_guest(struct cli_state *cli) uint32 capabilities = cli_session_setup_capabilities(cli); memset(cli->outbuf, '\0', smb_size); - set_message(cli->outbuf,13,0,True); + set_message(NULL,cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -229,7 +229,7 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); memset(cli->outbuf, '\0', smb_size); - set_message(cli->outbuf,13,0,True); + set_message(NULL,cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -378,7 +378,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,13,0,True); + set_message(NULL,cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -458,7 +458,7 @@ static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,12,0,True); + set_message(NULL,cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -982,7 +982,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + set_message(NULL,cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBulogoffX); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); @@ -1059,7 +1059,7 @@ BOOL cli_send_tconX(struct cli_state *cli, slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); - set_message(cli->outbuf,4, 0, True); + set_message(NULL,cli->outbuf,4, 0, True); SCVAL(cli->outbuf,smb_com,SMBtconX); cli_setup_packet(cli); @@ -1110,7 +1110,7 @@ BOOL cli_send_tconX(struct cli_state *cli, BOOL cli_tdis(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + set_message(NULL,cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBtdis); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1142,7 +1142,7 @@ void cli_negprot_send(struct cli_state *cli) memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ - set_message(cli->outbuf,0,0,True); + set_message(NULL,cli->outbuf,0,0,True); p = smb_buf(cli->outbuf); for (numprots=0; @@ -1182,7 +1182,7 @@ BOOL cli_negprot(struct cli_state *cli) numprots++) plength += strlen(prots[numprots].name)+2; - set_message(cli->outbuf,0,plength,True); + set_message(NULL,cli->outbuf,0,plength,True); p = smb_buf(cli->outbuf); for (numprots=0; @@ -1716,7 +1716,7 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 0, 0, True); + set_message(NULL,cli->outbuf, 0, 0, True); SCVAL(cli->outbuf,smb_com,SMBtcon); cli_setup_packet(cli); diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 83ea81ddf1..2f64b2c05d 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -72,7 +72,7 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot, /* Setup the smb part. */ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ memcpy(tmp,ptr,4); - set_message(ptr,17,strlen(mailslot) + 1 + len,True); + set_message(NULL,ptr,17,strlen(mailslot) + 1 + len,True); memcpy(ptr,tmp,4); SCVAL(ptr,smb_com,SMBtrans); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index de575e83a2..e1dacb3921 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -298,7 +298,7 @@ void cli_setup_packet(struct cli_state *cli) void cli_setup_bcc(struct cli_state *cli, void *p) { - set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); + set_message_bcc(NULL,cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); } /**************************************************************************** @@ -584,7 +584,7 @@ BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) SMB_ASSERT(length < 1024); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,length,True); + set_message(NULL,cli->outbuf,1,length,True); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); SSVAL(cli->outbuf,smb_vwv0,1); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ce2081a81e..ad6029f224 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -390,7 +390,7 @@ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 0, True); + set_message(NULL,cli->outbuf,1, 0, True); SCVAL(cli->outbuf,smb_com,SMBmv); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -427,7 +427,7 @@ BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 4, 0, True); + set_message(NULL,cli->outbuf, 4, 0, True); SCVAL(cli->outbuf,smb_com,SMBntrename); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -465,7 +465,7 @@ BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *f memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 4, 0, True); + set_message(NULL,cli->outbuf, 4, 0, True); SCVAL(cli->outbuf,smb_com,SMBntrename); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -503,7 +503,7 @@ BOOL cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 0,True); + set_message(NULL,cli->outbuf,1, 0,True); SCVAL(cli->outbuf,smb_com,SMBunlink); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -548,7 +548,7 @@ BOOL cli_mkdir(struct cli_state *cli, const char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 0,True); + set_message(NULL,cli->outbuf,0, 0,True); SCVAL(cli->outbuf,smb_com,SMBmkdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -583,7 +583,7 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 0, True); + set_message(NULL,cli->outbuf,0, 0, True); SCVAL(cli->outbuf,smb_com,SMBrmdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -665,7 +665,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,24,0,True); + set_message(NULL,cli->outbuf,24,0,True); SCVAL(cli->outbuf,smb_com,SMBntcreateX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -759,7 +759,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,15,0,True); + set_message(NULL,cli->outbuf,15,0,True); SCVAL(cli->outbuf,smb_com,SMBopenX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -806,7 +806,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,3,0,True); + set_message(NULL,cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -838,7 +838,7 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,0,True); + set_message(NULL,cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -890,7 +890,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,0,True); + set_message(NULL,cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -943,7 +943,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,0,True); + set_message(NULL,cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -995,7 +995,7 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,0,True); + set_message(NULL,cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1050,7 +1050,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,0,True); + set_message(NULL,cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1197,7 +1197,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); + set_message(NULL,cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBgetattrE); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1249,7 +1249,7 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + set_message(NULL,cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBgetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1301,7 +1301,7 @@ BOOL cli_setattrE(struct cli_state *cli, int fd, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,7,0,True); + set_message(NULL,cli->outbuf,7,0,True); SCVAL(cli->outbuf,smb_com,SMBsetattrE); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1340,7 +1340,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,0,True); + set_message(NULL,cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBsetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1382,7 +1382,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) *path2 = '\\'; memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + set_message(NULL,cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBcheckpath); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1409,7 +1409,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + set_message(NULL,cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBdskattr); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1438,7 +1438,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,3,0,True); + set_message(NULL,cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBctemp); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1488,7 +1488,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 3, 0, True); + set_message(NULL,cli->outbuf, 3, 0, True); SCVAL(cli->outbuf,smb_com,SMBioctl); cli_setup_packet(cli); diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3e76cd4775..8290a57742 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -418,7 +418,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + set_message(NULL,cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBsearch); @@ -475,7 +475,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + set_message(NULL,cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 1aa659c1ba..6850c4b8df 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -30,7 +30,7 @@ int cli_message_start_build(struct cli_state *cli, char *host, char *username) /* construct a SMBsendstrt command */ memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + set_message(NULL,cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBsendstrt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -75,7 +75,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) char *p; memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); + set_message(NULL,cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBsendtxt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -125,7 +125,7 @@ int cli_message_end_build(struct cli_state *cli, int grp) char *p; memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); + set_message(NULL,cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBsendend); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index 037d7147db..c08bde0248 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -32,7 +32,7 @@ BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) cli->outbuf = buf; memset(buf,'\0',smb_size); - set_message(buf,8,0,True); + set_message(NULL,buf,8,0,True); SCVAL(buf,smb_com,SMBlockingX); SSVAL(buf,smb_tid, cli->cnum); diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index cb04e0ddcc..b09fb38906 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -194,7 +194,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,15,0,True); + set_message(NULL,cli->outbuf,15,0,True); SCVAL(cli->outbuf,smb_com,SMBsplopen); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -241,7 +241,7 @@ BOOL cli_spl_close(struct cli_state *cli, int fnum) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,3,0,True); + set_message(NULL,cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBsplclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 02fa804f41..1c72cb2942 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -35,7 +35,7 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, if ((SMB_BIG_UINT)offset >> 32) bigoffset = True; - set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); + set_message(NULL,cli->outbuf,bigoffset ? 12 : 10,0,True); SCVAL(cli->outbuf,smb_com,SMBreadX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -176,7 +176,7 @@ static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,10,0,True); + set_message(NULL,cli->outbuf,10,0,True); SCVAL(cli->outbuf,smb_com,SMBreadbraw); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -285,9 +285,9 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, } if (large_writex) - set_message(cli->outbuf,14,0,True); + set_message(NULL,cli->outbuf,14,0,True); else - set_message(cli->outbuf,12,0,True); + set_message(NULL,cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBwriteX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -399,7 +399,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,5, 0,True); + set_message(NULL,cli->outbuf,5, 0,True); SCVAL(cli->outbuf,smb_com,SMBwrite); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 33fddae202..3e3ebc1ce1 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -44,7 +44,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,14+lsetup,0,True); + set_message(NULL,cli->outbuf,14+lsetup,0,True); SCVAL(cli->outbuf,smb_com,trans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); @@ -113,7 +113,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); + set_message(NULL,cli->outbuf,trans==SMBtrans?8:9,0,True); SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); outparam = smb_buf(cli->outbuf); @@ -352,7 +352,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,19+lsetup,0,True); + set_message(NULL,cli->outbuf,19+lsetup,0,True); SCVAL(cli->outbuf,smb_com,SMBnttrans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); @@ -413,7 +413,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - set_message(cli->outbuf,18,0,True); + set_message(NULL,cli->outbuf,18,0,True); SCVAL(cli->outbuf,smb_com,SMBnttranss); /* XXX - these should probably be aligned */ diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 2e3e2f4ce3..dde69570ab 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -95,7 +95,7 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); /* Reset the length. */ - smb_setlen(buf, data_len + 4, inbuf); + smb_setlen(inbuf, buf, data_len + 4); SAFE_FREE(inbuf); return NT_STATUS_OK; @@ -204,7 +204,7 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta } memcpy(buf + 8, out_buf.value, out_buf.length); - smb_setlen(buf, out_buf.length + 4, out_buf.value); + smb_setlen(out_buf.value, buf, out_buf.length + 4); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; -- cgit From 8a22b1f0ea81f06616a2dc41a138c5126359f009 Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 20 Apr 2007 18:34:33 +0000 Subject: r22417: Refactor the various daemon run-mode options to make the semantics of the various flags explicit. (This used to be commit 19c929c6330a50f278ac322ac5fcb83d03734ea2) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index cbd94ff567..0826bc5218 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -651,7 +651,7 @@ struct in_addr *name_query(int fd,const char *name,int name_type, Start parsing the lmhosts file. *********************************************************/ -XFILE *startlmhosts(char *fname) +XFILE *startlmhosts(const char *fname) { XFILE *fp = x_fopen(fname,O_RDONLY, 0); if (!fp) { -- cgit From b304cabb4472ad0e89de5c0c678a10c83ec50ee9 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 21 Apr 2007 20:43:54 +0000 Subject: r22425: Avoid to segfault if we only have the realm. (This used to be commit ace1520270d19d41c24236d4e26ccf77071ebeb9) --- source3/libsmb/namequery_dc.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 110b9986b7..65e860d45e 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -215,6 +215,11 @@ BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct if ( (our_domain && lp_security()==SEC_ADS) || realm ) { ret = ads_dc_name(domain, realm, &dc_ip, srv_name); } + + if (!domain) { + /* if we have only the realm we can't do anything else */ + return False; + } if (!ret) { /* fall back on rpc methods if the ADS methods fail */ -- cgit From 1ee9650a1dfa28badac1f37b4c14fca920c6330c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Apr 2007 08:40:54 +0000 Subject: r22479: Add "net ads keytab list". Guenther (This used to be commit 9ec76c542775ae58ff03f42ebfa1acc1a63a1bb1) --- source3/libsmb/clikrb5.c | 47 +++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 7043a26408..474c6823ea 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -28,11 +28,11 @@ #ifdef HAVE_KRB5 -#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE -#define KRB5_KEY_TYPE(k) ((k)->keytype) +#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE /* Heimdal */ +#define KRB5_KEY_TYPE(k) ((k)->keytype) #define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) #define KRB5_KEY_DATA(k) ((k)->keyvalue.data) -#else +#else /* MIT */ #define KRB5_KEY_TYPE(k) ((k)->enctype) #define KRB5_KEY_LENGTH(k) ((k)->length) #define KRB5_KEY_DATA(k) ((k)->contents) @@ -1216,7 +1216,7 @@ out: krb5_free_creds(context, creds); } #else -#error No suitable krb5 ticket renew function available +#error NO_SUITABKE_KRB5_TICKET_RENEW_FUNCTION_AVAILABLE #endif @@ -1428,18 +1428,53 @@ done: #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE #ifdef KRB5_CREDS_OPT_FREE_REQUIRES_CONTEXT - /* Modern MIT version */ + /* Modern MIT or Heimdal version */ krb5_get_init_creds_opt_free(context, opt); #else /* Heimdal version */ krb5_get_init_creds_opt_free(opt); -#endif +#endif /* KRB5_CREDS_OPT_FREE_REQUIRES_CONTEXT */ #else /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */ /* Historical MIT version */ SAFE_FREE(opt); opt = NULL; #endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */ +} + + krb5_enctype smb_get_enctype_from_kt_entry(const krb5_keytab_entry *kt_entry) +{ +#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ + return kt_entry->key.enctype; +#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) /* Heimdal */ + return kt_entry->keyblock.keytype; +#else +#error UNKNOWN_KRB5_KEYTAB_ENTRY_KEYBLOCK_FORMAT +#endif +} + + +/* caller needs to free etype_s */ + krb5_error_code smb_krb5_enctype_to_string(krb5_context context, + krb5_enctype enctype, + char **etype_s) +{ +#ifdef HAVE_KRB5_ENCTYPE_TO_STRING_WITH_KRB5_CONTEXT_ARG + return krb5_enctype_to_string(context, enctype, etype_s); /* Heimdal */ +#elif defined(HAVE_KRB5_ENCTYPE_TO_STRING_WITH_SIZE_T_ARG) + char buf[256]; + krb5_error_code ret = krb5_enctype_to_string(enctype, buf, 256); /* MIT */ + if (ret) { + return ret; + } + *etype_s = SMB_STRDUP(buf); + if (!*etype_s) { + return ENOMEM; + } + return ret; +#else +#error UNKNOWN_KRB5_ENCTYPE_TO_STRING_FUNCTION +#endif } krb5_error_code smb_krb5_mk_error(krb5_context context, -- cgit From 12ba88574bf91bdcc4447bfc3d429b799064bfd9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Apr 2007 23:18:41 +0000 Subject: r22542: Move over to using the _strict varients of the talloc calls. No functional changes. Looks bigger than it is :-). Jeremy. (This used to be commit f6fa3080fee1b20df9f1968500840a88cf0ee592) --- source3/libsmb/cliquota.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 5627d28bb5..2a47ae2463 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -322,13 +322,13 @@ BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST } if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { - DEBUG(0,("talloc_zero() failed\n")); + DEBUG(0,("TALLOC_ZERO() failed\n")); talloc_destroy(mem_ctx); return (-1); } if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { - DEBUG(0,("talloc_zero() failed\n")); + DEBUG(0,("TALLOC_ZERO() failed\n")); talloc_destroy(mem_ctx); return (-1); } @@ -382,13 +382,13 @@ BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST } if ((tmp_list_ent=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_LIST))==NULL) { - DEBUG(0,("talloc_zero() failed\n")); + DEBUG(0,("TALLOC_ZERO() failed\n")); talloc_destroy(mem_ctx); goto cleanup; } if ((tmp_list_ent->quotas=TALLOC_ZERO_P(mem_ctx,SMB_NTQUOTA_STRUCT))==NULL) { - DEBUG(0,("talloc_zero() failed\n")); + DEBUG(0,("TALLOC_ZERO() failed\n")); talloc_destroy(mem_ctx); goto cleanup; } -- cgit From be8b0685a55700c6bce3681734800ec6434b0364 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Apr 2007 02:39:34 +0000 Subject: r22589: Make TALLOC_ARRAY consistent across all uses. Jeremy. (This used to be commit 8968808c3b5b0208cbad9ac92eaf948f2c546dd9) --- source3/libsmb/clifile.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index ad6029f224..2e1c156f14 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1692,9 +1692,13 @@ static BOOL cli_get_ea_list(struct cli_state *cli, goto out; } - ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); - if (!ea_list) { - goto out; + if (num_eas) { + ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); + if (!ea_list) { + goto out; + } + } else { + ea_list = NULL; } ea_size = (size_t)IVAL(rdata,0); -- cgit From d14e7803e7d024f7f95cbfce330e947ab66e3661 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 3 May 2007 11:49:32 +0000 Subject: r22644: Fix memleak. Guenther (This used to be commit 65a2701f36439db37e8cd6067be69e8ffdc4615b) --- source3/libsmb/cliconnect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index cc2a7304be..6991905c58 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -536,6 +536,7 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B int32 cur = 0; DATA_BLOB send_blob = data_blob(NULL, 0); int32 max_blob_size = 0; + DATA_BLOB receive_blob = data_blob(NULL, 0); if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) { DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small " @@ -575,7 +576,8 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B return False; } - cli_session_setup_blob_receive(cli); + receive_blob = cli_session_setup_blob_receive(cli); + data_blob_free(&receive_blob); if (cli_is_error(cli) && !NT_STATUS_EQUAL( cli_get_nt_error(cli), -- cgit From b213b35e08cb53eec47ceae87a52d3b0832a5914 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 3 May 2007 12:29:32 +0000 Subject: r22647: Avoid leaking a full info3 structure on each winbindd cached login by making netsamlogon_cache_get() return a talloc'ed structure. Guenther (This used to be commit 5b149967cc3ab68057db015e67b688c9b9577f0d) --- source3/libsmb/samlogon_cache.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 3edbbaa2c1..0791cd80e4 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -192,10 +192,13 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user data = tdb_fetch_bystring( netsamlogon_tdb, keystr ); if ( data.dptr ) { - - if ( (user = SMB_MALLOC_P(NET_USER_INFO_3)) == NULL ) + + + user = TALLOC_ZERO_P(mem_ctx, NET_USER_INFO_3); + if (user == NULL) { return NULL; - + } + prs_init( &ps, 0, mem_ctx, UNMARSHALL ); prs_give_memory( &ps, (char *)data.dptr, data.dsize, True ); @@ -247,7 +250,6 @@ BOOL netsamlogon_cache_have(const DOM_SID *user_sid) result = (user != NULL); talloc_destroy(mem_ctx); - SAFE_FREE(user); return result; } -- cgit From e7d06b1c258aa6ea7d039c2d592fbfff96fccafc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 3 May 2007 20:12:00 +0000 Subject: r22655: Call correct free-macros in netsamlogon_cache_get() error paths. Forgot those in the previous commit. Guenther (This used to be commit fce2fe9903417f4ee58a1ddc03ad0083109b7c50) --- source3/libsmb/samlogon_cache.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 0791cd80e4..106ff21dfe 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -193,7 +193,6 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user if ( data.dptr ) { - user = TALLOC_ZERO_P(mem_ctx, NET_USER_INFO_3); if (user == NULL) { return NULL; @@ -204,12 +203,12 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) { prs_mem_free( &ps ); - SAFE_FREE(user); + TALLOC_FREE(user); return False; } if ( !net_io_user_info3("", user, &ps, 0, 3, 0) ) { - SAFE_FREE( user ); + TALLOC_FREE( user ); } prs_mem_free( &ps ); @@ -228,7 +227,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) { DEBUG(10,("netsamlogon_cache_get: cache entry expired \n")); tdb_delete( netsamlogon_tdb, key ); - SAFE_FREE( user ); + TALLOC_FREE( user ); } #endif } -- cgit From 116c1532e7e8c398a1b22253a361bd88b729fb0f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 May 2007 09:55:40 +0000 Subject: r22664: When we have krb5_get_init_creds_opt_get_error() then try to get the NTSTATUS codes directly out of the krb5_error edata. Guenther (This used to be commit dcd902f24a59288bbb7400d59c0afc0c8303ed69) --- source3/libsmb/clikrb5.c | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 474c6823ea..64cfe6e952 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -272,6 +272,45 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, } #endif +BOOL unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx, + DATA_BLOB *edata, + DATA_BLOB *edata_out) +{ + DATA_BLOB edata_contents; + ASN1_DATA data; + int edata_type; + + if (!edata->length) { + return False; + } + + asn1_load(&data, *edata); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_read_Integer(&data, &edata_type); + + if (edata_type != KRB5_PADATA_PW_SALT) { + DEBUG(0,("edata is not of required type %d but of type %d\n", + KRB5_PADATA_PW_SALT, edata_type)); + asn1_free(&data); + return False; + } + + asn1_start_tag(&data, ASN1_CONTEXT(2)); + asn1_read_OctetString(&data, &edata_contents); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_free(&data); + + *edata_out = data_blob_talloc(mem_ctx, edata_contents.data, edata_contents.length); + + data_blob_free(&edata_contents); + + return True; +} + + BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data) { DATA_BLOB pac_contents; -- cgit From d1153fc79076741571b203b1d70f1536bde208f0 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 7 May 2007 03:07:39 +0000 Subject: r22732: - Testing of libsmbclient against Vista revealed what is likely a bug in Vista. Vista provides a plethora of kludges to simulate older versions of Windows. The kludges are in the form of shortcuts (or more likely symbolic links, but I don't know enough about Vista to determine that definitively) and in most cases, attempts to access them get back an "access denied" error. On one particular folder, however, "/Users/All Users", it returns an unknown (to ethereal and the Samba3 code) NT status code: 0x8000002d. Although this code does not have a high byte of 0xc0 indicating that it is an error, it appears to be an alternate form of "access denied". Without this patch, libsmbclient times out on an attempt to enumerate that folder rather than returning an error to the caller. This patch corrects that problem. (This used to be commit cc0cd3a12f76b8cd711e3165d4cfe920552f256d) --- source3/libsmb/clierror.c | 9 +++++++++ source3/libsmb/clitrans.c | 9 ++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 4b222c9015..d98f428217 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -385,6 +385,15 @@ int cli_errno(struct cli_state *cli) return cli_errno_from_nt(status); } + /* + * Yuck! A special case for this Vista error. Since its high-order + * byte isn't 0xc0, it doesn't match cli_is_nt_error() above. + */ + status = cli_nt_error(cli); + if (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) { + return EACCES; + } + /* for other cases */ return EINVAL; } diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 3e3ebc1ce1..d7492b31c3 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -196,11 +196,18 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, * returned when a trans2 findfirst/next finishes. * When setting up an encrypted transport we can also * see NT_STATUS_MORE_PROCESSING_REQUIRED here. + * + * Vista returns NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT if the folder + * "/Users/All Users" is enumerated. This is a special pseudo + * folder, and the response does not have parameters (nor a parameter + * length). */ status = cli_nt_error(cli); if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES)) { + if (NT_STATUS_IS_ERR(status) || + NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES) || + NT_STATUS_EQUAL(status,NT_STATUS_INACCESSIBLE_SYSTEM_SHORTCUT)) { goto out; } } -- cgit From e6383f47629368d9dd4e803f17566a24e9d7359e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 09:35:35 +0000 Subject: r22736: Start to merge the low-hanging fruit from the now 7000-line cluster patch. This changes "struct process_id" to "struct server_id", keeping both is just too much hassle. No functional change (I hope ;-)) Volker (This used to be commit 0ad4b1226c9d91b72136310d3bbb640d2c5d67b8) --- source3/libsmb/smb_share_modes.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 53f99d0f50..da8d9e1fdc 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -42,12 +42,12 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, const struct smb_share_mode_entry *new_entry, const char *sharepath, const char *filename); -static BOOL sharemodes_procid_equal(const struct process_id *p1, const struct process_id *p2) +static BOOL sharemodes_procid_equal(const struct server_id *p1, const struct server_id *p2) { return (p1->pid == p2->pid); } -static pid_t sharemodes_procid_to_pid(const struct process_id *proc) +static pid_t sharemodes_procid_to_pid(const struct server_id *proc) { return proc->pid; } @@ -211,7 +211,7 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, for (i = 0; i < num_share_modes; i++) { struct share_mode_entry *share = &shares[i]; struct smb_share_mode_entry *sme = &list[list_num]; - struct process_id pid = share->pid; + struct server_id pid = share->pid; /* Check this process really exists. */ if (kill(sharemodes_procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { @@ -416,7 +416,7 @@ int smb_delete_share_mode_entry(struct smbdb_ctx *db_ctx, num_share_modes = 0; for (i = 0; i < orig_num_share_modes; i++) { struct share_mode_entry *share = &shares[i]; - struct process_id pid = share->pid; + struct server_id pid = share->pid; /* Check this process really exists. */ if (kill(sharemodes_procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { @@ -492,7 +492,7 @@ int smb_change_share_mode_entry(struct smbdb_ctx *db_ctx, for (i = 0; i < num_share_modes; i++) { struct share_mode_entry *share = &shares[i]; - struct process_id pid = share->pid; + struct server_id pid = share->pid; /* Check this process really exists. */ if (kill(sharemodes_procid_to_pid(&pid), 0) == -1 && (errno == ESRCH)) { -- cgit From 71921605995fa95d84301534760a6bc2db3fa74b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 May 2007 15:07:49 +0000 Subject: r22747: Fix some C++ warnings (This used to be commit a66a04e9f11f6c4462f2b56b447bae4eca7b177c) --- source3/libsmb/clikrb5.c | 2 +- source3/libsmb/smb_seal.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 64cfe6e952..a668d3b55c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1450,7 +1450,7 @@ done: *opt = NULL; - if ((my_opt = SMB_MALLOC(sizeof(krb5_get_init_creds_opt))) == NULL) { + if ((my_opt = SMB_MALLOC_P(krb5_get_init_creds_opt)) == NULL) { return ENOMEM; } diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index dde69570ab..81c6ff1bac 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -72,7 +72,7 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) return NT_STATUS_BUFFER_TOO_SMALL; } - inbuf = smb_xmemdup(buf, buf_len); + inbuf = (char *)smb_xmemdup(buf, buf_len); /* Adjust for the signature. */ data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; @@ -204,7 +204,7 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta } memcpy(buf + 8, out_buf.value, out_buf.length); - smb_setlen(out_buf.value, buf, out_buf.length + 4); + smb_setlen((char *)out_buf.value, buf, out_buf.length + 4); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; @@ -269,7 +269,7 @@ static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_sta * bother :-*(. JRA. */ - *ppbuf_out = SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */ + *ppbuf_out = (char *)SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */ if (!*ppbuf_out) { gss_release_buffer(&minor, &out_buf); return NT_STATUS_NO_MEMORY; -- cgit From b4a7b7a8889737e2891fc1176feabd4ce47f2737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 12:16:20 +0000 Subject: r22844: Introduce const DATA_BLOB data_blob_null = { NULL, 0, NULL }; and replace all data_blob(NULL, 0) calls. (This used to be commit 3d3d61687ef00181f4f04e001d42181d93ac931e) --- source3/libsmb/cliconnect.c | 30 +++++++++++++++--------------- source3/libsmb/clifile.c | 2 +- source3/libsmb/clifsinfo.c | 16 ++++++++-------- source3/libsmb/clispnego.c | 2 +- source3/libsmb/ntlmssp.c | 34 +++++++++++++++++----------------- source3/libsmb/ntlmssp_parse.c | 2 +- source3/libsmb/smbencrypt.c | 4 ++-- 7 files changed, 45 insertions(+), 45 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6991905c58..86834ad081 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -61,8 +61,8 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, const char *pass, size_t passlen, const char *workgroup) { - DATA_BLOB session_key = data_blob(NULL, 0); - DATA_BLOB lm_response = data_blob(NULL, 0); + DATA_BLOB session_key = data_blob_null; + DATA_BLOB lm_response = data_blob_null; fstring pword; char *p; @@ -299,9 +299,9 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, const char *workgroup) { uint32 capabilities = cli_session_setup_capabilities(cli); - DATA_BLOB lm_response = data_blob(NULL, 0); - DATA_BLOB nt_response = data_blob(NULL, 0); - DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB lm_response = data_blob_null; + DATA_BLOB nt_response = data_blob_null; + DATA_BLOB session_key = data_blob_null; NTSTATUS result; char *p; @@ -334,7 +334,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, E_md4hash(pass, nt_hash); #ifdef LANMAN_ONLY - nt_response = data_blob(NULL, 0); + nt_response = data_blob_null; #else nt_response = data_blob(NULL, 24); SMBNTencrypt(pass,cli->secblob.data,nt_response.data); @@ -485,7 +485,7 @@ static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) { - DATA_BLOB blob2 = data_blob(NULL, 0); + DATA_BLOB blob2 = data_blob_null; char *p; size_t len; @@ -534,9 +534,9 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B { int32 remaining = blob.length; int32 cur = 0; - DATA_BLOB send_blob = data_blob(NULL, 0); + DATA_BLOB send_blob = data_blob_null; int32 max_blob_size = 0; - DATA_BLOB receive_blob = data_blob(NULL, 0); + DATA_BLOB receive_blob = data_blob_null; if (cli->max_xmit < BASE_SESSSETUP_BLOB_PACKET_SIZE + 1) { DEBUG(0,("cli_session_setup_blob: cli->max_xmit too small " @@ -554,7 +554,7 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B send_blob.length = max_blob_size; remaining -= max_blob_size; } else { - DATA_BLOB null_blob = data_blob(NULL, 0); + DATA_BLOB null_blob = data_blob_null; send_blob.length = remaining; remaining = 0; @@ -656,9 +656,9 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use NTSTATUS nt_status; int turn = 1; DATA_BLOB msg1; - DATA_BLOB blob = data_blob(NULL, 0); - DATA_BLOB blob_in = data_blob(NULL, 0); - DATA_BLOB blob_out = data_blob(NULL, 0); + DATA_BLOB blob = data_blob_null; + DATA_BLOB blob_in = data_blob_null; + DATA_BLOB blob_out = data_blob_null; cli_temp_set_signing(cli); @@ -715,7 +715,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use } } else if ((turn == 1) && NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DATA_BLOB tmp_blob = data_blob(NULL, 0); + DATA_BLOB tmp_blob = data_blob_null; /* the server might give us back two challenges */ if (!spnego_parse_challenge(blob, &blob_in, &tmp_blob)) { @@ -743,7 +743,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length); - DATA_BLOB null_blob = data_blob(NULL, 0); + DATA_BLOB null_blob = data_blob_null; BOOL res; fstrcpy(cli->server_domain, ntlmssp_state->server_domain); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 2e1c156f14..61c4347b5b 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1505,7 +1505,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * return cli_nt_error(cli); } - *blob = data_blob(NULL, 0); + *blob = data_blob_null; return NT_STATUS_OK; } diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 0bc4f7f2f2..d8ada1a896 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -395,9 +395,9 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, const char *pass, const char *domain) { - DATA_BLOB blob_in = data_blob(NULL, 0); - DATA_BLOB blob_out = data_blob(NULL, 0); - DATA_BLOB param_out = data_blob(NULL, 0); + DATA_BLOB blob_in = data_blob_null; + DATA_BLOB blob_out = data_blob_null; + DATA_BLOB param_out = data_blob_null; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_NTLM); @@ -477,8 +477,8 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, gss_buffer_desc input_name; gss_buffer_desc *p_tok_in; gss_buffer_desc tok_out, tok_in; - DATA_BLOB blob_out = data_blob(NULL, 0); - DATA_BLOB blob_in = data_blob(NULL, 0); + DATA_BLOB blob_out = data_blob_null; + DATA_BLOB blob_in = data_blob_null; char *host_princ_s = NULL; OM_uint32 ret_flags = 0; NTSTATUS status = NT_STATUS_OK; @@ -569,9 +569,9 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) { - DATA_BLOB blob_recv = data_blob(NULL, 0); - DATA_BLOB blob_send = data_blob(NULL, 0); - DATA_BLOB param_out = data_blob(NULL, 0); + DATA_BLOB blob_recv = data_blob_null; + DATA_BLOB blob_send = data_blob_null; + DATA_BLOB param_out = data_blob_null; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; fstring fqdn; const char *servicename; diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index d2494cac86..5ea5cf3011 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -542,7 +542,7 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, asn1_check_enumerated(&data, negResult); asn1_end_tag(&data); - *auth = data_blob(NULL,0); + *auth = data_blob_null; if (asn1_tag_remaining(&data)) { asn1_start_tag(&data,ASN1_CONTEXT(1)); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 2bc2183add..7368070985 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -299,13 +299,13 @@ NTSTATUS ntlmssp_update(NTLMSSP_STATE *ntlmssp_state, return NT_STATUS_INVALID_PARAMETER; } - *out = data_blob(NULL, 0); + *out = data_blob_null; if (!in.length && ntlmssp_state->stored_response.length) { input = ntlmssp_state->stored_response; /* we only want to read the stored response once - overwrite it */ - ntlmssp_state->stored_response = data_blob(NULL, 0); + ntlmssp_state->stored_response = data_blob_null; } else { input = in; } @@ -582,7 +582,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname, 0, ""); } else { - struct_blob = data_blob(NULL, 0); + struct_blob = data_blob_null; } { @@ -623,10 +623,10 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) { - DATA_BLOB encrypted_session_key = data_blob(NULL, 0); - DATA_BLOB user_session_key = data_blob(NULL, 0); - DATA_BLOB lm_session_key = data_blob(NULL, 0); - DATA_BLOB session_key = data_blob(NULL, 0); + DATA_BLOB encrypted_session_key = data_blob_null; + DATA_BLOB user_session_key = data_blob_null; + DATA_BLOB lm_session_key = data_blob_null; + DATA_BLOB session_key = data_blob_null; uint32 ntlmssp_command, auth_flags; NTSTATUS nt_status = NT_STATUS_OK; @@ -642,7 +642,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, char *workstation = NULL; /* parse the NTLMSSP packet */ - *reply = data_blob(NULL, 0); + *reply = data_blob_null; #if 0 file_save("ntlmssp_auth.dat", request.data, request.length); @@ -807,7 +807,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } else { DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM2 session key.\n")); - session_key = data_blob(NULL, 0); + session_key = data_blob_null; } } else if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) { if (lm_session_key.data && lm_session_key.length >= 8) { @@ -834,7 +834,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key.length); } else { DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n")); - session_key = data_blob(NULL, 0); + session_key = data_blob_null; } } else if (user_session_key.data) { session_key = user_session_key; @@ -846,7 +846,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, dump_data_pw("unmodified session key:\n", session_key.data, session_key.length); } else { DEBUG(10,("ntlmssp_server_auth: Failed to create unmodified session key.\n")); - session_key = data_blob(NULL, 0); + session_key = data_blob_null; } /* With KEY_EXCH, the client supplies the proposed session key, @@ -877,7 +877,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, } if (!NT_STATUS_IS_OK(nt_status)) { - ntlmssp_state->session_key = data_blob(NULL, 0); + ntlmssp_state->session_key = data_blob_null; } else if (ntlmssp_state->session_key.length) { nt_status = ntlmssp_sign_init(ntlmssp_state); } @@ -992,14 +992,14 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, uint32 chal_flags, ntlmssp_command, unkn1, unkn2; DATA_BLOB server_domain_blob; DATA_BLOB challenge_blob; - DATA_BLOB struct_blob = data_blob(NULL, 0); + DATA_BLOB struct_blob = data_blob_null; char *server_domain; const char *chal_parse_string; const char *auth_gen_string; - DATA_BLOB lm_response = data_blob(NULL, 0); - DATA_BLOB nt_response = data_blob(NULL, 0); - DATA_BLOB session_key = data_blob(NULL, 0); - DATA_BLOB encrypted_session_key = data_blob(NULL, 0); + DATA_BLOB lm_response = data_blob_null; + DATA_BLOB nt_response = data_blob_null; + DATA_BLOB session_key = data_blob_null; + DATA_BLOB encrypted_session_key = data_blob_null; NTSTATUS nt_status = NT_STATUS_OK; if (!msrpc_parse(&reply, "CdBd", diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index e71504867e..3d96fa5f1a 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -265,7 +265,7 @@ BOOL msrpc_parse(const DATA_BLOB *blob, b = (DATA_BLOB *)va_arg(ap, void *); if (len1 == 0 && len2 == 0) { - *b = data_blob(NULL, 0); + *b = data_blob_null; } else { /* make sure its in the right format - be strict */ if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index ad833374f3..2586128966 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -347,7 +347,7 @@ void SMBsesskeygen_lm_sess_key(const uchar lm_hash[16], DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, const char *domain) { - DATA_BLOB names_blob = data_blob(NULL, 0); + DATA_BLOB names_blob = data_blob_null; msrpc_gen(&names_blob, "aaa", NTLMSSP_NAME_TYPE_DOMAIN, domain, @@ -359,7 +359,7 @@ DATA_BLOB NTLMv2_generate_names_blob(const char *hostname, static DATA_BLOB NTLMv2_generate_client_data(const DATA_BLOB *names_blob) { uchar client_chal[8]; - DATA_BLOB response = data_blob(NULL, 0); + DATA_BLOB response = data_blob_null; char long_date[8]; generate_random_buffer(client_chal, sizeof(client_chal)); -- cgit From 00790cb8afaf768ba650ee40796ccdafc535ae8d Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 14 May 2007 14:19:30 +0000 Subject: r22850: - Fixes bug 4601. smbc_getxattr() would not, in one case, properly return the required size of a buffer needed to contain the extended attributes. (This used to be commit 34f77af02e2073ccaabe1583011abeeabbbb24e1) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 7a197f57f8..b1f073debc 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4699,7 +4699,7 @@ cacl_get(SMBCCTX *context, ace->access_mask); } } - if (n > bufsize) { + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; } -- cgit From 63f9607ea7d48ad4bd418fc1135d72215aa05c85 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 May 2007 13:56:00 +0000 Subject: r22905: cli_send_mailslot had a message_send_pid inside (This used to be commit 3fdfb5b7cdf25f4db7bbacb416523d75cab1b103) --- source3/libsmb/clidgram.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 2f64b2c05d..15125eb077 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -26,7 +26,8 @@ * cli_send_mailslot, send a mailslot for client code ... */ -BOOL cli_send_mailslot(BOOL unique, const char *mailslot, +BOOL cli_send_mailslot(struct messaging_context *msg_ctx, + BOOL unique, const char *mailslot, uint16 priority, char *buf, int len, const char *srcname, int src_type, @@ -104,9 +105,10 @@ BOOL cli_send_mailslot(BOOL unique, const char *mailslot, DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), inet_ntoa(dest_ip))); - return NT_STATUS_IS_OK(message_send_pid(pid_to_procid(nmbd_pid), - MSG_SEND_PACKET, &p, sizeof(p), - False)); + return NT_STATUS_IS_OK(messaging_send_buf(msg_ctx, + pid_to_procid(nmbd_pid), + MSG_SEND_PACKET, + (uint8 *)&p, sizeof(p))); } /* @@ -133,7 +135,8 @@ BOOL cli_get_response(const char *mailslot, char *buf, int bufsiz) static char cli_backup_list[1024]; -int cli_get_backup_list(const char *myname, const char *send_to_name) +int cli_get_backup_list(struct messaging_context *msg_ctx, + const char *myname, const char *send_to_name) { pstring outbuf; char *p; @@ -160,7 +163,7 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) SIVAL(p, 0, 1); /* The sender's token ... */ p += 4; - cli_send_mailslot(True, "\\MAILSLOT\\BROWSE", 1, outbuf, + cli_send_mailslot(msg_ctx, True, "\\MAILSLOT\\BROWSE", 1, outbuf, PTR_DIFF(p, outbuf), myname, 0, send_to_name, 0x1d, sendto_ip); @@ -179,16 +182,18 @@ int cli_get_backup_list(const char *myname, const char *send_to_name) * cli_get_backup_server: Get the backup list and retrieve a server from it */ -int cli_get_backup_server(char *my_name, char *target, char *servername, int namesize) +int cli_get_backup_server(struct messaging_context *msg_ctx, + char *my_name, char *target, char *servername, + int namesize) { /* Get the backup list first. We could pull this from the cache later */ - cli_get_backup_list(my_name, target); /* FIXME: Check the response */ + cli_get_backup_list(msg_ctx, my_name, target); /* FIXME: Check the response */ if (!cli_backup_list[0]) { /* Empty list ... try again */ - cli_get_backup_list(my_name, target); + cli_get_backup_list(msg_ctx, my_name, target); } -- cgit From 84758bd1f8633d3efe30e293887596db6bfd5e5b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 15 May 2007 15:14:32 +0000 Subject: r22908: All callers of message_init now also call messaging_init. Unify those. (This used to be commit 330946ad2307ca34f0a8d068a0193fcb8a0d6036) --- source3/libsmb/clidgram.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 15125eb077..2208378863 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -45,9 +45,6 @@ BOOL cli_send_mailslot(struct messaging_context *msg_ctx, return False; } - if (!message_init()) - return False; - memset((char *)&p, '\0', sizeof(p)); /* -- cgit From 4a413b304369df0650db8999ecdaff119582d5f7 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 15 May 2007 19:10:29 +0000 Subject: r22914: - Fixes bug 4599. A missing if statement forced subseqeuent attempts to set attributes to fail. - I also noticed that missing attributes were setting an invalid return string by getxattr(), e.g. if there was not group, the return string had "GROUP:;" instead of excluding the GROUP attribute entirely as it should. The big problem with the way it was, is that the string could not then be passed to setxattr() and parsed. (This used to be commit 7213b5ebec8cd7f1955f5aa8ee4050c39cd11ed1) --- source3/libsmb/libsmbclient.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b1f073debc..32f195547f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4546,7 +4546,7 @@ cacl_get(SMBCCTX *context, return -1; } n = strlen(p); - } else { + } else if (sidstr[0] != '\0') { n = snprintf(buf, bufsize, ",OWNER:%s", sidstr); } @@ -4591,7 +4591,7 @@ cacl_get(SMBCCTX *context, return -1; } n = strlen(p); - } else { + } else if (sidstr[0] != '\0') { n = snprintf(buf, bufsize, ",GROUP:%s", sidstr); } @@ -5317,7 +5317,9 @@ smbc_setxattr_ctx(SMBCCTX *context, ipc_srv = smbc_attr_server(context, server, share, workgroup, user, password, &pol); - srv->no_nt_session = True; + if (! ipc_srv) { + srv->no_nt_session = True; + } } else { ipc_srv = NULL; } @@ -5742,7 +5744,9 @@ smbc_removexattr_ctx(SMBCCTX *context, ipc_srv = smbc_attr_server(context, server, share, workgroup, user, password, &pol); - srv->no_nt_session = True; + if (! ipc_srv) { + srv->no_nt_session = True; + } } else { ipc_srv = NULL; } -- cgit From 32106b23951e01fb17f814584ebbcc8d7288cb75 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 00:07:38 +0000 Subject: r22920: Add in the UNIX capability for 24-bit readX, as discussed with the Apple guys and Linux kernel guys. Still looking at how to do writeX as there's no recvfile(). Jeremy. (This used to be commit a53268fb2082de586e2df250d8ddfcff53379102) --- source3/libsmb/clientgen.c | 127 +++++++++++++++++++++++++++++++++++++----- source3/libsmb/clifsinfo.c | 2 +- source3/libsmb/clireadwrite.c | 50 +++++++++++++---- source3/libsmb/smb_signing.c | 10 ++++ 4 files changed, 164 insertions(+), 25 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e1dacb3921..1a4b1f770f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. SMB client generic functions Copyright (C) Andrew Tridgell 1994-1998 + Copyright (C) Jeremy Allison 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -54,20 +55,20 @@ int cli_set_port(struct cli_state *cli, int port) should never go into a blocking read. ****************************************************************************/ -static BOOL client_receive_smb(struct cli_state *cli, BOOL eat_keepalives) +static ssize_t client_receive_smb(struct cli_state *cli, BOOL eat_keepalives, size_t maxlen) { - BOOL ret; + ssize_t len; int fd = cli->fd; char *buffer = cli->inbuf; unsigned int timeout = cli->timeout; for(;;) { - ret = receive_smb_raw(fd, buffer, timeout); + len = receive_smb_raw(fd, buffer, timeout, maxlen); - if (!ret) { + if (len < 0) { DEBUG(10,("client_receive_smb failed\n")); show_msg(buffer); - return ret; + return len; } /* Ignore session keepalive packets. */ @@ -85,11 +86,11 @@ static BOOL client_receive_smb(struct cli_state *cli, BOOL eat_keepalives) cli->smb_rw_error = READ_BAD_DECRYPT; close(cli->fd); cli->fd = -1; - return False; + return -1; } } show_msg(buffer); - return ret; + return len; } /**************************************************************************** @@ -98,21 +99,21 @@ static BOOL client_receive_smb(struct cli_state *cli, BOOL eat_keepalives) BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) { - BOOL ret; + ssize_t len; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) return False; again: - ret = client_receive_smb(cli, eat_keepalives); + len = client_receive_smb(cli, eat_keepalives, 0); - if (ret && !eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { + if (len >= 0 && !eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { /* Give back the keepalive. */ return True; } - if (ret) { + if (len > 0) { /* it might be an oplock break request */ if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && CVAL(cli->inbuf,smb_com) == SMBlockingX && @@ -121,7 +122,9 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) if (cli->oplock_handler) { int fnum = SVAL(cli->inbuf,smb_vwv2); unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); - if (!cli->oplock_handler(cli, fnum, level)) return False; + if (!cli->oplock_handler(cli, fnum, level)) { + return False; + } } /* try to prevent loops */ SCVAL(cli->inbuf,smb_com,0xFF); @@ -130,12 +133,12 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) } /* If the server is not responding, note that now */ - if (!ret) { + if (len <= 0) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); cli->smb_rw_error = smb_read_error; close(cli->fd); cli->fd = -1; - return ret; + return False; } if (!cli_check_sign_mac(cli)) { @@ -187,6 +190,102 @@ BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) return cli_receive_smb_internal(cli, False); } +/**************************************************************************** + Read the data portion of a readX smb. + The timeout is in milliseconds +****************************************************************************/ + +ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) +{ + if (cli->timeout > 0) { + return read_socket_with_timeout(cli->fd, buffer, len, len, cli->timeout); + } else { + return read_data(cli->fd, buffer, len); + } +} + +/**************************************************************************** + Read a smb readX header. + We can only use this if encryption and signing are off. +****************************************************************************/ + +BOOL cli_receive_smb_readX_header(struct cli_state *cli) +{ + ssize_t len, offset; + + if (cli->fd == -1) + return False; + + again: + + /* Read up to the size of a readX header reply. */ + len = client_receive_smb(cli, True, (smb_size - 4) + 24); + + if (len > 0) { + /* it might be an oplock break request */ + if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && + CVAL(cli->inbuf,smb_com) == SMBlockingX && + SVAL(cli->inbuf,smb_vwv6) == 0 && + SVAL(cli->inbuf,smb_vwv7) == 0) { + ssize_t total_len = smb_len(cli->inbuf); + + if (total_len > CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN) { + goto read_err; + } + + /* Read the rest of the data. */ + if (!cli_receive_smb_data(cli,cli->inbuf+len,total_len - len)) { + goto read_err; + } + + if (cli->oplock_handler) { + int fnum = SVAL(cli->inbuf,smb_vwv2); + unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); + if (!cli->oplock_handler(cli, fnum, level)) return False; + } + /* try to prevent loops */ + SCVAL(cli->inbuf,smb_com,0xFF); + goto again; + } + } + + /* Check it's a non-chained readX reply. */ + if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) || + (CVAL(cli->inbuf,smb_vwv0) != 0xFF) || + (CVAL(cli->inbuf,smb_com) != SMBreadX)) { + /* + * We're not coping here with asnyc replies to + * other calls. Punt here - we need async client + * libs for this. + */ + goto read_err; + } + + /* + * We know it's a readX reply - ensure we've read the + * padding bytes also. + */ + + offset = SVAL(cli->inbuf,smb_vwv6); + if (offset > len) { + ssize_t ret; + size_t padbytes = offset - len; + ret = cli_receive_smb_data(cli,smb_buf(cli->inbuf),padbytes); + if (ret != padbytes) { + goto read_err; + } + } + + return True; + + read_err: + + cli->smb_rw_error = smb_read_error = READ_ERROR; + close(cli->fd); + cli->fd = -1; + return False; +} + static ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index d8ada1a896..28facb511d 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -66,7 +66,7 @@ BOOL cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 * *pmajor = SVAL(rdata,0); *pminor = SVAL(rdata,2); - *pcaplow = IVAL(rdata,4); + cli->posix_capabilities = *pcaplow = IVAL(rdata,4); *pcaphigh = IVAL(rdata,8); /* todo: but not yet needed diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 1c72cb2942..35d2afe2e7 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -46,7 +46,7 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, SIVAL(cli->outbuf,smb_vwv3,offset); SSVAL(cli->outbuf,smb_vwv5,size); SSVAL(cli->outbuf,smb_vwv6,size); - SSVAL(cli->outbuf,smb_vwv7,((size >> 16) & 1)); + SSVAL(cli->outbuf,smb_vwv7,(size >> 16)); SSVAL(cli->outbuf,smb_mid,cli->mid + i); if (bigoffset) { @@ -63,9 +63,11 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { char *p; - int size2; - int readsize; + size_t size2; + size_t readsize; ssize_t total = 0; + /* We can only do direct reads if not signing. */ + BOOL direct_reads = !client_is_signing_on(cli); if (size == 0) return 0; @@ -75,7 +77,11 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ * rounded down to a multiple of 1024. */ - if (cli->capabilities & CAP_LARGE_READX) { + if (client_is_signing_on(cli) == False && + cli_encryption_on(cli) == False && + (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { + readsize = CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; + } else if (cli->capabilities & CAP_LARGE_READX) { if (cli->is_samba) { readsize = CLI_SAMBA_MAX_LARGE_READX_SIZE; } else { @@ -93,8 +99,13 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ if (!cli_issue_read(cli, fnum, offset, readsize, 0)) return -1; - if (!cli_receive_smb(cli)) - return -1; + if (direct_reads) { + if (!cli_receive_smb_readX_header(cli)) + return -1; + } else { + if (!cli_receive_smb(cli)) + return -1; + } /* Check for error. Make sure to check for DOS and NT errors. */ @@ -125,7 +136,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ } size2 = SVAL(cli->inbuf, smb_vwv5); - size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7) & 1)) << 16); + size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7))) << 16); if (size2 > readsize) { DEBUG(5,("server returned more than we wanted!\n")); @@ -135,10 +146,29 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return -1; } - /* Copy data into buffer */ + if (!direct_reads) { + /* Copy data into buffer */ + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf + total, p, size2); + } else { + /* Ensure the remaining data matches the return size. */ + ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6); - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - memcpy(buf + total, p, size2); + /* Ensure the size is correct. */ + if (toread != size2) { + DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n", + (int)toread, (unsigned int)size2 )); + return -1; + } + + /* Read data directly into buffer */ + toread = cli_receive_smb_data(cli,buf+total,size2); + if (toread != size2) { + DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n", + (int)toread, (unsigned int)size2 )); + return -1; + } + } total += size2; offset += size2; diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d3384ce365..30f41476e3 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -657,6 +657,16 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) return True; } +/*********************************************************** + Is client signing on ? +************************************************************/ + +BOOL client_is_signing_on(struct cli_state *cli) +{ + struct smb_sign_info *si = &cli->sign_info; + return si->doing_signing; +} + /*********************************************************** SMB signing - Server implementation - send the MAC. ************************************************************/ -- cgit From bfb863c57cd1b8fc16cf7cda3cc3989104b4246c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 01:34:22 +0000 Subject: r22924: Fix the build by correctly processing readX errors in the direct read case. Jeremy. (This used to be commit 6fe2ee3bd79fadfe43a9a84e03c398bd339259c1) --- source3/libsmb/clientgen.c | 46 +++++++++++++++++++++++++--------------------- 1 file changed, 25 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1a4b1f770f..9021d1a362 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -249,30 +249,34 @@ BOOL cli_receive_smb_readX_header(struct cli_state *cli) } } - /* Check it's a non-chained readX reply. */ - if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) || - (CVAL(cli->inbuf,smb_vwv0) != 0xFF) || - (CVAL(cli->inbuf,smb_com) != SMBreadX)) { + /* If it's not the above size it probably was an error packet. */ + + if ((len == (smb_size - 4) + 24) && !cli_is_error(cli)) { + /* Check it's a non-chained readX reply. */ + if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) || + (CVAL(cli->inbuf,smb_vwv0) != 0xFF) || + (CVAL(cli->inbuf,smb_com) != SMBreadX)) { + /* + * We're not coping here with asnyc replies to + * other calls. Punt here - we need async client + * libs for this. + */ + goto read_err; + } + /* - * We're not coping here with asnyc replies to - * other calls. Punt here - we need async client - * libs for this. + * We know it's a readX reply - ensure we've read the + * padding bytes also. */ - goto read_err; - } - /* - * We know it's a readX reply - ensure we've read the - * padding bytes also. - */ - - offset = SVAL(cli->inbuf,smb_vwv6); - if (offset > len) { - ssize_t ret; - size_t padbytes = offset - len; - ret = cli_receive_smb_data(cli,smb_buf(cli->inbuf),padbytes); - if (ret != padbytes) { - goto read_err; + offset = SVAL(cli->inbuf,smb_vwv6); + if (offset > len) { + ssize_t ret; + size_t padbytes = offset - len; + ret = cli_receive_smb_data(cli,smb_buf(cli->inbuf),padbytes); + if (ret != padbytes) { + goto read_err; + } } } -- cgit From cc5c058e5992ae8209caaf8ff63d03eff686ce50 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 May 2007 09:53:41 +0000 Subject: r22929: Attempt to fix some build farm failures: On port 139 the first successful packet gives len==0 from the server, so the = in if (len <= 0) { in line 136 of clientgen.c throws a failure. Jeremy, please fix this properly, I'm not merging this to 3_0_26 so that you can filter it when you merge. Volker (This used to be commit 9c5111d8c5064a43762d7d0146acff5e7691dafd) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 26 ++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 86834ad081..f13aa21fbd 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1347,7 +1347,7 @@ BOOL cli_session_request(struct cli_state *cli, cli_send_smb(cli); DEBUG(5,("Sent session request\n")); - if (!cli_receive_smb(cli)) + if (!cli_receive_sessionreply(cli)) return False; if (CVAL(cli->inbuf,0) == 0x84) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 9021d1a362..92a9678de5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -190,6 +190,32 @@ BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) return cli_receive_smb_internal(cli, False); } +/**************************************************************************** + Recv an smb session reply +****************************************************************************/ + +BOOL cli_receive_sessionreply(struct cli_state *cli) +{ + ssize_t len; + + /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ + if (cli->fd == -1) + return False; + + len = client_receive_smb(cli, False, 0); + + /* If the server is not responding, note that now */ + if (len < 0) { + DEBUG(0, ("Receiving SMB: Server stopped responding\n")); + cli->smb_rw_error = smb_read_error; + close(cli->fd); + cli->fd = -1; + return False; + } + + return True; +} + /**************************************************************************** Read the data portion of a readX smb. The timeout is in milliseconds -- cgit From e24acb681b0f0d3a04c1ae50e6c68369e5edc115 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 16 May 2007 10:59:04 +0000 Subject: r22930: Next attempt to get the build farm in line. Jeremy, please check this and merge if appropriate. (This used to be commit 0bdf4f1a5937abd0ef266700115d74396bc1629c) --- source3/libsmb/clientgen.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 92a9678de5..ef74de9f4b 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -260,7 +260,8 @@ BOOL cli_receive_smb_readX_header(struct cli_state *cli) } /* Read the rest of the data. */ - if (!cli_receive_smb_data(cli,cli->inbuf+len,total_len - len)) { + if ((total_len - len > 0) && + !cli_receive_smb_data(cli,cli->inbuf+len,total_len - len)) { goto read_err; } -- cgit From 478ccc150ba3b8c87ac67769c46be20a73d14096 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 May 2007 17:17:25 +0000 Subject: r22950: Fix the issue Volker reported here : "Attempt to fix some build farm failures: On port 139 the first successful packet gives len==0 from the server, so the = in if (len <= 0) { in line 136 of clientgen.c throws a failure." The irritating thing is that I already had it correct in SAMBA_3_0_26 and forgot to merge the change across. len == 0 is a valid return - I messed that up when converting client_receive_smb() to return a length rather than a BOOL. Doh ! Jeremy. (This used to be commit a398bdf08d9efac51af28aed29f2c0f151cd5aad) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 28 +--------------------------- 2 files changed, 2 insertions(+), 28 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f13aa21fbd..86834ad081 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1347,7 +1347,7 @@ BOOL cli_session_request(struct cli_state *cli, cli_send_smb(cli); DEBUG(5,("Sent session request\n")); - if (!cli_receive_sessionreply(cli)) + if (!cli_receive_smb(cli)) return False; if (CVAL(cli->inbuf,0) == 0x84) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ef74de9f4b..43211a6c5a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -133,7 +133,7 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) } /* If the server is not responding, note that now */ - if (len <= 0) { + if (len < 0) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); cli->smb_rw_error = smb_read_error; close(cli->fd); @@ -190,32 +190,6 @@ BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) return cli_receive_smb_internal(cli, False); } -/**************************************************************************** - Recv an smb session reply -****************************************************************************/ - -BOOL cli_receive_sessionreply(struct cli_state *cli) -{ - ssize_t len; - - /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) - return False; - - len = client_receive_smb(cli, False, 0); - - /* If the server is not responding, note that now */ - if (len < 0) { - DEBUG(0, ("Receiving SMB: Server stopped responding\n")); - cli->smb_rw_error = smb_read_error; - close(cli->fd); - cli->fd = -1; - return False; - } - - return True; -} - /**************************************************************************** Read the data portion of a readX smb. The timeout is in milliseconds -- cgit From 5217cff98570127422e87488f1115a3019aadc8f Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 18 May 2007 13:42:48 +0000 Subject: r23001: - Fix but #4634. Type of the size parameter to getpeername was wrong. (This used to be commit 6675c8acf1d83b7131d38f09f381062b6a604c7e) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 32f195547f..725916e737 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -500,7 +500,7 @@ static int smbc_check_server(SMBCCTX * context, SMBCSRV * server) { - size_t size; + socklen_t size; struct sockaddr addr; /* -- cgit From 94e4a468f02bc243b72c7e1ddd5a15facf661ae5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 24 May 2007 23:11:11 +0000 Subject: r23127: Fill in some more netlogon dsgetdcname flavours (netr_DsRGetDCNameEx, netr_DsRGetDCNameEx2) and add new ds request and reply flags, also add some more WERROR codes. Guenther (This used to be commit 37ae7f419702c563bcd0d9c27c02bde7efd34dd7) --- source3/libsmb/doserr.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 414c2d4916..022d9b6247 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -37,6 +37,7 @@ werror_code_struct dos_errs[] = { "WERR_BADFID", WERR_BADFID }, { "WERR_BADFUNC", WERR_BADFUNC }, { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, + { "WERR_SEM_TIMEOUT", WERR_SEM_TIMEOUT }, { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, { "WERR_ALREADY_EXISTS", WERR_ALREADY_EXISTS }, { "WERR_INVALID_PARAM", WERR_INVALID_PARAM }, @@ -59,6 +60,7 @@ werror_code_struct dos_errs[] = { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, + { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, @@ -67,7 +69,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, - { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, + { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, @@ -80,6 +82,8 @@ werror_code_struct dos_errs[] = { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, + { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE}, + { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS}, { NULL, W_ERROR(0) } }; -- cgit From 4d6caa09e2b8c1c26f3dde832586d871bbbc2dda Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 May 2007 23:50:35 +0000 Subject: r23148: Fix old old bug in cli_smbwrite() (not incrementing data being sent). Patch from mnix@wanm.com.au. Jeremy. (This used to be commit 2524d85465ba5406e684199c10f59e685ab860b5) --- source3/libsmb/clireadwrite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 35d2afe2e7..c31d417fbd 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -443,7 +443,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, p = smb_buf(cli->outbuf); *p++ = 1; SSVAL(p, 0, size); p += 2; - memcpy(p, buf, size); p += size; + memcpy(p, buf + total, size); p += size; cli_setup_bcc(cli, p); -- cgit From e8156439f24137b5418baad20a7f00f6949cfe29 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 May 2007 09:30:34 +0000 Subject: r23183: Check in a change made by Tridge: This replaces the internal explicit dev/ino file id representation by a "struct file_id". This is necessary as cluster file systems and NFS don't necessarily assign the same device number to the shared file system. With this structure in place we can now easily add different schemes to map a file to a unique 64-bit device node. Jeremy, you might note that I did not change the external interface of smb_share_modes.c. Volker (This used to be commit 9b10dbbd5de8813fc15ebbb6be9b18010ffe8139) --- source3/libsmb/smb_share_modes.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index da8d9e1fdc..89395fe373 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -137,8 +137,8 @@ static int share_mode_entry_equal(const struct smb_share_mode_entry *e_entry, e_entry->open_time.tv_usec == entry->time.tv_usec && e_entry->share_access == (uint32_t)entry->share_access && e_entry->access_mask == (uint32_t)entry->access_mask && - e_entry->dev == (uint64_t)entry->dev && - e_entry->ino == (uint64_t)entry->inode); + e_entry->dev == entry->id.devid && + e_entry->ino == entry->id.inode); } /* @@ -156,8 +156,8 @@ static void create_share_mode_entry(struct share_mode_entry *out, out->time.tv_usec = in->open_time.tv_usec; out->share_access = in->share_access; out->access_mask = in->access_mask; - out->dev = (SMB_DEV_T)in->dev; - out->inode = (SMB_INO_T)in->ino; + out->id.devid = in->dev; + out->id.inode = in->ino; out->uid = (uint32)geteuid(); out->flags = 0; } @@ -224,8 +224,8 @@ int smb_get_share_mode_entries(struct smbdb_ctx *db_ctx, } /* Copy into the external list. */ - sme->dev = (uint64_t)share->dev; - sme->ino = (uint64_t)share->inode; + sme->dev = share->id.devid; + sme->ino = share->id.inode; sme->share_access = (uint32_t)share->share_access; sme->access_mask = (uint32_t)share->access_mask; sme->open_time.tv_sec = share->time.tv_sec; -- cgit From 6426d8b4a0fceb352641e936e632bf5bb0f84525 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 May 2007 19:09:38 +0000 Subject: r23224: Move map_nt_error_from_unix to lib/errmap_unix.c. This function is useful even in binaries that don't link in libsmb (This used to be commit 52545d119277b42a46d13b5b031c85f47d96b84c) --- source3/libsmb/errormap.c | 63 ----------------------------------------------- 1 file changed, 63 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 33b75eece0..bb4154ee95 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1505,69 +1505,6 @@ WERROR ntstatus_to_werror(NTSTATUS error) return W_ERROR(NT_STATUS_V(error) & 0xffff); } -/* Mapping between Unix, DOS and NT error numbers */ - -const struct unix_error_map unix_dos_nt_errmap[] = { - { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, - { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, - { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY }, - { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, - { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, - { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, - { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, - { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, - { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, - { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, - { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY }, - { EISDIR, ERRDOS, ERRnoaccess, NT_STATUS_FILE_IS_A_DIRECTORY}, - { EMLINK, ERRDOS, ERRgeneral, NT_STATUS_TOO_MANY_LINKS }, -#ifdef EDQUOT - { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, /* Windows apps need this, not NT_STATUS_QUOTA_EXCEEDED */ -#endif -#ifdef ENOTEMPTY - { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, -#endif -#ifdef EXDEV - { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE }, -#endif -#ifdef EROFS - { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, -#endif -#ifdef ENAMETOOLONG - { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, -#endif -#ifdef EFBIG - { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, -#endif -#ifdef ENOBUFS - { ENOBUFS, ERRDOS, ERRnomem, NT_STATUS_INSUFFICIENT_RESOURCES }, -#endif - { 0, 0, 0, NT_STATUS_OK } -}; - -/********************************************************************* - Map an NT error code from a Unix error code. -*********************************************************************/ - -NTSTATUS map_nt_error_from_unix(int unix_error) -{ - int i = 0; - - if (unix_error == 0) - return NT_STATUS_OK; - - /* Look through list */ - while(unix_dos_nt_errmap[i].unix_error != 0) { - if (unix_dos_nt_errmap[i].unix_error == unix_error) - return unix_dos_nt_errmap[i].nt_error; - i++; - } - - /* Default return */ - return NT_STATUS_ACCESS_DENIED; -} - #if defined(HAVE_GSSAPI) /******************************************************************************* Map between gssapi errors and NT status. I made these up :-(. JRA. -- cgit From 902daae1c706e493b5c433dc729c6fd581613c91 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 4 Jun 2007 23:31:34 +0000 Subject: r23347: Fix Coverity 363. Dead code elimination. Jeremy. (This used to be commit 4524ee2dbcd5c1c66085032de67c6d083f91cb8a) --- source3/libsmb/clifile.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 61c4347b5b..64b3e652cf 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1692,13 +1692,9 @@ static BOOL cli_get_ea_list(struct cli_state *cli, goto out; } - if (num_eas) { - ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); - if (!ea_list) { - goto out; - } - } else { - ea_list = NULL; + ea_list = TALLOC_ARRAY(ctx, struct ea_struct, num_eas); + if (!ea_list) { + goto out; } ea_size = (size_t)IVAL(rdata,0); -- cgit From b1ce226af8b61ad7e3c37860a59c6715012e738b Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 15 Jun 2007 21:58:49 +0000 Subject: r23510: Tidy calls to smb_panic by removing trailing newlines. Print the failed expression in SMB_ASSERT. (This used to be commit 171dc060e2a576d724eed1ca65636bdafffd7713) --- source3/libsmb/cliquota.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 2a47ae2463..8bba453d52 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -54,8 +54,9 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, ZERO_STRUCT(qt); - if (!rdata||!offset||!pqt) - smb_panic("parse_quota_record: called with NULL POINTER!\n"); + if (!rdata||!offset||!pqt) { + smb_panic("parse_quota_record: called with NULL POINTER!"); + } if (rdata_count < 40) { return False; @@ -138,8 +139,9 @@ BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUC unsigned int sid_len; unsigned int offset; - if (!cli||!pqt) + if (!cli||!pqt) { smb_panic("cli_get_user_quota() called with NULL Pointer!"); + } setup = NT_TRANSACT_GET_USER_QUOTA; @@ -204,8 +206,9 @@ BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUC unsigned int sid_len; memset(data,'\0',112); - if (!cli||!pqt) + if (!cli||!pqt) { smb_panic("cli_set_user_quota() called with NULL Pointer!"); + } setup = NT_TRANSACT_SET_USER_QUOTA; @@ -265,8 +268,9 @@ BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST SMB_NTQUOTA_STRUCT qt; SMB_NTQUOTA_LIST *tmp_list_ent; - if (!cli||!pqt_list) + if (!cli||!pqt_list) { smb_panic("cli_list_user_quota() called with NULL Pointer!"); + } setup = NT_TRANSACT_GET_USER_QUOTA; @@ -419,8 +423,9 @@ BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_ST SMB_NTQUOTA_STRUCT qt; ZERO_STRUCT(qt); - if (!cli||!pqt) + if (!cli||!pqt) { smb_panic("cli_get_fs_quota_info() called with NULL Pointer!"); + } setup = TRANSACT2_QFSINFO; @@ -507,8 +512,9 @@ BOOL cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_ST ZERO_STRUCT(qt); memset(data,'\0',48); - if (!cli||!pqt) + if (!cli||!pqt) { smb_panic("cli_set_fs_quota_info() called with NULL Pointer!"); + } setup = TRANSACT2_SETFSINFO; @@ -577,8 +583,9 @@ static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric) void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric)) { - if (!qt) + if (!qt) { smb_panic("dump_ntquota() called with NULL pointer"); + } switch (qt->qtype) { case SMB_USER_FS_QUOTA_TYPE: -- cgit From ce02d0dfcbeeeec316578322257d998589090c6f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 20 Jun 2007 17:38:42 +0000 Subject: r23554: Fix bug #4711 by makeing cli_connect return an NTSTATUS. Long overdue fix.... Jeremy. (This used to be commit 073fdc5a58139796dbaa7ea9833dca5308f11282) --- source3/libsmb/cliconnect.c | 25 ++++++++++++------------- source3/libsmb/clidfs.c | 9 +++++++-- source3/libsmb/libsmbclient.c | 19 +++++++++++-------- source3/libsmb/passchange.c | 10 +++++----- 4 files changed, 35 insertions(+), 28 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 86834ad081..78386ce503 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1401,7 +1401,7 @@ BOOL cli_session_request(struct cli_state *cli, Open the client sockets. ****************************************************************************/ -BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) +NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) { int name_type = 0x20; char *p; @@ -1419,7 +1419,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) if (!ip || is_zero_ip(*ip)) { if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) { - return False; + return NT_STATUS_BAD_NETWORK_NAME; } if (ip) *ip = cli->dest_ip; } else { @@ -1444,12 +1444,12 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) if (cli->fd == -1) { DEBUG(1,("Error connecting to %s (%s)\n", ip?inet_ntoa(*ip):host,strerror(errno))); - return False; + return map_nt_error_from_unix(errno); } set_socket_options(cli->fd,user_socket_options); - return True; + return NT_STATUS_OK; } /** @@ -1503,15 +1503,12 @@ again: DEBUG(3,("Connecting to host=%s\n", dest_host)); - if (!cli_connect(cli, dest_host, &ip)) { - DEBUG(1,("cli_start_connection: failed to connect to %s (%s)\n", - nmb_namestr(&called), inet_ntoa(ip))); + nt_status = cli_connect(cli, dest_host, &ip); + if (!NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n", + nmb_namestr(&called), inet_ntoa(ip), nt_errstr(nt_status) )); cli_shutdown(cli); - if (is_zero_ip(ip)) { - return NT_STATUS_BAD_NETWORK_NAME; - } else { - return NT_STATUS_CONNECTION_REFUSED; - } + return nt_status; } if (retry) @@ -1656,6 +1653,7 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho } if (!cli_session_request(*ppcli, &calling, &called)) { + NTSTATUS status; struct nmb_name smbservername; make_nmb_name(&smbservername , "*SMBSERVER", 0x20); @@ -1685,7 +1683,8 @@ with error %s.\n", desthost, cli_errstr(*ppcli) )); return False; } - if (!cli_connect(*ppcli, desthost, pdest_ip) || + status = cli_connect(*ppcli, desthost, pdest_ip); + if (!NT_STATUS_IS_OK(status) || !cli_session_request(*ppcli, &calling, &smbservername)) { DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) )); diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 4009b98b41..d5e31b5eb8 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -69,6 +69,7 @@ static struct cli_state *do_connect( const char *server, const char *share, pstring servicename; char *sharename; fstring newserver, newshare; + NTSTATUS status; /* make a copy so we don't modify the global string 'service' */ pstrcpy(servicename, share); @@ -94,11 +95,15 @@ static struct cli_state *do_connect( const char *server, const char *share, ip = dest_ip; /* have to open a new connection */ - if (!(c=cli_initialise()) || (cli_set_port(c, port) != port) || - !cli_connect(c, server_n, &ip)) { + if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) { d_printf("Connection to %s failed\n", server_n); return NULL; } + status = cli_connect(c, server_n, &ip); + if (!NT_STATUS_IS_OK(status)) { + d_printf("Connection to %s failed (Error %s)\n", server_n, nt_errstr(status)); + return NULL; + } c->protocol = max_protocol; c->use_kerberos = use_kerberos; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 725916e737..c36bb21ff4 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -675,7 +675,8 @@ smbc_server(SMBCCTX *context, int port_try_first; int port_try_next; const char *username_used; - + NTSTATUS status; + zero_ip(&ip); ZERO_STRUCT(c); @@ -795,17 +796,19 @@ smbc_server(SMBCCTX *context, c->port = port_try_first; - if (!cli_connect(c, server_n, &ip)) { + status = cli_connect(c, server_n, &ip); + if (!NT_STATUS_IS_OK(status)) { /* First connection attempt failed. Try alternate port. */ c->port = port_try_next; - if (!cli_connect(c, server_n, &ip)) { - cli_shutdown(c); - errno = ETIMEDOUT; - return NULL; - } - } + status = cli_connect(c, server_n, &ip); + if (!NT_STATUS_IS_OK(status)) { + cli_shutdown(c); + errno = ETIMEDOUT; + return NULL; + } + } if (!cli_session_request(c, &calling, &called)) { cli_shutdown(c); diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 5b4b0896c0..bfa513d002 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -39,7 +39,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam *err_str = '\0'; if(!resolve_name( remote_machine, &ip, 0x20)) { - slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n", + slprintf(err_str, err_str_len-1, "Unable to find an IP address for machine %s.\n", remote_machine ); return NT_STATUS_UNSUCCESSFUL; } @@ -49,10 +49,10 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam return NT_STATUS_NO_MEMORY; } - if (!cli_connect(cli, remote_machine, &ip)) { - slprintf(err_str, err_str_len-1, "unable to connect to SMB server on machine %s. Error was : %s.\n", - remote_machine, cli_errstr(cli) ); - result = cli_nt_error(cli); + result = cli_connect(cli, remote_machine, &ip); + if (!NT_STATUS_IS_OK(result)) { + slprintf(err_str, err_str_len-1, "Unable to connect to SMB server on machine %s. Error was : %s.\n", + remote_machine, nt_errstr(result) ); cli_shutdown(cli); return result; } -- cgit From c66831e04b468743df8993edc68cd72ebb4a391d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Jun 2007 11:20:37 +0000 Subject: r23582: Fix event based krb5 ticket refreshing in winbindd. We were incorrectly using the renew_till timestamp instead of the renewed ticket's endtime to calculate the next refreshing date. Guenther (This used to be commit aa3511a5b5e6a96a02110a7ad0ab1d43e6d25766) --- source3/libsmb/clikrb5.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index a668d3b55c..078706d1db 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1134,7 +1134,7 @@ out: krb5_error_code smb_krb5_renew_ticket(const char *ccache_string, /* FILE:/tmp/krb5cc_0 */ const char *client_string, /* gd@BER.SUSE.DE */ const char *service_string, /* krbtgt/BER.SUSE.DE@BER.SUSE.DE */ - time_t *new_start_time) + time_t *expire_time) { krb5_error_code ret; krb5_context context = NULL; @@ -1189,8 +1189,8 @@ out: ret = krb5_cc_store_cred(context, ccache, &creds); - if (new_start_time) { - *new_start_time = (time_t) creds.times.renew_till; + if (expire_time) { + *expire_time = (time_t) creds.times.endtime; } krb5_free_cred_contents(context, &creds); @@ -1247,8 +1247,8 @@ out: ret = krb5_cc_store_cred(context, ccache, creds); - if (new_start_time) { - *new_start_time = (time_t) creds->times.renew_till; + if (expire_time) { + *expire_time = (time_t) creds->times.endtime; } krb5_free_cred_contents(context, &creds_in); -- cgit From 33c7b666adfa5c873ffd1461edca37b068dfddac Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Jun 2007 14:43:42 +0000 Subject: r23586: Fix heimdal path in the krb5 renew routine when we need to compose the tgt string ourselves. Guenther (This used to be commit 1e4a7af99303fb17ebca499ff7e0a017a2017754) --- source3/libsmb/clikrb5.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 078706d1db..0180bef47a 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1223,7 +1223,11 @@ out: } } else { /* build tgt service by default */ - client_realm = krb5_princ_realm(context, client); + client_realm = krb5_princ_realm(context, creds_in.client); + if (!client_realm) { + ret = ENOMEM; + goto done; + } ret = krb5_make_principal(context, &creds_in.server, *client_realm, KRB5_TGS_NAME, *client_realm, NULL); if (ret) { goto done; -- cgit From 679727b8df0b64cfe2e04111a41a3e512c1428c5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Jun 2007 14:50:15 +0000 Subject: r23587: Cleanup redundant code in the krb5 renew function. Guenther (This used to be commit 0b9acc8610ae2ba9c42168e9ceb2e9ea8bc2f5bd) --- source3/libsmb/clikrb5.c | 39 ++++++++++++++++----------------------- 1 file changed, 16 insertions(+), 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 0180bef47a..be6fb1bda8 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1159,22 +1159,22 @@ out: goto done; } + if (client_string) { + ret = smb_krb5_parse_name(context, client_string, &client); + if (ret) { + goto done; + } + } else { + ret = krb5_cc_get_principal(context, ccache, &client); + if (ret) { + goto done; + } + } + #ifdef HAVE_KRB5_GET_RENEWED_CREDS /* MIT */ { krb5_creds creds; - - if (client_string) { - ret = smb_krb5_parse_name(context, client_string, &client); - if (ret) { - goto done; - } - } else { - ret = krb5_cc_get_principal(context, ccache, &client); - if (ret) { - goto done; - } - } - + ret = krb5_get_renewed_creds(context, &creds, client, ccache, CONST_DISCARD(char *, service_string)); if (ret) { DEBUG(10,("smb_krb5_renew_ticket: krb5_get_kdc_cred failed: %s\n", error_message(ret))); @@ -1204,16 +1204,9 @@ out: memset(&creds_in, 0, sizeof(creds_in)); - if (client_string) { - ret = smb_krb5_parse_name(context, client_string, &creds_in.client); - if (ret) { - goto done; - } - } else { - ret = krb5_cc_get_principal(context, ccache, &creds_in.client); - if (ret) { - goto done; - } + ret = krb5_copy_principal(context, client, &creds_in.client); + if (ret) { + goto done; } if (service_string) { -- cgit From 32a3c30627fad859bc7fa218cc40e7b056bac30d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Jun 2007 14:54:39 +0000 Subject: r23588: Some more cleanups and error checks in the krb5 renew function. Guenther (This used to be commit 277e07c8553e2ed20bc95493cdc996be43feb6bd) --- source3/libsmb/clikrb5.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index be6fb1bda8..f452766e32 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1151,6 +1151,11 @@ out: ccache_string = krb5_cc_default_name(context); } + if (!ccache_string) { + ret = EINVAL; + goto done; + } + DEBUG(10,("smb_krb5_renew_ticket: using %s as ccache\n", ccache_string)); /* FIXME: we should not fall back to defaults */ @@ -1175,6 +1180,8 @@ out: { krb5_creds creds; + ZERO_STRUCT(creds); + ret = krb5_get_renewed_creds(context, &creds, client, ccache, CONST_DISCARD(char *, service_string)); if (ret) { DEBUG(10,("smb_krb5_renew_ticket: krb5_get_kdc_cred failed: %s\n", error_message(ret))); @@ -1202,7 +1209,7 @@ out: krb5_realm *client_realm; krb5_creds *creds; - memset(&creds_in, 0, sizeof(creds_in)); + ZERO_STRUCT(creds_in); ret = krb5_copy_principal(context, client, &creds_in.client); if (ret) { @@ -1252,7 +1259,7 @@ out: krb5_free_creds(context, creds); } #else -#error NO_SUITABKE_KRB5_TICKET_RENEW_FUNCTION_AVAILABLE +#error NO_SUITABLE_KRB5_TICKET_RENEW_FUNCTION_AVAILABLE #endif @@ -1260,15 +1267,14 @@ done: if (client) { krb5_free_principal(context, client); } - if (context) { - krb5_free_context(context); - } if (ccache) { krb5_cc_close(context, ccache); } + if (context) { + krb5_free_context(context); + } return ret; - } krb5_error_code smb_krb5_free_addresses(krb5_context context, smb_krb5_addresses *addr) -- cgit From 75f6a458b5d62f2d07e5f5dc121c72b6f26d0f65 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 26 Jun 2007 10:19:06 +0000 Subject: r23609: Removing more redundant codepaths out of smb_krb5_renew_ticket(). Thanks Volker for the pointer hint :) Guenther (This used to be commit eb1ec508ace3a5eeb53cf47be44047bd9228cd19) --- source3/libsmb/clikrb5.c | 64 ++++++++++++++++++++---------------------------- 1 file changed, 26 insertions(+), 38 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index f452766e32..1e322974cc 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1140,6 +1140,10 @@ out: krb5_context context = NULL; krb5_ccache ccache = NULL; krb5_principal client = NULL; + krb5_creds creds, creds_in, *creds_out = NULL; + + ZERO_STRUCT(creds); + ZERO_STRUCT(creds_in); initialize_krb5_error_table(); ret = krb5_init_context(&context); @@ -1178,38 +1182,16 @@ out: #ifdef HAVE_KRB5_GET_RENEWED_CREDS /* MIT */ { - krb5_creds creds; - - ZERO_STRUCT(creds); - ret = krb5_get_renewed_creds(context, &creds, client, ccache, CONST_DISCARD(char *, service_string)); if (ret) { DEBUG(10,("smb_krb5_renew_ticket: krb5_get_kdc_cred failed: %s\n", error_message(ret))); goto done; } - - /* hm, doesn't that create a new one if the old one wasn't there? - Guenther */ - ret = krb5_cc_initialize(context, ccache, client); - if (ret) { - goto done; - } - - ret = krb5_cc_store_cred(context, ccache, &creds); - - if (expire_time) { - *expire_time = (time_t) creds.times.endtime; - } - - krb5_free_cred_contents(context, &creds); } #elif defined(HAVE_KRB5_GET_KDC_CRED) /* Heimdal */ { krb5_kdc_flags flags; - krb5_creds creds_in; - krb5_realm *client_realm; - krb5_creds *creds; - - ZERO_STRUCT(creds_in); + krb5_realm *client_realm = NULL; ret = krb5_copy_principal(context, client, &creds_in.client); if (ret) { @@ -1237,33 +1219,39 @@ out: flags.i = 0; flags.b.renewable = flags.b.renew = True; - ret = krb5_get_kdc_cred(context, ccache, flags, NULL, NULL, &creds_in, &creds); + ret = krb5_get_kdc_cred(context, ccache, flags, NULL, NULL, &creds_in, &creds_out); if (ret) { DEBUG(10,("smb_krb5_renew_ticket: krb5_get_kdc_cred failed: %s\n", error_message(ret))); goto done; } - - /* hm, doesn't that create a new one if the old one wasn't there? - Guenther */ - ret = krb5_cc_initialize(context, ccache, creds_in.client); - if (ret) { - goto done; - } - - ret = krb5_cc_store_cred(context, ccache, creds); - if (expire_time) { - *expire_time = (time_t) creds->times.endtime; - } - - krb5_free_cred_contents(context, &creds_in); - krb5_free_creds(context, creds); + creds = *creds_out; } #else #error NO_SUITABLE_KRB5_TICKET_RENEW_FUNCTION_AVAILABLE #endif + /* hm, doesn't that create a new one if the old one wasn't there? - Guenther */ + ret = krb5_cc_initialize(context, ccache, client); + if (ret) { + goto done; + } + + ret = krb5_cc_store_cred(context, ccache, &creds); + + if (expire_time) { + *expire_time = (time_t) creds.times.endtime; + } done: + krb5_free_cred_contents(context, &creds_in); + + if (creds_out) { + krb5_free_creds(context, creds_out); + } else { + krb5_free_cred_contents(context, &creds); + } + if (client) { krb5_free_principal(context, client); } -- cgit From f09115f85cc315bde71df47bfb63f080e509dd72 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 27 Jun 2007 09:36:00 +0000 Subject: r23624: Merge dos error code from samba4 (returned from dfs_Enum against w2k3 as soon as a one DFS_VOLUME_FLAVOR_AD_BLOB dfsroot exists). Guenther (This used to be commit 837b0a14c430faa4e4cada03a1efe2823a7b2e2e) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 022d9b6247..7e386e9606 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -70,6 +70,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, + { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, -- cgit From 7eb828135bd7407851a10c32d57c404ecb030140 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 27 Jun 2007 11:42:17 +0000 Subject: r23627: Allow to pass down the lookup-level to rpccli_lsa_lookup_names(). Guenther (This used to be commit e9a7512a9f630340004913f1379452eea8a9b6ae) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c36bb21ff4..550c691a8d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3849,7 +3849,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, } if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx, - pol, 1, &str, NULL, &sids, + pol, 1, &str, NULL, 1, &sids, &types))) { result = False; goto done; -- cgit From a24867293257585260deb0587e7e1b710654843a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 09:42:14 +0000 Subject: r23649: Fix the build (by moving smb_krb5_open_keytab() to clikrb5.c). Guenther (This used to be commit 19020d19dca7f34be92c8c2ec49ae7dbde60f8c1) --- source3/libsmb/clikrb5.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 137 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 1e322974cc..5836fc34e0 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -4,7 +4,7 @@ Copyright (C) Andrew Tridgell 2001 Copyright (C) Luke Howard 2002-2003 Copyright (C) Andrew Bartlett 2005 - Copyright (C) Guenther Deschner 2005 + Copyright (C) Guenther Deschner 2005-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1544,6 +1544,142 @@ done: #endif } +/********************************************************************** + * Open a krb5 keytab with flags, handles readonly or readwrite access and + * allows to process non-default keytab names. + * @param context krb5_context + * @param keytab_name_req string + * @param write_access BOOL if writable keytab is required + * @param krb5_keytab pointer to krb5_keytab (close with krb5_kt_close()) + * @return krb5_error_code +**********************************************************************/ + +/* This MAX_NAME_LEN is a constant defined in krb5.h */ +#ifndef MAX_KEYTAB_NAME_LEN +#define MAX_KEYTAB_NAME_LEN 1100 +#endif + + krb5_error_code smb_krb5_open_keytab(krb5_context context, + const char *keytab_name_req, + BOOL write_access, + krb5_keytab *keytab) +{ + krb5_error_code ret = 0; + TALLOC_CTX *mem_ctx; + char keytab_string[MAX_KEYTAB_NAME_LEN]; + BOOL found_valid_name = False; + const char *pragma = "FILE"; + const char *tmp = NULL; + + if (!write_access && !keytab_name_req) { + /* caller just wants to read the default keytab readonly, so be it */ + return krb5_kt_default(context, keytab); + } + + mem_ctx = talloc_init("smb_krb5_open_keytab"); + if (!mem_ctx) { + return ENOMEM; + } + +#ifdef HAVE_WRFILE_KEYTAB + if (write_access) { + pragma = "WRFILE"; + } +#endif + + if (keytab_name_req) { + + if (strlen(keytab_name_req) > MAX_KEYTAB_NAME_LEN) { + ret = KRB5_CONFIG_NOTENUFSPACE; + goto out; + } + + if ((strncmp(keytab_name_req, "WRFILE:/", 8) == 0) || + (strncmp(keytab_name_req, "FILE:/", 6) == 0)) { + tmp = keytab_name_req; + goto resolve; + } + + if (keytab_name_req[0] != '/') { + ret = KRB5_KT_BADNAME; + goto out; + } + + tmp = talloc_asprintf(mem_ctx, "%s:%s", pragma, keytab_name_req); + if (!tmp) { + ret = ENOMEM; + goto out; + } + + goto resolve; + } + + /* we need to handle more complex keytab_strings, like: + * "ANY:FILE:/etc/krb5.keytab,krb4:/etc/srvtab" */ + + ret = krb5_kt_default_name(context, &keytab_string[0], MAX_KEYTAB_NAME_LEN - 2); + if (ret) { + goto out; + } + + DEBUG(10,("smb_krb5_open_keytab: krb5_kt_default_name returned %s\n", keytab_string)); + + tmp = talloc_strdup(mem_ctx, keytab_string); + if (!tmp) { + ret = ENOMEM; + goto out; + } + + if (strncmp(tmp, "ANY:", 4) == 0) { + tmp += 4; + } + + memset(&keytab_string, '\0', sizeof(keytab_string)); + + while (next_token(&tmp, keytab_string, ",", sizeof(keytab_string))) { + + if (strncmp(keytab_string, "WRFILE:", 7) == 0) { + found_valid_name = True; + tmp = keytab_string; + tmp += 7; + } + + if (strncmp(keytab_string, "FILE:", 5) == 0) { + found_valid_name = True; + tmp = keytab_string; + tmp += 5; + } + + if (found_valid_name) { + + if (tmp[0] != '/') { + ret = KRB5_KT_BADNAME; + goto out; + } + + tmp = talloc_asprintf(mem_ctx, "%s:%s", pragma, tmp); + if (!tmp) { + ret = ENOMEM; + goto out; + } + break; + } + } + + if (!found_valid_name) { + ret = KRB5_KT_UNKNOWN_TYPE; + goto out; + } + + resolve: + DEBUG(10,("smb_krb5_open_keytab: resolving: %s\n", tmp)); + ret = krb5_kt_resolve(context, tmp, keytab); + + out: + TALLOC_FREE(mem_ctx); + return ret; +} + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, -- cgit From 3b1956f9d2ad36dfc8c10a4ce22ee05a138bd2f9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 09:54:39 +0000 Subject: r23650: Fix remaining callers of krb5_kt_default(). Guenther (This used to be commit b9d7a2962a472afb0c6b8e3ac5c2c819d4af2b39) --- source3/libsmb/clikrb5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5836fc34e0..82796d39cc 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -951,10 +951,10 @@ get_key_from_keytab(krb5_context context, may be in the middle of a keytab enumeration when this is called. JRA. */ - ret = krb5_kt_default(context, &keytab); + ret = smb_krb5_open_keytab(context, NULL, False, &keytab); if (ret) { - DEBUG(0,("get_key_from_keytab: failed to open keytab: %s\n", error_message(ret))); - return ret; + DEBUG(1,("get_key_from_keytab: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); + goto out; } if ( DEBUGLEVEL >= 10 ) { -- cgit From 110e420196bcaf87d8d434b3680100d9b265a879 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 29 Jun 2007 09:58:11 +0000 Subject: r23651: Always, always, always compile before commit... Guenther (This used to be commit accb40446ad3f872c5167fc2306d892553293b7b) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 82796d39cc..96c18c3a8c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -954,7 +954,7 @@ get_key_from_keytab(krb5_context context, ret = smb_krb5_open_keytab(context, NULL, False, &keytab); if (ret) { DEBUG(1,("get_key_from_keytab: smb_krb5_open_keytab failed (%s)\n", error_message(ret))); - goto out; + return ret; } if ( DEBUGLEVEL >= 10 ) { -- cgit From 254e1ad28b095b54ac3df3c840c6a7f3b27da203 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 4 Jul 2007 22:30:25 +0000 Subject: r23710: Remove some code duplication, we do have a random number generator (This used to be commit afd7febd980bb000f81d5251d03d500cb43c39f4) --- source3/libsmb/namequery.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0826bc5218..bde24b4b90 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -145,15 +145,11 @@ char *saf_fetch( const char *domain ) static int generate_trn_id(void) { - static int trn_id; + uint16 id; - if (trn_id == 0) { - sys_srandom(sys_getpid()); - } - - trn_id = sys_random(); + generate_random_buffer((uint8 *)&id, sizeof(id)); - return trn_id % (unsigned)0x7FFF; + return id % (unsigned)0x7FFF; } /**************************************************************************** -- cgit From 4ce65137d927a1f464dcd8f3e5b7b13c71adda27 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 5 Jul 2007 13:46:47 +0000 Subject: r23723: Alexander Larsson pointed me at a missing mapping in clierror.c When renaming a file across 2 filesystem a samba server returns NT_STATUS_NOT_SAME_DEVICE but thius is not translated to EXDEV, and the generic EINVAL is returned instead. This should fix it, Jeremy or Derrel please check if this is ok. (This used to be commit b35038fa4e3e69f1397758497a46dc0d37edee79) --- source3/libsmb/clierror.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index d98f428217..90e82c5101 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -336,7 +336,9 @@ static const struct { #ifdef ECOMM {NT_STATUS_NET_WRITE_FAULT, ECOMM}, #endif - +#ifdef EXDEV + {NT_STATUS_NOT_SAME_DEVICE, EXDEV}, +#endif {NT_STATUS(0), 0} }; -- cgit From fcda5b589633b96415890c569bf23e3e284e0916 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jul 2007 16:33:37 +0000 Subject: r23726: Explicitly pass down the FLAGS2 field to srvstr_pull_buf. The next checkin will pull this up to srvstr_get_path. At that point we can get more independent of the inbuf, the base_ptr in pull_string will only be used to satisfy UCS2 alignment constraints. (This used to be commit 836782b07bf133e9b2598c4a089f1c810e4c7754) --- source3/libsmb/clistr.c | 4 +++- source3/libsmb/ntlmssp_parse.c | 21 ++++++++++++--------- source3/libsmb/smbencrypt.c | 3 ++- 3 files changed, 17 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 6191f99ea9..4d18434ff9 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -43,7 +43,9 @@ size_t clistr_pull_fn(const char *function, unsigned int line, int dest_len, int src_len, int flags) { - return pull_string_fn(function, line, cli->inbuf, dest, src, dest_len, src_len, flags); + return pull_string_fn(function, line, cli->inbuf, + SVAL(cli->inbuf, smb_flg2), dest, src, dest_len, + src_len, flags); } diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 3d96fa5f1a..a3977dbc01 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -220,9 +220,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, return False; if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_UNICODE|STR_NOALIGN); + pull_string( + NULL, 0, p, + blob->data + ptr, sizeof(p), + len1, STR_UNICODE|STR_NOALIGN); (*ps) = smb_xstrdup(p); } else { (*ps) = smb_xstrdup(""); @@ -248,9 +249,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, return False; if (0 < len1) { - pull_string(NULL, p, blob->data + ptr, sizeof(p), - len1, - STR_ASCII|STR_NOALIGN); + pull_string( + NULL, 0, p, + blob->data + ptr, sizeof(p), + len1, STR_ASCII|STR_NOALIGN); (*ps) = smb_xstrdup(p); } else { (*ps) = smb_xstrdup(""); @@ -300,9 +302,10 @@ BOOL msrpc_parse(const DATA_BLOB *blob, if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) return False; - head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); + head_ofs += pull_string( + NULL, 0, p, blob->data+head_ofs, sizeof(p), + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); if (strcmp(s, p) != 0) { return False; } diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 2586128966..4e8c5066a8 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -555,7 +555,8 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, } /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(NULL, new_pwrd, &in_buffer[512 - byte_len], new_pwrd_size, + *new_pw_len = pull_string(NULL, 0, new_pwrd, + &in_buffer[512 - byte_len], new_pwrd_size, byte_len, string_flags); #ifdef DEBUG_PASSWORD -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libsmb/asn1.c | 2 +- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clidfs.c | 2 +- source3/libsmb/clidgram.c | 2 +- source3/libsmb/clientgen.c | 2 +- source3/libsmb/clierror.c | 2 +- source3/libsmb/clifile.c | 2 +- source3/libsmb/clifsinfo.c | 2 +- source3/libsmb/clikrb5.c | 2 +- source3/libsmb/clilist.c | 2 +- source3/libsmb/climessage.c | 2 +- source3/libsmb/clioplock.c | 2 +- source3/libsmb/cliprint.c | 2 +- source3/libsmb/cliquota.c | 2 +- source3/libsmb/clirap.c | 2 +- source3/libsmb/clirap2.c | 2 +- source3/libsmb/clireadwrite.c | 2 +- source3/libsmb/clisecdesc.c | 2 +- source3/libsmb/clispnego.c | 2 +- source3/libsmb/clistr.c | 2 +- source3/libsmb/clitrans.c | 2 +- source3/libsmb/conncache.c | 2 +- source3/libsmb/credentials.c | 2 +- source3/libsmb/dcerpc_err.c | 2 +- source3/libsmb/doserr.c | 2 +- source3/libsmb/errormap.c | 2 +- source3/libsmb/libsmb_cache.c | 2 +- source3/libsmb/libsmb_compat.c | 2 +- source3/libsmb/libsmbclient.c | 2 +- source3/libsmb/namecache.c | 2 +- source3/libsmb/namequery.c | 2 +- source3/libsmb/namequery_dc.c | 2 +- source3/libsmb/nmblib.c | 2 +- source3/libsmb/nterr.c | 2 +- source3/libsmb/ntlm_check.c | 2 +- source3/libsmb/ntlmssp.c | 2 +- source3/libsmb/ntlmssp_parse.c | 2 +- source3/libsmb/ntlmssp_sign.c | 2 +- source3/libsmb/passchange.c | 2 +- source3/libsmb/pwd_cache.c | 2 +- source3/libsmb/samlogon_cache.c | 2 +- source3/libsmb/smb_seal.c | 2 +- source3/libsmb/smb_signing.c | 2 +- source3/libsmb/smbdes.c | 2 +- source3/libsmb/smbencrypt.c | 2 +- source3/libsmb/smberr.c | 2 +- source3/libsmb/spnego.c | 2 +- source3/libsmb/trustdom_cache.c | 2 +- source3/libsmb/trusts_util.c | 2 +- source3/libsmb/unexpected.c | 2 +- 50 files changed, 50 insertions(+), 50 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 6ebe9ab62c..abab5ce8e8 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 78386ce503..7c72c00673 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index d5e31b5eb8..9e66756a73 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 2208378863..68c8bed5bb 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 43211a6c5a..282ebb7cb9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 90e82c5101..8a66e397c5 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 64b3e652cf..0416ff2f37 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 28facb511d..ab0b2718fb 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 96c18c3a8c..73eefe749c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 8290a57742..74aa35945e 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 6850c4b8df..e0685958d4 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index c08bde0248..4d6a7aeb26 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index b09fb38906..818c69f08f 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 8bba453d52..4e06f1e339 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 5891120323..85d668e942 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 1730626066..45a89c775e 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index c31d417fbd..3ba9be58b6 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index e55be48e94..4e16b73e15 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 5ea5cf3011..aaa18a94bd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 4d18434ff9..d3aab42dc6 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index d7492b31c3..d7ce0743ca 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index b8ddcb2ba9..790ad47fa5 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 3243719d5c..674121ae29 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/dcerpc_err.c b/source3/libsmb/dcerpc_err.c index 7121ba396d..03e34ad191 100644 --- a/source3/libsmb/dcerpc_err.c +++ b/source3/libsmb/dcerpc_err.c @@ -4,7 +4,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 7e386e9606..363122e3be 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -5,7 +5,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index bb4154ee95..1de7115c8a 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -8,7 +8,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index fdde7acaf8..113b0de3e9 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index cfd5948e26..7b8993a19a 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 550c691a8d..f6c793a13b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 02956fa137..4cad944fae 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index bde24b4b90..a0aad79c64 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 65e860d45e..0469297605 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 5280dfdbff..b6dec4dc65 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 35ebc3d339..aa740066f1 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -5,7 +5,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index 1ce5d5e424..5059ce74ba 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 7368070985..fc1ac124b3 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index a3977dbc01..489e036221 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index a30535e2de..7c707dee4b 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -6,7 +6,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index bfa513d002..0c9c64ec78 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index a0f3383e29..72e2f707d2 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 106ff21dfe..c58f3b212d 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 81c6ff1bac..4ae819cf86 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 30f41476e3..039edecf72 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -6,7 +6,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index 8168eee207..bfebc7237a 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -8,7 +8,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 4e8c5066a8..7f909374f3 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 82a06bde2b..ffb6305190 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -4,7 +4,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index a2839578ae..a160be3ff2 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 57fcc1b248..8faadd5311 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -7,7 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index e4061883eb..4b9f3e9441 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -6,7 +6,7 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 5aee16e4c6..5e45710d10 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libsmb/asn1.c | 3 +-- source3/libsmb/cliconnect.c | 3 +-- source3/libsmb/clidfs.c | 3 +-- source3/libsmb/clidgram.c | 3 +-- source3/libsmb/clientgen.c | 3 +-- source3/libsmb/clierror.c | 3 +-- source3/libsmb/clifile.c | 3 +-- source3/libsmb/clifsinfo.c | 3 +-- source3/libsmb/clikrb5.c | 3 +-- source3/libsmb/clilist.c | 3 +-- source3/libsmb/climessage.c | 3 +-- source3/libsmb/clioplock.c | 3 +-- source3/libsmb/cliprint.c | 3 +-- source3/libsmb/cliquota.c | 3 +-- source3/libsmb/clirap.c | 3 +-- source3/libsmb/clirap2.c | 3 +-- source3/libsmb/clireadwrite.c | 3 +-- source3/libsmb/clisecdesc.c | 3 +-- source3/libsmb/clispnego.c | 3 +-- source3/libsmb/clistr.c | 3 +-- source3/libsmb/clitrans.c | 3 +-- source3/libsmb/conncache.c | 3 +-- source3/libsmb/credentials.c | 3 +-- source3/libsmb/libsmb_cache.c | 3 +-- source3/libsmb/libsmb_compat.c | 3 +-- source3/libsmb/libsmbclient.c | 3 +-- source3/libsmb/namecache.c | 3 +-- source3/libsmb/namequery.c | 3 +-- source3/libsmb/namequery_dc.c | 3 +-- source3/libsmb/nmblib.c | 3 +-- source3/libsmb/ntlm_check.c | 3 +-- source3/libsmb/ntlmssp.c | 3 +-- source3/libsmb/ntlmssp_parse.c | 3 +-- source3/libsmb/passchange.c | 3 +-- source3/libsmb/pwd_cache.c | 3 +-- source3/libsmb/samlogon_cache.c | 3 +-- source3/libsmb/smb_seal.c | 3 +-- source3/libsmb/smb_signing.c | 3 +-- source3/libsmb/smbdes.c | 3 +-- source3/libsmb/smbencrypt.c | 3 +-- source3/libsmb/smberr.c | 3 +-- source3/libsmb/spnego.c | 3 +-- source3/libsmb/trustdom_cache.c | 3 +-- source3/libsmb/unexpected.c | 3 +-- 44 files changed, 44 insertions(+), 88 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index abab5ce8e8..4d13207151 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7c72c00673..58f893b060 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 9e66756a73..d32629b139 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 68c8bed5bb..7a6ee17f4a 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 282ebb7cb9..29d4d9c334 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 8a66e397c5..374fdfa5e4 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 0416ff2f37..7e29c1bf1a 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index ab0b2718fb..48865c98ca 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 73eefe749c..c036d7a930 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #define KRB5_PRIVATE 1 /* this file uses PRIVATE interfaces! */ diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 74aa35945e..31012e6011 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index e0685958d4..252f2cd725 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index 4d6a7aeb26..041de41cad 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 818c69f08f..08737f87e4 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 4e06f1e339..47d8cfe5fe 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 85d668e942..801b6f61ec 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 45a89c775e..23113003f0 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ /*****************************************************/ diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 3ba9be58b6..7e479dc00a 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 4e16b73e15..27629ea96d 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index aaa18a94bd..f93cbcf39b 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index d3aab42dc6..7e6ad790fc 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index d7ce0743ca..752983377c 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index 790ad47fa5..c4a87623d7 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 674121ae29..80b18c6b99 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 113b0de3e9..b98df024fa 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 7b8993a19a..e0f2a90bd6 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f6c793a13b..90cde9100a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 4cad944fae..aeca5673c0 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index a0aad79c64..f0bef3ef96 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 0469297605..8c6e8e37af 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index b6dec4dc65..348555baf8 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index 5059ce74ba..dfc62c3070 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index fc1ac124b3..0c0744867d 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 489e036221..f17af38e8e 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 0c9c64ec78..cec150d8b2 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c index 72e2f707d2..071e729e8c 100644 --- a/source3/libsmb/pwd_cache.c +++ b/source3/libsmb/pwd_cache.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index c58f3b212d..c206922a5e 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 4ae819cf86..33352b85ce 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 039edecf72..3964bfa534 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -15,8 +15,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c index bfebc7237a..98d5cd05b7 100644 --- a/source3/libsmb/smbdes.c +++ b/source3/libsmb/smbdes.c @@ -17,8 +17,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 7f909374f3..f536383f4e 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index ffb6305190..1d81011d92 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -13,8 +13,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index a160be3ff2..d69d25c0db 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -17,8 +17,7 @@ You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 8faadd5311..37ad85ce0c 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 5e45710d10..6f85f36a62 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ -- cgit From 2c09988e46d4e917b1c53c9bda3f81a48bba4952 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 01:44:42 +0000 Subject: r23790: LGPLv3+ conversion for our LGPLv2+ library code (This used to be commit 1b78cace504f60c0f525765fbf59d9cc6506cd4d) --- source3/libsmb/smb_share_modes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 89395fe373..77368de23f 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -13,7 +13,7 @@ This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. + version 3 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of -- cgit From 9fa1c63578733077c0aaaeeb2fc97c3b191089cc Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 03:42:26 +0000 Subject: r23798: updated old Temple Place FSF addresses to new URL (This used to be commit c676a971142d7176fd5dbf21405fca14515a0a76) --- source3/libsmb/ntlmssp_sign.c | 3 +-- source3/libsmb/smb_share_modes.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 7c707dee4b..0e0a1c472f 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -15,8 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * along with this program; if not, see . */ #include "includes.h" diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index 77368de23f..b0cfc765d1 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -21,8 +21,7 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + License along with this library; if not, see . */ #include "includes.h" -- cgit From 153cfb9c83534b09f15cc16205d7adb19b394928 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 05:23:25 +0000 Subject: r23801: The FSF has moved around a lot. This fixes their Mass Ave address. (This used to be commit 87c91e4362c51819032bfbebbb273c52e203b227) --- source3/libsmb/dcerpc_err.c | 3 +-- source3/libsmb/doserr.c | 3 +-- source3/libsmb/errormap.c | 3 +-- source3/libsmb/nterr.c | 3 +-- source3/libsmb/trusts_util.c | 3 +-- 5 files changed, 5 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dcerpc_err.c b/source3/libsmb/dcerpc_err.c index 03e34ad191..b1874b943f 100644 --- a/source3/libsmb/dcerpc_err.c +++ b/source3/libsmb/dcerpc_err.c @@ -13,8 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, see . */ #include "includes.h" diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 363122e3be..23214e8d94 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, see . */ /* DOS error codes. please read doserr.h */ diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 1de7115c8a..412126eeca 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -17,8 +17,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, see . */ #include "includes.h" diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index aa740066f1..d88e650c9c 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -14,8 +14,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, see . */ /* NT error codes. please read nterr.h */ diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 4b9f3e9441..0922f9f41e 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -15,8 +15,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * along with this program; if not, see . */ #include "includes.h" -- cgit From 809c9d4d3136cc46dc228107918ca19d5a008a0a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 11:08:00 +0000 Subject: r23888: move elements belonging to the current ldap connection to a substructure. metze (This used to be commit 00909194a6c1ed193dfdb296f50f58a53450583c) --- source3/libsmb/namequery_dc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 8c6e8e37af..0c1207d4e5 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -106,7 +106,7 @@ static BOOL ads_dc_name(const char *domain, create_local_private_krb5_conf_for_domain(realm, domain, sitename, - ads->ldap_ip); + ads->ldap.ip); } #endif break; @@ -123,7 +123,7 @@ static BOOL ads_dc_name(const char *domain, fstrcpy(srv_name, ads->config.ldap_server_name); strupper_m(srv_name); - *dc_ip = ads->ldap_ip; + *dc_ip = ads->ldap.ip; ads_destroy(&ads); DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n", -- cgit From 57dd25cccbc0691dd4b84d2dca03497863b355ea Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 16 Jul 2007 14:35:33 +0000 Subject: r23893: add dummy callbacks for LDAP SASL wrapping, they're not used yet... metze (This used to be commit a3b97cdce719d9d5e82f26096c0e8c3a86ff3965) --- source3/libsmb/namequery_dc.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 0c1207d4e5..7dac69e2db 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -123,7 +123,11 @@ static BOOL ads_dc_name(const char *domain, fstrcpy(srv_name, ads->config.ldap_server_name); strupper_m(srv_name); +#ifdef HAVE_ADS *dc_ip = ads->ldap.ip; +#else + ZERO_STRUCT(*dc_ip); +#endif ads_destroy(&ads); DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n", -- cgit From 25a3427ef16f261cbfcf65abc367f55165676aaa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 21 Jul 2007 21:56:33 +0000 Subject: r23986: Some const (This used to be commit dc6f4bdb7f5fc0fd4cd9f687c47af3719985da8b) --- source3/libsmb/smb_signing.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 3964bfa534..d893af54f8 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -170,7 +170,9 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL null_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) +static BOOL null_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + BOOL must_be_ok) { return True; } @@ -217,7 +219,8 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(char *inbuf, struct smb_sign_info *si, BOOL good, uint32 seq, BOOL must_be_ok) +static BOOL signing_good(const char *inbuf, struct smb_sign_info *si, + BOOL good, uint32 seq, BOOL must_be_ok) { if (good) { @@ -375,7 +378,9 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL client_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) +static BOOL client_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + BOOL must_be_ok) { BOOL good; uint32 reply_seq_number; @@ -531,7 +536,8 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL temp_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL foo) +static BOOL temp_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, BOOL foo) { return True; } @@ -712,7 +718,9 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ -static BOOL srv_check_incoming_message(char *inbuf, struct smb_sign_info *si, BOOL must_be_ok) +static BOOL srv_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, + BOOL must_be_ok) { BOOL good; struct smb_basic_signing_context *data = -- cgit From ece86db24cd82b086de69e9681de4fb1f391cc2e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 22 Jul 2007 13:51:39 +0000 Subject: r23991: Some const (This used to be commit 804be77e4695eb923048948dbc6e223967fdef94) --- source3/libsmb/smb_signing.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d893af54f8..c5b1d44586 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -812,7 +812,7 @@ BOOL srv_oplock_set_signing(BOOL onoff) Called to validate an incoming packet from the client. ************************************************************/ -BOOL srv_check_sign_mac(char *inbuf, BOOL must_be_ok) +BOOL srv_check_sign_mac(const char *inbuf, BOOL must_be_ok) { /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) { -- cgit From b62bd05b93e2317f78a4aea089295cf1162d23e2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 2 Aug 2007 18:06:45 +0000 Subject: r24133: Explicitly pass flags2 down to push_string_fn This needs a bit closer review, it also touches the client libs (This used to be commit 824eb26738d64af1798d319d339582cf047521f0) --- source3/libsmb/clistr.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 7e6ad790fc..39315729c4 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -28,13 +28,21 @@ size_t clistr_push_fn(const char *function, unsigned int line, if (dest_len == -1) { if (((ptrdiff_t)dest < (ptrdiff_t)cli->outbuf) || (buf_used > cli->bufsize)) { DEBUG(0, ("Pushing string of 'unlimited' length into non-SMB buffer!\n")); - return push_string_fn(function, line, cli->outbuf, dest, src, -1, flags); + return push_string_fn(function, line, + cli->outbuf, + SVAL(cli->outbuf, smb_flg2), + dest, src, -1, flags); } - return push_string_fn(function, line, cli->outbuf, dest, src, cli->bufsize - buf_used, flags); + return push_string_fn(function, line, cli->outbuf, + SVAL(cli->outbuf, smb_flg2), + dest, src, cli->bufsize - buf_used, + flags); } /* 'normal' push into size-specified buffer */ - return push_string_fn(function, line, cli->outbuf, dest, src, dest_len, flags); + return push_string_fn(function, line, cli->outbuf, + SVAL(cli->outbuf, smb_flg2), + dest, src, dest_len, flags); } size_t clistr_pull_fn(const char *function, unsigned int line, -- cgit From c847b2afe7f4c979499c20869563439e25f0cb7e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 4 Aug 2007 20:08:35 +0000 Subject: r24223: Convert reply_echo to the new API (This used to be commit 4863ff2899419e791ed0e340821072d004fb1d17) --- source3/libsmb/clientgen.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 29d4d9c334..a23e0184d7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -680,9 +680,11 @@ BOOL cli_send_keepalive(struct cli_state *cli) Send/receive a SMBecho command: ping the server ****************************************************************************/ -BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) +BOOL cli_echo(struct cli_state *cli, uint16 num_echos, + unsigned char *data, size_t length) { char *p; + int i; SMB_ASSERT(length < 1024); @@ -690,7 +692,7 @@ BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) set_message(NULL,cli->outbuf,1,length,True); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); - SSVAL(cli->outbuf,smb_vwv0,1); + SSVAL(cli->outbuf,smb_vwv0,num_echos); cli_setup_packet(cli); p = smb_buf(cli->outbuf); memcpy(p, data, length); @@ -699,12 +701,16 @@ BOOL cli_echo(struct cli_state *cli, unsigned char *data, size_t length) cli_setup_bcc(cli, p); cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; - } - if (cli_is_error(cli)) { - return False; + for (i=0; i Date: Wed, 8 Aug 2007 23:56:55 +0000 Subject: r24281: Fix bug found by Herb. The vuid entry in the cli_state structure gets left as nonzero as returned by the failed cli_session_setup_spnego. When we then try to authenticate as the user in cli_session_setup this returns an error "Bad userid" (as seen in wireshark). "We should only leave cli->vuid != 0 on success. Looks like it's getting set in the cli_session_setup_blob_receive() call and not cleared again on error." Jeremy. (This used to be commit fa8e66dd8d2c68b91b27169c3c43820989f58758) --- source3/libsmb/cliconnect.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 58f893b060..c03097acc3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -583,6 +583,7 @@ static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B NT_STATUS_MORE_PROCESSING_REQUIRED)) { DEBUG(0, ("cli_session_setup_blob: recieve failed (%s)\n", nt_errstr(cli_get_nt_error(cli)) )); + cli->vuid = 0; return False; } } @@ -769,6 +770,9 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use ntlmssp_end(&ntlmssp_state); + if (!NT_STATUS_IS_OK(nt_status)) { + cli->vuid = 0; + } return nt_status; } -- cgit From 83fc92c82c6d6150661b3054047324f5318bbaa4 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 14 Aug 2007 03:02:34 +0000 Subject: r24388: - ACL retrieval provided incomplete information because the buffer pointer was incremented too far in some circumstances. In these cases, only the first of multiple concatenated strings would be seen. - Working on bug 4649 pertaining to delete an ACL, this fixes the reported crash. It appears to have been an incomplete switchover from malloc to talloc, as the memory was still being freed with SAFE_FREE. Deleting ACLs still doesn't work. Although a valid request is sent to the server and a SUCCESS response is returned, the method that's used in libsmbclient for deleting ACLs seems to be incorrect. In looking at the samba4 torture tests, it appears that we should be turning on the INHERIT flag if we want to delete the ACL. (I could use some assistance on the proper flags to send, from anyone familiar with this stuff.) - Apply patch from SATOH Fumiyasu to fix bug 4750. smbc_telldir_ctx() was not returning a value useful to smbc_lseekdir_ctx(). Derrell (This used to be commit 2ac502e29bd8390252fe4ae8344faab49ca01ff5) --- source3/libsmb/libsmbclient.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 90cde9100a..af619e8f3a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3434,8 +3434,6 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { - off_t ret_val; /* Squash warnings about cast */ - if (!context || !context->internal || !context->internal->_initialized) { @@ -3458,12 +3456,16 @@ smbc_telldir_ctx(SMBCCTX *context, } + /* See if we're already at the end. */ + if (dir->dir_next == NULL) { + /* We are. */ + return -1; + } + /* * We return the pointer here as the offset */ - ret_val = (off_t)(long)dir->dir_next; - return ret_val; - + return (off_t)(long)dir->dir_next->dirent; } /* @@ -4526,6 +4528,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_nt_owner) { @@ -4573,6 +4576,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_nt_group) { @@ -4618,6 +4622,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_nt_acl) { @@ -4708,6 +4713,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } } @@ -4782,6 +4788,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_dos_size) { @@ -4826,6 +4833,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_dos_create_time && @@ -4868,6 +4876,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_dos_access_time) { @@ -4909,6 +4918,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_dos_write_time) { @@ -4950,6 +4960,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_dos_change_time) { @@ -4991,6 +5002,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } if (! exclude_dos_inode) { @@ -5035,6 +5047,7 @@ cacl_get(SMBCCTX *context, buf += n; n_used += n; bufsize -= n; + n = 0; } /* Restore name pointer to its original value */ @@ -5129,8 +5142,8 @@ cacl_set(TALLOC_CTX *ctx, switch (mode) { case SMBC_XATTR_MODE_REMOVE_ALL: old->dacl->num_aces = 0; - SAFE_FREE(old->dacl->aces); - SAFE_FREE(old->dacl); + prs_mem_free(old->dacl->aces); + prs_mem_free(&old->dacl); old->dacl = NULL; dacl = old->dacl; break; @@ -5149,8 +5162,8 @@ cacl_set(TALLOC_CTX *ctx, } old->dacl->num_aces--; if (old->dacl->num_aces == 0) { - SAFE_FREE(old->dacl->aces); - SAFE_FREE(old->dacl); + prs_mem_free(&old->dacl->aces); + prs_mem_free(&old->dacl); old->dacl = NULL; } found = True; -- cgit From c638a84cb1215f9d67531c72959baf10deea2700 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 14 Aug 2007 14:27:42 +0000 Subject: r24410: - I got tricked by function naming. Contrary to what seemed obvious to me, prs_mem_free() is not the function to be called to free memory allocated by prs_alloc_mem(). I've added a comment so others may not get bitten too. - Remove incorrect memory free calls added yesterday to replace SAFE_FREE. The memory is actually now on a talloc context, so gets freed by the caller when that context is freed. We don't need to free it iternally. Derrell (This used to be commit 2fde343150c17959fc970b18e1eb4efde800b4db) --- source3/libsmb/libsmbclient.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index af619e8f3a..bcbdd5a15a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5142,8 +5142,6 @@ cacl_set(TALLOC_CTX *ctx, switch (mode) { case SMBC_XATTR_MODE_REMOVE_ALL: old->dacl->num_aces = 0; - prs_mem_free(old->dacl->aces); - prs_mem_free(&old->dacl); old->dacl = NULL; dacl = old->dacl; break; @@ -5162,8 +5160,6 @@ cacl_set(TALLOC_CTX *ctx, } old->dacl->num_aces--; if (old->dacl->num_aces == 0) { - prs_mem_free(&old->dacl->aces); - prs_mem_free(&old->dacl); old->dacl = NULL; } found = True; -- cgit From e60c0a5bff677e0626b6992b46b5a167cf14db1e Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 15 Aug 2007 13:44:44 +0000 Subject: r24462: - Removing all ACEs was causing removal of the DACL entirely. Win2000 ignored the request, presumably due to the PROTECTED flag not being set. Setting that flag (in make_sec_desc()) has much wider implications than just to libsmbclient, so instead of modifying that, we'll remove security descriptors by setting the number of ACEs to zero. At some point, we might want to look into whether we should actually be setting the PROTECTED flag in the DACL. Reference http://www.microsoft.com/technet/prodtechnol/windows2000serv/reskit/distrib/dsce_ctl_qxju.mspx?mfr=true Derrell (This used to be commit 319df380e579fd860348a8f08a584e13161dde9d) --- source3/libsmb/libsmbclient.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index bcbdd5a15a..8fd18bd99d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5142,7 +5142,6 @@ cacl_set(TALLOC_CTX *ctx, switch (mode) { case SMBC_XATTR_MODE_REMOVE_ALL: old->dacl->num_aces = 0; - old->dacl = NULL; dacl = old->dacl; break; @@ -5159,9 +5158,6 @@ cacl_set(TALLOC_CTX *ctx, old->dacl->aces[k+1]; } old->dacl->num_aces--; - if (old->dacl->num_aces == 0) { - old->dacl = NULL; - } found = True; dacl = old->dacl; break; -- cgit From 415b7463a3b543f4c7a1eab83162d65918337045 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 15 Aug 2007 17:40:26 +0000 Subject: r24466: - Sort ACEs according to http://support.microsoft.com/kb/269175 so that Windows Explorer doesn't complain about the order (and so that they get interpreted properly). Derrell (This used to be commit 8f371e2ea97a3b58d1c7c3aa1368a0904295f681) --- source3/libsmb/libsmbclient.c | 82 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 8fd18bd99d..fcc7c65a3a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3732,32 +3732,94 @@ smbc_utimes_ctx(SMBCCTX *context, } -/* The MSDN is contradictory over the ordering of ACE entries in an ACL. - However NT4 gives a "The information may have been modified by a - computer running Windows NT 5.0" if denied ACEs do not appear before - allowed ACEs. */ +/* + * Sort ACEs according to the documentation at + * http://support.microsoft.com/kb/269175, at least as far as it defines the + * order. + */ static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2) { - if (sec_ace_equal(ace1, ace2)) + BOOL b1; + BOOL b2; + + /* If the ACEs are equal, we have nothing more to do. */ + if (sec_ace_equal(ace1, ace2)) { return 0; + } + + /* Inherited follow non-inherited */ + b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); + b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * What shall we do with AUDITs and ALARMs? It's undefined. We'll + * sort them after DENY and ALLOW. + */ + b1 = (ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED && + ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && + ace1->type != SEC_ACE_TYPE_ACCESS_DENIED && + ace1->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + b2 = (ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED && + ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && + ace2->type != SEC_ACE_TYPE_ACCESS_DENIED && + ace2->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* Allowed ACEs follow denied ACEs */ + b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || + ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); + b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED || + ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } - if (ace1->type != ace2->type) + /* + * ACEs applying to an entity's object follow those applying to the + * entity itself + */ + b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace2->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * If we get this far, the ACEs are similar as far as the + * characteristics we typically care about (those defined by the + * referenced MS document). We'll now sort by characteristics that + * just seems reasonable. + */ + + if (ace1->type != ace2->type) { return ace2->type - ace1->type; + } - if (sid_compare(&ace1->trustee, &ace2->trustee)) + if (sid_compare(&ace1->trustee, &ace2->trustee)) { return sid_compare(&ace1->trustee, &ace2->trustee); + } - if (ace1->flags != ace2->flags) + if (ace1->flags != ace2->flags) { return ace1->flags - ace2->flags; + } - if (ace1->access_mask != ace2->access_mask) + if (ace1->access_mask != ace2->access_mask) { return ace1->access_mask - ace2->access_mask; + } - if (ace1->size != ace2->size) + if (ace1->size != ace2->size) { return ace1->size - ace2->size; + } return memcmp(ace1, ace2, sizeof(SEC_ACE)); } -- cgit From a2c3e56a499fd6fbeb29be62fbacd3c99c1b3028 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 18 Aug 2007 17:29:39 +0000 Subject: r24543: Apply missing portion of correction for bug 4750 (This used to be commit 5a83c306bb80b492a3c3d5e86b0767dc45e5c262) --- source3/libsmb/libsmbclient.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index fcc7c65a3a..dd3cbfc621 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -3536,6 +3536,11 @@ smbc_lseekdir_ctx(SMBCCTX *context, } + if (offset == -1) { /* Seek to the end of the list */ + dir->dir_next = NULL; + return 0; + } + /* Now, run down the list and make sure that the entry is OK */ /* This may need to be changed if we change the format of the list */ -- cgit From 1c72c4c360b6443f5b9705f2781fa9917492537e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 28 Aug 2007 14:20:53 +0000 Subject: r24737: Remove older TODO: Convert internal_resolve_name() and friends to NTSTATUS. Guenther (This used to be commit 8300aac4944613e411a78ab98de5d77f8fd38fa7) --- source3/libsmb/cliconnect.c | 3 +- source3/libsmb/namequery.c | 230 ++++++++++++++++++++++++++------------------ 2 files changed, 136 insertions(+), 97 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index c03097acc3..820a904ea4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1847,7 +1847,8 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user /* Go looking for workgroups by broadcasting on the local network */ - if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, + &count))) { DEBUG(99, ("No master browsers responded\n")); return False; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f0bef3ef96..77d259cfa6 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -777,17 +777,18 @@ static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_add Resolve via "bcast" method. *********************************************************/ -BOOL name_resolve_bcast(const char *name, int name_type, - struct ip_service **return_iplist, int *return_count) +NTSTATUS name_resolve_bcast(const char *name, int name_type, + struct ip_service **return_iplist, + int *return_count) { int sock, i; int num_interfaces = iface_count(); struct in_addr *ip_list; - BOOL ret; + NTSTATUS status; if (lp_disable_netbios()) { DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type)); - return False; + return NT_STATUS_INVALID_PARAMETER; } *return_iplist = NULL; @@ -802,7 +803,7 @@ BOOL name_resolve_bcast(const char *name, int name_type, sock = open_socket_in( SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True ); - if (sock == -1) return False; + if (sock == -1) return NT_STATUS_UNSUCCESSFUL; set_socket_options(sock,"SO_BROADCAST"); /* @@ -823,33 +824,34 @@ BOOL name_resolve_bcast(const char *name, int name_type, /* failed - no response */ close(sock); - return False; + return NT_STATUS_UNSUCCESSFUL; success: - ret = True; + status = NT_STATUS_OK; if ( !convert_ip2service(return_iplist, ip_list, *return_count) ) - ret = False; + status = NT_STATUS_INVALID_PARAMETER; SAFE_FREE( ip_list ); close(sock); - return ret; + return status; } /******************************************************** Resolve via "wins" method. *********************************************************/ -BOOL resolve_wins(const char *name, int name_type, - struct ip_service **return_iplist, int *return_count) +NTSTATUS resolve_wins(const char *name, int name_type, + struct ip_service **return_iplist, + int *return_count) { int sock, t, i; char **wins_tags; struct in_addr src_ip, *ip_list = NULL; - BOOL ret; + NTSTATUS status; if (lp_disable_netbios()) { DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type)); - return False; + return NT_STATUS_INVALID_PARAMETER; } *return_iplist = NULL; @@ -859,7 +861,7 @@ BOOL resolve_wins(const char *name, int name_type, if (wins_srv_count() < 1) { DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); - return False; + return NT_STATUS_INVALID_PARAMETER; } /* we try a lookup on each of the WINS tags in turn */ @@ -867,7 +869,7 @@ BOOL resolve_wins(const char *name, int name_type, if (!wins_tags) { /* huh? no tags?? give up in disgust */ - return False; + return NT_STATUS_INVALID_PARAMETER; } /* the address we will be sending from */ @@ -924,26 +926,27 @@ BOOL resolve_wins(const char *name, int name_type, } wins_srv_tags_free(wins_tags); - return False; + return NT_STATUS_NO_LOGON_SERVERS; success: - ret = True; + status = NT_STATUS_OK; if ( !convert_ip2service( return_iplist, ip_list, *return_count ) ) - ret = False; + status = NT_STATUS_INVALID_PARAMETER; SAFE_FREE( ip_list ); wins_srv_tags_free(wins_tags); close(sock); - return ret; + return status; } /******************************************************** Resolve via "lmhosts" method. *********************************************************/ -static BOOL resolve_lmhosts(const char *name, int name_type, - struct ip_service **return_iplist, int *return_count) +static NTSTATUS resolve_lmhosts(const char *name, int name_type, + struct ip_service **return_iplist, + int *return_count) { /* * "lmhosts" means parse the local lmhosts file. @@ -953,7 +956,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, pstring lmhost_name; int name_type2; struct in_addr return_ip; - BOOL result = False; + NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; *return_iplist = NULL; *return_count = 0; @@ -963,7 +966,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, fp = startlmhosts(dyn_LMHOSTSFILE); if ( fp == NULL ) - return False; + return NT_STATUS_NO_SUCH_FILE; while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) { @@ -980,7 +983,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, if ((*return_iplist) == NULL) { endlmhosts(fp); DEBUG(3,("resolve_lmhosts: malloc fail !\n")); - return False; + return NT_STATUS_NO_MEMORY; } (*return_iplist)[*return_count].ip = return_ip; @@ -988,7 +991,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, *return_count += 1; /* we found something */ - result = True; + status = NT_STATUS_OK; /* Multiple names only for DC lookup */ if (name_type != 0x1c) @@ -997,7 +1000,7 @@ static BOOL resolve_lmhosts(const char *name, int name_type, endlmhosts(fp); - return result; + return status; } @@ -1005,8 +1008,9 @@ static BOOL resolve_lmhosts(const char *name, int name_type, Resolve via "hosts" method. *********************************************************/ -static BOOL resolve_hosts(const char *name, int name_type, - struct ip_service **return_iplist, int *return_count) +static NTSTATUS resolve_hosts(const char *name, int name_type, + struct ip_service **return_iplist, + int *return_count) { /* * "host" means do a localhost, or dns lookup. @@ -1015,7 +1019,7 @@ static BOOL resolve_hosts(const char *name, int name_type, if ( name_type != 0x20 && name_type != 0x0) { DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type)); - return False; + return NT_STATUS_INVALID_PARAMETER; } *return_iplist = NULL; @@ -1029,23 +1033,24 @@ static BOOL resolve_hosts(const char *name, int name_type, *return_iplist = SMB_MALLOC_P(struct ip_service); if(*return_iplist == NULL) { DEBUG(3,("resolve_hosts: malloc fail !\n")); - return False; + return NT_STATUS_NO_MEMORY; } (*return_iplist)->ip = return_ip; (*return_iplist)->port = PORT_NONE; *return_count = 1; - return True; + return NT_STATUS_OK; } - return False; + return NT_STATUS_UNSUCCESSFUL; } /******************************************************** Resolve via "ADS" method. *********************************************************/ -static BOOL resolve_ads(const char *name, int name_type, - const char *sitename, - struct ip_service **return_iplist, int *return_count) +NTSTATUS resolve_ads(const char *name, int name_type, + const char *sitename, + struct ip_service **return_iplist, + int *return_count) { int i, j; NTSTATUS status; @@ -1054,25 +1059,36 @@ static BOOL resolve_ads(const char *name, int name_type, int numdcs = 0; int numaddrs = 0; - if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE)) - return False; - - DEBUG(5,("resolve_ads: Attempting to resolve DC's for %s using DNS\n", - name)); - + if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE)) { + return NT_STATUS_INVALID_PARAMETER; + } + if ( (ctx = talloc_init("resolve_ads")) == NULL ) { DEBUG(0,("resolve_ads: talloc_init() failed!\n")); - return False; + return NT_STATUS_NO_MEMORY; } - if (name_type == KDC_NAME_TYPE) { - status = ads_dns_query_kdcs(ctx, name, sitename, &dcs, &numdcs); - } else { - status = ads_dns_query_dcs(ctx, name, sitename, &dcs, &numdcs); + switch (name_type) { + case 0x1c: + DEBUG(5,("resolve_ads: Attempting to resolve " + "DCs for %s using DNS\n", name)); + status = ads_dns_query_dcs(ctx, name, sitename, &dcs, + &numdcs); + break; + case KDC_NAME_TYPE: + DEBUG(5,("resolve_ads: Attempting to resolve " + "KDCs for %s using DNS\n", name)); + status = ads_dns_query_kdcs(ctx, name, sitename, &dcs, + &numdcs); + break; + default: + status = NT_STATUS_INVALID_PARAMETER; + break; } + if ( !NT_STATUS_IS_OK( status ) ) { talloc_destroy(ctx); - return False; + return status; } for (i=0;iip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){ DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); SAFE_FREE(*return_iplist); - return False; + return NT_STATUS_INVALID_PARAMETER; } } else { (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0; } *return_count = 1; - return True; + return NT_STATUS_OK; } /* Check name cache */ if (namecache_fetch(name, name_type, return_iplist, return_count)) { /* This could be a negative response */ - return (*return_count > 0); + if (*return_count > 0) { + return NT_STATUS_OK; + } else { + return NT_STATUS_UNSUCCESSFUL; + } } /* set the name resolution order */ if ( strcmp( resolve_order, "NULL") == 0 ) { DEBUG(8,("internal_resolve_name: all lookups disabled\n")); - return False; + return NT_STATUS_INVALID_PARAMETER; } if ( !resolve_order ) { @@ -1214,44 +1234,55 @@ BOOL internal_resolve_name(const char *name, int name_type, while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { - if (resolve_hosts(name, name_type, return_iplist, return_count)) { - result = True; + status = resolve_hosts(name, name_type, return_iplist, + return_count); + if (NT_STATUS_IS_OK(status)) { goto done; } } else if(strequal( tok, "kdc")) { /* deal with KDC_NAME_TYPE names here. This will result in a SRV record lookup */ - if (resolve_ads(name, KDC_NAME_TYPE, sitename, return_iplist, return_count)) { - result = True; + status = resolve_ads(name, KDC_NAME_TYPE, sitename, + return_iplist, return_count); + if (NT_STATUS_IS_OK(status)) { /* Ensure we don't namecache this with the KDC port. */ name_type = KDC_NAME_TYPE; goto done; } } else if(strequal( tok, "ads")) { - /* deal with 0x1c names here. This will result in a + /* deal with 0x1c and 0x1b names here. This will result in a SRV record lookup */ - if (resolve_ads(name, name_type, sitename, return_iplist, return_count)) { - result = True; + status = resolve_ads(name, name_type, sitename, + return_iplist, return_count); + if (NT_STATUS_IS_OK(status)) { goto done; } } else if(strequal( tok, "lmhosts")) { - if (resolve_lmhosts(name, name_type, return_iplist, return_count)) { - result = True; + status = resolve_lmhosts(name, name_type, + return_iplist, return_count); + if (NT_STATUS_IS_OK(status)) { goto done; } } else if(strequal( tok, "wins")) { /* don't resolve 1D via WINS */ - if (name_type != 0x1D && resolve_wins(name, name_type, return_iplist, return_count)) { - result = True; - goto done; + if (name_type != 0x1D) { + status = resolve_wins(name, name_type, + return_iplist, + return_count); + if (NT_STATUS_IS_OK(status)) { + goto done; + } } } else if(strequal( tok, "bcast")) { - if (name_resolve_bcast(name, name_type, return_iplist, return_count)) { - result = True; + status = name_resolve_bcast(name, name_type, + return_iplist, + return_count); + if (NT_STATUS_IS_OK(status)) { goto done; } } else { - DEBUG(0,("resolve_name: unknown name switch type %s\n", tok)); + DEBUG(0,("resolve_name: unknown name switch type %s\n", + tok)); } } @@ -1260,7 +1291,7 @@ BOOL internal_resolve_name(const char *name, int name_type, SAFE_FREE(*return_iplist); *return_count = 0; - return False; + return NT_STATUS_UNSUCCESSFUL; done: @@ -1293,7 +1324,7 @@ BOOL internal_resolve_name(const char *name, int name_type, DEBUG(10, ("\n")); } - return result; + return status; } /******************************************************** @@ -1315,7 +1346,9 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) return True; } - if (internal_resolve_name(name, name_type, sitename, &ip_list, &count, lp_name_resolve_order())) { + if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename, + &ip_list, &count, + lp_name_resolve_order()))) { int i; /* only return valid addresses for TCP connections */ @@ -1346,18 +1379,24 @@ BOOL find_master_ip(const char *group, struct in_addr *master_ip) { struct ip_service *ip_list = NULL; int count = 0; + NTSTATUS status; if (lp_disable_netbios()) { DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group)); return False; } - if (internal_resolve_name(group, 0x1D, NULL, &ip_list, &count, lp_name_resolve_order())) { + status = internal_resolve_name(group, 0x1D, NULL, &ip_list, &count, + lp_name_resolve_order()); + if (NT_STATUS_IS_OK(status)) { *master_ip = ip_list[0].ip; SAFE_FREE(ip_list); return True; } - if(internal_resolve_name(group, 0x1B, NULL, &ip_list, &count, lp_name_resolve_order())) { + + status = internal_resolve_name(group, 0x1B, NULL, &ip_list, &count, + lp_name_resolve_order()); + if (NT_STATUS_IS_OK(status)) { *master_ip = ip_list[0].ip; SAFE_FREE(ip_list); return True; @@ -1376,10 +1415,14 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) { struct ip_service *ip_list = NULL; int count = 0; + NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; /* Look up #1B name */ - if (!internal_resolve_name(domain, 0x1b, NULL, &ip_list, &count, lp_name_resolve_order())) { + status = internal_resolve_name(domain, 0x1b, NULL, &ip_list, + &count, + lp_name_resolve_order()); + if (!NT_STATUS_IS_OK(status)) { return False; } @@ -1423,6 +1466,7 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ struct ip_service *auto_ip_list = NULL; BOOL done_auto_lookup = False; int auto_count = 0; + NTSTATUS status; *ordered = False; @@ -1471,14 +1515,8 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ if ( !*pserver ) { DEBUG(10,("get_dc_list: no preferred domain controllers.\n")); - /* TODO: change return type of internal_resolve_name to - * NTSTATUS */ - if (internal_resolve_name(domain, 0x1C, sitename, ip_list, count, - resolve_order)) { - return NT_STATUS_OK; - } else { - return NT_STATUS_NO_LOGON_SERVERS; - } + return internal_resolve_name(domain, 0x1C, sitename, ip_list, + count, resolve_order); } DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver )); @@ -1493,9 +1531,13 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ p = pserver; while (next_token(&p,name,LIST_SEP,sizeof(name))) { if (strequal(name, "*")) { - if (internal_resolve_name(domain, 0x1C, sitename, &auto_ip_list, - &auto_count, resolve_order)) + status = internal_resolve_name(domain, 0x1C, sitename, + &auto_ip_list, + &auto_count, + resolve_order); + if (NT_STATUS_IS_OK(status)) { num_addresses += auto_count; + } done_auto_lookup = True; DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); } else { @@ -1512,12 +1554,8 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ SAFE_FREE(auto_ip_list); return NT_STATUS_NO_LOGON_SERVERS; } - if (internal_resolve_name(domain, 0x1C, sitename, ip_list, count, - resolve_order)) { - return NT_STATUS_OK; - } else { - return NT_STATUS_NO_LOGON_SERVERS; - } + return internal_resolve_name(domain, 0x1C, sitename, ip_list, + count, resolve_order); } if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { -- cgit From 22cf5a3f8086b8f823fa5c45bce4432df825b92c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 28 Aug 2007 14:27:48 +0000 Subject: r24739: With resolve_ads() allow to query for PDCs as well. Also add dns query functions to find GCs and DCs by GUID. Guenther (This used to be commit cc469157f6684ec507bf1c3a659fc36a53d304a1) --- source3/libsmb/namequery.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 77d259cfa6..49e3375f50 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1059,7 +1059,8 @@ NTSTATUS resolve_ads(const char *name, int name_type, int numdcs = 0; int numaddrs = 0; - if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE)) { + if ((name_type != 0x1c) && (name_type != KDC_NAME_TYPE) && + (name_type != 0x1b)) { return NT_STATUS_INVALID_PARAMETER; } @@ -1069,6 +1070,12 @@ NTSTATUS resolve_ads(const char *name, int name_type, } switch (name_type) { + case 0x1b: + DEBUG(5,("resolve_ads: Attempting to resolve " + "PDC for %s using DNS\n", name)); + status = ads_dns_query_pdc(ctx, name, &dcs, &numdcs); + break; + case 0x1c: DEBUG(5,("resolve_ads: Attempting to resolve " "DCs for %s using DNS\n", name)); @@ -1419,11 +1426,18 @@ BOOL get_pdc_ip(const char *domain, struct in_addr *ip) /* Look up #1B name */ - status = internal_resolve_name(domain, 0x1b, NULL, &ip_list, - &count, - lp_name_resolve_order()); - if (!NT_STATUS_IS_OK(status)) { - return False; + if (lp_security() == SEC_ADS) { + status = internal_resolve_name(domain, 0x1b, NULL, &ip_list, + &count, "ads"); + } + + if (!NT_STATUS_IS_OK(status) || count == 0) { + status = internal_resolve_name(domain, 0x1b, NULL, &ip_list, + &count, + lp_name_resolve_order()); + if (!NT_STATUS_IS_OK(status)) { + return False; + } } /* if we get more than 1 IP back we have to assume it is a -- cgit From 84bce05e71720a54aa87900bd6550576317d52cb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 28 Aug 2007 15:01:23 +0000 Subject: r24742: Add experimental DsGetDcName() call (will be used by krb5 locator for fine grained KDC DNS queries). Guenther (This used to be commit 3263cd680fe429430d789b284464fca72ef45719) --- source3/libsmb/dsgetdcname.c | 955 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 955 insertions(+) create mode 100644 source3/libsmb/dsgetdcname.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c new file mode 100644 index 0000000000..6f4961b3c3 --- /dev/null +++ b/source3/libsmb/dsgetdcname.c @@ -0,0 +1,955 @@ +/* + Unix SMB/CIFS implementation. + + DsGetDcname + + Copyright (C) Gerald Carter 2006 + Copyright (C) Guenther Deschner 2007 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +#define DSGETDCNAME_FMT "DSGETDCNAME/DOMAIN/%s" +/* 15 minutes */ +#define DSGETDCNAME_CACHE_TTL 60*15 + +struct ip_service_name { + struct in_addr ip; + unsigned port; + const char *hostname; +}; + +/**************************************************************** +****************************************************************/ + +void debug_dsdcinfo_flags(int lvl, uint32_t flags) +{ + DEBUG(lvl,("debug_dsdcinfo_flags: 0x%08x\n\t", flags)); + + if (flags & DS_FORCE_REDISCOVERY) + DEBUGADD(lvl,("DS_FORCE_REDISCOVERY ")); + if (flags & 0x000000002) + DEBUGADD(lvl,("0x00000002 ")); + if (flags & 0x000000004) + DEBUGADD(lvl,("0x00000004 ")); + if (flags & 0x000000008) + DEBUGADD(lvl,("0x00000008 ")); + if (flags & DS_DIRECTORY_SERVICE_REQUIRED) + DEBUGADD(lvl,("DS_DIRECTORY_SERVICE_REQUIRED ")); + if (flags & DS_DIRECTORY_SERVICE_PREFERRED) + DEBUGADD(lvl,("DS_DIRECTORY_SERVICE_PREFERRED ")); + if (flags & DS_GC_SERVER_REQUIRED) + DEBUGADD(lvl,("DS_GC_SERVER_REQUIRED ")); + if (flags & DS_PDC_REQUIRED) + DEBUGADD(lvl,("DS_PDC_REQUIRED ")); + if (flags & DS_BACKGROUND_ONLY) + DEBUGADD(lvl,("DS_BACKGROUND_ONLY ")); + if (flags & DS_IP_REQUIRED) + DEBUGADD(lvl,("DS_IP_REQUIRED ")); + if (flags & DS_KDC_REQUIRED) + DEBUGADD(lvl,("DS_KDC_REQUIRED ")); + if (flags & DS_TIMESERV_REQUIRED) + DEBUGADD(lvl,("DS_TIMESERV_REQUIRED ")); + if (flags & DS_WRITABLE_REQUIRED) + DEBUGADD(lvl,("DS_WRITABLE_REQUIRED ")); + if (flags & DS_GOOD_TIMESERV_PREFERRED) + DEBUGADD(lvl,("DS_GOOD_TIMESERV_PREFERRED ")); + if (flags & DS_AVOID_SELF) + DEBUGADD(lvl,("DS_AVOID_SELF ")); + if (flags & DS_ONLY_LDAP_NEEDED) + DEBUGADD(lvl,("DS_ONLY_LDAP_NEEDED ")); + if (flags & 0x00010000) + DEBUGADD(lvl,("0x00010000 ")); + if (flags & 0x00020000) + DEBUGADD(lvl,("0x00020000 ")); + if (flags & 0x00040000) + DEBUGADD(lvl,("0x00040000 ")); + if (flags & 0x00080000) + DEBUGADD(lvl,("0x00080000 ")); + if (flags & DS_IS_FLAT_NAME) + DEBUGADD(lvl,("DS_IS_FLAT_NAME ")); + if (flags & DS_IS_DNS_NAME) + DEBUGADD(lvl,("DS_IS_DNS_NAME ")); + if (flags & 0x00040000) + DEBUGADD(lvl,("0x00040000 ")); + if (flags & 0x00080000) + DEBUGADD(lvl,("0x00080000 ")); + if (flags & 0x00100000) + DEBUGADD(lvl,("0x00100000 ")); + if (flags & 0x00200000) + DEBUGADD(lvl,("0x00200000 ")); + if (flags & 0x00400000) + DEBUGADD(lvl,("0x00400000 ")); + if (flags & 0x00800000) + DEBUGADD(lvl,("0x00800000 ")); + if (flags & 0x01000000) + DEBUGADD(lvl,("0x01000000 ")); + if (flags & 0x02000000) + DEBUGADD(lvl,("0x02000000 ")); + if (flags & 0x04000000) + DEBUGADD(lvl,("0x04000000 ")); + if (flags & 0x08000000) + DEBUGADD(lvl,("0x08000000 ")); + if (flags & 0x10000000) + DEBUGADD(lvl,("0x10000000 ")); + if (flags & 0x20000000) + DEBUGADD(lvl,("0x20000000 ")); + if (flags & DS_RETURN_DNS_NAME) + DEBUGADD(lvl,("DS_RETURN_DNS_NAME ")); + if (flags & DS_RETURN_FLAT_NAME) + DEBUGADD(lvl,("DS_RETURN_FLAT_NAME ")); + if (flags) + DEBUGADD(lvl,("\n")); +} + +/********************************************************************* + ********************************************************************/ + +static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, + unsigned char **buf) +{ + unsigned char *buffer = NULL; + int len = 0; + int buflen = 0; + UUID_FLAT guid_flat; + + DEBUG(10,("pack_dsdcinfo: Packing dsdcinfo\n")); + + ZERO_STRUCT(guid_flat); + + if (info->domain_guid) { + const struct GUID *guid = info->domain_guid; + smb_uuid_pack(*guid, &guid_flat); + } + + again: + len = 0; + + if (buflen > 0) { + DEBUG(10,("pack_dsdcinfo: Packing domain %s (%s)\n", + info->domain_name, info->domain_controller_name)); + } + + len += tdb_pack(buffer+len, buflen-len, "ffdBffdff", + info->domain_controller_name, + info->domain_controller_address, + info->domain_controller_address_type, + UUID_FLAT_SIZE, guid_flat.info, + info->domain_name, + info->dns_forest_name, + info->flags, + info->dc_site_name, + info->client_site_name); + + if (buflen < len) { + SAFE_FREE(buffer); + if ((buffer = SMB_MALLOC_ARRAY(unsigned char, len)) == NULL ) { + DEBUG(0,("pack_dsdcinfo: failed to alloc buffer!\n")); + buflen = -1; + goto done; + } + buflen = len; + goto again; + } + + *buf = buffer; + + done: + return buflen; +} + +/********************************************************************* + ********************************************************************/ + +static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, + unsigned char *buf, + int buflen, + struct DS_DOMAIN_CONTROLLER_INFO **info_ret) +{ + int len = 0; + struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + uint32_t guid_len = 0; + unsigned char *guid_buf = NULL; + UUID_FLAT guid_flat; + + /* forgive me 6 times */ + fstring domain_controller_name; + fstring domain_controller_address; + fstring domain_name; + fstring dns_forest_name; + fstring dc_site_name; + fstring client_site_name; + + info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO); + NT_STATUS_HAVE_NO_MEMORY(info); + + len += tdb_unpack(buf+len, buflen-len, "ffdBffdff", + &domain_controller_name, + &domain_controller_address, + &info->domain_controller_address_type, + &guid_len, &guid_buf, + &domain_name, + &dns_forest_name, + &info->flags, + &dc_site_name, + &client_site_name); + if (len == -1) { + DEBUG(5,("unpack_dsdcinfo: Failed to unpack domain\n")); + goto failed; + } + + info->domain_controller_name = + talloc_strdup(mem_ctx, domain_controller_name); + info->domain_controller_address = + talloc_strdup(mem_ctx, domain_controller_address); + info->domain_name = + talloc_strdup(mem_ctx, domain_name); + info->dns_forest_name = + talloc_strdup(mem_ctx, dns_forest_name); + info->dc_site_name = + talloc_strdup(mem_ctx, dc_site_name); + info->client_site_name = + talloc_strdup(mem_ctx, client_site_name); + + if (!info->domain_controller_name || + !info->domain_controller_address || + !info->domain_name || + !info->dns_forest_name || + !info->dc_site_name || + !info->client_site_name) { + goto failed; + } + + if (guid_len > 0) { + struct GUID guid; + + if (guid_len != UUID_FLAT_SIZE) { + goto failed; + } + + memcpy(&guid_flat.info, guid_buf, guid_len); + smb_uuid_unpack(guid_flat, &guid); + + info->domain_guid = talloc_memdup(mem_ctx, &guid, sizeof(guid)); + if (!info->domain_guid) { + goto failed; + } + SAFE_FREE(guid_buf); + } + + DEBUG(10,("unpack_dcscinfo: Unpacked domain %s (%s)\n", + info->domain_name, info->domain_controller_name)); + + *info_ret = info; + + return NT_STATUS_OK; + + failed: + TALLOC_FREE(info); + SAFE_FREE(guid_buf); + return NT_STATUS_NO_MEMORY; +} + +/**************************************************************** +****************************************************************/ + +static char *DsGetDcName_cache_key(TALLOC_CTX *mem_ctx, const char *domain) +{ + if (!mem_ctx || !domain) { + return NULL; + } + + return talloc_asprintf(mem_ctx, DSGETDCNAME_FMT, + strupper_static(domain)); +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS DsGetDcName_cache_delete(TALLOC_CTX *mem_ctx, + const char *domain_name) +{ + char *key; + + if (!gencache_init()) { + return NT_STATUS_INTERNAL_DB_ERROR; + } + + key = DsGetDcName_cache_key(mem_ctx, domain_name); + if (!key) { + return NT_STATUS_NO_MEMORY; + } + + if (!gencache_del(key)) { + return NT_STATUS_UNSUCCESSFUL; + } + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS DsGetDcName_cache_store(TALLOC_CTX *mem_ctx, + const char *domain_name, + struct DS_DOMAIN_CONTROLLER_INFO *info) +{ + time_t expire_time; + char *key; + BOOL ret = False; + DATA_BLOB blob; + unsigned char *buf = NULL; + int len = 0; + + if (!gencache_init()) { + return NT_STATUS_INTERNAL_DB_ERROR; + } + + key = DsGetDcName_cache_key(mem_ctx, domain_name); + if (!key) { + return NT_STATUS_NO_MEMORY; + } + + expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL; + + len = pack_dsdcinfo(info, &buf); + if (len == -1) { + return NT_STATUS_UNSUCCESSFUL; + } + + blob = data_blob(buf, len); + SAFE_FREE(buf); + + if (gencache_lock_entry(key) != 0) { + data_blob_free(&blob); + return NT_STATUS_LOCK_NOT_GRANTED; + } + + ret = gencache_set_data_blob(key, &blob, expire_time); + data_blob_free(&blob); + + gencache_unlock_entry(key); + + return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS DsGetDcName_cache_refresh(TALLOC_CTX *mem_ctx, + const char *domain_name, + struct GUID *domain_guid, + uint32_t flags, + const char *site_name, + struct DS_DOMAIN_CONTROLLER_INFO *info) +{ + struct cldap_netlogon_reply r; + + /* check if matching entry is older then 15 minutes, if yes, send + * CLDAP/MAILSLOT ping again and store the cached data */ + + ZERO_STRUCT(r); + + if (ads_cldap_netlogon(info->domain_controller_name, + info->domain_name, &r)) { + + DsGetDcName_cache_delete(mem_ctx, domain_name); + + return DsGetDcName_cache_store(mem_ctx, + info->domain_name, + info); + } + + return NT_STATUS_INVALID_NETWORK_RESPONSE; +} + +/**************************************************************** +****************************************************************/ + +#define RETURN_ON_FALSE(x) if (!x) return False; + +static BOOL check_cldap_reply_required_flags(uint32_t ret_flags, + uint32_t req_flags) +{ + if (req_flags & DS_PDC_REQUIRED) + RETURN_ON_FALSE(ret_flags & ADS_PDC); + + if (req_flags & DS_GC_SERVER_REQUIRED) + RETURN_ON_FALSE(ret_flags & ADS_GC); + + if (req_flags & DS_ONLY_LDAP_NEEDED) + RETURN_ON_FALSE(ret_flags & ADS_LDAP); + + if ((req_flags & DS_DIRECTORY_SERVICE_REQUIRED) || + (req_flags & DS_DIRECTORY_SERVICE_PREFERRED)) + RETURN_ON_FALSE(ret_flags & ADS_DS); + + if (req_flags & DS_KDC_REQUIRED) + RETURN_ON_FALSE(ret_flags & ADS_KDC); + + if (req_flags & DS_TIMESERV_REQUIRED) + RETURN_ON_FALSE(ret_flags & ADS_TIMESERV); + + if (req_flags & DS_WRITABLE_REQUIRED) + RETURN_ON_FALSE(ret_flags & ADS_WRITABLE); + + return True; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS DsGetDcName_cache_fetch(TALLOC_CTX *mem_ctx, + const char *domain_name, + struct GUID *domain_guid, + uint32_t flags, + const char *site_name, + struct DS_DOMAIN_CONTROLLER_INFO **info, + BOOL *expired) +{ + char *key; + DATA_BLOB blob; + NTSTATUS status; + + if (!gencache_init()) { + return NT_STATUS_INTERNAL_DB_ERROR; + } + + key = DsGetDcName_cache_key(mem_ctx, domain_name); + if (!key) { + return NT_STATUS_NO_MEMORY; + } + + if (!gencache_get_data_blob(key, &blob, expired)) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + + status = unpack_dsdcinfo(mem_ctx, blob.data, blob.length, info); + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&blob); + return status; + } + + data_blob_free(&blob); + + /* check flags */ + if (!check_cldap_reply_required_flags((*info)->flags, flags)) { + DEBUG(10,("invalid flags\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if ((flags & DS_IP_REQUIRED) && + !((*info)->domain_controller_address_type != ADS_INET_ADDRESS)) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS DsGetDcName_cached(TALLOC_CTX *mem_ctx, + const char *domain_name, + struct GUID *domain_guid, + uint32_t flags, + const char *site_name, + struct DS_DOMAIN_CONTROLLER_INFO **info) +{ + NTSTATUS status; + BOOL expired = False; + + status = DsGetDcName_cache_fetch(mem_ctx, domain_name, domain_guid, + flags, site_name, info, &expired); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("DsGetDcName_cached: cache fetch failed with: %s\n", + nt_errstr(status))); + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + } + + if (flags & DS_BACKGROUND_ONLY) { + return status; + } + + if (expired) { + status = DsGetDcName_cache_refresh(mem_ctx, domain_name, + domain_guid, flags, + site_name, *info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + } + + return status; +} + +/**************************************************************** +****************************************************************/ + +static BOOL check_allowed_required_flags(uint32_t flags) +{ + uint32_t return_type = flags & (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME); + uint32_t offered_type = flags & (DS_IS_FLAT_NAME|DS_IS_DNS_NAME); + uint32_t query_type = flags & (DS_BACKGROUND_ONLY|DS_FORCE_REDISCOVERY); + + /* FIXME: check for DSGETDC_VALID_FLAGS and check for excluse bits + * (DS_PDC_REQUIRED, DS_KDC_REQUIRED, DS_GC_SERVER_REQUIRED) */ + + debug_dsdcinfo_flags(0, flags); + + if (return_type == (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME)) { + return False; + } + + if (offered_type == (DS_IS_DNS_NAME|DS_IS_FLAT_NAME)) { + return False; + } + + if (query_type == (DS_BACKGROUND_ONLY|DS_FORCE_REDISCOVERY)) { + return False; + } + +#if 0 + if ((flags & DS_RETURN_DNS_NAME) && (!(flags & DS_IP_REQUIRED))) { + printf("gd: here5 \n"); + return False; + } +#endif + return True; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS discover_dc_netbios(TALLOC_CTX *mem_ctx, + const char *domain_name, + uint32_t flags, + struct ip_service_name **returned_dclist, + int *return_count) +{ + if (lp_disable_netbios()) { + return NT_STATUS_NOT_SUPPORTED; + } + + /* FIXME: code here */ + + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, + const char *domain_name, + struct GUID *domain_guid, + uint32_t flags, + const char *site_name, + struct ip_service_name **returned_dclist, + int *return_count) +{ + int i, j; + NTSTATUS status; + struct dns_rr_srv *dcs = NULL; + int numdcs = 0; + int numaddrs = 0; + + if ((!(flags & DS_DIRECTORY_SERVICE_REQUIRED)) && + (!(flags & DS_KDC_REQUIRED)) && + (!(flags & DS_GC_SERVER_REQUIRED)) && + (!(flags & DS_PDC_REQUIRED))) { + DEBUG(1,("discover_dc_dns: invalid flags\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (flags & DS_PDC_REQUIRED) { + status = ads_dns_query_pdc(mem_ctx, domain_name, + &dcs, &numdcs); + } else if (flags & DS_GC_SERVER_REQUIRED) { + status = ads_dns_query_gcs(mem_ctx, domain_name, site_name, + &dcs, &numdcs); + } else if (flags & DS_KDC_REQUIRED) { + status = ads_dns_query_kdcs(mem_ctx, domain_name, site_name, + &dcs, &numdcs); + } else if (flags & DS_DIRECTORY_SERVICE_REQUIRED) { + status = ads_dns_query_dcs(mem_ctx, domain_name, site_name, + &dcs, &numdcs); + } else if (domain_guid) { + status = ads_dns_query_dcs_guid(mem_ctx, domain_name, + domain_guid, &dcs, &numdcs); + } else { + /* FIXME: ? */ + DEBUG(1,("discover_dc_dns: not enough input\n")); + status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + } + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (numdcs == 0) { + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + } + + for (i=0;iport = dcs[i].port; + r->hostname = dcs[i].hostname; + + if (!(flags & DS_IP_REQUIRED)) { + (*return_count)++; + continue; + } + + /* If we don't have an IP list for a name, lookup it up */ + + if (!dcs[i].ips) { + r->ip = *interpret_addr2(dcs[i].hostname); + i++; + j = 0; + } else { + /* use the IP addresses from the SRV sresponse */ + + if (j >= dcs[i].num_ips) { + i++; + j = 0; + continue; + } + + r->ip = dcs[i].ips[j]; + j++; + } + + /* make sure it is a valid IP. I considered checking the + * negative connection cache, but this is the wrong place for + * it. Maybe only as a hac. After think about it, if all of + * the IP addresses retuend from DNS are dead, what hope does a + * netbios name lookup have? The standard reason for falling + * back to netbios lookups is that our DNS server doesn't know + * anything about the DC's -- jerry */ + + if (!is_zero_ip(r->ip)) { + (*return_count)++; + continue; + } + } + + return (*return_count > 0) ? NT_STATUS_OK : + NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, + const char *domain_controller_name, + const char *domain_controller_address, + uint32_t domain_controller_address_type, + const struct GUID *domain_guid, + const char *domain_name, + const char *dns_forest_name, + uint32_t flags, + const char *dc_site_name, + const char *client_site_name, + struct DS_DOMAIN_CONTROLLER_INFO **info_out) +{ + struct DS_DOMAIN_CONTROLLER_INFO *info; + + info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO); + NT_STATUS_HAVE_NO_MEMORY(info); + + if (domain_controller_name) { + info->domain_controller_name = talloc_strdup(mem_ctx, + domain_controller_name); + NT_STATUS_HAVE_NO_MEMORY(info->domain_controller_name); + } + + if (domain_controller_address) { + info->domain_controller_address = talloc_strdup(mem_ctx, + domain_controller_address); + NT_STATUS_HAVE_NO_MEMORY(info->domain_controller_address); + } + + info->domain_controller_address_type = domain_controller_address_type; + + if (domain_guid) { + info->domain_guid = talloc_memdup(mem_ctx, domain_guid, + sizeof(*domain_guid)); + NT_STATUS_HAVE_NO_MEMORY(info->domain_guid); + } + + if (domain_name) { + info->domain_name = talloc_strdup(mem_ctx, domain_name); + NT_STATUS_HAVE_NO_MEMORY(info->domain_name); + } + + if (dns_forest_name) { + info->dns_forest_name = talloc_strdup(mem_ctx, + dns_forest_name); + NT_STATUS_HAVE_NO_MEMORY(info->dns_forest_name); + } + + info->flags = flags; + + if (dc_site_name) { + info->dc_site_name = talloc_strdup(mem_ctx, dc_site_name); + NT_STATUS_HAVE_NO_MEMORY(info->dc_site_name); + } + + if (client_site_name) { + info->client_site_name = talloc_strdup(mem_ctx, + client_site_name); + NT_STATUS_HAVE_NO_MEMORY(info->client_site_name); + } + + *info_out = info; + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, + const char *domain_name, + uint32_t flags, + struct ip_service_name **dclist, + int num_dcs, + struct DS_DOMAIN_CONTROLLER_INFO **info) +{ + int i = 0; + BOOL valid_dc = False; + struct cldap_netlogon_reply r; + const char *dc_hostname, *dc_domain_name; + const char *dc_address; + uint32_t dc_address_type; + uint32_t dc_flags; + struct GUID dc_guid; + + for (i=0; ihostname, + domain_name, &r)) && + (check_cldap_reply_required_flags(r.flags, flags))) { + valid_dc = True; + break; + } + + continue; + } + + if (!valid_dc) { + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + } + + dc_flags = r.flags; + + if (flags & DS_RETURN_FLAT_NAME) { + if (!strlen(r.netbios_hostname) || !strlen(r.netbios_domain)) { + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + } + dc_hostname = r.netbios_hostname; + dc_domain_name = r.netbios_domain; + } else if (flags & DS_RETURN_DNS_NAME) { + if (!strlen(r.hostname) || !strlen(r.domain)) { + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + } + dc_hostname = r.hostname; + dc_domain_name = r.domain; + dc_flags |= ADS_DNS_DOMAIN | ADS_DNS_CONTROLLER; + } else { + /* FIXME */ + dc_hostname = r.hostname; + dc_domain_name = r.domain; + dc_flags |= ADS_DNS_DOMAIN | ADS_DNS_CONTROLLER; + } + + if (flags & DS_IP_REQUIRED) { + dc_address = talloc_asprintf(mem_ctx, "\\\\%s", + inet_ntoa(dclist[i]->ip)); + dc_address_type = ADS_INET_ADDRESS; + } else { + dc_address = talloc_asprintf(mem_ctx, "\\\\%s", + r.netbios_hostname); + dc_address_type = ADS_NETBIOS_ADDRESS; + } + NT_STATUS_HAVE_NO_MEMORY(dc_address); + dc_guid = smb_uuid_unpack_static(r.guid); + + if (r.forest) { + dc_flags |= ADS_DNS_FOREST; + } + + return make_domain_controller_info(mem_ctx, + dc_hostname, + dc_address, + dc_address_type, + &dc_guid, + dc_domain_name, + r.forest, + dc_flags, + r.server_site_name, + r.client_site_name, + info); + +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, + const char *domain_name, + uint32_t flags, + struct ip_service_name **dclist, + int num_dcs, + struct DS_DOMAIN_CONTROLLER_INFO **info) +{ + /* FIXME: code here */ + + return NT_STATUS_NOT_SUPPORTED; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS DsGetDcName_rediscover(TALLOC_CTX *mem_ctx, + const char *domain_name, + struct GUID *domain_guid, + uint32_t flags, + const char *site_name, + struct DS_DOMAIN_CONTROLLER_INFO **info) +{ + NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + struct ip_service_name *dclist; + int num_dcs; + + DEBUG(10,("DsGetDcName_rediscover\n")); + + if (flags & DS_IS_FLAT_NAME) { + + status = discover_dc_netbios(mem_ctx, domain_name, flags, + &dclist, &num_dcs); + NT_STATUS_NOT_OK_RETURN(status); + + return process_dc_netbios(mem_ctx, domain_name, flags, + &dclist, num_dcs, info); + } + + if (flags & DS_IS_DNS_NAME) { + + status = discover_dc_dns(mem_ctx, domain_name, domain_guid, + flags, site_name, &dclist, &num_dcs); + NT_STATUS_NOT_OK_RETURN(status); + + return process_dc_dns(mem_ctx, domain_name, flags, + &dclist, num_dcs, info); + } + + status = discover_dc_dns(mem_ctx, domain_name, domain_guid, flags, + site_name, &dclist, &num_dcs); + + if (NT_STATUS_IS_OK(status) && num_dcs != 0) { + + status = process_dc_dns(mem_ctx, domain_name, flags, &dclist, + num_dcs, info); + if (NT_STATUS_IS_OK(status)) { + return status; + } + } + + status = discover_dc_netbios(mem_ctx, domain_name, flags, &dclist, + &num_dcs); + NT_STATUS_NOT_OK_RETURN(status); + + return process_dc_netbios(mem_ctx, domain_name, flags, &dclist, + num_dcs, info); +} + +/******************************************************************** + DsGetDcName. + + This will be the only public function here. +********************************************************************/ + +NTSTATUS DsGetDcName(TALLOC_CTX *mem_ctx, + const char *computer_name, + const char *domain_name, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags, + struct DS_DOMAIN_CONTROLLER_INFO **info) +{ + NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + struct DS_DOMAIN_CONTROLLER_INFO *myinfo = NULL; + + DEBUG(10,("DsGetDcName: computer_name: %s, domain_name: %s, " + "domain_guid: %s, site_name: %s, flags: 0x%08x\n", + computer_name, domain_name, + domain_guid ? GUID_string(mem_ctx, domain_guid) : "(null)", + site_name, flags)); + + *info = NULL; + + if (!check_allowed_required_flags(flags)) { + DEBUG(0,("invalid flags specified\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (flags & DS_FORCE_REDISCOVERY) { + goto rediscover; + } + + status = DsGetDcName_cached(mem_ctx, domain_name, domain_guid, + flags, site_name, &myinfo); + if (NT_STATUS_IS_OK(status)) { + *info = myinfo; + return status; + } + + if (flags & DS_BACKGROUND_ONLY) { + return status; + } + + rediscover: + status = DsGetDcName_rediscover(mem_ctx, domain_name, + domain_guid, flags, site_name, + &myinfo); + + if (NT_STATUS_IS_OK(status)) { + DsGetDcName_cache_store(mem_ctx, domain_name, myinfo); + *info = myinfo; + } + + return status; +} -- cgit From 52cd23c92a21edd7b70a0f7b3aca0176bdf520c7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 28 Aug 2007 15:31:42 +0000 Subject: r24749: Increase debuglevel. Guenther (This used to be commit d82c1638b8ada43cfcbf9f71586c4c6849902c7e) --- source3/libsmb/dsgetdcname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 6f4961b3c3..4cb3d1beac 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -508,7 +508,7 @@ static BOOL check_allowed_required_flags(uint32_t flags) /* FIXME: check for DSGETDC_VALID_FLAGS and check for excluse bits * (DS_PDC_REQUIRED, DS_KDC_REQUIRED, DS_GC_SERVER_REQUIRED) */ - debug_dsdcinfo_flags(0, flags); + debug_dsdcinfo_flags(10, flags); if (return_type == (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME)) { return False; -- cgit From d68a5c2718498a36ff3b7bc25ec9f2ebbb19b85d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 28 Aug 2007 15:38:03 +0000 Subject: r24750: Fix one more caller of name_resolve_bcast(). Michael (This used to be commit 757b5c1bd7ff3d6bbf99753c1b617338ee837531) --- source3/libsmb/libsmbclient.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index dd3cbfc621..8d6ad57d90 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2665,7 +2665,9 @@ smbc_opendir_ctx(SMBCCTX *context, */ ip_list = NULL; - if (!name_resolve_bcast(MSBROWSE, 1, &ip_list, &count)) { + if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, + &count))) + { SAFE_FREE(ip_list); -- cgit From 4429a01c83f8900d318c7c162f004d1e5764556a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 29 Aug 2007 12:35:20 +0000 Subject: r24776: Remove accidentially commited flag checks. Guenther (This used to be commit 1efc5009a4b72a5a4c600ca3af7dc7cf05f74353) --- source3/libsmb/dsgetdcname.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 4cb3d1beac..3d8d57d157 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -71,14 +71,6 @@ void debug_dsdcinfo_flags(int lvl, uint32_t flags) DEBUGADD(lvl,("DS_AVOID_SELF ")); if (flags & DS_ONLY_LDAP_NEEDED) DEBUGADD(lvl,("DS_ONLY_LDAP_NEEDED ")); - if (flags & 0x00010000) - DEBUGADD(lvl,("0x00010000 ")); - if (flags & 0x00020000) - DEBUGADD(lvl,("0x00020000 ")); - if (flags & 0x00040000) - DEBUGADD(lvl,("0x00040000 ")); - if (flags & 0x00080000) - DEBUGADD(lvl,("0x00080000 ")); if (flags & DS_IS_FLAT_NAME) DEBUGADD(lvl,("DS_IS_FLAT_NAME ")); if (flags & DS_IS_DNS_NAME) -- cgit From 1a13b09894ea8f6424cb904c83a4cd6214040e89 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 29 Aug 2007 13:56:52 +0000 Subject: r24782: Fix C++ warnings (This used to be commit f7e8df81ef9e1deadb1251e5e5959e90a4432f40) --- source3/libsmb/dsgetdcname.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 3d8d57d157..90e6d49274 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -235,7 +235,8 @@ static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, memcpy(&guid_flat.info, guid_buf, guid_len); smb_uuid_unpack(guid_flat, &guid); - info->domain_guid = talloc_memdup(mem_ctx, &guid, sizeof(guid)); + info->domain_guid = (struct GUID *)talloc_memdup( + mem_ctx, &guid, sizeof(guid)); if (!info->domain_guid) { goto failed; } @@ -694,8 +695,8 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, info->domain_controller_address_type = domain_controller_address_type; if (domain_guid) { - info->domain_guid = talloc_memdup(mem_ctx, domain_guid, - sizeof(*domain_guid)); + info->domain_guid = (struct GUID *)talloc_memdup( + mem_ctx, domain_guid, sizeof(*domain_guid)); NT_STATUS_HAVE_NO_MEMORY(info->domain_guid); } -- cgit From b79f9b087054fd3b5c5cddfc89e4c56434309d34 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 30 Aug 2007 09:15:07 +0000 Subject: r24797: Fix logic in dsgetdcname(). Guenther (This used to be commit aca2d78db139ed32bcedec9861e83cb8c42809cf) --- source3/libsmb/dsgetdcname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 90e6d49274..384b9ec48d 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -445,7 +445,7 @@ static NTSTATUS DsGetDcName_cache_fetch(TALLOC_CTX *mem_ctx, } if ((flags & DS_IP_REQUIRED) && - !((*info)->domain_controller_address_type != ADS_INET_ADDRESS)) { + ((*info)->domain_controller_address_type != ADS_INET_ADDRESS)) { return NT_STATUS_INVALID_PARAMETER_MIX; } -- cgit From c3678b45df9faba9680c0a4e790b446bb3e7ac62 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 1 Sep 2007 18:34:50 +0000 Subject: r24864: - Correct failure of libsmbclient against a version of Windows found on a NAS device. The device resets a NBT connection on port 139 when it receives a NetBIOS keepalive request. That request should be supported when NetBIOS is in use; Windows is behaving badly. libsmbclient needs a way to determine if a connection is still alive, and was using a NetBIOS keepalive request if port 139 was in use (on the assumption that it was probably NBT), and getpeername() when port 139 was not being used (assuming naked transport). This patch simplifies the code by exclusively using getpeername() to check whether a connection is still alive. The NetBIOS keepalive request is optional anyway (with preference being given to using TCP mechanisms for the same purpose), so this should be both simpler and more reliable. Derrell (This used to be commit 1f122352b02e3f4be9ac2d638b18807dafd05429) --- source3/libsmb/libsmbclient.c | 26 ++------------------------ 1 file changed, 2 insertions(+), 24 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 8d6ad57d90..f903f37d14 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -502,30 +502,8 @@ smbc_check_server(SMBCCTX * context, socklen_t size; struct sockaddr addr; - /* - * Although the use of port 139 is not a guarantee that we're using - * netbios, we assume so. We don't want to send a keepalive packet if - * not netbios because it's not valid, and Vista, at least, - * disconnects the client on such a request. - */ - if (server->cli->port == 139) { - /* Assuming netbios. Send a keepalive packet */ - if ( send_keepalive(server->cli->fd) == False ) { - return 1; - } - } else { - /* - * Assuming not netbios. Try a different method to detect if - * the connection is still alive. - */ - size = sizeof(addr); - if (getpeername(server->cli->fd, &addr, &size) == -1) { - return 1; - } - } - - /* connection is ok */ - return 0; + size = sizeof(addr); + return (getpeername(server->cli->fd, &addr, &size) == -1); } /* -- cgit From 274e35f36e55ff215cef26d44d35627cb9c97924 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 5 Sep 2007 12:53:56 +0000 Subject: r24969: Fwd port "open" patch (This used to be commit 113d62682ae8b045ff0132a743a32f3bc4856d54) --- source3/libsmb/libsmb_compat.c | 2 +- source3/libsmb/libsmbclient.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index e0f2a90bd6..d6c2fe2109 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -156,7 +156,7 @@ int smbc_open(const char *furl, int flags, mode_t mode) SMBCFILE * file; int fd; - file = statcont->open(statcont, furl, flags, mode); + file = (statcont->open)(statcont, furl, flags, mode); if (!file) return -1; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index f903f37d14..b6b4119ff4 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5971,7 +5971,7 @@ smbc_open_print_job_ctx(SMBCCTX *context, /* What if the path is empty, or the file exists? */ - return context->open(context, fname, O_WRONLY, 666); + return (context->open)(context, fname, O_WRONLY, 666); } @@ -6012,7 +6012,7 @@ smbc_print_file_ctx(SMBCCTX *c_file, /* Try to open the file for reading ... */ - if ((long)(fid1 = c_file->open(c_file, fname, O_RDONLY, 0666)) < 0) { + if ((long)(fid1 = (c_file->open)(c_file, fname, O_RDONLY, 0666)) < 0) { DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); return -1; /* smbc_open sets errno */ -- cgit From 9044d034892ea7f21082bf915fa5dd531043b473 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 6 Sep 2007 13:21:31 +0000 Subject: r24981: - Use the formal syntax for calling functions through pointers. I've wanted to make this change for ages, but now with the issue of "open" requiring it, this is the time to just do all of them. Derrell (This used to be commit e746aaaf4db7099252ef048da7857bd488cb681f) --- source3/libsmb/libsmb_compat.c | 84 ++++++++++++++++---------------- source3/libsmb/libsmbclient.c | 108 +++++++++++++++++++++-------------------- 2 files changed, 98 insertions(+), 94 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index d6c2fe2109..573d087d6e 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -162,7 +162,7 @@ int smbc_open(const char *furl, int flags, mode_t mode) fd = add_fd(file); if (fd == -1) - statcont->close_fn(statcont, file); + (statcont->close_fn)(statcont, file); return fd; } @@ -172,15 +172,15 @@ int smbc_creat(const char *furl, mode_t mode) SMBCFILE * file; int fd; - file = statcont->creat(statcont, furl, mode); + file = (statcont->creat)(statcont, furl, mode); if (!file) return -1; fd = add_fd(file); if (fd == -1) { /* Hmm... should we delete the file too ? I guess we could try */ - statcont->close_fn(statcont, file); - statcont->unlink(statcont, furl); + (statcont->close_fn)(statcont, file); + (statcont->unlink)(statcont, furl); } return fd; } @@ -189,36 +189,36 @@ int smbc_creat(const char *furl, mode_t mode) ssize_t smbc_read(int fd, void *buf, size_t bufsize) { SMBCFILE * file = find_fd(fd); - return statcont->read(statcont, file, buf, bufsize); + return (statcont->read)(statcont, file, buf, bufsize); } ssize_t smbc_write(int fd, void *buf, size_t bufsize) { SMBCFILE * file = find_fd(fd); - return statcont->write(statcont, file, buf, bufsize); + return (statcont->write)(statcont, file, buf, bufsize); } off_t smbc_lseek(int fd, off_t offset, int whence) { SMBCFILE * file = find_fd(fd); - return statcont->lseek(statcont, file, offset, whence); + return (statcont->lseek)(statcont, file, offset, whence); } int smbc_close(int fd) { SMBCFILE * file = find_fd(fd); del_fd(fd); - return statcont->close_fn(statcont, file); + return (statcont->close_fn)(statcont, file); } int smbc_unlink(const char *fname) { - return statcont->unlink(statcont, fname); + return (statcont->unlink)(statcont, fname); } int smbc_rename(const char *ourl, const char *nurl) { - return statcont->rename(statcont, ourl, statcont, nurl); + return (statcont->rename)(statcont, ourl, statcont, nurl); } int smbc_opendir(const char *durl) @@ -226,13 +226,13 @@ int smbc_opendir(const char *durl) SMBCFILE * file; int fd; - file = statcont->opendir(statcont, durl); + file = (statcont->opendir)(statcont, durl); if (!file) return -1; fd = add_fd(file); if (fd == -1) - statcont->closedir(statcont, file); + (statcont->closedir)(statcont, file); return fd; } @@ -241,62 +241,62 @@ int smbc_closedir(int dh) { SMBCFILE * file = find_fd(dh); del_fd(dh); - return statcont->closedir(statcont, file); + return (statcont->closedir)(statcont, file); } int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count) { SMBCFILE * file = find_fd(dh); - return statcont->getdents(statcont, file,dirp, count); + return (statcont->getdents)(statcont, file,dirp, count); } struct smbc_dirent* smbc_readdir(unsigned int dh) { SMBCFILE * file = find_fd(dh); - return statcont->readdir(statcont, file); + return (statcont->readdir)(statcont, file); } off_t smbc_telldir(int dh) { SMBCFILE * file = find_fd(dh); - return statcont->telldir(statcont, file); + return (statcont->telldir)(statcont, file); } int smbc_lseekdir(int fd, off_t offset) { SMBCFILE * file = find_fd(fd); - return statcont->lseekdir(statcont, file, offset); + return (statcont->lseekdir)(statcont, file, offset); } int smbc_mkdir(const char *durl, mode_t mode) { - return statcont->mkdir(statcont, durl, mode); + return (statcont->mkdir)(statcont, durl, mode); } int smbc_rmdir(const char *durl) { - return statcont->rmdir(statcont, durl); + return (statcont->rmdir)(statcont, durl); } int smbc_stat(const char *url, struct stat *st) { - return statcont->stat(statcont, url, st); + return (statcont->stat)(statcont, url, st); } int smbc_fstat(int fd, struct stat *st) { SMBCFILE * file = find_fd(fd); - return statcont->fstat(statcont, file, st); + return (statcont->fstat)(statcont, file, st); } int smbc_chmod(const char *url, mode_t mode) { - return statcont->chmod(statcont, url, mode); + return (statcont->chmod)(statcont, url, mode); } int smbc_utimes(const char *fname, struct timeval *tbuf) { - return statcont->utimes(statcont, fname, tbuf); + return (statcont->utimes)(statcont, fname, tbuf); } #ifdef HAVE_UTIME_H @@ -305,13 +305,13 @@ int smbc_utime(const char *fname, struct utimbuf *utbuf) struct timeval tv[2]; if (utbuf == NULL) - return statcont->utimes(statcont, fname, NULL); + return (statcont->utimes)(statcont, fname, NULL); tv[0].tv_sec = utbuf->actime; tv[1].tv_sec = utbuf->modtime; tv[0].tv_usec = tv[1].tv_usec = 0; - return statcont->utimes(statcont, fname, tv); + return (statcont->utimes)(statcont, fname, tv); } #endif @@ -321,7 +321,7 @@ int smbc_setxattr(const char *fname, size_t size, int flags) { - return statcont->setxattr(statcont, fname, name, value, size, flags); + return (statcont->setxattr)(statcont, fname, name, value, size, flags); } int smbc_lsetxattr(const char *fname, @@ -330,7 +330,7 @@ int smbc_lsetxattr(const char *fname, size_t size, int flags) { - return statcont->setxattr(statcont, fname, name, value, size, flags); + return (statcont->setxattr)(statcont, fname, name, value, size, flags); } int smbc_fsetxattr(int fd, @@ -344,8 +344,8 @@ int smbc_fsetxattr(int fd, errno = EBADF; return -1; } - return statcont->setxattr(statcont, file->fname, - name, value, size, flags); + return (statcont->setxattr)(statcont, file->fname, + name, value, size, flags); } int smbc_getxattr(const char *fname, @@ -353,7 +353,7 @@ int smbc_getxattr(const char *fname, const void *value, size_t size) { - return statcont->getxattr(statcont, fname, name, value, size); + return (statcont->getxattr)(statcont, fname, name, value, size); } int smbc_lgetxattr(const char *fname, @@ -361,7 +361,7 @@ int smbc_lgetxattr(const char *fname, const void *value, size_t size) { - return statcont->getxattr(statcont, fname, name, value, size); + return (statcont->getxattr)(statcont, fname, name, value, size); } int smbc_fgetxattr(int fd, @@ -374,19 +374,19 @@ int smbc_fgetxattr(int fd, errno = EBADF; return -1; } - return statcont->getxattr(statcont, file->fname, name, value, size); + return (statcont->getxattr)(statcont, file->fname, name, value, size); } int smbc_removexattr(const char *fname, const char *name) { - return statcont->removexattr(statcont, fname, name); + return (statcont->removexattr)(statcont, fname, name); } int smbc_lremovexattr(const char *fname, const char *name) { - return statcont->removexattr(statcont, fname, name); + return (statcont->removexattr)(statcont, fname, name); } int smbc_fremovexattr(int fd, @@ -397,21 +397,21 @@ int smbc_fremovexattr(int fd, errno = EBADF; return -1; } - return statcont->removexattr(statcont, file->fname, name); + return (statcont->removexattr)(statcont, file->fname, name); } int smbc_listxattr(const char *fname, char *list, size_t size) { - return statcont->listxattr(statcont, fname, list, size); + return (statcont->listxattr)(statcont, fname, list, size); } int smbc_llistxattr(const char *fname, char *list, size_t size) { - return statcont->listxattr(statcont, fname, list, size); + return (statcont->listxattr)(statcont, fname, list, size); } int smbc_flistxattr(int fd, @@ -423,29 +423,29 @@ int smbc_flistxattr(int fd, errno = EBADF; return -1; } - return statcont->listxattr(statcont, file->fname, list, size); + return (statcont->listxattr)(statcont, file->fname, list, size); } int smbc_print_file(const char *fname, const char *printq) { - return statcont->print_file(statcont, fname, statcont, printq); + return (statcont->print_file)(statcont, fname, statcont, printq); } int smbc_open_print_job(const char *fname) { - SMBCFILE * file = statcont->open_print_job(statcont, fname); + SMBCFILE * file = (statcont->open_print_job)(statcont, fname); if (!file) return -1; return file->cli_fd; } int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn) { - return statcont->list_print_jobs(statcont, purl, fn); + return (statcont->list_print_jobs)(statcont, purl, fn); } int smbc_unlink_print_job(const char *purl, int id) { - return statcont->unlink_print_job(statcont, purl, id); + return (statcont->unlink_print_job)(statcont, purl, id); } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b6b4119ff4..7394008786 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -541,7 +541,7 @@ smbc_remove_unused_server(SMBCCTX * context, DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); - context->callbacks.remove_cached_srv_fn(context, srv); + (context->callbacks.remove_cached_srv_fn)(context, srv); SAFE_FREE(srv); @@ -561,19 +561,19 @@ find_server(SMBCCTX *context, check_server_cache: - srv = context->callbacks.get_cached_srv_fn(context, server, share, - workgroup, username); + srv = (context->callbacks.get_cached_srv_fn)(context, server, share, + workgroup, username); if (!auth_called && !srv && (!username[0] || !password[0])) { if (context->internal->_auth_fn_with_context != NULL) { - context->internal->_auth_fn_with_context( + (context->internal->_auth_fn_with_context)( context, server, share, workgroup, sizeof(fstring), username, sizeof(fstring), password, sizeof(fstring)); } else { - context->callbacks.auth_fn( + (context->callbacks.auth_fn)( server, share, workgroup, sizeof(fstring), username, sizeof(fstring), @@ -591,22 +591,22 @@ find_server(SMBCCTX *context, } if (srv) { - if (context->callbacks.check_server_fn(context, srv)) { + if ((context->callbacks.check_server_fn)(context, srv)) { /* * This server is no good anymore * Try to remove it and check for more possible * servers in the cache */ - if (context->callbacks.remove_unused_server_fn(context, - srv)) { + if ((context->callbacks.remove_unused_server_fn)(context, + srv)) { /* * We could not remove the server completely, * remove it from the cache so we will not get * it again. It will be removed when the last * file/dir is closed. */ - context->callbacks.remove_cached_srv_fn(context, - srv); + (context->callbacks.remove_cached_srv_fn)(context, + srv); } /* @@ -683,14 +683,14 @@ smbc_server(SMBCCTX *context, if (srv->cli->cnum == (uint16) -1) { /* Ensure we have accurate auth info */ if (context->internal->_auth_fn_with_context != NULL) { - context->internal->_auth_fn_with_context( + (context->internal->_auth_fn_with_context)( context, server, share, workgroup, sizeof(fstring), username, sizeof(fstring), password, sizeof(fstring)); } else { - context->callbacks.auth_fn( + (context->callbacks.auth_fn)( server, share, workgroup, sizeof(fstring), username, sizeof(fstring), @@ -703,8 +703,8 @@ smbc_server(SMBCCTX *context, errno = smbc_errno(context, srv->cli); cli_shutdown(srv->cli); srv->cli = NULL; - context->callbacks.remove_cached_srv_fn(context, - srv); + (context->callbacks.remove_cached_srv_fn)(context, + srv); srv = NULL; } @@ -881,7 +881,9 @@ smbc_server(SMBCCTX *context, /* now add it to the cache (internal or external) */ /* Let the cache function set errno if it wants to */ errno = 0; - if (context->callbacks.add_cached_srv_fn(context, srv, server, share, workgroup, username)) { + if ((context->callbacks.add_cached_srv_fn)(context, srv, + server, share, + workgroup, username)) { int saved_errno = errno; DEBUG(3, (" Failed to add server to cache\n")); errno = saved_errno; @@ -940,14 +942,14 @@ smbc_attr_server(SMBCCTX *context, if (*password == '\0') { /* ... then retrieve it now. */ if (context->internal->_auth_fn_with_context != NULL) { - context->internal->_auth_fn_with_context( + (context->internal->_auth_fn_with_context)( context, server, share, workgroup, sizeof(fstring), username, sizeof(fstring), password, sizeof(fstring)); } else { - context->callbacks.auth_fn( + (context->callbacks.auth_fn)( server, share, workgroup, sizeof(fstring), username, sizeof(fstring), @@ -1019,11 +1021,11 @@ smbc_attr_server(SMBCCTX *context, /* now add it to the cache (internal or external) */ errno = 0; /* let cache function set errno if it likes */ - if (context->callbacks.add_cached_srv_fn(context, ipc_srv, - server, - "*IPC$", - workgroup, - username)) { + if ((context->callbacks.add_cached_srv_fn)(context, ipc_srv, + server, + "*IPC$", + workgroup, + username)) { DEBUG(3, (" Failed to add server to cache\n")); if (errno == 0) { errno = ENOMEM; @@ -1186,7 +1188,7 @@ smbc_open_ctx(SMBCCTX *context, int eno = 0; eno = smbc_errno(context, srv->cli); - file = context->opendir(context, fname); + file = (context->opendir)(context, fname); if (!file) errno = eno; return file; @@ -1425,7 +1427,7 @@ smbc_close_ctx(SMBCCTX *context, /* IS a dir ... */ if (!file->file) { - return context->closedir(context, file); + return (context->closedir)(context, file); } @@ -1462,7 +1464,7 @@ smbc_close_ctx(SMBCCTX *context, DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); - context->callbacks.remove_unused_server_fn(context, srv); + (context->callbacks.remove_unused_server_fn)(context, srv); return -1; @@ -2175,7 +2177,7 @@ smbc_fstat_ctx(SMBCCTX *context, if (!file->file) { - return context->fstatdir(context, file, st); + return (context->fstatdir)(context, file, st); } @@ -2936,20 +2938,22 @@ smbc_opendir_ctx(SMBCCTX *context, */ cb = &context->callbacks; if (cli_is_error(targetcli) && - cb->check_server_fn(context, srv)) { - - /* ... then remove it. */ - if (cb->remove_unused_server_fn(context, - srv)) { - /* - * We could not remove the server - * completely, remove it from the - * cache so we will not get it - * again. It will be removed when the - * last file/dir is closed. - */ - cb->remove_cached_srv_fn(context, srv); - } + (cb->check_server_fn)(context, srv)) { + + /* ... then remove it. */ + if ((cb->remove_unused_server_fn)(context, + srv)) { + /* + * We could not remove the + * server completely, remove + * it from the cache so we + * will not get it again. It + * will be removed when the + * last file/dir is closed. + */ + (cb->remove_cached_srv_fn)(context, + srv); + } } errno = saved_errno; @@ -6021,24 +6025,24 @@ smbc_print_file_ctx(SMBCCTX *c_file, /* Now, try to open the printer file for writing */ - if ((long)(fid2 = c_print->open_print_job(c_print, printq)) < 0) { + if ((long)(fid2 = (c_print->open_print_job)(c_print, printq)) < 0) { saverr = errno; /* Save errno */ - c_file->close_fn(c_file, fid1); + (c_file->close_fn)(c_file, fid1); errno = saverr; return -1; } - while ((bytes = c_file->read(c_file, fid1, buf, sizeof(buf))) > 0) { + while ((bytes = (c_file->read)(c_file, fid1, buf, sizeof(buf))) > 0) { tot_bytes += bytes; - if ((c_print->write(c_print, fid2, buf, bytes)) < 0) { + if (((c_print->write)(c_print, fid2, buf, bytes)) < 0) { saverr = errno; - c_file->close_fn(c_file, fid1); - c_print->close_fn(c_print, fid2); + (c_file->close_fn)(c_file, fid1); + (c_print->close_fn)(c_print, fid2); errno = saverr; } @@ -6047,8 +6051,8 @@ smbc_print_file_ctx(SMBCCTX *c_file, saverr = errno; - c_file->close_fn(c_file, fid1); /* We have to close these anyway */ - c_print->close_fn(c_print, fid2); + (c_file->close_fn)(c_file, fid1); /* We have to close these anyway */ + (c_print->close_fn)(c_print, fid2); if (bytes < 0) { @@ -6298,7 +6302,7 @@ smbc_free_context(SMBCCTX *context, f = context->internal->_files; while (f) { - context->close_fn(context, f); + (context->close_fn)(context, f); f = f->next; } context->internal->_files = NULL; @@ -6314,8 +6318,8 @@ smbc_free_context(SMBCCTX *context, DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", s, s->cli->fd)); cli_shutdown(s->cli); - context->callbacks.remove_cached_srv_fn(context, - s); + (context->callbacks.remove_cached_srv_fn)(context, + s); next = s->next; DLIST_REMOVE(context->internal->_servers, s); SAFE_FREE(s); @@ -6326,7 +6330,7 @@ smbc_free_context(SMBCCTX *context, } else { /* This is the polite way */ - if (context->callbacks.purge_cached_fn(context)) { + if ((context->callbacks.purge_cached_fn)(context)) { DEBUG(1, ("Could not purge all servers, " "free_context failed.\n")); errno = EBUSY; -- cgit From a747e8bdcfdd45f34324ec72310320927e97e9ad Mon Sep 17 00:00:00 2001 From: Lars Müller Date: Sat, 8 Sep 2007 14:56:11 +0000 Subject: r25032: Contact an off site DC if non is available on site. (This used to be commit 50879e6de5101b6c5ab8b3fb954f1d2a48530716) --- source3/libsmb/namequery_dc.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 7dac69e2db..bdac833d13 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -98,15 +98,22 @@ static BOOL ads_dc_name(const char *domain, } #ifdef HAVE_KRB5 - if (is_our_primary_domain(domain) && (ads->config.flags & ADS_KDC) && ads_closest_dc(ads)) { - /* We're going to use this KDC for this realm/domain. - If we are using sites, then force the krb5 libs - to use this KDC. */ - - create_local_private_krb5_conf_for_domain(realm, - domain, - sitename, - ads->ldap.ip); + if (is_our_primary_domain(domain) && (ads->config.flags & ADS_KDC)) { + if (ads_closest_dc(ads)) { + /* We're going to use this KDC for this realm/domain. + If we are using sites, then force the krb5 libs + to use this KDC. */ + + create_local_private_krb5_conf_for_domain(realm, + domain, + sitename, + ads->ldap.ip); + } else { + create_local_private_krb5_conf_for_domain(realm, + domain, + NULL, + ads->ldap.ip); + } } #endif break; -- cgit From eacd3140573d1122a3785823e4003bfc6352c431 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Sep 2007 22:08:59 +0000 Subject: r25138: More pstring elimination. Add a TALLOC_CTX parameter to unix_convert(). Jeremy. (This used to be commit 39c211a702e91c34c1a5a689e1b0c4530ea8a1ac) --- source3/libsmb/ntlmssp_parse.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index f17af38e8e..15739d3068 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -151,7 +151,8 @@ BOOL msrpc_gen(DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); - head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, + n = str_charnum(s) + 1; + head_ofs += push_string(NULL, blob->data+head_ofs, s, n, STR_ASCII|STR_TERMINATE); break; } -- cgit From 42349190b7c9b69009549770fe6ec7cd2df5d8ee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Sep 2007 14:33:32 +0000 Subject: r25227: Patch from "Steven Danneman" : - We ran across a bug joining our Samba server to a Win2K domain with LDAP signing turned on. Upon investigation I discovered that there is a bug in Win2K server which returns a duplicated responseToken in the LDAP bindResponse packet. This blob is placed in the optional mechListMIC field which is unsupported in both Win2K and Win2K3. You can see RFC 2478 for the proper packet construction. I've worked with metze on this to confirm all these finding. This patch properly parses then discards the mechListMIC field if it exists in the packet, so we don't produce a malformed packet error, causing LDAP signed joins to fail. Also attached is a sniff of the domain join, exposing Win2Ks bad behavior (packet 21). - (I've just changed the scope of the DATA_BLOB mechList) metze (This used to be commit 200b5bfb8180af09446762e915eac63d14c6c7b0) --- source3/libsmb/clispnego.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index f93cbcf39b..9432ce81d3 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -557,6 +557,20 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, data.has_error = 1; } + /* Binding against Win2K DC returns a duplicate of the responseToken in + * the optional mechListMIC field. This is a bug in Win2K. We ignore + * this field if it exists. Win2K8 may return a proper mechListMIC at + * which point we need to implement the integrity checking. */ + if (asn1_tag_remaining(&data)) { + DATA_BLOB mechList = data_blob_null; + asn1_start_tag(&data, ASN1_CONTEXT(3)); + asn1_read_OctetString(&data, &mechList); + asn1_end_tag(&data); + data_blob_free(&mechList); + DEBUG(5,("spnego_parse_auth_response received mechListMIC, " + "ignoring.\n")); + } + asn1_end_tag(&data); asn1_end_tag(&data); -- cgit From 3529156971e17c7ec13f6a6243f7b613e4666cdd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 03:54:42 +0000 Subject: r25400: Windows 2008 (Longhorn) Interop fixes for AD specific auth2 flags, and client fixes. Patch from Todd Stetcher . (This used to be commit 8304ccba7346597425307e260e88647e49081f68) --- source3/libsmb/cliconnect.c | 38 ++++++++++++++++++++++++++++---------- source3/libsmb/clispnego.c | 19 +++++++++++++++++++ source3/libsmb/namequery.c | 29 +++++++++++++++++++++++++++++ source3/libsmb/trusts_util.c | 2 +- 4 files changed, 77 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 820a904ea4..a4bbf9a6ec 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -822,20 +822,36 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, free(OIDs[i]); } - DEBUG(3,("got principal=%s\n", principal ? principal : "")); if (got_kerberos_mechanism && (principal == NULL)) { + fstring dns_name; + fstring nb_name; + /* - * It is WRONG to depend on the principal sent in the negprot - * reply, but right now we do it. So for safety (don't - * segfault later) disable Kerberos when no principal was - * sent. -- VL - */ - DEBUG(1, ("Kerberos mech was offered, but no principal was " - "sent, disabling Kerberos\n")); - cli->use_kerberos = False; + * We didn't get a valid principal in the negTokenInit. Fake + * it, or fall back on NTLM. We prefer to fake it, and hit the + * translate_name cache to get a REAL realm name. + */ + if (!(cli->desthost && translate_name(domain, dns_name, + nb_name) && + asprintf(&principal, "host/%s@%s", cli->desthost, + dns_name))) { + + /* + * It is WRONG to depend on the principal sent in the + * negprot reply, but right now we do it. So for safety + * (don't segfault later) disable Kerberos when no + * principal was sent. -- VL + */ + DEBUG(1, ("Kerberos mech was offered, but no principal was " + "sent, disabling Kerberos\n")); + cli->use_kerberos = False; + } + } + DEBUG(3,("got principal=%s\n", principal ? principal : "")); + fstrcpy(cli->user_name, user); #ifdef HAVE_KRB5 @@ -872,7 +888,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, ntlmssp: - return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain)); + /* NTLM is sensitive to adding a domain with a UPN */ + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, + (strchr(user, '@') ? NULL : domain))); } /**************************************************************************** diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 9432ce81d3..c45883d890 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -52,7 +52,18 @@ DATA_BLOB spnego_gen_negTokenInit(char guid[16], asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); + + /* + * @todo + * Windows 2008 sends a bogus principal, since this + * is not truly supported in the SPNEGO protocol. + * + * We should do the same, but I'm worried this will break things, + * such as DFS. + * todd.stecher@isilon.com + */ asn1_write_GeneralString(&data,principal); + asn1_pop_tag(&data); asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -154,6 +165,14 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_read_GeneralString(&data,principal); + /* + * Windows 2008 sends a bogus principal, since this + * is not truly supported in the SPNEGO protocol. + * todd.stecher@isilon.com + */ + if (strcmp(ADS_IGNORE_PRINCIPAL, *principal) == 0) + SAFE_FREE(*principal); + asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 49e3375f50..4a7ae0c2e5 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1714,3 +1714,32 @@ NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_servic return NT_STATUS_OK; } + + +BOOL translate_name(const char *realm, fstring dns_domain_name, + fstring nb_domain_name) +{ + struct winbindd_request request; + struct winbindd_response response; + NSS_STATUS wb_result; + + /* Call winbindd */ + + ZERO_STRUCT(request); + ZERO_STRUCT(response); + + fstrcpy(request.domain_name, realm); + wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO, + &request, &response); + + if (wb_result != NSS_STATUS_SUCCESS) { + DEBUG(0, ("Failed to translate %s\n", realm)); + return False; + } + + fstrcpy(dns_domain_name, response.data.domain_info.alt_name); + fstrcpy(nb_domain_name, response.data.domain_info.name); + + return True; + +} diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 0922f9f41e..4a231dcd15 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -40,7 +40,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX already have valid creds. If not we must set them up. */ if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; result = rpccli_netlogon_setup_creds(cli, cli->cli->desthost, /* server name */ -- cgit From 5221ebb299081da6a806362212c6a8ceb9cc70a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 18:15:34 +0000 Subject: r25407: Revert Longhorn join patch as it is not correct for the 3.2 tree. The translate_name() used by cli_session_setup_spnego() cann rely Winbindd since it is needed by the join process (and hence before Winbind can be run). (This used to be commit 00a93ed336c5f36643e6e33bd277608eaf05677c) --- source3/libsmb/cliconnect.c | 38 ++++++++++---------------------------- source3/libsmb/clispnego.c | 19 ------------------- source3/libsmb/namequery.c | 29 ----------------------------- source3/libsmb/trusts_util.c | 2 +- 4 files changed, 11 insertions(+), 77 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index a4bbf9a6ec..820a904ea4 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -822,36 +822,20 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, free(OIDs[i]); } + DEBUG(3,("got principal=%s\n", principal ? principal : "")); if (got_kerberos_mechanism && (principal == NULL)) { - fstring dns_name; - fstring nb_name; - /* - * We didn't get a valid principal in the negTokenInit. Fake - * it, or fall back on NTLM. We prefer to fake it, and hit the - * translate_name cache to get a REAL realm name. - */ - if (!(cli->desthost && translate_name(domain, dns_name, - nb_name) && - asprintf(&principal, "host/%s@%s", cli->desthost, - dns_name))) { - - /* - * It is WRONG to depend on the principal sent in the - * negprot reply, but right now we do it. So for safety - * (don't segfault later) disable Kerberos when no - * principal was sent. -- VL - */ - DEBUG(1, ("Kerberos mech was offered, but no principal was " - "sent, disabling Kerberos\n")); - cli->use_kerberos = False; - } - + * It is WRONG to depend on the principal sent in the negprot + * reply, but right now we do it. So for safety (don't + * segfault later) disable Kerberos when no principal was + * sent. -- VL + */ + DEBUG(1, ("Kerberos mech was offered, but no principal was " + "sent, disabling Kerberos\n")); + cli->use_kerberos = False; } - DEBUG(3,("got principal=%s\n", principal ? principal : "")); - fstrcpy(cli->user_name, user); #ifdef HAVE_KRB5 @@ -888,9 +872,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, ntlmssp: - /* NTLM is sensitive to adding a domain with a UPN */ - return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, - (strchr(user, '@') ? NULL : domain))); + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain)); } /**************************************************************************** diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index c45883d890..9432ce81d3 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -52,18 +52,7 @@ DATA_BLOB spnego_gen_negTokenInit(char guid[16], asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); - - /* - * @todo - * Windows 2008 sends a bogus principal, since this - * is not truly supported in the SPNEGO protocol. - * - * We should do the same, but I'm worried this will break things, - * such as DFS. - * todd.stecher@isilon.com - */ asn1_write_GeneralString(&data,principal); - asn1_pop_tag(&data); asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -165,14 +154,6 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_read_GeneralString(&data,principal); - /* - * Windows 2008 sends a bogus principal, since this - * is not truly supported in the SPNEGO protocol. - * todd.stecher@isilon.com - */ - if (strcmp(ADS_IGNORE_PRINCIPAL, *principal) == 0) - SAFE_FREE(*principal); - asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 4a7ae0c2e5..49e3375f50 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1714,32 +1714,3 @@ NTSTATUS get_kdc_list( const char *realm, const char *sitename, struct ip_servic return NT_STATUS_OK; } - - -BOOL translate_name(const char *realm, fstring dns_domain_name, - fstring nb_domain_name) -{ - struct winbindd_request request; - struct winbindd_response response; - NSS_STATUS wb_result; - - /* Call winbindd */ - - ZERO_STRUCT(request); - ZERO_STRUCT(response); - - fstrcpy(request.domain_name, realm); - wb_result = winbindd_request_response(WINBINDD_DOMAIN_INFO, - &request, &response); - - if (wb_result != NSS_STATUS_SUCCESS) { - DEBUG(0, ("Failed to translate %s\n", realm)); - return False; - } - - fstrcpy(dns_domain_name, response.data.domain_info.alt_name); - fstrcpy(nb_domain_name, response.data.domain_info.name); - - return True; - -} diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 4a231dcd15..0922f9f41e 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -40,7 +40,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX already have valid creds. If not we must set them up. */ if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; + uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; result = rpccli_netlogon_setup_creds(cli, cli->cli->desthost, /* server name */ -- cgit From 0d87820380416955a132d565a479b4234f78c113 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 Oct 2007 20:43:55 +0000 Subject: r25492: Start adding IPv6 compatible code to lib/util_sock.c and deal with the ripple effects this causes. utmp has to change etc. Remove some global varables and store address/port in the unexpected db. Jeremy. (This used to be commit 18c6a2211d9e25233d01715b3f78977edcd6d869) --- source3/libsmb/nmblib.c | 473 ++++++++++++++++++++++++++------------------ source3/libsmb/unexpected.c | 76 ++++--- 2 files changed, 333 insertions(+), 216 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 348555baf8..74deb91a73 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1,28 +1,26 @@ -/* +/* Unix SMB/CIFS implementation. NBT netbios library routines Copyright (C) Andrew Tridgell 1994-1998 - + Copyright (C) Jeremy Allison 2007 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . - + */ #include "includes.h" -extern struct in_addr lastip; -extern int lastport; - int num_good_sends = 0; int num_good_receives = 0; @@ -82,12 +80,12 @@ static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) unsigned char x = res->rdata[i+j]; if (x < 32 || x > 127) x = '.'; - + if (i+j >= res->rdlength) break; DEBUGADD(4, ("%c", x)); } - + DEBUGADD(4, (" hex ")); for (j = 0; j < MAX_NETBIOSNAME_LEN; j++) { @@ -95,7 +93,7 @@ static void debug_nmb_res_rec(struct res_rec *res, const char *hdr) break; DEBUGADD(4, ("%02X", (unsigned char)res->rdata[i+j])); } - + DEBUGADD(4, ("\n")); } } @@ -109,19 +107,22 @@ void debug_nmb_packet(struct packet_struct *p) struct nmb_packet *nmb = &p->packet.nmb; if( DEBUGLVL( 4 ) ) { - dbgtext( "nmb packet from %s(%d) header: id=%d opcode=%s(%d) response=%s\n", + dbgtext( "nmb packet from %s(%d) header: id=%d " + "opcode=%s(%d) response=%s\n", inet_ntoa(p->ip), p->port, nmb->header.name_trn_id, lookup_opcode_name(nmb->header.opcode), nmb->header.opcode, BOOLSTR(nmb->header.response) ); - dbgtext( " header: flags: bcast=%s rec_avail=%s rec_des=%s trunc=%s auth=%s\n", + dbgtext( " header: flags: bcast=%s rec_avail=%s " + "rec_des=%s trunc=%s auth=%s\n", BOOLSTR(nmb->header.nm_flags.bcast), BOOLSTR(nmb->header.nm_flags.recursion_available), BOOLSTR(nmb->header.nm_flags.recursion_desired), BOOLSTR(nmb->header.nm_flags.trunc), BOOLSTR(nmb->header.nm_flags.authoritative) ); - dbgtext( " header: rcode=%d qdcount=%d ancount=%d nscount=%d arcount=%d\n", + dbgtext( " header: rcode=%d qdcount=%d ancount=%d " + "nscount=%d arcount=%d\n", nmb->header.rcode, nmb->header.qdcount, nmb->header.ancount, @@ -155,17 +156,18 @@ static BOOL handle_name_ptrs(unsigned char *ubuf,int *offset,int length, BOOL *got_pointer,int *ret) { int loop_count=0; - + while ((ubuf[*offset] & 0xC0) == 0xC0) { if (!*got_pointer) (*ret) += 2; (*got_pointer)=True; (*offset) = ((ubuf[*offset] & ~0xC0)<<8) | ubuf[(*offset)+1]; - if (loop_count++ == 10 || (*offset) < 0 || (*offset)>(length-2)) { - return(False); + if (loop_count++ == 10 || + (*offset) < 0 || (*offset)>(length-2)) { + return False; } } - return(True); + return True; } /******************************************************************* @@ -183,12 +185,12 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) int offset = ofs; if (length - offset < 2) - return(0); + return(0); /* handle initial name pointers */ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0); - + m = ubuf[offset]; if (!m) @@ -214,14 +216,15 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) name->name[n] = 0; if (n==MAX_NETBIOSNAME_LEN) { - /* parse out the name type, its always in the 16th byte of the name */ + /* parse out the name type, its always + * in the 16th byte of the name */ name->name_type = ((unsigned char)name->name[15]) & 0xff; - + /* remove trailing spaces */ name->name[15] = 0; n = 14; while (n && name->name[n]==' ') - name->name[n--] = 0; + name->name[n--] = 0; } /* now the domain parts (if any) */ @@ -253,7 +256,7 @@ static int parse_nmb_name(char *inbuf,int ofs,int length, struct nmb_name *name) if (loop_count++ == 10) return 0; } - name->scope[n++] = 0; + name->scope[n++] = 0; return(ret); } @@ -268,7 +271,8 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type) { size_t len = strlen(name); - memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? len : MAX_NETBIOSNAME_LEN - 1); + memcpy(dest, name, (len < MAX_NETBIOSNAME_LEN) ? + len : MAX_NETBIOSNAME_LEN - 1); if (len < MAX_NETBIOSNAME_LEN - 1) { memset(dest + len, pad, MAX_NETBIOSNAME_LEN - 1 - len); } @@ -282,6 +286,8 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type) Compressed names are really weird. The "compression" doubles the size. The idea is that it also means that compressed names conform to the doman name system. See RFC1002. + + If buf == NULL this is a length calculation. ******************************************************************/ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) @@ -297,33 +303,42 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) put_name(buf1, name->name, ' ', name->name_type); } - buf[offset] = 0x20; + if (buf) { + buf[offset] = 0x20; + } ret = 34; for (m=0;m>4)&0xF); - buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + if (buf) { + buf[offset+1+2*m] = 'A' + ((buf1[m]>>4)&0xF); + buf[offset+2+2*m] = 'A' + (buf1[m]&0xF); + } } offset += 33; - buf[offset] = 0; + if (buf) { + buf[offset] = 0; + } if (name->scope[0]) { /* XXXX this scope handling needs testing */ ret += strlen(name->scope) + 1; - safe_strcpy(&buf[offset+1],name->scope,sizeof(name->scope)); - - p = &buf[offset+1]; - while ((p = strchr_m(p,'.'))) { - buf[offset] = PTR_DIFF(p,&buf[offset+1]); - offset += (buf[offset] + 1); + if (buf) { + safe_strcpy(&buf[offset+1],name->scope, + sizeof(name->scope)); + p = &buf[offset+1]; + while ((p = strchr_m(p,'.'))) { + buf[offset] = PTR_DIFF(p,&buf[offset+1]); + offset += (buf[offset] + 1); + p = &buf[offset+1]; + } + buf[offset] = strlen(&buf[offset+1]); } - buf[offset] = strlen(&buf[offset+1]); } - return(ret); + return ret; } /******************************************************************* @@ -341,7 +356,8 @@ char *nmb_namestr(const struct nmb_name *n) if (!n->scope[0]) slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type); else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",name,n->name_type,n->scope); + slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s", + name,n->name_type,n->scope); i = (i+1)%4; return(p); @@ -363,7 +379,8 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, memset((char *)*recs,'\0',sizeof(**recs)*count); for (i=0;i length) { SAFE_FREE(*recs); @@ -374,19 +391,20 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length, (*recs)[i].ttl = RIVAL(inbuf,(*offset)+4); (*recs)[i].rdlength = RSVAL(inbuf,(*offset)+8); (*offset) += 10; - if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || + if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) || (*offset)+(*recs)[i].rdlength > length) { SAFE_FREE(*recs); return(False); } memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength); - (*offset) += (*recs)[i].rdlength; + (*offset) += (*recs)[i].rdlength; } return(True); } /******************************************************************* Put a resource record into a packet. + If buf == NULL this is a length calculation. ******************************************************************/ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) @@ -398,42 +416,52 @@ static int put_res_rec(char *buf,int offset,struct res_rec *recs,int count) int l = put_nmb_name(buf,offset,&recs[i].rr_name); offset += l; ret += l; - RSSVAL(buf,offset,recs[i].rr_type); - RSSVAL(buf,offset+2,recs[i].rr_class); - RSIVAL(buf,offset+4,recs[i].ttl); - RSSVAL(buf,offset+8,recs[i].rdlength); - memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength); + if (buf) { + RSSVAL(buf,offset,recs[i].rr_type); + RSSVAL(buf,offset+2,recs[i].rr_class); + RSIVAL(buf,offset+4,recs[i].ttl); + RSSVAL(buf,offset+8,recs[i].rdlength); + memcpy(buf+offset+10,recs[i].rdata,recs[i].rdlength); + } offset += 10+recs[i].rdlength; ret += 10+recs[i].rdlength; } - return(ret); + return ret; } /******************************************************************* Put a compressed name pointer record into a packet. + If buf == NULL this is a length calculation. ******************************************************************/ -static int put_compressed_name_ptr(unsigned char *buf,int offset,struct res_rec *rec,int ptr_offset) -{ +static int put_compressed_name_ptr(unsigned char *buf, + int offset, + struct res_rec *rec, + int ptr_offset) +{ int ret=0; - buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); - buf[offset+1] = (ptr_offset & 0xFF); + if (buf) { + buf[offset] = (0xC0 | ((ptr_offset >> 8) & 0xFF)); + buf[offset+1] = (ptr_offset & 0xFF); + } offset += 2; ret += 2; - RSSVAL(buf,offset,rec->rr_type); - RSSVAL(buf,offset+2,rec->rr_class); - RSIVAL(buf,offset+4,rec->ttl); - RSSVAL(buf,offset+8,rec->rdlength); - memcpy(buf+offset+10,rec->rdata,rec->rdlength); + if (buf) { + RSSVAL(buf,offset,rec->rr_type); + RSSVAL(buf,offset+2,rec->rr_class); + RSIVAL(buf,offset+4,rec->ttl); + RSSVAL(buf,offset+8,rec->rdlength); + memcpy(buf+offset+10,rec->rdata,rec->rdlength); + } offset += 10+rec->rdlength; ret += 10+rec->rdlength; - - return(ret); + + return ret; } /******************************************************************* - Parse a dgram packet. Return False if the packet can't be parsed + Parse a dgram packet. Return False if the packet can't be parsed or is invalid for some reason, True otherwise. This is documented in section 4.4.1 of RFC1002. @@ -466,19 +494,22 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) if (dgram->header.msg_type == 0x10 || dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { - offset += parse_nmb_name(inbuf,offset,length,&dgram->source_name); - offset += parse_nmb_name(inbuf,offset,length,&dgram->dest_name); + dgram->header.msg_type == 0x12) { + offset += parse_nmb_name(inbuf,offset,length, + &dgram->source_name); + offset += parse_nmb_name(inbuf,offset,length, + &dgram->dest_name); } - if (offset >= length || (length-offset > sizeof(dgram->data))) + if (offset >= length || (length-offset > sizeof(dgram->data))) return(False); dgram->datasize = length-offset; memcpy(dgram->data,inbuf+offset,dgram->datasize); /* Paranioa. Ensure the last 2 bytes in the dgram buffer are - zero. This should be true anyway, just enforce it for paranioa sake. JRA. */ + zero. This should be true anyway, just enforce it for + paranioa sake. JRA. */ SMB_ASSERT(dgram->datasize <= (sizeof(dgram->data)-2)); memset(&dgram->data[sizeof(dgram->data)-2], '\0', 2); @@ -486,7 +517,7 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram) } /******************************************************************* - Parse a nmb packet. Return False if the packet can't be parsed + Parse a nmb packet. Return False if the packet can't be parsed or is invalid for some reason, True otherwise. ******************************************************************/ @@ -511,15 +542,16 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) nmb->header.nm_flags.recursion_available = (nm_flags&8)?True:False; nmb->header.nm_flags.recursion_desired = (nm_flags&0x10)?True:False; nmb->header.nm_flags.trunc = (nm_flags&0x20)?True:False; - nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; + nmb->header.nm_flags.authoritative = (nm_flags&0x40)?True:False; nmb->header.rcode = CVAL(inbuf,3) & 0xF; nmb->header.qdcount = RSVAL(inbuf,4); nmb->header.ancount = RSVAL(inbuf,6); nmb->header.nscount = RSVAL(inbuf,8); nmb->header.arcount = RSVAL(inbuf,10); - + if (nmb->header.qdcount) { - offset = parse_nmb_name(inbuf,12,length,&nmb->question.question_name); + offset = parse_nmb_name(inbuf,12,length, + &nmb->question.question_name); if (!offset) return(False); @@ -534,16 +566,19 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) } /* and any resource records */ - if (nmb->header.ancount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, + if (nmb->header.ancount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->answers, nmb->header.ancount)) return(False); - if (nmb->header.nscount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, + if (nmb->header.nscount && + !parse_alloc_res_rec(inbuf,&offset,length,&nmb->nsrecs, nmb->header.nscount)) return(False); - - if (nmb->header.arcount && !parse_alloc_res_rec(inbuf,&offset,length,&nmb->additional, - nmb->header.arcount)) + + if (nmb->header.arcount && + !parse_alloc_res_rec(inbuf,&offset,length, + &nmb->additional, nmb->header.arcount)) return(False); return(True); @@ -554,7 +589,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb) ******************************************************************/ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) -{ +{ struct nmb_packet *nmb; struct nmb_packet *copy_nmb; struct packet_struct *pkt_copy; @@ -582,21 +617,24 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) /* Now copy any resource records. */ if (nmb->answers) { - if((copy_nmb->answers = SMB_MALLOC_ARRAY(struct res_rec,nmb->header.ancount)) == NULL) + if((copy_nmb->answers = SMB_MALLOC_ARRAY( + struct res_rec,nmb->header.ancount)) == NULL) goto free_and_exit; - memcpy((char *)copy_nmb->answers, (char *)nmb->answers, + memcpy((char *)copy_nmb->answers, (char *)nmb->answers, nmb->header.ancount * sizeof(struct res_rec)); } if (nmb->nsrecs) { - if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.nscount)) == NULL) + if((copy_nmb->nsrecs = SMB_MALLOC_ARRAY( + struct res_rec, nmb->header.nscount)) == NULL) goto free_and_exit; - memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, + memcpy((char *)copy_nmb->nsrecs, (char *)nmb->nsrecs, nmb->header.nscount * sizeof(struct res_rec)); } if (nmb->additional) { - if((copy_nmb->additional = SMB_MALLOC_ARRAY(struct res_rec, nmb->header.arcount)) == NULL) + if((copy_nmb->additional = SMB_MALLOC_ARRAY( + struct res_rec, nmb->header.arcount)) == NULL) goto free_and_exit; - memcpy((char *)copy_nmb->additional, (char *)nmb->additional, + memcpy((char *)copy_nmb->additional, (char *)nmb->additional, nmb->header.arcount * sizeof(struct res_rec)); } @@ -618,7 +656,7 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet) ******************************************************************/ static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) -{ +{ struct packet_struct *pkt_copy; if(( pkt_copy = SMB_MALLOC_P(struct packet_struct)) == NULL) { @@ -643,20 +681,20 @@ static struct packet_struct *copy_dgram_packet(struct packet_struct *packet) ******************************************************************/ struct packet_struct *copy_packet(struct packet_struct *packet) -{ +{ if(packet->packet_type == NMB_PACKET) return copy_nmb_packet(packet); else if (packet->packet_type == DGRAM_PACKET) return copy_dgram_packet(packet); return NULL; } - + /******************************************************************* Free up any resources associated with an nmb packet. ******************************************************************/ static void free_nmb_packet(struct nmb_packet *nmb) -{ +{ SAFE_FREE(nmb->answers); SAFE_FREE(nmb->nsrecs); SAFE_FREE(nmb->additional); @@ -667,7 +705,7 @@ static void free_nmb_packet(struct nmb_packet *nmb) ******************************************************************/ static void free_dgram_packet(struct dgram_packet *nmb) -{ +{ /* We have nothing to do for a dgram packet. */ } @@ -676,8 +714,8 @@ static void free_dgram_packet(struct dgram_packet *nmb) ******************************************************************/ void free_packet(struct packet_struct *packet) -{ - if (packet->locked) +{ + if (packet->locked) return; if (packet->packet_type == NMB_PACKET) free_nmb_packet(&packet->packet.nmb); @@ -692,7 +730,9 @@ void free_packet(struct packet_struct *packet) ******************************************************************/ struct packet_struct *parse_packet(char *buf,int length, - enum packet_type packet_type) + enum packet_type packet_type, + struct in_addr ip, + int port) { struct packet_struct *p; BOOL ok=False; @@ -703,8 +743,8 @@ struct packet_struct *parse_packet(char *buf,int length, p->next = NULL; p->prev = NULL; - p->ip = lastip; - p->port = lastport; + p->ip = ip; + p->port = port; p->locked = False; p->timestamp = time(NULL); p->packet_type = packet_type; @@ -713,7 +753,7 @@ struct packet_struct *parse_packet(char *buf,int length, case NMB_PACKET: ok = parse_nmb(buf,length,&p->packet.nmb); break; - + case DGRAM_PACKET: ok = parse_dgram(buf,length,&p->packet.dgram); break; @@ -735,27 +775,34 @@ struct packet_struct *parse_packet(char *buf,int length, struct packet_struct *read_packet(int fd,enum packet_type packet_type) { struct packet_struct *packet; + struct sockaddr_storage sa; + struct sockaddr_in *si = (struct sockaddr_in *)&sa; char buf[MAX_DGRAM_SIZE]; int length; - - length = read_udp_socket(fd,buf,sizeof(buf)); - if (length < MIN_DGRAM_SIZE) - return(NULL); - - packet = parse_packet(buf, length, packet_type); + + length = read_udp_v4_socket(fd,buf,sizeof(buf),&sa); + if (length < MIN_DGRAM_SIZE || sa.ss_family != AF_INET) { + return NULL; + } + + packet = parse_packet(buf, + length, + packet_type, + si->sin_addr, + si->sin_port); if (!packet) return NULL; packet->fd = fd; - + num_good_receives++; - + DEBUG(5,("Received a packet of len %d from (%s) port %d\n", length, inet_ntoa(packet->ip), packet->port ) ); - + return(packet); } - + /******************************************************************* Send a udp packet on a already open socket. ******************************************************************/ @@ -771,16 +818,17 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) putip((char *)&sock_out.sin_addr,(char *)&ip); sock_out.sin_port = htons( port ); sock_out.sin_family = AF_INET; - + DEBUG( 5, ( "Sending a packet of len %d to (%s) on port %d\n", len, inet_ntoa(ip), port ) ); /* * Patch to fix asynch error notifications from Linux kernel. */ - + for (i = 0; i < 5; i++) { - ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, sizeof(sock_out)) >= 0); + ret = (sendto(fd,buf,len,0,(struct sockaddr *)&sock_out, + sizeof(sock_out)) >= 0); if (ret || errno != ECONNREFUSED) break; } @@ -797,48 +845,41 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port) /******************************************************************* Build a dgram packet ready for sending. - - XXXX This currently doesn't handle packets too big for one - datagram. It should split them and use the packet_offset, more and - first flags to handle the fragmentation. Yuck. - - [...but it isn't clear that we would ever need to send a - a fragmented NBT Datagram. The IP layer does its own - fragmentation to ensure that messages can fit into the path - MTU. It *is* important to be able to receive and rebuild - fragmented NBT datagrams, just in case someone out there - really has implemented this 'feature'. crh -)------ ] - + If buf == NULL this is a length calculation. ******************************************************************/ -static int build_dgram(char *buf,struct packet_struct *p) +static int build_dgram(char *buf, size_t len, struct packet_struct *p) { struct dgram_packet *dgram = &p->packet.dgram; unsigned char *ubuf = (unsigned char *)buf; int offset=0; /* put in the header */ - ubuf[0] = dgram->header.msg_type; - ubuf[1] = (((int)dgram->header.flags.node_type)<<2); - if (dgram->header.flags.more) - ubuf[1] |= 1; - if (dgram->header.flags.first) - ubuf[1] |= 2; - RSSVAL(ubuf,2,dgram->header.dgm_id); - putip(ubuf+4,(char *)&dgram->header.source_ip); - RSSVAL(ubuf,8,dgram->header.source_port); - RSSVAL(ubuf,12,dgram->header.packet_offset); + if (buf) { + ubuf[0] = dgram->header.msg_type; + ubuf[1] = (((int)dgram->header.flags.node_type)<<2); + if (dgram->header.flags.more) + ubuf[1] |= 1; + if (dgram->header.flags.first) + ubuf[1] |= 2; + RSSVAL(ubuf,2,dgram->header.dgm_id); + putip(ubuf+4,(char *)&dgram->header.source_ip); + RSSVAL(ubuf,8,dgram->header.source_port); + RSSVAL(ubuf,12,dgram->header.packet_offset); + } offset = 14; if (dgram->header.msg_type == 0x10 || dgram->header.msg_type == 0x11 || - dgram->header.msg_type == 0x12) { + dgram->header.msg_type == 0x12) { offset += put_nmb_name((char *)ubuf,offset,&dgram->source_name); offset += put_nmb_name((char *)ubuf,offset,&dgram->dest_name); } - memcpy(ubuf+offset,dgram->data,dgram->datasize); + if (buf) { + memcpy(ubuf+offset,dgram->data,dgram->datasize); + } offset += dgram->datasize; /* automatically set the dgm_length @@ -846,9 +887,11 @@ static int build_dgram(char *buf,struct packet_struct *p) * include the fourteen-byte header. crh */ dgram->header.dgm_length = (offset - 14); - RSSVAL(ubuf,10,dgram->header.dgm_length); + if (buf) { + RSSVAL(ubuf,10,dgram->header.dgm_length); + } - return(offset); + return offset; } /******************************************************************* @@ -879,59 +922,90 @@ BOOL nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) /******************************************************************* Build a nmb packet ready for sending. - - XXXX this currently relies on not being passed something that expands - to a packet too big for the buffer. Eventually this should be - changed to set the trunc bit so the receiver can request the rest - via tcp (when that becomes supported) + If buf == NULL this is a length calculation. ******************************************************************/ -static int build_nmb(char *buf,struct packet_struct *p) +static int build_nmb(char *buf, size_t len, struct packet_struct *p) { struct nmb_packet *nmb = &p->packet.nmb; unsigned char *ubuf = (unsigned char *)buf; int offset=0; + if (len && len < 12) { + return 0; + } + /* put in the header */ - RSSVAL(ubuf,offset,nmb->header.name_trn_id); - ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; - if (nmb->header.response) - ubuf[offset+2] |= (1<<7); - if (nmb->header.nm_flags.authoritative && - nmb->header.response) - ubuf[offset+2] |= 0x4; - if (nmb->header.nm_flags.trunc) - ubuf[offset+2] |= 0x2; - if (nmb->header.nm_flags.recursion_desired) - ubuf[offset+2] |= 0x1; - if (nmb->header.nm_flags.recursion_available && - nmb->header.response) - ubuf[offset+3] |= 0x80; - if (nmb->header.nm_flags.bcast) - ubuf[offset+3] |= 0x10; - ubuf[offset+3] |= (nmb->header.rcode & 0xF); - - RSSVAL(ubuf,offset+4,nmb->header.qdcount); - RSSVAL(ubuf,offset+6,nmb->header.ancount); - RSSVAL(ubuf,offset+8,nmb->header.nscount); - RSSVAL(ubuf,offset+10,nmb->header.arcount); - + if (buf) { + RSSVAL(ubuf,offset,nmb->header.name_trn_id); + ubuf[offset+2] = (nmb->header.opcode & 0xF) << 3; + if (nmb->header.response) + ubuf[offset+2] |= (1<<7); + if (nmb->header.nm_flags.authoritative && + nmb->header.response) + ubuf[offset+2] |= 0x4; + if (nmb->header.nm_flags.trunc) + ubuf[offset+2] |= 0x2; + if (nmb->header.nm_flags.recursion_desired) + ubuf[offset+2] |= 0x1; + if (nmb->header.nm_flags.recursion_available && + nmb->header.response) + ubuf[offset+3] |= 0x80; + if (nmb->header.nm_flags.bcast) + ubuf[offset+3] |= 0x10; + ubuf[offset+3] |= (nmb->header.rcode & 0xF); + + RSSVAL(ubuf,offset+4,nmb->header.qdcount); + RSSVAL(ubuf,offset+6,nmb->header.ancount); + RSSVAL(ubuf,offset+8,nmb->header.nscount); + RSSVAL(ubuf,offset+10,nmb->header.arcount); + } + offset += 12; if (nmb->header.qdcount) { /* XXXX this doesn't handle a qdcount of > 1 */ - offset += put_nmb_name((char *)ubuf,offset,&nmb->question.question_name); - RSSVAL(ubuf,offset,nmb->question.question_type); - RSSVAL(ubuf,offset+2,nmb->question.question_class); + if (len) { + /* Length check. */ + int extra = put_nmb_name(NULL,offset, + &nmb->question.question_name); + if (offset + extra > len) { + return 0; + } + } + offset += put_nmb_name((char *)ubuf,offset, + &nmb->question.question_name); + if (buf) { + RSSVAL(ubuf,offset,nmb->question.question_type); + RSSVAL(ubuf,offset+2,nmb->question.question_class); + } offset += 4; } - if (nmb->header.ancount) + if (nmb->header.ancount) { + if (len) { + /* Length check. */ + int extra = put_res_rec(NULL,offset,nmb->answers, + nmb->header.ancount); + if (offset + extra > len) { + return 0; + } + } offset += put_res_rec((char *)ubuf,offset,nmb->answers, nmb->header.ancount); + } - if (nmb->header.nscount) + if (nmb->header.nscount) { + if (len) { + /* Length check. */ + int extra = put_res_rec(NULL,offset,nmb->nsrecs, + nmb->header.nscount); + if (offset + extra > len) { + return 0; + } + } offset += put_res_rec((char *)ubuf,offset,nmb->nsrecs, nmb->header.nscount); + } /* * The spec says we must put compressed name pointers @@ -941,37 +1015,53 @@ static int build_nmb(char *buf,struct packet_struct *p) */ if((nmb->header.response == False) && - ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || - (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || - (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || - (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && - (nmb->header.arcount == 1)) { - - offset += put_compressed_name_ptr(ubuf,offset,nmb->additional,12); - + ((nmb->header.opcode == NMB_NAME_REG_OPCODE) || + (nmb->header.opcode == NMB_NAME_RELEASE_OPCODE) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_8) || + (nmb->header.opcode == NMB_NAME_REFRESH_OPCODE_9) || + (nmb->header.opcode == NMB_NAME_MULTIHOMED_REG_OPCODE)) && + (nmb->header.arcount == 1)) { + + if (len) { + /* Length check. */ + int extra = put_compressed_name_ptr(NULL,offset, + nmb->additional,12); + if (offset + extra > len) { + return 0; + } + } + offset += put_compressed_name_ptr(ubuf,offset, + nmb->additional,12); } else if (nmb->header.arcount) { + if (len) { + /* Length check. */ + int extra = put_res_rec(NULL,offset,nmb->additional, + nmb->header.arcount); + if (offset + extra > len) { + return 0; + } + } offset += put_res_rec((char *)ubuf,offset,nmb->additional, - nmb->header.arcount); + nmb->header.arcount); } - return(offset); + return offset; } /******************************************************************* Linearise a packet. ******************************************************************/ -int build_packet(char *buf, struct packet_struct *p) +int build_packet(char *buf, size_t buflen, struct packet_struct *p) { int len = 0; switch (p->packet_type) { case NMB_PACKET: - len = build_nmb(buf,p); + len = build_nmb(buf,buflen,p); break; case DGRAM_PACKET: - len = build_dgram(buf,p); + len = build_dgram(buf,buflen,p); break; } @@ -989,7 +1079,7 @@ BOOL send_packet(struct packet_struct *p) memset(buf,'\0',sizeof(buf)); - len = build_packet(buf, p); + len = build_packet(buf, sizeof(buf), p); if (!len) return(False); @@ -1015,16 +1105,17 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) if ((ret = sys_select_intr(fd+1,&fds,NULL,NULL,&timeout)) == -1) { /* errno should be EBADF or EINVAL. */ - DEBUG(0,("select returned -1, errno = %s (%d)\n", strerror(errno), errno)); + DEBUG(0,("select returned -1, errno = %s (%d)\n", + strerror(errno), errno)); return NULL; } if (ret == 0) /* timeout */ return NULL; - if (FD_ISSET(fd,&fds)) + if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); - + return(NULL); } @@ -1057,7 +1148,8 @@ struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id) The timeout is in milliseconds. ***************************************************************************/ -struct packet_struct *receive_dgram_packet(int fd, int t, const char *mailslot_name) +struct packet_struct *receive_dgram_packet(int fd, int t, + const char *mailslot_name) { struct packet_struct *p; @@ -1114,8 +1206,8 @@ int matching_quad_bits(unsigned char *p1, unsigned char *p2) if ((p1[i] & (1<<(7-j))) != (p2[i] & (1<<(7-j)))) break; ret++; - } - + } + return ret; } @@ -1127,7 +1219,8 @@ static unsigned char sort_ip[4]; static int name_query_comp(unsigned char *p1, unsigned char *p2) { - return matching_quad_bits(p2+2, sort_ip) - matching_quad_bits(p1+2, sort_ip); + return matching_quad_bits(p2+2, sort_ip) - + matching_quad_bits(p1+2, sort_ip); } /**************************************************************************** @@ -1163,7 +1256,7 @@ char *dns_to_netbios_name(const char *dns_name) int i; StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); netbios_name[15] = 0; - + /* ok. this is because of a stupid microsoft-ism. if the called host name contains a '.', microsoft clients expect you to truncate the netbios name up to and including the '.' this even applies, by @@ -1300,7 +1393,7 @@ static char *name_ptr(char *buf,int ofs) } else { return(buf+ofs); } -} +} /**************************************************************************** Extract a netbios name from a buf (into a unix string) return name type. @@ -1316,7 +1409,7 @@ int name_extract(char *buf,int ofs, fstring name) return(0); return(name_interpret(p,name)); } - + /**************************************************************************** Return the total storage length of a mangled name. ****************************************************************************/ diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 6f85f36a62..f5837f321c 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -1,21 +1,21 @@ -/* +/* Unix SMB/CIFS implementation. handle unexpected packets Copyright (C) Andrew Tridgell 2000 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . - + */ #include "includes.h" @@ -29,13 +29,12 @@ struct unexpected_key { int count; }; - - /**************************************************************************** - all unexpected packets are passed in here, to be stored in a unexpected + All unexpected packets are passed in here, to be stored in a unexpected packet database. This allows nmblookup and other tools to receive packets - erroneoously sent to the wrong port by broken MS systems - **************************************************************************/ + erroneoously sent to the wrong port by broken MS systems. +**************************************************************************/ + void unexpected_packet(struct packet_struct *p) { static int count; @@ -43,9 +42,10 @@ void unexpected_packet(struct packet_struct *p) struct unexpected_key key; char buf[1024]; int len=0; + uint32_t enc_ip; if (!tdbd) { - tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0, + tdbd = tdb_open_log(lock_path("unexpected.tdb"), 0, TDB_CLEAR_IF_FIRST|TDB_DEFAULT, O_RDWR | O_CREAT, 0644); if (!tdbd) { @@ -55,8 +55,13 @@ void unexpected_packet(struct packet_struct *p) } memset(buf,'\0',sizeof(buf)); - - len = build_packet(buf, p); + + /* Encode the ip addr and port. */ + enc_ip = ntohl(p->ip.s_addr); + SIVAL(buf,0,enc_ip); + SSVAL(buf,4,p->port); + + len = build_packet(&buf[6], sizeof(buf)-6, p) + 6; key.packet_type = p->packet_type; key.timestamp = p->timestamp; @@ -74,8 +79,9 @@ void unexpected_packet(struct packet_struct *p) static time_t lastt; /**************************************************************************** -delete the record if it is too old - **************************************************************************/ + Delete the record if it is too old. +**************************************************************************/ + static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct unexpected_key key; @@ -91,8 +97,9 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st /**************************************************************************** -delete all old unexpected packets - **************************************************************************/ + Delete all old unexpected packets. +**************************************************************************/ + void clear_unexpected(time_t t) { if (!tdbd) return; @@ -112,22 +119,39 @@ static enum packet_type match_type; static const char *match_name; /**************************************************************************** -tdb traversal fn to find a matching 137 packet - **************************************************************************/ + tdb traversal fn to find a matching 137 packet. +**************************************************************************/ + static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) { struct unexpected_key key; + struct in_addr ip; + uint32_t enc_ip; + int port; struct packet_struct *p; memcpy(&key, kbuf.dptr, sizeof(key)); if (key.packet_type != match_type) return 0; - p = parse_packet((char *)dbuf.dptr, dbuf.dsize, match_type); + if (dbuf.dsize < 6) { + return 0; + } + + /* Decode the ip addr and port. */ + enc_ip = IVAL(dbuf.dptr,0); + ip.s_addr = htonl(enc_ip); + port = SVAL(dbuf.dptr,4); + + p = parse_packet((char *)&dbuf.dptr[6], + dbuf.dsize-6, + match_type, + ip, + port); - if ((match_type == NMB_PACKET && + if ((match_type == NMB_PACKET && p->packet.nmb.header.name_trn_id == match_id) || - (match_type == DGRAM_PACKET && + (match_type == DGRAM_PACKET && match_mailslot_name(p, match_name))) { matched_packet = p; return -1; @@ -138,11 +162,11 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void return 0; } - /**************************************************************************** -check for a particular packet in the unexpected packet queue - **************************************************************************/ -struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, + Check for a particular packet in the unexpected packet queue. +**************************************************************************/ + +struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, const char *mailslot_name) { TDB_CONTEXT *tdb2; -- cgit From 3dbb3d4c269ecf28f25d857aa8a4e5c1109ee5e8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Oct 2007 01:11:33 +0000 Subject: r25510: Now we're returning the port instead of using a global, remember to use ntohs. Hopefully will fix the build farm. Jeremy. (This used to be commit 5174acccb589edbfbe4ba633f4178f7200d7d6c4) --- source3/libsmb/nmblib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 74deb91a73..61e24eb6f9 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -789,7 +789,7 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type) length, packet_type, si->sin_addr, - si->sin_port); + ntohs(si->sin_port)); if (!packet) return NULL; -- cgit From 9d1a95ac9c780339c80cbb0fe3fdf3a78d8c7059 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 5 Oct 2007 21:28:54 +0000 Subject: r25533: remove a pstring (This used to be commit 0f2552e20fb66b0b80006a8a7b999ccf6f54c656) --- source3/libsmb/nterr.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index d88e650c9c..774e50e700 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -647,7 +647,6 @@ nt_err_code_struct nt_err_desc[] = const char *nt_errstr(NTSTATUS nt_code) { - static pstring msg; int idx = 0; #ifdef HAVE_LDAP @@ -656,8 +655,6 @@ const char *nt_errstr(NTSTATUS nt_code) } #endif - slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); - while (nt_errs[idx].nt_errstr != NULL) { if (NT_STATUS_EQUAL(nt_errs[idx].nt_errcode, nt_code)) { return nt_errs[idx].nt_errstr; @@ -665,7 +662,8 @@ const char *nt_errstr(NTSTATUS nt_code) idx++; } - return msg; + return talloc_asprintf(talloc_tos(), "NT code 0x%08x", + NT_STATUS_V(nt_code)); } /************************************************************************ @@ -688,28 +686,6 @@ const char *get_friendly_nt_error_msg(NTSTATUS nt_code) return nt_errstr(nt_code); } -/***************************************************************************** - Returns an NT_STATUS constant as a string for inclusion in autogen C code. - *****************************************************************************/ - -const char *get_nt_error_c_code(NTSTATUS nt_code) -{ - static pstring out; - int idx = 0; - - while (nt_errs[idx].nt_errstr != NULL) { - if (NT_STATUS_V(nt_errs[idx].nt_errcode) == - NT_STATUS_V(nt_code)) { - return nt_errs[idx].nt_errstr; - } - idx++; - } - - slprintf(out, sizeof(out), "NT_STATUS(0x%08x)", NT_STATUS_V(nt_code)); - - return out; -} - /***************************************************************************** Returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) *****************************************************************************/ -- cgit From b92212575d370275bf1609cac6bc13c71de472d4 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 5 Oct 2007 22:06:24 +0000 Subject: r25538: Revert r25533 (This used to be commit 1e02208c43cb27ca4b43d268a7f0324f2a9b2cfd) --- source3/libsmb/nterr.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 774e50e700..d88e650c9c 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -647,6 +647,7 @@ nt_err_code_struct nt_err_desc[] = const char *nt_errstr(NTSTATUS nt_code) { + static pstring msg; int idx = 0; #ifdef HAVE_LDAP @@ -655,6 +656,8 @@ const char *nt_errstr(NTSTATUS nt_code) } #endif + slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); + while (nt_errs[idx].nt_errstr != NULL) { if (NT_STATUS_EQUAL(nt_errs[idx].nt_errcode, nt_code)) { return nt_errs[idx].nt_errstr; @@ -662,8 +665,7 @@ const char *nt_errstr(NTSTATUS nt_code) idx++; } - return talloc_asprintf(talloc_tos(), "NT code 0x%08x", - NT_STATUS_V(nt_code)); + return msg; } /************************************************************************ @@ -686,6 +688,28 @@ const char *get_friendly_nt_error_msg(NTSTATUS nt_code) return nt_errstr(nt_code); } +/***************************************************************************** + Returns an NT_STATUS constant as a string for inclusion in autogen C code. + *****************************************************************************/ + +const char *get_nt_error_c_code(NTSTATUS nt_code) +{ + static pstring out; + int idx = 0; + + while (nt_errs[idx].nt_errstr != NULL) { + if (NT_STATUS_V(nt_errs[idx].nt_errcode) == + NT_STATUS_V(nt_code)) { + return nt_errs[idx].nt_errstr; + } + idx++; + } + + slprintf(out, sizeof(out), "NT_STATUS(0x%08x)", NT_STATUS_V(nt_code)); + + return out; +} + /***************************************************************************** Returns the NT_STATUS constant matching the string supplied (as an NTSTATUS) *****************************************************************************/ -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/libsmb/cliconnect.c | 25 ++- source3/libsmb/clidgram.c | 2 +- source3/libsmb/clientgen.c | 96 ++------ source3/libsmb/clierror.c | 5 - source3/libsmb/clifile.c | 44 ++-- source3/libsmb/clifsinfo.c | 324 --------------------------- source3/libsmb/clilist.c | 4 +- source3/libsmb/climessage.c | 6 +- source3/libsmb/clioplock.c | 2 +- source3/libsmb/cliprint.c | 4 +- source3/libsmb/clireadwrite.c | 14 +- source3/libsmb/clitrans.c | 8 +- source3/libsmb/errormap.c | 106 --------- source3/libsmb/libsmbclient.c | 76 ++++--- source3/libsmb/smb_seal.c | 496 ------------------------------------------ 15 files changed, 112 insertions(+), 1100 deletions(-) delete mode 100644 source3/libsmb/smb_seal.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 820a904ea4..78cc63de50 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -98,7 +98,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,10, 0, True); + set_message(cli->outbuf,10, 0, True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -168,7 +168,7 @@ static NTSTATUS cli_session_setup_guest(struct cli_state *cli) uint32 capabilities = cli_session_setup_capabilities(cli); memset(cli->outbuf, '\0', smb_size); - set_message(NULL,cli->outbuf,13,0,True); + set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -228,7 +228,7 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); memset(cli->outbuf, '\0', smb_size); - set_message(NULL,cli->outbuf,13,0,True); + set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -377,7 +377,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,13,0,True); + set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -457,7 +457,7 @@ static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,12,0,True); + set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -765,7 +765,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use } } - /* we have a reference counter on ntlmssp_state, if we are signing + /* we have a reference conter on ntlmssp_state, if we are signing then the state will be kept by the signing engine */ ntlmssp_end(&ntlmssp_state); @@ -978,6 +978,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, } return NT_STATUS_OK; + } /**************************************************************************** @@ -987,7 +988,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, BOOL cli_ulogoff(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,2,0,True); + set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBulogoffX); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); @@ -1064,7 +1065,7 @@ BOOL cli_send_tconX(struct cli_state *cli, slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); - set_message(NULL,cli->outbuf,4, 0, True); + set_message(cli->outbuf,4, 0, True); SCVAL(cli->outbuf,smb_com,SMBtconX); cli_setup_packet(cli); @@ -1115,7 +1116,7 @@ BOOL cli_send_tconX(struct cli_state *cli, BOOL cli_tdis(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,0,0,True); + set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBtdis); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1147,7 +1148,7 @@ void cli_negprot_send(struct cli_state *cli) memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ - set_message(NULL,cli->outbuf,0,0,True); + set_message(cli->outbuf,0,0,True); p = smb_buf(cli->outbuf); for (numprots=0; @@ -1187,7 +1188,7 @@ BOOL cli_negprot(struct cli_state *cli) numprots++) plength += strlen(prots[numprots].name)+2; - set_message(NULL,cli->outbuf,0,plength,True); + set_message(cli->outbuf,0,plength,True); p = smb_buf(cli->outbuf); for (numprots=0; @@ -1720,7 +1721,7 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf, 0, 0, True); + set_message(cli->outbuf, 0, 0, True); SCVAL(cli->outbuf,smb_com,SMBtcon); cli_setup_packet(cli); diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 7a6ee17f4a..f170834fa9 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -69,7 +69,7 @@ BOOL cli_send_mailslot(struct messaging_context *msg_ctx, /* Setup the smb part. */ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ memcpy(tmp,ptr,4); - set_message(NULL,ptr,17,strlen(mailslot) + 1 + len,True); + set_message(ptr,17,strlen(mailslot) + 1 + len,True); memcpy(ptr,tmp,4); SCVAL(ptr,smb_com,SMBtrans); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index a23e0184d7..1e3af9a3d7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -48,18 +48,15 @@ int cli_set_port(struct cli_state *cli, int port) *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. The timeout is in milliseconds - This is exactly the same as receive_smb except that it can be set to never return + This is exactly the same as receive_smb except that it never returns a session keepalive packet (just as receive_smb used to do). receive_smb was changed to return keepalives as the oplock processing means this call should never go into a blocking read. ****************************************************************************/ -static ssize_t client_receive_smb(struct cli_state *cli, BOOL eat_keepalives, size_t maxlen) +static ssize_t client_receive_smb(int fd,char *buffer, unsigned int timeout, size_t maxlen) { ssize_t len; - int fd = cli->fd; - char *buffer = cli->inbuf; - unsigned int timeout = cli->timeout; for(;;) { len = receive_smb_raw(fd, buffer, timeout, maxlen); @@ -71,22 +68,8 @@ static ssize_t client_receive_smb(struct cli_state *cli, BOOL eat_keepalives, si } /* Ignore session keepalive packets. */ - if (eat_keepalives && (CVAL(buffer,0) == SMBkeepalive)) { - continue; - } - break; - } - - if (cli_encryption_on(cli)) { - NTSTATUS status = cli_decrypt_message(cli); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", - nt_errstr(status))); - cli->smb_rw_error = READ_BAD_DECRYPT; - close(cli->fd); - cli->fd = -1; - return -1; - } + if(CVAL(buffer,0) != SMBkeepalive) + break; } show_msg(buffer); return len; @@ -96,7 +79,7 @@ static ssize_t client_receive_smb(struct cli_state *cli, BOOL eat_keepalives, si Recv an smb. ****************************************************************************/ -BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) +BOOL cli_receive_smb(struct cli_state *cli) { ssize_t len; @@ -105,12 +88,7 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) return False; again: - len = client_receive_smb(cli, eat_keepalives, 0); - - if (len >= 0 && !eat_keepalives && (CVAL(cli->inbuf,0) == SMBkeepalive)) { - /* Give back the keepalive. */ - return True; - } + len = client_receive_smb(cli->fd,cli->inbuf,cli->timeout, 0); if (len > 0) { /* it might be an oplock break request */ @@ -166,29 +144,10 @@ BOOL cli_receive_smb_internal(struct cli_state *cli, BOOL eat_keepalives) close(cli->fd); cli->fd = -1; return False; - } - + }; return True; } -/**************************************************************************** - Recv an smb - eat keepalives. -****************************************************************************/ - -BOOL cli_receive_smb(struct cli_state *cli) -{ - return cli_receive_smb_internal(cli, True); -} - -/**************************************************************************** - Recv an smb - return keepalives. -****************************************************************************/ - -BOOL cli_receive_smb_return_keepalive(struct cli_state *cli) -{ - return cli_receive_smb_internal(cli, False); -} - /**************************************************************************** Read the data portion of a readX smb. The timeout is in milliseconds @@ -205,7 +164,6 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) /**************************************************************************** Read a smb readX header. - We can only use this if encryption and signing are off. ****************************************************************************/ BOOL cli_receive_smb_readX_header(struct cli_state *cli) @@ -218,7 +176,7 @@ BOOL cli_receive_smb_readX_header(struct cli_state *cli) again: /* Read up to the size of a readX header reply. */ - len = client_receive_smb(cli, True, (smb_size - 4) + 24); + len = client_receive_smb(cli->fd, cli->inbuf, cli->timeout, (smb_size - 4) + 24); if (len > 0) { /* it might be an oplock break request */ @@ -296,7 +254,7 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); ret = write_data(fd,buf,len); - + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); if(ret <= 0) DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", @@ -314,36 +272,18 @@ BOOL cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; - char *buf_out = cli->outbuf; - BOOL enc_on = cli_encryption_on(cli); /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ - if (cli->fd == -1) { + if (cli->fd == -1) return False; - } cli_calculate_sign_mac(cli); - if (enc_on) { - NTSTATUS status = cli_encrypt_message(cli, &buf_out); - if (!NT_STATUS_IS_OK(status)) { - close(cli->fd); - cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; - DEBUG(0,("Error in encrypting client message. Error %s\n", - nt_errstr(status) )); - return False; - } - } - - len = smb_len(buf_out) + 4; + len = smb_len(cli->outbuf) + 4; while (nwritten < len) { - ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); + ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); if (ret <= 0) { - if (enc_on) { - cli_free_enc_buffer(cli, buf_out); - } close(cli->fd); cli->fd = -1; cli->smb_rw_error = WRITE_ERROR; @@ -353,14 +293,10 @@ BOOL cli_send_smb(struct cli_state *cli) } nwritten += ret; } - - cli_free_enc_buffer(cli, buf_out); - /* Increment the mid so we can tell between responses. */ cli->mid++; - if (!cli->mid) { + if (!cli->mid) cli->mid++; - } return True; } @@ -401,7 +337,7 @@ void cli_setup_packet(struct cli_state *cli) void cli_setup_bcc(struct cli_state *cli, void *p) { - set_message_bcc(NULL,cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); + set_message_bcc(cli->outbuf, PTR_DIFF(p, smb_buf(cli->outbuf))); } /**************************************************************************** @@ -607,8 +543,6 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->inbuf); cli_free_signing_context(cli); - cli_free_encryption_context(cli); - data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); @@ -689,7 +623,7 @@ BOOL cli_echo(struct cli_state *cli, uint16 num_echos, SMB_ASSERT(length < 1024); memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,1,length,True); + set_message(cli->outbuf,1,length,True); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); SSVAL(cli->outbuf,smb_vwv0,num_echos); diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 374fdfa5e4..be018074eb 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -83,7 +83,6 @@ static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli) case WRITE_ERROR: return NT_STATUS_UNEXPECTED_NETWORK_ERROR; case READ_BAD_SIG: - case READ_BAD_DECRYPT: return NT_STATUS_INVALID_PARAMETER; default: break; @@ -133,10 +132,6 @@ const char *cli_errstr(struct cli_state *cli) slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Server packet had invalid SMB signature!"); break; - case READ_BAD_DECRYPT: - slprintf(cli_error_message, sizeof(cli_error_message) - 1, - "Server packet could not be decrypted !"); - break; default: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Unknown error code %d\n", cli->smb_rw_error ); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 7e29c1bf1a..c7b39f0b8d 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -389,7 +389,7 @@ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,1, 0, True); + set_message(cli->outbuf,1, 0, True); SCVAL(cli->outbuf,smb_com,SMBmv); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -426,7 +426,7 @@ BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf, 4, 0, True); + set_message(cli->outbuf, 4, 0, True); SCVAL(cli->outbuf,smb_com,SMBntrename); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -464,7 +464,7 @@ BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *f memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf, 4, 0, True); + set_message(cli->outbuf, 4, 0, True); SCVAL(cli->outbuf,smb_com,SMBntrename); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -502,7 +502,7 @@ BOOL cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,1, 0,True); + set_message(cli->outbuf,1, 0,True); SCVAL(cli->outbuf,smb_com,SMBunlink); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -547,7 +547,7 @@ BOOL cli_mkdir(struct cli_state *cli, const char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,0, 0,True); + set_message(cli->outbuf,0, 0,True); SCVAL(cli->outbuf,smb_com,SMBmkdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -582,7 +582,7 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,0, 0, True); + set_message(cli->outbuf,0, 0, True); SCVAL(cli->outbuf,smb_com,SMBrmdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -664,7 +664,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,24,0,True); + set_message(cli->outbuf,24,0,True); SCVAL(cli->outbuf,smb_com,SMBntcreateX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -758,7 +758,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,15,0,True); + set_message(cli->outbuf,15,0,True); SCVAL(cli->outbuf,smb_com,SMBopenX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -805,7 +805,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,3,0,True); + set_message(cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -837,7 +837,7 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(NULL,cli->outbuf,8,0,True); + set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -889,7 +889,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(NULL,cli->outbuf,8,0,True); + set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -942,7 +942,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,8,0,True); + set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -994,7 +994,7 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(NULL,cli->outbuf,8,0,True); + set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1049,7 +1049,7 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,8,0,True); + set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1196,7 +1196,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,1,0,True); + set_message(cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBgetattrE); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1248,7 +1248,7 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,0,0,True); + set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBgetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1300,7 +1300,7 @@ BOOL cli_setattrE(struct cli_state *cli, int fd, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,7,0,True); + set_message(cli->outbuf,7,0,True); SCVAL(cli->outbuf,smb_com,SMBsetattrE); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1339,7 +1339,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,8,0,True); + set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBsetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1381,7 +1381,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) *path2 = '\\'; memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,0,0,True); + set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBcheckpath); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1408,7 +1408,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,0,0,True); + set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBdskattr); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1437,7 +1437,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,3,0,True); + set_message(cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBctemp); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1487,7 +1487,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf, 3, 0, True); + set_message(cli->outbuf, 3, 0, True); SCVAL(cli->outbuf,smb_com,SMBioctl); cli_setup_packet(cli); diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 48865c98ca..d2f759b192 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -2,7 +2,6 @@ Unix SMB/CIFS implementation. FS info functions Copyright (C) Stefan (metze) Metzmacher 2003 - Copyright (C) Jeremy Allison 2007. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -302,326 +301,3 @@ cleanup: return ret; } - -/****************************************************************************** - Send/receive the request encryption blob. -******************************************************************************/ - -static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out, DATA_BLOB *param_out) -{ - uint16 setup; - char param[4]; - char *rparam=NULL, *rdata=NULL; - unsigned int rparam_count=0, rdata_count=0; - NTSTATUS status = NT_STATUS_OK; - - setup = TRANSACT2_SETFSINFO; - - SSVAL(param,0,0); - SSVAL(param,2,SMB_REQUEST_TRANSPORT_ENCRYPTION); - - if (!cli_send_trans(cli, SMBtrans2, - NULL, - 0, 0, - &setup, 1, 0, - param, 4, 0, - (char *)in->data, in->length, CLI_BUFFER_SIZE)) { - status = cli_nt_error(cli); - goto out; - } - - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, &rparam_count, - &rdata, &rdata_count)) { - status = cli_nt_error(cli); - goto out; - } - - if (cli_is_error(cli)) { - status = cli_nt_error(cli); - if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - goto out; - } - } - - *out = data_blob(rdata, rdata_count); - *param_out = data_blob(rparam, rparam_count); - - out: - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - return status; -} - -/****************************************************************************** - Make a client state struct. -******************************************************************************/ - -static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type smb_enc_type) -{ - struct smb_trans_enc_state *es = NULL; - es = SMB_MALLOC_P(struct smb_trans_enc_state); - if (!es) { - return NULL; - } - ZERO_STRUCTP(es); - es->smb_enc_type = smb_enc_type; - - if (smb_enc_type == SMB_TRANS_ENC_GSS) { -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss); - if (!es->s.gss_state) { - SAFE_FREE(es); - return NULL; - } - ZERO_STRUCTP(es->s.gss_state); -#else - DEBUG(0,("make_cli_enc_state: no krb5 compiled.\n")); - SAFE_FREE(es); - return NULL; -#endif - } - return es; -} - -/****************************************************************************** - Start a raw ntlmssp encryption. -******************************************************************************/ - -NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, - const char *user, - const char *pass, - const char *domain) -{ - DATA_BLOB blob_in = data_blob_null; - DATA_BLOB blob_out = data_blob_null; - DATA_BLOB param_out = data_blob_null; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_NTLM); - - if (!es) { - return NT_STATUS_NO_MEMORY; - } - status = ntlmssp_client_start(&es->s.ntlmssp_state); - if (!NT_STATUS_IS_OK(status)) { - goto fail; - } - - ntlmssp_want_feature(es->s.ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); - es->s.ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL); - - if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->s.ntlmssp_state, user))) { - goto fail; - } - if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->s.ntlmssp_state, domain))) { - goto fail; - } - if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->s.ntlmssp_state, pass))) { - goto fail; - } - - do { - status = ntlmssp_update(es->s.ntlmssp_state, blob_in, &blob_out); - data_blob_free(&blob_in); - data_blob_free(¶m_out); - if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) { - status = enc_blob_send_receive(cli, &blob_out, &blob_in, ¶m_out); - } - if (param_out.length == 2) { - es->enc_ctx_num = SVAL(param_out.data, 0); - } - data_blob_free(&blob_out); - } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); - - data_blob_free(&blob_in); - - if (NT_STATUS_IS_OK(status)) { - /* Replace the old state, if any. */ - if (cli->trans_enc_state) { - common_free_encryption_state(&cli->trans_enc_state); - } - cli->trans_enc_state = es; - cli->trans_enc_state->enc_on = True; - es = NULL; - } - - fail: - - common_free_encryption_state(&es); - return status; -} - -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - -#ifndef SMB_GSS_REQUIRED_FLAGS -#define SMB_GSS_REQUIRED_FLAGS (GSS_C_CONF_FLAG|GSS_C_INTEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG) -#endif - -/****************************************************************************** - Get client gss blob to send to a server. -******************************************************************************/ - -static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, - const char *service, - const char *host, - NTSTATUS status_in, - DATA_BLOB spnego_blob_in, - DATA_BLOB *p_blob_out) -{ - const char *krb_mechs[] = {OID_KERBEROS5, NULL}; - OM_uint32 ret; - OM_uint32 min; - gss_name_t srv_name; - gss_buffer_desc input_name; - gss_buffer_desc *p_tok_in; - gss_buffer_desc tok_out, tok_in; - DATA_BLOB blob_out = data_blob_null; - DATA_BLOB blob_in = data_blob_null; - char *host_princ_s = NULL; - OM_uint32 ret_flags = 0; - NTSTATUS status = NT_STATUS_OK; - - gss_OID_desc nt_hostbased_service = - {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")}; - - memset(&tok_out, '\0', sizeof(tok_out)); - - /* Get a ticket for the service@host */ - asprintf(&host_princ_s, "%s@%s", service, host); - if (host_princ_s == NULL) { - return NT_STATUS_NO_MEMORY; - } - - input_name.value = host_princ_s; - input_name.length = strlen(host_princ_s) + 1; - - ret = gss_import_name(&min, - &input_name, - &nt_hostbased_service, - &srv_name); - - if (ret != GSS_S_COMPLETE) { - SAFE_FREE(host_princ_s); - return map_nt_error_from_gss(ret, min); - } - - if (spnego_blob_in.length == 0) { - p_tok_in = GSS_C_NO_BUFFER; - } else { - /* Remove the SPNEGO wrapper */ - if (!spnego_parse_auth_response(spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) { - status = NT_STATUS_UNSUCCESSFUL; - goto fail; - } - tok_in.value = blob_in.data; - tok_in.length = blob_in.length; - p_tok_in = &tok_in; - } - - ret = gss_init_sec_context(&min, - GSS_C_NO_CREDENTIAL, /* Use our default cred. */ - &es->s.gss_state->gss_ctx, - srv_name, - GSS_C_NO_OID, /* default OID. */ - GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, - GSS_C_INDEFINITE, /* requested ticket lifetime. */ - NULL, /* no channel bindings */ - p_tok_in, - NULL, /* ignore mech type */ - &tok_out, - &ret_flags, - NULL); /* ignore time_rec */ - - status = map_nt_error_from_gss(ret, min); - if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { - ADS_STATUS adss = ADS_ERROR_GSS(ret, min); - DEBUG(10,("make_cli_gss_blob: gss_init_sec_context failed with %s\n", - ads_errstr(adss))); - goto fail; - } - - if ((ret_flags & SMB_GSS_REQUIRED_FLAGS) != SMB_GSS_REQUIRED_FLAGS) { - status = NT_STATUS_ACCESS_DENIED; - } - - blob_out = data_blob(tok_out.value, tok_out.length); - - /* Wrap in an SPNEGO wrapper */ - *p_blob_out = gen_negTokenTarg(krb_mechs, blob_out); - - fail: - - data_blob_free(&blob_out); - data_blob_free(&blob_in); - SAFE_FREE(host_princ_s); - gss_release_name(&min, &srv_name); - if (tok_out.value) { - gss_release_buffer(&min, &tok_out); - } - return status; -} - -/****************************************************************************** - Start a SPNEGO gssapi encryption context. -******************************************************************************/ - -NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) -{ - DATA_BLOB blob_recv = data_blob_null; - DATA_BLOB blob_send = data_blob_null; - DATA_BLOB param_out = data_blob_null; - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - fstring fqdn; - const char *servicename; - struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_GSS); - - if (!es) { - return NT_STATUS_NO_MEMORY; - } - - name_to_fqdn(fqdn, cli->desthost); - strlower_m(fqdn); - - servicename = "cifs"; - status = make_cli_gss_blob(es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); - if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { - servicename = "host"; - status = make_cli_gss_blob(es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); - if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { - goto fail; - } - } - - do { - data_blob_free(&blob_recv); - status = enc_blob_send_receive(cli, &blob_send, &blob_recv, ¶m_out); - if (param_out.length == 2) { - es->enc_ctx_num = SVAL(param_out.data, 0); - } - data_blob_free(&blob_send); - status = make_cli_gss_blob(es, servicename, fqdn, status, blob_recv, &blob_send); - } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); - data_blob_free(&blob_recv); - - if (NT_STATUS_IS_OK(status)) { - /* Replace the old state, if any. */ - if (cli->trans_enc_state) { - common_free_encryption_state(&cli->trans_enc_state); - } - cli->trans_enc_state = es; - cli->trans_enc_state->enc_on = True; - es = NULL; - } - - fail: - - common_free_encryption_state(&es); - return status; -} -#else -NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) -{ - return NT_STATUS_NOT_SUPPORTED; -} -#endif diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 31012e6011..5da63096b1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -417,7 +417,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,2,0,True); + set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBsearch); @@ -474,7 +474,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,2,0,True); + set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 252f2cd725..46d7c1c3be 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -29,7 +29,7 @@ int cli_message_start_build(struct cli_state *cli, char *host, char *username) /* construct a SMBsendstrt command */ memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,0,0,True); + set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBsendstrt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -74,7 +74,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) char *p; memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,1,0,True); + set_message(cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBsendtxt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -124,7 +124,7 @@ int cli_message_end_build(struct cli_state *cli, int grp) char *p; memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,1,0,True); + set_message(cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBsendend); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index 041de41cad..387c40b401 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -31,7 +31,7 @@ BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) cli->outbuf = buf; memset(buf,'\0',smb_size); - set_message(NULL,buf,8,0,True); + set_message(buf,8,0,True); SCVAL(buf,smb_com,SMBlockingX); SSVAL(buf,smb_tid, cli->cnum); diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 08737f87e4..9e55e5cef3 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -193,7 +193,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,15,0,True); + set_message(cli->outbuf,15,0,True); SCVAL(cli->outbuf,smb_com,SMBsplopen); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -240,7 +240,7 @@ BOOL cli_spl_close(struct cli_state *cli, int fnum) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,3,0,True); + set_message(cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBsplclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 7e479dc00a..ed80dfaf1a 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -34,7 +34,7 @@ static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, if ((SMB_BIG_UINT)offset >> 32) bigoffset = True; - set_message(NULL,cli->outbuf,bigoffset ? 12 : 10,0,True); + set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); SCVAL(cli->outbuf,smb_com,SMBreadX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -76,9 +76,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ * rounded down to a multiple of 1024. */ - if (client_is_signing_on(cli) == False && - cli_encryption_on(cli) == False && - (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { + if (client_is_signing_on(cli) == False && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { readsize = CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; } else if (cli->capabilities & CAP_LARGE_READX) { if (cli->is_samba) { @@ -205,7 +203,7 @@ static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,10,0,True); + set_message(cli->outbuf,10,0,True); SCVAL(cli->outbuf,smb_com,SMBreadbraw); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -314,9 +312,9 @@ static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, } if (large_writex) - set_message(NULL,cli->outbuf,14,0,True); + set_message(cli->outbuf,14,0,True); else - set_message(NULL,cli->outbuf,12,0,True); + set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBwriteX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -428,7 +426,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,5, 0,True); + set_message(cli->outbuf,5, 0,True); SCVAL(cli->outbuf,smb_com,SMBwrite); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 752983377c..e859dce956 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -43,7 +43,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,14+lsetup,0,True); + set_message(cli->outbuf,14+lsetup,0,True); SCVAL(cli->outbuf,smb_com,trans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); @@ -112,7 +112,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - set_message(NULL,cli->outbuf,trans==SMBtrans?8:9,0,True); + set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); outparam = smb_buf(cli->outbuf); @@ -358,7 +358,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); memset(cli->outbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,19+lsetup,0,True); + set_message(cli->outbuf,19+lsetup,0,True); SCVAL(cli->outbuf,smb_com,SMBnttrans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); @@ -419,7 +419,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - set_message(NULL,cli->outbuf,18,0,True); + set_message(cli->outbuf,18,0,True); SCVAL(cli->outbuf,smb_com,SMBnttranss); /* XXX - these should probably be aligned */ diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index 412126eeca..ce826ae999 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -4,7 +4,6 @@ * Copyright (C) Andrew Tridgell 2001 * Copyright (C) Andrew Bartlett 2001 * Copyright (C) Tim Potter 2000 - * Copyright (C) Jeremy Allison 2007 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -1503,108 +1502,3 @@ WERROR ntstatus_to_werror(NTSTATUS error) /* a lame guess */ return W_ERROR(NT_STATUS_V(error) & 0xffff); } - -#if defined(HAVE_GSSAPI) -/******************************************************************************* - Map between gssapi errors and NT status. I made these up :-(. JRA. -*******************************************************************************/ - -static const struct { - unsigned long gss_err; - NTSTATUS ntstatus; -} gss_to_ntstatus_errormap[] = { -#if defined(GSS_S_CALL_INACCESSIBLE_READ) - {GSS_S_CALL_INACCESSIBLE_READ, NT_STATUS_INVALID_PARAMETER}, -#endif -#if defined(GSS_S_CALL_INACCESSIBLE_WRITE) - {GSS_S_CALL_INACCESSIBLE_WRITE, NT_STATUS_INVALID_PARAMETER}, -#endif -#if defined(GSS_S_CALL_BAD_STRUCTURE) - {GSS_S_CALL_BAD_STRUCTURE, NT_STATUS_INVALID_PARAMETER}, -#endif -#if defined(GSS_S_BAD_MECH) - {GSS_S_BAD_MECH, NT_STATUS_INVALID_PARAMETER}, -#endif -#if defined(GSS_S_BAD_NAME) - {GSS_S_BAD_NAME, NT_STATUS_INVALID_ACCOUNT_NAME}, -#endif -#if defined(GSS_S_BAD_NAMETYPE) - {GSS_S_BAD_NAMETYPE, NT_STATUS_INVALID_PARAMETER}, -#endif -#if defined(GSS_S_BAD_BINDINGS) - {GSS_S_BAD_BINDINGS, NT_STATUS_INVALID_PARAMETER}, -#endif -#if defined(GSS_S_BAD_STATUS) - {GSS_S_BAD_STATUS, NT_STATUS_UNSUCCESSFUL}, -#endif -#if defined(GSS_S_BAD_SIG) - {GSS_S_BAD_SIG, NT_STATUS_ACCESS_DENIED}, -#endif -#if defined(GSS_S_NO_CRED) - {GSS_S_NO_CRED, NT_STATUS_ACCESS_DENIED}, -#endif -#if defined(GSS_S_NO_CONTEXT) - {GSS_S_NO_CONTEXT, NT_STATUS_ACCESS_DENIED}, -#endif -#if defined(GSS_S_DEFECTIVE_TOKEN) - {GSS_S_DEFECTIVE_TOKEN, NT_STATUS_ACCESS_DENIED}, -#endif -#if defined(GSS_S_DEFECTIVE_CREDENTIAL) - {GSS_S_DEFECTIVE_CREDENTIAL, NT_STATUS_ACCESS_DENIED}, -#endif -#if defined(GSS_S_CREDENTIALS_EXPIRED) - {GSS_S_CREDENTIALS_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, -#endif -#if defined(GSS_S_CONTEXT_EXPIRED) - {GSS_S_CONTEXT_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, -#endif -#if defined(GSS_S_BAD_QOP) - {GSS_S_BAD_QOP, NT_STATUS_ACCESS_DENIED}, -#endif -#if defined(GSS_S_UNAUTHORIZED) - {GSS_S_UNAUTHORIZED, NT_STATUS_ACCESS_DENIED}, -#endif -#if defined(GSS_S_UNAVAILABLE) - {GSS_S_UNAVAILABLE, NT_STATUS_UNSUCCESSFUL}, -#endif -#if defined(GSS_S_DUPLICATE_ELEMENT) - {GSS_S_DUPLICATE_ELEMENT, NT_STATUS_INVALID_PARAMETER}, -#endif -#if defined(GSS_S_NAME_NOT_MN) - {GSS_S_NAME_NOT_MN, NT_STATUS_INVALID_PARAMETER}, -#endif - { 0, NT_STATUS_OK } -}; - -/********************************************************************* - Map an NT error code from a gssapi error code. -*********************************************************************/ - -NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor) -{ - int i = 0; - - if (gss_maj == GSS_S_COMPLETE) { - return NT_STATUS_OK; - } - - if (gss_maj == GSS_S_CONTINUE_NEEDED) { - return NT_STATUS_MORE_PROCESSING_REQUIRED; - } - - if (gss_maj == GSS_S_FAILURE) { - return map_nt_error_from_unix((int)minor); - } - - /* Look through list */ - while(gss_to_ntstatus_errormap[i].gss_err != 0) { - if (gss_to_ntstatus_errormap[i].gss_err == gss_maj) { - return gss_to_ntstatus_errormap[i].ntstatus; - } - i++; - } - - /* Default return */ - return NT_STATUS_ACCESS_DENIED; -} -#endif diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 7394008786..45226a028c 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2471,15 +2471,16 @@ net_share_enum_rpc(struct cli_state *cli, void *state) { int i; - NTSTATUS result; - uint32 enum_hnd; + WERROR result; + ENUM_HND enum_hnd; uint32 info_level = 1; uint32 preferred_len = 0xffffffff; - struct srvsvc_NetShareCtr1 ctr1; - union srvsvc_NetShareCtr ctr; + uint32 type; + SRV_SHARE_INFO_CTR ctr; + fstring name = ""; + fstring comment = ""; void *mem_ctx; struct rpc_pipe_client *pipe_hnd; - uint32 numentries; NTSTATUS nt_status; /* Open the server service pipe */ @@ -2497,28 +2498,37 @@ net_share_enum_rpc(struct cli_state *cli, return -1; } - ZERO_STRUCT(ctr1); - ctr.ctr1 = &ctr1; - /* Issue the NetShareEnum RPC call and retrieve the response */ - enum_hnd = 0; - result = rpccli_srvsvc_NetShareEnum(pipe_hnd, mem_ctx, NULL, - &info_level, &ctr, preferred_len, - &numentries, &enum_hnd); + init_enum_hnd(&enum_hnd, 0); + result = rpccli_srvsvc_net_share_enum(pipe_hnd, + mem_ctx, + info_level, + &ctr, + preferred_len, + &enum_hnd); /* Was it successful? */ - if (!NT_STATUS_IS_OK(result) || numentries == 0) { + if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { /* Nope. Go clean up. */ goto done; } /* For each returned entry... */ - for (i = 0; i < numentries; i++) { + for (i = 0; i < ctr.num_entries; i++) { + + /* pull out the share name */ + rpcstr_pull_unistr2_fstring( + name, &ctr.share.info1[i].info_1_str.uni_netname); + + /* pull out the share's comment */ + rpcstr_pull_unistr2_fstring( + comment, &ctr.share.info1[i].info_1_str.uni_remark); + + /* Get the type value */ + type = ctr.share.info1[i].info_1.type; /* Add this share to the list */ - (*fn)(ctr.ctr1->array[i].name, - ctr.ctr1->array[i].type, - ctr.ctr1->array[i].comment, state); + (*fn)(name, type, comment, state); } done: @@ -2529,7 +2539,7 @@ done: TALLOC_FREE(mem_ctx); /* Tell 'em if it worked */ - return NT_STATUS_IS_OK(result) ? 0 : -1; + return W_ERROR_IS_OK(result) ? 0 : -1; } @@ -4076,7 +4086,7 @@ sec_desc_parse(TALLOC_CTX *ctx, fstring tok; SEC_DESC *ret = NULL; size_t sd_size; - DOM_SID *grp_sid=NULL; + DOM_SID *group_sid=NULL; DOM_SID *owner_sid=NULL; SEC_ACL *dacl=NULL; int revision=1; @@ -4121,15 +4131,15 @@ sec_desc_parse(TALLOC_CTX *ctx, } if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { - if (grp_sid) { + if (group_sid) { DEBUG(5, ("GROUP specified more than once!\n")); goto done; } - grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!grp_sid || + group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!group_sid || !convert_string_to_sid(ipc_cli, pol, numeric, - grp_sid, tok+6)) { + group_sid, tok+6)) { DEBUG(5, ("Failed to parse group sid\n")); goto done; } @@ -4137,15 +4147,15 @@ sec_desc_parse(TALLOC_CTX *ctx, } if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { - if (grp_sid) { + if (group_sid) { DEBUG(5, ("GROUP specified more than once!\n")); goto done; } - grp_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!grp_sid || + group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!group_sid || !convert_string_to_sid(ipc_cli, pol, False, - grp_sid, tok+6)) { + group_sid, tok+6)) { DEBUG(5, ("Failed to parse group sid\n")); goto done; } @@ -4183,10 +4193,10 @@ sec_desc_parse(TALLOC_CTX *ctx, } ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, - owner_sid, grp_sid, NULL, dacl, &sd_size); + owner_sid, group_sid, NULL, dacl, &sd_size); done: - SAFE_FREE(grp_sid); + SAFE_FREE(group_sid); SAFE_FREE(owner_sid); return ret; @@ -5132,7 +5142,7 @@ cacl_set(TALLOC_CTX *ctx, SEC_DESC *sd = NULL, *old; SEC_ACL *dacl = NULL; DOM_SID *owner_sid = NULL; - DOM_SID *grp_sid = NULL; + DOM_SID *group_sid = NULL; uint32 i, j; size_t sd_size; int ret = 0; @@ -5257,7 +5267,7 @@ cacl_set(TALLOC_CTX *ctx, case SMBC_XATTR_MODE_SET: old = sd; owner_sid = old->owner_sid; - grp_sid = old->group_sid; + group_sid = old->group_sid; dacl = old->dacl; break; @@ -5266,7 +5276,7 @@ cacl_set(TALLOC_CTX *ctx, break; case SMBC_XATTR_MODE_CHGRP: - grp_sid = sd->group_sid; + group_sid = sd->group_sid; break; } @@ -5275,7 +5285,7 @@ cacl_set(TALLOC_CTX *ctx, /* Create new security descriptor and set it */ sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, - owner_sid, grp_sid, NULL, dacl, &sd_size); + owner_sid, group_sid, NULL, dacl, &sd_size); fnum = cli_nt_create(cli, filename, WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c deleted file mode 100644 index 33352b85ce..0000000000 --- a/source3/libsmb/smb_seal.c +++ /dev/null @@ -1,496 +0,0 @@ -/* - Unix SMB/CIFS implementation. - SMB Transport encryption (sealing) code. - Copyright (C) Jeremy Allison 2007. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/****************************************************************************** - Pull out the encryption context for this packet. 0 means global context. -******************************************************************************/ - -NTSTATUS get_enc_ctx_num(char *buf, uint16 *p_enc_ctx_num) -{ - if (smb_len(buf) < 8) { - return NT_STATUS_INVALID_BUFFER_SIZE; - } - - if (buf[4] == (char)0xFF) { - if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') { - /* Not an encrypted buffer. */ - return NT_STATUS_NOT_FOUND; - } - if (buf[5] == 'E') { - *p_enc_ctx_num = SVAL(buf,6); - return NT_STATUS_OK; - } - } - return NT_STATUS_INVALID_NETWORK_RESPONSE; -} - -/****************************************************************************** - Generic code for client and server. - Is encryption turned on ? -******************************************************************************/ - -BOOL common_encryption_on(struct smb_trans_enc_state *es) -{ - return ((es != NULL) && es->enc_on); -} - -/****************************************************************************** - Generic code for client and server. - NTLM decrypt an incoming buffer. - Abartlett tells me that SSPI puts the signature first before the encrypted - output, so cope with the same for compatibility. -******************************************************************************/ - -NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) -{ - NTSTATUS status; - size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ - size_t data_len; - char *inbuf; - DATA_BLOB sig; - - if (buf_len < 8 + NTLMSSP_SIG_SIZE) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - inbuf = (char *)smb_xmemdup(buf, buf_len); - - /* Adjust for the signature. */ - data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; - - /* Point at the signature. */ - sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE); - - status = ntlmssp_unseal_packet(ntlmssp_state, - (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' */ - data_len, - (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, - data_len, - &sig); - - if (!NT_STATUS_IS_OK(status)) { - SAFE_FREE(inbuf); - return status; - } - - memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); - - /* Reset the length. */ - smb_setlen(inbuf, buf, data_len + 4); - - SAFE_FREE(inbuf); - return NT_STATUS_OK; -} - -/****************************************************************************** - Generic code for client and server. - NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. - Abartlett tells me that SSPI puts the signature first before the encrypted - output, so do the same for compatibility. -******************************************************************************/ - -NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, - uint16 enc_ctx_num, - char *buf, - char **ppbuf_out) -{ - NTSTATUS status; - char *buf_out; - size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */ - DATA_BLOB sig; - - *ppbuf_out = NULL; - - if (data_len == 0) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - /* - * We know smb_len can't return a value > 128k, so no int overflow - * check needed. - */ - - buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len); - - /* Copy the data from the original buffer. */ - - memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len); - - smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); - - sig = data_blob(NULL, NTLMSSP_SIG_SIZE); - - status = ntlmssp_seal_packet(ntlmssp_state, - (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' */ - data_len, - (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, - data_len, - &sig); - - if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&sig); - SAFE_FREE(buf_out); - return status; - } - - /* First 16 data bytes are signature for SSPI compatibility. */ - memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); - *ppbuf_out = buf_out; - return NT_STATUS_OK; -} - -/****************************************************************************** - Generic code for client and server. - gss-api decrypt an incoming buffer. We insist that the size of the - unwrapped buffer must be smaller or identical to the incoming buffer. -******************************************************************************/ - -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) -static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) -{ - gss_ctx_id_t gss_ctx = gss_state->gss_ctx; - OM_uint32 ret = 0; - OM_uint32 minor = 0; - int flags_got = 0; - gss_buffer_desc in_buf, out_buf; - size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ - - if (buf_len < 8) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - in_buf.value = buf + 8; - in_buf.length = buf_len - 8; - - ret = gss_unwrap(&minor, - gss_ctx, - &in_buf, - &out_buf, - &flags_got, /* did we get sign+seal ? */ - (gss_qop_t *) NULL); - - if (ret != GSS_S_COMPLETE) { - ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); - DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", - ads_errstr(adss) )); - return map_nt_error_from_gss(ret, minor); - } - - if (out_buf.length > in_buf.length) { - DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap size (%u) too large (%u) !\n", - (unsigned int)out_buf.length, - (unsigned int)in_buf.length )); - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_INVALID_PARAMETER; - } - - memcpy(buf + 8, out_buf.value, out_buf.length); - smb_setlen((char *)out_buf.value, buf, out_buf.length + 4); - - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_OK; -} - -/****************************************************************************** - Generic code for client and server. - gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. -******************************************************************************/ - -static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, - uint16 enc_ctx_num, - char *buf, - char **ppbuf_out) -{ - gss_ctx_id_t gss_ctx = gss_state->gss_ctx; - OM_uint32 ret = 0; - OM_uint32 minor = 0; - int flags_got = 0; - gss_buffer_desc in_buf, out_buf; - size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ - - *ppbuf_out = NULL; - - if (buf_len < 8) { - return NT_STATUS_BUFFER_TOO_SMALL; - } - - in_buf.value = buf + 8; - in_buf.length = buf_len - 8; - - ret = gss_wrap(&minor, - gss_ctx, - True, /* we want sign+seal. */ - GSS_C_QOP_DEFAULT, - &in_buf, - &flags_got, /* did we get sign+seal ? */ - &out_buf); - - if (ret != GSS_S_COMPLETE) { - ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); - DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", - ads_errstr(adss) )); - return map_nt_error_from_gss(ret, minor); - } - - if (!flags_got) { - /* Sign+seal not supported. */ - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_NOT_SUPPORTED; - } - - /* Ya see - this is why I *hate* gss-api. I don't - * want to have to malloc another buffer of the - * same size + 8 bytes just to get a continuous - * header + buffer, but gss won't let me pass in - * a pre-allocated buffer. Bastards (and you know - * who you are....). I might fix this by - * going to "encrypt_and_send" passing in a file - * descriptor and doing scatter-gather write with - * TCP cork on Linux. But I shouldn't have to - * bother :-*(. JRA. - */ - - *ppbuf_out = (char *)SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */ - if (!*ppbuf_out) { - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_NO_MEMORY; - } - - memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); - smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num); - - gss_release_buffer(&minor, &out_buf); - return NT_STATUS_OK; -} -#endif - -/****************************************************************************** - Generic code for client and server. - Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. -******************************************************************************/ - -NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) -{ - if (!common_encryption_on(es)) { - /* Not encrypting. */ - *buf_out = buffer; - return NT_STATUS_OK; - } - - switch (es->smb_enc_type) { - case SMB_TRANS_ENC_NTLM: - return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, es->enc_ctx_num, buffer, buf_out); -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - case SMB_TRANS_ENC_GSS: - return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out); -#endif - default: - return NT_STATUS_NOT_SUPPORTED; - } -} - -/****************************************************************************** - Generic code for client and server. - Decrypt an incoming SMB buffer. Replaces the data within it. - New data must be less than or equal to the current length. -******************************************************************************/ - -NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) -{ - if (!common_encryption_on(es)) { - /* Not decrypting. */ - return NT_STATUS_OK; - } - - switch (es->smb_enc_type) { - case SMB_TRANS_ENC_NTLM: - return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - case SMB_TRANS_ENC_GSS: - return common_gss_decrypt_buffer(es->s.gss_state, buf); -#endif - default: - return NT_STATUS_NOT_SUPPORTED; - } -} - -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) -/****************************************************************************** - Shutdown a gss encryption state. -******************************************************************************/ - -static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state) -{ - OM_uint32 minor = 0; - struct smb_tran_enc_state_gss *gss_state = *pp_gss_state; - - if (gss_state->creds != GSS_C_NO_CREDENTIAL) { - gss_release_cred(&minor, &gss_state->creds); - } - if (gss_state->gss_ctx != GSS_C_NO_CONTEXT) { - gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); - } - SAFE_FREE(*pp_gss_state); -} -#endif - -/****************************************************************************** - Shutdown an encryption state. -******************************************************************************/ - -void common_free_encryption_state(struct smb_trans_enc_state **pp_es) -{ - struct smb_trans_enc_state *es = *pp_es; - - if (es == NULL) { - return; - } - - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - if (es->s.ntlmssp_state) { - ntlmssp_end(&es->s.ntlmssp_state); - } - } -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { - /* Free the gss context handle. */ - if (es->s.gss_state) { - common_free_gss_state(&es->s.gss_state); - } - } -#endif - SAFE_FREE(es); - *pp_es = NULL; -} - -/****************************************************************************** - Free an encryption-allocated buffer. -******************************************************************************/ - -void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) -{ - if (!common_encryption_on(es)) { - return; - } - - if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { - SAFE_FREE(buf); - return; - } - -#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) - if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { - OM_uint32 min; - gss_buffer_desc rel_buf; - rel_buf.value = buf; - rel_buf.length = smb_len(buf) + 4; - gss_release_buffer(&min, &rel_buf); - } -#endif -} - -/****************************************************************************** - Client side encryption. -******************************************************************************/ - -/****************************************************************************** - Is client encryption on ? -******************************************************************************/ - -BOOL cli_encryption_on(struct cli_state *cli) -{ - /* If we supported multiple encrytion contexts - * here we'd look up based on tid. - */ - return common_encryption_on(cli->trans_enc_state); -} - -/****************************************************************************** - Shutdown a client encryption state. -******************************************************************************/ - -void cli_free_encryption_context(struct cli_state *cli) -{ - common_free_encryption_state(&cli->trans_enc_state); -} - -/****************************************************************************** - Free an encryption-allocated buffer. -******************************************************************************/ - -void cli_free_enc_buffer(struct cli_state *cli, char *buf) -{ - /* We know this is an smb buffer, and we - * didn't malloc, only copy, for a keepalive, - * so ignore session keepalives. */ - - if(CVAL(buf,0) == SMBkeepalive) { - return; - } - - /* If we supported multiple encrytion contexts - * here we'd look up based on tid. - */ - common_free_enc_buffer(cli->trans_enc_state, buf); -} - -/****************************************************************************** - Decrypt an incoming buffer. -******************************************************************************/ - -NTSTATUS cli_decrypt_message(struct cli_state *cli) -{ - NTSTATUS status; - uint16 enc_ctx_num; - - /* Ignore session keepalives. */ - if(CVAL(cli->inbuf,0) == SMBkeepalive) { - return NT_STATUS_OK; - } - - status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num); - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { - return NT_STATUS_INVALID_HANDLE; - } - - return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); -} - -/****************************************************************************** - Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. -******************************************************************************/ - -NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) -{ - /* Ignore session keepalives. */ - if(CVAL(cli->outbuf,0) == SMBkeepalive) { - return NT_STATUS_OK; - } - - /* If we supported multiple encrytion contexts - * here we'd look up based on tid. - */ - return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); -} -- cgit From 8e54530b52fd256137740107e9fdf000f00a7a30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Oct 2007 18:25:16 -0700 Subject: Add start of IPv6 implementation. Currently most of this is avoiding IPv6 in winbindd, but moves most of the socket functions that were wrongly in lib/util.c into lib/util_sock.c and provides generic IPv4/6 independent versions of most things. Still lots of work to do, but now I can see how I'll fix the access check code. Nasty part that remains is the name resolution code which is used to returning arrays of in_addr structs. Jeremy. (This used to be commit 3f6bd0e1ec5cc6670f3d08f76fc2cd94c9cd1a08) --- source3/libsmb/cliconnect.c | 8 ++++---- source3/libsmb/clidfs.c | 4 ++-- source3/libsmb/dsgetdcname.c | 2 +- source3/libsmb/libsmbclient.c | 10 +++++----- source3/libsmb/namequery.c | 35 ++++++++++++++++++++++++----------- source3/libsmb/namequery_dc.c | 6 +++--- 6 files changed, 39 insertions(+), 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 78cc63de50..16c3bed438 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1421,7 +1421,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip *p = 0; } - if (!ip || is_zero_ip(*ip)) { + if (!ip || is_zero_ip_v4(*ip)) { if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) { return NT_STATUS_BAD_NETWORK_NAME; } @@ -1522,7 +1522,7 @@ again: char *p; DEBUG(1,("session request to %s failed (%s)\n", called.name, cli_errstr(cli))); - if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) { + if ((p=strchr(called.name, '.')) && !is_ipaddress_v4(called.name)) { *p = 0; goto again; } @@ -1650,7 +1650,7 @@ BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho * then use *SMBSERVER immediately. */ - if(is_ipaddress(desthost)) { + if(is_ipaddress_v4(desthost)) { make_nmb_name(&called, "*SMBSERVER", 0x20); } else { make_nmb_name(&called, desthost, 0x20); @@ -1764,7 +1764,7 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, if (NT_STATUS_IS_OK(nt_status)) { return cli; - } else if (is_ipaddress(server)) { + } else if (is_ipaddress_v4(server)) { /* windows 9* needs a correct NMB name for connections */ fstring remote_name; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index d32629b139..db4a9dfbd5 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -83,13 +83,13 @@ static struct cli_state *do_connect( const char *server, const char *share, server_n = server; - zero_ip(&ip); + zero_ip_v4(&ip); make_nmb_name(&calling, global_myname(), 0x0); make_nmb_name(&called , server, name_type); again: - zero_ip(&ip); + zero_ip_v4(&ip); if (have_ip) ip = dest_ip; diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 384b9ec48d..89bb65006d 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -650,7 +650,7 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, * back to netbios lookups is that our DNS server doesn't know * anything about the DC's -- jerry */ - if (!is_zero_ip(r->ip)) { + if (!is_zero_ip_v4(r->ip)) { (*return_count)++; continue; } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 45226a028c..49384e2728 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -654,7 +654,7 @@ smbc_server(SMBCCTX *context, const char *username_used; NTSTATUS status; - zero_ip(&ip); + zero_ip_v4(&ip); ZERO_STRUCT(c); if (server[0] == 0) { @@ -742,7 +742,7 @@ smbc_server(SMBCCTX *context, again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); - zero_ip(&ip); + zero_ip_v4(&ip); /* have to open a new connection */ if ((c = cli_initialise()) == NULL) { @@ -796,7 +796,7 @@ smbc_server(SMBCCTX *context, /* Only try this if server is an IP address ... */ - if (is_ipaddress(server) && !tried_reverse) { + if (is_ipaddress_v4(server) && !tried_reverse) { fstring remote_name; struct in_addr rem_ip; @@ -962,7 +962,7 @@ smbc_attr_server(SMBCCTX *context, flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } - zero_ip(&ip); + zero_ip_v4(&ip); nt_status = cli_full_connection(&ipc_cli, global_myname(), server, &ip, 0, "IPC$", "?????", @@ -2761,7 +2761,7 @@ smbc_opendir_ctx(SMBCCTX *context, * LMB or DMB */ if (!srv && - !is_ipaddress(server) && + !is_ipaddress_v4(server) && (resolve_name(server, &rem_ip, 0x1d) || /* LMB */ resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */ diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 49e3375f50..182d3641f7 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -352,12 +352,18 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) { int max_bits1=0, max_bits2=0; int num_interfaces = iface_count(); + struct sockaddr_storage ss; int i; for (i=0;iss_family != AF_INET) { + continue; + } + ip = ((const struct sockaddr_in *)pss)->sin_addr; bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr); bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr); max_bits1 = MAX(bits1, max_bits1); @@ -365,10 +371,12 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) } /* bias towards directly reachable IPs */ - if (iface_local(*ip1)) { + in_addr_to_sockaddr_storage(&ss, *ip1); + if (iface_local(&ss)) { max_bits1 += 32; } - if (iface_local(*ip2)) { + in_addr_to_sockaddr_storage(&ss, *ip1); + if (iface_local(&ss)) { max_bits2 += 32; } @@ -431,19 +439,19 @@ static int remove_duplicate_addrs2( struct ip_service *iplist, int count ) /* one loop to remove duplicates */ for ( i=0; i= 0; i--) { struct in_addr sendto_ip; + const struct sockaddr_storage *ss = iface_n_bcast(i); int flags; + /* Done this way to fix compiler error on IRIX 5.x */ - sendto_ip = *iface_n_bcast(i); + if (!ss || ss->ss_family != AF_INET) { + continue; + } + sendto_ip = ((const struct sockaddr_in *)ss)->sin_addr; ip_list = name_query(sock, name, name_type, True, True, sendto_ip, return_count, &flags, NULL); if( ip_list ) @@ -886,7 +899,7 @@ NTSTATUS resolve_wins(const char *name, int name_type, wins_ip = wins_srv_ip_tag(wins_tags[t], src_ip); - if (global_in_nmbd && ismyip(wins_ip)) { + if (global_in_nmbd && ismyip_v4(wins_ip)) { /* yikes! we'll loop forever */ continue; } @@ -1144,7 +1157,7 @@ NTSTATUS resolve_ads(const char *name, int name_type, The standard reason for falling back to netbios lookups is that our DNS server doesn't know anything about the DC's -- jerry */ - if ( ! is_zero_ip(r->ip) ) + if ( ! is_zero_ip_v4(r->ip) ) (*return_count)++; } @@ -1173,7 +1186,7 @@ NTSTATUS internal_resolve_name(const char *name, int name_type, const char *ptr; BOOL allones = (strcmp(name,"255.255.255.255") == 0); BOOL allzeros = (strcmp(name,"0.0.0.0") == 0); - BOOL is_address = is_ipaddress(name); + BOOL is_address = is_ipaddress_v4(name); NTSTATUS status = NT_STATUS_UNSUCCESSFUL; int i; @@ -1347,7 +1360,7 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type) char *sitename = sitename_fetch(lp_realm()); /* wild guess */ int count = 0; - if (is_ipaddress(name)) { + if (is_ipaddress_v4(name)) { *return_ip = *interpret_addr2(name); SAFE_FREE(sitename); return True; diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index bdac833d13..39215aaa8f 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -155,7 +155,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip int count, i; NTSTATUS result; - zero_ip(&exclude_ip); + zero_ip_v4(&exclude_ip); /* get a list of all domain controllers */ @@ -168,7 +168,7 @@ static BOOL rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip /* Remove the entry we've already failed with (should be the PDC). */ for (i = 0; i < count; i++) { - if (is_zero_ip(ip_list[i].ip)) + if (is_zero_ip_v4(ip_list[i].ip)) continue; if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) { @@ -212,7 +212,7 @@ BOOL get_dc_name(const char *domain, const char *realm, fstring srv_name, struct BOOL ret; BOOL our_domain = False; - zero_ip(&dc_ip); + zero_ip_v4(&dc_ip); ret = False; -- cgit From 06ae5243f302c79fa2fe9ebbf1fb212e2f830c18 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 15 Oct 2007 19:10:19 +0200 Subject: Add WERR_SERVICE_ALREADY_RUNNING. Guenther (This used to be commit 357f00384994946485a5190b6a9c493aeee53cd2) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 23214e8d94..52afb0d022 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -77,6 +77,7 @@ werror_code_struct dos_errs[] = { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { "WERR_IO_PENDING", WERR_IO_PENDING }, { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL }, + { "WERR_SERVICE_ALREADY_RUNNING", WERR_SERVICE_ALREADY_RUNNING }, { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, { "WERR_REG_CORRUPT", WERR_REG_CORRUPT }, { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, -- cgit From 666f50b01f282e520c59b94944d4b1583168d46a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 Oct 2007 16:11:48 -0700 Subject: Move to protocol independent code in most of lib/util_sock.c We don't use gethostbyname any more except in one case where we're looking for host aliases (I don't know how to do that with getaddrinfo yet). New function should be getaddrinfo(). Next step will be fixing lib/access.c, and then changing libsmb/namequery.c to cope with IPv6 address returns. Jeremy. (This used to be commit 4a56b697b6adcf095e25895c4a9ba3192ed34124) --- source3/libsmb/namequery.c | 60 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 182d3641f7..5459210c64 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1028,8 +1028,12 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, /* * "host" means do a localhost, or dns lookup. */ - struct hostent *hp; - + struct addrinfo hints; + struct addrinfo *ailist = NULL; + struct addrinfo *res = NULL; + int ret = -1; + int i = 0; + if ( name_type != 0x20 && name_type != 0x0) { DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type)); return NT_STATUS_INVALID_PARAMETER; @@ -1039,18 +1043,54 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, *return_count = 0; DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type)); - - if (((hp = sys_gethostbyname(name)) != NULL) && (hp->h_addr != NULL)) { + + ZERO_STRUCT(hints); + /* By default make sure it supports TCP. */ + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_ADDRCONFIG; + + ret = getaddrinfo(name, + NULL, + &hints, + &ailist); + if (ret) { + DEBUG(3,("resolve_hosts: getaddrinfo failed for name %s [%s]\n", + name, + gai_strerror(ret) )); + } + + for (res = ailist; res; res = res->ai_next) { struct in_addr return_ip; - putip((char *)&return_ip,(char *)hp->h_addr); - *return_iplist = SMB_MALLOC_P(struct ip_service); - if(*return_iplist == NULL) { + + /* IPv4 only for now until I convert ip_service */ + if (res->ai_family != AF_INET) { + continue; + } + if (!res->ai_addr) { + continue; + } + + putip((char *)&return_ip, + &((struct sockaddr_in *)res->ai_addr)->sin_addr); + + *return_count += 1; + i++; + + *return_iplist = SMB_REALLOC_ARRAY(*return_iplist, + struct ip_service, + *return_count); + if (!*return_iplist) { DEBUG(3,("resolve_hosts: malloc fail !\n")); + freeaddrinfo(ailist); return NT_STATUS_NO_MEMORY; } - (*return_iplist)->ip = return_ip; - (*return_iplist)->port = PORT_NONE; - *return_count = 1; + (*return_iplist)[i].ip = return_ip; + (*return_iplist)[i].port = PORT_NONE; + } + if (ailist) { + freeaddrinfo(ailist); + } + if (*return_count) { return NT_STATUS_OK; } return NT_STATUS_UNSUCCESSFUL; -- cgit From 4d910553dcf8e19f4b1d6fb65ee9d5473a55cbbd Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Thu, 18 Oct 2007 13:00:46 +0200 Subject: Add net rap file user (This used to be commit 2972c97e5e676964585de930601f083c19080735) --- source3/libsmb/clirap2.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 23113003f0..b8fe31a562 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1021,7 +1021,10 @@ int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const c * False - failure * ****************************************************************************/ -int cli_NetFileEnum(struct cli_state *cli, char * user, char * base_path, void (*fn)(const char *, const char *, uint16, uint16, uint32)) +int cli_NetFileEnum(struct cli_state *cli, const char * user, + const char * base_path, + void (*fn)(const char *, const char *, uint16, uint16, + uint32)) { char *rparam = NULL; char *rdata = NULL; -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libsmb/asn1.c | 46 ++++++++++----------- source3/libsmb/cliconnect.c | 30 +++++++------- source3/libsmb/clidfs.c | 22 +++++----- source3/libsmb/clidgram.c | 6 +-- source3/libsmb/clientgen.c | 18 ++++----- source3/libsmb/clierror.c | 6 +-- source3/libsmb/clifile.c | 86 ++++++++++++++++++++-------------------- source3/libsmb/clifsinfo.c | 20 +++++----- source3/libsmb/clikrb5.c | 28 ++++++------- source3/libsmb/clilist.c | 4 +- source3/libsmb/climessage.c | 6 +-- source3/libsmb/clioplock.c | 6 +-- source3/libsmb/cliprint.c | 2 +- source3/libsmb/cliquota.c | 30 +++++++------- source3/libsmb/clirap.c | 30 +++++++------- source3/libsmb/clirap2.c | 16 ++++---- source3/libsmb/clireadwrite.c | 14 +++---- source3/libsmb/clisecdesc.c | 6 +-- source3/libsmb/clispnego.c | 18 ++++----- source3/libsmb/clitrans.c | 12 +++--- source3/libsmb/credentials.c | 8 ++-- source3/libsmb/dsgetdcname.c | 12 +++--- source3/libsmb/libsmbclient.c | 82 +++++++++++++++++++------------------- source3/libsmb/namecache.c | 20 +++++----- source3/libsmb/namequery.c | 52 ++++++++++++------------ source3/libsmb/namequery_dc.c | 12 +++--- source3/libsmb/nmblib.c | 24 +++++------ source3/libsmb/ntlm_check.c | 8 ++-- source3/libsmb/ntlmssp.c | 6 +-- source3/libsmb/ntlmssp_parse.c | 4 +- source3/libsmb/ntlmssp_sign.c | 2 +- source3/libsmb/passchange.c | 2 +- source3/libsmb/samlogon_cache.c | 14 +++---- source3/libsmb/smb_share_modes.c | 2 +- source3/libsmb/smb_signing.c | 64 +++++++++++++++--------------- source3/libsmb/smbencrypt.c | 20 +++++----- source3/libsmb/spnego.c | 12 +++--- source3/libsmb/trustdom_cache.c | 12 +++--- source3/libsmb/trusts_util.c | 4 +- 39 files changed, 383 insertions(+), 383 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 4d13207151..0cbfa70e7b 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -34,7 +34,7 @@ void asn1_free(ASN1_DATA *data) } /* write to the ASN1 buffer, advancing the buffer pointer */ -BOOL asn1_write(ASN1_DATA *data, const void *p, int len) +bool asn1_write(ASN1_DATA *data, const void *p, int len) { if (data->has_error) return False; if (data->length < data->ofs+len) { @@ -52,13 +52,13 @@ BOOL asn1_write(ASN1_DATA *data, const void *p, int len) } /* useful fn for writing a uint8 */ -BOOL asn1_write_uint8(ASN1_DATA *data, uint8 v) +bool asn1_write_uint8(ASN1_DATA *data, uint8 v) { return asn1_write(data, &v, 1); } /* push a tag onto the asn1 data buffer. Used for nested structures */ -BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) +bool asn1_push_tag(ASN1_DATA *data, uint8 tag) { struct nesting *nesting; @@ -76,7 +76,7 @@ BOOL asn1_push_tag(ASN1_DATA *data, uint8 tag) } /* pop a tag */ -BOOL asn1_pop_tag(ASN1_DATA *data) +bool asn1_pop_tag(ASN1_DATA *data) { struct nesting *nesting; size_t len; @@ -127,7 +127,7 @@ BOOL asn1_pop_tag(ASN1_DATA *data) /* write an integer */ -BOOL asn1_write_Integer(ASN1_DATA *data, int i) +bool asn1_write_Integer(ASN1_DATA *data, int i) { if (!asn1_push_tag(data, ASN1_INTEGER)) return False; do { @@ -138,7 +138,7 @@ BOOL asn1_write_Integer(ASN1_DATA *data, int i) } /* write an object ID to a ASN1 buffer */ -BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) +bool asn1_write_OID(ASN1_DATA *data, const char *OID) { unsigned v, v2; const char *p = (const char *)OID; @@ -167,7 +167,7 @@ BOOL asn1_write_OID(ASN1_DATA *data, const char *OID) } /* write an octet string */ -BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) +bool asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) { asn1_push_tag(data, ASN1_OCTET_STRING); asn1_write(data, p, length); @@ -176,7 +176,7 @@ BOOL asn1_write_OctetString(ASN1_DATA *data, const void *p, size_t length) } /* write a general string */ -BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) +bool asn1_write_GeneralString(ASN1_DATA *data, const char *s) { asn1_push_tag(data, ASN1_GENERAL_STRING); asn1_write(data, s, strlen(s)); @@ -185,7 +185,7 @@ BOOL asn1_write_GeneralString(ASN1_DATA *data, const char *s) } /* write a BOOLEAN */ -BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) +bool asn1_write_BOOLEAN(ASN1_DATA *data, bool v) { asn1_write_uint8(data, ASN1_BOOLEAN); asn1_write_uint8(data, v); @@ -194,7 +194,7 @@ BOOL asn1_write_BOOLEAN(ASN1_DATA *data, BOOL v) /* write a BOOLEAN - hmm, I suspect this one is the correct one, and the above boolean is bogus. Need to check */ -BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) +bool asn1_write_BOOLEAN2(ASN1_DATA *data, bool v) { asn1_push_tag(data, ASN1_BOOLEAN); asn1_write_uint8(data, v); @@ -203,7 +203,7 @@ BOOL asn1_write_BOOLEAN2(ASN1_DATA *data, BOOL v) } /* check a BOOLEAN */ -BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) +bool asn1_check_BOOLEAN(ASN1_DATA *data, bool v) { uint8 b = 0; @@ -222,7 +222,7 @@ BOOL asn1_check_BOOLEAN(ASN1_DATA *data, BOOL v) /* load a ASN1_DATA structure with a lump of data, ready to be parsed */ -BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) +bool asn1_load(ASN1_DATA *data, DATA_BLOB blob) { ZERO_STRUCTP(data); data->data = (unsigned char *)memdup(blob.data, blob.length); @@ -235,7 +235,7 @@ BOOL asn1_load(ASN1_DATA *data, DATA_BLOB blob) } /* read from a ASN1 buffer, advancing the buffer pointer */ -BOOL asn1_read(ASN1_DATA *data, void *p, int len) +bool asn1_read(ASN1_DATA *data, void *p, int len) { if (data->has_error) return False; @@ -255,13 +255,13 @@ BOOL asn1_read(ASN1_DATA *data, void *p, int len) } /* read a uint8 from a ASN1 buffer */ -BOOL asn1_read_uint8(ASN1_DATA *data, uint8 *v) +bool asn1_read_uint8(ASN1_DATA *data, uint8 *v) { return asn1_read(data, v, 1); } /* start reading a nested asn1 structure */ -BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) +bool asn1_start_tag(ASN1_DATA *data, uint8 tag) { uint8 b; struct nesting *nesting; @@ -310,7 +310,7 @@ BOOL asn1_start_tag(ASN1_DATA *data, uint8 tag) /* stop reading a tag */ -BOOL asn1_end_tag(ASN1_DATA *data) +bool asn1_end_tag(ASN1_DATA *data) { struct nesting *nesting; @@ -346,7 +346,7 @@ int asn1_tag_remaining(ASN1_DATA *data) } /* read an object ID from a ASN1 buffer */ -BOOL asn1_read_OID(ASN1_DATA *data, char **OID) +bool asn1_read_OID(ASN1_DATA *data, char **OID) { uint8 b; pstring oid_str; @@ -385,7 +385,7 @@ BOOL asn1_read_OID(ASN1_DATA *data, char **OID) } /* check that the next object ID is correct */ -BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) +bool asn1_check_OID(ASN1_DATA *data, const char *OID) { char *id; @@ -402,7 +402,7 @@ BOOL asn1_check_OID(ASN1_DATA *data, const char *OID) } /* read a GeneralString from a ASN1 buffer */ -BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) +bool asn1_read_GeneralString(ASN1_DATA *data, char **s) { int len; char *str; @@ -433,7 +433,7 @@ BOOL asn1_read_GeneralString(ASN1_DATA *data, char **s) } /* read a octet string blob */ -BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) +bool asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) { int len; ZERO_STRUCTP(blob); @@ -450,7 +450,7 @@ BOOL asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) } /* read an interger */ -BOOL asn1_read_Integer(ASN1_DATA *data, int *i) +bool asn1_read_Integer(ASN1_DATA *data, int *i) { uint8 b; *i = 0; @@ -465,7 +465,7 @@ BOOL asn1_read_Integer(ASN1_DATA *data, int *i) } /* check a enumarted value is correct */ -BOOL asn1_check_enumerated(ASN1_DATA *data, int v) +bool asn1_check_enumerated(ASN1_DATA *data, int v) { uint8 b; if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; @@ -479,7 +479,7 @@ BOOL asn1_check_enumerated(ASN1_DATA *data, int v) } /* write an enumarted value to the stream */ -BOOL asn1_write_enumerated(ASN1_DATA *data, uint8 v) +bool asn1_write_enumerated(ASN1_DATA *data, uint8 v) { if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; asn1_write_uint8(data, v); diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 16c3bed438..82cd6d6d13 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -447,7 +447,7 @@ end: Send a extended security session setup blob ****************************************************************************/ -static BOOL cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) +static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) { uint32 capabilities = cli_session_setup_capabilities(cli); char *p; @@ -529,7 +529,7 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) #define BASE_SESSSETUP_BLOB_PACKET_SIZE (35 + 24 + 22) -static BOOL cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_BLOB session_key_krb5) +static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_BLOB session_key_krb5) { int32 remaining = blob.length; int32 cur = 0; @@ -744,7 +744,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use DATA_BLOB key = data_blob(ntlmssp_state->session_key.data, ntlmssp_state->session_key.length); DATA_BLOB null_blob = data_blob_null; - BOOL res; + bool res; fstrcpy(cli->server_domain, ntlmssp_state->server_domain); cli_set_session_key(cli, ntlmssp_state->session_key); @@ -786,7 +786,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, char *principal; char *OIDs[ASN1_MAX_OIDS]; int i; - BOOL got_kerberos_mechanism = False; + bool got_kerberos_mechanism = False; DATA_BLOB blob; DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); @@ -985,7 +985,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, Send a uloggoff. *****************************************************************************/ -BOOL cli_ulogoff(struct cli_state *cli) +bool cli_ulogoff(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,2,0,True); @@ -1010,7 +1010,7 @@ BOOL cli_ulogoff(struct cli_state *cli) Send a tconX. ****************************************************************************/ -BOOL cli_send_tconX(struct cli_state *cli, +bool cli_send_tconX(struct cli_state *cli, const char *share, const char *dev, const char *pass, int passlen) { fstring fullshare, pword; @@ -1113,7 +1113,7 @@ BOOL cli_send_tconX(struct cli_state *cli, Send a tree disconnect. ****************************************************************************/ -BOOL cli_tdis(struct cli_state *cli) +bool cli_tdis(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); @@ -1171,7 +1171,7 @@ void cli_negprot_send(struct cli_state *cli) Send a negprot command. ****************************************************************************/ -BOOL cli_negprot(struct cli_state *cli) +bool cli_negprot(struct cli_state *cli) { char *p; int numprots; @@ -1313,7 +1313,7 @@ BOOL cli_negprot(struct cli_state *cli) Send a session request. See rfc1002.txt 4.3 and 4.3.2. ****************************************************************************/ -BOOL cli_session_request(struct cli_state *cli, +bool cli_session_request(struct cli_state *cli, struct nmb_name *calling, struct nmb_name *called) { char *p; @@ -1381,7 +1381,7 @@ BOOL cli_session_request(struct cli_state *cli, /* Try again */ { static int depth; - BOOL ret; + bool ret; if (depth > 4) { DEBUG(0,("Retarget recursion - failing\n")); return False; @@ -1462,7 +1462,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip @param dest_host The netbios name of the remote host @param dest_ip (optional) The the destination IP, NULL for name based lookup @param port (optional) The destination port (0 for default) - @param retry BOOL. Did this connection fail with a retryable error ? + @param retry bool. Did this connection fail with a retryable error ? */ NTSTATUS cli_start_connection(struct cli_state **output_cli, @@ -1470,7 +1470,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, const char *dest_host, struct in_addr *dest_ip, int port, int signing_state, int flags, - BOOL *retry) + bool *retry) { NTSTATUS nt_status; struct nmb_name calling; @@ -1566,7 +1566,7 @@ again: @param user Username, unix string @param domain User's domain @param password User's password, unencrypted unix string. - @param retry BOOL. Did this connection fail with a retryable error ? + @param retry bool. Did this connection fail with a retryable error ? */ NTSTATUS cli_full_connection(struct cli_state **output_cli, @@ -1577,7 +1577,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *user, const char *domain, const char *password, int flags, int signing_state, - BOOL *retry) + bool *retry) { NTSTATUS nt_status; struct cli_state *cli = NULL; @@ -1638,7 +1638,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, Attempt a NetBIOS session request, falling back to *SMBSERVER if needed. ****************************************************************************/ -BOOL attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost, +bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost, struct in_addr *pdest_ip) { struct nmb_name calling, called; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index db4a9dfbd5..f7bf8506fe 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -42,14 +42,14 @@ struct client_connection { static pstring username; static pstring password; -static BOOL use_kerberos; -static BOOL got_pass; +static bool use_kerberos; +static bool got_pass; static int signing_state; int max_protocol = PROTOCOL_NT1; static int port; static int name_type = 0x20; -static BOOL have_ip; +static bool have_ip; static struct in_addr dest_ip; static struct client_connection *connections; @@ -59,7 +59,7 @@ static struct client_connection *connections; ********************************************************************/ static struct cli_state *do_connect( const char *server, const char *share, - BOOL show_sessetup ) + bool show_sessetup ) { struct cli_state *c = NULL; struct nmb_name called, calling; @@ -238,7 +238,7 @@ const char *cli_cm_get_mntpoint( struct cli_state *c ) static struct cli_state *cli_cm_connect( const char *server, const char *share, - BOOL show_hdr) + bool show_hdr) { struct client_connection *node; @@ -282,7 +282,7 @@ static struct cli_state *cli_cm_find( const char *server, const char *share ) struct cli_state *cli_cm_open(const char *server, const char *share, - BOOL show_hdr) + bool show_hdr) { struct cli_state *c; @@ -476,7 +476,7 @@ static void cli_dfs_make_full_path( struct cli_state *cli, check for dfs referral ********************************************************************/ -static BOOL cli_dfs_check_error( struct cli_state *cli, NTSTATUS status ) +static bool cli_dfs_check_error( struct cli_state *cli, NTSTATUS status ) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); @@ -495,7 +495,7 @@ static BOOL cli_dfs_check_error( struct cli_state *cli, NTSTATUS status ) get the dfs referral link ********************************************************************/ -BOOL cli_dfs_get_referral( struct cli_state *cli, +bool cli_dfs_get_referral( struct cli_state *cli, const char *path, CLIENT_DFS_REFERRAL**refs, size_t *num_refs, @@ -582,7 +582,7 @@ BOOL cli_dfs_get_referral( struct cli_state *cli, /******************************************************************** ********************************************************************/ -BOOL cli_resolve_path( const char *mountpt, +bool cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const char *path, struct cli_state **targetcli, @@ -745,14 +745,14 @@ BOOL cli_resolve_path( const char *mountpt, /******************************************************************** ********************************************************************/ -BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, +bool cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, fstring newserver, fstring newshare ) { CLIENT_DFS_REFERRAL *refs = NULL; size_t num_refs; uint16 consumed; pstring fullpath; - BOOL res; + bool res; uint16 cnum; pstring newextrapath; diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index f170834fa9..4fc9243b5b 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -25,8 +25,8 @@ * cli_send_mailslot, send a mailslot for client code ... */ -BOOL cli_send_mailslot(struct messaging_context *msg_ctx, - BOOL unique, const char *mailslot, +bool cli_send_mailslot(struct messaging_context *msg_ctx, + bool unique, const char *mailslot, uint16 priority, char *buf, int len, const char *srcname, int src_type, @@ -110,7 +110,7 @@ BOOL cli_send_mailslot(struct messaging_context *msg_ctx, /* * cli_get_response: Get a response ... */ -BOOL cli_get_response(const char *mailslot, char *buf, int bufsiz) +bool cli_get_response(const char *mailslot, char *buf, int bufsiz) { struct packet_struct *p; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1e3af9a3d7..ca05b2e38a 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -79,7 +79,7 @@ static ssize_t client_receive_smb(int fd,char *buffer, unsigned int timeout, siz Recv an smb. ****************************************************************************/ -BOOL cli_receive_smb(struct cli_state *cli) +bool cli_receive_smb(struct cli_state *cli) { ssize_t len; @@ -166,7 +166,7 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) Read a smb readX header. ****************************************************************************/ -BOOL cli_receive_smb_readX_header(struct cli_state *cli) +bool cli_receive_smb_readX_header(struct cli_state *cli) { ssize_t len, offset; @@ -267,7 +267,7 @@ static ssize_t write_socket(int fd, const char *buf, size_t len) Send an smb to a fd. ****************************************************************************/ -BOOL cli_send_smb(struct cli_state *cli) +bool cli_send_smb(struct cli_state *cli) { size_t len; size_t nwritten=0; @@ -469,9 +469,9 @@ struct cli_state *cli_initialise(void) Returns False if the cli_close call failed. ****************************************************************************/ -BOOL cli_rpc_pipe_close(struct rpc_pipe_client *cli) +bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) { - BOOL ret; + bool ret; if (!cli) { return False; @@ -584,9 +584,9 @@ uint16 cli_setpid(struct cli_state *cli, uint16 pid) Set the case sensitivity flag on the packets. Returns old state. ****************************************************************************/ -BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) +bool cli_set_case_sensitive(struct cli_state *cli, bool case_sensitive) { - BOOL ret = cli->case_sensitive; + bool ret = cli->case_sensitive; cli->case_sensitive = case_sensitive; return ret; } @@ -595,7 +595,7 @@ BOOL cli_set_case_sensitive(struct cli_state *cli, BOOL case_sensitive) Send a keepalive packet to the server ****************************************************************************/ -BOOL cli_send_keepalive(struct cli_state *cli) +bool cli_send_keepalive(struct cli_state *cli) { if (cli->fd == -1) { DEBUG(3, ("cli_send_keepalive: fd == -1\n")); @@ -614,7 +614,7 @@ BOOL cli_send_keepalive(struct cli_state *cli) Send/receive a SMBecho command: ping the server ****************************************************************************/ -BOOL cli_echo(struct cli_state *cli, uint16 num_echos, +bool cli_echo(struct cli_state *cli, uint16 num_echos, unsigned char *data, size_t length) { char *p; diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index be018074eb..4ab1c237dc 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -396,7 +396,7 @@ int cli_errno(struct cli_state *cli) /* Return true if the last packet was in error */ -BOOL cli_is_error(struct cli_state *cli) +bool cli_is_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), rcls = 0; @@ -419,7 +419,7 @@ BOOL cli_is_error(struct cli_state *cli) /* Return true if the last error was an NT error */ -BOOL cli_is_nt_error(struct cli_state *cli) +bool cli_is_nt_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); @@ -433,7 +433,7 @@ BOOL cli_is_nt_error(struct cli_state *cli) /* Return true if the last error was a DOS error */ -BOOL cli_is_dos_error(struct cli_state *cli) +bool cli_is_dos_error(struct cli_state *cli) { uint32 flgs2 = SVAL(cli->inbuf,smb_flg2); diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index c7b39f0b8d..27ad8364ee 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -25,7 +25,7 @@ Creates new name (sym)linked to oldname. ****************************************************************************/ -static BOOL cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, BOOL hard_link) +static bool cli_link_internal(struct cli_state *cli, const char *oldname, const char *newname, bool hard_link) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -168,7 +168,7 @@ static mode_t unix_filetype_from_wire(uint32 wire_type) Do a POSIX getfacl (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf) +bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char **retbuf) { unsigned int param_len = 0; unsigned int data_len = 0; @@ -217,7 +217,7 @@ BOOL cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, Stat a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf) +bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf) { unsigned int param_len = 0; unsigned int data_len = 0; @@ -293,7 +293,7 @@ BOOL cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu Symlink a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname) +bool cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *newname) { return cli_link_internal(cli, oldname, newname, False); } @@ -302,7 +302,7 @@ BOOL cli_unix_symlink(struct cli_state *cli, const char *oldname, const char *ne Hard a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname) +bool cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *newname) { return cli_link_internal(cli, oldname, newname, True); } @@ -311,7 +311,7 @@ BOOL cli_unix_hardlink(struct cli_state *cli, const char *oldname, const char *n Chmod or chown a file internal (UNIX extensions). ****************************************************************************/ -static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid) +static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fname, uint32 mode, uint32 uid, uint32 gid) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -363,7 +363,7 @@ static BOOL cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna chmod a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) +bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) { return cli_unix_chmod_chown_internal(cli, fname, unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE); @@ -373,7 +373,7 @@ BOOL cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) chown a file (UNIX extensions). ****************************************************************************/ -BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid) +bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid) { return cli_unix_chmod_chown_internal(cli, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid); } @@ -382,7 +382,7 @@ BOOL cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t g Rename a file. ****************************************************************************/ -BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst) +bool cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_dst) { char *p; @@ -419,7 +419,7 @@ BOOL cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ NT Rename a file. ****************************************************************************/ -BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst) +bool cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fname_dst) { char *p; @@ -457,7 +457,7 @@ BOOL cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam NT hardlink a file. ****************************************************************************/ -BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) +bool cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *fname_dst) { char *p; @@ -495,7 +495,7 @@ BOOL cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *f Delete a file. ****************************************************************************/ -BOOL cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs) +bool cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs) { char *p; @@ -531,7 +531,7 @@ BOOL cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs) Delete a file. ****************************************************************************/ -BOOL cli_unlink(struct cli_state *cli, const char *fname) +bool cli_unlink(struct cli_state *cli, const char *fname) { return cli_unlink_full(cli, fname, aSYSTEM | aHIDDEN); } @@ -540,7 +540,7 @@ BOOL cli_unlink(struct cli_state *cli, const char *fname) Create a directory. ****************************************************************************/ -BOOL cli_mkdir(struct cli_state *cli, const char *dname) +bool cli_mkdir(struct cli_state *cli, const char *dname) { char *p; @@ -575,7 +575,7 @@ BOOL cli_mkdir(struct cli_state *cli, const char *dname) Remove a directory. ****************************************************************************/ -BOOL cli_rmdir(struct cli_state *cli, const char *dname) +bool cli_rmdir(struct cli_state *cli, const char *dname) { char *p; @@ -610,7 +610,7 @@ BOOL cli_rmdir(struct cli_state *cli, const char *dname) Set or clear the delete on close flag. ****************************************************************************/ -int cli_nt_delete_on_close(struct cli_state *cli, int fnum, BOOL flag) +int cli_nt_delete_on_close(struct cli_state *cli, int fnum, bool flag) { unsigned int data_len = 1; unsigned int param_len = 6; @@ -800,7 +800,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode Close a file. ****************************************************************************/ -BOOL cli_close(struct cli_state *cli, int fnum) +bool cli_close(struct cli_state *cli, int fnum) { memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -880,7 +880,7 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, note that timeout is in units of 2 milliseconds ****************************************************************************/ -BOOL cli_lock(struct cli_state *cli, int fnum, +bool cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout, enum brl_type lock_type) { char *p; @@ -935,7 +935,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, Unlock a file. ****************************************************************************/ -BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) +bool cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) { char *p; @@ -977,7 +977,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) Lock a file with 64 bit offsets. ****************************************************************************/ -BOOL cli_lock64(struct cli_state *cli, int fnum, +bool cli_lock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type) { char *p; @@ -1038,7 +1038,7 @@ BOOL cli_lock64(struct cli_state *cli, int fnum, Unlock a file with 64 bit offsets. ****************************************************************************/ -BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len) +bool cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len) { char *p; @@ -1084,8 +1084,8 @@ BOOL cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ Get/unlock a POSIX lock on a file - internal function. ****************************************************************************/ -static BOOL cli_posix_lock_internal(struct cli_state *cli, int fnum, - SMB_BIG_UINT offset, SMB_BIG_UINT len, BOOL wait_lock, enum brl_type lock_type) +static bool cli_posix_lock_internal(struct cli_state *cli, int fnum, + SMB_BIG_UINT offset, SMB_BIG_UINT len, bool wait_lock, enum brl_type lock_type) { unsigned int param_len = 4; unsigned int data_len = POSIX_LOCK_DATA_SIZE; @@ -1155,9 +1155,9 @@ static BOOL cli_posix_lock_internal(struct cli_state *cli, int fnum, POSIX Lock a file. ****************************************************************************/ -BOOL cli_posix_lock(struct cli_state *cli, int fnum, +bool cli_posix_lock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len, - BOOL wait_lock, enum brl_type lock_type) + bool wait_lock, enum brl_type lock_type) { if (lock_type != READ_LOCK && lock_type != WRITE_LOCK) { return False; @@ -1169,7 +1169,7 @@ BOOL cli_posix_lock(struct cli_state *cli, int fnum, POSIX Unlock a file. ****************************************************************************/ -BOOL cli_posix_unlock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len) +bool cli_posix_unlock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len) { return cli_posix_lock_internal(cli, fnum, offset, len, False, UNLOCK_LOCK); } @@ -1178,7 +1178,7 @@ BOOL cli_posix_unlock(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_ POSIX Get any lock covering a file. ****************************************************************************/ -BOOL cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, SMB_BIG_UINT *plen) +bool cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, SMB_BIG_UINT *plen) { return True; } @@ -1187,7 +1187,7 @@ BOOL cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, S Do a SMBgetattrE call. ****************************************************************************/ -BOOL cli_getattrE(struct cli_state *cli, int fd, +bool cli_getattrE(struct cli_state *cli, int fd, uint16 *attr, SMB_OFF_T *size, time_t *change_time, time_t *access_time, @@ -1240,7 +1240,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd, Do a SMBgetatr call ****************************************************************************/ -BOOL cli_getatr(struct cli_state *cli, const char *fname, +bool cli_getatr(struct cli_state *cli, const char *fname, uint16 *attr, SMB_OFF_T *size, time_t *write_time) { char *p; @@ -1289,7 +1289,7 @@ BOOL cli_getatr(struct cli_state *cli, const char *fname, Do a SMBsetattrE call. ****************************************************************************/ -BOOL cli_setattrE(struct cli_state *cli, int fd, +bool cli_setattrE(struct cli_state *cli, int fd, time_t change_time, time_t access_time, time_t write_time) @@ -1332,7 +1332,7 @@ BOOL cli_setattrE(struct cli_state *cli, int fd, Do a SMBsetatr call. ****************************************************************************/ -BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) +bool cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) { char *p; @@ -1370,7 +1370,7 @@ BOOL cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) /**************************************************************************** Check for existance of a dir. ****************************************************************************/ -BOOL cli_chkpath(struct cli_state *cli, const char *path) +bool cli_chkpath(struct cli_state *cli, const char *path) { pstring path2; char *p; @@ -1405,7 +1405,7 @@ BOOL cli_chkpath(struct cli_state *cli, const char *path) Query disk space. ****************************************************************************/ -BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) +bool cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); @@ -1513,7 +1513,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * Set an extended attribute utility fn. *********************************************************/ -static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len, +static bool cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len, const char *ea_name, const char *ea_val, size_t ea_len) { unsigned int data_len = 0; @@ -1573,7 +1573,7 @@ static BOOL cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigne Set an extended attribute on a pathname. *********************************************************/ -BOOL cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) +bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_name, const char *ea_val, size_t ea_len) { uint16 setup = TRANSACT2_SETPATHINFO; unsigned int param_len = 0; @@ -1595,7 +1595,7 @@ BOOL cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_nam Set an extended attribute on an fnum. *********************************************************/ -BOOL cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len) +bool cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const char *ea_val, size_t ea_len) { char param[6]; uint16 setup = TRANSACT2_SETFILEINFO; @@ -1611,7 +1611,7 @@ BOOL cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const Get an extended attribute list tility fn. *********************************************************/ -static BOOL cli_get_ea_list(struct cli_state *cli, +static bool cli_get_ea_list(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len, TALLOC_CTX *ctx, size_t *pnum_eas, @@ -1623,7 +1623,7 @@ static BOOL cli_get_ea_list(struct cli_state *cli, char *p; size_t ea_size; size_t num_eas; - BOOL ret = False; + bool ret = False; struct ea_struct *ea_list; *pnum_eas = 0; @@ -1736,7 +1736,7 @@ static BOOL cli_get_ea_list(struct cli_state *cli, Get an extended attribute list from a pathname. *********************************************************/ -BOOL cli_get_ea_list_path(struct cli_state *cli, const char *path, +bool cli_get_ea_list_path(struct cli_state *cli, const char *path, TALLOC_CTX *ctx, size_t *pnum_eas, struct ea_struct **pea_list) @@ -1760,7 +1760,7 @@ BOOL cli_get_ea_list_path(struct cli_state *cli, const char *path, Get an extended attribute list from an fnum. *********************************************************/ -BOOL cli_get_ea_list_fnum(struct cli_state *cli, int fnum, +bool cli_get_ea_list_fnum(struct cli_state *cli, int fnum, TALLOC_CTX *ctx, size_t *pnum_eas, struct ea_struct **pea_list) @@ -1832,7 +1832,7 @@ static uint32 open_flags_to_wire(int flags) Open a file - POSIX semantics. Returns fnum. Doesn't request oplock. ****************************************************************************/ -static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int flags, mode_t mode, BOOL is_dir) +static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int flags, mode_t mode, bool is_dir) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -1911,7 +1911,7 @@ int cli_posix_mkdir(struct cli_state *cli, const char *fname, mode_t mode) unlink or rmdir - POSIX semantics. ****************************************************************************/ -static BOOL cli_posix_unlink_internal(struct cli_state *cli, const char *fname, BOOL is_dir) +static bool cli_posix_unlink_internal(struct cli_state *cli, const char *fname, bool is_dir) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -1958,7 +1958,7 @@ static BOOL cli_posix_unlink_internal(struct cli_state *cli, const char *fname, unlink - POSIX semantics. ****************************************************************************/ -BOOL cli_posix_unlink(struct cli_state *cli, const char *fname) +bool cli_posix_unlink(struct cli_state *cli, const char *fname) { return cli_posix_unlink_internal(cli, fname, False); } diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index d2f759b192..a45623b9e4 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -23,10 +23,10 @@ Get UNIX extensions version info. ****************************************************************************/ -BOOL cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor, +bool cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor, uint32 *pcaplow, uint32 *pcaphigh) { - BOOL ret = False; + bool ret = False; uint16 setup; char param[2]; char *rparam=NULL, *rdata=NULL; @@ -82,10 +82,10 @@ cleanup: Set UNIX extensions capabilities. ****************************************************************************/ -BOOL cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, uint16 minor, +bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, uint16 minor, uint32 caplow, uint32 caphigh) { - BOOL ret = False; + bool ret = False; uint16 setup; char param[4]; char data[12]; @@ -131,9 +131,9 @@ cleanup: return ret; } -BOOL cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) +bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) { - BOOL ret = False; + bool ret = False; uint16 setup; char param[2]; char *rparam=NULL, *rdata=NULL; @@ -185,9 +185,9 @@ cleanup: return ret; } -BOOL cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number) +bool cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number) { - BOOL ret = False; + bool ret = False; uint16 setup; char param[2]; char *rparam=NULL, *rdata=NULL; @@ -241,9 +241,9 @@ cleanup: return ret; } -BOOL cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate) +bool cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate) { - BOOL ret = False; + bool ret = False; uint16 setup; char param[2]; char *rparam=NULL, *rdata=NULL; diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index c036d7a930..4291834797 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -271,7 +271,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, } #endif -BOOL unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx, +bool unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx, DATA_BLOB *edata, DATA_BLOB *edata_out) { @@ -310,7 +310,7 @@ BOOL unwrap_edata_ntstatus(TALLOC_CTX *mem_ctx, } -BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data) +bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_pac_data) { DATA_BLOB pac_contents; ASN1_DATA data; @@ -347,10 +347,10 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ return True; } - BOOL get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt) + bool get_auth_data_from_tkt(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, krb5_ticket *tkt) { DATA_BLOB auth_data_wrapped; - BOOL got_auth_data_pac = False; + bool got_auth_data_pac = False; int i; #if defined(HAVE_KRB5_TKT_ENC_PART2) @@ -540,7 +540,7 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ #endif } - BOOL kerberos_compatible_enctypes(krb5_context context, + bool kerberos_compatible_enctypes(krb5_context context, krb5_enctype enctype1, krb5_enctype enctype2) { @@ -554,7 +554,7 @@ BOOL unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ #endif } -static BOOL ads_cleanup_expired_creds(krb5_context context, +static bool ads_cleanup_expired_creds(krb5_context context, krb5_ccache ccache, krb5_creds *credsp) { @@ -607,7 +607,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, krb5_creds * credsp; krb5_creds creds; krb5_data in_data; - BOOL creds_ready = False; + bool creds_ready = False; int i = 0, maxtries = 3; retval = smb_krb5_parse_name(context, principal, &server); @@ -759,11 +759,11 @@ failed: return retval; } - BOOL get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, BOOL remote) + bool get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, bool remote) { krb5_keyblock *skey; krb5_error_code err; - BOOL ret = False; + bool ret = False; if (remote) err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); @@ -1095,7 +1095,7 @@ out: return smb_krb5_parse_name(context, name, principal); } - BOOL smb_krb5_principal_compare_any_realm(krb5_context context, + bool smb_krb5_principal_compare_any_realm(krb5_context context, krb5_const_principal princ1, krb5_const_principal princ2) { @@ -1383,7 +1383,7 @@ done: krb5_data *packet) { krb5_error_code ret; - BOOL got_error_code = False; + bool got_error_code = False; DEBUG(10,("handle_krberror_packet: got error packet\n")); @@ -1548,7 +1548,7 @@ done: * allows to process non-default keytab names. * @param context krb5_context * @param keytab_name_req string - * @param write_access BOOL if writable keytab is required + * @param write_access bool if writable keytab is required * @param krb5_keytab pointer to krb5_keytab (close with krb5_kt_close()) * @return krb5_error_code **********************************************************************/ @@ -1560,13 +1560,13 @@ done: krb5_error_code smb_krb5_open_keytab(krb5_context context, const char *keytab_name_req, - BOOL write_access, + bool write_access, krb5_keytab *keytab) { krb5_error_code ret = 0; TALLOC_CTX *mem_ctx; char keytab_string[MAX_KEYTAB_NAME_LEN]; - BOOL found_valid_name = False; + bool found_valid_name = False; const char *pragma = "FILE"; const char *tmp = NULL; diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 5da63096b1..fd0c380409 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -168,7 +168,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, char *dirlist = NULL; int dirlist_len = 0; int total_received = -1; - BOOL First = True; + bool First = True; int ff_searchcount=0; int ff_eos=0; int ff_dir_handle=0; @@ -401,7 +401,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, { char *p; int received = 0; - BOOL first = True; + bool first = True; char status[21]; int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; int num_received = 0; diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 46d7c1c3be..2a195753ae 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -45,7 +45,7 @@ int cli_message_start_build(struct cli_state *cli, char *host, char *username) return(PTR_DIFF(p, cli->outbuf)); } -BOOL cli_message_start(struct cli_state *cli, char *host, char *username, +bool cli_message_start(struct cli_state *cli, char *host, char *username, int *grp) { cli_message_start_build(cli, host, username); @@ -101,7 +101,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) return(PTR_DIFF(p, cli->outbuf)); } -BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +bool cli_message_text(struct cli_state *cli, char *msg, int len, int grp) { cli_message_text_build(cli, msg, len, grp); @@ -137,7 +137,7 @@ int cli_message_end_build(struct cli_state *cli, int grp) return(PTR_DIFF(p, cli->outbuf)); } -BOOL cli_message_end(struct cli_state *cli, int grp) +bool cli_message_end(struct cli_state *cli, int grp) { cli_message_end_build(cli, grp); diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index 387c40b401..effd4a5565 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -22,11 +22,11 @@ /**************************************************************************** send an ack for an oplock break request ****************************************************************************/ -BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) +bool cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) { char *oldbuf = cli->outbuf; pstring buf; - BOOL ret; + bool ret; cli->outbuf = buf; @@ -59,7 +59,7 @@ BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) set the oplock handler for a connection ****************************************************************************/ void cli_oplock_handler(struct cli_state *cli, - BOOL (*handler)(struct cli_state *, int, unsigned char)) + bool (*handler)(struct cli_state *, int, unsigned char)) { cli->oplock_handler = handler; } diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 9e55e5cef3..cab890b08b 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -235,7 +235,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_ Close a file. ****************************************************************************/ -BOOL cli_spl_close(struct cli_state *cli, int fnum) +bool cli_spl_close(struct cli_state *cli, int fnum) { memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 47d8cfe5fe..1932c044e2 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -19,7 +19,7 @@ #include "includes.h" -BOOL cli_get_quota_handle(struct cli_state *cli, int *quota_fnum) +bool cli_get_quota_handle(struct cli_state *cli, int *quota_fnum) { *quota_fnum = cli_nt_create_full(cli, FAKE_FILE_NAME_QUOTA_WIN32, 0x00000016, DESIRED_ACCESS_PIPE, @@ -46,7 +46,7 @@ void free_ntquota_list(SMB_NTQUOTA_LIST **qt_list) return; } -static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt) +static bool parse_user_quota_record(const char *rdata, unsigned int rdata_count, unsigned int *offset, SMB_NTQUOTA_STRUCT *pqt) { int sid_len; SMB_NTQUOTA_STRUCT qt; @@ -126,9 +126,9 @@ static BOOL parse_user_quota_record(const char *rdata, unsigned int rdata_count, return True; } -BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +bool cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) { - BOOL ret = False; + bool ret = False; uint16 setup; char params[16]; unsigned int data_len; @@ -194,9 +194,9 @@ BOOL cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUC return ret; } -BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +bool cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) { - BOOL ret = False; + bool ret = False; uint16 setup; char params[2]; char data[112]; @@ -253,9 +253,9 @@ BOOL cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUC return ret; } -BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list) +bool cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST **pqt_list) { - BOOL ret = False; + bool ret = False; uint16 setup; char params[16]; char *rparam=NULL, *rdata=NULL; @@ -412,9 +412,9 @@ BOOL cli_list_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_LIST return ret; } -BOOL cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +bool cli_get_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) { - BOOL ret = False; + bool ret = False; uint16 setup; char param[2]; char *rparam=NULL, *rdata=NULL; @@ -499,9 +499,9 @@ cleanup: return ret; } -BOOL cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) +bool cli_set_fs_quota_info(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUCT *pqt) { - BOOL ret = False; + bool ret = False; uint16 setup; char param[4]; char data[48]; @@ -562,7 +562,7 @@ cleanup: return ret; } -static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric) +static char *quota_str_static(SMB_BIG_UINT val, bool special, bool _numeric) { static fstring buffer; @@ -580,7 +580,7 @@ static char *quota_str_static(SMB_BIG_UINT val, BOOL special, BOOL _numeric) return buffer; } -void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric)) +void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, bool _verbose, bool _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, bool _numeric)) { if (!qt) { smb_panic("dump_ntquota() called with NULL pointer"); @@ -630,7 +630,7 @@ void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, BOOL _verbose, BOOL _numeric, void (*_ } } -void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, BOOL _verbose, BOOL _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, BOOL _numeric)) +void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, bool _verbose, bool _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, bool _numeric)) { SMB_NTQUOTA_LIST *cur; diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 801b6f61ec..9d106d0394 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -24,7 +24,7 @@ Call a remote api on an arbitrary pipe. takes param, data and setup buffers. ****************************************************************************/ -BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, +bool cli_api_pipe(struct cli_state *cli, const char *pipe_name, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, char *data, uint32 data_count, uint32 max_data_count, @@ -47,7 +47,7 @@ BOOL cli_api_pipe(struct cli_state *cli, const char *pipe_name, Call a remote api ****************************************************************************/ -BOOL cli_api(struct cli_state *cli, +bool cli_api(struct cli_state *cli, char *param, int prcnt, int mprcnt, char *data, int drcnt, int mdrcnt, char **rparam, unsigned int *rprcnt, @@ -70,7 +70,7 @@ BOOL cli_api(struct cli_state *cli, Perform a NetWkstaUserLogon. ****************************************************************************/ -BOOL cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) +bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) { char *rparam = NULL; char *rdata = NULL; @@ -205,7 +205,7 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co the comment and a state pointer. ****************************************************************************/ -BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, +bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, void (*fn)(const char *, uint32, const char *, void *), void *state) { @@ -291,7 +291,7 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, Send a SamOEMChangePassword command. ****************************************************************************/ -BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, +bool cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password) { pstring param; @@ -380,7 +380,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char Send a qpathinfo call. ****************************************************************************/ -BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, +bool cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *change_time, time_t *access_time, time_t *write_time, @@ -393,7 +393,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, pstring param; char *rparam=NULL, *rdata=NULL; int count=8; - BOOL ret; + bool ret; time_t (*date_fn)(struct cli_state *, void *); char *p; @@ -463,7 +463,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname, Send a setpathinfo call. ****************************************************************************/ -BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, +bool cli_setpathinfo(struct cli_state *cli, const char *fname, time_t create_time, time_t access_time, time_t write_time, @@ -478,7 +478,7 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, pstring data; char *rparam=NULL, *rdata=NULL; int count=8; - BOOL ret; + bool ret; char *p; memset(param, 0, sizeof(param)); @@ -561,7 +561,7 @@ BOOL cli_setpathinfo(struct cli_state *cli, const char *fname, Send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level. ****************************************************************************/ -BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, +bool cli_qpathinfo2(struct cli_state *cli, const char *fname, struct timespec *create_time, struct timespec *access_time, struct timespec *write_time, @@ -635,7 +635,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname, Send a qfileinfo QUERY_FILE_NAME_INFO call. ****************************************************************************/ -BOOL cli_qfilename(struct cli_state *cli, int fnum, +bool cli_qfilename(struct cli_state *cli, int fnum, pstring name) { unsigned int data_len = 0; @@ -678,7 +678,7 @@ BOOL cli_qfilename(struct cli_state *cli, int fnum, Send a qfileinfo call. ****************************************************************************/ -BOOL cli_qfileinfo(struct cli_state *cli, int fnum, +bool cli_qfileinfo(struct cli_state *cli, int fnum, uint16 *mode, SMB_OFF_T *size, struct timespec *create_time, struct timespec *access_time, @@ -753,7 +753,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum, Send a qpathinfo BASIC_INFO call. ****************************************************************************/ -BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, +bool cli_qpathinfo_basic( struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf, uint32 *attributes ) { unsigned int param_len = 0; @@ -817,7 +817,7 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name, Send a qfileinfo call. ****************************************************************************/ -BOOL cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen) +bool cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutdata, uint32 *poutlen) { unsigned int data_len = 0; unsigned int param_len = 0; @@ -882,7 +882,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin char *rparam=NULL, *rdata=NULL; int count=8; char *p; - BOOL ret; + bool ret; unsigned int len; p = param; diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index b8fe31a562..6be7fb6a56 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1231,7 +1231,7 @@ int cli_NetShareDelete(struct cli_state *cli, const char * share_name ) * False - failure * ************************************************************************/ -BOOL cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) +bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) { char *rparam = NULL; char *rdata = NULL; @@ -1311,7 +1311,7 @@ BOOL cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum() * ************************************************************************/ -BOOL cli_get_server_domain(struct cli_state *cli) +bool cli_get_server_domain(struct cli_state *cli) { char *rparam = NULL; char *rdata = NULL; @@ -1376,7 +1376,7 @@ BOOL cli_get_server_domain(struct cli_state *cli) * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum() * ************************************************************************/ -BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype) +bool cli_get_server_type(struct cli_state *cli, uint32 *pstype) { char *rparam = NULL; char *rdata = NULL; @@ -1416,7 +1416,7 @@ BOOL cli_get_server_type(struct cli_state *cli, uint32 *pstype) return(res == 0 || res == ERRmoredata); } -BOOL cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, +bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, char **servername) { char *rparam = NULL; @@ -1428,7 +1428,7 @@ BOOL cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, +sizeof(RAP_SERVER_INFO_L1) /* return string */ +WORDSIZE /* info level */ +WORDSIZE]; /* buffer size */ - BOOL res = False; + bool res = False; fstring tmp; /* send a SMBtrans command with api NetServerGetInfo */ @@ -1499,7 +1499,7 @@ BOOL cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, * False - failure * ************************************************************************/ -BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype) +bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype) { char *rparam = NULL; char *rdata = NULL; @@ -1512,7 +1512,7 @@ BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 sty +WORDSIZE /* buffer size */ +DWORDSIZE /* server type */ +RAP_MACHNAME_LEN]; /* workgroup */ - BOOL found_server = False; + bool found_server = False; int res = -1; /* send a SMBtrans command with api NetServerEnum */ @@ -1566,7 +1566,7 @@ BOOL cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 sty /**************************************************************************** perform a NetWkstaUserLogoff ****************************************************************************/ -BOOL cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) +bool cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) { char *rparam = NULL; char *rdata = NULL; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index ed80dfaf1a..0d037e946e 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -23,10 +23,10 @@ Issue a single SMBread and don't wait for a reply. ****************************************************************************/ -static BOOL cli_issue_read(struct cli_state *cli, int fnum, off_t offset, +static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { - BOOL bigoffset = False; + bool bigoffset = False; memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -66,7 +66,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ size_t readsize; ssize_t total = 0; /* We can only do direct reads if not signing. */ - BOOL direct_reads = !client_is_signing_on(cli); + bool direct_reads = !client_is_signing_on(cli); if (size == 0) return 0; @@ -108,7 +108,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ errors. */ if (cli_is_error(cli)) { - BOOL recoverable_error = False; + bool recoverable_error = False; NTSTATUS status = NT_STATUS_OK; uint8 eclass = 0; uint32 ecode = 0; @@ -191,7 +191,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ Issue a single SMBreadraw and don't wait for a reply. ****************************************************************************/ -static BOOL cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, +static bool cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { @@ -284,12 +284,12 @@ ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, si issue a single SMBwrite and don't wait for a reply ****************************************************************************/ -static BOOL cli_issue_write(struct cli_state *cli, int fnum, off_t offset, +static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint16 mode, const char *buf, size_t size, int i) { char *p; - BOOL large_writex = False; + bool large_writex = False; if (size > cli->bufsize) { cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024); diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 27629ea96d..46a6609415 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -29,7 +29,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; prs_struct pd; - BOOL pd_initialized = False; + bool pd_initialized = False; SEC_DESC *psd = NULL; SIVAL(param, 0, fnum); @@ -81,7 +81,7 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, /**************************************************************************** set the security descriptor for a open file ****************************************************************************/ -BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) +bool cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) { char param[8]; char *rparam=NULL, *rdata=NULL; @@ -89,7 +89,7 @@ BOOL cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) uint32 sec_info = 0; TALLOC_CTX *mem_ctx; prs_struct pd; - BOOL ret = False; + bool ret = False; if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) { DEBUG(0,("talloc_init failed.\n")); diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 9432ce81d3..f95b11e4cd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -122,12 +122,12 @@ DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) parse a negTokenInit packet giving a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ -BOOL spnego_parse_negTokenInit(DATA_BLOB blob, +bool spnego_parse_negTokenInit(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], char **principal) { int i; - BOOL ret; + bool ret; ASN1_DATA data; asn1_load(&data, blob); @@ -224,7 +224,7 @@ DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) /* parse a negTokenTarg packet giving a list of OIDs and a security blob */ -BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) +bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) { int i; ASN1_DATA data; @@ -301,9 +301,9 @@ DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2]) /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) +bool spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) { - BOOL ret; + bool ret; ASN1_DATA data; int data_remaining; @@ -373,10 +373,10 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, /* parse a spnego NTLMSSP challenge packet giving two security blobs */ -BOOL spnego_parse_challenge(const DATA_BLOB blob, +bool spnego_parse_challenge(const DATA_BLOB blob, DATA_BLOB *chal1, DATA_BLOB *chal2) { - BOOL ret; + bool ret; ASN1_DATA data; ZERO_STRUCTP(chal1); @@ -448,7 +448,7 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) /* parse a SPNEGO auth packet. This contains the encrypted passwords */ -BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) +bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) { ASN1_DATA data; @@ -519,7 +519,7 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, /* parse a SPNEGO auth packet. This contains the encrypted passwords */ -BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, +bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, const char *mechOID, DATA_BLOB *auth) { diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index e859dce956..5db624150d 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -24,7 +24,7 @@ Send a SMB trans or trans2 request. ****************************************************************************/ -BOOL cli_send_trans(struct cli_state *cli, int trans, +bool cli_send_trans(struct cli_state *cli, int trans, const char *pipe_name, int fid, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, @@ -162,7 +162,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans, Receive a SMB trans or trans2 response allocating the necessary memory. ****************************************************************************/ -BOOL cli_receive_trans(struct cli_state *cli,int trans, +bool cli_receive_trans(struct cli_state *cli,int trans, char **param, unsigned int *param_len, char **data, unsigned int *data_len) { @@ -170,7 +170,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, unsigned int total_param=0; unsigned int this_data,this_param; NTSTATUS status; - BOOL ret = False; + bool ret = False; *data_len = *param_len = 0; @@ -341,7 +341,7 @@ BOOL cli_receive_trans(struct cli_state *cli,int trans, Send a SMB nttrans request. ****************************************************************************/ -BOOL cli_send_nt_trans(struct cli_state *cli, +bool cli_send_nt_trans(struct cli_state *cli, int function, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, @@ -469,7 +469,7 @@ BOOL cli_send_nt_trans(struct cli_state *cli, Receive a SMB nttrans response allocating the necessary memory. ****************************************************************************/ -BOOL cli_receive_nt_trans(struct cli_state *cli, +bool cli_receive_nt_trans(struct cli_state *cli, char **param, unsigned int *param_len, char **data, unsigned int *data_len) { @@ -478,7 +478,7 @@ BOOL cli_receive_nt_trans(struct cli_state *cli, unsigned int this_data,this_param; uint8 eclass; uint32 ecode; - BOOL ret = False; + bool ret = False; *data_len = *param_len = 0; diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 80b18c6b99..973bb6ad28 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -211,7 +211,7 @@ void creds_server_init(uint32 neg_flags, Check a credential sent by the client. ****************************************************************************/ -BOOL creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in) +bool creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in) { if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) { DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data))); @@ -243,9 +243,9 @@ static void creds_reseed(struct dcinfo *dc) Step the server credential chain one forward. ****************************************************************************/ -BOOL creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out) +bool creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out) { - BOOL ret; + bool ret; struct dcinfo tmp_dc = *dc; /* Do all operations on a temporary copy of the dc, @@ -315,7 +315,7 @@ void creds_client_init(uint32 neg_flags, Check a credential returned by the server. ****************************************************************************/ -BOOL creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in) +bool creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in) { if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, 8)) { DEBUG(5,("creds_client_check: challenge : %s\n", credstr(rcv_srv_chal_in->data))); diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 89bb65006d..bffbd0f8dc 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -302,7 +302,7 @@ static NTSTATUS DsGetDcName_cache_store(TALLOC_CTX *mem_ctx, { time_t expire_time; char *key; - BOOL ret = False; + bool ret = False; DATA_BLOB blob; unsigned char *buf = NULL; int len = 0; @@ -374,7 +374,7 @@ static NTSTATUS DsGetDcName_cache_refresh(TALLOC_CTX *mem_ctx, #define RETURN_ON_FALSE(x) if (!x) return False; -static BOOL check_cldap_reply_required_flags(uint32_t ret_flags, +static bool check_cldap_reply_required_flags(uint32_t ret_flags, uint32_t req_flags) { if (req_flags & DS_PDC_REQUIRED) @@ -411,7 +411,7 @@ static NTSTATUS DsGetDcName_cache_fetch(TALLOC_CTX *mem_ctx, uint32_t flags, const char *site_name, struct DS_DOMAIN_CONTROLLER_INFO **info, - BOOL *expired) + bool *expired) { char *key; DATA_BLOB blob; @@ -463,7 +463,7 @@ static NTSTATUS DsGetDcName_cached(TALLOC_CTX *mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO **info) { NTSTATUS status; - BOOL expired = False; + bool expired = False; status = DsGetDcName_cache_fetch(mem_ctx, domain_name, domain_guid, flags, site_name, info, &expired); @@ -492,7 +492,7 @@ static NTSTATUS DsGetDcName_cached(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static BOOL check_allowed_required_flags(uint32_t flags) +static bool check_allowed_required_flags(uint32_t flags) { uint32_t return_type = flags & (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME); uint32_t offered_type = flags & (DS_IS_FLAT_NAME|DS_IS_DNS_NAME); @@ -740,7 +740,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO **info) { int i = 0; - BOOL valid_dc = False; + bool valid_dc = False; struct cldap_netlogon_reply r; const char *dc_hostname, *dc_domain_name; const char *dc_address; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 49384e2728..3b5818a015 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -111,7 +111,7 @@ smbc_lseek_ctx(SMBCCTX *context, off_t offset, int whence); -extern BOOL in_client; +extern bool in_client; /* * Is the logging working / configfile read ? @@ -635,7 +635,7 @@ find_server(SMBCCTX *context, static SMBCSRV * smbc_server(SMBCCTX *context, - BOOL connect_if_not_found, + bool connect_if_not_found, const char *server, const char *share, fstring workgroup, @@ -1481,7 +1481,7 @@ smbc_close_ctx(SMBCCTX *context, * Get info from an SMB server on a file. Use a qpathinfo call first * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo */ -static BOOL +static bool smbc_getatr(SMBCCTX * context, SMBCSRV *srv, char *path, @@ -1580,7 +1580,7 @@ smbc_getatr(SMBCCTX * context, * * "mode" (attributes) parameter may be set to -1 if it is not to be set. */ -static BOOL +static bool smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, time_t create_time, time_t access_time, @@ -3741,8 +3741,8 @@ static int ace_compare(SEC_ACE *ace1, SEC_ACE *ace2) { - BOOL b1; - BOOL b2; + bool b1; + bool b2; /* If the ACEs are equal, we have nothing more to do. */ if (sec_ace_equal(ace1, ace2)) { @@ -3851,7 +3851,7 @@ static void convert_sid_to_string(struct cli_state *ipc_cli, POLICY_HND *pol, fstring str, - BOOL numeric, + bool numeric, DOM_SID *sid) { char **domains = NULL; @@ -3885,16 +3885,16 @@ convert_sid_to_string(struct cli_state *ipc_cli, } /* convert a string to a SID, either numeric or username/group */ -static BOOL +static bool convert_string_to_sid(struct cli_state *ipc_cli, POLICY_HND *pol, - BOOL numeric, + bool numeric, DOM_SID *sid, const char *str) { enum lsa_SidType *types = NULL; DOM_SID *sids = NULL; - BOOL result = True; + bool result = True; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); if (!pipe_hnd) { @@ -3925,11 +3925,11 @@ convert_string_to_sid(struct cli_state *ipc_cli, /* parse an ACE in the same format as print_ace() */ -static BOOL +static bool parse_ace(struct cli_state *ipc_cli, POLICY_HND *pol, SEC_ACE *ace, - BOOL numeric, + bool numeric, char *str) { char *p; @@ -4024,7 +4024,7 @@ parse_ace(struct cli_state *ipc_cli, p = tok; while(*p) { - BOOL found = False; + bool found = False; for (v = special_values; v->perm; v++) { if (v->perm[0] == *p) { @@ -4048,7 +4048,7 @@ parse_ace(struct cli_state *ipc_cli, } /* add an ACE to a list of ACEs in a SEC_ACL */ -static BOOL +static bool add_ace(SEC_ACL **the_acl, SEC_ACE *ace, TALLOC_CTX *ctx) @@ -4079,7 +4079,7 @@ static SEC_DESC * sec_desc_parse(TALLOC_CTX *ctx, struct cli_state *ipc_cli, POLICY_HND *pol, - BOOL numeric, + bool numeric, char *str) { const char *p = str; @@ -4359,25 +4359,25 @@ cacl_get(SMBCCTX *context, uint32 i; int n = 0; int n_used; - BOOL all; - BOOL all_nt; - BOOL all_nt_acls; - BOOL all_dos; - BOOL some_nt; - BOOL some_dos; - BOOL exclude_nt_revision = False; - BOOL exclude_nt_owner = False; - BOOL exclude_nt_group = False; - BOOL exclude_nt_acl = False; - BOOL exclude_dos_mode = False; - BOOL exclude_dos_size = False; - BOOL exclude_dos_create_time = False; - BOOL exclude_dos_access_time = False; - BOOL exclude_dos_write_time = False; - BOOL exclude_dos_change_time = False; - BOOL exclude_dos_inode = False; - BOOL numeric = True; - BOOL determine_size = (bufsize == 0); + bool all; + bool all_nt; + bool all_nt_acls; + bool all_dos; + bool some_nt; + bool some_dos; + bool exclude_nt_revision = False; + bool exclude_nt_owner = False; + bool exclude_nt_group = False; + bool exclude_nt_acl = False; + bool exclude_dos_mode = False; + bool exclude_dos_size = False; + bool exclude_dos_create_time = False; + bool exclude_dos_access_time = False; + bool exclude_dos_write_time = False; + bool exclude_dos_change_time = False; + bool exclude_dos_inode = False; + bool numeric = True; + bool determine_size = (bufsize == 0); int fnum = -1; SEC_DESC *sd; fstring sidstr; @@ -5147,7 +5147,7 @@ cacl_set(TALLOC_CTX *ctx, size_t sd_size; int ret = 0; char *p; - BOOL numeric = True; + bool numeric = True; /* the_acl will be null for REMOVE_ALL operations */ if (the_acl) { @@ -5208,7 +5208,7 @@ cacl_set(TALLOC_CTX *ctx, case SMBC_XATTR_MODE_REMOVE: for (i=0;sd->dacl && idacl->num_aces;i++) { - BOOL found = False; + bool found = False; for (j=0;old->dacl && jdacl->num_aces;j++) { if (sec_ace_equal(&sd->dacl->aces[i], @@ -5235,7 +5235,7 @@ cacl_set(TALLOC_CTX *ctx, case SMBC_XATTR_MODE_ADD: for (i=0;sd->dacl && idacl->num_aces;i++) { - BOOL found = False; + bool found = False; for (j=0;old->dacl && jdacl->num_aces;j++) { if (sid_equal(&sd->dacl->aces[i].trustee, @@ -6387,7 +6387,7 @@ smbc_option_set(SMBCCTX *context, va_list ap; union { int i; - BOOL b; + bool b; smbc_get_auth_data_with_context_fn auth_fn; void *v; } option_value; @@ -6398,7 +6398,7 @@ smbc_option_set(SMBCCTX *context, /* * Log to standard error instead of standard output. */ - option_value.b = (BOOL) va_arg(ap, int); + option_value.b = (bool) va_arg(ap, int); context->internal->_debug_stderr = option_value.b; } else if (strcmp(option_name, "full_time_names") == 0) { @@ -6410,7 +6410,7 @@ smbc_option_set(SMBCCTX *context, * be CHANGE_TIME but was confused and sometimes referred to * CREATE_TIME.) */ - option_value.b = (BOOL) va_arg(ap, int); + option_value.b = (bool) va_arg(ap, int); context->internal->_full_time_names = option_value.b; } else if (strcmp(option_name, "open_share_mode") == 0) { @@ -6533,7 +6533,7 @@ smbc_init_context(SMBCCTX *context) * Do some library-wide intializations the first time we get * called */ - BOOL conf_loaded = False; + bool conf_loaded = False; /* Set this to what the user wants */ DEBUGLEVEL = context->debug; diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index aeca5673c0..b569100d94 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -33,7 +33,7 @@ * false on failure **/ -BOOL namecache_enable(void) +bool namecache_enable(void) { /* * Check if name caching disabled by setting the name cache @@ -68,7 +68,7 @@ BOOL namecache_enable(void) * false on failure **/ -BOOL namecache_shutdown(void) +bool namecache_shutdown(void) { if (!gencache_shutdown()) { DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n")); @@ -111,13 +111,13 @@ static char* namecache_key(const char *name, int name_type) * ip addresses being stored **/ -BOOL namecache_store(const char *name, int name_type, +bool namecache_store(const char *name, int name_type, int num_names, struct ip_service *ip_list) { time_t expiry; char *key, *value_string; int i; - BOOL ret; + bool ret; /* * we use gecache call to avoid annoying debug messages about @@ -179,7 +179,7 @@ BOOL namecache_store(const char *name, int name_type, * false if name isn't found in the cache or has expired **/ -BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_list, +bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_list, int *num_names) { char *key, *value; @@ -229,9 +229,9 @@ BOOL namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis * **/ -BOOL namecache_delete(const char *name, int name_type) +bool namecache_delete(const char *name, int name_type) { - BOOL ret; + bool ret; char *key; if (!gencache_init()) @@ -298,13 +298,13 @@ static char *namecache_status_record_key(const char *name, int name_type1, /* Store a name status record. */ -BOOL namecache_status_store(const char *keyname, int keyname_type, +bool namecache_status_store(const char *keyname, int keyname_type, int name_type, struct in_addr keyip, const char *srvname) { char *key; time_t expiry; - BOOL ret; + bool ret; if (!gencache_init()) return False; @@ -327,7 +327,7 @@ BOOL namecache_status_store(const char *keyname, int keyname_type, /* Fetch a name status record. */ -BOOL namecache_status_fetch(const char *keyname, int keyname_type, +bool namecache_status_fetch(const char *keyname, int keyname_type, int name_type, struct in_addr keyip, char *srvname_out) { char *key = NULL; diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 5459210c64..12e0d01b3b 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -20,7 +20,7 @@ #include "includes.h" /* nmbd.c sets this to True. */ -BOOL global_in_nmbd = False; +bool global_in_nmbd = False; /**************************** * SERVER AFFINITY ROUTINES * @@ -46,11 +46,11 @@ static char *saf_key(const char *domain) /**************************************************************************** ****************************************************************************/ -BOOL saf_store( const char *domain, const char *servername ) +bool saf_store( const char *domain, const char *servername ) { char *key; time_t expire; - BOOL ret = False; + bool ret = False; if ( !domain || !servername ) { DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n")); @@ -79,10 +79,10 @@ BOOL saf_store( const char *domain, const char *servername ) return ret; } -BOOL saf_delete( const char *domain ) +bool saf_delete( const char *domain ) { char *key; - BOOL ret = False; + bool ret = False; if ( !domain ) { DEBUG(2,("saf_delete: Refusing to delete empty domain\n")); @@ -111,7 +111,7 @@ char *saf_fetch( const char *domain ) { char *server = NULL; time_t timeout; - BOOL ret = False; + bool ret = False; char *key = NULL; if ( !domain || strlen(domain) == 0) { @@ -198,7 +198,7 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, struct in_addr to_ip, int *num_names, struct node_status_extra *extra) { - BOOL found=False; + bool found=False; int retries = 2; int retry_time = 2000; struct timeval tval; @@ -281,13 +281,13 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, a servers name given its IP. Return the matched name in *name. **************************************************************************/ -BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name) +bool name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name) { NODE_STATUS_STRUCT *status = NULL; struct nmb_name nname; int count, i; int sock; - BOOL result = False; + bool result = False; if (lp_disable_netbios()) { DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type)); @@ -471,11 +471,11 @@ static int remove_duplicate_addrs2( struct ip_service *iplist, int count ) ****************************************************************************/ struct in_addr *name_query(int fd,const char *name,int name_type, - BOOL bcast,BOOL recurse, + bool bcast,bool recurse, struct in_addr to_ip, int *count, int *flags, - BOOL *timed_out) + bool *timed_out) { - BOOL found=False; + bool found=False; int i, retries = 3; int retry_time = bcast?250:2000; struct timeval tval; @@ -669,7 +669,7 @@ XFILE *startlmhosts(const char *fname) Parse the next line in the lmhosts file. *********************************************************/ -BOOL getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) +bool getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) { pstring line; @@ -761,7 +761,7 @@ void endlmhosts(XFILE *fp) return False on failure. Port is set to PORT_NONE; *********************************************************/ -static BOOL convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count ) +static bool convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count ) { int i; @@ -895,7 +895,7 @@ NTSTATUS resolve_wins(const char *name, int name_type, for (i=0; iname_type == n2->name_type) && strequal(n1->name ,n2->name ) && @@ -1072,7 +1072,7 @@ int build_packet(char *buf, size_t buflen, struct packet_struct *p) Send a packet_struct. ******************************************************************/ -BOOL send_packet(struct packet_struct *p) +bool send_packet(struct packet_struct *p) { char buf[1024]; int len=0; @@ -1169,7 +1169,7 @@ struct packet_struct *receive_dgram_packet(int fd, int t, See if a datagram has the right mailslot name. ***************************************************************************/ -BOOL match_mailslot_name(struct packet_struct *p, const char *mailslot_name) +bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name) { struct dgram_packet *dgram = &p->packet.dgram; char *buf; diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index dfc62c3070..f8ed044f8a 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -29,7 +29,7 @@ Core of smb password checking routine. ****************************************************************************/ -static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, +static bool smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, const uchar *part_passwd, const DATA_BLOB *sec_blob, DATA_BLOB *user_sess_key) @@ -80,11 +80,11 @@ static BOOL smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, Note: The same code works with both NTLMv2 and LMv2. ****************************************************************************/ -static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, +static bool smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, const uchar *part_passwd, const DATA_BLOB *sec_blob, const char *user, const char *domain, - BOOL upper_case_domain, /* should the domain be transformed into upper case? */ + bool upper_case_domain, /* should the domain be transformed into upper case? */ DATA_BLOB *user_sess_key) { /* Finish the encryption of part_passwd. */ @@ -92,7 +92,7 @@ static BOOL smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, uchar value_from_encryption[16]; uchar client_response[16]; DATA_BLOB client_key_data; - BOOL res; + bool res; if (part_passwd == NULL) { DEBUG(10,("No password set - DISALLOWING access\n")); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 0c0744867d..7205d57a0a 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -121,7 +121,7 @@ static const uint8 *get_challenge(const struct ntlmssp_state *ntlmssp_state) * */ -static BOOL may_set_challenge(const struct ntlmssp_state *ntlmssp_state) +static bool may_set_challenge(const struct ntlmssp_state *ntlmssp_state) { return True; } @@ -400,7 +400,7 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state, } static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, - uint32 neg_flags, BOOL allow_lm) { + uint32 neg_flags, bool allow_lm) { if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) { ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_UNICODE; ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_OEM; @@ -630,7 +630,7 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, NTSTATUS nt_status = NT_STATUS_OK; /* used by NTLM2 */ - BOOL doing_ntlm2 = False; + bool doing_ntlm2 = False; uchar session_nonce[16]; uchar session_nonce_hash[16]; diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 15739d3068..76194d5974 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -39,7 +39,7 @@ d = word (4 bytes) C = constant ascii string */ -BOOL msrpc_gen(DATA_BLOB *blob, +bool msrpc_gen(DATA_BLOB *blob, const char *format, ...) { int i, n; @@ -182,7 +182,7 @@ if ((head_ofs + amount) > blob->length) { \ C = constant ascii string */ -BOOL msrpc_parse(const DATA_BLOB *blob, +bool msrpc_parse(const DATA_BLOB *blob, const char *format, ...) { int i; diff --git a/source3/libsmb/ntlmssp_sign.c b/source3/libsmb/ntlmssp_sign.c index 0e0a1c472f..8413c8066b 100644 --- a/source3/libsmb/ntlmssp_sign.c +++ b/source3/libsmb/ntlmssp_sign.c @@ -56,7 +56,7 @@ static NTSTATUS ntlmssp_make_packet_signature(NTLMSSP_STATE *ntlmssp_state, const uchar *whole_pdu, size_t pdu_length, enum ntlmssp_direction direction, DATA_BLOB *sig, - BOOL encrypt_sig) + bool encrypt_sig) { if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_NTLM2) { HMACMD5Context ctx; diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index cec150d8b2..83cfc3efbf 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -33,7 +33,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam struct in_addr ip; NTSTATUS result; - BOOL pass_must_change = False; + bool pass_must_change = False; *err_str = '\0'; diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index c206922a5e..b1d6c8d8f3 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -30,7 +30,7 @@ static TDB_CONTEXT *netsamlogon_tdb = NULL; open the tdb ***********************************************************************/ -BOOL netsamlogon_cache_init(void) +bool netsamlogon_cache_init(void) { if (!netsamlogon_tdb) { netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0, @@ -45,7 +45,7 @@ BOOL netsamlogon_cache_init(void) Shutdown samlogon_cache database ***********************************************************************/ -BOOL netsamlogon_cache_shutdown(void) +bool netsamlogon_cache_shutdown(void) { if(netsamlogon_tdb) return (tdb_close(netsamlogon_tdb) == 0); @@ -58,7 +58,7 @@ BOOL netsamlogon_cache_shutdown(void) ***********************************************************************/ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) { - BOOL got_tdb = False; + bool got_tdb = False; DOM_SID sid; fstring key_str, sid_string; @@ -104,12 +104,12 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) username should be in UTF-8 format ***********************************************************************/ -BOOL netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) +bool netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) { TDB_DATA data; fstring keystr; prs_struct ps; - BOOL result = False; + bool result = False; DOM_SID user_sid; time_t t = time(NULL); TALLOC_CTX *mem_ctx; @@ -234,11 +234,11 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user return user; } -BOOL netsamlogon_cache_have(const DOM_SID *user_sid) +bool netsamlogon_cache_have(const DOM_SID *user_sid) { TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); NET_USER_INFO_3 *user = NULL; - BOOL result; + bool result; if (!mem_ctx) return False; diff --git a/source3/libsmb/smb_share_modes.c b/source3/libsmb/smb_share_modes.c index b0cfc765d1..16b3b10925 100644 --- a/source3/libsmb/smb_share_modes.c +++ b/source3/libsmb/smb_share_modes.c @@ -41,7 +41,7 @@ int smb_create_share_mode_entry_ex(struct smbdb_ctx *db_ctx, uint64_t dev, uint64_t ino, const struct smb_share_mode_entry *new_entry, const char *sharepath, const char *filename); -static BOOL sharemodes_procid_equal(const struct server_id *p1, const struct server_id *p2) +static bool sharemodes_procid_equal(const struct server_id *p1, const struct server_id *p2) { return (p1->pid == p2->pid); } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index c5b1d44586..1e150525ba 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,7 +25,7 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; - BOOL can_delete; /* Set to False in trans state. */ + bool can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -34,7 +34,7 @@ struct smb_basic_signing_context { struct outstanding_packet_lookup *outstanding_packet_list; }; -static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, +static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 reply_seq_num) { struct outstanding_packet_lookup *t; @@ -68,7 +68,7 @@ static BOOL store_sequence_for_reply(struct outstanding_packet_lookup **list, return True; } -static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, +static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, uint16 mid, uint32 *reply_seq_num) { struct outstanding_packet_lookup *t; @@ -88,7 +88,7 @@ static BOOL get_sequence_for_reply(struct outstanding_packet_lookup **list, return False; } -static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, BOOL can_delete_entry) +static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) { struct outstanding_packet_lookup *t; @@ -105,7 +105,7 @@ static BOOL set_sequence_can_delete_flag(struct outstanding_packet_lookup **list SMB signing - Common code before we set a new signing implementation ************************************************************/ -static BOOL cli_set_smb_signing_common(struct cli_state *cli) +static bool cli_set_smb_signing_common(struct cli_state *cli) { if (!cli->sign_info.allow_smb_signing) { return False; @@ -134,7 +134,7 @@ static BOOL cli_set_smb_signing_common(struct cli_state *cli) SMB signing - Common code for 'real' implementations ************************************************************/ -static BOOL set_smb_signing_real_common(struct smb_sign_info *si) +static bool set_smb_signing_real_common(struct smb_sign_info *si) { if (si->mandatory_signing) { DEBUG(5, ("Mandatory SMB signing enabled!\n")); @@ -170,9 +170,9 @@ static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - NULL implementation - check a MAC sent by server. ************************************************************/ -static BOOL null_check_incoming_message(const char *inbuf, +static bool null_check_incoming_message(const char *inbuf, struct smb_sign_info *si, - BOOL must_be_ok) + bool must_be_ok) { return True; } @@ -193,7 +193,7 @@ static void null_free_signing_context(struct smb_sign_info *si) shut down a real signing mechanism */ -static BOOL null_set_signing(struct smb_sign_info *si) +static bool null_set_signing(struct smb_sign_info *si) { si->signing_context = NULL; @@ -219,8 +219,8 @@ static void free_signing_context(struct smb_sign_info *si) } -static BOOL signing_good(const char *inbuf, struct smb_sign_info *si, - BOOL good, uint32 seq, BOOL must_be_ok) +static bool signing_good(const char *inbuf, struct smb_sign_info *si, + bool good, uint32 seq, bool must_be_ok) { if (good) { @@ -378,11 +378,11 @@ static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Client implementation - check a MAC sent by server. ************************************************************/ -static BOOL client_check_incoming_message(const char *inbuf, +static bool client_check_incoming_message(const char *inbuf, struct smb_sign_info *si, - BOOL must_be_ok) + bool must_be_ok) { - BOOL good; + bool good; uint32 reply_seq_number; unsigned char calc_md5_mac[16]; unsigned char *server_sent_mac; @@ -465,7 +465,7 @@ static void simple_free_signing_context(struct smb_sign_info *si) SMB signing - Simple implementation - setup the MAC key. ************************************************************/ -BOOL cli_simple_set_signing(struct cli_state *cli, +bool cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response) { @@ -536,8 +536,8 @@ static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - TEMP implementation - check a MAC sent by server. ************************************************************/ -static BOOL temp_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, BOOL foo) +static bool temp_check_incoming_message(const char *inbuf, + struct smb_sign_info *si, bool foo) { return True; } @@ -555,7 +555,7 @@ static void temp_free_signing_context(struct smb_sign_info *si) SMB signing - NULL implementation - setup the MAC key. ************************************************************/ -BOOL cli_null_set_signing(struct cli_state *cli) +bool cli_null_set_signing(struct cli_state *cli) { return null_set_signing(&cli->sign_info); } @@ -564,7 +564,7 @@ BOOL cli_null_set_signing(struct cli_state *cli) SMB signing - temp implementation - setup the MAC key. ************************************************************/ -BOOL cli_temp_set_signing(struct cli_state *cli) +bool cli_temp_set_signing(struct cli_state *cli) { if (!cli_set_smb_signing_common(cli)) { return False; @@ -599,7 +599,7 @@ void cli_calculate_sign_mac(struct cli_state *cli) * which had a bad checksum, True otherwise. */ -BOOL cli_check_sign_mac(struct cli_state *cli) +bool cli_check_sign_mac(struct cli_state *cli) { if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); @@ -612,7 +612,7 @@ BOOL cli_check_sign_mac(struct cli_state *cli) Enter trans/trans2/nttrans state. ************************************************************/ -BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) +bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) { struct smb_sign_info *si = &cli->sign_info; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; @@ -636,7 +636,7 @@ BOOL client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) Leave trans/trans2/nttrans state. ************************************************************/ -BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) +bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) { uint32 reply_seq_num; struct smb_sign_info *si = &cli->sign_info; @@ -666,7 +666,7 @@ BOOL client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) Is client signing on ? ************************************************************/ -BOOL client_is_signing_on(struct cli_state *cli) +bool client_is_signing_on(struct cli_state *cli) { struct smb_sign_info *si = &cli->sign_info; return si->doing_signing; @@ -718,11 +718,11 @@ static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) SMB signing - Server implementation - check a MAC sent by server. ************************************************************/ -static BOOL srv_check_incoming_message(const char *inbuf, +static bool srv_check_incoming_message(const char *inbuf, struct smb_sign_info *si, - BOOL must_be_ok) + bool must_be_ok) { - BOOL good; + bool good; struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; uint32 reply_seq_number = data->send_seq_num; @@ -801,9 +801,9 @@ static struct smb_sign_info srv_sign_info = { Turn signing off or on for oplock break code. ************************************************************/ -BOOL srv_oplock_set_signing(BOOL onoff) +bool srv_oplock_set_signing(bool onoff) { - BOOL ret = srv_sign_info.doing_signing; + bool ret = srv_sign_info.doing_signing; srv_sign_info.doing_signing = onoff; return ret; } @@ -812,7 +812,7 @@ BOOL srv_oplock_set_signing(BOOL onoff) Called to validate an incoming packet from the client. ************************************************************/ -BOOL srv_check_sign_mac(const char *inbuf, BOOL must_be_ok) +bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) { /* Check if it's a session keepalive. */ if(CVAL(inbuf,0) == SMBkeepalive) { @@ -908,7 +908,7 @@ void srv_set_signing_negotiated(void) reads/writes if it is. ************************************************************/ -BOOL srv_is_signing_active(void) +bool srv_is_signing_active(void) { return srv_sign_info.doing_signing; } @@ -919,7 +919,7 @@ BOOL srv_is_signing_active(void) in the negprot. ************************************************************/ -BOOL srv_is_signing_negotiated(void) +bool srv_is_signing_negotiated(void) { return srv_sign_info.negotiated_smb_signing; } @@ -928,7 +928,7 @@ BOOL srv_is_signing_negotiated(void) Returns whether signing is actually happening ************************************************************/ -BOOL srv_signing_started(void) +bool srv_signing_started(void) { struct smb_basic_signing_context *data; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index f536383f4e..20eddff722 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -49,9 +49,9 @@ void SMBencrypt_hash(const uchar lm_hash[16], const uchar *c8, uchar p24[24]) Returns False if password must have been truncated to create LM hash */ -BOOL SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) +bool SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24]) { - BOOL ret; + bool ret; uchar lm_hash[16]; ret = E_deshash(passwd, lm_hash); @@ -107,9 +107,9 @@ void E_md5hash(const uchar salt[16], const uchar nthash[16], uchar hash_out[16]) * @note p16 is filled in regardless */ -BOOL E_deshash(const char *passwd, uchar p16[16]) +bool E_deshash(const char *passwd, uchar p16[16]) { - BOOL ret = True; + bool ret = True; fstring dospwd; ZERO_STRUCT(dospwd); @@ -159,9 +159,9 @@ void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar p16[16]) } /* Does both the NTLMv2 owfs of a user's password */ -BOOL ntv2_owf_gen(const uchar owf[16], +bool ntv2_owf_gen(const uchar owf[16], const char *user_in, const char *domain_in, - BOOL upper_case_domain, /* Transform the domain into UPPER case */ + bool upper_case_domain, /* Transform the domain into UPPER case */ uchar kr_buf[16]) { smb_ucs2_t *user; @@ -431,7 +431,7 @@ static DATA_BLOB LMv2_generate_response(const uchar ntlm_v2_hash[16], return final_response; } -BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_hash[16], +bool SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_hash[16], const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, @@ -470,7 +470,7 @@ BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_ /* Plaintext version of the above. */ -BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, +bool SMBNTLMv2encrypt(const char *user, const char *domain, const char *password, const DATA_BLOB *server_chal, const DATA_BLOB *names_blob, DATA_BLOB *lm_response, DATA_BLOB *nt_response, @@ -490,7 +490,7 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password encode a password buffer with a unicode password. The buffer is filled with random data to make it harder to attack. ************************************************************/ -BOOL encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags) +bool encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags) { uchar new_pw[512]; size_t new_pw_len; @@ -522,7 +522,7 @@ BOOL encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags) returned password including termination. ************************************************************/ -BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, +bool decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, int new_pwrd_size, uint32 *new_pw_len, int string_flags) { diff --git a/source3/libsmb/spnego.c b/source3/libsmb/spnego.c index d69d25c0db..57b2d8060b 100644 --- a/source3/libsmb/spnego.c +++ b/source3/libsmb/spnego.c @@ -25,7 +25,7 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_AUTH -static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) +static bool read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) { ZERO_STRUCTP(token); @@ -106,7 +106,7 @@ static BOOL read_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) return !asn1->has_error; } -static BOOL write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) +static bool write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) { asn1_push_tag(asn1, ASN1_CONTEXT(0)); asn1_push_tag(asn1, ASN1_SEQUENCE(0)); @@ -169,7 +169,7 @@ static BOOL write_negTokenInit(ASN1_DATA *asn1, negTokenInit_t *token) return !asn1->has_error; } -static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) +static bool read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) { ZERO_STRUCTP(token); @@ -212,7 +212,7 @@ static BOOL read_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) return !asn1->has_error; } -static BOOL write_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) +static bool write_negTokenTarg(ASN1_DATA *asn1, negTokenTarg_t *token) { asn1_push_tag(asn1, ASN1_CONTEXT(1)); asn1_push_tag(asn1, ASN1_SEQUENCE(0)); @@ -311,9 +311,9 @@ ssize_t write_spnego_data(DATA_BLOB *blob, SPNEGO_DATA *spnego) return ret; } -BOOL free_spnego_data(SPNEGO_DATA *spnego) +bool free_spnego_data(SPNEGO_DATA *spnego) { - BOOL ret = True; + bool ret = True; if (!spnego) goto out; diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 37ad85ce0c..f350cd0bc8 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -47,7 +47,7 @@ * false if cache init failed **/ -BOOL trustdom_cache_enable(void) +bool trustdom_cache_enable(void) { /* Init trustdom cache by calling gencache initialisation */ if (!gencache_init()) { @@ -67,7 +67,7 @@ BOOL trustdom_cache_enable(void) * false if it failed **/ -BOOL trustdom_cache_shutdown(void) +bool trustdom_cache_shutdown(void) { /* Close trustdom cache by calling gencache shutdown */ if (!gencache_shutdown()) { @@ -108,12 +108,12 @@ static char* trustdom_cache_key(const char* name) * false if store attempt failed **/ -BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, +bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, time_t timeout) { char *key, *alt_key; fstring sid_string; - BOOL ret; + bool ret; /* * we use gecache call to avoid annoying debug messages @@ -161,7 +161,7 @@ BOOL trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, * false if has expired/doesn't exist **/ -BOOL trustdom_cache_fetch(const char* name, DOM_SID* sid) +bool trustdom_cache_fetch(const char* name, DOM_SID* sid) { char *key = NULL, *value = NULL; time_t timeout; @@ -230,7 +230,7 @@ uint32 trustdom_cache_fetch_timestamp( void ) store the timestamp from the last update *******************************************************************/ -BOOL trustdom_cache_store_timestamp( uint32 t, time_t timeout ) +bool trustdom_cache_store_timestamp( uint32 t, time_t timeout ) { fstring value; diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 0922f9f41e..e82d24426d 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -140,7 +140,7 @@ NTSTATUS trust_pw_find_change_and_store_it(struct rpc_pipe_client *cli, Enumerate the list of trusted domains from a DC *********************************************************************/ -BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, +bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, char ***domain_names, uint32 *num_domains, DOM_SID **sids ) { @@ -151,7 +151,7 @@ BOOL enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, uint32 enum_ctx = 0; struct cli_state *cli = NULL; struct rpc_pipe_client *lsa_pipe; - BOOL retry; + bool retry; *domain_names = NULL; *num_domains = 0; -- cgit From 13bf4c4bb7a0c2fa1495bacdc81c91ee70588ce6 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Fri, 19 Oct 2007 14:36:34 -0500 Subject: Fix a crash in resolve_hosts() caused by an out-of-bounds array reference. (This used to be commit fd28d09a95b31bdbc6babd13c5a4ed9fc9ef4bfd) --- source3/libsmb/namequery.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 12e0d01b3b..6585fd751c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1074,7 +1074,6 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, &((struct sockaddr_in *)res->ai_addr)->sin_addr); *return_count += 1; - i++; *return_iplist = SMB_REALLOC_ARRAY(*return_iplist, struct ip_service, @@ -1086,6 +1085,8 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, } (*return_iplist)[i].ip = return_ip; (*return_iplist)[i].port = PORT_NONE; + + i++; } if (ailist) { freeaddrinfo(ailist); -- cgit From f88b7a076be74a29a3bf876b4e2705f4a1ecf42b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 24 Oct 2007 14:16:54 -0700 Subject: This is a large patch (sorry). Migrate from struct in_addr to struct sockaddr_storage in most places that matter (ie. not the nmbd and NetBIOS lookups). This passes make test on an IPv4 box, but I'll have to do more work/testing on IPv6 enabled boxes. This should now give us a framework for testing and finishing the IPv6 migration. It's at the state where someone with a working IPv6 setup should (theorecically) be able to type : smbclient //ipv6-address/share and have it work. Jeremy. (This used to be commit 98e154c3125d5732c37a72d74b0eb5cd7b6155fd) --- source3/libsmb/cliconnect.c | 152 +++--- source3/libsmb/clidfs.c | 20 +- source3/libsmb/clidgram.c | 27 +- source3/libsmb/clikrb5.c | 4 +- source3/libsmb/libsmbclient.c | 106 ++-- source3/libsmb/namecache.c | 156 +++--- source3/libsmb/namequery.c | 1126 +++++++++++++++++++++++++---------------- source3/libsmb/namequery_dc.c | 75 +-- source3/libsmb/nmblib.c | 15 +- source3/libsmb/passchange.c | 6 +- source3/libsmb/trusts_util.c | 6 +- 11 files changed, 999 insertions(+), 694 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 82cd6d6d13..826315ad7a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1366,11 +1366,17 @@ bool cli_session_request(struct cli_state *cli, int16 port; }; */ - int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); + uint16_t port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9); + struct in_addr dest_ip; + /* SESSION RETARGET */ - putip((char *)&cli->dest_ip,cli->inbuf+4); + putip((char *)&dest_ip,cli->inbuf+4); + in_addr_to_sockaddr_storage(&cli->dest_ss, dest_ip); - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT); + cli->fd = open_socket_out(SOCK_STREAM, + &cli->dest_ss, + port, + LONG_CONNECT_TIMEOUT); if (cli->fd == -1) return False; @@ -1405,49 +1411,61 @@ bool cli_session_request(struct cli_state *cli, Open the client sockets. ****************************************************************************/ -NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip) +NTSTATUS cli_connect(struct cli_state *cli, + const char *host, + struct sockaddr_storage *dest_ss) + { int name_type = 0x20; char *p; /* reasonable default hostname */ - if (!host) host = "*SMBSERVER"; + if (!host) { + host = "*SMBSERVER"; + } fstrcpy(cli->desthost, host); /* allow hostnames of the form NAME#xx and do a netbios lookup */ if ((p = strchr(cli->desthost, '#'))) { - name_type = strtol(p+1, NULL, 16); + name_type = strtol(p+1, NULL, 16); *p = 0; } - - if (!ip || is_zero_ip_v4(*ip)) { - if (!resolve_name(cli->desthost, &cli->dest_ip, name_type)) { + + if (!dest_ss || is_zero_addr(dest_ss)) { + if (!resolve_name(cli->desthost, &cli->dest_ss, name_type)) { return NT_STATUS_BAD_NETWORK_NAME; } - if (ip) *ip = cli->dest_ip; + if (dest_ss) { + *dest_ss = cli->dest_ss; + } } else { - cli->dest_ip = *ip; + cli->dest_ss = *dest_ss; } if (getenv("LIBSMB_PROG")) { cli->fd = sock_exec(getenv("LIBSMB_PROG")); } else { /* try 445 first, then 139 */ - int port = cli->port?cli->port:445; - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + uint16_t port = cli->port?cli->port:445; + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss, port, cli->timeout); if (cli->fd == -1 && cli->port == 0) { port = 139; - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss, port, cli->timeout); } - if (cli->fd != -1) + if (cli->fd != -1) { cli->port = port; + } } if (cli->fd == -1) { + char addr[INET6_ADDRSTRLEN]; + if (dest_ss) { + print_sockaddr(addr, sizeof(addr), dest_ss); + } DEBUG(1,("Error connecting to %s (%s)\n", - ip?inet_ntoa(*ip):host,strerror(errno))); + dest_ss?addr:host,strerror(errno))); return map_nt_error_from_unix(errno); } @@ -1460,7 +1478,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip establishes a connection to after the negprot. @param output_cli A fully initialised cli structure, non-null only on success @param dest_host The netbios name of the remote host - @param dest_ip (optional) The the destination IP, NULL for name based lookup + @param dest_ss (optional) The the destination IP, NULL for name based lookup @param port (optional) The destination port (0 for default) @param retry bool. Did this connection fail with a retryable error ? @@ -1468,7 +1486,7 @@ NTSTATUS cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip NTSTATUS cli_start_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, - struct in_addr *dest_ip, int port, + struct sockaddr_storage *dest_ss, int port, int signing_state, int flags, bool *retry) { @@ -1476,7 +1494,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, struct nmb_name calling; struct nmb_name called; struct cli_state *cli; - struct in_addr ip; + struct sockaddr_storage ss; if (retry) *retry = False; @@ -1498,19 +1516,22 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, cli_set_timeout(cli, 10000); /* 10 seconds. */ - if (dest_ip) - ip = *dest_ip; - else - ZERO_STRUCT(ip); + if (dest_ss) { + ss = *dest_ss; + } else { + zero_addr(&ss, AF_INET); + } again: DEBUG(3,("Connecting to host=%s\n", dest_host)); - - nt_status = cli_connect(cli, dest_host, &ip); + + nt_status = cli_connect(cli, dest_host, &ss); if (!NT_STATUS_IS_OK(nt_status)) { + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), &ss); DEBUG(1,("cli_start_connection: failed to connect to %s (%s). Error %s\n", - nmb_namestr(&called), inet_ntoa(ip), nt_errstr(nt_status) )); + nmb_namestr(&called), addr, nt_errstr(nt_status) )); cli_shutdown(cli); return nt_status; } @@ -1520,9 +1541,9 @@ again: if (!cli_session_request(cli, &calling, &called)) { char *p; - DEBUG(1,("session request to %s failed (%s)\n", + DEBUG(1,("session request to %s failed (%s)\n", called.name, cli_errstr(cli))); - if ((p=strchr(called.name, '.')) && !is_ipaddress_v4(called.name)) { + if ((p=strchr(called.name, '.')) && !is_ipaddress(called.name)) { *p = 0; goto again; } @@ -1572,7 +1593,7 @@ again: NTSTATUS cli_full_connection(struct cli_state **output_cli, const char *my_name, const char *dest_host, - struct in_addr *dest_ip, int port, + struct sockaddr_storage *dest_ss, int port, const char *service, const char *service_type, const char *user, const char *domain, const char *password, int flags, @@ -1589,9 +1610,10 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, password = ""; } - nt_status = cli_start_connection(&cli, my_name, dest_host, - dest_ip, port, signing_state, flags, retry); - + nt_status = cli_start_connection(&cli, my_name, dest_host, + dest_ss, port, signing_state, + flags, retry); + if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; } @@ -1615,7 +1637,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, return nt_status; } } - + if (service) { if (!cli_send_tconX(cli, service, service_type, password, pw_len)) { nt_status = cli_nt_error(cli); @@ -1639,7 +1661,7 @@ NTSTATUS cli_full_connection(struct cli_state **output_cli, ****************************************************************************/ bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srchost, const char *desthost, - struct in_addr *pdest_ip) + struct sockaddr_storage *pdest_ss) { struct nmb_name calling, called; @@ -1650,7 +1672,7 @@ bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho * then use *SMBSERVER immediately. */ - if(is_ipaddress_v4(desthost)) { + if(is_ipaddress(desthost)) { make_nmb_name(&called, "*SMBSERVER", 0x20); } else { make_nmb_name(&called, desthost, 0x20); @@ -1687,7 +1709,7 @@ with error %s.\n", desthost, cli_errstr(*ppcli) )); return False; } - status = cli_connect(*ppcli, desthost, pdest_ip); + status = cli_connect(*ppcli, desthost, pdest_ss); if (!NT_STATUS_IS_OK(status) || !cli_session_request(*ppcli, &calling, &smbservername)) { DEBUG(0,("attempt_netbios_session_request: %s rejected the session for \ @@ -1699,10 +1721,6 @@ name *SMBSERVER with error %s\n", desthost, cli_errstr(*ppcli) )); return True; } - - - - /**************************************************************************** Send an old style tcon. ****************************************************************************/ @@ -1749,27 +1767,28 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, /* Return a cli_state pointing at the IPC$ share for the given server */ -struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, - struct user_auth_info *user_info) +struct cli_state *get_ipc_connect(char *server, + struct sockaddr_storage *server_ss, + struct user_auth_info *user_info) { struct cli_state *cli; pstring myname; NTSTATUS nt_status; get_myname(myname); - - nt_status = cli_full_connection(&cli, myname, server, server_ip, 0, "IPC$", "IPC", + + nt_status = cli_full_connection(&cli, myname, server, server_ss, 0, "IPC$", "IPC", user_info->username, lp_workgroup(), user_info->password, CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return cli; - } else if (is_ipaddress_v4(server)) { + } else if (is_ipaddress(server)) { /* windows 9* needs a correct NMB name for connections */ fstring remote_name; - if (name_status_find("*", 0, 0, *server_ip, remote_name)) { - cli = get_ipc_connect(remote_name, server_ip, user_info); + if (name_status_find("*", 0, 0, server_ss, remote_name)) { + cli = get_ipc_connect(remote_name, server_ss, user_info); if (cli) return cli; } @@ -1789,14 +1808,16 @@ struct cli_state *get_ipc_connect(char *server, struct in_addr *server_ip, * entire network browse list) */ -struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring workgroup, struct user_auth_info *user_info) +struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring workgroup, struct user_auth_info *user_info) { + char addr[INET6_ADDRSTRLEN]; static fstring name; struct cli_state *cli; - struct in_addr server_ip; + struct sockaddr_storage server_ss; + print_sockaddr(addr, sizeof(addr), &mb_ip->ss); DEBUG(99, ("Looking up name of master browser %s\n", - inet_ntoa(mb_ip->ip))); + addr)); /* * Do a name status query to find out the name of the master browser. @@ -1809,28 +1830,27 @@ struct cli_state *get_ipc_connect_master_ip(struct ip_service * mb_ip, pstring w * the original wildcard query as the first choice and fall back to * MSBROWSE if the wildcard query fails. */ - if (!name_status_find("*", 0, 0x1d, mb_ip->ip, name) && - !name_status_find(MSBROWSE, 1, 0x1d, mb_ip->ip, name)) { + if (!name_status_find("*", 0, 0x1d, &mb_ip->ss, name) && + !name_status_find(MSBROWSE, 1, 0x1d, &mb_ip->ss, name)) { DEBUG(99, ("Could not retrieve name status for %s\n", - inet_ntoa(mb_ip->ip))); + addr)); return NULL; } - if (!find_master_ip(name, &server_ip)) { + if (!find_master_ip(name, &server_ss)) { DEBUG(99, ("Could not find master ip for %s\n", name)); return NULL; } - pstrcpy(workgroup, name); + pstrcpy(workgroup, name); - DEBUG(4, ("found master browser %s, %s\n", - name, inet_ntoa(mb_ip->ip))); + DEBUG(4, ("found master browser %s, %s\n", name, addr)); - cli = get_ipc_connect(inet_ntoa(server_ip), &server_ip, user_info); + print_sockaddr(addr, sizeof(addr), &server_ss); + cli = get_ipc_connect(addr, &server_ss, user_info); - return cli; - + return cli; } /* @@ -1846,7 +1866,7 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user DEBUG(99, ("Do broadcast lookup for workgroups on local network\n")); - /* Go looking for workgroups by broadcasting on the local network */ + /* Go looking for workgroups by broadcasting on the local network */ if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, &count))) { @@ -1855,11 +1875,13 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user } for (i = 0; i < count; i++) { - DEBUG(99, ("Found master browser %s\n", inet_ntoa(ip_list[i].ip))); + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); + DEBUG(99, ("Found master browser %s\n", addr)); - cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info); - if (cli) - return(cli); + cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info); + if (cli) + return(cli); } return NULL; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index f7bf8506fe..e1ca924b09 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -50,7 +50,7 @@ int max_protocol = PROTOCOL_NT1; static int port; static int name_type = 0x20; static bool have_ip; -static struct in_addr dest_ip; +static struct sockaddr_storage dest_ss; static struct client_connection *connections; @@ -64,7 +64,7 @@ static struct cli_state *do_connect( const char *server, const char *share, struct cli_state *c = NULL; struct nmb_name called, calling; const char *server_n; - struct in_addr ip; + struct sockaddr_storage ss; pstring servicename; char *sharename; fstring newserver, newshare; @@ -83,22 +83,22 @@ static struct cli_state *do_connect( const char *server, const char *share, server_n = server; - zero_ip_v4(&ip); + zero_addr(&ss, AF_INET); make_nmb_name(&calling, global_myname(), 0x0); make_nmb_name(&called , server, name_type); again: - zero_ip_v4(&ip); - if (have_ip) - ip = dest_ip; + zero_addr(&ss, AF_INET); + if (have_ip) + ss = dest_ss; /* have to open a new connection */ if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) { d_printf("Connection to %s failed\n", server_n); return NULL; } - status = cli_connect(c, server_n, &ip); + status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { d_printf("Connection to %s failed (Error %s)\n", server_n, nt_errstr(status)); return NULL; @@ -366,10 +366,10 @@ void cli_cm_set_dest_name_type( int type ) /**************************************************************************** ****************************************************************************/ -void cli_cm_set_dest_ip(struct in_addr ip ) +void cli_cm_set_dest_ss(struct sockaddr_storage *pss) { - dest_ip = ip; - have_ip = True; + dest_ss = *pss; + have_ip = true; } /********************************************************************** diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 4fc9243b5b..9f6f4480c5 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -29,21 +29,27 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, bool unique, const char *mailslot, uint16 priority, char *buf, int len, - const char *srcname, int src_type, + const char *srcname, int src_type, const char *dstname, int dest_type, - struct in_addr dest_ip) + const struct sockaddr_storage *dest_ss) { struct packet_struct p; struct dgram_packet *dgram = &p.packet.dgram; char *ptr, *p2; char tmp[4]; pid_t nmbd_pid; + char addr[INET6_ADDRSTRLEN]; if ((nmbd_pid = pidfile_pid("nmbd")) == 0) { DEBUG(3, ("No nmbd found\n")); return False; } + if (dest_ss->ss_family != AF_INET) { + DEBUG(3, ("cli_send_mailslot: can't send to IPv6 address.\n")); + return false; + } + memset((char *)&p, '\0', sizeof(p)); /* @@ -51,7 +57,7 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, */ /* DIRECT GROUP or UNIQUE datagram. */ - dgram->header.msg_type = unique ? 0x10 : 0x11; + dgram->header.msg_type = unique ? 0x10 : 0x11; dgram->header.flags.node_type = M_NODE; dgram->header.flags.first = True; dgram->header.flags.more = False; @@ -60,7 +66,7 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, /* source ip is filled by nmbd */ dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */ dgram->header.packet_offset = 0; - + make_nmb_name(&dgram->source_name,srcname,src_type); make_nmb_name(&dgram->dest_name,dstname,dest_type); @@ -93,13 +99,14 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ p.packet_type = DGRAM_PACKET; - p.ip = dest_ip; + p.ip = ((const struct sockaddr_in *)&dest_ss)->sin_addr; p.timestamp = time(NULL); DEBUG(4,("send_mailslot: Sending to mailslot %s from %s ", mailslot, nmb_namestr(&dgram->source_name))); - DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), - inet_ntoa(dest_ip))); + print_sockaddr(addr, sizeof(addr), dest_ss); + + DEBUGADD(4,("to %s IP %s\n", nmb_namestr(&dgram->dest_name), addr)); return NT_STATUS_IS_OK(messaging_send_buf(msg_ctx, pid_to_procid(nmbd_pid), @@ -136,9 +143,9 @@ int cli_get_backup_list(struct messaging_context *msg_ctx, { pstring outbuf; char *p; - struct in_addr sendto_ip; + struct sockaddr_storage sendto_ss; - if (!resolve_name(send_to_name, &sendto_ip, 0x1d)) { + if (!resolve_name(send_to_name, &sendto_ss, 0x1d)) { DEBUG(0, ("Could not resolve name: %s<1D>\n", send_to_name)); return False; @@ -161,7 +168,7 @@ int cli_get_backup_list(struct messaging_context *msg_ctx, cli_send_mailslot(msg_ctx, True, "\\MAILSLOT\\BROWSE", 1, outbuf, PTR_DIFF(p, outbuf), myname, 0, send_to_name, - 0x1d, sendto_ip); + 0x1d, &sendto_ss); /* We should check the error and return if we got one */ diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 4291834797..fb25e9e203 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -162,7 +162,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* HEIMDAL */ - void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) + void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr) { pkaddr->addr_type = KRB5_ADDRESS_INET; pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); @@ -170,7 +170,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, } #elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ - void setup_kaddr( krb5_address *pkaddr, struct sockaddr *paddr) + void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr) { pkaddr->addrtype = ADDRTYPE_INET; pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3b5818a015..d5bf1828c6 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -626,7 +626,7 @@ find_server(SMBCCTX *context, * Connect to a server, possibly on an existing connection * * Here, what we want to do is: If the server and username - * match an existing connection, reuse that, otherwise, establish a + * match an existing connection, reuse that, otherwise, establish a * new connection. * * If we have to create a new connection, call the auth_fn to get the @@ -637,9 +637,9 @@ static SMBCSRV * smbc_server(SMBCCTX *context, bool connect_if_not_found, const char *server, - const char *share, + const char *share, fstring workgroup, - fstring username, + fstring username, fstring password) { SMBCSRV *srv=NULL; @@ -647,14 +647,14 @@ smbc_server(SMBCCTX *context, struct nmb_name called, calling; const char *server_n = server; pstring ipenv; - struct in_addr ip; + struct sockaddr_storage ss; int tried_reverse = 0; int port_try_first; int port_try_next; const char *username_used; NTSTATUS status; - zero_ip_v4(&ip); + zero_addr(&ss, AF_INET); ZERO_STRUCT(c); if (server[0] == 0) { @@ -665,7 +665,7 @@ smbc_server(SMBCCTX *context, /* Look for a cached connection */ srv = find_server(context, server, share, workgroup, username, password); - + /* * If we found a connection and we're only allowed one share per * server... @@ -699,7 +699,7 @@ smbc_server(SMBCCTX *context, if (! cli_send_tconX(srv->cli, share, "?????", password, strlen(password)+1)) { - + errno = smbc_errno(context, srv->cli); cli_shutdown(srv->cli); srv->cli = NULL; @@ -718,7 +718,7 @@ smbc_server(SMBCCTX *context, } } } - + /* If we have a connection... */ if (srv) { @@ -736,13 +736,13 @@ smbc_server(SMBCCTX *context, make_nmb_name(&called , server, 0x20); DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - + DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); - zero_ip_v4(&ip); + zero_addr(&ss, AF_INET); /* have to open a new connection */ if ((c = cli_initialise()) == NULL) { @@ -773,13 +773,13 @@ smbc_server(SMBCCTX *context, c->port = port_try_first; - status = cli_connect(c, server_n, &ip); + status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { /* First connection attempt failed. Try alternate port. */ c->port = port_try_next; - status = cli_connect(c, server_n, &ip); + status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { cli_shutdown(c); errno = ETIMEDOUT; @@ -796,20 +796,22 @@ smbc_server(SMBCCTX *context, /* Only try this if server is an IP address ... */ - if (is_ipaddress_v4(server) && !tried_reverse) { + if (is_ipaddress(server) && !tried_reverse) { fstring remote_name; - struct in_addr rem_ip; + struct sockaddr_storage rem_ss; - if ((rem_ip.s_addr=inet_addr(server)) == INADDR_NONE) { + if (!interpret_string_addr(&rem_ss, server, + NI_NUMERICHOST)) { DEBUG(4, ("Could not convert IP address " - "%s to struct in_addr\n", server)); + "%s to struct sockaddr_storage\n", + server)); errno = ETIMEDOUT; return NULL; } tried_reverse++; /* Yuck */ - if (name_status_find("*", 0, 0, rem_ip, remote_name)) { + if (name_status_find("*", 0, 0, &rem_ss, remote_name)) { make_nmb_name(&called, remote_name, 0x20); goto again; } @@ -818,9 +820,9 @@ smbc_server(SMBCCTX *context, errno = ETIMEDOUT; return NULL; } - + DEBUG(4,(" session request ok\n")); - + if (!cli_negprot(c)) { cli_shutdown(c); errno = ETIMEDOUT; @@ -829,11 +831,11 @@ smbc_server(SMBCCTX *context, username_used = username; - if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, + if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, password, strlen(password), password, strlen(password), workgroup))) { - + /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; @@ -857,9 +859,9 @@ smbc_server(SMBCCTX *context, cli_shutdown(c); return NULL; } - + DEBUG(4,(" tconx ok\n")); - + /* * Ok, we have got a nice connection * Let's allocate a server structure. @@ -892,8 +894,8 @@ smbc_server(SMBCCTX *context, } goto failed; } - - DEBUG(2, ("Server connect ok: //%s/%s: %p\n", + + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", server, share, srv)); DLIST_ADD(context->internal->_servers, srv); @@ -904,7 +906,7 @@ smbc_server(SMBCCTX *context, if (!srv) { return NULL; } - + SAFE_FREE(srv); return NULL; } @@ -916,14 +918,14 @@ smbc_server(SMBCCTX *context, static SMBCSRV * smbc_attr_server(SMBCCTX *context, const char *server, - const char *share, + const char *share, fstring workgroup, fstring username, fstring password, POLICY_HND *pol) { int flags; - struct in_addr ip; + struct sockaddr_storage ss; struct cli_state *ipc_cli; struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; @@ -956,16 +958,16 @@ smbc_attr_server(SMBCCTX *context, password, sizeof(fstring)); } } - + flags = 0; if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } - zero_ip_v4(&ip); + zero_addr(&ss, AF_INET); nt_status = cli_full_connection(&ipc_cli, - global_myname(), server, - &ip, 0, "IPC$", "?????", + global_myname(), server, + &ss, 0, "IPC$", "?????", username, workgroup, password, flags, Undefined, NULL); @@ -2557,7 +2559,7 @@ smbc_opendir_ctx(SMBCCTX *context, SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; struct _smbc_callbacks *cb; - struct in_addr rem_ip; + struct sockaddr_storage rem_ss; if (!context || !context->internal || !context->internal->_initialized) { @@ -2602,10 +2604,8 @@ smbc_opendir_ctx(SMBCCTX *context, dir = SMB_MALLOC_P(SMBCFILE); if (!dir) { - errno = ENOMEM; return NULL; - } ZERO_STRUCTP(dir); @@ -2661,7 +2661,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(ip_list); - if (!find_master_ip(workgroup, &server_addr.ip)) { + if (!find_master_ip(workgroup, &server_addr.ss)) { if (dir) { SAFE_FREE(dir->fname); @@ -2676,13 +2676,15 @@ smbc_opendir_ctx(SMBCCTX *context, } for (i = 0; i < count && i < max_lmb_count; i++) { + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), - inet_ntoa(ip_list[i].ip))); - + addr)); + cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, &u_info); - /* cli == NULL is the master browser refused to talk or + /* cli == NULL is the master browser refused to talk or could not be found */ if ( !cli ) continue; @@ -2699,18 +2701,18 @@ smbc_opendir_ctx(SMBCCTX *context, * already have one, and determine the * workgroups/domains that it knows about. */ - + srv = smbc_server(context, True, server, "IPC$", workgroup, user, password); if (!srv) { continue; } - + dir->srv = srv; dir->dir_type = SMBC_WORKGROUP; /* Now, list the stuff ... */ - + if (!cli_NetServerEnum(srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, @@ -2721,7 +2723,7 @@ smbc_opendir_ctx(SMBCCTX *context, } SAFE_FREE(ip_list); - } else { + } else { /* * Server not an empty string ... Check the rest and see what * gives @@ -2761,9 +2763,9 @@ smbc_opendir_ctx(SMBCCTX *context, * LMB or DMB */ if (!srv && - !is_ipaddress_v4(server) && - (resolve_name(server, &rem_ip, 0x1d) || /* LMB */ - resolve_name(server, &rem_ip, 0x1b) )) { /* DMB */ + !is_ipaddress(server) && + (resolve_name(server, &rem_ss, 0x1d) || /* LMB */ + resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */ fstring buserver; @@ -2773,7 +2775,7 @@ smbc_opendir_ctx(SMBCCTX *context, * Get the backup list ... */ if (!name_status_find(server, 0, 0, - rem_ip, buserver)) { + &rem_ss, buserver)) { DEBUG(0, ("Could not get name of " "local/domain master browser " @@ -2818,8 +2820,8 @@ smbc_opendir_ctx(SMBCCTX *context, return NULL; } } else if (srv || - (resolve_name(server, &rem_ip, 0x20))) { - + (resolve_name(server, &rem_ss, 0x20))) { + /* If we hadn't found the server, get one now */ if (!srv) { srv = smbc_server(context, True, @@ -2848,9 +2850,9 @@ smbc_opendir_ctx(SMBCCTX *context, (void *) dir) < 0 && cli_RNetShareEnum( srv->cli, - list_fn, + list_fn, (void *)dir) < 0) { - + errno = cli_errno(srv->cli); if (dir) { SAFE_FREE(dir->fname); @@ -2861,7 +2863,7 @@ smbc_opendir_ctx(SMBCCTX *context, } } else { /* Neither the workgroup nor server exists */ - errno = ECONNREFUSED; + errno = ECONNREFUSED; if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index b569100d94..6a675d2ef2 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -1,21 +1,22 @@ -/* +/* Unix SMB/CIFS implementation. NetBIOS name cache module on top of gencache mechanism. - + Copyright (C) Tim Potter 2002 Copyright (C) Rafal Szczesniak 2002 - + Copyright (C) Jeremy Allison 2007 + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -24,11 +25,10 @@ #define NBTKEY_FMT "NBT/%s#%02X" - /** * Initialise namecache system. Function calls gencache * initialisation function to perform necessary actions - * + * * @return true upon successful initialisation of the cache or * false on failure **/ @@ -38,7 +38,7 @@ bool namecache_enable(void) /* * Check if name caching disabled by setting the name cache * timeout to zero. - */ + */ if (lp_name_cache_timeout() == 0) { DEBUG(5, ("namecache_enable: disabling netbios name cache\n")); @@ -48,18 +48,19 @@ bool namecache_enable(void) /* Init namecache by calling gencache initialisation */ if (!gencache_init()) { - DEBUG(2, ("namecache_enable: Couldn't initialise namecache on top of gencache.\n")); + DEBUG(2, ("namecache_enable: " + "Couldn't initialise namecache on top of gencache.\n")); return False; } - /* I leave it for now, though I don't think we really need this (mimir, 27.09.2002) */ + /* I leave it for now, though I don't think we really + * need this (mimir, 27.09.2002) */ DEBUG(5, ("namecache_enable: enabling netbios namecache, timeout %d " "seconds\n", lp_name_cache_timeout())); return True; } - /** * Shutdown namecache. Routine calls gencache close function * to safely close gencache file. @@ -67,19 +68,20 @@ bool namecache_enable(void) * @return true upon successful shutdown of the cache or * false on failure **/ - + bool namecache_shutdown(void) { if (!gencache_shutdown()) { - DEBUG(2, ("namecache_shutdown: Couldn't close namecache on top of gencache.\n")); + DEBUG(2, ("namecache_shutdown: " + "Couldn't close namecache on top of gencache.\n")); return False; } - - DEBUG(5, ("namecache_shutdown: netbios namecache closed successfully.\n")); + + DEBUG(5, ("namecache_shutdown: " + "netbios namecache closed successfully.\n")); return True; } - /** * Generates a key for netbios name lookups on basis of * netbios name and type. @@ -92,7 +94,8 @@ bool namecache_shutdown(void) * type number */ -static char* namecache_key(const char *name, int name_type) +static char* namecache_key(const char *name, + int name_type) { char *keystr; asprintf(&keystr, NBTKEY_FMT, strupper_static(name), name_type); @@ -100,7 +103,6 @@ static char* namecache_key(const char *name, int name_type) return keystr; } - /** * Store a name(s) in the name cache * @@ -111,8 +113,10 @@ static char* namecache_key(const char *name, int name_type) * ip addresses being stored **/ -bool namecache_store(const char *name, int name_type, - int num_names, struct ip_service *ip_list) +bool namecache_store(const char *name, + int name_type, + int num_names, + struct ip_service *ip_list) { time_t expiry; char *key, *value_string; @@ -123,23 +127,35 @@ bool namecache_store(const char *name, int name_type, * we use gecache call to avoid annoying debug messages about * initialised namecache again and again... */ - if (!gencache_init()) return False; + if (!gencache_init()) { + return False; + } if (name_type > 255) { return False; /* Don't store non-real name types. */ } if ( DEBUGLEVEL >= 5 ) { + TALLOC_CTX *ctx = talloc_stackframe(); + char *addr = NULL; + DEBUG(5, ("namecache_store: storing %d address%s for %s#%02x: ", num_names, num_names == 1 ? "": "es", name, name_type)); - for (i = 0; i < num_names; i++) - DEBUGADD(5, ("%s:%d%s", inet_ntoa(ip_list[i].ip), - ip_list[i].port, (i == (num_names - 1) ? "" : ","))); - + for (i = 0; i < num_names; i++) { + addr = print_canonical_sockaddr(ctx, + &ip_list[i].ss); + if (!addr) { + continue; + } + DEBUGADD(5, ("%s%s", addr, + (i == (num_names - 1) ? "" : ","))); + + } DEBUGADD(5, ("\n")); + TALLOC_FREE(ctx); } - + key = namecache_key(name, name_type); if (!key) { return False; @@ -155,9 +171,9 @@ bool namecache_store(const char *name, int name_type, if (!ipstr_list_make(&value_string, ip_list, num_names)) { SAFE_FREE(key); SAFE_FREE(value_string); - return False; + return false; } - + /* set the entry */ ret = gencache_set(key, value_string, expiry); SAFE_FREE(key); @@ -165,7 +181,6 @@ bool namecache_store(const char *name, int name_type, return ret; } - /** * Look up a name in the cache. * @@ -179,17 +194,22 @@ bool namecache_store(const char *name, int name_type, * false if name isn't found in the cache or has expired **/ -bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_list, - int *num_names) +bool namecache_fetch(const char *name, + int name_type, + struct ip_service **ip_list, + int *num_names) { char *key, *value; time_t timeout; /* exit now if null pointers were passed as they're required further */ - if (!ip_list || !num_names) return False; + if (!ip_list || !num_names) { + return False; + } - if (!gencache_init()) + if (!gencache_init()) { return False; + } if (name_type > 255) { return False; /* Don't fetch non-real name types. */ @@ -197,7 +217,7 @@ bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis *num_names = 0; - /* + /* * Use gencache interface - lookup the key */ key = namecache_key(name, name_type); @@ -212,16 +232,16 @@ bool namecache_fetch(const char *name, int name_type, struct ip_service **ip_lis } else { DEBUG(5, ("name %s#%02X found.\n", name, name_type)); } - + /* * Split up the stored value into the list of IP adresses */ *num_names = ipstr_list_parse(value, ip_list); - + SAFE_FREE(key); SAFE_FREE(value); - - return *num_names > 0; /* true only if some ip has been fetched */ + + return *num_names > 0; /* true only if some ip has been fetched */ } /** @@ -256,27 +276,30 @@ bool namecache_delete(const char *name, int name_type) * **/ -static void flush_netbios_name(const char* key, const char *value, time_t timeout, void* dptr) +static void flush_netbios_name(const char *key, + const char *value, + time_t timeout, + void *dptr) { gencache_del(key); DEBUG(5, ("Deleting entry %s\n", key)); } - /** * Flush all names from the name cache. * It's done by gencache_iterate() * - * @return True upon successful deletion or - * False in case of an error + * @return true upon successful deletion or + * false in case of an error **/ void namecache_flush(void) { - if (!gencache_init()) + if (!gencache_init()) { return; + } - /* + /* * iterate through each NBT cache's entry and flush it * by flush_netbios_name function */ @@ -286,40 +309,49 @@ void namecache_flush(void) /* Construct a name status record key. */ -static char *namecache_status_record_key(const char *name, int name_type1, - int name_type2, struct in_addr keyip) +static char *namecache_status_record_key(const char *name, + int name_type1, + int name_type2, + const struct sockaddr_storage *keyip) { + char addr[INET6_ADDRSTRLEN]; char *keystr; + print_sockaddr(addr, sizeof(addr), keyip); asprintf(&keystr, "NBT/%s#%02X.%02X.%s", - strupper_static(name), name_type1, name_type2, inet_ntoa(keyip)); + strupper_static(name), name_type1, name_type2, addr); return keystr; } /* Store a name status record. */ bool namecache_status_store(const char *keyname, int keyname_type, - int name_type, struct in_addr keyip, + int name_type, const struct sockaddr_storage *keyip, const char *srvname) { char *key; time_t expiry; bool ret; - if (!gencache_init()) + if (!gencache_init()) { return False; + } - key = namecache_status_record_key(keyname, keyname_type, name_type, keyip); + key = namecache_status_record_key(keyname, keyname_type, + name_type, keyip); if (!key) return False; expiry = time(NULL) + lp_name_cache_timeout(); ret = gencache_set(key, srvname, expiry); - if (ret) - DEBUG(5, ("namecache_status_store: entry %s -> %s\n", key, srvname )); - else - DEBUG(5, ("namecache_status_store: entry %s store failed.\n", key )); + if (ret) { + DEBUG(5, ("namecache_status_store: entry %s -> %s\n", + key, srvname )); + } else { + DEBUG(5, ("namecache_status_store: entry %s store failed.\n", + key )); + } SAFE_FREE(key); return ret; @@ -327,8 +359,11 @@ bool namecache_status_store(const char *keyname, int keyname_type, /* Fetch a name status record. */ -bool namecache_status_fetch(const char *keyname, int keyname_type, - int name_type, struct in_addr keyip, char *srvname_out) +bool namecache_status_fetch(const char *keyname, + int keyname_type, + int name_type, + const struct sockaddr_storage *keyip, + char *srvname_out) { char *key = NULL; char *value = NULL; @@ -337,16 +372,19 @@ bool namecache_status_fetch(const char *keyname, int keyname_type, if (!gencache_init()) return False; - key = namecache_status_record_key(keyname, keyname_type, name_type, keyip); + key = namecache_status_record_key(keyname, keyname_type, + name_type, keyip); if (!key) return False; if (!gencache_get(key, &value, &timeout)) { - DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key)); + DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", + key)); SAFE_FREE(key); return False; } else { - DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", key, value )); + DEBUG(5, ("namecache_status_fetch: key %s -> %s\n", + key, value )); } strlcpy(srvname_out, value, 16); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 6585fd751c..34fe09b8c2 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1,20 +1,21 @@ -/* +/* Unix SMB/CIFS implementation. name query routines Copyright (C) Andrew Tridgell 1994-1998 - + Copyright (C) Jeremy Allison 2007. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License - along with this program. If not, see . + along with this program. If not, see . */ #include "includes.h" @@ -25,10 +26,10 @@ bool global_in_nmbd = False; /**************************** * SERVER AFFINITY ROUTINES * ****************************/ - - /* Server affinity is the concept of preferring the last domain + + /* Server affinity is the concept of preferring the last domain controller with whom you had a successful conversation */ - + /**************************************************************************** ****************************************************************************/ #define SAFKEY_FMT "SAF/DOMAIN/%s" @@ -37,7 +38,7 @@ bool global_in_nmbd = False; static char *saf_key(const char *domain) { char *keystr; - + asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) ); return keystr; @@ -51,31 +52,32 @@ bool saf_store( const char *domain, const char *servername ) char *key; time_t expire; bool ret = False; - + if ( !domain || !servername ) { - DEBUG(2,("saf_store: Refusing to store empty domain or servername!\n")); + DEBUG(2,("saf_store: " + "Refusing to store empty domain or servername!\n")); return False; } if ( (strlen(domain) == 0) || (strlen(servername) == 0) ) { - DEBUG(0,("saf_store: refusing to store 0 length domain or servername!\n")); + DEBUG(0,("saf_store: " + "refusing to store 0 length domain or servername!\n")); return False; } - - if ( !gencache_init() ) + + if ( !gencache_init() ) return False; - + key = saf_key( domain ); expire = time( NULL ) + SAF_TTL; - - + DEBUG(10,("saf_store: domain = [%s], server = [%s], expire = [%u]\n", domain, servername, (unsigned int)expire )); - + ret = gencache_set( key, servername, expire ); - + SAFE_FREE( key ); - + return ret; } @@ -83,20 +85,20 @@ bool saf_delete( const char *domain ) { char *key; bool ret = False; - + if ( !domain ) { - DEBUG(2,("saf_delete: Refusing to delete empty domain\n")); + DEBUG(2,("saf_delete: Refusing to delete empty domain\n")); return False; } - - if ( !gencache_init() ) + + if ( !gencache_init() ) return False; - + key = saf_key(domain); ret = gencache_del(key); - + if (ret) { - DEBUG(10,("saf_delete: domain = [%s]\n", domain )); + DEBUG(10,("saf_delete: domain = [%s]\n", domain )); } SAFE_FREE( key ); @@ -118,23 +120,24 @@ char *saf_fetch( const char *domain ) DEBUG(2,("saf_fetch: Empty domain name!\n")); return NULL; } - - if ( !gencache_init() ) + + if ( !gencache_init() ) return False; - + key = saf_key( domain ); - + ret = gencache_get( key, &server, &timeout ); - + SAFE_FREE( key ); - + if ( !ret ) { - DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", domain )); + DEBUG(5,("saf_fetch: failed to find server for \"%s\" domain\n", + domain )); } else { - DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n", + DEBUG(5,("saf_fetch: Returning \"%s\" for \"%s\" domain\n", server, domain )); } - + return server; } @@ -155,7 +158,9 @@ static int generate_trn_id(void) Parse a node status response into an array of structures. ****************************************************************************/ -static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct node_status_extra *extra) +static NODE_STATUS_STRUCT *parse_node_status(char *p, + int *num_names, + struct node_status_extra *extra) { NODE_STATUS_STRUCT *ret; int i; @@ -176,7 +181,7 @@ static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct nod ret[i].type = CVAL(p,15); ret[i].flags = p[16]; p += 18; - DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, + DEBUG(10, ("%s#%02x: flags = 0x%02x\n", ret[i].name, ret[i].type, ret[i].flags)); } /* @@ -194,9 +199,11 @@ static NODE_STATUS_STRUCT *parse_node_status(char *p, int *num_names, struct nod structures holding the returned names or NULL if the query failed. **************************************************************************/ -NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, - struct in_addr to_ip, int *num_names, - struct node_status_extra *extra) +NODE_STATUS_STRUCT *node_status_query(int fd, + struct nmb_name *name, + const struct sockaddr_storage *to_ss, + int *num_names, + struct node_status_extra *extra) { bool found=False; int retries = 2; @@ -209,14 +216,18 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, ZERO_STRUCT(p); + if (to_ss->ss_family != AF_INET) { + /* Can't do node status to IPv6 */ + return NULL; + } nmb->header.name_trn_id = generate_trn_id(); nmb->header.opcode = 0; - nmb->header.response = False; - nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = False; - nmb->header.nm_flags.recursion_desired = False; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; + nmb->header.response = false; + nmb->header.nm_flags.bcast = false; + nmb->header.nm_flags.recursion_available = false; + nmb->header.nm_flags.recursion_desired = false; + nmb->header.nm_flags.trunc = false; + nmb->header.nm_flags.authoritative = false; nmb->header.rcode = 0; nmb->header.qdcount = 1; nmb->header.ancount = 0; @@ -226,15 +237,15 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, nmb->question.question_type = 0x21; nmb->question.question_class = 0x1; - p.ip = to_ip; + p.ip = ((const struct sockaddr_in *)to_ss)->sin_addr; p.port = NMB_PORT; p.fd = fd; p.timestamp = time(NULL); p.packet_type = NMB_PACKET; - + GetTimeOfDay(&tval); - - if (!send_packet(&p)) + + if (!send_packet(&p)) return NULL; retries--; @@ -251,10 +262,10 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, retries--; } - if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); - + if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || nmb2->header.rcode || @@ -267,12 +278,13 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, continue; } - ret = parse_node_status(&nmb2->answers->rdata[0], num_names, extra); + ret = parse_node_status(&nmb2->answers->rdata[0], + num_names, extra); free_packet(p2); return ret; } } - + return NULL; } @@ -281,34 +293,54 @@ NODE_STATUS_STRUCT *node_status_query(int fd,struct nmb_name *name, a servers name given its IP. Return the matched name in *name. **************************************************************************/ -bool name_status_find(const char *q_name, int q_type, int type, struct in_addr to_ip, fstring name) +bool name_status_find(const char *q_name, + int q_type, + int type, + const struct sockaddr_storage *to_ss, + fstring name) { + char addr[INET6_ADDRSTRLEN]; + struct sockaddr_storage ss; NODE_STATUS_STRUCT *status = NULL; struct nmb_name nname; int count, i; int sock; - bool result = False; + bool result = false; if (lp_disable_netbios()) { - DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type)); + DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", + q_name, q_type)); return False; } - DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, - q_type, inet_ntoa(to_ip))); + print_sockaddr(addr, sizeof(addr), to_ss); + + DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name, + q_type, addr)); /* Check the cache first. */ - if (namecache_status_fetch(q_name, q_type, type, to_ip, name)) + if (namecache_status_fetch(q_name, q_type, type, to_ss, name)) { return True; + } + + if (to_ss->ss_family != AF_INET) { + /* Can't do node status to IPv6 */ + return false; + } + + if (!interpret_string_addr(&ss, lp_socket_address(), + AI_NUMERICHOST|AI_PASSIVE)) { + zero_addr(&ss, AF_INET); + } - sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True); + sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True); if (sock == -1) goto done; /* W2K PDC's seem not to respond to '*'#0. JRA */ make_nmb_name(&nname, q_name, q_type); - status = node_status_query(sock, &nname, to_ip, &count, NULL); + status = node_status_query(sock, &nname, to_ss, &count, NULL); close(sock); if (!status) goto done; @@ -323,13 +355,14 @@ bool name_status_find(const char *q_name, int q_type, int type, struct in_addr t pull_ascii_nstring(name, sizeof(fstring), status[i].name); /* Store the result in the cache. */ - /* but don't store an entry for 0x1c names here. Here we have + /* but don't store an entry for 0x1c names here. Here we have a single host and DOMAIN<0x1c> names should be a list of hosts */ - - if ( q_type != 0x1c ) - namecache_status_store(q_name, q_type, type, to_ip, name); - result = True; + if ( q_type != 0x1c ) { + namecache_status_store(q_name, q_type, type, to_ss, name); + } + + result = true; done: SAFE_FREE(status); @@ -337,49 +370,92 @@ bool name_status_find(const char *q_name, int q_type, int type, struct in_addr t DEBUG(10, ("name_status_find: name %sfound", result ? "" : "not ")); if (result) - DEBUGADD(10, (", name %s ip address is %s", name, inet_ntoa(to_ip))); + DEBUGADD(10, (", name %s ip address is %s", name, addr)); - DEBUG(10, ("\n")); + DEBUG(10, ("\n")); return result; } /* - comparison function used by sort_ip_list + comparison function used by sort_addr_list */ -static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) +static int addr_compare(const struct sockaddr_storage *ss1, + const struct sockaddr_storage *ss2) { int max_bits1=0, max_bits2=0; int num_interfaces = iface_count(); - struct sockaddr_storage ss; int i; + /* Sort IPv6 addresses first. */ + if (ss1->ss_family != ss2->ss_family) { + if (ss2->ss_family == AF_INET) { + return -1; + } else { + return 1; + } + } + + /* Here we know both addresses are of the same + * family. */ + for (i=0;iss_family != AF_INET) { + if (pss->ss_family != ss1->ss_family) { + /* Ignore interfaces of the wrong type. */ continue; } - ip = ((const struct sockaddr_in *)pss)->sin_addr; - bits1 = matching_quad_bits((uchar *)&ip1->s_addr, (uchar *)&ip.s_addr); - bits2 = matching_quad_bits((uchar *)&ip2->s_addr, (uchar *)&ip.s_addr); + if (pss->ss_family == AF_INET) { + p_if = (unsigned char *) + &((const struct sockaddr_in *)pss)->sin_addr; + p_ss1 = (unsigned char *) + &((const struct sockaddr_in *)ss1)->sin_addr; + p_ss2 = (unsigned char *) + &((const struct sockaddr_in *)ss2)->sin_addr; + len = 4; + } +#if defined(HAVE_IPV6) + if (pss->ss_family == AF_INET6) { + p_if = (unsigned char *) + &((const struct sockaddr_in6 *)pss)->sin6_addr; + p_ss1 = (unsigned char *) + &((const struct sockaddr_in6 *)ss1)->sin6_addr; + p_ss2 = (unsigned char *) + &((const struct sockaddr_in6 *)ss2)->sin6_addr; + len = 16; + } +#endif + if (!p_ss1 || !p_ss2 || !p_if || len == 0) { + continue; + } + bits1 = matching_len_bits(p_ss1, p_if, len); + bits2 = matching_len_bits(p_ss2, p_if, len); max_bits1 = MAX(bits1, max_bits1); max_bits2 = MAX(bits2, max_bits2); - } - - /* bias towards directly reachable IPs */ - in_addr_to_sockaddr_storage(&ss, *ip1); - if (iface_local(&ss)) { - max_bits1 += 32; - } - in_addr_to_sockaddr_storage(&ss, *ip1); - if (iface_local(&ss)) { - max_bits2 += 32; } + /* Bias towards directly reachable IPs */ + if (iface_local(ss1)) { + if (ss1->ss_family == AF_INET) { + max_bits1 += 32; + } else { + max_bits1 += 128; + } + } + if (iface_local(ss2)) { + if (ss2->ss_family == AF_INET) { + max_bits2 += 32; + } else { + max_bits2 += 128; + } + } return max_bits2 - max_bits1; } @@ -387,73 +463,84 @@ static int ip_compare(struct in_addr *ip1, struct in_addr *ip2) compare 2 ldap IPs by nearness to our interfaces - used in qsort *******************************************************************/ -int ip_service_compare(struct ip_service *ip1, struct ip_service *ip2) +int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2) { int result; - - if ( (result = ip_compare(&ip1->ip, &ip2->ip)) != 0 ) + + if ((result = addr_compare(&ss1->ss, &ss2->ss)) != 0) { return result; - - if ( ip1->port > ip2->port ) + } + + if (ss1->port > ss2->port) { return 1; - - if ( ip1->port < ip2->port ) + } + + if (ss1->port < ss2->port) { return -1; - + } + return 0; } /* - sort an IP list so that names that are close to one of our interfaces - are at the top. This prevents the problem where a WINS server returns an IP that - is not reachable from our subnet as the first match + sort an IP list so that names that are close to one of our interfaces + are at the top. This prevents the problem where a WINS server returns an IP + that is not reachable from our subnet as the first match */ -static void sort_ip_list(struct in_addr *iplist, int count) +static void sort_addr_list(struct sockaddr_storage *sslist, int count) { if (count <= 1) { return; } - qsort(iplist, count, sizeof(struct in_addr), QSORT_CAST ip_compare); + qsort(sslist, count, sizeof(struct sockaddr_storage), + QSORT_CAST addr_compare); } -static void sort_ip_list2(struct ip_service *iplist, int count) +static void sort_service_list(struct ip_service *servlist, int count) { if (count <= 1) { return; } - qsort(iplist, count, sizeof(struct ip_service), QSORT_CAST ip_service_compare); + qsort(servlist, count, sizeof(struct ip_service), + QSORT_CAST ip_service_compare); } /********************************************************************** - Remove any duplicate address/port pairs in the list + Remove any duplicate address/port pairs in the list *********************************************************************/ -static int remove_duplicate_addrs2( struct ip_service *iplist, int count ) +static int remove_duplicate_addrs2(struct ip_service *iplist, int count ) { int i, j; - - DEBUG(10,("remove_duplicate_addrs2: looking for duplicate address/port pairs\n")); - + + DEBUG(10,("remove_duplicate_addrs2: " + "looking for duplicate address/port pairs\n")); + /* one loop to remove duplicates */ for ( i=0; iss_family != AF_INET) { return NULL; } if (timed_out) { - *timed_out = False; + *timed_out = false; } - + memset((char *)&p,'\0',sizeof(p)); (*count) = 0; (*flags) = 0; - + nmb->header.name_trn_id = generate_trn_id(); nmb->header.opcode = 0; - nmb->header.response = False; + nmb->header.response = false; nmb->header.nm_flags.bcast = bcast; - nmb->header.nm_flags.recursion_available = False; + nmb->header.nm_flags.recursion_available = false; nmb->header.nm_flags.recursion_desired = recurse; - nmb->header.nm_flags.trunc = False; - nmb->header.nm_flags.authoritative = False; + nmb->header.nm_flags.trunc = false; + nmb->header.nm_flags.authoritative = false; nmb->header.rcode = 0; nmb->header.qdcount = 1; nmb->header.ancount = 0; nmb->header.nscount = 0; nmb->header.arcount = 0; - + make_nmb_name(&nmb->question.question_name,name,name_type); - + nmb->question.question_type = 0x20; nmb->question.question_class = 0x1; - - p.ip = to_ip; + + p.ip = ((struct sockaddr_in *)to_ss)->sin_addr; p.port = NMB_PORT; p.fd = fd; p.timestamp = time(NULL); p.packet_type = NMB_PACKET; - + GetTimeOfDay(&tval); - - if (!send_packet(&p)) + + if (!send_packet(&p)) return NULL; - + retries--; - + while (1) { struct timeval tval2; - + GetTimeOfDay(&tval2); if (TvalDiff(&tval,&tval2) > retry_time) { if (!retries) @@ -541,52 +638,60 @@ struct in_addr *name_query(int fd,const char *name,int name_type, GetTimeOfDay(&tval); retries--; } - - if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { + + if ((p2=receive_nmb_packet(fd,90,nmb->header.name_trn_id))) { struct nmb_packet *nmb2 = &p2->packet.nmb; debug_nmb_packet(p2); - + /* If we get a Negative Name Query Response from a WINS * server, we should report it and give up. */ - if( 0 == nmb2->header.opcode /* A query response */ + if( 0 == nmb2->header.opcode /* A query response */ && !(bcast) /* from a WINS server */ - && nmb2->header.rcode /* Error returned */ + && nmb2->header.rcode /* Error returned */ ) { - + if( DEBUGLVL( 3 ) ) { /* Only executed if DEBUGLEVEL >= 3 */ - dbgtext( "Negative name query response, rcode 0x%02x: ", nmb2->header.rcode ); + dbgtext( "Negative name query " + "response, rcode 0x%02x: ", + nmb2->header.rcode ); switch( nmb2->header.rcode ) { case 0x01: - dbgtext( "Request was invalidly formatted.\n" ); + dbgtext( "Request " + "was invalidly formatted.\n" ); break; case 0x02: - dbgtext( "Problem with NBNS, cannot process name.\n"); + dbgtext( "Problem with NBNS, " + "cannot process name.\n"); break; case 0x03: - dbgtext( "The name requested does not exist.\n" ); + dbgtext( "The name requested " + "does not exist.\n" ); break; case 0x04: - dbgtext( "Unsupported request error.\n" ); + dbgtext( "Unsupported request " + "error.\n" ); break; case 0x05: - dbgtext( "Query refused error.\n" ); + dbgtext( "Query refused " + "error.\n" ); break; default: - dbgtext( "Unrecognized error code.\n" ); + dbgtext( "Unrecognized error " + "code.\n" ); break; } } free_packet(p2); return( NULL ); } - + if (nmb2->header.opcode != 0 || nmb2->header.nm_flags.bcast || nmb2->header.rcode || !nmb2->header.ancount) { - /* + /* * XXXX what do we do with this? Could be a * redirect, but we'll discard it for the * moment. @@ -594,25 +699,33 @@ struct in_addr *name_query(int fd,const char *name,int name_type, free_packet(p2); continue; } - - ip_list = SMB_REALLOC_ARRAY( ip_list, struct in_addr, - (*count) + nmb2->answers->rdlength/6 ); - - if (!ip_list) { + + ss_list = SMB_REALLOC_ARRAY(ss_list, + struct sockaddr_storage, + (*count) + + nmb2->answers->rdlength/6); + + if (!ss_list) { DEBUG(0,("name_query: Realloc failed.\n")); free_packet(p2); - return( NULL ); + return NULL; } - - DEBUG(2,("Got a positive name query response from %s ( ", inet_ntoa(p2->ip))); + + DEBUG(2,("Got a positive name query response " + "from %s ( ", + inet_ntoa(p2->ip))); + for (i=0;ianswers->rdlength/6;i++) { - putip((char *)&ip_list[(*count)],&nmb2->answers->rdata[2+i*6]); - DEBUGADD(2,("%s ",inet_ntoa(ip_list[(*count)]))); + struct in_addr ip; + putip((char *)&ip,&nmb2->answers->rdata[2+i*6]); + in_addr_to_sockaddr_storage(&ss_list[(*count)], + ip); + DEBUGADD(2,("%s ",inet_ntoa(ip))); (*count)++; } DEBUGADD(2,(")\n")); - - found=True; + + found=true; retries=0; /* We add the flags back ... */ if (nmb2->header.response) @@ -639,15 +752,15 @@ struct in_addr *name_query(int fd,const char *name,int name_type, } /* only set timed_out if we didn't fund what we where looking for*/ - + if ( !found && timed_out ) { - *timed_out = True; + *timed_out = true; } /* sort the ip list so we choose close servers first if possible */ - sort_ip_list(ip_list, *count); + sort_addr_list(ss_list, *count); - return ip_list; + return ss_list; } /******************************************************** @@ -658,8 +771,9 @@ XFILE *startlmhosts(const char *fname) { XFILE *fp = x_fopen(fname,O_RDONLY, 0); if (!fp) { - DEBUG(4,("startlmhosts: Can't open lmhosts file %s. Error was %s\n", - fname, strerror(errno))); + DEBUG(4,("startlmhosts: Can't open lmhosts file %s. " + "Error was %s\n", + fname, strerror(errno))); return NULL; } return fp; @@ -669,7 +783,8 @@ XFILE *startlmhosts(const char *fname) Parse the next line in the lmhosts file. *********************************************************/ -bool getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipaddr) +bool getlmhostsent(XFILE *fp, pstring name, int *name_type, + struct sockaddr_storage *pss) { pstring line; @@ -708,43 +823,51 @@ bool getlmhostsent( XFILE *fp, pstring name, int *name_type, struct in_addr *ipa continue; if (count > 0 && count < 2) { - DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n",line)); + DEBUG(0,("getlmhostsent: Ill formed hosts line [%s]\n", + line)); continue; } if (count >= 4) { - DEBUG(0,("getlmhostsent: too many columns in lmhosts file (obsolete syntax)\n")); + DEBUG(0,("getlmhostsent: too many columns " + "in lmhosts file (obsolete syntax)\n")); continue; } - DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); + DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", + ip, name, flags)); if (strchr_m(flags,'G') || strchr_m(flags,'S')) { - DEBUG(0,("getlmhostsent: group flag in lmhosts ignored (obsolete)\n")); + DEBUG(0,("getlmhostsent: group flag " + "in lmhosts ignored (obsolete)\n")); continue; } - *ipaddr = *interpret_addr2(ip); + if (!interpret_string_addr(pss, ip, AI_NUMERICHOST)) { + DEBUG(0,("getlmhostsent: invalid address " + "%s.\n", ip)); + } - /* Extra feature. If the name ends in '#XX', where XX is a hex number, - then only add that name type. */ + /* Extra feature. If the name ends in '#XX', + * where XX is a hex number, then only add that name type. */ if((ptr1 = strchr_m(name, '#')) != NULL) { char *endptr; ptr1++; *name_type = (int)strtol(ptr1, &endptr, 16); if(!*ptr1 || (endptr == ptr1)) { - DEBUG(0,("getlmhostsent: invalid name %s containing '#'.\n", name)); + DEBUG(0,("getlmhostsent: invalid name " + "%s containing '#'.\n", name)); continue; } *(--ptr1) = '\0'; /* Truncate at the '#' */ } - return True; + return true; } - return False; + return false; } /******************************************************** @@ -757,61 +880,75 @@ void endlmhosts(XFILE *fp) } /******************************************************** - convert an array if struct in_addrs to struct ip_service - return False on failure. Port is set to PORT_NONE; + convert an array if struct sockaddr_storage to struct ip_service + return false on failure. Port is set to PORT_NONE; *********************************************************/ -static bool convert_ip2service( struct ip_service **return_iplist, struct in_addr *ip_list, int count ) +static bool convert_ss2service(struct ip_service **return_iplist, + const struct sockaddr_storage *ss_list, + int count) { int i; - if ( count==0 || !ip_list ) + if ( count==0 || !ss_list ) return False; - + /* copy the ip address; port will be PORT_NONE */ - if ( (*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == NULL ) { - DEBUG(0,("convert_ip2service: malloc failed for %d enetries!\n", count )); + if ((*return_iplist = SMB_MALLOC_ARRAY(struct ip_service, count)) == + NULL) { + DEBUG(0,("convert_ip2service: malloc failed " + "for %d enetries!\n", count )); return False; } - + for ( i=0; i\n", name, name_type)); + DEBUG(3,("name_resolve_bcast: Attempting broadcast lookup " + "for name %s<0x%x>\n", name, name_type)); - sock = open_socket_in( SOCK_DGRAM, 0, 3, - interpret_addr(lp_socket_address()), True ); + if (!interpret_string_addr(&ss, lp_socket_address(), + AI_NUMERICHOST|AI_PASSIVE)) { + zero_addr(&ss, AF_INET); + } - if (sock == -1) return NT_STATUS_UNSUCCESSFUL; + sock = open_socket_in( SOCK_DGRAM, 0, 3, &ss, true ); + if (sock == -1) { + return NT_STATUS_UNSUCCESSFUL; + } set_socket_options(sock,"SO_BROADCAST"); /* @@ -819,32 +956,32 @@ NTSTATUS name_resolve_bcast(const char *name, int name_type, * the first successful match. */ for( i = num_interfaces-1; i >= 0; i--) { - struct in_addr sendto_ip; - const struct sockaddr_storage *ss = iface_n_bcast(i); + const struct sockaddr_storage *pss = iface_n_bcast(i); int flags; /* Done this way to fix compiler error on IRIX 5.x */ - if (!ss || ss->ss_family != AF_INET) { + if (!pss) { continue; } - sendto_ip = ((const struct sockaddr_in *)ss)->sin_addr; - ip_list = name_query(sock, name, name_type, True, - True, sendto_ip, return_count, &flags, NULL); - if( ip_list ) + ss_list = name_query(sock, name, name_type, true, + true, pss, return_count, &flags, NULL); + if (ss_list) { goto success; + } } - + /* failed - no response */ - + close(sock); return NT_STATUS_UNSUCCESSFUL; - + success: + status = NT_STATUS_OK; - if ( !convert_ip2service(return_iplist, ip_list, *return_count) ) + if (!convert_ss2service(return_iplist, ss_list, *return_count) ) status = NT_STATUS_INVALID_PARAMETER; - - SAFE_FREE( ip_list ); + + SAFE_FREE(ss_list); close(sock); return status; } @@ -853,27 +990,32 @@ success: Resolve via "wins" method. *********************************************************/ -NTSTATUS resolve_wins(const char *name, int name_type, - struct ip_service **return_iplist, - int *return_count) +NTSTATUS resolve_wins(const char *name, + int name_type, + struct ip_service **return_iplist, + int *return_count) { int sock, t, i; char **wins_tags; - struct in_addr src_ip, *ip_list = NULL; + struct sockaddr_storage src_ss, *ss_list = NULL; + struct in_addr src_ip; NTSTATUS status; if (lp_disable_netbios()) { - DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type)); + DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", + name, name_type)); return NT_STATUS_INVALID_PARAMETER; } *return_iplist = NULL; *return_count = 0; - - DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type)); + + DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", + name, name_type)); if (wins_srv_count() < 1) { - DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS servers listed.\n")); + DEBUG(3,("resolve_wins: WINS server resolution selected " + "and no WINS servers listed.\n")); return NT_STATUS_INVALID_PARAMETER; } @@ -886,13 +1028,28 @@ NTSTATUS resolve_wins(const char *name, int name_type, } /* the address we will be sending from */ - src_ip = *interpret_addr2(lp_socket_address()); + if (!interpret_string_addr(&src_ss, lp_socket_address(), + AI_NUMERICHOST|AI_PASSIVE)) { + zero_addr(&src_ss, AF_INET); + } + + if (src_ss.ss_family != AF_INET) { + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), &src_ss); + DEBUG(3,("resolve_wins: cannot receive WINS replies " + "on IPv6 address %s\n", + addr)); + return NT_STATUS_INVALID_PARAMETER; + } + + src_ip = ((struct sockaddr_in *)&src_ss)->sin_addr; /* in the worst case we will try every wins server with every tag! */ for (t=0; wins_tags && wins_tags[t]; t++) { int srv_count = wins_srv_count_tag(wins_tags[t]); for (i=0; i\n", name, name_type)); + DEBUG(3,("resolve_lmhosts: " + "Attempting lmhosts lookup for name %s<0x%x>\n", + name, name_type)); fp = startlmhosts(dyn_LMHOSTSFILE); if ( fp == NULL ) return NT_STATUS_NO_SUCH_FILE; - while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) - { + while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ss)) { if (!strequal(name, lmhost_name)) continue; @@ -990,7 +1160,8 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, if ((name_type2 != -1) && (name_type != name_type2)) continue; - *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service, + *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), + struct ip_service, (*return_count)+1); if ((*return_iplist) == NULL) { @@ -999,7 +1170,7 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, return NT_STATUS_NO_MEMORY; } - (*return_iplist)[*return_count].ip = return_ip; + (*return_iplist)[*return_count].ss = return_ss; (*return_iplist)[*return_count].port = PORT_NONE; *return_count += 1; @@ -1012,7 +1183,6 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, } endlmhosts(fp); - return status; } @@ -1035,14 +1205,17 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, int i = 0; if ( name_type != 0x20 && name_type != 0x0) { - DEBUG(5, ("resolve_hosts: not appropriate for name type <0x%x>\n", name_type)); + DEBUG(5, ("resolve_hosts: not appropriate " + "for name type <0x%x>\n", + name_type)); return NT_STATUS_INVALID_PARAMETER; } *return_iplist = NULL; *return_count = 0; - DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", name, name_type)); + DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x%x>\n", + name, name_type)); ZERO_STRUCT(hints); /* By default make sure it supports TCP. */ @@ -1060,18 +1233,14 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, } for (res = ailist; res; res = res->ai_next) { - struct in_addr return_ip; + struct sockaddr_storage ss; - /* IPv4 only for now until I convert ip_service */ - if (res->ai_family != AF_INET) { - continue; - } - if (!res->ai_addr) { + if (!res->ai_addr || res->ai_addrlen == 0) { continue; } - putip((char *)&return_ip, - &((struct sockaddr_in *)res->ai_addr)->sin_addr); + memset(&ss, '\0', sizeof(ss)); + memcpy(&ss, res->ai_addr, res->ai_addrlen); *return_count += 1; @@ -1083,9 +1252,8 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, freeaddrinfo(ailist); return NT_STATUS_NO_MEMORY; } - (*return_iplist)[i].ip = return_ip; + (*return_iplist)[i].ss = ss; (*return_iplist)[i].port = PORT_NONE; - i++; } if (ailist) { @@ -1101,10 +1269,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, Resolve via "ADS" method. *********************************************************/ -NTSTATUS resolve_ads(const char *name, int name_type, - const char *sitename, - struct ip_service **return_iplist, - int *return_count) +NTSTATUS resolve_ads(const char *name, + int name_type, + const char *sitename, + struct ip_service **return_iplist, + int *return_count) { int i, j; NTSTATUS status; @@ -1123,6 +1292,8 @@ NTSTATUS resolve_ads(const char *name, int name_type, return NT_STATUS_NO_MEMORY; } + /* The DNS code needs fixing to find IPv6 addresses... JRA. */ + switch (name_type) { case 0x1b: DEBUG(5,("resolve_ads: Attempting to resolve " @@ -1155,53 +1326,60 @@ NTSTATUS resolve_ads(const char *name, int name_type, for (i=0;iport = dcs[i].port; - + /* If we don't have an IP list for a name, lookup it up */ - - if ( !dcs[i].ips ) { - r->ip = *interpret_addr2(dcs[i].hostname); + + if (!dcs[i].ips) { + ip = *interpret_addr2(dcs[i].hostname); i++; j = 0; } else { /* use the IP addresses from the SRV sresponse */ - + if ( j >= dcs[i].num_ips ) { i++; j = 0; continue; } - - r->ip = dcs[i].ips[j]; + + ip = dcs[i].ips[j]; j++; } - - /* make sure it is a valid IP. I considered checking the negative - connection cache, but this is the wrong place for it. Maybe only - as a hac. After think about it, if all of the IP addresses retuend - from DNS are dead, what hope does a netbios name lookup have? - The standard reason for falling back to netbios lookups is that - our DNS server doesn't know anything about the DC's -- jerry */ - - if ( ! is_zero_ip_v4(r->ip) ) + + in_addr_to_sockaddr_storage(&r->ss, ip); + + /* make sure it is a valid IP. I considered checking the + * negative connection cache, but this is the wrong place + * for it. Maybe only as a hack. After think about it, if + * all of the IP addresses returned from DNS are dead, what + * hope does a netbios name lookup have ? The standard reason + * for falling back to netbios lookups is that our DNS server + * doesn't know anything about the DC's -- jerry */ + + if (!is_zero_addr(&r->ss)) { (*return_count)++; + } } - + talloc_destroy(ctx); return NT_STATUS_OK; } @@ -1211,23 +1389,22 @@ NTSTATUS resolve_ads(const char *name, int name_type, Use this function if the string is either an IP address, DNS or host name or NetBIOS name. This uses the name switch in the smb.conf to determine the order of name resolution. - + Added support for ip addr/port to support ADS ldap servers. - the only place we currently care about the port is in the + the only place we currently care about the port is in the resolve_hosts() when looking up DC's via SRV RR entries in DNS **********************************************************************/ -NTSTATUS internal_resolve_name(const char *name, int name_type, - const char *sitename, - struct ip_service **return_iplist, - int *return_count, const char *resolve_order) +NTSTATUS internal_resolve_name(const char *name, + int name_type, + const char *sitename, + struct ip_service **return_iplist, + int *return_count, + const char *resolve_order) { pstring name_resolve_list; fstring tok; const char *ptr; - bool allones = (strcmp(name,"255.255.255.255") == 0); - bool allzeros = (strcmp(name,"0.0.0.0") == 0); - bool is_address = is_ipaddress_v4(name); NTSTATUS status = NT_STATUS_UNSUCCESSFUL; int i; @@ -1237,30 +1414,29 @@ NTSTATUS internal_resolve_name(const char *name, int name_type, DEBUG(10, ("internal_resolve_name: looking up %s#%x (sitename %s)\n", name, name_type, sitename ? sitename : NULL)); - if (allzeros || allones || is_address) { - - if ( (*return_iplist = SMB_MALLOC_P(struct ip_service)) == NULL ) { + if (is_ipaddress(name)) { + if ((*return_iplist = SMB_MALLOC_P(struct ip_service)) == + NULL) { DEBUG(0,("internal_resolve_name: malloc fail !\n")); return NT_STATUS_NO_MEMORY; } - - if(is_address) { - /* ignore the port here */ - (*return_iplist)->port = PORT_NONE; - - /* if it's in the form of an IP address then get the lib to interpret it */ - if (((*return_iplist)->ip.s_addr = inet_addr(name)) == 0xFFFFFFFF ){ - DEBUG(1,("internal_resolve_name: inet_addr failed on %s\n", name)); - SAFE_FREE(*return_iplist); - return NT_STATUS_INVALID_PARAMETER; - } - } else { - (*return_iplist)->ip.s_addr = allones ? 0xFFFFFFFF : 0; + + /* ignore the port here */ + (*return_iplist)->port = PORT_NONE; + + /* if it's in the form of an IP address then get the lib to interpret it */ + if (!interpret_string_addr(&(*return_iplist)->ss, + name, AI_NUMERICHOST)) { + DEBUG(1,("internal_resolve_name: interpret_string_addr " + "failed on %s\n", + name)); + SAFE_FREE(*return_iplist); + return NT_STATUS_INVALID_PARAMETER; } *return_count = 1; return NT_STATUS_OK; } - + /* Check name cache */ if (namecache_fetch(name, name_type, return_iplist, return_count)) { @@ -1274,25 +1450,25 @@ NTSTATUS internal_resolve_name(const char *name, int name_type, /* set the name resolution order */ - if ( strcmp( resolve_order, "NULL") == 0 ) { + if (strcmp( resolve_order, "NULL") == 0) { DEBUG(8,("internal_resolve_name: all lookups disabled\n")); return NT_STATUS_INVALID_PARAMETER; } - - if ( !resolve_order ) { + + if (!resolve_order) { pstrcpy(name_resolve_list, lp_name_resolve_order()); } else { pstrcpy(name_resolve_list, resolve_order); } - if ( !name_resolve_list[0] ) { + if (!name_resolve_list[0]) { ptr = "host"; } else { ptr = name_resolve_list; } /* iterate through the name resolution backends */ - + while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { status = resolve_hosts(name, name_type, return_iplist, @@ -1301,18 +1477,19 @@ NTSTATUS internal_resolve_name(const char *name, int name_type, goto done; } } else if(strequal( tok, "kdc")) { - /* deal with KDC_NAME_TYPE names here. This will result in a - SRV record lookup */ + /* deal with KDC_NAME_TYPE names here. + * This will result in a SRV record lookup */ status = resolve_ads(name, KDC_NAME_TYPE, sitename, return_iplist, return_count); if (NT_STATUS_IS_OK(status)) { - /* Ensure we don't namecache this with the KDC port. */ + /* Ensure we don't namecache + * this with the KDC port. */ name_type = KDC_NAME_TYPE; goto done; } } else if(strequal( tok, "ads")) { - /* deal with 0x1c and 0x1b names here. This will result in a - SRV record lookup */ + /* deal with 0x1c and 0x1b names here. + * This will result in a SRV record lookup */ status = resolve_ads(name, name_type, sitename, return_iplist, return_count); if (NT_STATUS_IS_OK(status)) { @@ -1362,29 +1539,43 @@ NTSTATUS internal_resolve_name(const char *name, int name_type, the iplist when the PDC is down will cause two sets of timeouts. */ if ( *return_count ) { - *return_count = remove_duplicate_addrs2( *return_iplist, *return_count ); + *return_count = remove_duplicate_addrs2(*return_iplist, + *return_count ); } - + /* Save in name cache */ if ( DEBUGLEVEL >= 100 ) { - for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) - DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", name, - name_type, inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); + for (i = 0; i < *return_count && DEBUGLEVEL == 100; i++) { + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), + &(*return_iplist)[i].ss); + DEBUG(100, ("Storing name %s of type %d (%s:%d)\n", + name, + name_type, + addr, + (*return_iplist)[i].port)); + } } - + namecache_store(name, name_type, *return_count, *return_iplist); /* Display some debugging info */ if ( DEBUGLEVEL >= 10 ) { - DEBUG(10, ("internal_resolve_name: returning %d addresses: ", *return_count)); + DEBUG(10, ("internal_resolve_name: returning %d addresses: ", + *return_count)); for (i = 0; i < *return_count; i++) { - DEBUGADD(10, ("%s:%d ", inet_ntoa((*return_iplist)[i].ip), (*return_iplist)[i].port)); + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), + &(*return_iplist)[i].ss); + DEBUGADD(10, ("%s:%d ", + addr, + (*return_iplist)[i].port)); } DEBUG(10, ("\n")); } - + return status; } @@ -1395,39 +1586,38 @@ NTSTATUS internal_resolve_name(const char *name, int name_type, smb.conf to determine the order of name resolution. *********************************************************/ -bool resolve_name(const char *name, struct in_addr *return_ip, int name_type) +bool resolve_name(const char *name, + struct sockaddr_storage *return_ss, + int name_type) { - struct ip_service *ip_list = NULL; - char *sitename = sitename_fetch(lp_realm()); /* wild guess */ + struct ip_service *ss_list = NULL; + char *sitename = NULL; int count = 0; - if (is_ipaddress_v4(name)) { - *return_ip = *interpret_addr2(name); - SAFE_FREE(sitename); - return True; + if (is_ipaddress(name)) { + return interpret_string_addr(return_ss, name, AI_NUMERICHOST); } + sitename = sitename_fetch(lp_realm()); /* wild guess */ + if (NT_STATUS_IS_OK(internal_resolve_name(name, name_type, sitename, - &ip_list, &count, + &ss_list, &count, lp_name_resolve_order()))) { int i; - + /* only return valid addresses for TCP connections */ for (i=0; i 1 ) { - DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count)); - sort_ip_list2( ip_list, count ); + DEBUG(6,("get_pdc_ip: PDC has %d IP addresses!\n", count)); + sort_service_list(ip_list, count); } - *ip = ip_list[0].ip; - + *pss = ip_list[0].ss; SAFE_FREE(ip_list); - - return True; + return true; } /* Private enum type for lookups. */ @@ -1518,8 +1706,12 @@ enum dc_lookup_type { DC_NORMAL_LOOKUP, DC_ADS_ONLY, DC_KDC_ONLY }; a domain. *********************************************************/ -static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_service **ip_list, - int *count, enum dc_lookup_type lookup_type, bool *ordered) +static NTSTATUS get_dc_list(const char *domain, + const char *sitename, + struct ip_service **ip_list, + int *count, + enum dc_lookup_type lookup_type, + bool *ordered) { fstring resolve_order; char *saf_servername; @@ -1544,56 +1736,56 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ are disabled and ads_only is True, then set the string to NULL. */ - fstrcpy( resolve_order, lp_name_resolve_order() ); - strlower_m( resolve_order ); - if ( lookup_type == DC_ADS_ONLY) { - if ( strstr( resolve_order, "host" ) ) { - fstrcpy( resolve_order, "ads" ); + fstrcpy(resolve_order, lp_name_resolve_order()); + strlower_m(resolve_order); + if (lookup_type == DC_ADS_ONLY) { + if (strstr( resolve_order, "host")) { + fstrcpy( resolve_order, "ads"); /* DNS SRV lookups used by the ads resolver are already sorted by priority and weight */ - *ordered = True; + *ordered = true; } else { - fstrcpy( resolve_order, "NULL" ); + fstrcpy(resolve_order, "NULL"); } } else if (lookup_type == DC_KDC_ONLY) { /* DNS SRV lookups used by the ads/kdc resolver are already sorted by priority and weight */ - *ordered = True; - fstrcpy( resolve_order, "kdc" ); + *ordered = true; + fstrcpy(resolve_order, "kdc"); } - /* fetch the server we have affinity for. Add the + /* fetch the server we have affinity for. Add the 'password server' list to a search for our domain controllers */ - + saf_servername = saf_fetch( domain); - - if ( strequal(domain, lp_workgroup()) || strequal(domain, lp_realm()) ) { - pstr_sprintf( pserver, "%s, %s", + + if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) { + pstr_sprintf(pserver, "%s, %s", saf_servername ? saf_servername : "", - lp_passwordserver() ); + lp_passwordserver()); } else { - pstr_sprintf( pserver, "%s, *", - saf_servername ? saf_servername : "" ); + pstr_sprintf(pserver, "%s, *", + saf_servername ? saf_servername : ""); } SAFE_FREE( saf_servername ); /* if we are starting from scratch, just lookup DOMAIN<0x1c> */ - if ( !*pserver ) { + if (!*pserver ) { DEBUG(10,("get_dc_list: no preferred domain controllers.\n")); return internal_resolve_name(domain, 0x1C, sitename, ip_list, count, resolve_order); } DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver )); - + /* * if '*' appears in the "password server" list then add * an auto lookup to the list of manually configured - * DC's. If any DC is listed by name, then the list should be - * considered to be ordered + * DC's. If any DC is listed by name, then the list should be + * considered to be ordered */ p = pserver; @@ -1606,8 +1798,9 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ if (NT_STATUS_IS_OK(status)) { num_addresses += auto_count; } - done_auto_lookup = True; - DEBUG(8,("Adding %d DC's from auto lookup\n", auto_count)); + done_auto_lookup = true; + DEBUG(8,("Adding %d DC's from auto lookup\n", + auto_count)); } else { num_addresses++; } @@ -1615,10 +1808,10 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ /* if we have no addresses and haven't done the auto lookup, then just return the list of DC's. Or maybe we just failed. */ - - if ( (num_addresses == 0) ) { - if ( done_auto_lookup ) { - DEBUG(4,("get_dc_list: no servers found\n")); + + if ((num_addresses == 0)) { + if (done_auto_lookup) { + DEBUG(4,("get_dc_list: no servers found\n")); SAFE_FREE(auto_ip_list); return NT_STATUS_NO_LOGON_SERVERS; } @@ -1626,7 +1819,8 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ count, resolve_order); } - if ( (return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL ) { + if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service, + num_addresses)) == NULL) { DEBUG(3,("get_dc_list: malloc fail !\n")); SAFE_FREE(auto_ip_list); return NT_STATUS_NO_MEMORY; @@ -1636,74 +1830,101 @@ static NTSTATUS get_dc_list(const char *domain, const char *sitename, struct ip_ local_count = 0; /* fill in the return list now with real IP's */ - - while ( (local_count= 4 ) { - DEBUG(4,("get_dc_list: returning %d ip addresses in an %sordered list\n", local_count, - *ordered ? "":"un")); + DEBUG(4,("get_dc_list: returning %d ip addresses " + "in an %sordered list\n", + local_count, + *ordered ? "":"un")); DEBUG(4,("get_dc_list: ")); - for ( i=0; ildap.ip); + &ads->ldap.ss); } else { create_local_private_krb5_conf_for_domain(realm, domain, NULL, - ads->ldap.ip); + &ads->ldap.ss); } } #endif @@ -131,34 +132,36 @@ static bool ads_dc_name(const char *domain, fstrcpy(srv_name, ads->config.ldap_server_name); strupper_m(srv_name); #ifdef HAVE_ADS - *dc_ip = ads->ldap.ip; + *dc_ss = ads->ldap.ss; #else - ZERO_STRUCT(*dc_ip); + zero_addr(dc_ss,AF_INET); #endif ads_destroy(&ads); - + + print_sockaddr(addr, sizeof(addr), dc_ss); DEBUG(4,("ads_dc_name: using server='%s' IP=%s\n", - srv_name, inet_ntoa(*dc_ip))); - + srv_name, addr)); + return True; } /**************************************************************************** - Utility function to return the name of a DC. The name is guaranteed to be - valid since we have already done a name_status_find on it + Utility function to return the name of a DC. The name is guaranteed to be + valid since we have already done a name_status_find on it ***************************************************************************/ -static bool rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip_out) +static bool rpc_dc_name(const char *domain, + fstring srv_name, + struct sockaddr_storage *ss_out) { struct ip_service *ip_list = NULL; - struct in_addr dc_ip, exclude_ip; + struct sockaddr_storage dc_ss; int count, i; NTSTATUS result; - - zero_ip_v4(&exclude_ip); + char addr[INET6_ADDRSTRLEN]; /* get a list of all domain controllers */ - + if (!NT_STATUS_IS_OK(get_sorted_dc_list(domain, NULL, &ip_list, &count, False))) { DEBUG(3, ("Could not look up dc's for domain %s\n", domain)); @@ -168,35 +171,34 @@ static bool rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip /* Remove the entry we've already failed with (should be the PDC). */ for (i = 0; i < count; i++) { - if (is_zero_ip_v4(ip_list[i].ip)) + if (is_zero_addr(&ip_list[i].ss)) continue; - if (name_status_find(domain, 0x1c, 0x20, ip_list[i].ip, srv_name)) { + if (name_status_find(domain, 0x1c, 0x20, &ip_list[i].ss, srv_name)) { result = check_negative_conn_cache( domain, srv_name ); if ( NT_STATUS_IS_OK(result) ) { - dc_ip = ip_list[i].ip; + dc_ss = ip_list[i].ss; goto done; } } } - SAFE_FREE(ip_list); /* No-one to talk to )-: */ return False; /* Boo-hoo */ - + done: /* We have the netbios name and IP address of a domain controller. Ideally we should sent a SAMLOGON request to determine whether the DC is alive and kicking. If we can catch a dead DC before performing a cli_connect() we can avoid a 30-second timeout. */ + print_sockaddr(addr, sizeof(addr), &dc_ss); DEBUG(3, ("rpc_dc_name: Returning DC %s (%s) for domain %s\n", srv_name, - inet_ntoa(dc_ip), domain)); - - *ip_out = dc_ip; + addr, domain)); + *ss_out = dc_ss; SAFE_FREE(ip_list); return True; @@ -206,37 +208,40 @@ static bool rpc_dc_name(const char *domain, fstring srv_name, struct in_addr *ip wrapper around ads and rpc methods of finds DC's **********************************************************************/ -bool get_dc_name(const char *domain, const char *realm, fstring srv_name, struct in_addr *ip_out) +bool get_dc_name(const char *domain, + const char *realm, + fstring srv_name, + struct sockaddr_storage *ss_out) { - struct in_addr dc_ip; + struct sockaddr_storage dc_ss; bool ret; bool our_domain = False; - zero_ip_v4(&dc_ip); + zero_addr(&dc_ss, AF_INET); ret = False; - + if ( strequal(lp_workgroup(), domain) || strequal(lp_realm(), realm) ) our_domain = True; - - /* always try to obey what the admin specified in smb.conf + + /* always try to obey what the admin specified in smb.conf (for the local domain) */ - + if ( (our_domain && lp_security()==SEC_ADS) || realm ) { - ret = ads_dc_name(domain, realm, &dc_ip, srv_name); + ret = ads_dc_name(domain, realm, &dc_ss, srv_name); } if (!domain) { /* if we have only the realm we can't do anything else */ return False; } - + if (!ret) { /* fall back on rpc methods if the ADS methods fail */ - ret = rpc_dc_name(domain, srv_name, &dc_ip); + ret = rpc_dc_name(domain, srv_name, &dc_ss); } - - *ip_out = dc_ip; + + *ss_out = dc_ss; return ret; } diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 4d21258f99..7e152ab324 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -1187,19 +1187,20 @@ bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name) } /**************************************************************************** - Return the number of bits that match between two 4 character buffers + Return the number of bits that match between two len character buffers ***************************************************************************/ -int matching_quad_bits(unsigned char *p1, unsigned char *p2) +int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len) { - int i, j, ret = 0; - for (i=0; i<4; i++) { + size_t i, j; + int ret = 0; + for (i=0; i Date: Thu, 25 Oct 2007 18:15:02 -0700 Subject: Fix cast typo - would have broken all dgram sends. Jeremy. (This used to be commit 17ea899f39e80241afa235cb933695ba6bae846a) --- source3/libsmb/clidgram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 9f6f4480c5..5b619b6458 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -99,7 +99,7 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */ p.packet_type = DGRAM_PACKET; - p.ip = ((const struct sockaddr_in *)&dest_ss)->sin_addr; + p.ip = ((const struct sockaddr_in *)dest_ss)->sin_addr; p.timestamp = time(NULL); DEBUG(4,("send_mailslot: Sending to mailslot %s from %s ", -- cgit From 6128d116b3f09ce0b055d2df89b2f7282185782e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Oct 2007 18:28:36 -0700 Subject: Fix resolve name to resolve IPv6 addresses of link-local%ifaddr Jeremy. (This used to be commit e6609cab732d5cd5cc9a5ae50aee15147f2ec6ec) --- source3/libsmb/namequery.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 34fe09b8c2..90e6be6a90 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1594,6 +1594,32 @@ bool resolve_name(const char *name, char *sitename = NULL; int count = 0; +#if defined(HAVE_IPV6) + unsigned int if_idx = 0; + const char *p = strchr_m(name, '%'); + + if (p && (if_idx = if_nametoindex(p+1)) != 0) { + char *newname = SMB_STRDUP(name); + if (!newname) { + return false; + } + newname[PTR_DIFF(p,name)] = '\0'; + if (is_ipaddress(newname) && + interpret_string_addr(return_ss, + newname, AI_NUMERICHOST)) { + struct sockaddr_in6 *psa6 = + (struct sockaddr_in6 *)&return_ss; + if (psa6->sin6_scope_id == 0 && + IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) { + psa6->sin6_scope_id = if_idx; + } + SAFE_FREE(newname); + return true; + } + SAFE_FREE(newname); + } +#endif + if (is_ipaddress(name)) { return interpret_string_addr(return_ss, name, AI_NUMERICHOST); } -- cgit From fc91aa6988e93ee5a001781d56699e3c1b9684a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Oct 2007 16:03:20 -0700 Subject: Move the horrible hack for link local addresses out of namequery.c and into util_sock.c. is_ipaddress() now copes with link:local:v6%ifname addresses, as does interpret_string_addr(). Jeremy (This used to be commit a3f7db3d30ced566c8340696914f1be3293a9c5b) --- source3/libsmb/namequery.c | 26 -------------------------- 1 file changed, 26 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 90e6be6a90..34fe09b8c2 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1594,32 +1594,6 @@ bool resolve_name(const char *name, char *sitename = NULL; int count = 0; -#if defined(HAVE_IPV6) - unsigned int if_idx = 0; - const char *p = strchr_m(name, '%'); - - if (p && (if_idx = if_nametoindex(p+1)) != 0) { - char *newname = SMB_STRDUP(name); - if (!newname) { - return false; - } - newname[PTR_DIFF(p,name)] = '\0'; - if (is_ipaddress(newname) && - interpret_string_addr(return_ss, - newname, AI_NUMERICHOST)) { - struct sockaddr_in6 *psa6 = - (struct sockaddr_in6 *)&return_ss; - if (psa6->sin6_scope_id == 0 && - IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) { - psa6->sin6_scope_id = if_idx; - } - SAFE_FREE(newname); - return true; - } - SAFE_FREE(newname); - } -#endif - if (is_ipaddress(name)) { return interpret_string_addr(return_ss, name, AI_NUMERICHOST); } -- cgit From d4307679b95088d05f0abad440de5e961ee965df Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 27 Oct 2007 20:29:36 -0700 Subject: Change all occurrences of zero_addr(&ss,AF_INET) to zero_addr(&ss). All current uses were always of the AF_INET form, so simplify the call. If in the future we need to zero an addr to AF_INET6 this can be done separately. Jeremy. (This used to be commit 2e92418a138bf2738b77b7e0fcb2fa37ad84fc0c) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clidfs.c | 4 ++-- source3/libsmb/libsmbclient.c | 6 +++--- source3/libsmb/namequery.c | 8 ++++---- source3/libsmb/namequery_dc.c | 4 ++-- 5 files changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 826315ad7a..448bfd7663 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1519,7 +1519,7 @@ NTSTATUS cli_start_connection(struct cli_state **output_cli, if (dest_ss) { ss = *dest_ss; } else { - zero_addr(&ss, AF_INET); + zero_addr(&ss); } again: diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e1ca924b09..6393f654c0 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -83,13 +83,13 @@ static struct cli_state *do_connect( const char *server, const char *share, server_n = server; - zero_addr(&ss, AF_INET); + zero_addr(&ss); make_nmb_name(&calling, global_myname(), 0x0); make_nmb_name(&called , server, name_type); again: - zero_addr(&ss, AF_INET); + zero_addr(&ss); if (have_ip) ss = dest_ss; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index d5bf1828c6..0b45cad3e1 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -654,7 +654,7 @@ smbc_server(SMBCCTX *context, const char *username_used; NTSTATUS status; - zero_addr(&ss, AF_INET); + zero_addr(&ss); ZERO_STRUCT(c); if (server[0] == 0) { @@ -742,7 +742,7 @@ smbc_server(SMBCCTX *context, again: slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); - zero_addr(&ss, AF_INET); + zero_addr(&ss); /* have to open a new connection */ if ((c = cli_initialise()) == NULL) { @@ -964,7 +964,7 @@ smbc_attr_server(SMBCCTX *context, flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } - zero_addr(&ss, AF_INET); + zero_addr(&ss); nt_status = cli_full_connection(&ipc_cli, global_myname(), server, &ss, 0, "IPC$", "?????", diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 34fe09b8c2..f4c516921c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -331,7 +331,7 @@ bool name_status_find(const char *q_name, if (!interpret_string_addr(&ss, lp_socket_address(), AI_NUMERICHOST|AI_PASSIVE)) { - zero_addr(&ss, AF_INET); + zero_addr(&ss); } sock = open_socket_in(SOCK_DGRAM, 0, 3, &ss, True); @@ -528,7 +528,7 @@ static int remove_duplicate_addrs2(struct ip_service *iplist, int count ) for ( j=i+1; jldap.ss; #else - zero_addr(dc_ss,AF_INET); + zero_addr(dc_ss); #endif ads_destroy(&ads); @@ -217,7 +217,7 @@ bool get_dc_name(const char *domain, bool ret; bool our_domain = False; - zero_addr(&dc_ss, AF_INET); + zero_addr(&dc_ss); ret = False; -- cgit From e2d0526c9799a75f87bbbe24f2e5a268df89fea9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 29 Oct 2007 13:34:00 -0700 Subject: Change our DNS code to cope with AAAA records. A6 records look like a nightmare to use, so ignore them for now. Jeremy. (This used to be commit 814daded90781dc5a5bdd522ea8cfe5d47e6d7a7) --- source3/libsmb/dsgetdcname.c | 14 ++++++++------ source3/libsmb/namequery.c | 9 +++------ 2 files changed, 11 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index bffbd0f8dc..f6c3273084 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -27,7 +27,7 @@ #define DSGETDCNAME_CACHE_TTL 60*15 struct ip_service_name { - struct in_addr ip; + struct sockaddr_storage ss; unsigned port; const char *hostname; }; @@ -625,8 +625,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, /* If we don't have an IP list for a name, lookup it up */ - if (!dcs[i].ips) { - r->ip = *interpret_addr2(dcs[i].hostname); + if (!dcs[i].ss_s) { + interpret_string_addr(&r->ss, dcs[i].hostname, 0); i++; j = 0; } else { @@ -638,7 +638,7 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, continue; } - r->ip = dcs[i].ips[j]; + r->ss = dcs[i].ss_s[j]; j++; } @@ -650,7 +650,7 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, * back to netbios lookups is that our DNS server doesn't know * anything about the DC's -- jerry */ - if (!is_zero_ip_v4(r->ip)) { + if (!is_zero_addr(&r->ss)) { (*return_count)++; continue; } @@ -789,8 +789,10 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, } if (flags & DS_IP_REQUIRED) { + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), &dclist[i]->ss); dc_address = talloc_asprintf(mem_ctx, "\\\\%s", - inet_ntoa(dclist[i]->ip)); + addr); dc_address_type = ADS_INET_ADDRESS; } else { dc_address = talloc_asprintf(mem_ctx, "\\\\%s", diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f4c516921c..dde758b41c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1341,15 +1341,14 @@ NTSTATUS resolve_ads(const char *name, i = 0; j = 0; while ( i < numdcs && (*return_countport = dcs[i].port; /* If we don't have an IP list for a name, lookup it up */ - if (!dcs[i].ips) { - ip = *interpret_addr2(dcs[i].hostname); + if (!dcs[i].ss_s) { + interpret_string_addr(&r->ss, dcs[i].hostname, 0); i++; j = 0; } else { @@ -1361,12 +1360,10 @@ NTSTATUS resolve_ads(const char *name, continue; } - ip = dcs[i].ips[j]; + r->ss = dcs[i].ss_s[j]; j++; } - in_addr_to_sockaddr_storage(&r->ss, ip); - /* make sure it is a valid IP. I considered checking the * negative connection cache, but this is the wrong place * for it. Maybe only as a hack. After think about it, if -- cgit From 32dd016353355acfb71dd773187076f95ff6e86e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 29 Oct 2007 15:03:36 -0700 Subject: Fix the setup_kaddr() call to cope with IPv6. This is the last obvious change I can see. At this point we can start claiming IPv6 support (Hurrah !:-). Jeremy. (This used to be commit bda8c0bf571c994b524a9d67eebc422033d17094) --- source3/libsmb/clikrb5.c | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index fb25e9e203..d996d61a48 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -162,19 +162,45 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, #if defined(HAVE_ADDR_TYPE_IN_KRB5_ADDRESS) /* HEIMDAL */ - void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr) + bool setup_kaddr( krb5_address *pkaddr, struct sockaddr_storage *paddr) { - pkaddr->addr_type = KRB5_ADDRESS_INET; - pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); - pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); + memset(pkaddr, '\0', sizeof(krb5_address)); +#if defined(HAVE_IPV6) && defined(KRB5_ADDRESS_INET6) + if (paddr->ss_family == AF_INET6) { + pkaddr->addr_type = KRB5_ADDRESS_INET6; + pkaddr->address.length = sizeof(((struct sockaddr_in6 *)paddr)->sin6_addr); + pkaddr->address.data = (char *)&(((struct sockaddr_in6 *)paddr)->sin6_addr); + return true; + } +#endif + if (paddr->ss_family == AF_INET) { + pkaddr->addr_type = KRB5_ADDRESS_INET; + pkaddr->address.length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->address.data = (char *)&(((struct sockaddr_in *)paddr)->sin_addr); + return true; + } + return false; } #elif defined(HAVE_ADDRTYPE_IN_KRB5_ADDRESS) /* MIT */ - void setup_kaddr_v4( krb5_address *pkaddr, struct sockaddr *paddr) + bool setup_kaddr( krb5_address *pkaddr, struct sockaddr_storage *paddr) { - pkaddr->addrtype = ADDRTYPE_INET; - pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); - pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); + memset(pkaddr, '\0', sizeof(krb5_address)); +#if defined(HAVE_IPV6) && defined(ADDRTYPE_INET6) + if (paddr->ss_family == AF_INET6) { + pkaddr->addrtype = ADDRTYPE_INET6; + pkaddr->length = sizeof(((struct sockaddr_in6 *)paddr)->sin6_addr); + pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in6 *)paddr)->sin6_addr); + return true; + } +#endif + if (paddr->ss_family == AF_INET) { + pkaddr->addrtype = ADDRTYPE_INET; + pkaddr->length = sizeof(((struct sockaddr_in *)paddr)->sin_addr); + pkaddr->contents = (krb5_octet *)&(((struct sockaddr_in *)paddr)->sin_addr); + return true; + } + return false; } #else #error UNKNOWN_ADDRTYPE -- cgit From f5dcac6e8ed17a45d82ce395b01f8d5418a11331 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Oct 2007 12:54:39 -0700 Subject: Our userlevel SMBwriteX call is non-standard in that it sometimes uses a 12-word write and doesn't include a pad byte (as Windows does). Fix this so that we are identical to Windows clients. This will make recvfile processing much easier to detect (as we can just read a standard writeX header length to decide). Jeremy. (This used to be commit 3d3d1b806aef3617abaac46daf230ed32076e2ce) --- source3/libsmb/clireadwrite.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 0d037e946e..e2d5337ee4 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -291,7 +291,7 @@ static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, char *p; bool large_writex = False; - if (size > cli->bufsize) { + if (size + 1 > cli->bufsize) { cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024); if (!cli->outbuf) { return False; @@ -307,7 +307,7 @@ static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - if (((SMB_BIG_UINT)offset >> 32) || (size > 0xFFFF)) { + if (cli->capabilities & CAP_LARGE_FILES) { large_writex = True; } @@ -315,11 +315,11 @@ static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, set_message(cli->outbuf,14,0,True); else set_message(cli->outbuf,12,0,True); - + SCVAL(cli->outbuf,smb_com,SMBwriteX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - + SCVAL(cli->outbuf,smb_vwv0,0xFF); SSVAL(cli->outbuf,smb_vwv2,fnum); @@ -336,19 +336,21 @@ static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, */ SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1)); SSVAL(cli->outbuf,smb_vwv10,size); + /* +1 is pad byte. */ SSVAL(cli->outbuf,smb_vwv11, - smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + smb_buf(cli->outbuf) - smb_base(cli->outbuf) + 1); if (large_writex) { SIVAL(cli->outbuf,smb_vwv12,(((SMB_BIG_UINT)offset)>>32) & 0xffffffff); } - - p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11) -1; + *p++ = '\0'; /* pad byte. */ memcpy(p, buf, size); cli_setup_bcc(cli, p+size); SSVAL(cli->outbuf,smb_mid,cli->mid + i); - + show_msg(cli->outbuf); return cli_send_smb(cli); } -- cgit From 0e073b8152103d9de9fc68cb5b0dfbb7c9b0327a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 20 Oct 2007 11:12:11 +0200 Subject: Fix for bug 5021 This is a different fix than the bug reporter (Evgeniy Dushistov , thanks!) created, but it lives without the boolean status variable. Untested so far, but I can not add attachments to bugs right now. But to me this looks really obvious. (This used to be commit b481abf5914dcafe5642c4d9394d02603e905bbb) --- source3/libsmb/libsmbclient.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 0b45cad3e1..ff434d275a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2671,7 +2671,11 @@ smbc_opendir_ctx(SMBCCTX *context, return NULL; } - ip_list = &server_addr; + ip_list = memdup(&server_addr, sizeof(server_addr)); + if (ip_list == NULL) { + errno = ENOMEM; + return NULL; + } count = 1; } -- cgit From 329365684bca99bf9020b6638a1357df65c1d938 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Nov 2007 12:21:34 -0700 Subject: Change the client library to write directly out of the incoming buffer in the non-signed case. Speeds up writes by over 10% or so. Complete the server recvfile implementation. Jeremy. (This used to be commit 81ca5853b2475f123faab3b550f0a7b24ae3c208) --- source3/libsmb/clientgen.c | 65 ++++++++++++++++++++++++-- source3/libsmb/clireadwrite.c | 106 +++++++++++++++++++++++++++++------------- 2 files changed, 136 insertions(+), 35 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ca05b2e38a..19210dd069 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -251,15 +251,15 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) static ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; - + DEBUG(6,("write_socket(%d,%d)\n",fd,(int)len)); ret = write_data(fd,buf,len); - + DEBUG(6,("write_socket(%d,%d) wrote %d\n",fd,(int)len,(int)ret)); if(ret <= 0) DEBUG(0,("write_socket: Error writing %d bytes to socket %d: ERRNO = %s\n", (int)len, fd, strerror(errno) )); - + return(ret); } @@ -300,6 +300,65 @@ bool cli_send_smb(struct cli_state *cli) return True; } +/**************************************************************************** + Send a "direct" writeX smb to a fd. +****************************************************************************/ + +bool cli_send_smb_direct_writeX(struct cli_state *cli, + const char *p, + size_t extradata) +{ + /* First length to send is the offset to the data. */ + size_t len = SVAL(cli->outbuf,smb_vwv11) + 4; + size_t nwritten=0; + ssize_t ret; + + /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ + if (cli->fd == -1) { + return false; + } + + if (client_is_signing_on(cli)) { + DEBUG(0,("cli_send_smb_large: cannot send signed packet.\n")); + return false; + } + + while (nwritten < len) { + ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + if (ret <= 0) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; + DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", + (int)len,(int)ret, strerror(errno) )); + return false; + } + nwritten += ret; + } + + /* Now write the extra data. */ + nwritten=0; + while (nwritten < extradata) { + ret = write_socket(cli->fd,p+nwritten,extradata - nwritten); + if (ret <= 0) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = WRITE_ERROR; + DEBUG(0,("Error writing %d extradata " + "bytes to client. %d (%s)\n", + (int)extradata,(int)ret, strerror(errno) )); + return False; + } + nwritten += ret; + } + + /* Increment the mid so we can tell between responses. */ + cli->mid++; + if (!cli->mid) + cli->mid++; + return true; +} + /**************************************************************************** Setup basics in a outgoing packet. ****************************************************************************/ diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index e2d5337ee4..0c79da9f84 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. client file read/write routines Copyright (C) Andrew Tridgell 1994-1998 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -23,7 +23,7 @@ Issue a single SMBread and don't wait for a reply. ****************************************************************************/ -static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset, +static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset, size_t size, int i) { bool bigoffset = False; @@ -31,11 +31,11 @@ static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - if ((SMB_BIG_UINT)offset >> 32) + if ((SMB_BIG_UINT)offset >> 32) bigoffset = True; set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); - + SCVAL(cli->outbuf,smb_com,SMBreadX); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -68,7 +68,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ /* We can only do direct reads if not signing. */ bool direct_reads = !client_is_signing_on(cli); - if (size == 0) + if (size == 0) return 0; /* @@ -280,18 +280,25 @@ ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, si return total; } #endif + /**************************************************************************** -issue a single SMBwrite and don't wait for a reply + Issue a single SMBwrite and don't wait for a reply. ****************************************************************************/ -static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, - uint16 mode, const char *buf, - size_t size, int i) +static bool cli_issue_write(struct cli_state *cli, + int fnum, + off_t offset, + uint16 mode, + const char *buf, + size_t size, + int i) { char *p; - bool large_writex = False; + bool large_writex = false; + /* We can only do direct writes if not signing. */ + bool direct_writes = !client_is_signing_on(cli); - if (size + 1 > cli->bufsize) { + if (!direct_writes && size + 1 > cli->bufsize) { cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024); if (!cli->outbuf) { return False; @@ -311,10 +318,11 @@ static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, large_writex = True; } - if (large_writex) + if (large_writex) { set_message(cli->outbuf,14,0,True); - else + } else { set_message(cli->outbuf,12,0,True); + } SCVAL(cli->outbuf,smb_com,SMBwriteX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -334,7 +342,7 @@ static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, * locally. However, this check might already have been * done by our callers. */ - SSVAL(cli->outbuf,smb_vwv9,((size>>16)&1)); + SSVAL(cli->outbuf,smb_vwv9,(size>>16)); SSVAL(cli->outbuf,smb_vwv10,size); /* +1 is pad byte. */ SSVAL(cli->outbuf,smb_vwv11, @@ -346,13 +354,27 @@ static bool cli_issue_write(struct cli_state *cli, int fnum, off_t offset, p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11) -1; *p++ = '\0'; /* pad byte. */ - memcpy(p, buf, size); - cli_setup_bcc(cli, p+size); + if (!direct_writes) { + memcpy(p, buf, size); + } + if (size > 0x1FFFF) { + /* This is a POSIX 14 word large write. */ + set_message_bcc(cli->outbuf, 0); /* Set bcc to zero. */ + _smb_setlen_large(cli->outbuf,smb_size + 28 + 1 /* pad */ + size - 4); + } else { + cli_setup_bcc(cli, p+size); + } SSVAL(cli->outbuf,smb_mid,cli->mid + i); show_msg(cli->outbuf); - return cli_send_smb(cli); + if (direct_writes) { + /* For direct writes we now need to write the data + * directly out of buf. */ + return cli_send_smb_direct_writeX(cli, buf, size); + } else { + return cli_send_smb(cli); + } } /**************************************************************************** @@ -371,8 +393,8 @@ ssize_t cli_write(struct cli_state *cli, unsigned int issued = 0; unsigned int received = 0; int mpx = 1; - int block = cli->max_xmit - (smb_size+32); - int blocks = (size + (block-1)) / block; + size_t writesize; + int blocks; if(cli->max_mux > 1) { mpx = cli->max_mux-1; @@ -380,11 +402,29 @@ ssize_t cli_write(struct cli_state *cli, mpx = 1; } + if (!client_is_signing_on(cli) && + (cli->posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) && + (cli->capabilities & CAP_LARGE_FILES)) { + /* Only do massive writes if we can do them direct + * with no signing. */ + writesize = CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE; + } else if (cli->capabilities & CAP_LARGE_READX) { + if (cli->is_samba) { + writesize = CLI_SAMBA_MAX_LARGE_READX_SIZE; + } else { + writesize = CLI_WINDOWS_MAX_LARGE_READX_SIZE; + } + } else { + writesize = (cli->max_xmit - (smb_size+32)) & ~1023; + } + + blocks = (size + (writesize-1)) / writesize; + while (received < blocks) { while ((issued - received < mpx) && (issued < blocks)) { - ssize_t bsent = issued * block; - ssize_t size1 = MIN(block, size - bsent); + ssize_t bsent = issued * writesize; + ssize_t size1 = MIN(writesize, size - bsent); if (!cli_issue_write(cli, fnum, offset + bsent, write_mode, @@ -394,8 +434,9 @@ ssize_t cli_write(struct cli_state *cli, issued++; } - if (!cli_receive_smb(cli)) + if (!cli_receive_smb(cli)) { return bwritten; + } received++; @@ -406,9 +447,10 @@ ssize_t cli_write(struct cli_state *cli, bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))<<16); } - while (received < issued && cli_receive_smb(cli)) + while (received < issued && cli_receive_smb(cli)) { received++; - + } + return bwritten; } @@ -424,7 +466,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, do { size_t size = MIN(size1, cli->max_xmit - 48); - + memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -433,25 +475,25 @@ ssize_t cli_smbwrite(struct cli_state *cli, SCVAL(cli->outbuf,smb_com,SMBwrite); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - + SSVAL(cli->outbuf,smb_vwv0,fnum); SSVAL(cli->outbuf,smb_vwv1,size); SIVAL(cli->outbuf,smb_vwv2,offset); SSVAL(cli->outbuf,smb_vwv4,0); - + p = smb_buf(cli->outbuf); *p++ = 1; SSVAL(p, 0, size); p += 2; memcpy(p, buf + total, size); p += size; cli_setup_bcc(cli, p); - + if (!cli_send_smb(cli)) return -1; if (!cli_receive_smb(cli)) return -1; - + if (cli_is_error(cli)) return -1; -- cgit From 73d407968002587eadd0ff13eb413ddf07c78771 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2007 15:12:42 -0700 Subject: Remove the smb_read_error global variable and replace it with accessor functions. "One global or pstring a day...." :-). Jeremy. (This used to be commit d50d14c300abc83b7015718ec48acc8b3227a273) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 21 ++++++++++----------- source3/libsmb/clierror.c | 20 ++++++++++---------- 3 files changed, 21 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 448bfd7663..b86939a897 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -699,7 +699,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use nt_status = cli_nt_error(cli); if (cli_is_error(cli) && NT_STATUS_IS_OK(nt_status)) { - if (cli->smb_rw_error == READ_BAD_SIG) { + if (cli->smb_rw_error == SMB_READ_BAD_SIG) { nt_status = NT_STATUS_ACCESS_DENIED; } else { nt_status = NT_STATUS_UNSUCCESSFUL; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 19210dd069..0a8ff4e552 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -20,8 +20,6 @@ #include "includes.h" -extern int smb_read_error; - /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -112,7 +110,7 @@ bool cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (len < 0) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); - cli->smb_rw_error = smb_read_error; + cli->smb_rw_error = get_smb_read_error(); close(cli->fd); cli->fd = -1; return False; @@ -135,12 +133,12 @@ bool cli_receive_smb(struct cli_state *cli) * Reflected signature on login error. * Set bad sig but don't close fd. */ - cli->smb_rw_error = READ_BAD_SIG; + cli->smb_rw_error = SMB_READ_BAD_SIG; return True; } DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); - cli->smb_rw_error = READ_BAD_SIG; + cli->smb_rw_error = SMB_READ_BAD_SIG; close(cli->fd); cli->fd = -1; return False; @@ -242,7 +240,8 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) read_err: - cli->smb_rw_error = smb_read_error = READ_ERROR; + set_smb_read_error(SMB_READ_ERROR); + cli->smb_rw_error = SMB_READ_ERROR; close(cli->fd); cli->fd = -1; return False; @@ -286,7 +285,7 @@ bool cli_send_smb(struct cli_state *cli) if (ret <= 0) { close(cli->fd); cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; + cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); return False; @@ -328,7 +327,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, if (ret <= 0) { close(cli->fd); cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; + cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); return false; @@ -343,7 +342,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, if (ret <= 0) { close(cli->fd); cli->fd = -1; - cli->smb_rw_error = WRITE_ERROR; + cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d extradata " "bytes to client. %d (%s)\n", (int)extradata,(int)ret, strerror(errno) )); @@ -590,11 +589,11 @@ void cli_shutdown(struct cli_state *cli) * later. This tree disconnect forces the peer to clean up, since the * connection will be going away. * - * Also, do not do tree disconnect when cli->smb_rw_error is DO_NOT_DO_TDIS + * Also, do not do tree disconnect when cli->smb_rw_error is SMB_DO_NOT_DO_TDIS * the only user for this so far is smbmount which passes opened connection * down to kernel's smbfs module. */ - if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != DO_NOT_DO_TDIS ) ) { + if ( (cli->cnum != (uint16)-1) && (cli->smb_rw_error != SMB_DO_NOT_DO_TDIS ) ) { cli_tdis(cli); } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 4ab1c237dc..1c35bcf146 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -72,17 +72,17 @@ static const char *cli_smb_errstr(struct cli_state *cli) static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli) { switch(cli->smb_rw_error) { - case READ_TIMEOUT: + case SMB_READ_TIMEOUT: return NT_STATUS_IO_TIMEOUT; - case READ_EOF: + case SMB_READ_EOF: return NT_STATUS_END_OF_FILE; /* What we shoud really do for read/write errors is convert from errno. */ /* FIXME. JRA. */ - case READ_ERROR: + case SMB_READ_ERROR: return NT_STATUS_INVALID_NETWORK_RESPONSE; - case WRITE_ERROR: + case SMB_WRITE_ERROR: return NT_STATUS_UNEXPECTED_NETWORK_ERROR; - case READ_BAD_SIG: + case SMB_READ_BAD_SIG: return NT_STATUS_INVALID_PARAMETER; default: break; @@ -111,24 +111,24 @@ const char *cli_errstr(struct cli_state *cli) /* Was it server socket error ? */ if (cli->fd == -1 && cli->smb_rw_error) { switch(cli->smb_rw_error) { - case READ_TIMEOUT: + case SMB_READ_TIMEOUT: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Call timed out: server did not respond after %d milliseconds", cli->timeout); break; - case READ_EOF: + case SMB_READ_EOF: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Call returned zero bytes (EOF)" ); break; - case READ_ERROR: + case SMB_READ_ERROR: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Read error: %s", strerror(errno) ); break; - case WRITE_ERROR: + case SMB_WRITE_ERROR: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Write error: %s", strerror(errno) ); break; - case READ_BAD_SIG: + case SMB_READ_BAD_SIG: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Server packet had invalid SMB signature!"); break; -- cgit From 36441da4240f3e3a296eed65f0796b25b7b05a3a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 5 Nov 2007 11:12:56 -0800 Subject: Remove the horror that was the global smb_rw_error. Each cli struct has it's own local copy of this variable, so use that in client code. In the smbd server, add one static to smbd/proccess.c and use that inside smbd. Fix a bunch of places where smb_rw_error could be set by calling read_data() in places where we weren't reading from the SMB client socket (ie. winbindd). Jeremy. (This used to be commit 255c2adf7b6ef30932b5bb9f142ccef4a5d3d0db) --- source3/libsmb/clientgen.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0a8ff4e552..ee1a0fe3db 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -52,24 +52,26 @@ int cli_set_port(struct cli_state *cli, int port) should never go into a blocking read. ****************************************************************************/ -static ssize_t client_receive_smb(int fd,char *buffer, unsigned int timeout, size_t maxlen) +static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) { ssize_t len; for(;;) { - len = receive_smb_raw(fd, buffer, timeout, maxlen); + len = receive_smb_raw(cli->fd, cli->inbuf, cli->timeout, + maxlen, &cli->smb_rw_error); if (len < 0) { DEBUG(10,("client_receive_smb failed\n")); - show_msg(buffer); + show_msg(cli->inbuf); return len; } /* Ignore session keepalive packets. */ - if(CVAL(buffer,0) != SMBkeepalive) + if(CVAL(cli->inbuf,0) != SMBkeepalive) { break; + } } - show_msg(buffer); + show_msg(cli->inbuf); return len; } @@ -86,7 +88,7 @@ bool cli_receive_smb(struct cli_state *cli) return False; again: - len = client_receive_smb(cli->fd,cli->inbuf,cli->timeout, 0); + len = client_receive_smb(cli, 0); if (len > 0) { /* it might be an oplock break request */ @@ -110,7 +112,6 @@ bool cli_receive_smb(struct cli_state *cli) /* If the server is not responding, note that now */ if (len < 0) { DEBUG(0, ("Receiving SMB: Server stopped responding\n")); - cli->smb_rw_error = get_smb_read_error(); close(cli->fd); cli->fd = -1; return False; @@ -154,9 +155,10 @@ bool cli_receive_smb(struct cli_state *cli) ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) { if (cli->timeout > 0) { - return read_socket_with_timeout(cli->fd, buffer, len, len, cli->timeout); + return read_socket_with_timeout(cli->fd, buffer, len, + len, cli->timeout, &cli->smb_rw_error); } else { - return read_data(cli->fd, buffer, len); + return read_data(cli->fd, buffer, len, &cli->smb_rw_error); } } @@ -174,7 +176,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) again: /* Read up to the size of a readX header reply. */ - len = client_receive_smb(cli->fd, cli->inbuf, cli->timeout, (smb_size - 4) + 24); + len = client_receive_smb(cli, (smb_size - 4) + 24); if (len > 0) { /* it might be an oplock break request */ @@ -240,7 +242,6 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) read_err: - set_smb_read_error(SMB_READ_ERROR); cli->smb_rw_error = SMB_READ_ERROR; close(cli->fd); cli->fd = -1; -- cgit From 7498e1b8c09abef2db0658c6bfd6d42891c9690d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 6 Nov 2007 14:12:38 -0800 Subject: Ensure we don't use massive writes in pipe mode. Jeremy. (This used to be commit 47640fb20e42f226e7ea104076fd52547bfe1abb) --- source3/libsmb/clireadwrite.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 0c79da9f84..d77875bae5 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -402,11 +402,12 @@ ssize_t cli_write(struct cli_state *cli, mpx = 1; } - if (!client_is_signing_on(cli) && + if (write_mode == 0 && + !client_is_signing_on(cli) && (cli->posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) && (cli->capabilities & CAP_LARGE_FILES)) { /* Only do massive writes if we can do them direct - * with no signing. */ + * with no signing - not on a pipe. */ writesize = CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE; } else if (cli->capabilities & CAP_LARGE_READX) { if (cli->is_samba) { -- cgit From 380840d588fa38a7e5a4a8aa39a0f3a35eb6a5d6 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 8 Nov 2007 14:33:04 +0100 Subject: add win_errstr() as wrapper of dos_errstr(). this makes merging stuff from samba4 easier metze (This used to be commit cfbdb133b998a704c6c167b9b4b56370f4ff666d) --- source3/libsmb/doserr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 52afb0d022..b8cb8b4bc6 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -108,3 +108,9 @@ const char *dos_errstr(WERROR werror) return msg; } + +/* compat function for samba4 */ +const char *win_errstr(WERROR werror) +{ + return dos_errstr(werror); +} -- cgit From d40e47db4b5da41c8604a2058f3a0b0a82164f08 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Nov 2007 17:25:45 -0800 Subject: Remove more fstring/pstring bad useage. Go talloc ! Jeremy. (This used to be commit 2a0173743d2cf615d52278f3dd87cc804abe2d16) --- source3/libsmb/ntlmssp.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 7205d57a0a..ed08e8102b 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -501,18 +501,19 @@ DATA_BLOB ntlmssp_weaken_keys(NTLMSSP_STATE *ntlmssp_state, TALLOC_CTX *mem_ctx) /** * Next state function for the Negotiate packet - * + * * @param ntlmssp_state NTLMSSP State * @param request The request, as a DATA_BLOB * @param request The reply, as an allocated DATA_BLOB, caller to free. - * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. + * @return Errors or MORE_PROCESSING_REQUIRED if a reply is sent. */ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, const DATA_BLOB request, DATA_BLOB *reply) { DATA_BLOB struct_blob; - fstring dnsname, dnsdomname; + const char *dnsname; + char *dnsdomname = NULL; uint32 neg_flags = 0; uint32 ntlmssp_command, chal_flags; const uint8 *cryptkey; @@ -535,7 +536,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, } debug_ntlmssp_flags(neg_flags); } - + ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth()); /* Ask our caller what challenge they would like in the packet */ @@ -548,31 +549,34 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* The flags we send back are not just the negotiated flags, * they are also 'what is in this packet'. Therfore, we - * operate on 'chal_flags' from here on + * operate on 'chal_flags' from here on */ chal_flags = ntlmssp_state->neg_flags; /* get the right name to fill in as 'target' */ - target_name = ntlmssp_target_name(ntlmssp_state, - neg_flags, &chal_flags); - if (target_name == NULL) + target_name = ntlmssp_target_name(ntlmssp_state, + neg_flags, &chal_flags); + if (target_name == NULL) return NT_STATUS_INVALID_PARAMETER; ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8); - /* This should be a 'netbios domain -> DNS domain' mapping */ - dnsdomname[0] = '\0'; - get_mydnsdomname(dnsdomname); + dnsdomname = get_mydnsdomname(ntlmssp_state->mem_ctx); + if (!dnsdomname) { + return NT_STATUS_BAD_NETWORK_NAME; + } strlower_m(dnsdomname); - - dnsname[0] = '\0'; - get_mydnsfullname(dnsname); - + + dnsname = get_mydnsfullname(); + if (!dnsdomname) { + return NT_STATUS_INVALID_COMPUTER_NAME; + } + /* This creates the 'blob' of names that appears at the end of the packet */ - if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) + if (chal_flags & NTLMSSP_CHAL_TARGET_INFO) { msrpc_gen(&struct_blob, "aaaaa", NTLMSSP_NAME_TYPE_DOMAIN, target_name, @@ -592,9 +596,9 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, } else { gen_string = "CdAdbddB"; } - + msrpc_gen(reply, gen_string, - "NTLMSSP", + "NTLMSSP", NTLMSSP_CHALLENGE, target_name, chal_flags, @@ -602,7 +606,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, 0, 0, struct_blob.data, struct_blob.length); } - + data_blob_free(&struct_blob); ntlmssp_state->expected_state = NTLMSSP_AUTH; @@ -612,7 +616,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /** * Next state function for the Authenticate packet - * + * * @param ntlmssp_state NTLMSSP State * @param request The request, as a DATA_BLOB * @param request The reply, as an allocated DATA_BLOB, caller to free. -- cgit From 5f4693d8f8cf435cb2c62787ba95acf2b0b5f7d2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Nov 2007 18:50:07 -0800 Subject: Remove more pstring/fstrings. Jeremy. (This used to be commit 7a1de5b44e84a7474e78518c6ba33b3fedc42b5f) --- source3/libsmb/cliconnect.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b86939a897..8b180f0135 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1772,12 +1772,9 @@ struct cli_state *get_ipc_connect(char *server, struct user_auth_info *user_info) { struct cli_state *cli; - pstring myname; NTSTATUS nt_status; - get_myname(myname); - - nt_status = cli_full_connection(&cli, myname, server, server_ss, 0, "IPC$", "IPC", + nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", user_info->username, lp_workgroup(), user_info->password, CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL); -- cgit From 9e5ef9a87424ce02d114c702c238fcd14a92de01 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 7 Nov 2007 18:47:32 +0100 Subject: pstring removal (This used to be commit 0ee896827215a24e70a4ac6bde5ded13f9497296) --- source3/libsmb/doserr.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index b8cb8b4bc6..478b87d730 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -94,11 +94,9 @@ werror_code_struct dos_errs[] = const char *dos_errstr(WERROR werror) { - static pstring msg; + char *result; int idx = 0; - slprintf(msg, sizeof(msg), "DOS code 0x%08x", W_ERROR_V(werror)); - while (dos_errs[idx].dos_errstr != NULL) { if (W_ERROR_V(dos_errs[idx].werror) == W_ERROR_V(werror)) @@ -106,7 +104,10 @@ const char *dos_errstr(WERROR werror) idx++; } - return msg; + result = talloc_asprintf(talloc_tos(), "DOS code 0x%08x", + W_ERROR_V(werror)); + SMB_ASSERT(result != NULL); + return result; } /* compat function for samba4 */ -- cgit From e63bcdd720d801df278ef84063c46144df087793 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 1 Nov 2007 18:13:00 +0100 Subject: Remove the silly "user_socket_options" global variable This is better done with a 'lp_do_parameter(-1, "socket options", ..); (This used to be commit 814bed029efa391e664ac432d0d68dfeab26381f) --- source3/libsmb/cliconnect.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8b180f0135..2fdd1223f0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -20,8 +20,6 @@ #include "includes.h" -extern pstring user_socket_options; - static const struct { int prot; const char *name; @@ -1382,7 +1380,7 @@ bool cli_session_request(struct cli_state *cli, DEBUG(3,("Retargeted\n")); - set_socket_options(cli->fd,user_socket_options); + set_socket_options(cli->fd, lp_socket_options()); /* Try again */ { @@ -1469,7 +1467,7 @@ NTSTATUS cli_connect(struct cli_state *cli, return map_nt_error_from_unix(errno); } - set_socket_options(cli->fd,user_socket_options); + set_socket_options(cli->fd, lp_socket_options()); return NT_STATUS_OK; } -- cgit From 637f9d9bf0947600e612057ddcd9caf137b9698e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 9 Nov 2007 14:23:16 +0100 Subject: Fix some warnings (This used to be commit 0a1f524e8cce9bbe4fd10467c1f64f7a8862d298) --- source3/libsmb/libsmbclient.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ff434d275a..dbc51d168e 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2671,7 +2671,8 @@ smbc_opendir_ctx(SMBCCTX *context, return NULL; } - ip_list = memdup(&server_addr, sizeof(server_addr)); + ip_list = (struct ip_service *)memdup( + &server_addr, sizeof(server_addr)); if (ip_list == NULL) { errno = ENOMEM; return NULL; -- cgit From 50d9b94f6f7762fb4a86b020af461553422a71ad Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 11 Nov 2007 15:38:50 +0100 Subject: Remove a static fstring I'm not sure why this used to be static, to me it seems that every time this variable is overwritten. I just don't see how name_status_find() could return true and not overwrite name. Can someone please review this and potentially check it in? Thanks, Volker (This used to be commit 329c688e4a9e69b71996fd1b0eee2202a849f3f5) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2fdd1223f0..f0b03a85cf 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1806,7 +1806,7 @@ struct cli_state *get_ipc_connect(char *server, struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring workgroup, struct user_auth_info *user_info) { char addr[INET6_ADDRSTRLEN]; - static fstring name; + fstring name; struct cli_state *cli; struct sockaddr_storage server_ss; -- cgit From 63d141d4e8b6fa0977b9b89545e9cf8bc694f416 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 11 Nov 2007 15:50:16 +0100 Subject: Remove a static fstring Feel free to push :-) Volker (This used to be commit f213556f50de4a28b5c5d2e1e762013837feb722) --- source3/libsmb/cliquota.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 1932c044e2..690da5928c 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -562,26 +562,26 @@ cleanup: return ret; } -static char *quota_str_static(SMB_BIG_UINT val, bool special, bool _numeric) +static const char *quota_str_static(SMB_BIG_UINT val, bool special, bool _numeric) { - static fstring buffer; - - memset(buffer,'\0',sizeof(buffer)); + const char *result; if (!_numeric&&special&&(val == SMB_NTQUOTAS_NO_LIMIT)) { - fstr_sprintf(buffer,"NO LIMIT"); - return buffer; + return "NO LIMIT"; } #if defined(HAVE_LONGLONG) - fstr_sprintf(buffer,"%llu",val); + result = talloc_asprintf(talloc_tos(), "%llu", val); #else - fstr_sprintf(buffer,"%lu",val); -#endif - return buffer; + result = talloc_asprintf(talloc_tos(), "%lu", val); +#endif + SMB_ASSERT(result != NULL); + return result; } void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, bool _verbose, bool _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, bool _numeric)) { + TALLOC_CTX *frame = talloc_stackframe(); + if (!qt) { smb_panic("dump_ntquota() called with NULL pointer"); } @@ -626,8 +626,9 @@ void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, bool _verbose, bool _numeric, void (*_ break; default: d_printf("dump_ntquota() invalid qtype(%d)\n",qt->qtype); - return; } + TALLOC_FREE(frame); + return; } void dump_ntquota_list(SMB_NTQUOTA_LIST **qtl, bool _verbose, bool _numeric, void (*_sidtostring)(fstring str, DOM_SID *sid, bool _numeric)) -- cgit From 6069670f1bebc37527c8363a72a653e43fff7c0b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 11 Nov 2007 15:30:01 +0100 Subject: Some pstring removal Hi! Feel free to push :-) Volker From 7fae6b3709a973bd0a5a13d3f5c880c61d5e35de Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 11 Nov 2007 15:28:59 +0100 Subject: [PATCH] Remove some static pstrings (This used to be commit c3a66b4ee97a902c5cf43c3bb145541849a029ed) --- source3/libsmb/clierror.c | 14 ++++++++--- source3/libsmb/dcerpc_err.c | 9 ++++--- source3/libsmb/nterr.c | 18 ++++++++------ source3/libsmb/smberr.c | 60 +++++++++++++++++++++++++++------------------ 4 files changed, 61 insertions(+), 40 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 1c35bcf146..2232ee27a7 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -98,14 +98,15 @@ static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli) const char *cli_errstr(struct cli_state *cli) { - static fstring cli_error_message; + fstring cli_error_message; uint32 flgs2 = SVAL(cli->inbuf,smb_flg2), errnum; uint8 errclass; int i; + char *result; if (!cli->initialised) { fstrcpy(cli_error_message, "[Programmer's error] cli_errstr called on unitialized cli_stat struct!\n"); - return cli_error_message; + goto done; } /* Was it server socket error ? */ @@ -137,7 +138,7 @@ const char *cli_errstr(struct cli_state *cli) "Unknown error code %d\n", cli->smb_rw_error ); break; } - return cli_error_message; + goto done; } /* Case #1: RAP error */ @@ -151,7 +152,7 @@ const char *cli_errstr(struct cli_state *cli) slprintf(cli_error_message, sizeof(cli_error_message) - 1, "RAP code %d", cli->rap_error); - return cli_error_message; + goto done; } /* Case #2: 32-bit NT errors */ @@ -166,6 +167,11 @@ const char *cli_errstr(struct cli_state *cli) /* Case #3: SMB error */ return cli_smb_errstr(cli); + + done: + result = talloc_strdup(talloc_tos(), cli_error_message); + SMB_ASSERT(result); + return result; } diff --git a/source3/libsmb/dcerpc_err.c b/source3/libsmb/dcerpc_err.c index b1874b943f..900b8d769f 100644 --- a/source3/libsmb/dcerpc_err.c +++ b/source3/libsmb/dcerpc_err.c @@ -38,11 +38,9 @@ static const struct dcerpc_fault_table dcerpc_faults[] = const char *dcerpc_errstr(uint32 fault_code) { - static pstring msg; + char *result; int idx = 0; - slprintf(msg, sizeof(msg), "DCERPC fault 0x%08x", fault_code); - while (dcerpc_faults[idx].errstr != NULL) { if (dcerpc_faults[idx].faultcode == fault_code) { return dcerpc_faults[idx].errstr; @@ -50,5 +48,8 @@ const char *dcerpc_errstr(uint32 fault_code) idx++; } - return msg; + result = talloc_asprintf(talloc_tos(), "DCERPC fault 0x%08x", + fault_code); + SMB_ASSERT(result != NULL); + return result; } diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index d88e650c9c..cf443f2339 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -647,8 +647,8 @@ nt_err_code_struct nt_err_desc[] = const char *nt_errstr(NTSTATUS nt_code) { - static pstring msg; int idx = 0; + char *result; #ifdef HAVE_LDAP if (NT_STATUS_TYPE(nt_code) == NT_STATUS_TYPE_LDAP) { @@ -656,8 +656,6 @@ const char *nt_errstr(NTSTATUS nt_code) } #endif - slprintf(msg, sizeof(msg), "NT code 0x%08x", NT_STATUS_V(nt_code)); - while (nt_errs[idx].nt_errstr != NULL) { if (NT_STATUS_EQUAL(nt_errs[idx].nt_errcode, nt_code)) { return nt_errs[idx].nt_errstr; @@ -665,7 +663,10 @@ const char *nt_errstr(NTSTATUS nt_code) idx++; } - return msg; + result = talloc_asprintf(talloc_tos(), "NT code 0x%08x", + NT_STATUS_V(nt_code)); + SMB_ASSERT(result != NULL); + return result; } /************************************************************************ @@ -694,7 +695,7 @@ const char *get_friendly_nt_error_msg(NTSTATUS nt_code) const char *get_nt_error_c_code(NTSTATUS nt_code) { - static pstring out; + char *result; int idx = 0; while (nt_errs[idx].nt_errstr != NULL) { @@ -705,9 +706,10 @@ const char *get_nt_error_c_code(NTSTATUS nt_code) idx++; } - slprintf(out, sizeof(out), "NT_STATUS(0x%08x)", NT_STATUS_V(nt_code)); - - return out; + result = talloc_asprintf(talloc_tos(), "NT_STATUS(0x%08x)", + NT_STATUS_V(nt_code)); + SMB_ASSERT(result); + return result; } /***************************************************************************** diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c index 1d81011d92..f4a13983f0 100644 --- a/source3/libsmb/smberr.c +++ b/source3/libsmb/smberr.c @@ -160,7 +160,7 @@ return a SMB error name from a class and code ****************************************************************************/ const char *smb_dos_err_name(uint8 e_class, uint16 num) { - static pstring ret; + char *result; int i,j; for (i=0;err_classes[i].e_class;i++) @@ -172,12 +172,15 @@ const char *smb_dos_err_name(uint8 e_class, uint16 num) return err[j].name; } } - slprintf(ret, sizeof(ret) - 1, "%d",num); - return ret; + result = talloc_asprintf(talloc_tos(), "%d", num); + SMB_ASSERT(result != NULL); + return result; } - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error class (%d,%d)",e_class,num); - return(ret); + result = talloc_asprintf(talloc_tos(), "Error: Unknown error class " + "(%d,%d)", e_class,num); + SMB_ASSERT(result != NULL); + return result; } /* Return a string for a DOS error */ @@ -196,17 +199,19 @@ return a SMB error class name as a string. ****************************************************************************/ const char *smb_dos_err_class(uint8 e_class) { - static pstring ret; + char *result; int i; - + for (i=0;err_classes[i].e_class;i++) { if (err_classes[i].code == e_class) { return err_classes[i].e_class; } } - - slprintf(ret, sizeof(ret) - 1, "Error: Unknown class (%d)",e_class); - return(ret); + + result = talloc_asprintf(talloc_tos(), "Error: Unknown class (%d)", + e_class); + SMB_ASSERT(result != NULL); + return result; } /**************************************************************************** @@ -214,11 +219,11 @@ return a SMB string from an SMB buffer ****************************************************************************/ char *smb_dos_errstr(char *inbuf) { - static pstring ret; + char *result; int e_class = CVAL(inbuf,smb_rcls); int num = SVAL(inbuf,smb_err); int i,j; - + for (i=0;err_classes[i].e_class;i++) if (err_classes[i].code == e_class) { if (err_classes[i].err_msgs) { @@ -226,22 +231,29 @@ char *smb_dos_errstr(char *inbuf) for (j=0;err[j].name;j++) if (num == err[j].code) { if (DEBUGLEVEL > 0) - slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)", - err_classes[i].e_class, - err[j].name,err[j].message); + result = talloc_asprintf( + talloc_tos(), "%s - %s (%s)", + err_classes[i].e_class, + err[j].name,err[j].message); else - slprintf(ret, sizeof(ret) - 1, "%s - %s", - err_classes[i].e_class,err[j].name); - return ret; + result = talloc_asprintf( + talloc_tos(), "%s - %s", + err_classes[i].e_class, + err[j].name); + goto done; } } - - slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].e_class,num); - return ret; + + result = talloc_asprintf(talloc_tos(), "%s - %d", + err_classes[i].e_class, num); + goto done; } - - slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",e_class,num); - return(ret); + + result = talloc_asprintf(talloc_tos(), "Error: Unknown error (%d,%d)", + e_class, num); + done: + SMB_ASSERT(result != NULL); + return result; } /***************************************************************************** -- cgit From 79266500cd3f84c74b2f89ceeb15c23cedacc2b5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 12 Nov 2007 15:02:50 -0800 Subject: Remove all pstrings from smbd/chgpasswd.c. Jeremy. (This used to be commit eaf14c701b08e9eff5b94bf57af68cb29142d7fc) --- source3/libsmb/smbencrypt.c | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 20eddff722..77ff063cb9 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -522,12 +522,17 @@ bool encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags) returned password including termination. ************************************************************/ -bool decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, - int new_pwrd_size, uint32 *new_pw_len, - int string_flags) +bool decode_pw_buffer(TALLOC_CTX *ctx, + uint8 in_buffer[516], + char **pp_new_pwrd, + uint32 *new_pw_len, + int string_flags) { int byte_len=0; + *pp_new_pwrd = NULL; + *new_pw_len = 0; + /* the incoming buffer can be any alignment. */ string_flags |= STR_NOALIGN; @@ -550,22 +555,31 @@ bool decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd, if ( (byte_len < 0) || (byte_len > 512)) { DEBUG(0, ("decode_pw_buffer: incorrect password length (%d).\n", byte_len)); DEBUG(0, ("decode_pw_buffer: check that 'encrypt passwords = yes'\n")); - return False; + return false; } - /* decode into the return buffer. Buffer length supplied */ - *new_pw_len = pull_string(NULL, 0, new_pwrd, - &in_buffer[512 - byte_len], new_pwrd_size, - byte_len, string_flags); + /* decode into the return buffer. */ + *new_pw_len = pull_string_talloc(ctx, + NULL, + 0, + pp_new_pwrd, + &in_buffer[512 - byte_len], + byte_len, + string_flags); + + if (!*pp_new_pwrd || *new_pw_len == 0) { + DEBUG(0, ("decode_pw_buffer: pull_string_talloc failed\n")); + return false; + } #ifdef DEBUG_PASSWORD DEBUG(100,("decode_pw_buffer: new_pwrd: ")); - dump_data(100, (uint8 *)new_pwrd, *new_pw_len); + dump_data(100, (uint8 *)*pp_new_pwrd, *new_pw_len); DEBUG(100,("multibyte len:%d\n", *new_pw_len)); DEBUG(100,("original char len:%d\n", byte_len/2)); #endif - - return True; + + return true; } /*********************************************************** -- cgit From 68be9a820059ee96dd26c527efd7c14e679d3f2c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Nov 2007 14:19:52 -0800 Subject: More pstring removal. This one was tricky. I had to add one horror (pstring_clean_name()) which will have to remain until I've removed all pstrings from the client code. Jeremy. (This used to be commit 1ea3ac80146b83c2522b69e7747c823366a2b47d) --- source3/libsmb/clidfs.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 6393f654c0..037c0d6b26 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -208,8 +208,12 @@ static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) } if ( p ) { - pstrcpy( p->mount, mnt ); - clean_name(p->mount); + char *name = clean_name(NULL, p->mount); + if (!name) { + return; + } + pstrcpy( p->mount, name ); + TALLOC_FREE(name); } } -- cgit From 9a41314ce8582875e0ec59efb670279f39b42ce3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Nov 2007 15:15:09 -0800 Subject: Remove pstring from nmbd. Jeremy. (This used to be commit a317f70c229f7730279eaa323f7ebfd499257f76) --- source3/libsmb/namequery.c | 46 ++++++++++++++++++++++++++++++++++------------ 1 file changed, 34 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index dde758b41c..f4f9f84b00 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -783,20 +783,25 @@ XFILE *startlmhosts(const char *fname) Parse the next line in the lmhosts file. *********************************************************/ -bool getlmhostsent(XFILE *fp, pstring name, int *name_type, +bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, struct sockaddr_storage *pss) { - pstring line; + char line[1024]; + + *pp_name = NULL; while(!x_feof(fp) && !x_ferror(fp)) { - pstring ip,flags,extra; + char ip[INET6_ADDRSTRLEN]; + fstring flags; + fstring extra; + fstring name; const char *ptr; char *ptr1; int count = 0; *name_type = -1; - if (!fgets_slash(line,sizeof(pstring),fp)) { + if (!fgets_slash(line,sizeof(line),fp)) { continue; } @@ -804,15 +809,15 @@ bool getlmhostsent(XFILE *fp, pstring name, int *name_type, continue; } - pstrcpy(ip,""); - pstrcpy(name,""); - pstrcpy(flags,""); + ip[0] = '\0'; + name[0] = '\0'; + flags[0] = '\0'; ptr = line; if (next_token(&ptr,ip ,NULL,sizeof(ip))) ++count; - if (next_token(&ptr,name ,NULL, sizeof(pstring))) + if (next_token(&ptr,name ,NULL, sizeof(name))) ++count; if (next_token(&ptr,flags,NULL, sizeof(flags))) ++count; @@ -864,6 +869,10 @@ bool getlmhostsent(XFILE *fp, pstring name, int *name_type, *(--ptr1) = '\0'; /* Truncate at the '#' */ } + *pp_name = talloc_strdup(ctx, name); + if (!*pp_name) { + return false; + } return true; } @@ -1135,10 +1144,11 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, */ XFILE *fp; - pstring lmhost_name; + char *lmhost_name = NULL; int name_type2; struct sockaddr_storage return_ss; NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + TALLOC_CTX *ctx = NULL; *return_iplist = NULL; *return_count = 0; @@ -1152,19 +1162,30 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, if ( fp == NULL ) return NT_STATUS_NO_SUCH_FILE; - while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ss)) { + ctx = talloc_init("resolve_lmhosts"); + if (!ctx) { + endlmhosts(fp); + return NT_STATUS_NO_MEMORY; + } + + while (getlmhostsent(ctx, fp, &lmhost_name, &name_type2, &return_ss)) { - if (!strequal(name, lmhost_name)) + if (!strequal(name, lmhost_name)) { + TALLOC_FREE(lmhost_name); continue; + } - if ((name_type2 != -1) && (name_type != name_type2)) + if ((name_type2 != -1) && (name_type != name_type2)) { + TALLOC_FREE(lmhost_name); continue; + } *return_iplist = SMB_REALLOC_ARRAY((*return_iplist), struct ip_service, (*return_count)+1); if ((*return_iplist) == NULL) { + TALLOC_FREE(ctx); endlmhosts(fp); DEBUG(3,("resolve_lmhosts: malloc fail !\n")); return NT_STATUS_NO_MEMORY; @@ -1182,6 +1203,7 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, break; } + TALLOC_FREE(ctx); endlmhosts(fp); return status; } -- cgit From 428e663100fa2c009b16941e2a390587fdfc00b5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 19 Nov 2007 12:36:16 +0100 Subject: Add stackframes to public libsmbclient functions As we use talloc_tos() in inner libsmbclient/ functions more and more, we need to make sure not to create memleaks by not free'ing talloc stackframes. This patch wraps all calls in libsmbclient.c that are publically exported into a talloc_stackframe()/talloc_free() pair. Jeremy, Derrell, can you check this? Thanks, Volker (This used to be commit db9fa472a89eb78a7b1f7cabcf195331c3b448d9) --- source3/libsmb/libsmbclient.c | 309 +++++++++++++++++++++++++++++++++--------- 1 file changed, 245 insertions(+), 64 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index dbc51d168e..ee560b65c3 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1060,11 +1060,13 @@ smbc_open_ctx(SMBCCTX *context, SMBCSRV *srv = NULL; SMBCFILE *file = NULL; int fd; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return NULL; } @@ -1072,6 +1074,7 @@ smbc_open_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return NULL; } @@ -1085,6 +1088,7 @@ smbc_open_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return NULL; } @@ -1096,6 +1100,7 @@ smbc_open_ctx(SMBCCTX *context, if (!srv) { if (errno == EPERM) errno = EACCES; + TALLOC_FREE(frame); return NULL; /* smbc_server sets errno */ } @@ -1114,6 +1119,7 @@ smbc_open_ctx(SMBCCTX *context, if (!file) { errno = ENOMEM; + TALLOC_FREE(frame); return NULL; } @@ -1125,6 +1131,7 @@ smbc_open_ctx(SMBCCTX *context, { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); + TALLOC_FREE(frame); return NULL; } /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ @@ -1136,6 +1143,7 @@ smbc_open_ctx(SMBCCTX *context, SAFE_FREE(file); errno = smbc_errno(context, targetcli); + TALLOC_FREE(frame); return NULL; } @@ -1176,10 +1184,12 @@ smbc_open_ctx(SMBCCTX *context, if (smbc_lseek_ctx(context, file, 0, SEEK_END) < 0) { (void) smbc_close_ctx(context, file); errno = ENXIO; + TALLOC_FREE(frame); return NULL; } } + TALLOC_FREE(frame); return file; } @@ -1192,11 +1202,13 @@ smbc_open_ctx(SMBCCTX *context, eno = smbc_errno(context, srv->cli); file = (context->opendir)(context, fname); if (!file) errno = eno; + TALLOC_FREE(frame); return file; } errno = EINVAL; /* FIXME, correct errno ? */ + TALLOC_FREE(frame); return NULL; } @@ -1238,6 +1250,7 @@ smbc_read_ctx(SMBCCTX *context, fstring server, share, user, password; pstring path, targetpath; struct cli_state *targetcli; + TALLOC_CTX *frame = talloc_stackframe(); /* * offset: @@ -1254,6 +1267,7 @@ smbc_read_ctx(SMBCCTX *context, !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1263,6 +1277,7 @@ smbc_read_ctx(SMBCCTX *context, if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; + TALLOC_FREE(frame); return -1; } @@ -1274,6 +1289,7 @@ smbc_read_ctx(SMBCCTX *context, if (buf == NULL) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1288,6 +1304,7 @@ smbc_read_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1296,6 +1313,7 @@ smbc_read_ctx(SMBCCTX *context, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ @@ -1305,6 +1323,7 @@ smbc_read_ctx(SMBCCTX *context, if (ret < 0) { errno = smbc_errno(context, targetcli); + TALLOC_FREE(frame); return -1; } @@ -1313,6 +1332,7 @@ smbc_read_ctx(SMBCCTX *context, DEBUG(4, (" --> %d\n", ret)); + TALLOC_FREE(frame); return ret; /* Success, ret bytes of data ... */ } @@ -1332,6 +1352,7 @@ smbc_write_ctx(SMBCCTX *context, fstring server, share, user, password; pstring path, targetpath; struct cli_state *targetcli; + TALLOC_CTX *frame = talloc_stackframe(); /* First check all pointers before dereferencing them */ @@ -1339,6 +1360,7 @@ smbc_write_ctx(SMBCCTX *context, !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1346,6 +1368,7 @@ smbc_write_ctx(SMBCCTX *context, if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; + TALLOC_FREE(frame); return -1; } @@ -1355,6 +1378,7 @@ smbc_write_ctx(SMBCCTX *context, if (buf == NULL) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1371,6 +1395,7 @@ smbc_write_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1379,6 +1404,7 @@ smbc_write_ctx(SMBCCTX *context, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ @@ -1389,12 +1415,14 @@ smbc_write_ctx(SMBCCTX *context, if (ret <= 0) { errno = smbc_errno(context, targetcli); + TALLOC_FREE(frame); return -1; } file->offset += ret; + TALLOC_FREE(frame); return ret; /* Success, 0 bytes of data ... */ } @@ -1410,11 +1438,13 @@ smbc_close_ctx(SMBCCTX *context, fstring server, share, user, password; pstring path, targetpath; struct cli_state *targetcli; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1422,6 +1452,7 @@ smbc_close_ctx(SMBCCTX *context, if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; + TALLOC_FREE(frame); return -1; } @@ -1429,6 +1460,7 @@ smbc_close_ctx(SMBCCTX *context, /* IS a dir ... */ if (!file->file) { + TALLOC_FREE(frame); return (context->closedir)(context, file); } @@ -1443,6 +1475,7 @@ smbc_close_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1451,6 +1484,7 @@ smbc_close_ctx(SMBCCTX *context, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ @@ -1467,7 +1501,7 @@ smbc_close_ctx(SMBCCTX *context, SAFE_FREE(file->fname); SAFE_FREE(file); (context->callbacks.remove_unused_server_fn)(context, srv); - + TALLOC_FREE(frame); return -1; } @@ -1475,6 +1509,7 @@ smbc_close_ctx(SMBCCTX *context, DLIST_REMOVE(context->internal->_files, file); SAFE_FREE(file->fname); SAFE_FREE(file); + TALLOC_FREE(frame); return 0; } @@ -1499,11 +1534,13 @@ smbc_getatr(SMBCCTX * context, pstring targetpath; struct cli_state *targetcli; time_t write_time; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1522,6 +1559,7 @@ smbc_getatr(SMBCCTX * context, if (!cli_resolve_path( "", srv->cli, fixedpath, &targetcli, targetpath)) { d_printf("Couldn't resolve %s\n", path); + TALLOC_FREE(frame); return False; } @@ -1532,12 +1570,14 @@ smbc_getatr(SMBCCTX * context, write_time_ts, change_time_ts, size, mode, ino)) { - return True; + TALLOC_FREE(frame); + return True; } /* if this is NT then don't bother with the getatr */ if (targetcli->capabilities & CAP_NT_SMBS) { errno = EPERM; + TALLOC_FREE(frame); return False; } @@ -1564,10 +1604,12 @@ smbc_getatr(SMBCCTX * context, } srv->no_pathinfo2 = True; + TALLOC_FREE(frame); return True; } errno = EPERM; + TALLOC_FREE(frame); return False; } @@ -1592,6 +1634,7 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, { int fd; int ret; + TALLOC_CTX *frame = talloc_stackframe(); /* * First, try setpathinfo (if qpathinfo succeeded), for it is the @@ -1624,6 +1667,7 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { errno = smbc_errno(context, srv->cli); + TALLOC_FREE(frame); return -1; } @@ -1648,10 +1692,12 @@ smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, if (! ret) { errno = smbc_errno(context, srv->cli); + TALLOC_FREE(frame); return False; } } + TALLOC_FREE(frame); return True; } @@ -1667,11 +1713,13 @@ smbc_unlink_ctx(SMBCCTX *context, pstring path, targetpath; struct cli_state *targetcli; SMBCSRV *srv = NULL; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return -1; } @@ -1679,6 +1727,7 @@ smbc_unlink_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1692,6 +1741,7 @@ smbc_unlink_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1702,6 +1752,7 @@ smbc_unlink_ctx(SMBCCTX *context, if (!srv) { + TALLOC_FREE(frame); return -1; /* smbc_server sets errno */ } @@ -1710,6 +1761,7 @@ smbc_unlink_ctx(SMBCCTX *context, if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ @@ -1738,6 +1790,7 @@ smbc_unlink_ctx(SMBCCTX *context, /* Hmmm, bad error ... What? */ errno = smbc_errno(context, targetcli); + TALLOC_FREE(frame); return -1; } @@ -1751,10 +1804,12 @@ smbc_unlink_ctx(SMBCCTX *context, } } + TALLOC_FREE(frame); return -1; } + TALLOC_FREE(frame); return 0; /* Success ... */ } @@ -1785,6 +1840,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, struct cli_state *targetcli1; struct cli_state *targetcli2; SMBCSRV *srv = NULL; + TALLOC_CTX *frame = talloc_stackframe(); if (!ocontext || !ncontext || !ocontext->internal || !ncontext->internal || @@ -1792,6 +1848,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, !ncontext->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return -1; } @@ -1799,6 +1856,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, if (!oname || !nname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1833,6 +1891,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, /* Can't rename across file systems, or users?? */ errno = EXDEV; + TALLOC_FREE(frame); return -1; } @@ -1841,6 +1900,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, server1, share1, workgroup, user1, password1); if (!srv) { + TALLOC_FREE(frame); return -1; } @@ -1849,6 +1909,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, if (!cli_resolve_path( "", srv->cli, path1, &targetcli1, targetpath1)) { d_printf("Could not resolve %s\n", path1); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ @@ -1856,6 +1917,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, if (!cli_resolve_path( "", srv->cli, path2, &targetcli2, targetpath2)) { d_printf("Could not resolve %s\n", path2); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ @@ -1866,6 +1928,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, /* can't rename across file systems */ errno = EXDEV; + TALLOC_FREE(frame); return -1; } @@ -1877,13 +1940,14 @@ smbc_rename_ctx(SMBCCTX *ocontext, !cli_rename(targetcli1, targetpath1, targetpath2)) { errno = eno; + TALLOC_FREE(frame); return -1; } } + TALLOC_FREE(frame); return 0; /* Success */ - } /* @@ -1900,11 +1964,13 @@ smbc_lseek_ctx(SMBCCTX *context, fstring server, share, user, password; pstring path, targetpath; struct cli_state *targetcli; + TALLOC_CTX *frame = talloc_tos(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1912,6 +1978,7 @@ smbc_lseek_ctx(SMBCCTX *context, if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; + TALLOC_FREE(frame); return -1; } @@ -1919,6 +1986,7 @@ smbc_lseek_ctx(SMBCCTX *context, if (!file->file) { errno = EINVAL; + TALLOC_FREE(frame); return -1; /* Can't lseek a dir ... */ } @@ -1944,6 +2012,7 @@ smbc_lseek_ctx(SMBCCTX *context, NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -1952,6 +2021,7 @@ smbc_lseek_ctx(SMBCCTX *context, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ @@ -1964,6 +2034,7 @@ smbc_lseek_ctx(SMBCCTX *context, NULL, &b_size, NULL, NULL, NULL)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } else size = b_size; @@ -1977,6 +2048,7 @@ smbc_lseek_ctx(SMBCCTX *context, } + TALLOC_FREE(frame); return file->offset; } @@ -1989,7 +2061,6 @@ static ino_t smbc_inode(SMBCCTX *context, const char *name) { - if (!context || !context->internal || !context->internal->_initialized) { @@ -2015,6 +2086,7 @@ smbc_setup_stat(SMBCCTX *context, SMB_OFF_T size, int mode) { + TALLOC_CTX *frame = talloc_stackframe(); st->st_mode = 0; @@ -2049,6 +2121,7 @@ smbc_setup_stat(SMBCCTX *context, st->st_ino = smbc_inode(context, fname); } + TALLOC_FREE(frame); return True; /* FIXME: Is this needed ? */ } @@ -2075,11 +2148,13 @@ smbc_stat_ctx(SMBCCTX *context, SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return -1; } @@ -2087,6 +2162,7 @@ smbc_stat_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -2102,6 +2178,7 @@ smbc_stat_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -2111,6 +2188,7 @@ smbc_stat_ctx(SMBCCTX *context, server, share, workgroup, user, password); if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -2122,6 +2200,7 @@ smbc_stat_ctx(SMBCCTX *context, &ino)) { errno = smbc_errno(context, srv->cli); + TALLOC_FREE(frame); return -1; } @@ -2135,6 +2214,7 @@ smbc_stat_ctx(SMBCCTX *context, set_mtimespec(st, write_time_ts); st->st_dev = srv->dev; + TALLOC_FREE(frame); return 0; } @@ -2161,11 +2241,13 @@ smbc_fstat_ctx(SMBCCTX *context, pstring targetpath; struct cli_state *targetcli; SMB_INO_T ino = 0; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -2173,12 +2255,14 @@ smbc_fstat_ctx(SMBCCTX *context, if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; + TALLOC_FREE(frame); return -1; } if (!file->file) { + TALLOC_FREE(frame); return (context->fstatdir)(context, file, st); } @@ -2193,6 +2277,7 @@ smbc_fstat_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -2201,6 +2286,7 @@ smbc_fstat_ctx(SMBCCTX *context, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ @@ -2218,6 +2304,7 @@ smbc_fstat_ctx(SMBCCTX *context, &change_time, &access_time, &write_time)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -2235,6 +2322,7 @@ smbc_fstat_ctx(SMBCCTX *context, set_mtimespec(st, write_time_ts); st->st_dev = file->srv->dev; + TALLOC_FREE(frame); return 0; } @@ -2481,7 +2569,6 @@ net_share_enum_rpc(struct cli_state *cli, SRV_SHARE_INFO_CTR ctr; fstring name = ""; fstring comment = ""; - void *mem_ctx; struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; @@ -2492,18 +2579,10 @@ net_share_enum_rpc(struct cli_state *cli, return -1; } - /* Allocate a context for parsing and for the entries in "ctr" */ - mem_ctx = talloc_init("libsmbclient: net_share_enum_rpc"); - if (mem_ctx == NULL) { - DEBUG(0, ("out of memory for net_share_enum_rpc!\n")); - cli_rpc_pipe_close(pipe_hnd); - return -1; - } - /* Issue the NetShareEnum RPC call and retrieve the response */ init_enum_hnd(&enum_hnd, 0); result = rpccli_srvsvc_net_share_enum(pipe_hnd, - mem_ctx, + talloc_tos(), info_level, &ctr, preferred_len, @@ -2537,9 +2616,6 @@ done: /* Close the server service pipe */ cli_rpc_pipe_close(pipe_hnd); - /* Free all memory which was allocated for this request */ - TALLOC_FREE(mem_ctx); - /* Tell 'em if it worked */ return W_ERROR_IS_OK(result) ? 0 : -1; } @@ -2560,11 +2636,13 @@ smbc_opendir_ctx(SMBCCTX *context, SMBCFILE *dir = NULL; struct _smbc_callbacks *cb; struct sockaddr_storage rem_ss; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { DEBUG(4, ("no valid context\n")); errno = EINVAL + 8192; + TALLOC_FREE(frame); return NULL; } @@ -2572,6 +2650,7 @@ smbc_opendir_ctx(SMBCCTX *context, if (!fname) { DEBUG(4, ("no valid fname\n")); errno = EINVAL + 8193; + TALLOC_FREE(frame); return NULL; } @@ -2585,6 +2664,7 @@ smbc_opendir_ctx(SMBCCTX *context, options, sizeof(options))) { DEBUG(4, ("no valid path\n")); errno = EINVAL + 8194; + TALLOC_FREE(frame); return NULL; } @@ -2596,6 +2676,7 @@ smbc_opendir_ctx(SMBCCTX *context, if (smbc_check_options(server, share, path, options)) { DEBUG(4, ("unacceptable options (%s)\n", options)); errno = EINVAL + 8195; + TALLOC_FREE(frame); return NULL; } @@ -2605,6 +2686,7 @@ smbc_opendir_ctx(SMBCCTX *context, if (!dir) { errno = ENOMEM; + TALLOC_FREE(frame); return NULL; } @@ -2634,6 +2716,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } @@ -2668,6 +2751,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir); } errno = ENOENT; + TALLOC_FREE(frame); return NULL; } @@ -2675,6 +2759,7 @@ smbc_opendir_ctx(SMBCCTX *context, &server_addr, sizeof(server_addr)); if (ip_list == NULL) { errno = ENOMEM; + TALLOC_FREE(frame); return NULL; } count = 1; @@ -2742,6 +2827,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } @@ -2790,6 +2876,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir); } errno = EPERM; + TALLOC_FREE(frame); return NULL; } @@ -2807,6 +2894,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } @@ -2822,6 +2910,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } } else if (srv || @@ -2840,6 +2929,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } @@ -2863,6 +2953,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } @@ -2873,6 +2964,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } @@ -2897,6 +2989,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } @@ -2916,6 +3009,7 @@ smbc_opendir_ctx(SMBCCTX *context, SAFE_FREE(dir->fname); SAFE_FREE(dir); } + TALLOC_FREE(frame); return NULL; } @@ -2974,6 +3068,7 @@ smbc_opendir_ctx(SMBCCTX *context, } errno = saved_errno; + TALLOC_FREE(frame); return NULL; } } @@ -2981,6 +3076,7 @@ smbc_opendir_ctx(SMBCCTX *context, } DLIST_ADD(context->internal->_files, dir); + TALLOC_FREE(frame); return dir; } @@ -2993,11 +3089,13 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { + TALLOC_CTX *frame = talloc_tos(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3005,6 +3103,7 @@ smbc_closedir_ctx(SMBCCTX *context, if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; + TALLOC_FREE(frame); return -1; } @@ -3019,6 +3118,7 @@ smbc_closedir_ctx(SMBCCTX *context, SAFE_FREE(dir); /* Free the space too */ } + TALLOC_FREE(frame); return 0; } @@ -3069,6 +3169,7 @@ smbc_readdir_ctx(SMBCCTX *context, { int maxlen; struct smbc_dirent *dirp, *dirent; + TALLOC_CTX *frame = talloc_stackframe(); /* Check that all is ok first ... */ @@ -3077,6 +3178,7 @@ smbc_readdir_ctx(SMBCCTX *context, errno = EINVAL; DEBUG(0, ("Invalid context in smbc_readdir_ctx()\n")); + TALLOC_FREE(frame); return NULL; } @@ -3085,6 +3187,7 @@ smbc_readdir_ctx(SMBCCTX *context, errno = EBADF; DEBUG(0, ("Invalid dir in smbc_readdir_ctx()\n")); + TALLOC_FREE(frame); return NULL; } @@ -3093,11 +3196,13 @@ smbc_readdir_ctx(SMBCCTX *context, errno = ENOTDIR; DEBUG(0, ("Found file vs directory in smbc_readdir_ctx()\n")); + TALLOC_FREE(frame); return NULL; } if (!dir->dir_next) { + TALLOC_FREE(frame); return NULL; } @@ -3105,6 +3210,7 @@ smbc_readdir_ctx(SMBCCTX *context, if (!dirent) { errno = ENOENT; + TALLOC_FREE(frame); return NULL; } @@ -3117,6 +3223,7 @@ smbc_readdir_ctx(SMBCCTX *context, dir->dir_next = dir->dir_next->next; + TALLOC_FREE(frame); return dirp; } @@ -3135,6 +3242,7 @@ smbc_getdents_ctx(SMBCCTX *context, int maxlen; char *ndir = (char *)dirp; struct smbc_dir_list *dirlist; + TALLOC_CTX *frame = talloc_stackframe(); /* Check that all is ok first ... */ @@ -3142,6 +3250,7 @@ smbc_getdents_ctx(SMBCCTX *context, !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3149,6 +3258,7 @@ smbc_getdents_ctx(SMBCCTX *context, if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; + TALLOC_FREE(frame); return -1; } @@ -3156,6 +3266,7 @@ smbc_getdents_ctx(SMBCCTX *context, if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; + TALLOC_FREE(frame); return -1; } @@ -3172,6 +3283,7 @@ smbc_getdents_ctx(SMBCCTX *context, if (!dirlist->dirent) { errno = ENOENT; /* Bad error */ + TALLOC_FREE(frame); return -1; } @@ -3189,12 +3301,14 @@ smbc_getdents_ctx(SMBCCTX *context, if (rem < count) { /* We managed to copy something */ errno = 0; + TALLOC_FREE(frame); return count - rem; } else { /* Nothing copied ... */ errno = EINVAL; /* Not enough space ... */ + TALLOC_FREE(frame); return -1; } @@ -3215,6 +3329,8 @@ smbc_getdents_ctx(SMBCCTX *context, dir->dir_next = dirlist = dirlist -> next; } + TALLOC_FREE(frame); + if (rem == count) return 0; else @@ -3239,11 +3355,13 @@ smbc_mkdir_ctx(SMBCCTX *context, fstring workgroup; pstring path, targetpath; struct cli_state *targetcli; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3251,6 +3369,7 @@ smbc_mkdir_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3266,6 +3385,7 @@ smbc_mkdir_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3276,6 +3396,7 @@ smbc_mkdir_ctx(SMBCCTX *context, if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -3284,6 +3405,7 @@ smbc_mkdir_ctx(SMBCCTX *context, if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ @@ -3291,10 +3413,12 @@ smbc_mkdir_ctx(SMBCCTX *context, if (!cli_mkdir(targetcli, targetpath)) { errno = smbc_errno(context, targetcli); + TALLOC_FREE(frame); return -1; } + TALLOC_FREE(frame); return 0; } @@ -3335,11 +3459,13 @@ smbc_rmdir_ctx(SMBCCTX *context, pstring path; pstring targetpath; struct cli_state *targetcli; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3347,6 +3473,7 @@ smbc_rmdir_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3363,6 +3490,7 @@ smbc_rmdir_ctx(SMBCCTX *context, NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3373,6 +3501,7 @@ smbc_rmdir_ctx(SMBCCTX *context, if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -3381,6 +3510,7 @@ smbc_rmdir_ctx(SMBCCTX *context, if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) { d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); return -1; } /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ @@ -3419,10 +3549,12 @@ smbc_rmdir_ctx(SMBCCTX *context, } + TALLOC_FREE(frame); return -1; } + TALLOC_FREE(frame); return 0; } @@ -3435,10 +3567,13 @@ static off_t smbc_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { + TALLOC_CTX *frame = talloc_stackframe(); + if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3446,6 +3581,7 @@ smbc_telldir_ctx(SMBCCTX *context, if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { errno = EBADF; + TALLOC_FREE(frame); return -1; } @@ -3453,6 +3589,7 @@ smbc_telldir_ctx(SMBCCTX *context, if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; + TALLOC_FREE(frame); return -1; } @@ -3460,12 +3597,14 @@ smbc_telldir_ctx(SMBCCTX *context, /* See if we're already at the end. */ if (dir->dir_next == NULL) { /* We are. */ + TALLOC_FREE(frame); return -1; } /* * We return the pointer here as the offset */ + TALLOC_FREE(frame); return (off_t)(long)dir->dir_next->dirent; } @@ -3512,11 +3651,13 @@ smbc_lseekdir_ctx(SMBCCTX *context, long int l_offset = offset; /* Handle problems of size */ struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3524,6 +3665,7 @@ smbc_lseekdir_ctx(SMBCCTX *context, if (dir->file != False) { /* FIXME, should be dir, perhaps */ errno = ENOTDIR; + TALLOC_FREE(frame); return -1; } @@ -3533,12 +3675,14 @@ smbc_lseekdir_ctx(SMBCCTX *context, if (dirent == NULL) { /* Seek to the begining of the list */ dir->dir_next = dir->dir_list; + TALLOC_FREE(frame); return 0; } if (offset == -1) { /* Seek to the end of the list */ dir->dir_next = NULL; + TALLOC_FREE(frame); return 0; } @@ -3548,12 +3692,14 @@ smbc_lseekdir_ctx(SMBCCTX *context, if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) { errno = EINVAL; /* Bad entry */ + TALLOC_FREE(frame); return -1; } dir->dir_next = list_ent; + TALLOC_FREE(frame); return 0; } @@ -3595,11 +3741,13 @@ smbc_chmod_ctx(SMBCCTX *context, fstring workgroup; pstring path; uint16 mode; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return -1; } @@ -3607,6 +3755,7 @@ smbc_chmod_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3622,6 +3771,7 @@ smbc_chmod_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3631,6 +3781,7 @@ smbc_chmod_ctx(SMBCCTX *context, server, share, workgroup, user, password); if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -3643,9 +3794,11 @@ smbc_chmod_ctx(SMBCCTX *context, if (!cli_setatr(srv->cli, path, mode, 0)) { errno = smbc_errno(context, srv->cli); + TALLOC_FREE(frame); return -1; } + TALLOC_FREE(frame); return 0; } @@ -3663,11 +3816,13 @@ smbc_utimes_ctx(SMBCCTX *context, pstring path; time_t access_time; time_t write_time; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return -1; } @@ -3675,6 +3830,7 @@ smbc_utimes_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3717,6 +3873,7 @@ smbc_utimes_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -3726,14 +3883,17 @@ smbc_utimes_ctx(SMBCCTX *context, server, share, workgroup, user, password); if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } if (!smbc_setatr(context, srv, path, 0, access_time, write_time, 0, 0)) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_setatr */ } + TALLOC_FREE(frame); return 0; } @@ -5340,7 +5500,6 @@ smbc_setxattr_ctx(SMBCCTX *context, fstring password; fstring workgroup; pstring path; - TALLOC_CTX *ctx; POLICY_HND pol; DOS_ATTR_DESC *dad; struct { @@ -5349,11 +5508,13 @@ smbc_setxattr_ctx(SMBCCTX *context, const char * write_time_attr; const char * change_time_attr; } attr_strings; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return -1; } @@ -5361,6 +5522,7 @@ smbc_setxattr_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5377,6 +5539,7 @@ smbc_setxattr_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5385,6 +5548,7 @@ smbc_setxattr_ctx(SMBCCTX *context, srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -5399,12 +5563,6 @@ smbc_setxattr_ctx(SMBCCTX *context, ipc_srv = NULL; } - ctx = talloc_init("smbc_setxattr"); - if (!ctx) { - errno = ENOMEM; - return -1; - } - /* * Are they asking to set the entire set of known attributes? */ @@ -5412,16 +5570,17 @@ smbc_setxattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.*+") == 0) { /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", + talloc_asprintf(talloc_tos(), "%s:%s", name+7, (const char *) value); if (! namevalue) { errno = ENOMEM; ret = -1; + TALLOC_FREE(frame); return -1; } if (ipc_srv) { - ret = cacl_set(ctx, srv->cli, + ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &pol, path, namevalue, (*namevalue == '*' @@ -5433,7 +5592,7 @@ smbc_setxattr_ctx(SMBCCTX *context, } /* get a DOS Attribute Descriptor with current attributes */ - dad = dos_attr_query(context, ctx, path, srv); + dad = dos_attr_query(context, talloc_tos(), path, srv); if (dad) { /* Overwrite old with new, using what was provided */ dos_attr_parse(context, dad, srv, namevalue); @@ -5459,7 +5618,7 @@ smbc_setxattr_ctx(SMBCCTX *context, ret = 0; } - talloc_destroy(ctx); + TALLOC_FREE(frame); return ret; } @@ -5475,7 +5634,7 @@ smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", + talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); if (! ipc_srv) { @@ -5485,7 +5644,7 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, srv->cli, + ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &pol, path, namevalue, (*namevalue == '*' @@ -5493,7 +5652,7 @@ smbc_setxattr_ctx(SMBCCTX *context, : SMBC_XATTR_MODE_ADD), flags); } - talloc_destroy(ctx); + TALLOC_FREE(frame); return ret; } @@ -5505,7 +5664,7 @@ smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", + talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); if (! ipc_srv) { @@ -5516,11 +5675,11 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, srv->cli, + ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } - talloc_destroy(ctx); + TALLOC_FREE(frame); return ret; } @@ -5532,7 +5691,7 @@ smbc_setxattr_ctx(SMBCCTX *context, /* Yup. */ char *namevalue = - talloc_asprintf(ctx, "%s:%s", + talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); if (! ipc_srv) { @@ -5543,11 +5702,11 @@ smbc_setxattr_ctx(SMBCCTX *context, errno = ENOMEM; ret = -1; } else { - ret = cacl_set(ctx, srv->cli, + ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } - talloc_destroy(ctx); + TALLOC_FREE(frame); return ret; } @@ -5578,10 +5737,10 @@ smbc_setxattr_ctx(SMBCCTX *context, StrCaseCmp(name, attr_strings.change_time_attr) == 0) { /* get a DOS Attribute Descriptor with current attributes */ - dad = dos_attr_query(context, ctx, path, srv); + dad = dos_attr_query(context, talloc_tos(), path, srv); if (dad) { char *namevalue = - talloc_asprintf(ctx, "%s:%s", + talloc_asprintf(talloc_tos(), "%s:%s", name+16, (const char *) value); if (! namevalue) { errno = ENOMEM; @@ -5609,13 +5768,13 @@ smbc_setxattr_ctx(SMBCCTX *context, ret = -1; } - talloc_destroy(ctx); + TALLOC_FREE(frame); return ret; } /* Unsupported attribute name */ - talloc_destroy(ctx); errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5635,7 +5794,6 @@ smbc_getxattr_ctx(SMBCCTX *context, fstring password; fstring workgroup; pstring path; - TALLOC_CTX *ctx; POLICY_HND pol; struct { const char * create_time_attr; @@ -5643,12 +5801,13 @@ smbc_getxattr_ctx(SMBCCTX *context, const char * write_time_attr; const char * change_time_attr; } attr_strings; - + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return -1; } @@ -5656,6 +5815,7 @@ smbc_getxattr_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5671,6 +5831,7 @@ smbc_getxattr_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5679,6 +5840,7 @@ smbc_getxattr_ctx(SMBCCTX *context, srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -5693,12 +5855,6 @@ smbc_getxattr_ctx(SMBCCTX *context, ipc_srv = NULL; } - ctx = talloc_init("smbc:getxattr"); - if (!ctx) { - errno = ENOMEM; - return -1; - } - /* Determine whether to use old-style or new-style attribute names */ if (context->internal->_full_time_names) { /* new-style names */ @@ -5742,7 +5898,7 @@ smbc_getxattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.dos_attr.inode") == 0) { /* Yup. */ - ret = cacl_get(context, ctx, srv, + ret = cacl_get(context, talloc_tos(), srv, ipc_srv == NULL ? NULL : ipc_srv->cli, &pol, path, CONST_DISCARD(char *, name), @@ -5750,13 +5906,13 @@ smbc_getxattr_ctx(SMBCCTX *context, if (ret < 0 && errno == 0) { errno = smbc_errno(context, srv->cli); } - talloc_destroy(ctx); + TALLOC_FREE(frame); return ret; } /* Unsupported attribute name */ - talloc_destroy(ctx); errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5775,13 +5931,14 @@ smbc_removexattr_ctx(SMBCCTX *context, fstring password; fstring workgroup; pstring path; - TALLOC_CTX *ctx; POLICY_HND pol; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); return -1; } @@ -5789,6 +5946,7 @@ smbc_removexattr_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5804,6 +5962,7 @@ smbc_removexattr_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5812,6 +5971,7 @@ smbc_removexattr_ctx(SMBCCTX *context, srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -5827,24 +5987,19 @@ smbc_removexattr_ctx(SMBCCTX *context, } if (! ipc_srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_attr_server */ } - ctx = talloc_init("smbc_removexattr"); - if (!ctx) { - errno = ENOMEM; - return -1; - } - /* Are they asking to set the entire ACL? */ if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { /* Yup. */ - ret = cacl_set(ctx, srv->cli, + ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &pol, path, NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); - talloc_destroy(ctx); + TALLOC_FREE(frame); return ret; } @@ -5861,16 +6016,16 @@ smbc_removexattr_ctx(SMBCCTX *context, StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { /* Yup. */ - ret = cacl_set(ctx, srv->cli, + ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &pol, path, name + 19, SMBC_XATTR_MODE_REMOVE, 0); - talloc_destroy(ctx); + TALLOC_FREE(frame); return ret; } /* Unsupported attribute name */ - talloc_destroy(ctx); errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -5960,11 +6115,13 @@ smbc_open_print_job_ctx(SMBCCTX *context, fstring user; fstring password; pstring path; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return NULL; } @@ -5972,6 +6129,7 @@ smbc_open_print_job_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return NULL; } @@ -5987,11 +6145,13 @@ smbc_open_print_job_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return NULL; } /* What if the path is empty, or the file exists? */ + TALLOC_FREE(frame); return (context->open)(context, fname, O_WRONLY, 666); } @@ -6015,11 +6175,13 @@ smbc_print_file_ctx(SMBCCTX *c_file, int saverr; int tot_bytes = 0; char buf[4096]; + TALLOC_CTX *frame = talloc_stackframe(); if (!c_file || !c_file->internal->_initialized || !c_print || !c_print->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -6027,6 +6189,7 @@ smbc_print_file_ctx(SMBCCTX *c_file, if (!fname && !printq) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -6036,6 +6199,7 @@ smbc_print_file_ctx(SMBCCTX *c_file, if ((long)(fid1 = (c_file->open)(c_file, fname, O_RDONLY, 0666)) < 0) { DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); + TALLOC_FREE(frame); return -1; /* smbc_open sets errno */ } @@ -6047,6 +6211,7 @@ smbc_print_file_ctx(SMBCCTX *c_file, saverr = errno; /* Save errno */ (c_file->close_fn)(c_file, fid1); errno = saverr; + TALLOC_FREE(frame); return -1; } @@ -6074,10 +6239,12 @@ smbc_print_file_ctx(SMBCCTX *c_file, if (bytes < 0) { errno = saverr; + TALLOC_FREE(frame); return -1; } + TALLOC_FREE(frame); return tot_bytes; } @@ -6098,11 +6265,13 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, fstring password; fstring workgroup; pstring path; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -6110,6 +6279,7 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -6125,6 +6295,7 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -6135,6 +6306,7 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -6143,10 +6315,12 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, (void (*)(struct print_job_info *))fn) < 0) { errno = smbc_errno(context, srv->cli); + TALLOC_FREE(frame); return -1; } + TALLOC_FREE(frame); return 0; } @@ -6168,11 +6342,13 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, fstring workgroup; pstring path; int err; + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -6180,6 +6356,7 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, if (!fname) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -6195,6 +6372,7 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, password, sizeof(password), NULL, 0)) { errno = EINVAL; + TALLOC_FREE(frame); return -1; } @@ -6205,6 +6383,7 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, if (!srv) { + TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } @@ -6215,10 +6394,12 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, errno = smbc_errno(context, srv->cli); else if (err == ERRnosuchprintjob) errno = EINVAL; + TALLOC_FREE(frame); return -1; } + TALLOC_FREE(frame); return 0; } -- cgit From cae4c742a896c6adb02b3e7a3c091d02aebb7339 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Nov 2007 17:43:28 -0800 Subject: Always check return from push_ascii. Jeremy. (This used to be commit 9c3d10521e691169cfbb8b728f123911c3c970ae) --- source3/libsmb/clirap.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 9d106d0394..848a8d5482 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -216,6 +216,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, pstring param; int uLevel = 1; int count = -1; + size_t len; errno = 0; /* reset */ @@ -235,7 +236,11 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - p += push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER); + len = push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER); + if (len == (size_t)-1) { + return false; + } + p += len; if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ -- cgit From de51d3dd5f673019325abba88b100b279169a1c8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Nov 2007 18:55:36 -0800 Subject: More pstring removal.... Jeremy. (This used to be commit 809f5ab4c595740b28425e1667e395a6058b76a8) --- source3/libsmb/ntlmssp_parse.c | 145 ++++++++++++++++++++++++++++------------- 1 file changed, 98 insertions(+), 47 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index 76194d5974..ac8846ad1e 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 Copyright (C) Jim McDonough 2002 Copyright (C) Andrew Bartlett 2002-2003 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -89,7 +89,9 @@ bool msrpc_gen(DATA_BLOB *blob, } va_end(ap); - /* allocate the space, then scan the format again to fill in the values */ + /* allocate the space, then scan the format + * again to fill in the values */ + *blob = data_blob(NULL, head_size + data_size); head_ofs = 0; @@ -104,7 +106,8 @@ bool msrpc_gen(DATA_BLOB *blob, SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); + push_string(NULL, blob->data+data_ofs, + s, n*2, STR_UNICODE|STR_NOALIGN); data_ofs += n*2; break; case 'A': @@ -113,7 +116,8 @@ bool msrpc_gen(DATA_BLOB *blob, SSVAL(blob->data, head_ofs, n); head_ofs += 2; SSVAL(blob->data, head_ofs, n); head_ofs += 2; SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + push_string(NULL, blob->data+data_ofs, + s, n, STR_ASCII|STR_NOALIGN); data_ofs += n; break; case 'a': @@ -159,7 +163,7 @@ bool msrpc_gen(DATA_BLOB *blob, } va_end(ap); - return True; + return true; } @@ -193,7 +197,6 @@ bool msrpc_parse(const DATA_BLOB *blob, uint16 len1, len2; uint32 ptr; uint32 *v; - pstring p; va_start(ap, format); for (i=0; format[i]; i++) { @@ -208,23 +211,37 @@ bool msrpc_parse(const DATA_BLOB *blob, if (len1 == 0 && len2 == 0) { *ps = smb_xstrdup(""); } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; + /* make sure its in the right format + * be strict */ + if ((len1 != len2) || (ptr + len1 < ptr) || + (ptr + len1 < len1) || + (ptr + len1 > blob->length)) { + return false; } if (len1 & 1) { /* if odd length and unicode */ - return False; + return false; } - if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) - return False; + if (blob->data + ptr < + (uint8 *)(unsigned long)ptr || + blob->data + ptr < blob->data) + return false; if (0 < len1) { - pull_string( - NULL, 0, p, - blob->data + ptr, sizeof(p), - len1, STR_UNICODE|STR_NOALIGN); - (*ps) = smb_xstrdup(p); + char *p = NULL; + pull_string_talloc(talloc_tos(), + NULL, + 0, + &p, + blob->data + ptr, + len1, + STR_UNICODE|STR_NOALIGN); + if (p) { + (*ps) = smb_xstrdup(p); + TALLOC_FREE(p); + } else { + (*ps) = smb_xstrdup(""); + } } else { (*ps) = smb_xstrdup(""); } @@ -241,19 +258,32 @@ bool msrpc_parse(const DATA_BLOB *blob, if (len1 == 0 && len2 == 0) { *ps = smb_xstrdup(""); } else { - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; + if ((len1 != len2) || (ptr + len1 < ptr) || + (ptr + len1 < len1) || + (ptr + len1 > blob->length)) { + return false; } - if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) - return False; + if (blob->data + ptr < + (uint8 *)(unsigned long)ptr || + blob->data + ptr < blob->data) + return false; if (0 < len1) { - pull_string( - NULL, 0, p, - blob->data + ptr, sizeof(p), - len1, STR_ASCII|STR_NOALIGN); - (*ps) = smb_xstrdup(p); + char *p = NULL; + pull_string_talloc(talloc_tos(), + NULL, + 0, + &p, + blob->data + ptr, + len1, + STR_ASCII|STR_NOALIGN); + if (p) { + (*ps) = smb_xstrdup(p); + TALLOC_FREE(p); + } else { + (*ps) = smb_xstrdup(""); + } } else { (*ps) = smb_xstrdup(""); } @@ -269,14 +299,19 @@ bool msrpc_parse(const DATA_BLOB *blob, if (len1 == 0 && len2 == 0) { *b = data_blob_null; } else { - /* make sure its in the right format - be strict */ - if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { - return False; + /* make sure its in the right format + * be strict */ + if ((len1 != len2) || (ptr + len1 < ptr) || + (ptr + len1 < len1) || + (ptr + len1 > blob->length)) { + return false; } - if (blob->data + ptr < (uint8 *)(unsigned long)ptr || blob->data + ptr < blob->data) - return False; - + if (blob->data + ptr < + (uint8 *)(unsigned long)ptr || + blob->data + ptr < blob->data) + return false; + *b = data_blob(blob->data + ptr, len1); } break; @@ -285,9 +320,11 @@ bool msrpc_parse(const DATA_BLOB *blob, len1 = va_arg(ap, unsigned); /* make sure its in the right format - be strict */ NEED_DATA(len1); - if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) - return False; - + if (blob->data + head_ofs < (uint8 *)head_ofs || + blob->data + head_ofs < blob->data) { + return false; + } + *b = data_blob(blob->data + head_ofs, len1); head_ofs += len1; break; @@ -299,15 +336,29 @@ bool msrpc_parse(const DATA_BLOB *blob, case 'C': s = va_arg(ap, char *); - if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) - return False; - - head_ofs += pull_string( - NULL, 0, p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - return False; + if (blob->data + head_ofs < (uint8 *)head_ofs || + blob->data + head_ofs < blob->data) { + return false; + } + + { + char *p = NULL; + size_t ret = pull_string_talloc(talloc_tos(), + NULL, + 0, + &p, + blob->data+head_ofs, + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); + if (ret == (size_t)-1 || p == NULL) { + return false; + } + head_ofs += ret; + if (strcmp(s, p) != 0) { + TALLOC_FREE(p); + return false; + } + TALLOC_FREE(p); } break; } -- cgit From d2c2635a280b1bfbbcd52fa96bbeff3f60672c45 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 23 Nov 2007 12:04:35 +0100 Subject: Make remote_password_change return malloced error strings This fixes a segfault in smbpasswd -r (This used to be commit 49949f0b85007c7c2b3c340c12f3d18909862135) --- source3/libsmb/passchange.c | 69 +++++++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 31 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index f5057ec73b..9941b728ae 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -24,8 +24,8 @@ *************************************************************/ NTSTATUS remote_password_change(const char *remote_machine, const char *user_name, - const char *old_passwd, const char *new_passwd, - char *err_str, size_t err_str_len) + const char *old_passwd, const char *new_passwd, + char **err_str) { struct nmb_name calling, called; struct cli_state *cli; @@ -35,11 +35,11 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam NTSTATUS result; bool pass_must_change = False; - *err_str = '\0'; + *err_str = NULL; if(!resolve_name( remote_machine, &ss, 0x20)) { - slprintf(err_str, err_str_len-1, "Unable to find an IP address for machine %s.\n", - remote_machine ); + asprintf(err_str, "Unable to find an IP address for machine " + "%s.\n", remote_machine); return NT_STATUS_UNSUCCESSFUL; } @@ -50,8 +50,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam result = cli_connect(cli, remote_machine, &ss); if (!NT_STATUS_IS_OK(result)) { - slprintf(err_str, err_str_len-1, "Unable to connect to SMB server on machine %s. Error was : %s.\n", - remote_machine, nt_errstr(result) ); + asprintf(err_str, "Unable to connect to SMB server on " + "machine %s. Error was : %s.\n", + remote_machine, nt_errstr(result)); cli_shutdown(cli); return result; } @@ -60,8 +61,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam make_nmb_name(&called , remote_machine, 0x20); if (!cli_session_request(cli, &calling, &called)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", - remote_machine, cli_errstr(cli) ); + asprintf(err_str, "machine %s rejected the session setup. " + "Error was : %s.\n", + remote_machine, cli_errstr(cli) ); result = cli_nt_error(cli); cli_shutdown(cli); return result; @@ -70,8 +72,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli->protocol = PROTOCOL_NT1; if (!cli_negprot(cli)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the negotiate protocol. Error was : %s.\n", - remote_machine, cli_errstr(cli) ); + asprintf(err_str, "machine %s rejected the negotiate " + "protocol. Error was : %s.\n", + remote_machine, cli_errstr(cli) ); result = cli_nt_error(cli); cli_shutdown(cli); return result; @@ -92,9 +95,8 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (!NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_MUST_CHANGE) && !NT_STATUS_EQUAL(result, NT_STATUS_PASSWORD_EXPIRED)) { - slprintf(err_str, err_str_len-1, "Could not " - "connect to machine %s: %s\n", - remote_machine, cli_errstr(cli)); + asprintf(err_str, "Could not connect to machine %s: " + "%s\n", remote_machine, cli_errstr(cli)); cli_shutdown(cli); return result; } @@ -110,7 +112,8 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam result = cli_session_setup(cli, "", "", 0, "", 0, ""); if (!NT_STATUS_IS_OK(result)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n", + asprintf(err_str, "machine %s rejected the session " + "setup. Error was : %s.\n", remote_machine, cli_errstr(cli) ); cli_shutdown(cli); return result; @@ -122,8 +125,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", - remote_machine, cli_errstr(cli) ); + asprintf(err_str, "machine %s rejected the tconX on the IPC$ " + "share. Error was : %s.\n", + remote_machine, cli_errstr(cli) ); result = cli_nt_error(cli); cli_shutdown(cli); return result; @@ -155,17 +159,18 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if (lp_client_lanman_auth()) { /* Use the old RAP method. */ if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { - slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + asprintf(err_str, "machine %s rejected the " + "password change: Error was : %s.\n", remote_machine, cli_errstr(cli) ); result = cli_nt_error(cli); cli_shutdown(cli); return result; } } else { - slprintf(err_str, err_str_len-1, - "SAMR connection to machine %s failed. Error was %s, " - "but LANMAN password changed are disabled\n", - nt_errstr(result), remote_machine); + asprintf(err_str, "SAMR connection to machine %s " + "failed. Error was %s, but LANMAN password " + "changed are disabled\n", + nt_errstr(result), remote_machine); result = cli_nt_error(cli); cli_shutdown(cli); return result; @@ -182,7 +187,8 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { /* it failed, but for reasons such as wrong password, too short etc ... */ - slprintf(err_str, err_str_len-1, "machine %s rejected the password change: Error was : %s.\n", + asprintf(err_str, "machine %s rejected the password change: " + "Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); cli_shutdown(cli); return result; @@ -213,9 +219,10 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { /* it failed, but again it was due to things like new password too short */ - slprintf(err_str, err_str_len-1, - "machine %s rejected the (anonymous) password change: Error was : %s.\n", - remote_machine, get_friendly_nt_error_msg(result)); + asprintf(err_str, "machine %s rejected the " + "(anonymous) password change: Error was : " + "%s.\n", remote_machine, + get_friendly_nt_error_msg(result)); cli_shutdown(cli); return result; } @@ -231,16 +238,16 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_shutdown(cli); return NT_STATUS_OK; } - slprintf(err_str, err_str_len-1, - "machine %s rejected the password change: Error was : %s.\n", + asprintf(err_str, "machine %s rejected the password " + "change: Error was : %s.\n", remote_machine, cli_errstr(cli) ); result = cli_nt_error(cli); cli_shutdown(cli); return result; } else { - slprintf(err_str, err_str_len-1, - "SAMR connection to machine %s failed. Error was %s, " - "but LANMAN password changed are disabled\n", + asprintf(err_str, "SAMR connection to machine %s " + "failed. Error was %s, but LANMAN password " + "changed are disabled\n", nt_errstr(result), remote_machine); cli_shutdown(cli); return NT_STATUS_UNSUCCESSFUL; -- cgit From bff221cf1b52552fc556aa2c880a7e386b1cb2ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 Nov 2007 12:54:52 +0100 Subject: In libsmbclient, map NT_STATUS_OBJECT_PATH_NOT_FOUND to ENOENT Thanks to SATOH Fumiyasu! This fixes bug 4974 (This used to be commit 41e07682dc1fa535ddaf405efa26fabb33c8bbf9) --- source3/libsmb/clierror.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 2232ee27a7..c9c5a6cd30 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -239,6 +239,7 @@ static const struct { {NT_STATUS_INVALID_HANDLE, EBADF}, {NT_STATUS_ACCESS_DENIED, EACCES}, {NT_STATUS_OBJECT_NAME_NOT_FOUND, ENOENT}, + {NT_STATUS_OBJECT_PATH_NOT_FOUND, ENOENT}, {NT_STATUS_SHARING_VIOLATION, EBUSY}, {NT_STATUS_OBJECT_PATH_INVALID, ENOTDIR}, {NT_STATUS_OBJECT_NAME_COLLISION, EEXIST}, -- cgit From 1011b32678c7b32472a909b9f515698947d2a389 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 Nov 2007 10:10:52 +0100 Subject: Remove some statics (This used to be commit 1fab16ffb888cd4ec18e52d9da33976a67a5d104) --- source3/libsmb/dsgetdcname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index f6c3273084..b0870e249e 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -800,7 +800,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, dc_address_type = ADS_NETBIOS_ADDRESS; } NT_STATUS_HAVE_NO_MEMORY(dc_address); - dc_guid = smb_uuid_unpack_static(r.guid); + smb_uuid_unpack(r.guid, &dc_guid); if (r.forest) { dc_flags |= ADS_DNS_FOREST; -- cgit From 762fde90a0cb3a3a82adc4f9e96dff8cac4ca527 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Nov 2007 23:10:20 -0800 Subject: Remove pstrings from namequery.c. Jeremy. (This used to be commit 71ccd0c42e0ae66172ca5797be3d3a01f4a67a69) --- source3/libsmb/namequery.c | 71 ++++++++++++++++++++++++++++++---------------- 1 file changed, 47 insertions(+), 24 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index f4f9f84b00..71d7096914 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1421,7 +1421,7 @@ NTSTATUS internal_resolve_name(const char *name, int *return_count, const char *resolve_order) { - pstring name_resolve_list; + const char *name_resolve_list; fstring tok; const char *ptr; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -1475,9 +1475,9 @@ NTSTATUS internal_resolve_name(const char *name, } if (!resolve_order) { - pstrcpy(name_resolve_list, lp_name_resolve_order()); + name_resolve_list = lp_name_resolve_order(); } else { - pstrcpy(name_resolve_list, resolve_order); + name_resolve_list = resolve_order; } if (!name_resolve_list[0]) { @@ -1732,20 +1732,25 @@ static NTSTATUS get_dc_list(const char *domain, enum dc_lookup_type lookup_type, bool *ordered) { - fstring resolve_order; - char *saf_servername; - pstring pserver; + char *resolve_order = NULL; + char *saf_servername = NULL; + char *pserver = NULL; const char *p; - char *port_str; + char *port_str = NULL; int port; fstring name; int num_addresses = 0; int local_count, i, j; struct ip_service *return_iplist = NULL; struct ip_service *auto_ip_list = NULL; - bool done_auto_lookup = False; + bool done_auto_lookup = false; int auto_count = 0; NTSTATUS status; + TALLOC_CTX *ctx = talloc_init("get_dc_list"); + + if (!ctx) { + return NT_STATUS_NO_MEMORY; + } *ordered = False; @@ -1755,23 +1760,31 @@ static NTSTATUS get_dc_list(const char *domain, are disabled and ads_only is True, then set the string to NULL. */ - fstrcpy(resolve_order, lp_name_resolve_order()); + resolve_order = talloc_strdup(ctx, lp_name_resolve_order()); + if (!resolve_order) { + status = NT_STATUS_NO_MEMORY; + goto out; + } strlower_m(resolve_order); if (lookup_type == DC_ADS_ONLY) { if (strstr( resolve_order, "host")) { - fstrcpy( resolve_order, "ads"); + resolve_order = talloc_strdup(ctx, "ads"); /* DNS SRV lookups used by the ads resolver are already sorted by priority and weight */ *ordered = true; } else { - fstrcpy(resolve_order, "NULL"); + resolve_order = talloc_strdup(ctx, "NULL"); } } else if (lookup_type == DC_KDC_ONLY) { /* DNS SRV lookups used by the ads/kdc resolver are already sorted by priority and weight */ *ordered = true; - fstrcpy(resolve_order, "kdc"); + resolve_order = talloc_strdup(ctx, "kdc"); + } + if (!resolve_order) { + status = NT_STATUS_NO_MEMORY; + goto out; } /* fetch the server we have affinity for. Add the @@ -1780,22 +1793,27 @@ static NTSTATUS get_dc_list(const char *domain, saf_servername = saf_fetch( domain); if (strequal(domain, lp_workgroup()) || strequal(domain, lp_realm())) { - pstr_sprintf(pserver, "%s, %s", + pserver = talloc_asprintf(NULL, "%s, %s", saf_servername ? saf_servername : "", lp_passwordserver()); } else { - pstr_sprintf(pserver, "%s, *", + pserver = talloc_asprintf(NULL, "%s, *", saf_servername ? saf_servername : ""); } - SAFE_FREE( saf_servername ); + SAFE_FREE(saf_servername); + if (!pserver) { + status = NT_STATUS_NO_MEMORY; + goto out; + } /* if we are starting from scratch, just lookup DOMAIN<0x1c> */ if (!*pserver ) { DEBUG(10,("get_dc_list: no preferred domain controllers.\n")); - return internal_resolve_name(domain, 0x1C, sitename, ip_list, + status = internal_resolve_name(domain, 0x1C, sitename, ip_list, count, resolve_order); + goto out; } DEBUG(3,("get_dc_list: preferred server list: \"%s\"\n", pserver )); @@ -1831,18 +1849,19 @@ static NTSTATUS get_dc_list(const char *domain, if ((num_addresses == 0)) { if (done_auto_lookup) { DEBUG(4,("get_dc_list: no servers found\n")); - SAFE_FREE(auto_ip_list); - return NT_STATUS_NO_LOGON_SERVERS; + status = NT_STATUS_NO_LOGON_SERVERS; + goto out; } - return internal_resolve_name(domain, 0x1C, sitename, ip_list, + status = internal_resolve_name(domain, 0x1C, sitename, ip_list, count, resolve_order); + goto out; } if ((return_iplist = SMB_MALLOC_ARRAY(struct ip_service, num_addresses)) == NULL) { DEBUG(3,("get_dc_list: malloc fail !\n")); - SAFE_FREE(auto_ip_list); - return NT_STATUS_NO_MEMORY; + status = NT_STATUS_NO_MEMORY; + goto out; } p = pserver; @@ -1918,8 +1937,6 @@ static NTSTATUS get_dc_list(const char *domain, } } - SAFE_FREE(auto_ip_list); - /* need to remove duplicates in the list if we have any explicit password servers */ @@ -1947,7 +1964,13 @@ static NTSTATUS get_dc_list(const char *domain, *ip_list = return_iplist; *count = local_count; - return ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS ); + status = ( *count != 0 ? NT_STATUS_OK : NT_STATUS_NO_LOGON_SERVERS ); + + out: + + SAFE_FREE(auto_ip_list); + TALLOC_FREE(ctx); + return status; } /********************************************************************* -- cgit From 3daafc5662825228219e986a9fa570824b2104a8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Nov 2007 23:40:54 -0800 Subject: Remove pstrings from asn1.c. Jeremy. (This used to be commit 82f393e60378eb42ddcc740241902eee495719d3) --- source3/libsmb/asn1.c | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 0cbfa70e7b..99c5b0b1bd 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -348,22 +348,30 @@ int asn1_tag_remaining(ASN1_DATA *data) /* read an object ID from a ASN1 buffer */ bool asn1_read_OID(ASN1_DATA *data, char **OID) { - uint8 b; - pstring oid_str; - fstring el; + uint8 b = 0; + char *oid_str = NULL; *OID = NULL; if (!asn1_start_tag(data, ASN1_OID)) { - return False; + return false; } asn1_read_uint8(data, &b); - oid_str[0] = 0; - fstr_sprintf(el, "%u", b/40); - pstrcat(oid_str, el); - fstr_sprintf(el, " %u", b%40); - pstrcat(oid_str, el); + oid_str = talloc_asprintf(NULL, + "%u", + b/40); + if (!oid_str) { + data->has_error = true; + goto out; + } + oid_str = talloc_asprintf_append(oid_str, + " %u", + b%40); + if (!oid_str) { + data->has_error = true; + goto out; + } while (asn1_tag_remaining(data) > 0) { unsigned v = 0; @@ -371,16 +379,25 @@ bool asn1_read_OID(ASN1_DATA *data, char **OID) asn1_read_uint8(data, &b); v = (v<<7) | (b&0x7f); } while (!data->has_error && b & 0x80); - fstr_sprintf(el, " %u", v); - pstrcat(oid_str, el); + oid_str = talloc_asprintf_append(oid_str, + " %u", + v); + if (!oid_str) { + data->has_error = true; + goto out; + } } + out: + asn1_end_tag(data); if (!data->has_error) { *OID = SMB_STRDUP(oid_str); } + TALLOC_FREE(oid_str); + return !data->has_error; } -- cgit From eced14c6e698191f41f7f861ed1c71b2c8414866 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 Nov 2007 14:08:49 -0800 Subject: Remove unused code (and pstring). Jeremy. (This used to be commit a261a61226248b41be22dd4f2873b5ed82bc2a24) --- source3/libsmb/clidgram.c | 92 ----------------------------------------------- 1 file changed, 92 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 5b619b6458..82f874f383 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -113,95 +113,3 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, MSG_SEND_PACKET, (uint8 *)&p, sizeof(p))); } - -/* - * cli_get_response: Get a response ... - */ -bool cli_get_response(const char *mailslot, char *buf, int bufsiz) -{ - struct packet_struct *p; - - p = receive_unexpected(DGRAM_PACKET, 0, mailslot); - - if (p == NULL) - return False; - - memcpy(buf, &p->packet.dgram.data[92], - MIN(bufsiz, p->packet.dgram.datasize-92)); - - return True; -} - -/* - * cli_get_backup_list: Send a get backup list request ... - */ - -static char cli_backup_list[1024]; - -int cli_get_backup_list(struct messaging_context *msg_ctx, - const char *myname, const char *send_to_name) -{ - pstring outbuf; - char *p; - struct sockaddr_storage sendto_ss; - - if (!resolve_name(send_to_name, &sendto_ss, 0x1d)) { - - DEBUG(0, ("Could not resolve name: %s<1D>\n", send_to_name)); - return False; - - } - - memset(cli_backup_list, '\0', sizeof(cli_backup_list)); - memset(outbuf, '\0', sizeof(outbuf)); - - p = outbuf; - - SCVAL(p, 0, ANN_GetBackupListReq); - p++; - - SCVAL(p, 0, 1); /* Count pointer ... */ - p++; - - SIVAL(p, 0, 1); /* The sender's token ... */ - p += 4; - - cli_send_mailslot(msg_ctx, True, "\\MAILSLOT\\BROWSE", 1, outbuf, - PTR_DIFF(p, outbuf), myname, 0, send_to_name, - 0x1d, &sendto_ss); - - /* We should check the error and return if we got one */ - - /* Now, get the response ... */ - - cli_get_response("\\MAILSLOT\\BROWSE", - cli_backup_list, sizeof(cli_backup_list)); - - return True; - -} - -/* - * cli_get_backup_server: Get the backup list and retrieve a server from it - */ - -int cli_get_backup_server(struct messaging_context *msg_ctx, - char *my_name, char *target, char *servername, - int namesize) -{ - - /* Get the backup list first. We could pull this from the cache later */ - - cli_get_backup_list(msg_ctx, my_name, target); /* FIXME: Check the response */ - - if (!cli_backup_list[0]) { /* Empty list ... try again */ - - cli_get_backup_list(msg_ctx, my_name, target); - - } - - strncpy(servername, cli_backup_list, MIN(16, namesize)); - - return True; - -} -- cgit From 42c87fe6e6036a56b178183b034275321949050d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 13:24:14 -0800 Subject: Remove pstrings. Ensure we validate offsets. Jeremy. (This used to be commit ff06cc34e66a18ba71dd54f6c78b05a45b9f2d85) --- source3/libsmb/clilist.c | 196 +++++++++++++++++++++++++++++++---------------- 1 file changed, 132 insertions(+), 64 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index fd0c380409..64cb3e8fe3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. client directory list routines Copyright (C) Andrew Tridgell 1994-1998 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -21,6 +21,22 @@ extern file_info def_finfo; +/**************************************************************************** + Calculate a safe next_entry_offset. +****************************************************************************/ + +static size_t calc_next_entry_offset(const char *base, const char *pdata_end) +{ + size_t next_entry_offset = (size_t)IVAL(base,0); + + if (next_entry_offset == 0 || + base + next_entry_offset < base || + base + next_entry_offset > pdata_end) { + next_entry_offset = pdata_end - base; + } + return next_entry_offset; +} + /**************************************************************************** Interpret a long filename structure - this is mostly guesses at the moment. The length of the structure is returned @@ -28,12 +44,19 @@ extern file_info def_finfo; by NT and 2 is used by OS/2 ****************************************************************************/ -static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo, - uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len) +static size_t interpret_long_filename(struct cli_state *cli, + int level, + const char *p, + const char *pdata_end, + file_info *finfo, + uint32 *p_resume_key, + DATA_BLOB *p_last_name_raw) { file_info finfo2; int len; - char *base = p; + const char *base = p; + + data_blob_free(p_last_name_raw); if (!finfo) { finfo = &finfo2; @@ -49,6 +72,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ + if (pdata_end - base < 27) { + return pdata_end - base; + } finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); @@ -57,19 +83,25 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); + if (p + len + 2 > pdata_end) { + return pdata_end - base; + } /* the len+2 below looks strange but it is important to cope with the differences between win2000 and win9x for this call (tridge) */ p += clistr_pull(cli, finfo->name, p, sizeof(finfo->name), - len+2, + len+2, STR_TERMINATE); return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ /* these dates are converted to GMT by make_unix_date */ + if (pdata_end - base < 31) { + return pdata_end - base; + } finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); @@ -78,22 +110,30 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f len = CVAL(p, 30); p += 31; /* check for unisys! */ + if (p + len + 1 > pdata_end) { + return pdata_end - base; + } p += clistr_pull(cli, finfo->name, p, sizeof(finfo->name), - len, + len, STR_NOALIGN); return PTR_DIFF(p, base) + 1; - + case 260: /* NT uses this, but also accepts 2 */ { size_t namelen, slen; + + if (pdata_end - base < 94) { + return pdata_end - base; + } + p += 4; /* next entry offset */ if (p_resume_key) { *p_resume_key = IVAL(p,0); } p += 4; /* fileindex */ - + /* Offset zero is "create time", not "change time". */ p += 8; finfo->atime_ts = interpret_long_date(p); @@ -111,7 +151,11 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f p += 4; p += 4; /* EA size */ slen = SVAL(p, 0); - p += 2; + if (slen > 24) { + /* Bad short name length. */ + return pdata_end - base; + } + p += 2; { /* stupid NT bugs. grr */ int flags = 0; @@ -120,7 +164,10 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f sizeof(finfo->short_name), slen, flags); } - p += 24; /* short name? */ + p += 24; /* short name? */ + if (p + namelen < p || p + namelen > pdata_end) { + return pdata_end - base; + } clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, 0); @@ -130,29 +177,24 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f Namelen doesn't include the terminating unicode null, so copy it here. */ - if (p_last_name_raw && p_last_name_raw_len) { - if (namelen + 2 > p_last_name_raw->length) { - memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length)); - *p_last_name_raw_len = 0; - } else { - memcpy(p_last_name_raw->data, p, namelen); - SSVAL(p_last_name_raw->data, namelen, 0); - *p_last_name_raw_len = namelen + 2; - } + if (p_last_name_raw) { + *p_last_name_raw = data_blob(NULL, namelen+2); + memcpy(p_last_name_raw->data, p, namelen); + SSVAL(p_last_name_raw->data, namelen, 0); } - return (size_t)IVAL(base, 0); + return calc_next_entry_offset(base, pdata_end); } } - + DEBUG(1,("Unknown long filename format %d\n",level)); - return (size_t)IVAL(base,0); + return calc_next_entry_offset(base, pdata_end); } /**************************************************************************** Do a directory listing, calling fn on each file found. ****************************************************************************/ -int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, +int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { #if 1 @@ -161,8 +203,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int max_matches = 512; #endif int info_level; - char *p, *p2; - pstring mask; + char *p, *p2, *rdata_end; + char *mask = NULL; file_info finfo; int i; char *dirlist = NULL; @@ -174,19 +216,21 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - unsigned int param_len, data_len; + unsigned int param_len, data_len; uint16 setup; - pstring param; + char param[1024]; const char *mnt; uint32 resume_key = 0; - uint32 last_name_raw_len = 0; - DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring)); + DATA_BLOB last_name_raw = data_blob(NULL, 0); /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; - - pstrcpy(mask,Mask); - + + mask = SMB_STRDUP(Mask); + if (!mask) { + return -1; + } + while (ff_eos == 0) { loop_count++; if (loop_count > 200) { @@ -199,16 +243,16 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,0,attribute); /* attribute */ SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ - SSVAL(param,6,info_level); + SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; - p += clistr_push(cli, param+12, mask, sizeof(param)-12, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,info_level); + SSVAL(param,4,info_level); /* For W2K servers serving out FAT filesystems we *must* set the resume key. If it's not FAT then it's returned as zero. */ SIVAL(param,6,resume_key); /* ff_resume_key */ @@ -216,9 +260,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; - if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) { - memcpy(p, last_name_raw.data, last_name_raw_len); - p += last_name_raw_len; + if (last_name_raw.length && (last_name_raw.length < (sizeof(param)-12))) { + memcpy(p, last_name_raw.data, last_name_raw.length); + p += last_name_raw.length; } else { p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } @@ -226,12 +270,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, param_len = PTR_DIFF(p, param); - if (!cli_send_trans(cli, SMBtrans2, + if (!cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ - NULL, 0, + NULL, 0, #if 0 /* w2k value. */ MIN(16384,cli->max_xmit) /* data, length, max. */ @@ -242,7 +286,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - if (!cli_receive_trans(cli, SMBtrans2, + if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len) && cli_is_dos_error(cli)) { @@ -289,15 +333,21 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* point to the data bytes */ p = rdata; + rdata_end = rdata + data_len; /* we might need the lastname for continuations */ - for (p2=p,i=0;i 0) { - pstrcpy(mask, finfo.name); + mask = SMB_STRDUP(finfo.name); } else { - pstrcpy(mask,""); + mask = SMB_STRDUP(""); + } + if (!mask) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); + break; } /* grab the data for later use */ @@ -348,9 +404,15 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, total_received = -1; } else { /* no connection problem. let user function add each entry */ + rdata_end = dirlist + dirlist_len; for (p=dirlist,i=0;icli = cli; finfo->mode = CVAL(p,21); - + /* this date is converted to GMT by make_unix_date */ finfo->ctime_ts.tv_sec = cli_make_unix_date(cli, p+22); finfo->ctime_ts.tv_nsec = 0; @@ -396,7 +459,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi but should otherwise not be used. ****************************************************************************/ -int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, +int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { char *p; @@ -407,12 +470,15 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, int num_received = 0; int i; char *dirlist = NULL; - pstring mask; - + char *mask = NULL; + ZERO_ARRAY(status); - pstrcpy(mask,Mask); - + mask = SMB_STRDUP(Mask); + if (!mask) { + return -1; + } + while (1) { memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -426,10 +492,10 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(cli->outbuf,smb_vwv0,num_asked); SSVAL(cli->outbuf,smb_vwv1,attribute); - + p = smb_buf(cli->outbuf); *p++ = 4; - + p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE); *p++ = 5; if (first) { @@ -455,6 +521,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, dirlist,(num_received + received)*DIR_STRUCT_SIZE); if (!dirlist) { DEBUG(0,("cli_list_old: failed to expand dirlist")); + SAFE_FREE(mask); return 0; } @@ -462,11 +529,11 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memcpy(dirlist+num_received*DIR_STRUCT_SIZE, p,received*DIR_STRUCT_SIZE); - + memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); - + num_received += received; - + if (cli_is_error(cli)) break; } @@ -491,7 +558,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p += 2; memcpy(p,status,21); p += 21; - + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -505,6 +572,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, fn("\\", &finfo, Mask, state); } + SAFE_FREE(mask); SAFE_FREE(dirlist); return(num_received); } @@ -514,7 +582,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, This auto-switches between old and new style. ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { if (cli->protocol <= PROTOCOL_LANMAN1) -- cgit From d2cf97aeba14a4d336fb57b01f19bd5a08dcb003 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 13:24:54 -0800 Subject: Remove the explicit TALLOC_CTX * from cli_struct. Make us very explicit about how long a talloc ctx should last. Jeremy. (This used to be commit ba9e2be2b5a59684e854609f9d82ea1633448c62) --- source3/libsmb/cliconnect.c | 18 +++++++++--- source3/libsmb/clidfs.c | 9 ++++-- source3/libsmb/clientgen.c | 8 ------ source3/libsmb/clierror.c | 6 ++++ source3/libsmb/clioplock.c | 5 ++-- source3/libsmb/cliprint.c | 64 +++++++++++++++++++++---------------------- source3/libsmb/clirap.c | 2 +- source3/libsmb/libsmbclient.c | 28 ++++++++++++++----- source3/libsmb/passchange.c | 4 +-- 9 files changed, 85 insertions(+), 59 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f0b03a85cf..e3800bfb33 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1803,13 +1803,18 @@ struct cli_state *get_ipc_connect(char *server, * entire network browse list) */ -struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring workgroup, struct user_auth_info *user_info) +struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, + struct ip_service *mb_ip, + struct user_auth_info *user_info, + char **pp_workgroup_out) { char addr[INET6_ADDRSTRLEN]; fstring name; struct cli_state *cli; struct sockaddr_storage server_ss; + *pp_workgroup_out = NULL; + print_sockaddr(addr, sizeof(addr), &mb_ip->ss); DEBUG(99, ("Looking up name of master browser %s\n", addr)); @@ -1838,7 +1843,7 @@ struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring wo return NULL; } - pstrcpy(workgroup, name); + *pp_workgroup_out = talloc_strdup(ctx, name); DEBUG(4, ("found master browser %s, %s\n", name, addr)); @@ -1853,12 +1858,16 @@ struct cli_state *get_ipc_connect_master_ip(struct ip_service *mb_ip, pstring wo * connect to it. */ -struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user_auth_info *user_info) +struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx, + struct user_auth_info *user_info, + char **pp_workgroup_out) { struct ip_service *ip_list; struct cli_state *cli; int i, count; + *pp_workgroup_out = NULL; + DEBUG(99, ("Do broadcast lookup for workgroups on local network\n")); /* Go looking for workgroups by broadcasting on the local network */ @@ -1874,7 +1883,8 @@ struct cli_state *get_ipc_connect_master_ip_bcast(pstring workgroup, struct user print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); DEBUG(99, ("Found master browser %s\n", addr)); - cli = get_ipc_connect_master_ip(&ip_list[i], workgroup, user_info); + cli = get_ipc_connect_master_ip(ctx, &ip_list[i], + user_info, pp_workgroup_out); if (cli) return(cli); } diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 037c0d6b26..469cb231d2 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -245,9 +245,12 @@ static struct cli_state *cli_cm_connect( const char *server, bool show_hdr) { struct client_connection *node; - - node = SMB_XMALLOC_P( struct client_connection ); - + + node = SMB_CALLOC_ARRAY( struct client_connection, 1); + if (!node) { + return NULL; + } + node->cli = do_connect( server, share, show_hdr ); if ( !node->cli ) { diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ee1a0fe3db..1a6fb8f93f 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -492,9 +492,6 @@ struct cli_state *cli_initialise(void) if (!cli->outbuf || !cli->inbuf) goto error; - if ((cli->mem_ctx = talloc_init("cli based talloc")) == NULL) - goto error; - memset(cli->outbuf, 0, cli->bufsize); memset(cli->inbuf, 0, cli->bufsize); @@ -605,11 +602,6 @@ void cli_shutdown(struct cli_state *cli) data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); - if (cli->mem_ctx) { - talloc_destroy(cli->mem_ctx); - cli->mem_ctx = NULL; - } - if (cli->fd != -1) { close(cli->fd); } diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index c9c5a6cd30..587abade59 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -84,6 +84,8 @@ static NTSTATUS cli_smb_rw_error_to_ntstatus(struct cli_state *cli) return NT_STATUS_UNEXPECTED_NETWORK_ERROR; case SMB_READ_BAD_SIG: return NT_STATUS_INVALID_PARAMETER; + case SMB_NO_MEMORY: + return NT_STATUS_NO_MEMORY; default: break; } @@ -133,6 +135,10 @@ const char *cli_errstr(struct cli_state *cli) slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Server packet had invalid SMB signature!"); break; + case SMB_NO_MEMORY: + slprintf(cli_error_message, sizeof(cli_error_message) - 1, + "Out of memory"); + break; default: slprintf(cli_error_message, sizeof(cli_error_message) - 1, "Unknown error code %d\n", cli->smb_rw_error ); diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index effd4a5565..2e54f5a781 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -22,10 +22,11 @@ /**************************************************************************** send an ack for an oplock break request ****************************************************************************/ + bool cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) { char *oldbuf = cli->outbuf; - pstring buf; + char buf[smb_size+16]; bool ret; cli->outbuf = buf; @@ -47,7 +48,7 @@ bool cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) SSVAL(buf,smb_vwv6,0); /* unlockcount */ SSVAL(buf,smb_vwv7,0); /* lockcount */ - ret = cli_send_smb(cli); + ret = cli_send_smb(cli); cli->outbuf = oldbuf; diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index cab890b08b..7fbdb97c01 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. client print routines Copyright (C) Andrew Tridgell 1994-1998 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -21,13 +21,14 @@ /***************************************************************************** Convert a character pointer in a cli_call_api() response to a form we can use. - This function contains code to prevent core dumps if the server returns + This function contains code to prevent core dumps if the server returns invalid data. *****************************************************************************/ -static const char *fix_char_ptr(unsigned int datap, unsigned int converter, +static const char *fix_char_ptr(unsigned int datap, unsigned int converter, char *rdata, int rdrcnt) { - if (datap == 0) { /* turn NULL pointers into zero length strings */ + if (datap == 0) { + /* turn NULL pointers into zero length strings */ return ""; } else { unsigned int offset = datap - converter; @@ -42,41 +43,41 @@ static const char *fix_char_ptr(unsigned int datap, unsigned int converter, } } - /**************************************************************************** call fn() on each entry in a print queue ****************************************************************************/ -int cli_print_queue(struct cli_state *cli, + +int cli_print_queue(struct cli_state *cli, void (*fn)(struct print_job_info *)) { char *rparam = NULL; char *rdata = NULL; char *p; unsigned int rdrcnt, rprcnt; - pstring param; + char param[1024]; int result_code=0; int i = -1; - + memset(param,'\0',sizeof(param)); p = param; SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */ p += 2; - pstrcpy_base(p,"zWrLeh", param); /* parameter description? */ + safe_strcpy_base(p,"zWrLeh", param, sizeof(param)); /* parameter description? */ p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,"WWzWWDDzz", param); /* returned data format */ + safe_strcpy_base(p,"WWzWWDDzz", param, sizeof(param)); /* returned data format */ p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,cli->share, param); /* name of queue */ + safe_strcpy_base(p,cli->share, param, sizeof(param)); /* name of queue */ p = skip_string(param,sizeof(param),p); SSVAL(p,0,2); /* API function level 2, PRJINFO_2 data structure */ SSVAL(p,2,1000); /* size of bytes of returned data buffer */ p += 4; - pstrcpy_base(p,"", param); /* subformat */ + safe_strcpy_base(p,"", param,sizeof(param)); /* subformat */ p = skip_string(param,sizeof(param),p); DEBUG(4,("doing cli_print_queue for %s\n", cli->share)); - if (cli_api(cli, + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ @@ -87,21 +88,21 @@ int cli_print_queue(struct cli_state *cli, if (result_code == 0) { struct print_job_info job; - - p = rdata; + + p = rdata; for (i = 0; i < SVAL(rparam,4); ++i) { job.id = SVAL(p,0); job.priority = SVAL(p,2); fstrcpy(job.user, - fix_char_ptr(SVAL(p,4), converter, + fix_char_ptr(SVAL(p,4), converter, rdata, rdrcnt)); job.t = cli_make_unix_date3(cli, p + 12); job.size = IVAL(p,16); - fstrcpy(job.name,fix_char_ptr(SVAL(p,24), - converter, + fstrcpy(job.name,fix_char_ptr(SVAL(p,24), + converter, rdata, rdrcnt)); - fn(&job); + fn(&job); p += 28; } } @@ -117,6 +118,7 @@ int cli_print_queue(struct cli_state *cli, /**************************************************************************** cancel a print job ****************************************************************************/ + int cli_printjob_del(struct cli_state *cli, int job) { char *rparam = NULL; @@ -124,21 +126,21 @@ int cli_printjob_del(struct cli_state *cli, int job) char *p; unsigned int rdrcnt,rprcnt; int ret = -1; - pstring param; + char param[1024]; memset(param,'\0',sizeof(param)); p = param; SSVAL(p,0,81); /* DosPrintJobDel() */ p += 2; - pstrcpy_base(p,"W", param); + safe_strcpy_base(p,"W", param,sizeof(param)); p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,"", param); + safe_strcpy_base(p,"", param,sizeof(param)); p = skip_string(param,sizeof(param),p); - SSVAL(p,0,job); + SSVAL(p,0,job); p += 2; - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ @@ -178,7 +180,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_ accessmode |= 2; } else if ((flags & O_ACCMODE) == O_WRONLY) { accessmode |= 1; - } + } #if defined(O_SYNC) if ((flags & O_SYNC) == O_SYNC) { @@ -213,7 +215,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_ FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK); SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); } - + p = smb_buf(cli->outbuf); p += clistr_push(cli, p, fname, -1, STR_TERMINATE); @@ -256,5 +258,3 @@ bool cli_spl_close(struct cli_state *cli, int fnum) return !cli_is_error(cli); } - - diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 848a8d5482..c877dfa2ab 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -399,7 +399,7 @@ bool cli_qpathinfo(struct cli_state *cli, const char *fname, char *rparam=NULL, *rdata=NULL; int count=8; bool ret; - time_t (*date_fn)(struct cli_state *, void *); + time_t (*date_fn)(struct cli_state *, const void *); char *p; p = param; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index ee560b65c3..4f2503731d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1008,7 +1008,7 @@ smbc_attr_server(SMBCCTX *context, nt_status = rpccli_lsa_open_policy( pipe_hnd, - ipc_srv->cli->mem_ctx, + talloc_tos(), True, GENERIC_EXECUTE_ACCESS, pol); @@ -1964,7 +1964,7 @@ smbc_lseek_ctx(SMBCCTX *context, fstring server, share, user, password; pstring path, targetpath; struct cli_state *targetcli; - TALLOC_CTX *frame = talloc_tos(); + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { @@ -2767,18 +2767,23 @@ smbc_opendir_ctx(SMBCCTX *context, for (i = 0; i < count && i < max_lmb_count; i++) { char addr[INET6_ADDRSTRLEN]; + char *wg_ptr = NULL; + print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), addr)); - cli = get_ipc_connect_master_ip(&ip_list[i], - workgroup, &u_info); + cli = get_ipc_connect_master_ip(talloc_tos(), + &ip_list[i], + &u_info, + &wg_ptr); /* cli == NULL is the master browser refused to talk or could not be found */ if ( !cli ) continue; + pstrcpy(workgroup, wg_ptr); fstrcpy(server, cli->desthost); cli_shutdown(cli); @@ -3089,7 +3094,7 @@ static int smbc_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { - TALLOC_CTX *frame = talloc_tos(); + TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { @@ -4025,6 +4030,8 @@ convert_sid_to_string(struct cli_state *ipc_cli, char **names = NULL; enum lsa_SidType *types = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); + TALLOC_CTX *ctx; + sid_to_string(str, sid); if (numeric) { @@ -4037,13 +4044,17 @@ convert_sid_to_string(struct cli_state *ipc_cli, /* Ask LSA to convert the sid to a name */ - if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ipc_cli->mem_ctx, + ctx = talloc_stackframe(); + + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, pol, 1, sid, &domains, &names, &types)) || !domains || !domains[0] || !names || !names[0]) { + TALLOC_FREE(ctx); return; } + TALLOC_FREE(ctx); /* Converted OK */ slprintf(str, sizeof(fstring) - 1, "%s%s%s", @@ -4062,6 +4073,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, enum lsa_SidType *types = NULL; DOM_SID *sids = NULL; bool result = True; + TALLOC_CTX *ctx; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); if (!pipe_hnd) { @@ -4077,7 +4089,8 @@ convert_string_to_sid(struct cli_state *ipc_cli, goto done; } - if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ipc_cli->mem_ctx, + ctx = talloc_stackframe(); + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, pol, 1, &str, NULL, 1, &sids, &types))) { result = False; @@ -4087,6 +4100,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, sid_copy(sid, &sids[0]); done: + TALLOC_FREE(ctx); return result; } diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 9941b728ae..468750f801 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -177,7 +177,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } } - if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, cli->mem_ctx, user_name, + if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, pipe_hnd->mem_ctx, user_name, new_passwd, old_passwd))) { /* Great - it all worked! */ cli_shutdown(cli); @@ -207,7 +207,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam if ( pipe_hnd && (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, - cli->mem_ctx, + pipe_hnd->mem_ctx, user_name, new_passwd, old_passwd)))) { -- cgit From f692694b99319ef1f534ea29f001922656402cdf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 17:25:41 -0800 Subject: Remove PSTRING_LEN from smbd/ nmbd/. Remove pstring from libsmb/clidfs.c except for a nasty hack (that will be removed when pstrings are gone from client/). Jeremy. (This used to be commit cc257b71d13daa47e6f2315d0f07a60eb4aaeca6) --- source3/libsmb/cliconnect.c | 15 +- source3/libsmb/clidfs.c | 573 ++++++++++++++++++++++++++---------------- source3/libsmb/libsmbclient.c | 169 ++++++------- 3 files changed, 439 insertions(+), 318 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e3800bfb33..14140811d2 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -879,8 +879,8 @@ ntlmssp: password is in plaintext, the same should be done. ****************************************************************************/ -NTSTATUS cli_session_setup(struct cli_state *cli, - const char *user, +NTSTATUS cli_session_setup(struct cli_state *cli, + const char *user, const char *pass, int passlen, const char *ntpass, int ntpasslen, const char *workgroup) @@ -888,8 +888,17 @@ NTSTATUS cli_session_setup(struct cli_state *cli, char *p; fstring user2; + if (user) { + fstrcpy(user2, user); + } else { + user2[0] ='\0'; + } + + if (!workgroup) { + workgroup = ""; + } + /* allow for workgroups as part of the username */ - fstrcpy(user2, user); if ((p=strchr_m(user2,'\\')) || (p=strchr_m(user2,'/')) || (p=strchr_m(user2,*lp_winbind_separator()))) { *p = 0; diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 469cb231d2..8ff358e26f 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -1,20 +1,20 @@ -/* +/* Unix SMB/CIFS implementation. client connect/disconnect routines Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Gerald (Jerry) Carter 2004 Copyright (C) Jeremy Allison 2007 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -35,18 +35,22 @@ struct client_connection { struct client_connection *prev, *next; struct cli_state *cli; - pstring mount; + char *mount; }; /* global state....globals reek! */ - -static pstring username; -static pstring password; -static bool use_kerberos; -static bool got_pass; -static int signing_state; int max_protocol = PROTOCOL_NT1; +static struct cm_cred_struct { + char *username; + char *password; + bool got_pass; + bool use_kerberos; + int signing_state; +} cm_creds; + +static void cm_set_password(const char *newpass); + static int port; static int name_type = 0x20; static bool have_ip; @@ -58,31 +62,40 @@ static struct client_connection *connections; Return a connection to a server. ********************************************************************/ -static struct cli_state *do_connect( const char *server, const char *share, - bool show_sessetup ) +static struct cli_state *do_connect(TALLOC_CTX *ctx, + const char *server, + const char *share, + bool show_sessetup) { struct cli_state *c = NULL; struct nmb_name called, calling; const char *server_n; struct sockaddr_storage ss; - pstring servicename; + char *servicename; char *sharename; - fstring newserver, newshare; + char *newserver, *newshare; + const char *username; + const char *password; NTSTATUS status; - + /* make a copy so we don't modify the global string 'service' */ - pstrcpy(servicename, share); + servicename = talloc_strdup(ctx,share); + if (!servicename) { + return NULL; + } sharename = servicename; if (*sharename == '\\') { server = sharename+2; sharename = strchr_m(server,'\\'); - if (!sharename) return NULL; + if (!sharename) { + return NULL; + } *sharename = 0; sharename++; } server_n = server; - + zero_addr(&ss); make_nmb_name(&calling, global_myname(), 0x0); @@ -100,18 +113,19 @@ static struct cli_state *do_connect( const char *server, const char *share, } status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { - d_printf("Connection to %s failed (Error %s)\n", server_n, nt_errstr(status)); + d_printf("Connection to %s failed (Error %s)\n", + server_n, + nt_errstr(status)); return NULL; } c->protocol = max_protocol; - c->use_kerberos = use_kerberos; - cli_setup_signing_state(c, signing_state); - + c->use_kerberos = cm_creds.use_kerberos; + cli_setup_signing_state(c, cm_creds.signing_state); if (!cli_session_request(c, &calling, &called)) { char *p; - d_printf("session request to %s failed (%s)\n", + d_printf("session request to %s failed (%s)\n", called.name, cli_errstr(c)); cli_shutdown(c); c = NULL; @@ -134,24 +148,29 @@ static struct cli_state *do_connect( const char *server, const char *share, return NULL; } - if (!got_pass) { + if (!cm_creds.got_pass) { char *pass = getpass("Password: "); if (pass) { - pstrcpy(password, pass); - got_pass = 1; + cm_set_password(pass); } } - if (!NT_STATUS_IS_OK(cli_session_setup(c, username, + username = cm_creds.username ? cm_creds.username : ""; + password = cm_creds.password ? cm_creds.password : ""; + + if (!NT_STATUS_IS_OK(cli_session_setup(c, username, password, strlen(password), password, strlen(password), lp_workgroup()))) { - /* if a password was not supplied then try again with a null username */ - if (password[0] || !username[0] || use_kerberos || - !NT_STATUS_IS_OK(cli_session_setup(c, "", "", 0, "", 0, - lp_workgroup()))) { + /* If a password was not supplied then + * try again with a null username. */ + if (password[0] || !username[0] || cm_creds.use_kerberos || + !NT_STATUS_IS_OK(cli_session_setup(c, "", + "", 0, + "", 0, + lp_workgroup()))) { d_printf("session setup failed: %s\n", cli_errstr(c)); - if (NT_STATUS_V(cli_nt_error(c)) == + if (NT_STATUS_V(cli_nt_error(c)) == NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) d_printf("did you forget to run kinit?\n"); cli_shutdown(c); @@ -164,55 +183,59 @@ static struct cli_state *do_connect( const char *server, const char *share, if (*c->server_domain) { DEBUG(0,("Domain=[%s] OS=[%s] Server=[%s]\n", c->server_domain,c->server_os,c->server_type)); - } else if (*c->server_os || *c->server_type){ + } else if (*c->server_os || *c->server_type) { DEBUG(0,("OS=[%s] Server=[%s]\n", c->server_os,c->server_type)); - } + } } DEBUG(4,(" session setup ok\n")); /* here's the fun part....to support 'msdfs proxy' shares - (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL + (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL here before trying to connect to the original share. check_dfs_proxy() will fail if it is a normal share. */ - if ( (c->capabilities & CAP_DFS) && cli_check_msdfs_proxy( c, sharename, newserver, newshare ) ) { + if ((c->capabilities & CAP_DFS) && + cli_check_msdfs_proxy(ctx, c, sharename, + &newserver, &newshare)) { cli_shutdown(c); - return do_connect( newserver, newshare, False ); + return do_connect(ctx, newserver, newshare, false); } /* must be a normal share */ - if (!cli_send_tconX(c, sharename, "?????", password, strlen(password)+1)) { + if (!cli_send_tconX(c, sharename, "?????", + password, strlen(password)+1)) { d_printf("tree connect failed: %s\n", cli_errstr(c)); cli_shutdown(c); return NULL; } DEBUG(4,(" tconx ok\n")); - return c; } /**************************************************************************** ****************************************************************************/ -static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) +static void cli_cm_set_mntpoint(struct cli_state *c, const char *mnt) { struct client_connection *p; int i; - for ( p=connections,i=0; p; p=p->next,i++ ) { - if ( strequal(p->cli->desthost, c->desthost) && strequal(p->cli->share, c->share) ) + for (p=connections,i=0; p; p=p->next,i++) { + if (strequal(p->cli->desthost, c->desthost) && + strequal(p->cli->share, c->share)) { break; + } } - - if ( p ) { + + if (p) { char *name = clean_name(NULL, p->mount); if (!name) { return; } - pstrcpy( p->mount, name ); + p->mount = talloc_strdup(p, name); TALLOC_FREE(name); } } @@ -220,19 +243,21 @@ static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt ) /**************************************************************************** ****************************************************************************/ -const char *cli_cm_get_mntpoint( struct cli_state *c ) +const char *cli_cm_get_mntpoint(struct cli_state *c) { struct client_connection *p; int i; - for ( p=connections,i=0; p; p=p->next,i++ ) { - if ( strequal(p->cli->desthost, c->desthost) && strequal(p->cli->share, c->share) ) + for (p=connections,i=0; p; p=p->next,i++) { + if (strequal(p->cli->desthost, c->desthost) && + strequal(p->cli->share, c->share)) { break; + } } - - if ( p ) + + if (p) { return p->mount; - + } return NULL; } @@ -240,27 +265,29 @@ const char *cli_cm_get_mntpoint( struct cli_state *c ) Add a new connection to the list ********************************************************************/ -static struct cli_state *cli_cm_connect( const char *server, +static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, + const char *server, const char *share, bool show_hdr) { struct client_connection *node; - node = SMB_CALLOC_ARRAY( struct client_connection, 1); + /* NB This must be the null context here... JRA. */ + node = TALLOC_ZERO_ARRAY(NULL, struct client_connection, 1); if (!node) { return NULL; } - node->cli = do_connect( server, share, show_hdr ); + node->cli = do_connect(ctx, server, share, show_hdr); if ( !node->cli ) { - SAFE_FREE( node ); + TALLOC_FREE( node ); return NULL; } DLIST_ADD( connections, node ); - cli_cm_set_mntpoint( node->cli, "" ); + cli_cm_set_mntpoint(node->cli, ""); return node->cli; @@ -270,35 +297,37 @@ static struct cli_state *cli_cm_connect( const char *server, Return a connection to a server. ********************************************************************/ -static struct cli_state *cli_cm_find( const char *server, const char *share ) +static struct cli_state *cli_cm_find(const char *server, const char *share) { struct client_connection *p; - for ( p=connections; p; p=p->next ) { - if ( strequal(server, p->cli->desthost) && strequal(share,p->cli->share) ) + for (p=connections; p; p=p->next) { + if ( strequal(server, p->cli->desthost) && + strequal(share,p->cli->share)) { return p->cli; + } } return NULL; } /**************************************************************************** - open a client connection to a \\server\share. Set's the current *cli + Open a client connection to a \\server\share. Set's the current *cli global variable as a side-effect (but only if the connection is successful). ****************************************************************************/ -struct cli_state *cli_cm_open(const char *server, +struct cli_state *cli_cm_open(TALLOC_CTX *ctx, + const char *server, const char *share, bool show_hdr) { struct cli_state *c; - + /* try to reuse an existing connection */ - c = cli_cm_find( server, share ); - - if ( !c ) { - c = cli_cm_connect(server, share, show_hdr); + c = cli_cm_find(server, share); + if (!c) { + c = cli_cm_connect(ctx, server, share, show_hdr); } return c; @@ -307,17 +336,16 @@ struct cli_state *cli_cm_open(const char *server, /**************************************************************************** ****************************************************************************/ -void cli_cm_shutdown( void ) +void cli_cm_shutdown(void) { - struct client_connection *p, *x; - for ( p=connections; p; ) { - cli_shutdown( p->cli ); + for (p=connections; p;) { + cli_shutdown(p->cli); x = p; p = p->next; - SAFE_FREE( x ); + TALLOC_FREE(x); } connections = NULL; @@ -333,7 +361,7 @@ void cli_cm_display(void) int i; for ( p=connections,i=0; p; p=p->next,i++ ) { - d_printf("%d:\tserver=%s, share=%s\n", + d_printf("%d:\tserver=%s, share=%s\n", i, p->cli->desthost, p->cli->share ); } } @@ -341,23 +369,32 @@ void cli_cm_display(void) /**************************************************************************** ****************************************************************************/ -void cli_cm_set_credentials( struct user_auth_info *user ) +static void cm_set_password(const char *newpass) +{ + SAFE_FREE(cm_creds.password); + cm_creds.password = SMB_STRDUP(newpass); + if (cm_creds.password) { + cm_creds.got_pass = true; + } +} + +void cli_cm_set_credentials(struct user_auth_info *user) { - pstrcpy( username, user->username ); - - if ( user->got_pass ) { - pstrcpy( password, user->password ); - got_pass = True; - } - - use_kerberos = user->use_kerberos; - signing_state = user->signing_state; + SAFE_FREE(cm_creds.username); + cm_creds.username = SMB_STRDUP(user->username); + + if (user->got_pass) { + cm_set_password(user->password); + } + + cm_creds.use_kerberos = user->use_kerberos; + cm_creds.signing_state = user->signing_state; } /**************************************************************************** ****************************************************************************/ -void cli_cm_set_port( int port_number ) +void cli_cm_set_port(int port_number) { port = port_number; } @@ -365,7 +402,7 @@ void cli_cm_set_port( int port_number ) /**************************************************************************** ****************************************************************************/ -void cli_cm_set_dest_name_type( int type ) +void cli_cm_set_dest_name_type(int type) { name_type = type; } @@ -383,12 +420,23 @@ void cli_cm_set_dest_ss(struct sockaddr_storage *pss) split a dfs path into the server, share name, and extrapath components **********************************************************************/ -static void split_dfs_path( const char *nodepath, fstring server, fstring share, pstring extrapath ) +static void split_dfs_path(TALLOC_CTX *ctx, + const char *nodepath, + char **pp_server, + char **pp_share, + char **pp_extrapath) { char *p, *q; - pstring path; + char *path; - pstrcpy( path, nodepath ); + *pp_server = NULL; + *pp_share = NULL; + *pp_extrapath = NULL; + + path = talloc_strdup(ctx, nodepath); + if (!path) { + return; + } if ( path[0] != '\\' ) { return; @@ -407,32 +455,36 @@ static void split_dfs_path( const char *nodepath, fstring server, fstring share, if (q != NULL) { *q = '\0'; q++; - pstrcpy( extrapath, q ); + *pp_extrapath = talloc_strdup(ctx, q); } else { - pstrcpy( extrapath, '\0' ); + *pp_extrapath = talloc_strdup(ctx, ""); } - - fstrcpy( share, p ); - fstrcpy( server, &path[1] ); + + *pp_share = talloc_strdup(ctx, p); + *pp_server = talloc_strdup(ctx, &path[1]); } /**************************************************************************** Return the original path truncated at the directory component before - the first wildcard character. Trust the caller to provide a NULL + the first wildcard character. Trust the caller to provide a NULL terminated string ****************************************************************************/ -static void clean_path(const char *path, pstring path_out) +static char *clean_path(TALLOC_CTX *ctx, const char *path) { size_t len; char *p1, *p2, *p; - + char *path_out; + /* No absolute paths. */ while (IS_DIRECTORY_SEP(*path)) { path++; } - pstrcpy(path_out, path); + path_out = talloc_strdup(ctx, path); + if (!path_out) { + return NULL; + } p1 = strchr_m(path_out, '*'); p2 = strchr_m(path_out, '?'); @@ -462,21 +514,24 @@ static void clean_path(const char *path, pstring path_out) if ( (len > 0) && IS_DIRECTORY_SEP(path_out[len-1])) { path_out[len-1] = '\0'; } + + return path_out; } /**************************************************************************** ****************************************************************************/ -static void cli_dfs_make_full_path( struct cli_state *cli, - const char *dir, - pstring path_out) +static char *cli_dfs_make_full_path(TALLOC_CTX *ctx, + struct cli_state *cli, + const char *dir) { /* Ensure the extrapath doesn't start with a separator. */ while (IS_DIRECTORY_SEP(*dir)) { dir++; } - pstr_sprintf( path_out, "\\%s\\%s\\%s", cli->desthost, cli->share, dir); + return talloc_asprintf(ctx, "\\%s\\%s\\%s", + cli->desthost, cli->share, dir); } /******************************************************************** @@ -489,21 +544,22 @@ static bool cli_dfs_check_error( struct cli_state *cli, NTSTATUS status ) /* only deal with DS when we negotiated NT_STATUS codes and UNICODE */ - if ( !( (flgs2&FLAGS2_32_BIT_ERROR_CODES) && (flgs2&FLAGS2_UNICODE_STRINGS) ) ) - return False; + if (!((flgs2&FLAGS2_32_BIT_ERROR_CODES) && + (flgs2&FLAGS2_UNICODE_STRINGS))) + return false; - if ( NT_STATUS_EQUAL( status, NT_STATUS(IVAL(cli->inbuf,smb_rcls)) ) ) - return True; + if (NT_STATUS_EQUAL(status, NT_STATUS(IVAL(cli->inbuf,smb_rcls)))) + return true; - return False; + return false; } /******************************************************************** - get the dfs referral link + Get the dfs referral link. ********************************************************************/ -bool cli_dfs_get_referral( struct cli_state *cli, - const char *path, +bool cli_dfs_get_referral(struct cli_state *cli, + const char *path, CLIENT_DFS_REFERRAL**refs, size_t *num_refs, uint16 *consumed) @@ -511,19 +567,19 @@ bool cli_dfs_get_referral( struct cli_state *cli, unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_GET_DFS_REFERRAL; - char param[sizeof(pstring)+2]; - pstring data; + char param[1024+2]; char *rparam=NULL, *rdata=NULL; char *p; size_t pathlen = 2*(strlen(path)+1); uint16 num_referrals; CLIENT_DFS_REFERRAL *referrals = NULL; - + memset(param, 0, sizeof(param)); SSVAL(param, 0, 0x03); /* max referral level */ p = ¶m[2]; - p += clistr_push(cli, p, path, MIN(pathlen, sizeof(param)-2), STR_TERMINATE); + p += clistr_push(cli, p, path, MIN(pathlen, sizeof(param)-2), + STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, @@ -531,283 +587,366 @@ bool cli_dfs_get_referral( struct cli_state *cli, -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ + NULL, 0, cli->max_xmit /* data, length, max */ )) { - return False; + return false; } if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { - return False; + return false; } - + *consumed = SVAL( rdata, 0 ); num_referrals = SVAL( rdata, 2 ); - + if ( num_referrals != 0 ) { uint16 ref_version; uint16 ref_size; int i; uint16 node_offset; - referrals = SMB_XMALLOC_ARRAY( CLIENT_DFS_REFERRAL, num_referrals ); + referrals = SMB_XMALLOC_ARRAY( CLIENT_DFS_REFERRAL, + num_referrals); /* start at the referrals array */ - + p = rdata+8; for ( i=0; idfsroot) { *targetcli = rootcli; - pstrcpy( targetpath, path ); - return True; + *pp_targetpath = talloc_strdup(ctx, path); + if (!*pp_targetpath) { + return false; + } + return true; } *targetcli = NULL; /* Send a trans2_query_path_info to check for a referral. */ - clean_path(path, cleanpath); - cli_dfs_make_full_path(rootcli, cleanpath, dfs_path ); + cleanpath = clean_path(ctx, path); + if (!cleanpath) { + return false; + } + + dfs_path = cli_dfs_make_full_path(ctx, rootcli, cleanpath); + if (!dfs_path) { + return false; + } - if (cli_qpathinfo_basic( rootcli, dfs_path, &sbuf, &attributes ) ) { + if (cli_qpathinfo_basic( rootcli, dfs_path, &sbuf, &attributes)) { /* This is an ordinary path, just return it. */ *targetcli = rootcli; - pstrcpy( targetpath, path ); + *pp_targetpath = talloc_strdup(ctx, path); + if (!*pp_targetpath) { + return false; + } goto done; } /* Special case where client asked for a path that does not exist */ - if ( cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND) ) { + if (cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { *targetcli = rootcli; - pstrcpy( targetpath, path ); + *pp_targetpath = talloc_strdup(ctx, path); + if (!*pp_targetpath) { + return false; + } goto done; } /* We got an error, check for DFS referral. */ - if ( !cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED)) { - return False; + if (!cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED)) { + return false; } /* Check for the referral. */ - if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) ) { - return False; + if (!(cli_ipc = cli_cm_open(ctx, rootcli->desthost, "IPC$", false))) { + return false; } - - if ( !cli_dfs_get_referral(cli_ipc, dfs_path, &refs, &num_refs, &consumed) - || !num_refs ) { - return False; + + if (!cli_dfs_get_referral(cli_ipc, dfs_path, &refs, + &num_refs, &consumed) || !num_refs) { + return false; } - + /* Just store the first referral for now. */ - split_dfs_path( refs[0].dfspath, server, share, extrapath ); + split_dfs_path(ctx, refs[0].dfspath, &server, &share, &extrapath ); SAFE_FREE(refs); + if (!server || !share) { + return false; + } + /* Make sure to recreate the original string including any wildcards. */ - - cli_dfs_make_full_path( rootcli, path, dfs_path); - pathlen = strlen( dfs_path )*2; - consumed = MIN(pathlen, consumed ); - pstrcpy( targetpath, &dfs_path[consumed/2] ); + + dfs_path = cli_dfs_make_full_path(ctx, rootcli, path); + if (!dfs_path) { + return false; + } + pathlen = strlen(dfs_path)*2; + consumed = MIN(pathlen, consumed); + *pp_targetpath = talloc_strdup(ctx, &dfs_path[consumed/2]); + if (!*pp_targetpath) { + return false; + } dfs_path[consumed/2] = '\0'; /* - * targetpath is now the unconsumed part of the path. - * dfs_path is now the consumed part of the path (in \server\share\path format). + * *pp_targetpath is now the unconsumed part of the path. + * dfs_path is now the consumed part of the path + * (in \server\share\path format). */ /* Open the connection to the target server & share */ - - if ( (*targetcli = cli_cm_open(server, share, False)) == NULL ) { + if ((*targetcli = cli_cm_open(ctx, server, share, false)) == NULL) { d_printf("Unable to follow dfs referral [\\%s\\%s]\n", server, share ); - return False; + return false; } - - if (strlen(extrapath) > 0) { - string_append(&temppath, extrapath); - string_append(&temppath, targetpath); - pstrcpy( targetpath, temppath ); + + if (extrapath && strlen(extrapath) > 0) { + *pp_targetpath = talloc_asprintf(ctx, + "%s%s", + extrapath, + *pp_targetpath); + if (!*pp_targetpath) { + return false; + } } - + /* parse out the consumed mount path */ /* trim off the \server\share\ */ ppath = dfs_path; if (*ppath != '\\') { - d_printf("cli_resolve_path: dfs_path (%s) not in correct format.\n", + d_printf("cli_resolve_path: " + "dfs_path (%s) not in correct format.\n", dfs_path ); - return False; + return false; } ppath++; /* Now pointing at start of server name. */ - + if ((ppath = strchr_m( dfs_path, '\\' )) == NULL) { - return False; + return false; } ppath++; /* Now pointing at start of share name. */ if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) { - return False; + return false; } ppath++; /* Now pointing at path component. */ - pstr_sprintf( newmount, "%s\\%s", mountpt, ppath ); + newmount = talloc_asprintf(ctx, "%s\\%s", mountpt, ppath ); + if (!newmount) { + return false; + } - cli_cm_set_mntpoint( *targetcli, newmount ); + cli_cm_set_mntpoint(*targetcli, newmount); - /* Check for another dfs referral, note that we are not + /* Check for another dfs referral, note that we are not checking for loops here. */ - if ( !strequal( targetpath, "\\" ) && !strequal( targetpath, "/")) { - if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) { + if (!strequal(*pp_targetpath, "\\") && !strequal(*pp_targetpath, "/")) { + if (cli_resolve_path(ctx, + newmount, + *targetcli, + *pp_targetpath, + &newcli, + &newpath)) { /* * When cli_resolve_path returns true here it's always * returning the complete path in newpath, so we're done * here. */ *targetcli = newcli; - pstrcpy( targetpath, newpath ); - return True; + *pp_targetpath = newpath; + return true; } } done: - /* If returning True ensure we return a dfs root full path. */ - if ( (*targetcli)->dfsroot ) { - pstrcpy(dfs_path, targetpath ); - cli_dfs_make_full_path( *targetcli, dfs_path, targetpath); + /* If returning true ensure we return a dfs root full path. */ + if ((*targetcli)->dfsroot) { + dfs_path = talloc_strdup(ctx, *pp_targetpath); + if (!dfs_path) { + return false; + } + *pp_targetpath = cli_dfs_make_full_path(ctx, *targetcli, dfs_path); } - return True; + return true; +} + +/******************************************************************** + Temporary hack - remove when pstring is dead. JRA. +********************************************************************/ + +bool cli_resolve_path_pstring( const char *mountpt, + struct cli_state *rootcli, + const char *path, + struct cli_state **targetcli, + pstring targetpath) +{ + char *tpath = NULL; + TALLOC_CTX *ctx = talloc_stackframe(); + bool ret = cli_resolve_path(ctx, + mountpt, + rootcli, + path, + targetcli, + &tpath); + if (tpath) { + pstrcpy(targetpath, tpath); + } + return ret; } /******************************************************************** ********************************************************************/ -bool cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, - fstring newserver, fstring newshare ) +bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, + struct cli_state *cli, + const char *sharename, + char **pp_newserver, + char **pp_newshare ) { CLIENT_DFS_REFERRAL *refs = NULL; size_t num_refs; uint16 consumed; - pstring fullpath; + char *fullpath = NULL; bool res; uint16 cnum; - pstring newextrapath; - - if ( !cli || !sharename ) - return False; + char *newextrapath = NULL; + + if (!cli || !sharename) { + return false; + } cnum = cli->cnum; /* special case. never check for a referral on the IPC$ share */ - if ( strequal( sharename, "IPC$" ) ) { - return False; + if (strequal(sharename, "IPC$")) { + return false; } - + /* send a trans2_query_path_info to check for a referral */ - - pstr_sprintf( fullpath, "\\%s\\%s", cli->desthost, sharename ); + + fullpath = talloc_asprintf(ctx, "\\%s\\%s", cli->desthost, sharename ); + if (!fullpath) { + return false; + } /* check for the referral */ if (!cli_send_tconX(cli, "IPC$", "IPC", NULL, 0)) { - return False; + return false; } res = cli_dfs_get_referral(cli, fullpath, &refs, &num_refs, &consumed); if (!cli_tdis(cli)) { - SAFE_FREE( refs ); - return False; + SAFE_FREE(refs); + return false; } cli->cnum = cnum; - if (!res || !num_refs ) { - SAFE_FREE( refs ); - return False; + if (!res || !num_refs) { + SAFE_FREE(refs); + return false; + } + + split_dfs_path(ctx, refs[0].dfspath, pp_newserver, + pp_newshare, &newextrapath ); + + SAFE_FREE(refs); + + if (!pp_newserver || !pp_newshare) { + return false; } - - split_dfs_path( refs[0].dfspath, newserver, newshare, newextrapath ); /* check that this is not a self-referral */ - if ( strequal( cli->desthost, newserver ) && strequal( sharename, newshare ) ) { - SAFE_FREE( refs ); - return False; + if (strequal(cli->desthost, *pp_newserver) && + strequal(sharename, *pp_newshare)) { + return false; } - - SAFE_FREE( refs ); - - return True; + + return true; } diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 4f2503731d..b20b1cadaf 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1055,7 +1055,7 @@ smbc_open_ctx(SMBCCTX *context, { fstring server, share, user, password, workgroup; pstring path; - pstring targetpath; + char *targetpath = NULL; struct cli_state *targetcli; SMBCSRV *srv = NULL; SMBCFILE *file = NULL; @@ -1102,18 +1102,14 @@ smbc_open_ctx(SMBCCTX *context, if (errno == EPERM) errno = EACCES; TALLOC_FREE(frame); return NULL; /* smbc_server sets errno */ - + } /* Hmmm, the test for a directory is suspect here ... FIXME */ if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { - fd = -1; - - } - else { - + } else { file = SMB_MALLOC_P(SMBCFILE); if (!file) { @@ -1127,7 +1123,7 @@ smbc_open_ctx(SMBCCTX *context, ZERO_STRUCTP(file); /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) + if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); @@ -1135,7 +1131,7 @@ smbc_open_ctx(SMBCCTX *context, return NULL; } /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ - + if ((fd = cli_open(targetcli, targetpath, flags, context->internal->_share_mode)) < 0) { @@ -1248,7 +1244,8 @@ smbc_read_ctx(SMBCCTX *context, { int ret; fstring server, share, user, password; - pstring path, targetpath; + pstring path; + char *targetpath = NULL; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); @@ -1307,17 +1304,17 @@ smbc_read_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>read: resolving %s\n", path);*/ - if (!cli_resolve_path("", file->srv->cli, path, - &targetcli, targetpath)) + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); if (ret < 0) { @@ -1350,15 +1347,15 @@ smbc_write_ctx(SMBCCTX *context, int ret; off_t offset; fstring server, share, user, password; - pstring path, targetpath; + pstring path; + char *targetpath = NULL; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); /* First check all pointers before dereferencing them */ - + if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1366,17 +1363,14 @@ smbc_write_ctx(SMBCCTX *context, } if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; TALLOC_FREE(frame); return -1; - } /* Check that the buffer exists ... */ if (buf == NULL) { - errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1398,22 +1392,19 @@ smbc_write_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>write: resolving %s\n", path);*/ - if (!cli_resolve_path("", file->srv->cli, path, - &targetcli, targetpath)) - { + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; } /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); if (ret <= 0) { - errno = smbc_errno(context, targetcli); TALLOC_FREE(frame); return -1; @@ -1425,7 +1416,7 @@ smbc_write_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; /* Success, 0 bytes of data ... */ } - + /* * Routine to close() a file ... */ @@ -1434,9 +1425,10 @@ static int smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { - SMBCSRV *srv; + SMBCSRV *srv; fstring server, share, user, password; - pstring path, targetpath; + pstring path; + char *targetpath = NULL; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); @@ -1450,7 +1442,6 @@ smbc_close_ctx(SMBCCTX *context, } if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; TALLOC_FREE(frame); return -1; @@ -1459,7 +1450,6 @@ smbc_close_ctx(SMBCCTX *context, /* IS a dir ... */ if (!file->file) { - TALLOC_FREE(frame); return (context->closedir)(context, file); @@ -1478,11 +1468,10 @@ smbc_close_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>close: resolving %s\n", path);*/ - if (!cli_resolve_path("", file->srv->cli, path, - &targetcli, targetpath)) - { + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -1531,18 +1520,16 @@ smbc_getatr(SMBCCTX * context, SMB_INO_T *ino) { pstring fixedpath; - pstring targetpath; + char *targetpath = NULL; struct cli_state *targetcli; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } /* path fixup for . and .. */ @@ -1555,14 +1542,14 @@ smbc_getatr(SMBCCTX * context, trim_string(fixedpath, NULL, "\\."); } DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - - if (!cli_resolve_path( "", srv->cli, fixedpath, &targetcli, targetpath)) - { + + if (!cli_resolve_path(frame, "", srv->cli, fixedpath, + &targetcli, &targetpath)) { d_printf("Couldn't resolve %s\n", path); TALLOC_FREE(frame); return False; } - + if (!srv->no_pathinfo2 && cli_qpathinfo2(targetcli, targetpath, create_time_ts, @@ -1710,7 +1697,8 @@ smbc_unlink_ctx(SMBCCTX *context, const char *fname) { fstring server, share, user, password, workgroup; - pstring path, targetpath; + pstring path; + char *targetpath; struct cli_state *targetcli; SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); @@ -1758,8 +1746,8 @@ smbc_unlink_ctx(SMBCCTX *context, } /*d_printf(">>>unlink: resolving %s\n", path);*/ - if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) - { + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -1835,16 +1823,16 @@ smbc_rename_ctx(SMBCCTX *ocontext, fstring workgroup; pstring path1; pstring path2; - pstring targetpath1; - pstring targetpath2; + char *targetpath1; + char *targetpath2; struct cli_state *targetcli1; struct cli_state *targetcli2; SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!ocontext || !ncontext || + if (!ocontext || !ncontext || !ocontext->internal || !ncontext->internal || - !ocontext->internal->_initialized || + !ocontext->internal->_initialized || !ncontext->internal->_initialized) { errno = EINVAL; /* Best I can think of ... */ @@ -1852,15 +1840,14 @@ smbc_rename_ctx(SMBCCTX *ocontext, return -1; } - - if (!oname || !nname) { + if (!oname || !nname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); smbc_parse_path(ocontext, oname, @@ -1887,9 +1874,7 @@ smbc_rename_ctx(SMBCCTX *ocontext, if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { - /* Can't rename across file systems, or users?? */ - errno = EXDEV; TALLOC_FREE(frame); return -1; @@ -1906,27 +1891,26 @@ smbc_rename_ctx(SMBCCTX *ocontext, } /*d_printf(">>>rename: resolving %s\n", path1);*/ - if (!cli_resolve_path( "", srv->cli, path1, &targetcli1, targetpath1)) - { + if (!cli_resolve_path(frame, "", srv->cli, path1, + &targetcli1, &targetpath1)) { d_printf("Could not resolve %s\n", path1); TALLOC_FREE(frame); return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ /*d_printf(">>>rename: resolving %s\n", path2);*/ - if (!cli_resolve_path( "", srv->cli, path2, &targetcli2, targetpath2)) - { + if (!cli_resolve_path(frame, "", srv->cli, path2, + &targetcli2, &targetpath2)) { d_printf("Could not resolve %s\n", path2); TALLOC_FREE(frame); return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ - + if (strcmp(targetcli1->desthost, targetcli2->desthost) || strcmp(targetcli1->share, targetcli2->share)) { /* can't rename across file systems */ - errno = EXDEV; TALLOC_FREE(frame); return -1; @@ -1962,17 +1946,16 @@ smbc_lseek_ctx(SMBCCTX *context, { SMB_OFF_T size; fstring server, share, user, password; - pstring path, targetpath; + pstring path; + char *targetpath; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { @@ -2010,28 +1993,26 @@ smbc_lseek_ctx(SMBCCTX *context, user, sizeof(user), password, sizeof(password), NULL, 0)) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>lseek: resolving %s\n", path);*/ - if (!cli_resolve_path("", file->srv->cli, path, - &targetcli, targetpath)) - { + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; } /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ - + if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, - &size, NULL, NULL, NULL, NULL, NULL)) + &size, NULL, NULL, NULL, NULL, NULL)) { SMB_OFF_T b_size = size; if (!cli_getattrE(targetcli, file->cli_fd, - NULL, &b_size, NULL, NULL, NULL)) + NULL, &b_size, NULL, NULL, NULL)) { errno = EINVAL; TALLOC_FREE(frame); @@ -2238,14 +2219,13 @@ smbc_fstat_ctx(SMBCCTX *context, fstring user; fstring password; pstring path; - pstring targetpath; + char *targetpath; struct cli_state *targetcli; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -2253,7 +2233,6 @@ smbc_fstat_ctx(SMBCCTX *context, } if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; TALLOC_FREE(frame); return -1; @@ -2261,7 +2240,6 @@ smbc_fstat_ctx(SMBCCTX *context, } if (!file->file) { - TALLOC_FREE(frame); return (context->fstatdir)(context, file, st); @@ -2280,11 +2258,10 @@ smbc_fstat_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path("", file->srv->cli, path, - &targetcli, targetpath)) - { + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -2979,7 +2956,7 @@ smbc_opendir_ctx(SMBCCTX *context, * The server and share are specified ... work from * there ... */ - pstring targetpath; + char *targetpath; struct cli_state *targetcli; /* We connect to the server and list the directory */ @@ -3006,9 +2983,8 @@ smbc_opendir_ctx(SMBCCTX *context, p = path + strlen(path); pstrcat(path, "\\*"); - if (!cli_resolve_path("", srv->cli, path, - &targetcli, targetpath)) - { + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); if (dir) { SAFE_FREE(dir->fname); @@ -3017,7 +2993,7 @@ smbc_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, (void *)dir) < 0) { @@ -3358,13 +3334,13 @@ smbc_mkdir_ctx(SMBCCTX *context, fstring user; fstring password; fstring workgroup; - pstring path, targetpath; + pstring path; + char *targetpath; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->internal || + if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -3372,13 +3348,12 @@ smbc_mkdir_ctx(SMBCCTX *context, } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_mkdir(%s)\n", fname)); if (smbc_parse_path(context, fname, @@ -3407,8 +3382,8 @@ smbc_mkdir_ctx(SMBCCTX *context, } /*d_printf(">>>mkdir: resolving %s\n", path);*/ - if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) - { + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -3462,13 +3437,12 @@ smbc_rmdir_ctx(SMBCCTX *context, fstring password; fstring workgroup; pstring path; - pstring targetpath; + char *targetpath; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->internal || + if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -3476,13 +3450,12 @@ smbc_rmdir_ctx(SMBCCTX *context, } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_rmdir(%s)\n", fname)); if (smbc_parse_path(context, fname, @@ -3512,8 +3485,8 @@ smbc_rmdir_ctx(SMBCCTX *context, } /*d_printf(">>>rmdir: resolving %s\n", path);*/ - if (!cli_resolve_path( "", srv->cli, path, &targetcli, targetpath)) - { + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; -- cgit From 5b184c3525b19e1c13c229a5e05503d7ab7cc234 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 17:47:31 -0800 Subject: Remove pstrings from clifile.c. Jeremy. (This used to be commit d5658914c2d6ec878d9a11f8a1fa57f1697362e3) --- source3/libsmb/clifile.c | 61 ++++++++++++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 25 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 27ad8364ee..e438b6d926 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -30,8 +30,8 @@ static bool cli_link_internal(struct cli_state *cli, const char *oldname, const unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; - char param[sizeof(pstring)+6]; - pstring data; + char param[1024+6]; + char data[1024]; char *rparam=NULL, *rdata=NULL; char *p; size_t oldlen = 2*(strlen(oldname)+1); @@ -173,7 +173,7 @@ bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, unsigned int param_len = 0; unsigned int data_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - char param[sizeof(pstring)+6]; + char param[1024+6]; char *rparam=NULL, *rdata=NULL; char *p; @@ -181,7 +181,7 @@ bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_POSIX_ACL); p += 6; - p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, name, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, @@ -222,7 +222,7 @@ bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu unsigned int param_len = 0; unsigned int data_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - char param[sizeof(pstring)+6]; + char param[1024+6]; char *rparam=NULL, *rdata=NULL; char *p; @@ -232,7 +232,7 @@ bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC); p += 6; - p += clistr_push(cli, p, name, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, name, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, @@ -316,7 +316,7 @@ static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; - char param[sizeof(pstring)+6]; + char param[1024+6]; char data[100]; char *rparam=NULL, *rdata=NULL; char *p; @@ -615,7 +615,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, bool flag) unsigned int data_len = 1; unsigned int param_len = 6; uint16 setup = TRANSACT2_SETFILEINFO; - pstring param; + char param[6]; unsigned char data; char *rparam=NULL, *rdata=NULL; @@ -1359,7 +1359,7 @@ bool cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) if (!cli_receive_smb(cli)) { return False; } - + if (cli_is_error(cli)) { return False; } @@ -1370,16 +1370,22 @@ bool cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) /**************************************************************************** Check for existance of a dir. ****************************************************************************/ + bool cli_chkpath(struct cli_state *cli, const char *path) { - pstring path2; + char *path2 = NULL; char *p; - - pstrcpy(path2,path); + TALLOC_CTX *frame = talloc_stackframe(); + + path2 = talloc_strdup(frame, path); + if (!path2) { + TALLOC_FREE(frame); + return false; + } trim_char(path2,'\0','\\'); if (!*path2) *path2 = '\\'; - + memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBcheckpath); @@ -1393,9 +1399,12 @@ bool cli_chkpath(struct cli_state *cli, const char *path) cli_send_smb(cli); if (!cli_receive_smb(cli)) { + TALLOC_FREE(frame); return False; } + TALLOC_FREE(frame); + if (cli_is_error(cli)) return False; return True; @@ -1466,20 +1475,22 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) p = smb_buf(cli->inbuf); p += 4; len = smb_buflen(cli->inbuf) - 4; - if (len <= 0) return -1; + if (len <= 0 || len > PATH_MAX) return -1; if (tmp_path) { - pstring path2; - clistr_pull(cli, path2, p, - sizeof(path2), len, STR_ASCII); - *tmp_path = SMB_STRDUP(path2); + char *path2 = SMB_MALLOC(len+1); + if (!path2) { + return -1; + } + clistr_pull(cli, path2, p, + len+1, len, STR_ASCII); + *tmp_path = path2; } return SVAL(cli->inbuf,smb_vwv0); } - -/* +/* send a raw ioctl - used by the torture code */ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB *blob) @@ -1577,7 +1588,7 @@ bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_nam { uint16 setup = TRANSACT2_SETPATHINFO; unsigned int param_len = 0; - char param[sizeof(pstring)+6]; + char param[1024+6]; size_t srclen = 2*(strlen(path)+1); char *p; @@ -1743,14 +1754,14 @@ bool cli_get_ea_list_path(struct cli_state *cli, const char *path, { uint16 setup = TRANSACT2_QPATHINFO; unsigned int param_len = 0; - char param[sizeof(pstring)+6]; + char param[1024+6]; char *p; p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); p += 6; - p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, path, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); return cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list); @@ -1837,7 +1848,7 @@ static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; - char param[sizeof(pstring)+6]; + char param[1024+6]; char data[18]; char *rparam=NULL, *rdata=NULL; char *p; @@ -1916,7 +1927,7 @@ static bool cli_posix_unlink_internal(struct cli_state *cli, const char *fname, unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; - char param[sizeof(pstring)+6]; + char param[1024+6]; char data[2]; char *rparam=NULL, *rdata=NULL; char *p; -- cgit From 810f760afd814c869df91b47ae3c5de958edb355 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Nov 2007 13:09:04 -0800 Subject: Add talloc versions of all the next_token() functions. Now I can really start removing fixed length strings... Jeremy. (This used to be commit 0ae61e26547e594e94037d4474a008221e5df8cf) --- source3/libsmb/libsmbclient.c | 1333 ++++++++++++++++++++++------------------- 1 file changed, 728 insertions(+), 605 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b20b1cadaf..c81002b9cc 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -132,6 +132,7 @@ hex2int( unsigned int _char ) /* * smbc_urldecode() + * and smbc_urldecode_talloc() (internal fn.) * * Convert strings of %xx to their single character equivalent. Each 'x' must * be a valid hexadecimal digit, or that % sequence is left undecoded. @@ -141,53 +142,87 @@ hex2int( unsigned int _char ) * Returns the number of % sequences which could not be converted due to lack * of two following hexadecimal digits. */ -int -smbc_urldecode(char *dest, char * src, size_t max_dest_len) +static int +smbc_urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) { - int old_length = strlen(src); - int i = 0; - int err_count = 0; - pstring temp; - char * p; + int old_length = strlen(src); + int i = 0; + int err_count = 0; + size_t newlen = 1; + char *p, *dest; + + *pp_dest = NULL; + if (old_length == 0) { + return 0; + } - if ( old_length == 0 ) { - return 0; - } + for (i = 0; i < old_length; ) { + unsigned char character = src[i++]; + + if (character == '%') { + int a = i+1 < old_length ? hex2int(src[i]) : -1; + int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - p = temp; - while ( i < old_length ) { - unsigned char character = src[ i++ ]; + /* Replace valid sequence */ + if (a != -1 && b != -1) { + /* Replace valid %xx sequence with %dd */ + character = (a * 16) + b; + if (character == '\0') { + break; /* Stop at %00 */ + } + i += 2; + } else { + err_count++; + } + } + newlen++; + } + + dest = TALLOC_ARRAY(ctx, char, newlen); + if (!dest) { + return err_count; + } + + err_count = 0; + for (p = dest, i = 0; i < old_length; ) { + unsigned char character = src[i++]; if (character == '%') { - int a = i+1 < old_length ? hex2int( src[i] ) : -1; - int b = i+1 < old_length ? hex2int( src[i+1] ) : -1; + int a = i+1 < old_length ? hex2int(src[i]) : -1; + int b = i+1 < old_length ? hex2int(src[i+1]) : -1; /* Replace valid sequence */ if (a != -1 && b != -1) { - /* Replace valid %xx sequence with %dd */ character = (a * 16) + b; - if (character == '\0') { break; /* Stop at %00 */ } - i += 2; } else { - err_count++; } } - *p++ = character; } *p = '\0'; + *pp_dest = dest; + return err_count; +} - strncpy(dest, temp, max_dest_len - 1); - dest[max_dest_len - 1] = '\0'; +int +smbc_urldecode(char *dest, char *src, size_t max_dest_len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + char *pdest; + int ret = smbc_urldecode_talloc(frame, &pdest, src); - return err_count; + if (pdest) { + strlcpy(dest, pdest, max_dest_len); + } + TALLOC_FREE(frame); + return ret; } /* @@ -199,7 +234,7 @@ smbc_urldecode(char *dest, char * src, size_t max_dest_len) * Returns the remaining buffer length. */ int -smbc_urlencode(char * dest, char * src, int max_dest_len) +smbc_urlencode(char *dest, char *src, int max_dest_len) { char hex[] = "0123456789ABCDEF"; @@ -226,7 +261,7 @@ smbc_urlencode(char * dest, char * src, int max_dest_len) *dest++ = '\0'; max_dest_len--; - + return max_dest_len; } @@ -270,37 +305,46 @@ smbc_urlencode(char * dest, char * src, int max_dest_len) static const char *smbc_prefix = "smb:"; static int -smbc_parse_path(SMBCCTX *context, +smbc_parse_path(TALLOC_CTX *ctx, + SMBCCTX *context, const char *fname, - char *workgroup, int workgroup_len, - char *server, int server_len, - char *share, int share_len, - char *path, int path_len, - char *user, int user_len, - char *password, int password_len, - char *options, int options_len) + char **pp_workgroup, + char **pp_server, + char **pp_share, + char **pp_path, + char **pp_user, + char **pp_password, + char **pp_options) { - static pstring s; - pstring userinfo; + char *s; const char *p; char *q, *r; int len; - server[0] = share[0] = path[0] = user[0] = password[0] = (char)0; + /* Ensure these returns are at least valid pointers. */ + *pp_server = talloc_strdup(ctx, ""); + *pp_share = talloc_strdup(ctx, ""); + *pp_path = talloc_strdup(ctx, ""); + *pp_user = talloc_strdup(ctx, ""); + *pp_password = talloc_strdup(ctx, ""); + + if (!*pp_server || !*pp_share || !*pp_path || + !*pp_user || !*pp_password) { + return -1; + } /* * Assume we wont find an authentication domain to parse, so default * to the workgroup in the provided context. */ - if (workgroup != NULL) { - strncpy(workgroup, context->workgroup, workgroup_len - 1); - workgroup[workgroup_len - 1] = '\0'; - } + if (pp_workgroup != NULL) { + *pp_workgroup = talloc_strdup(ctx, context->workgroup); + } - if (options != NULL && options_len > 0) { - options[0] = (char)0; - } - pstrcpy(s, fname); + if (pp_options) { + *pp_options = talloc_strdup(ctx, ""); + } + s = talloc_strdup(ctx, fname); /* see if it has the right prefix */ len = strlen(smbc_prefix); @@ -313,10 +357,8 @@ smbc_parse_path(SMBCCTX *context, /* Watch the test below, we are testing to see if we should exit */ if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { - DEBUG(1, ("Invalid path (does not begin with smb://")); return -1; - } p += 2; /* Skip the double slash */ @@ -325,17 +367,19 @@ smbc_parse_path(SMBCCTX *context, if ((q = strrchr(p, '?')) != NULL ) { /* There are options. Null terminate here and point to them */ *q++ = '\0'; - + DEBUG(4, ("Found options '%s'", q)); - /* Copy the options */ - if (options != NULL && options_len > 0) { - safe_strcpy(options, q, options_len - 1); - } - } + /* Copy the options */ + if (*pp_options != NULL) { + TALLOC_FREE(*pp_options); + *pp_options = talloc_strdup(ctx, q); + } + } - if (*p == (char)0) - goto decoding; + if (*p == '\0') { + goto decoding; + } if (*p == '/') { int wl = strlen(context->workgroup); @@ -344,13 +388,16 @@ smbc_parse_path(SMBCCTX *context, wl = 16; } - strncpy(server, context->workgroup, wl); - server[wl] = '\0'; + *pp_server = talloc_strdup(ctx, context->workgroup); + if (!*pp_server) { + return -1; + } + *pp_server[wl] = '\0'; return 0; } /* - * ok, its for us. Now parse out the server, share etc. + * ok, its for us. Now parse out the server, share etc. * * However, we want to parse out [[domain;]user[:password]@] if it * exists ... @@ -360,81 +407,78 @@ smbc_parse_path(SMBCCTX *context, q = strchr_m(p, '@'); r = strchr_m(p, '/'); if (q && (!r || q < r)) { - pstring username, passwd, domain; - const char *u = userinfo; - - next_token_no_ltrim(&p, userinfo, "@", sizeof(fstring)); + char *userinfo = NULL; + const char *u; - username[0] = passwd[0] = domain[0] = 0; + next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@"); + if (!userinfo) { + return -1; + } + u = userinfo; if (strchr_m(u, ';')) { - - next_token_no_ltrim(&u, domain, ";", sizeof(fstring)); - + char *workgroup; + next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); + if (!workgroup) { + return -1; + } + if (pp_workgroup) { + *pp_workgroup = workgroup; + } } if (strchr_m(u, ':')) { - - next_token_no_ltrim(&u, username, ":", sizeof(fstring)); - - pstrcpy(passwd, u); - - } - else { - - pstrcpy(username, u); - + next_token_no_ltrim_talloc(ctx, &u, pp_user, ":"); + if (!*pp_user) { + return -1; + } + *pp_password = talloc_strdup(ctx, u); + if (!*pp_password) { + return -1; + } + } else { + *pp_user = talloc_strdup(ctx, u); + if (!*pp_user) { + return -1; + } } - - if (domain[0] && workgroup) { - strncpy(workgroup, domain, workgroup_len - 1); - workgroup[workgroup_len - 1] = '\0'; - } - - if (username[0]) { - strncpy(user, username, user_len - 1); - user[user_len - 1] = '\0'; - } - - if (passwd[0]) { - strncpy(password, passwd, password_len - 1); - password[password_len - 1] = '\0'; - } - } - if (!next_token(&p, server, "/", sizeof(fstring))) { - + if (!next_token_talloc(ctx, &p, pp_server, "/")) { return -1; - } - if (*p == (char)0) goto decoding; /* That's it ... */ - - if (!next_token(&p, share, "/", sizeof(fstring))) { + if (*p == (char)0) { + goto decoding; /* That's it ... */ + } + if (!next_token_talloc(ctx, &p, pp_share, "/")) { return -1; - } /* * Prepend a leading slash if there's a file path, as required by * NetApp filers. */ - *path = '\0'; if (*p != '\0') { - *path = '/'; - safe_strcpy(path + 1, p, path_len - 2); - } - - all_string_sub(path, "/", "\\", 0); + *pp_path = talloc_asprintf(ctx, + "\\%s", + p); + } else { + *pp_path = talloc_strdup(ctx, ""); + } + if (!*pp_path) { + return -1; + } + string_replace(*pp_path, '/', '\\'); decoding: - (void) smbc_urldecode(path, path, path_len); - (void) smbc_urldecode(server, server, server_len); - (void) smbc_urldecode(share, share, share_len); - (void) smbc_urldecode(user, user, user_len); - (void) smbc_urldecode(password, password, password_len); + + (void) smbc_urldecode_talloc(ctx, pp_path, *pp_path); + (void) smbc_urldecode_talloc(ctx, pp_server, *pp_server); + (void) smbc_urldecode_talloc(ctx, pp_share, *pp_share); + (void) smbc_urldecode_talloc(ctx, pp_user, *pp_user); + (void) smbc_urldecode_talloc(ctx, pp_password, *pp_password); return 0; } @@ -558,7 +602,7 @@ find_server(SMBCCTX *context, { SMBCSRV *srv; int auth_called = 0; - + check_server_cache: srv = (context->callbacks.get_cached_srv_fn)(context, server, share, @@ -646,7 +690,6 @@ smbc_server(SMBCCTX *context, struct cli_state *c; struct nmb_name called, calling; const char *server_n = server; - pstring ipenv; struct sockaddr_storage ss; int tried_reverse = 0; int port_try_first; @@ -740,7 +783,6 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); again: - slprintf(ipenv,sizeof(ipenv)-1,"HOST_%s", server_n); zero_addr(&ss); @@ -1053,8 +1095,8 @@ smbc_open_ctx(SMBCCTX *context, int flags, mode_t mode) { - fstring server, share, user, password, workgroup; - pstring path; + char *server, *share, *user, *password, *workgroup; + char *path; char *targetpath = NULL; struct cli_state *targetcli; SMBCSRV *srv = NULL; @@ -1079,30 +1121,37 @@ smbc_open_ctx(SMBCCTX *context, } - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; TALLOC_FREE(frame); - return NULL; + return NULL; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { - if (errno == EPERM) errno = EACCES; TALLOC_FREE(frame); return NULL; /* smbc_server sets errno */ - } /* Hmmm, the test for a directory is suspect here ... FIXME */ @@ -1113,18 +1162,15 @@ smbc_open_ctx(SMBCCTX *context, file = SMB_MALLOC_P(SMBCFILE); if (!file) { - errno = ENOMEM; TALLOC_FREE(frame); return NULL; - } ZERO_STRUCTP(file); /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) - { + if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); TALLOC_FREE(frame); @@ -1243,8 +1289,8 @@ smbc_read_ctx(SMBCCTX *context, size_t count) { int ret; - fstring server, share, user, password; - pstring path; + char *server, *share, *user, *password; + char *path; char *targetpath = NULL; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); @@ -1262,7 +1308,6 @@ smbc_read_ctx(SMBCCTX *context, if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1272,7 +1317,6 @@ smbc_read_ctx(SMBCCTX *context, DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; TALLOC_FREE(frame); return -1; @@ -1284,7 +1328,6 @@ smbc_read_ctx(SMBCCTX *context, /* Check that the buffer exists ... */ if (buf == NULL) { - errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1292,14 +1335,16 @@ smbc_read_ctx(SMBCCTX *context, } /*d_printf(">>>read: parsing %s\n", file->fname);*/ - if (smbc_parse_path(context, file->fname, - NULL, 0, - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + if (smbc_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1307,8 +1352,7 @@ smbc_read_ctx(SMBCCTX *context, /*d_printf(">>>read: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) - { + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; @@ -1346,8 +1390,8 @@ smbc_write_ctx(SMBCCTX *context, { int ret; off_t offset; - fstring server, share, user, password; - pstring path; + char *server, *share, *user, *password; + char *path; char *targetpath = NULL; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); @@ -1380,14 +1424,16 @@ smbc_write_ctx(SMBCCTX *context, offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ /*d_printf(">>>write: parsing %s\n", file->fname);*/ - if (smbc_parse_path(context, file->fname, - NULL, 0, - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + if (smbc_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1426,8 +1472,8 @@ smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { SMBCSRV *srv; - fstring server, share, user, password; - pstring path; + char *server, *share, *user, *password; + char *path; char *targetpath = NULL; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); @@ -1438,32 +1484,31 @@ smbc_close_ctx(SMBCCTX *context, errno = EINVAL; TALLOC_FREE(frame); return -1; - } if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; - } /* IS a dir ... */ if (!file->file) { TALLOC_FREE(frame); return (context->closedir)(context, file); - } /*d_printf(">>>close: parsing %s\n", file->fname);*/ - if (smbc_parse_path(context, file->fname, - NULL, 0, - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + if (smbc_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1510,16 +1555,16 @@ smbc_close_ctx(SMBCCTX *context, static bool smbc_getatr(SMBCCTX * context, SMBCSRV *srv, - char *path, + char *path, uint16 *mode, - SMB_OFF_T *size, + SMB_OFF_T *size, struct timespec *create_time_ts, struct timespec *access_time_ts, struct timespec *write_time_ts, struct timespec *change_time_ts, SMB_INO_T *ino) { - pstring fixedpath; + char *fixedpath; char *targetpath = NULL; struct cli_state *targetcli; time_t write_time; @@ -1533,11 +1578,20 @@ smbc_getatr(SMBCCTX * context, } /* path fixup for . and .. */ - if (strequal(path, ".") || strequal(path, "..")) - pstrcpy(fixedpath, "\\"); - else - { - pstrcpy(fixedpath, path); + if (strequal(path, ".") || strequal(path, "..")) { + fixedpath = talloc_strdup(frame, "\\"); + if (!fixedpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } else { + fixedpath = talloc_strdup(frame, path); + if (!fixedpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } trim_string(fixedpath, NULL, "\\.."); trim_string(fixedpath, NULL, "\\."); } @@ -1696,8 +1750,8 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) { - fstring server, share, user, password, workgroup; - pstring path; + char *server, *share, *user, *password, *workgroup; + char *path; char *targetpath; struct cli_state *targetcli; SMBCSRV *srv = NULL; @@ -1705,7 +1759,6 @@ smbc_unlink_ctx(SMBCCTX *context, if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; @@ -1713,33 +1766,40 @@ smbc_unlink_ctx(SMBCCTX *context, } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { - TALLOC_FREE(frame); return -1; /* smbc_server sets errno */ @@ -1812,17 +1872,17 @@ smbc_rename_ctx(SMBCCTX *ocontext, SMBCCTX *ncontext, const char *nname) { - fstring server1; - fstring share1; - fstring server2; - fstring share2; - fstring user1; - fstring user2; - fstring password1; - fstring password2; - fstring workgroup; - pstring path1; - pstring path2; + char *server1; + char *share1; + char *server2; + char *share2; + char *user1; + char *user2; + char *password1; + char *password2; + char *workgroup; + char *path1; + char *path2; char *targetpath1; char *targetpath2; struct cli_state *targetcli1; @@ -1834,43 +1894,66 @@ smbc_rename_ctx(SMBCCTX *ocontext, !ocontext->internal || !ncontext->internal || !ocontext->internal->_initialized || !ncontext->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - } if (!oname || !nname) { errno = EINVAL; TALLOC_FREE(frame); return -1; - } DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - smbc_parse_path(ocontext, oname, - workgroup, sizeof(workgroup), - server1, sizeof(server1), - share1, sizeof(share1), - path1, sizeof(path1), - user1, sizeof(user1), - password1, sizeof(password1), - NULL, 0); + if (smbc_parse_path(frame, + ocontext, + oname, + &workgroup, + &server1, + &share1, + &path1, + &user1, + &password1, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } - if (user1[0] == (char)0) fstrcpy(user1, ocontext->user); + if (!user1 || user1[0] == (char)0) { + user1 = talloc_strdup(frame, ocontext->user); + if (!user1) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } - smbc_parse_path(ncontext, nname, - NULL, 0, - server2, sizeof(server2), - share2, sizeof(share2), - path2, sizeof(path2), - user2, sizeof(user2), - password2, sizeof(password2), - NULL, 0); + if (smbc_parse_path(frame, + ncontext, + nname, + NULL, + &server2, + &share2, + &path2, + &user2, + &password2, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } - if (user2[0] == (char)0) fstrcpy(user2, ncontext->user); + if (!user2 || user2[0] == (char)0) { + user2 = talloc_strdup(frame, ncontext->user); + if (!user2) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { @@ -1878,13 +1961,11 @@ smbc_rename_ctx(SMBCCTX *ocontext, errno = EXDEV; TALLOC_FREE(frame); return -1; - } srv = smbc_server(ocontext, True, server1, share1, workgroup, user1, password1); if (!srv) { - TALLOC_FREE(frame); return -1; @@ -1945,8 +2026,8 @@ smbc_lseek_ctx(SMBCCTX *context, int whence) { SMB_OFF_T size; - fstring server, share, user, password; - pstring path; + char *server, *share, *user, *password; + char *path; char *targetpath; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); @@ -1985,18 +2066,20 @@ smbc_lseek_ctx(SMBCCTX *context, case SEEK_END: /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ - if (smbc_parse_path(context, file->fname, - NULL, 0, - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } + if (smbc_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } /*d_printf(">>>lseek: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, @@ -2117,12 +2200,12 @@ smbc_stat_ctx(SMBCCTX *context, struct stat *st) { SMBCSRV *srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; struct timespec write_time_ts; struct timespec access_time_ts; struct timespec change_time_ts; @@ -2137,33 +2220,39 @@ smbc_stat_ctx(SMBCCTX *context, errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + DEBUG(4, ("smbc_stat(%s)\n", fname)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame,context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -2173,17 +2262,15 @@ smbc_stat_ctx(SMBCCTX *context, return -1; /* errno set by smbc_server */ } - if (!smbc_getatr(context, srv, path, &mode, &size, + if (!smbc_getatr(context, srv, path, &mode, &size, NULL, &access_time_ts, &write_time_ts, &change_time_ts, &ino)) { - errno = smbc_errno(context, srv->cli); TALLOC_FREE(frame); return -1; - } st->st_ino = ino; @@ -2214,11 +2301,11 @@ smbc_fstat_ctx(SMBCCTX *context, struct timespec write_time_ts; SMB_OFF_T size; uint16 mode; - fstring server; - fstring share; - fstring user; - fstring password; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *path; char *targetpath; struct cli_state *targetcli; SMB_INO_T ino = 0; @@ -2229,31 +2316,30 @@ smbc_fstat_ctx(SMBCCTX *context, errno = EINVAL; TALLOC_FREE(frame); return -1; - } if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; - } if (!file->file) { TALLOC_FREE(frame); return (context->fstatdir)(context, file, st); - } /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ - if (smbc_parse_path(context, file->fname, - NULL, 0, - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + if (smbc_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -2467,14 +2553,13 @@ list_fn(const char *name, * Disk share = 0x00000000 * Print share = 0x00000001 * Comms share = 0x00000002 (obsolete?) - * IPC$ share = 0x00000003 + * IPC$ share = 0x00000003 * * administrative shares: * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 */ - + if (dir->dir_type == SMBC_FILE_SHARE) { - switch (type) { case 0 | 0x80000000: case 0: @@ -2604,9 +2689,9 @@ smbc_opendir_ctx(SMBCCTX *context, const char *fname) { int saved_errno; - fstring server, share, user, password, options; - pstring workgroup; - pstring path; + char *server, *share, *user, *password, *options; + char *workgroup; + char *path; uint16 mode; char *p; SMBCSRV *srv = NULL; @@ -2631,14 +2716,16 @@ smbc_opendir_ctx(SMBCCTX *context, return NULL; } - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - options, sizeof(options))) { + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + &options)) { DEBUG(4, ("no valid path\n")); errno = EINVAL + 8194; TALLOC_FREE(frame); @@ -3314,7 +3401,7 @@ smbc_getdents_ctx(SMBCCTX *context, if (rem == count) return 0; - else + else return count - rem; } @@ -3329,12 +3416,12 @@ smbc_mkdir_ctx(SMBCCTX *context, mode_t mode) { SMBCSRV *srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; char *targetpath; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); @@ -3344,32 +3431,39 @@ smbc_mkdir_ctx(SMBCCTX *context, errno = EINVAL; TALLOC_FREE(frame); return -1; - } if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; - } DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -3417,7 +3511,6 @@ rmdir_list_fn(const char *mnt, { if (strncmp(finfo->name, ".", 1) != 0 && strncmp(finfo->name, "..", 2) != 0) { - smbc_rmdir_dirempty = False; } } @@ -3431,12 +3524,12 @@ smbc_rmdir_ctx(SMBCCTX *context, const char *fname) { SMBCSRV *srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; char *targetpath; struct cli_state *targetcli; TALLOC_CTX *frame = talloc_stackframe(); @@ -3446,33 +3539,39 @@ smbc_rmdir_ctx(SMBCCTX *context, errno = EINVAL; TALLOC_FREE(frame); return -1; - } if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; - } DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) - { + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -3501,12 +3600,17 @@ smbc_rmdir_ctx(SMBCCTX *context, if (errno == EACCES) { /* Check if the dir empty or not */ /* Local storage to avoid buffer overflows */ - pstring lpath; + char *lpath; smbc_rmdir_dirempty = True; /* Make this so ... */ - pstrcpy(lpath, targetpath); - pstrcat(lpath, "\\*"); + lpath = talloc_asprintf(frame, "%s\\*", + targetpath); + if (!lpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } if (cli_list(targetcli, lpath, aDIR | aSYSTEM | aHIDDEN, @@ -3514,7 +3618,7 @@ smbc_rmdir_ctx(SMBCCTX *context, /* Fix errno to ignore latest error ... */ DEBUG(5, ("smbc_rmdir: " - "cli_list returned an error: %d\n", + "cli_list returned an error: %d\n", smbc_errno(context, targetcli))); errno = EACCES; @@ -3668,18 +3772,15 @@ smbc_lseekdir_ctx(SMBCCTX *context, /* This may need to be changed if we change the format of the list */ if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) { - errno = EINVAL; /* Bad entry */ TALLOC_FREE(frame); return -1; - } dir->dir_next = list_ent; TALLOC_FREE(frame); - return 0; - + return 0; } /* @@ -3692,18 +3793,14 @@ smbc_fstatdir_ctx(SMBCCTX *context, struct stat *st) { - if (!context || !context->internal || + if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; return -1; - } /* No code yet ... */ - return 0; - } static int @@ -3712,48 +3809,53 @@ smbc_chmod_ctx(SMBCCTX *context, mode_t newmode) { SMBCSRV *srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; uint16 mode; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -3775,7 +3877,7 @@ smbc_chmod_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + TALLOC_FREE(frame); return 0; } @@ -3786,33 +3888,29 @@ smbc_utimes_ctx(SMBCCTX *context, struct timeval *tbuf) { SMBCSRV *srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; time_t access_time; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + if (tbuf == NULL) { access_time = write_time = time(NULL); } else { @@ -3820,8 +3918,7 @@ smbc_utimes_ctx(SMBCCTX *context, write_time = tbuf[1].tv_sec; } - if (DEBUGLVL(4)) - { + if (DEBUGLVL(4)) { char *p; char atimebuf[32]; char mtimebuf[32]; @@ -3842,20 +3939,29 @@ smbc_utimes_ctx(SMBCCTX *context, fname, atimebuf, mtimebuf); } - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -3944,7 +4050,7 @@ ace_compare(SEC_ACE *ace1, * referenced MS document). We'll now sort by characteristics that * just seems reasonable. */ - + if (ace1->type != ace2->type) { return ace2->type - ace1->type; } @@ -4010,17 +4116,17 @@ convert_sid_to_string(struct cli_state *ipc_cli, if (numeric) { return; /* no lookup desired */ } - + if (!pipe_hnd) { return; } - + /* Ask LSA to convert the sid to a name */ ctx = talloc_stackframe(); if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, - pol, 1, sid, &domains, + pol, 1, sid, &domains, &names, &types)) || !domains || !domains[0] || !names || !names[0]) { TALLOC_FREE(ctx); @@ -4064,8 +4170,8 @@ convert_string_to_sid(struct cli_state *ipc_cli, ctx = talloc_stackframe(); if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, - pol, 1, &str, NULL, 1, &sids, - &types))) { + pol, 1, &str, NULL, 1, &sids, + &types))) { result = False; goto done; } @@ -4372,7 +4478,7 @@ dos_attr_query(SMBCCTX *context, uint16 mode = 0; SMB_INO_T inode = 0; DOS_ATTR_DESC *ret; - + ret = TALLOC_P(ctx, DOS_ATTR_DESC); if (!ret) { errno = ENOMEM; @@ -4381,19 +4487,17 @@ dos_attr_query(SMBCCTX *context, /* Obtain the DOS attributes */ if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename), - &mode, &size, + &mode, &size, &create_time_ts, &access_time_ts, &write_time_ts, - &change_time_ts, + &change_time_ts, &inode)) { - errno = smbc_errno(context, srv->cli); DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); return NULL; - } - + ret->mode = mode; ret->size = size; ret->create_time = convert_timespec_to_time_t(create_time_ts); @@ -4495,7 +4599,7 @@ dos_attr_parse(SMBCCTX *context, } } -/***************************************************** +/***************************************************** Retrieve the acls for a file. *******************************************************/ @@ -4735,7 +4839,7 @@ cacl_get(SMBCCTX *context, sd->revision); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -4947,10 +5051,10 @@ cacl_get(SMBCCTX *context, &write_time_ts, &change_time_ts, &ino)) { - + errno = smbc_errno(context, srv->cli); return -1; - + } create_time = convert_timespec_to_time_t(create_time_ts); @@ -4995,7 +5099,7 @@ cacl_get(SMBCCTX *context, "0x%x", mode); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -5040,7 +5144,7 @@ cacl_get(SMBCCTX *context, (double)size); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -5083,7 +5187,7 @@ cacl_get(SMBCCTX *context, "%lu", create_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -5125,7 +5229,7 @@ cacl_get(SMBCCTX *context, "%lu", access_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -5167,7 +5271,7 @@ cacl_get(SMBCCTX *context, "%lu", write_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -5209,7 +5313,7 @@ cacl_get(SMBCCTX *context, "%lu", change_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -5254,7 +5358,7 @@ cacl_get(SMBCCTX *context, (double) ino); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -5277,8 +5381,7 @@ cacl_get(SMBCCTX *context, return n_used; } - -/***************************************************** +/***************************************************** set the ACLs on a file given an ascii description *******************************************************/ static int @@ -5295,7 +5398,7 @@ cacl_set(TALLOC_CTX *ctx, int err = 0; SEC_DESC *sd = NULL, *old; SEC_ACL *dacl = NULL; - DOM_SID *owner_sid = NULL; + DOM_SID *owner_sid = NULL; DOM_SID *group_sid = NULL; uint32 i, j; size_t sd_size; @@ -5410,7 +5513,7 @@ cacl_set(TALLOC_CTX *ctx, ret = -1; goto failed; } - + for (i=0;sd->dacl && idacl->num_aces;i++) { add_ace(&old->dacl, &sd->dacl->aces[i], ctx); } @@ -5438,7 +5541,7 @@ cacl_set(TALLOC_CTX *ctx, sort_acl(old->dacl); /* Create new security descriptor and set it */ - sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, + sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, owner_sid, group_sid, NULL, dacl, &sd_size); fnum = cli_nt_create(cli, filename, @@ -5464,7 +5567,7 @@ cacl_set(TALLOC_CTX *ctx, if (err != 0) { errno = err; } - + return ret; } @@ -5481,12 +5584,12 @@ smbc_setxattr_ctx(SMBCCTX *context, int ret2; SMBCSRV *srv; SMBCSRV *ipc_srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; POLICY_HND pol; DOS_ATTR_DESC *dad; struct { @@ -5499,38 +5602,43 @@ smbc_setxattr_ctx(SMBCCTX *context, if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (const char*)value)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -5549,7 +5657,7 @@ smbc_setxattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + /* * Are they asking to set the entire set of known attributes? */ @@ -5655,7 +5763,6 @@ smbc_setxattr_ctx(SMBCCTX *context, name+19, (const char *) value); if (! ipc_srv) { - ret = -1; /* errno set by smbc_server() */ } else if (! namevalue) { @@ -5775,12 +5882,12 @@ smbc_getxattr_ctx(SMBCCTX *context, int ret; SMBCSRV *srv; SMBCSRV *ipc_srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; POLICY_HND pol; struct { const char * create_time_attr; @@ -5792,37 +5899,42 @@ smbc_getxattr_ctx(SMBCCTX *context, if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -5841,7 +5953,7 @@ smbc_getxattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->_full_time_names) { /* new-style names */ @@ -5912,48 +6024,53 @@ smbc_removexattr_ctx(SMBCCTX *context, int ret; SMBCSRV *srv; SMBCSRV *ipc_srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; POLICY_HND pol; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -5972,7 +6089,7 @@ smbc_removexattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + if (! ipc_srv) { TALLOC_FREE(frame); return -1; /* errno set by smbc_attr_server */ @@ -6097,40 +6214,38 @@ static SMBCFILE * smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) { - fstring server; - fstring share; - fstring user; - fstring password; - pstring path; + char *server; + char *share; + char *user; + char *password; + char *path; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return NULL; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return NULL; - } - + DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); - if (smbc_parse_path(context, fname, - NULL, 0, - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { + if (smbc_parse_path(frame, + context, + fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return NULL; @@ -6140,7 +6255,6 @@ smbc_open_print_job_ctx(SMBCCTX *context, TALLOC_FREE(frame); return (context->open)(context, fname, O_WRONLY, 666); - } /* @@ -6184,11 +6298,9 @@ smbc_print_file_ctx(SMBCCTX *c_file, /* Try to open the file for reading ... */ if ((long)(fid1 = (c_file->open)(c_file, fname, O_RDONLY, 0666)) < 0) { - DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); TALLOC_FREE(frame); return -1; /* smbc_open sets errno */ - } /* Now, try to open the printer file for writing */ @@ -6245,68 +6357,69 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn) { - SMBCSRV *srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + SMBCSRV *srv; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); - + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + srv = smbc_server(context, True, server, share, workgroup, user, password); if (!srv) { - TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ - } if (cli_print_queue(srv->cli, (void (*)(struct print_job_info *))fn) < 0) { - errno = smbc_errno(context, srv->cli); TALLOC_FREE(frame); return -1; - } - + TALLOC_FREE(frame); return 0; @@ -6321,49 +6434,54 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id) { - SMBCSRV *srv; - fstring server; - fstring share; - fstring user; - fstring password; - fstring workgroup; - pstring path; + SMBCSRV *srv; + char *server; + char *share; + char *user; + char *password; + char *workgroup; + char *path; int err; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } if (!fname) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } - + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - if (smbc_parse_path(context, fname, - workgroup, sizeof(workgroup), - server, sizeof(server), - share, sizeof(share), - path, sizeof(path), - user, sizeof(user), - password, sizeof(password), - NULL, 0)) { - errno = EINVAL; + if (smbc_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; TALLOC_FREE(frame); - return -1; + return -1; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } srv = smbc_server(context, True, server, share, workgroup, user, password); @@ -6392,7 +6510,7 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, } /* - * Get a new empty handle to fill in with your own info + * Get a new empty handle to fill in with your own info */ SMBCCTX * smbc_new_context(void) @@ -6416,7 +6534,6 @@ smbc_new_context(void) ZERO_STRUCTP(context->internal); - /* ADD REASONABLE DEFAULTS */ context->debug = 0; context->timeout = 20000; /* 20 seconds */ @@ -6465,10 +6582,10 @@ smbc_new_context(void) return context; } -/* +/* * Free a context * - * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed + * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed * and thus you'll be leaking memory if not handled properly. * */ @@ -6480,11 +6597,11 @@ smbc_free_context(SMBCCTX *context, errno = EBADF; return 1; } - + if (shutdown_ctx) { SMBCFILE * f; DEBUG(1,("Performing aggressive shutdown.\n")); - + f = context->internal->_files; while (f) { (context->close_fn)(context, f); @@ -6514,7 +6631,7 @@ smbc_free_context(SMBCCTX *context, } } else { - /* This is the polite way */ + /* This is the polite way */ if ((context->callbacks.purge_cached_fn)(context)) { DEBUG(1, ("Could not purge all servers, " "free_context failed.\n")); @@ -6532,14 +6649,14 @@ smbc_free_context(SMBCCTX *context, "free_context failed.\n")); errno = EBUSY; return 1; - } + } } /* Things we have to clean up */ SAFE_FREE(context->workgroup); SAFE_FREE(context->netbios_name); SAFE_FREE(context->user); - + DEBUG(3, ("Context %p succesfully freed\n", context)); SAFE_FREE(context->internal); SAFE_FREE(context); @@ -6669,7 +6786,7 @@ smbc_option_get(SMBCCTX *context, /* - * Initialise the library etc + * Initialise the library etc * * We accept a struct containing handle information. * valid values for info->debug from 0 to 100, @@ -6678,7 +6795,6 @@ smbc_option_get(SMBCCTX *context, SMBCCTX * smbc_init_context(SMBCCTX *context) { - pstring conf; int pid; char *user = NULL; char *home = NULL; @@ -6689,7 +6805,7 @@ smbc_init_context(SMBCCTX *context) } /* Do not initialise the same client twice */ - if (context->internal->_initialized) { + if (context->internal->_initialized) { return 0; } @@ -6712,7 +6828,7 @@ smbc_init_context(SMBCCTX *context) /* Set this to what the user wants */ DEBUGLEVEL = context->debug; - + load_case_tables(); setup_logging("libsmbclient", True); @@ -6722,20 +6838,23 @@ smbc_init_context(SMBCCTX *context) } /* Here we would open the smb.conf file if needed ... */ - + in_client = True; /* FIXME, make a param */ home = getenv("HOME"); if (home) { - slprintf(conf, sizeof(conf), "%s/.smb/smb.conf", home); - if (lp_load(conf, True, False, False, True)) { - conf_loaded = True; - } else { - DEBUG(5, ("Could not load config file: %s\n", - conf)); + char *conf = NULL; + if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) { + if (lp_load(conf, True, False, False, True)) { + conf_loaded = True; + } else { + DEBUG(5, ("Could not load config file: %s\n", + conf)); + } + SAFE_FREE(conf); } } - + if (!conf_loaded) { /* * Well, if that failed, try the dyn_CONFIGFILE @@ -6748,40 +6867,44 @@ smbc_init_context(SMBCCTX *context) DEBUG(5, ("Could not load config file: %s\n", dyn_CONFIGFILE)); } else if (home) { + char *conf; /* * We loaded the global config file. Now lets * load user-specific modifications to the * global config. */ - slprintf(conf, sizeof(conf), - "%s/.smb/smb.conf.append", home); - if (!lp_load(conf, True, False, False, False)) { - DEBUG(10, - ("Could not append config file: " - "%s\n", - conf)); - } + if (asprintf(&conf, + "%s/.smb/smb.conf.append", + home) > 0) { + if (!lp_load(conf, True, False, False, False)) { + DEBUG(10, + ("Could not append config file: " + "%s\n", + conf)); + } + SAFE_FREE(conf); + } } } load_interfaces(); /* Load the list of interfaces ... */ - + reopen_logs(); /* Get logging working ... */ - - /* - * Block SIGPIPE (from lib/util_sock.c: write()) - * It is not needed and should not stop execution + + /* + * Block SIGPIPE (from lib/util_sock.c: write()) + * It is not needed and should not stop execution */ BlockSignals(True, SIGPIPE); - + /* Done with one-time initialisation */ - smbc_initialized = 1; + smbc_initialized = 1; } - + if (!context->user) { /* - * FIXME: Is this the best way to get the user info? + * FIXME: Is this the best way to get the user info? */ user = getenv("USER"); /* walk around as "guest" if no username can be found */ @@ -6827,17 +6950,17 @@ smbc_init_context(SMBCCTX *context) } DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); - + /* shortest timeout is 1 second */ - if (context->timeout > 0 && context->timeout < 1000) + if (context->timeout > 0 && context->timeout < 1000) context->timeout = 1000; /* - * FIXME: Should we check the function pointers here? + * FIXME: Should we check the function pointers here? */ context->internal->_initialized = True; - + return context; } -- cgit From 5886f7c9f67fac052bca70f969d5b5244de23313 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 30 Nov 2007 14:05:53 +0100 Subject: Merge encode_wkssvc_join_password_buffer() from samba4. Guenther (This used to be commit b1d36cdb86978cb31d470fccf2dc24d366835c36) --- source3/libsmb/smbencrypt.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 77ff063cb9..6527cfab28 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -694,3 +694,39 @@ char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in) } +/* encode a wkssvc_PasswordBuffer: + * + * similar to samr_CryptPasswordEx. Different: 8byte confounder (instead of + * 16byte), confounder in front of the 516 byte buffer (instead of after that + * buffer), calling MD5Update() first with session_key and then with confounder + * (vice versa in samr) - Guenther */ + +static void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + const char *pwd, + DATA_BLOB *session_key, + struct wkssvc_PasswordBuffer *pwd_buf) +{ + uint8_t buffer[516]; + struct MD5Context ctx; + + DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); + + int confounder_len = 8; + uint8_t confounder[8]; + + encode_pw_buffer(buffer, pwd, STR_UNICODE); + + generate_random_buffer((uint8_t *)confounder, confounder_len); + + MD5Init(&ctx); + MD5Update(&ctx, session_key->data, session_key->length); + MD5Update(&ctx, confounder, confounder_len); + MD5Final(confounded_session_key.data, &ctx); + + SamOEMhashBlob(buffer, 516, &confounded_session_key); + + memcpy(&pwd_buf->data[0], confounder, confounder_len); + memcpy(&pwd_buf->data[8], buffer, 516); + + data_blob_free(&confounded_session_key); +} -- cgit From c224118ffe8ff0ee9799e80c98cfedfcb266ced5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 30 Nov 2007 14:34:33 +0100 Subject: Make encode_wkssvc_join_password_buffer() non-static. Guenther (This used to be commit 258ef17a266548bc02bed1870fd4ef5a272300b3) --- source3/libsmb/smbencrypt.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6527cfab28..6060669e49 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -701,10 +701,10 @@ char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in) * buffer), calling MD5Update() first with session_key and then with confounder * (vice versa in samr) - Guenther */ -static void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, - const char *pwd, - DATA_BLOB *session_key, - struct wkssvc_PasswordBuffer *pwd_buf) +void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + const char *pwd, + DATA_BLOB *session_key, + struct wkssvc_PasswordBuffer *pwd_buf) { uint8_t buffer[516]; struct MD5Context ctx; -- cgit From 22cf7f5ffa7f37be3c85d226c3477508f88eccd5 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 30 Nov 2007 19:46:25 +0100 Subject: Merge join error codes from Samba 4. Guenther (This used to be commit 88a01bd810c36631272c5db727334bdc6f12f07d) --- source3/libsmb/doserr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 478b87d730..84cc898187 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -69,6 +69,9 @@ werror_code_struct dos_errs[] = { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, + { "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED }, + { "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED }, + { "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER }, { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, -- cgit From b37ae99c3504eba895d91c2671aa88ca04d8440b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Nov 2007 14:19:55 -0800 Subject: Removed all pstrings from libsmbclient. Derryl please check. Passes valgrind tests I've run in examples/libsmbclient. Jeremy. (This used to be commit 9d0034faed939a4534637696f1631ac2da60e4a3) --- source3/libsmb/libsmbclient.c | 111 +++++++++++++++++++++++++----------------- 1 file changed, 65 insertions(+), 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index c81002b9cc..3990a29f4a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -151,11 +151,11 @@ smbc_urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) size_t newlen = 1; char *p, *dest; - *pp_dest = NULL; if (old_length == 0) { return 0; } + *pp_dest = NULL; for (i = 0; i < old_length; ) { unsigned char character = src[i++]; @@ -572,7 +572,7 @@ smbc_remove_unused_server(SMBCCTX * context, if (file->srv == srv) { /* Still used */ DEBUG(3, ("smbc_remove_usused_server: " - "%p still used by %p.\n", + "%p still used by %p.\n", srv, file)); return 1; } @@ -588,24 +588,23 @@ smbc_remove_unused_server(SMBCCTX * context, (context->callbacks.remove_cached_srv_fn)(context, srv); SAFE_FREE(srv); - return 0; } static SMBCSRV * find_server(SMBCCTX *context, - const char *server, - const char *share, - fstring workgroup, - fstring username, - fstring password) + const char *server, + const char *share, + char *workgroup, + char *username, + char *password) { SMBCSRV *srv; int auth_called = 0; check_server_cache: - srv = (context->callbacks.get_cached_srv_fn)(context, server, share, + srv = (context->callbacks.get_cached_srv_fn)(context, server, share, workgroup, username); if (!auth_called && !srv && (!username[0] || !password[0])) { @@ -613,16 +612,16 @@ find_server(SMBCCTX *context, (context->internal->_auth_fn_with_context)( context, server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); + workgroup, strlen(workgroup)+1, + username, strlen(username)+1, + password, strlen(password)+1); } else { (context->callbacks.auth_fn)( server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); - } + workgroup, strlen(workgroup)+1, + username, strlen(username)+1, + password, strlen(password)+1); + } /* * However, smbc_auth_fn may have picked up info relating to @@ -631,13 +630,13 @@ find_server(SMBCCTX *context, */ auth_called = 1; goto check_server_cache; - + } - + if (srv) { if ((context->callbacks.check_server_fn)(context, srv)) { /* - * This server is no good anymore + * This server is no good anymore * Try to remove it and check for more possible * servers in the cache */ @@ -679,12 +678,12 @@ find_server(SMBCCTX *context, static SMBCSRV * smbc_server(SMBCCTX *context, - bool connect_if_not_found, - const char *server, - const char *share, - fstring workgroup, - fstring username, - fstring password) + bool connect_if_not_found, + const char *server, + const char *share, + char *workgroup, + char *username, + char *password) { SMBCSRV *srv=NULL; struct cli_state *c; @@ -729,15 +728,15 @@ smbc_server(SMBCCTX *context, (context->internal->_auth_fn_with_context)( context, server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); + workgroup, strlen(workgroup)+1, + username, strlen(username)+1, + password, strlen(password)+1); } else { (context->callbacks.auth_fn)( server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); + workgroup, strlen(workgroup)+1, + username, strlen(username)+1, + password, strlen(password)+1); } if (! cli_send_tconX(srv->cli, share, "?????", @@ -961,9 +960,9 @@ static SMBCSRV * smbc_attr_server(SMBCCTX *context, const char *server, const char *share, - fstring workgroup, - fstring username, - fstring password, + char *workgroup, + char *username, + char *password, POLICY_HND *pol) { int flags; @@ -989,15 +988,15 @@ smbc_attr_server(SMBCCTX *context, (context->internal->_auth_fn_with_context)( context, server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); + workgroup, strlen(workgroup)+1, + username, strlen(username)+1, + password, strlen(password)+1); } else { (context->callbacks.auth_fn)( server, share, - workgroup, sizeof(fstring), - username, sizeof(fstring), - password, sizeof(fstring)); + workgroup, strlen(workgroup)+1, + username, strlen(username)+1, + password, strlen(password)+1); } } @@ -2744,7 +2743,14 @@ smbc_opendir_ctx(SMBCCTX *context, return NULL; } - if (user[0] == (char)0) fstrcpy(user, context->user); + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + } dir = SMB_MALLOC_P(SMBCFILE); @@ -2847,8 +2853,13 @@ smbc_opendir_ctx(SMBCCTX *context, if ( !cli ) continue; - pstrcpy(workgroup, wg_ptr); - fstrcpy(server, cli->desthost); + workgroup = talloc_strdup(frame, wg_ptr); + server = talloc_strdup(frame, cli->desthost); + if (!workgroup || !server) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } cli_shutdown(cli); DEBUG(4, ("using workgroup %s %s\n", @@ -3053,14 +3064,12 @@ smbc_opendir_ctx(SMBCCTX *context, workgroup, user, password); if (!srv) { - if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); } TALLOC_FREE(frame); return NULL; - } dir->srv = srv; @@ -3068,7 +3077,15 @@ smbc_opendir_ctx(SMBCCTX *context, /* Now, list the files ... */ p = path + strlen(path); - pstrcat(path, "\\*"); + path = talloc_asprintf_append(path, "\\*"); + if (!path) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { @@ -6825,6 +6842,7 @@ smbc_init_context(SMBCCTX *context) * called */ bool conf_loaded = False; + TALLOC_CTX *frame = talloc_stackframe(); /* Set this to what the user wants */ DEBUGLEVEL = context->debug; @@ -6900,6 +6918,7 @@ smbc_init_context(SMBCCTX *context) /* Done with one-time initialisation */ smbc_initialized = 1; + TALLOC_FREE(frame); } if (!context->user) { -- cgit From 4e266bd60fe7c43ba6255314bf2fb56d21e38e93 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Nov 2007 16:13:35 -0800 Subject: Remove pstring from clirap.c. Jeremy. (This used to be commit 6e27663cb44a79f729fa4366e000c43383f6d1b7) --- source3/libsmb/clirap.c | 305 +++++++++++++++++++++++++++++------------------- 1 file changed, 187 insertions(+), 118 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index c877dfa2ab..d8d8f2608c 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -1,19 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. client RAP calls Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Gerald (Jerry) Carter 2004 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -24,21 +24,21 @@ Call a remote api on an arbitrary pipe. takes param, data and setup buffers. ****************************************************************************/ -bool cli_api_pipe(struct cli_state *cli, const char *pipe_name, +bool cli_api_pipe(struct cli_state *cli, const char *pipe_name, uint16 *setup, uint32 setup_count, uint32 max_setup_count, char *params, uint32 param_count, uint32 max_param_count, char *data, uint32 data_count, uint32 max_data_count, char **rparam, uint32 *rparam_count, char **rdata, uint32 *rdata_count) { - cli_send_trans(cli, SMBtrans, - pipe_name, + cli_send_trans(cli, SMBtrans, + pipe_name, 0,0, /* fid, flags */ setup, setup_count, max_setup_count, params, param_count, max_param_count, data, data_count, max_data_count); - return (cli_receive_trans(cli, SMBtrans, + return (cli_receive_trans(cli, SMBtrans, rparam, (unsigned int *)rparam_count, rdata, (unsigned int *)rdata_count)); } @@ -58,7 +58,7 @@ bool cli_api(struct cli_state *cli, 0,0, /* fid, flags */ NULL,0,0, /* Setup, length, max */ param, prcnt, mprcnt, /* Params, length, max */ - data, drcnt, mdrcnt /* Data, length, max */ + data, drcnt, mdrcnt /* Data, length, max */ ); return (cli_receive_trans(cli,SMBtrans, @@ -76,35 +76,35 @@ bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) char *rdata = NULL; char *p; unsigned int rdrcnt,rprcnt; - pstring param; + char param[1024]; memset(param, 0, sizeof(param)); - + /* send a SMBtrans command with api NetWkstaUserLogon */ p = param; SSVAL(p,0,132); /* api number */ p += 2; - pstrcpy_base(p,"OOWb54WrLh",param); + strlcpy(p,"OOWb54WrLh",sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,"WB21BWDWWDDDDDDDzzzD",param); + strlcpy(p,"WB21BWDWWDDDDDDDzzzD",sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); SSVAL(p,0,1); p += 2; - pstrcpy_base(p,user,param); + strlcpy(p,user,sizeof(param)-PTR_DIFF(p,param)); strupper_m(p); p += 21; p++; p += 15; - p++; - pstrcpy_base(p, workstation, param); + p++; + strlcpy(p, workstation,sizeof(param)-PTR_DIFF(p,param)); strupper_m(p); p += 16; SSVAL(p, 0, CLI_BUFFER_SIZE); p += 2; SSVAL(p, 0, CLI_BUFFER_SIZE); p += 2; - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param),1024, /* param, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ @@ -112,7 +112,7 @@ bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) )) { cli->rap_error = rparam? SVAL(rparam,0) : -1; p = rdata; - + if (cli->rap_error == 0) { DEBUG(4,("NetWkstaUserLogon success\n")); cli->privileges = SVAL(p, 24); @@ -122,7 +122,7 @@ bool cli_NetWkstaUserLogon(struct cli_state *cli,char *user, char *workstation) DEBUG(1,("NetwkstaUserLogon gave error %d\n", cli->rap_error)); } } - + SAFE_FREE(rparam); SAFE_FREE(rdata); return (cli->rap_error == 0); @@ -138,16 +138,16 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co char *rdata = NULL; char *p; unsigned int rdrcnt,rprcnt; - pstring param; + char param[1024]; int count = -1; /* now send a SMBtrans command with api RNetShareEnum */ p = param; SSVAL(p,0,0); /* api number */ p += 2; - pstrcpy_base(p,"WrLeh",param); + strlcpy(p,"WrLeh",sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,"B13BWz",param); + strlcpy(p,"B13BWz",sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); SSVAL(p,0,1); /* @@ -156,44 +156,77 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co */ SSVAL(p,2,0xFFE0); p += 4; - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 0xFFE0, /* data, length, maxlen - Win2k needs a small buffer here too ! */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { int res = rparam? SVAL(rparam,0) : -1; - + if (res == 0 || res == ERRmoredata) { int converter=SVAL(rparam,2); int i; - + char *rdata_end = rdata + rdrcnt; + count=SVAL(rparam,4); p = rdata; - - for (i=0;i rdata_end) { + TALLOC_FREE(frame); + break; + } + + sname = p; + type = SVAL(p,14); + comment_offset = IVAL(p,16) & 0xFFFF; + if (comment_offset < 0 || comment_offset > (int)rdrcnt) { + TALLOC_FREE(frame); + break; + } + cmnt = comment_offset?(rdata+comment_offset-converter):""; + + /* Work out the comment length. */ + for (p1 = cmnt, len = 0; *p1 && + p1 < rdata_end; len++) + p1++; + if (!*p1) { + len++; + } + pull_string_talloc(frame,rdata,0, + &s1,sname,14,STR_ASCII); + pull_string_talloc(frame,rdata,0, + &s2,cmnt,len,STR_ASCII); + if (!s1 || !s2) { + TALLOC_FREE(frame); + continue; + } fn(s1, type, s2, state); + + TALLOC_FREE(frame); } } else { DEBUG(4,("NetShareEnum res=%d\n", res)); - } + } } else { DEBUG(4,("NetShareEnum failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return count; } @@ -213,7 +246,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, char *rdata = NULL; unsigned int rdrcnt,rprcnt; char *p; - pstring param; + char param[1024]; int uLevel = 1; int count = -1; size_t len; @@ -224,10 +257,10 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, p = param; SSVAL(p,0,0x68); /* api number */ p += 2; - pstrcpy_base(p,"WrLehDz", param); + strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); - - pstrcpy_base(p,"B16BBDz", param); + + strlcpy(p,"B16BBDz", sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); SSVAL(p,0,uLevel); @@ -236,20 +269,22 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, SIVAL(p,0,stype); p += 4; - len = push_ascii(p, workgroup, sizeof(pstring)-PTR_DIFF(p,param)-1, STR_TERMINATE|STR_UPPER); + len = push_ascii(p, workgroup, sizeof(param)-PTR_DIFF(p,param)-1, + STR_TERMINATE|STR_UPPER); if (len == (size_t)-1) { return false; } p += len; - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { int res = rparam? SVAL(rparam,0) : -1; - + char *rdata_end = rdata + rdrcnt; + if (res == 0 || res == ERRmoredata || (res != -1 && cli_errno(cli) == 0)) { int i; @@ -257,24 +292,55 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, count=SVAL(rparam,4); p = rdata; - + for (i = 0;i < count;i++, p += 26) { - char *sname = p; - int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; - const char *cmnt = comment_offset?(rdata+comment_offset):""; - pstring s1, s2; + char *sname; + int comment_offset; + const char *cmnt; + const char *p1; + char *s1, *s2; + TALLOC_CTX *frame = talloc_stackframe(); + + if (p + 26 > rdata_end) { + TALLOC_FREE(frame); + break; + } + + sname = p; + comment_offset = (IVAL(p,22) & 0xFFFF)-converter; + cmnt = comment_offset?(rdata+comment_offset):""; - if (comment_offset < 0 || comment_offset > (int)rdrcnt) continue; + if (comment_offset < 0 || comment_offset > (int)rdrcnt) { + TALLOC_FREE(frame); + continue; + } + + /* Work out the comment length. */ + for (p1 = cmnt, len = 0; *p1 && + p1 < rdata_end; len++) + p1++; + if (!*p1) { + len++; + } stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - pull_ascii_pstring(s1, sname); - pull_ascii_pstring(s2, cmnt); + pull_string_talloc(frame,rdata,0, + &s1,sname,16,STR_ASCII); + pull_string_talloc(frame,rdata,0, + &s2,cmnt,len,STR_ASCII); + + if (!s1 || !s2) { + TALLOC_FREE(frame); + continue; + } + fn(s1, stype, s2, state); + TALLOC_FREE(frame); } } } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -282,13 +348,13 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, errno = cli_errno(cli); } else { if (!count) { - /* this is a very special case, when the domain master for the + /* this is a very special case, when the domain master for the work group isn't part of the work group itself, there is something wild going on */ errno = ENOENT; } } - + return(count > 0); } @@ -299,7 +365,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, bool cli_oem_change_password(struct cli_state *cli, const char *user, const char *new_password, const char *old_password) { - pstring param; + char param[1024]; unsigned char data[532]; char *p = param; unsigned char old_pw_hash[16]; @@ -317,11 +383,11 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char SSVAL(p,0,214); /* SamOEMChangePassword command. */ p += 2; - pstrcpy_base(p, "zsT", param); + strlcpy(p, "zsT", sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); - pstrcpy_base(p, "B516B16", param); + strlcpy(p, "B516B16", sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); - pstrcpy_base(p,user, param); + strlcpy(p,user, sizeof(param)-PTR_DIFF(p,param)); p = skip_string(param,sizeof(param),p); SSVAL(p,0,532); p += 2; @@ -335,14 +401,14 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char E_deshash(old_password, old_pw_hash); encode_pw_buffer(data, new_password, STR_ASCII); - + #ifdef DEBUG_PASSWORD DEBUG(100,("make_oem_passwd_hash\n")); dump_data(100, data, 516); #endif SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, 516); - /* + /* * Now place the old password hash in the data. */ E_deshash(new_password, new_pw_hash); @@ -350,7 +416,7 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char E_old_pw_hash( new_pw_hash, old_pw_hash, (uchar *)&data[516]); data_len = 532; - + if (cli_send_trans(cli,SMBtrans, PIPE_LANMAN, /* name */ 0,0, /* fid, flags */ @@ -370,11 +436,11 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char user )); return False; } - + if (rparam) { cli->rap_error = SVAL(rparam,0); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -385,17 +451,17 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char Send a qpathinfo call. ****************************************************************************/ -bool cli_qpathinfo(struct cli_state *cli, const char *fname, +bool cli_qpathinfo(struct cli_state *cli, const char *fname, time_t *change_time, time_t *access_time, - time_t *write_time, + time_t *write_time, SMB_OFF_T *size, uint16 *mode) { unsigned int data_len = 0; unsigned int param_len = 0; unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_QPATHINFO; - pstring param; + char param[1024]; char *rparam=NULL, *rdata=NULL; int count=8; bool ret; @@ -406,19 +472,19 @@ bool cli_qpathinfo(struct cli_state *cli, const char *fname, memset(p, 0, 6); SSVAL(p, 0, SMB_INFO_STANDARD); p += 6; - p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); do { - ret = (cli_send_trans(cli, SMBtrans2, + ret = (cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, data_len, cli->max_xmit /* data, length, max */ ) && - cli_receive_trans(cli, SMBtrans2, + cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_len, &rdata, &rdata_len)); if (!cli_is_dos_error(cli)) break; @@ -468,7 +534,7 @@ bool cli_qpathinfo(struct cli_state *cli, const char *fname, Send a setpathinfo call. ****************************************************************************/ -bool cli_setpathinfo(struct cli_state *cli, const char *fname, +bool cli_setpathinfo(struct cli_state *cli, const char *fname, time_t create_time, time_t access_time, time_t write_time, @@ -479,8 +545,8 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, unsigned int param_len = 0; unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_SETPATHINFO; - pstring param; - pstring data; + char param[1024]; + char data[1024]; char *rparam=NULL, *rdata=NULL; int count=8; bool ret; @@ -498,7 +564,7 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, p += 6; /* Add the file name */ - p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); @@ -507,16 +573,15 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, /* * Add the create, last access, modification, and status change times */ - put_long_date(p, create_time); p += 8; put_long_date(p, access_time); p += 8; - + put_long_date(p, write_time); p += 8; - + put_long_date(p, change_time); p += 8; @@ -531,14 +596,14 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, data_len = PTR_DIFF(p, data); do { - ret = (cli_send_trans(cli, SMBtrans2, + ret = (cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ data, data_len, cli->max_xmit /* data, length, max */ ) && - cli_receive_trans(cli, SMBtrans2, + cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_len, &rdata, &rdata_len)); if (!cli_is_dos_error(cli)) break; @@ -566,10 +631,10 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, Send a qpathinfo call with the SMB_QUERY_FILE_ALL_INFO info level. ****************************************************************************/ -bool cli_qpathinfo2(struct cli_state *cli, const char *fname, +bool cli_qpathinfo2(struct cli_state *cli, const char *fname, struct timespec *create_time, struct timespec *access_time, - struct timespec *write_time, + struct timespec *write_time, struct timespec *change_time, SMB_OFF_T *size, uint16 *mode, SMB_INO_T *ino) @@ -577,7 +642,7 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - pstring param; + char param[1024]; char *rparam=NULL, *rdata=NULL; char *p; @@ -585,11 +650,11 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO); p += 6; - p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); - if (!cli_send_trans(cli, SMBtrans2, + if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ @@ -608,7 +673,7 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, if (!rdata || data_len < 22) { return False; } - + if (create_time) { *create_time = interpret_long_date(rdata+0); } @@ -640,21 +705,19 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, Send a qfileinfo QUERY_FILE_NAME_INFO call. ****************************************************************************/ -bool cli_qfilename(struct cli_state *cli, int fnum, - pstring name) +bool cli_qfilename(struct cli_state *cli, int fnum, char *name, size_t namelen) { unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; - pstring param; + char param[4]; char *rparam=NULL, *rdata=NULL; param_len = 4; - memset(param, 0, param_len); SSVAL(param, 0, fnum); SSVAL(param, 2, SMB_QUERY_FILE_NAME_INFO); - if (!cli_send_trans(cli, SMBtrans2, + if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ @@ -674,7 +737,7 @@ bool cli_qfilename(struct cli_state *cli, int fnum, return False; } - clistr_pull(cli, name, rdata+4, sizeof(pstring), IVAL(rdata, 0), STR_UNICODE); + clistr_pull(cli, name, rdata+4, namelen, IVAL(rdata, 0), STR_UNICODE); return True; } @@ -683,18 +746,18 @@ bool cli_qfilename(struct cli_state *cli, int fnum, Send a qfileinfo call. ****************************************************************************/ -bool cli_qfileinfo(struct cli_state *cli, int fnum, +bool cli_qfileinfo(struct cli_state *cli, int fnum, uint16 *mode, SMB_OFF_T *size, struct timespec *create_time, struct timespec *access_time, - struct timespec *write_time, + struct timespec *write_time, struct timespec *change_time, SMB_INO_T *ino) { unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; - pstring param; + char param[4]; char *rparam=NULL, *rdata=NULL; /* if its a win95 server then fail this - win95 totally screws it @@ -703,11 +766,10 @@ bool cli_qfileinfo(struct cli_state *cli, int fnum, param_len = 4; - memset(param, 0, param_len); SSVAL(param, 0, fnum); SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); - if (!cli_send_trans(cli, SMBtrans2, + if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ @@ -758,32 +820,40 @@ bool cli_qfileinfo(struct cli_state *cli, int fnum, Send a qpathinfo BASIC_INFO call. ****************************************************************************/ -bool cli_qpathinfo_basic( struct cli_state *cli, const char *name, +bool cli_qpathinfo_basic( struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbuf, uint32 *attributes ) { unsigned int param_len = 0; unsigned int data_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - char param[sizeof(pstring)+6]; + char param[1024+6]; char *rparam=NULL, *rdata=NULL; char *p; - pstring path; + char *path; int len; - - pstrcpy( path, name ); + TALLOC_CTX *frame = talloc_stackframe(); + + path = talloc_strdup(frame, name); + if (!path) { + TALLOC_FREE(frame); + return false; + } /* cleanup */ - - len = strlen( path ); - if ( path[len-1] == '\\' || path[len-1] == '/') + + len = strlen(path); + if ( path[len-1] == '\\' || path[len-1] == '/') { path[len-1] = '\0'; + } p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO); p += 6; - p += clistr_push(cli, p, path, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, path, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); + TALLOC_FREE(frame); + if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ @@ -809,12 +879,12 @@ bool cli_qpathinfo_basic( struct cli_state *cli, const char *name, set_atimespec(sbuf, interpret_long_date( rdata+8 )); /* Access time. */ set_mtimespec(sbuf, interpret_long_date( rdata+16 )); /* Write time. */ set_ctimespec(sbuf, interpret_long_date( rdata+24 )); /* Change time. */ - + *attributes = IVAL( rdata, 32 ); - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return True; } @@ -827,7 +897,7 @@ bool cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; - pstring param; + char param[4]; char *rparam=NULL, *rdata=NULL; *poutdata = NULL; @@ -840,11 +910,10 @@ bool cli_qfileinfo_test(struct cli_state *cli, int fnum, int level, char **poutd param_len = 4; - memset(param, 0, param_len); SSVAL(param, 0, fnum); SSVAL(param, 2, level); - if (!cli_send_trans(cli, SMBtrans2, + if (!cli_send_trans(cli, SMBtrans2, NULL, /* name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ @@ -883,7 +952,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - pstring param; + char param[1024+6]; char *rparam=NULL, *rdata=NULL; int count=8; char *p; @@ -894,19 +963,19 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin memset(p, 0, 6); SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO); p += 6; - p += clistr_push(cli, p, fname, sizeof(pstring)-6, STR_TERMINATE); + p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); param_len = PTR_DIFF(p, param); do { - ret = (cli_send_trans(cli, SMBtrans2, + ret = (cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, data_len, cli->max_xmit /* data, length, max */ ) && - cli_receive_trans(cli, SMBtrans2, + cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)); if (!ret && cli_is_dos_error(cli)) { -- cgit From e23fea92013a4c1de7f9addcea2b95789ed5c36d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Nov 2007 16:45:44 -0800 Subject: Whitespace cleanup. Jeremy. (This used to be commit 4dfe19be1c3a63b8517c6580c9cd363c7271693d) --- source3/libsmb/clirap2.c | 410 +++++++++++++++++++++++------------------------ 1 file changed, 201 insertions(+), 209 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 6be7fb6a56..f522e13345 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1,20 +1,19 @@ -/* - Samba Unix/Linux SMB client library +/* + Samba Unix/Linux SMB client library More client RAP (SMB Remote Procedure Calls) functions Copyright (C) 2001 Steve French (sfrench@us.ibm.com) Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com) - - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -30,8 +29,8 @@ /* supports all RAP command codes since some */ /* are quite obsolete and a few are specific */ /* to a particular network operating system */ -/* */ -/* Although it has largely been replaced */ +/* */ +/* Although it has largely been replaced */ /* for complex remote admistration and management */ /* (of servers) by the relatively newer */ /* DCE/RPC based remote API (which better handles */ @@ -73,9 +72,9 @@ /* WPrintJobEnum (API num 76, level 2) */ /* WPrintJobDel (API num 81) */ /* */ -/*****************************************************/ +/*****************************************************/ -#include "includes.h" +#include "includes.h" #define WORDSIZE 2 #define DWORDSIZE 4 @@ -128,9 +127,9 @@ static char *make_header(char *param, uint16 apinum, const char *reqfmt, const char *datafmt) { PUTWORD(param,apinum); - if (reqfmt) + if (reqfmt) PUTSTRING(param,reqfmt,0); - else + else *param++ = (char) 0; if (datafmt) @@ -140,7 +139,6 @@ static char *make_header(char *param, uint16 apinum, const char *reqfmt, const c return param; } - /**************************************************************************** call a NetGroupDelete - delete user group from remote server @@ -159,20 +157,20 @@ int cli_NetGroupDelete(struct cli_state *cli, const char *group_name ) +WORDSIZE]; /* reserved word */ /* now send a SMBtrans command with api GroupDel */ - p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL); + p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL); PUTSTRING(p, group_name, RAP_GROUPNAME_LEN); PUTWORD(p,0); /* reserved word MBZ on input */ - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 200, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = GETRES(rparam); - + if (res == 0) { - /* nothing to do */ + /* nothing to do */ } else if ((res == 5) || (res == 65)) { DEBUG(1, ("Access Denied\n")); @@ -182,15 +180,15 @@ int cli_NetGroupDelete(struct cli_state *cli, const char *group_name ) } else { DEBUG(4,("NetGroupDelete res=%d\n", res)); - } + } } else { res = -1; DEBUG(4,("NetGroupDelete failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return res; } @@ -212,7 +210,7 @@ int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) /* offset into data of free format strings. Will be updated */ /* by PUTSTRINGP macro and end up with total data length. */ - int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE; + int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE; char *data; size_t data_size; @@ -226,27 +224,27 @@ int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) } /* now send a SMBtrans command with api WGroupAdd */ - + p = make_header(param, RAP_WGroupAdd, - RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1); + RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1); PUTWORD(p, 1); /* info level */ PUTWORD(p, 0); /* reserved word 0 */ - + p = data; PUTSTRINGF(p, grinfo->group_name, RAP_GROUPNAME_LEN); PUTBYTE(p, 0); /* pad byte 0 */ PUTSTRINGP(p, grinfo->comment, data, soffset); - - if (cli_api(cli, + + if (cli_api(cli, param, sizeof(param), 1024, /* Param, length, maxlen */ data, soffset, sizeof(data), /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = GETRES(rparam); - + if (res == 0) { - /* nothing to do */ + /* nothing to do */ } else if ((res == 5) || (res == 65)) { DEBUG(1, ("Access Denied\n")); } @@ -260,7 +258,7 @@ int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) res = -1; DEBUG(4,("NetGroupAdd failed\n")); } - + SAFE_FREE(data); SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -280,11 +278,11 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char +WORDSIZE]; /* buffer size */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - - + + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WGroupEnum, RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L1); @@ -298,7 +296,7 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char &rdata, &rdrcnt)) { res = GETRES(rparam); cli->rap_error = res; - if(cli->rap_error == 234) + if(cli->rap_error == 234) DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n")); else if (cli->rap_error != 0) { DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error)); @@ -322,14 +320,14 @@ int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char GETSTRINGP(p, comment, rdata, converter); fn(groupname, comment, cli); - } + } } else { DEBUG(4,("NetGroupEnum res=%d\n", res)); } } else { DEBUG(4,("NetGroupEnum no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -347,11 +345,11 @@ int cli_RNetGroupEnum0(struct cli_state *cli, +WORDSIZE]; /* buffer size */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - - + + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WGroupEnum, RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L0); @@ -367,7 +365,7 @@ int cli_RNetGroupEnum0(struct cli_state *cli, &rdata, &rdrcnt)) { res = GETRES(rparam); cli->rap_error = res; - if(cli->rap_error == 234) + if(cli->rap_error == 234) DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n")); else if (cli->rap_error != 0) { DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error)); @@ -385,14 +383,14 @@ int cli_RNetGroupEnum0(struct cli_state *cli, char groupname[RAP_GROUPNAME_LEN]; GETSTRINGF(p, groupname, RAP_GROUPNAME_LEN); fn(groupname, cli); - } + } } else { DEBUG(4,("NetGroupEnum res=%d\n", res)); } } else { DEBUG(4,("NetGroupEnum no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -417,14 +415,14 @@ int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const ch PUTSTRING(p,group_name,RAP_GROUPNAME_LEN); PUTSTRING(p,user_name,RAP_USERNAME_LEN); - if (cli_api(cli, + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 200, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = GETRES(rparam); - + switch(res) { case 0: break; @@ -451,11 +449,11 @@ int cli_NetGroupDelUser(struct cli_state * cli, const char *group_name, const ch res = -1; DEBUG(4,("NetGroupDelUser failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - - return res; + + return res; } int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const char *user_name) @@ -476,14 +474,14 @@ int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const ch PUTSTRING(p,group_name,RAP_GROUPNAME_LEN); PUTSTRING(p,user_name,RAP_USERNAME_LEN); - if (cli_api(cli, + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 200, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = GETRES(rparam); - + switch(res) { case 0: break; @@ -507,10 +505,10 @@ int cli_NetGroupAddUser(struct cli_state * cli, const char *group_name, const ch res = -1; DEBUG(4,("NetGroupAddUser failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return res; } @@ -641,20 +639,20 @@ int cli_NetUserDelete(struct cli_state *cli, const char * user_name ) +WORDSIZE]; /* reserved word */ /* now send a SMBtrans command with api UserDel */ - p = make_header(param, RAP_WUserDel, RAP_NetGroupDel_REQ, NULL); + p = make_header(param, RAP_WUserDel, RAP_NetGroupDel_REQ, NULL); PUTSTRING(p, user_name, RAP_USERNAME_LEN); PUTWORD(p,0); /* reserved word MBZ on input */ - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 200, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = GETRES(rparam); - + if (res == 0) { - /* nothing to do */ + /* nothing to do */ } else if ((res == 5) || (res == 65)) { DEBUG(1, ("Access Denied\n")); @@ -664,15 +662,15 @@ int cli_NetUserDelete(struct cli_state *cli, const char * user_name ) } else { DEBUG(4,("NetUserDelete res=%d\n", res)); - } + } } else { res = -1; DEBUG(4,("NetUserDelete failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return res; } @@ -681,12 +679,9 @@ int cli_NetUserDelete(struct cli_state *cli, const char * user_name ) ****************************************************************************/ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo ) { - - - char *rparam = NULL; char *rdata = NULL; - char *p; + char *p; unsigned int rdrcnt,rprcnt; int res; char param[WORDSIZE /* api number */ @@ -695,7 +690,7 @@ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo ) +WORDSIZE /* info level */ +WORDSIZE /* buffer length */ +WORDSIZE]; /* reserved */ - + char data[1024]; /* offset into data of free format strings. Will be updated */ /* by PUTSTRINGP macro and end up with total data length. */ @@ -732,17 +727,17 @@ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo ) PUTWORD(p, userinfo->userflags); PUTSTRINGP(p, userinfo->logon_script, data, soffset); - if (cli_api(cli, + if (cli_api(cli, param, sizeof(param), 1024, /* Param, length, maxlen */ data, soffset, sizeof(data), /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = GETRES(rparam); - + if (res == 0) { - /* nothing to do */ - } + /* nothing to do */ + } else if ((res == 5) || (res == 65)) { DEBUG(1, ("Access Denied\n")); } @@ -756,7 +751,7 @@ int cli_NetUserAdd(struct cli_state *cli, RAP_USER_INFO_1 * userinfo ) res = -1; DEBUG(4,("NetUserAdd failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -775,10 +770,9 @@ int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char +WORDSIZE]; /* buffer size */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WUserEnum, @@ -828,7 +822,7 @@ int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char } else { DEBUG(4,("NetUserEnum no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -846,10 +840,9 @@ int cli_RNetUserEnum0(struct cli_state *cli, +WORDSIZE]; /* buffer size */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WUserEnum, @@ -887,7 +880,7 @@ int cli_RNetUserEnum0(struct cli_state *cli, } else { DEBUG(4,("NetUserEnum no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -911,31 +904,31 @@ int cli_NetFileClose(struct cli_state *cli, uint32 file_id ) /* now send a SMBtrans command with api RNetShareEnum */ p = make_header(param, RAP_WFileClose2, RAP_WFileClose2_REQ, NULL); - PUTDWORD(p, file_id); - - if (cli_api(cli, + PUTDWORD(p, file_id); + + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 200, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = GETRES(rparam); - + if (res == 0) { - /* nothing to do */ + /* nothing to do */ } else if (res == 2314){ DEBUG(1, ("NetFileClose2 - attempt to close non-existant file open instance\n")); } else { DEBUG(4,("NetFileClose2 res=%d\n", res)); - } + } } else { res = -1; DEBUG(4,("NetFileClose2 failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return res; } @@ -959,11 +952,11 @@ int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const c /* now send a SMBtrans command with api RNetShareEnum */ p = make_header(param, RAP_WFileGetInfo2, - RAP_WFileGetInfo2_REQ, RAP_FILE_INFO_L3); + RAP_WFileGetInfo2_REQ, RAP_FILE_INFO_L3); PUTDWORD(p, file_id); PUTWORD(p, 3); /* info level */ - PUTWORD(p, 0x1000); /* buffer size */ - if (cli_api(cli, + PUTWORD(p, 0x1000); /* buffer size */ + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 0x1000, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ @@ -973,7 +966,7 @@ int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const c if (res == 0 || res == ERRmoredata) { int converter,id, perms, locks; pstring fpath, fuser; - + p = rparam + WORDSIZE; /* skip result */ GETWORD(p, converter); @@ -983,38 +976,38 @@ int cli_NetFileGetInfo(struct cli_state *cli, uint32 file_id, void (*fn)(const c GETWORD(p, locks); GETSTRINGP(p, fpath, rdata, converter); GETSTRINGP(p, fuser, rdata, converter); - + fn(fpath, fuser, perms, locks, id); } else { DEBUG(4,("NetFileGetInfo2 res=%d\n", res)); - } + } } else { res = -1; DEBUG(4,("NetFileGetInfo2 failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return res; } /**************************************************************************** * Call a NetFileEnum2 - list open files on an SMB server -* -* PURPOSE: Remotes a NetFileEnum API call to the current server or target +* +* PURPOSE: Remotes a NetFileEnum API call to the current server or target * server listing the files open via the network (and their * corresponding open instance ids) -* +* * Dependencies: none * -* Parameters: +* Parameters: * cli - pointer to cli_state structure * user - if present, return only files opened by this remote user -* base_path - if present, return only files opened below this +* base_path - if present, return only files opened below this * base path * fn - display function to invoke for each entry in the result -* +* * * Returns: * True - success @@ -1043,35 +1036,35 @@ int cli_NetFileEnum(struct cli_state *cli, const char * user, /* now send a SMBtrans command with api RNetShareEnum */ p = make_header(param, RAP_WFileEnum2, - RAP_WFileEnum2_REQ, RAP_FILE_INFO_L3); + RAP_WFileEnum2_REQ, RAP_FILE_INFO_L3); PUTSTRING(p, base_path, 256); PUTSTRING(p, user, RAP_USERNAME_LEN); PUTWORD(p, 3); /* info level */ - PUTWORD(p, 0xFF00); /* buffer size */ + PUTWORD(p, 0xFF00); /* buffer size */ PUTDWORD(p, 0); /* zero out the resume key */ PUTDWORD(p, 0); /* or is this one the resume key? */ - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 0xFF00, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { int res = GETRES(rparam); - + if (res == 0 || res == ERRmoredata) { int converter, i; p = rparam + WORDSIZE; /* skip result */ GETWORD(p, converter); GETWORD(p, count); - + p = rdata; for (i=0; ipath, data, soffset); PUTSTRINGF(p, sinfo->password, RAP_SPASSWD_LEN); SCVAL(p,-1,0x0A); /* required 0x0A at end of password */ - - if (cli_api(cli, + + if (cli_api(cli, param, sizeof(param), 1024, /* Param, length, maxlen */ data, soffset, sizeof(data), /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = rparam? SVAL(rparam,0) : -1; - + if (res == 0) { - /* nothing to do */ + /* nothing to do */ } else { DEBUG(4,("NetShareAdd res=%d\n", res)); - } + } } else { res = -1; DEBUG(4,("NetShareAdd failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return res; } /**************************************************************************** @@ -1179,35 +1172,34 @@ int cli_NetShareDelete(struct cli_state *cli, const char * share_name ) +1 /* no ret string */ +RAP_SHARENAME_LEN /* share to del */ +WORDSIZE]; /* reserved word */ - /* now send a SMBtrans command with api RNetShareDelete */ p = make_header(param, RAP_WshareDel, RAP_WShareDel_REQ, NULL); PUTSTRING(p,share_name,RAP_SHARENAME_LEN); PUTWORD(p,0); /* reserved word MBZ on input */ - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 200, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ { res = GETRES(rparam); - + if (res == 0) { - /* nothing to do */ + /* nothing to do */ } else { DEBUG(4,("NetShareDelete res=%d\n", res)); - } + } } else { res = -1; DEBUG(4,("NetShareDelete failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return res; } /************************************************************************* @@ -1220,7 +1212,7 @@ int cli_NetShareDelete(struct cli_state *cli, const char * share_name ) * * Dependencies: none * -* Parameters: +* Parameters: * cli - pointer to cli_state structure * workgroup - pointer to string containing name of domain * pdc_name - pointer to string that will contain PDC name @@ -1245,7 +1237,7 @@ bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) +DWORDSIZE /* server type */ +RAP_MACHNAME_LEN]; /* workgroup */ int count = -1; - + *pdc_name = '\0'; /* send a SMBtrans command with api NetServerEnum */ @@ -1255,15 +1247,15 @@ bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) PUTWORD(p, CLI_BUFFER_SIZE); PUTDWORD(p, SV_TYPE_DOMAIN_CTRL); PUTSTRING(p, workgroup, RAP_MACHNAME_LEN); - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { cli->rap_error = GETRES(rparam); - + /* * We only really care to copy a name if the * API succeeded and we got back a name. @@ -1272,7 +1264,7 @@ bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ GETWORD(p, count); p = rdata; - + if (count > 0) GETSTRING(p, pdc_name); } @@ -1281,10 +1273,10 @@ bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); } } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return(count > 0); } @@ -1301,7 +1293,7 @@ bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) * * Dependencies: none * -* Parameters: +* Parameters: * cli - pointer to cli_state structure * * Returns: @@ -1323,34 +1315,34 @@ bool cli_get_server_domain(struct cli_state *cli) +WORDSIZE /* info level */ +WORDSIZE]; /* buffer size */ int res = -1; - + /* send a SMBtrans command with api NetWkstaGetInfo */ p = make_header(param, RAP_WWkstaGetInfo, RAP_WWkstaGetInfo_REQ, RAP_WKSTA_INFO_L10); PUTWORD(p, 10); /* info level */ PUTWORD(p, CLI_BUFFER_SIZE); - + if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt)) { /* return data, return size */ res = GETRES(rparam); - p = rdata; - + p = rdata; + if (res == 0) { int converter; p = rparam + WORDSIZE; GETWORD(p, converter); - + p = rdata + DWORDSIZE + DWORDSIZE; /* skip computer & user names */ GETSTRINGP(p, cli->server_domain, rdata, converter); } } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return(res == 0); } @@ -1365,7 +1357,7 @@ bool cli_get_server_domain(struct cli_state *cli) * * Dependencies: none * -* Parameters: +* Parameters: * cli - pointer to cli_state structure * pstype - pointer to uint32 to contain returned server type * @@ -1388,31 +1380,31 @@ bool cli_get_server_type(struct cli_state *cli, uint32 *pstype) +WORDSIZE /* info level */ +WORDSIZE]; /* buffer size */ int res = -1; - + /* send a SMBtrans command with api NetServerGetInfo */ p = make_header(param, RAP_WserverGetInfo, RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1); PUTWORD(p, 1); /* info level */ PUTWORD(p, CLI_BUFFER_SIZE); - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { - + res = GETRES(rparam); - + if (res == 0 || res == ERRmoredata) { - p = rdata; + p = rdata; *pstype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; } } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return(res == 0 || res == ERRmoredata); } @@ -1430,14 +1422,14 @@ bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, +WORDSIZE]; /* buffer size */ bool res = False; fstring tmp; - + /* send a SMBtrans command with api NetServerGetInfo */ p = make_header(param, RAP_WserverGetInfo, RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1); PUTWORD(p, 1); /* info level */ PUTWORD(p, CLI_BUFFER_SIZE); - - if (!cli_api(cli, + + if (!cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ @@ -1445,7 +1437,7 @@ bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, )) { goto failed; } - + if (GETRES(rparam) != 0) { goto failed; } @@ -1484,12 +1476,12 @@ bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, * then we conclude the server type checks out. This routine * is useful to retrieve list of server's of a certain * type when all you have is a null session connection and -* can't remote API calls such as NetWkstaGetInfo or +* can't remote API calls such as NetWkstaGetInfo or * NetServerGetInfo. * * Dependencies: none * -* Parameters: +* Parameters: * cli - pointer to cli_state structure * workgroup - pointer to string containing domain * stype - server type @@ -1514,7 +1506,7 @@ bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 sty +RAP_MACHNAME_LEN]; /* workgroup */ bool found_server = False; int res = -1; - + /* send a SMBtrans command with api NetServerEnum */ p = make_header(param, RAP_NetServerEnum2, RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L0); @@ -1522,14 +1514,14 @@ bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 sty PUTWORD(p, CLI_BUFFER_SIZE); PUTDWORD(p, stype); PUTSTRING(p, workgroup, RAP_MACHNAME_LEN); - - if (cli_api(cli, + + if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ &rparam, &rprcnt, /* return params, return size */ &rdata, &rdrcnt /* return data, return size */ )) { - + res = GETRES(rparam); cli->rap_error = res; @@ -1555,10 +1547,10 @@ bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 sty "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); } } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - + return found_server; } @@ -1580,7 +1572,7 @@ bool cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) +WORDSIZE /* buffer size */ +WORDSIZE]; /* buffer size? */ fstring upperbuf; - + memset(param, 0, sizeof(param)); /* send a SMBtrans command with api NetWkstaUserLogoff */ @@ -1597,7 +1589,7 @@ bool cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN); PUTWORD(p, CLI_BUFFER_SIZE); PUTWORD(p, CLI_BUFFER_SIZE); - + if (cli_api(cli, param, PTR_DIFF(p,param),1024, /* param, length, max */ NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ @@ -1605,17 +1597,17 @@ bool cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) &rdata, &rdrcnt /* return data, return size */ )) { cli->rap_error = GETRES(rparam); - + if (cli->rap_error != 0) { DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli->rap_error)); } } - + SAFE_FREE(rparam); SAFE_FREE(rdata); return (cli->rap_error == 0); } - + int cli_NetPrintQEnum(struct cli_state *cli, void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*)) @@ -1628,13 +1620,13 @@ int cli_NetPrintQEnum(struct cli_state *cli, +sizeof(RAP_SMB_PRINT_JOB_L1)]; /* more ret data */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - + memset(param, '\0',sizeof(param)); - p = make_header(param, RAP_WPrintQEnum, + p = make_header(param, RAP_WPrintQEnum, RAP_NetPrintQEnum_REQ, RAP_PRINTQ_INFO_L2); PUTWORD(p,2); /* Info level 2 */ PUTWORD(p,0xFFE0); /* Return buffer size */ @@ -1687,7 +1679,7 @@ int cli_NetPrintQEnum(struct cli_state *cli, uint16 jid, pos, fsstatus; pstring ownername, notifyname, datatype, jparms, jstatus, jcomment; unsigned int submitted, jsize; - + GETWORD(p, jid); GETSTRINGF(p, ownername, RAP_USERNAME_LEN); p++; /* pad byte */ @@ -1700,7 +1692,7 @@ int cli_NetPrintQEnum(struct cli_state *cli, GETDWORD(p, submitted); GETDWORD(p, jsize); GETSTRINGP(p, jcomment, rdata, converter); - + jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus, jstatus, submitted, jsize, jcomment); } @@ -1712,11 +1704,11 @@ int cli_NetPrintQEnum(struct cli_state *cli, } else { DEBUG(4,("NetPrintQEnum no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - return res; + return res; } int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, @@ -1725,17 +1717,17 @@ int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, { char param[WORDSIZE /* api number */ +sizeof(RAP_NetPrintQGetInfo_REQ) /* req string */ - +sizeof(RAP_PRINTQ_INFO_L2) /* return string */ + +sizeof(RAP_PRINTQ_INFO_L2) /* return string */ +RAP_SHARENAME_LEN /* printer name */ +WORDSIZE /* info level */ +WORDSIZE /* buffer size */ +sizeof(RAP_SMB_PRINT_JOB_L1)]; /* more ret data */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - + memset(param, '\0',sizeof(param)); p = make_header(param, RAP_WPrintQGetInfo, @@ -1762,7 +1754,7 @@ int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, int rsize, converter; pstring qname, sep_file, print_proc, dest, parms, comment; uint16 jobcount, priority, start_time, until_time, status; - + p = rparam + WORDSIZE; GETWORD(p, converter); GETWORD(p, rsize); @@ -1801,7 +1793,7 @@ int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, GETDWORD(p, submitted); GETDWORD(p, jsize); GETSTRINGP(p, jcomment, rdata, converter); - + jfn(jid, ownername, notifyname, datatype, jparms, pos, fsstatus, jstatus, submitted, jsize, jcomment); } @@ -1812,11 +1804,11 @@ int cli_NetPrintQGetInfo(struct cli_state *cli, const char *printer, } else { DEBUG(4,("NetPrintQGetInfo no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - return res; + return res; } /**************************************************************************** @@ -1831,15 +1823,15 @@ int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const ch +WORDSIZE]; /* buffer size */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - - + + memset(param, '\0', sizeof(param)); p = make_header(param, RAP_WServiceEnum, RAP_NetServiceEnum_REQ, RAP_SERVICE_INFO_L2); - PUTWORD(p,2); /* Info level 2 */ + PUTWORD(p,2); /* Info level 2 */ PUTWORD(p,0xFFE0); /* Return buffer size */ if (cli_api(cli, @@ -1849,7 +1841,7 @@ int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const ch &rdata, &rdrcnt)) { res = GETRES(rparam); cli->rap_error = res; - if(cli->rap_error == 234) + if(cli->rap_error == 234) DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n")); else if (cli->rap_error != 0) { DEBUG(1,("NetServiceEnum gave error %d\n", cli->rap_error)); @@ -1872,14 +1864,14 @@ int cli_RNetServiceEnum(struct cli_state *cli, void (*fn)(const char *, const ch GETSTRINGF(p, comment, RAP_SRVCCMNT_LEN); fn(servicename, comment, cli); /* BB add status too */ - } + } } else { DEBUG(4,("NetServiceEnum res=%d\n", res)); } } else { DEBUG(4,("NetServiceEnum no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -1899,12 +1891,12 @@ int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, +WORDSIZE]; /* buffer size */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - + memset(param, '\0', sizeof(param)); - p = make_header(param, RAP_WsessionEnum, + p = make_header(param, RAP_WsessionEnum, RAP_NetSessionEnum_REQ, RAP_SESSION_INFO_L2); PUTWORD(p,2); /* Info level 2 */ PUTWORD(p,0xFF); /* Return buffer size */ @@ -1924,7 +1916,7 @@ int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, if (rdata) { if (res == 0 || res == ERRmoredata) { int i, converter, count; - + p = rparam + WORDSIZE; GETWORD(p, converter); GETWORD(p, count); @@ -1947,14 +1939,14 @@ int cli_NetSessionEnum(struct cli_state *cli, void (*fn)(char *, char *, uint16, fn(wsname, username, num_conns, num_opens, num_users, sess_time, idle_time, user_flags, clitype_name); } - + } else { DEBUG(4,("NetSessionEnum res=%d\n", res)); } } else { DEBUG(4,("NetSesssionEnum no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); @@ -1969,19 +1961,19 @@ int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void ( { char param[WORDSIZE /* api number */ +sizeof(RAP_NetSessionGetInfo_REQ) /* req string */ - +sizeof(RAP_SESSION_INFO_L2) /* return string */ + +sizeof(RAP_SESSION_INFO_L2) /* return string */ +RAP_MACHNAME_LEN /* wksta name */ +WORDSIZE /* info level */ +WORDSIZE]; /* buffer size */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; - + memset(param, '\0', sizeof(param)); - p = make_header(param, RAP_WsessionGetInfo, + p = make_header(param, RAP_WsessionGetInfo, RAP_NetSessionGetInfo_REQ, RAP_SESSION_INFO_L2); PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1); PUTWORD(p,2); /* Info level 2 */ @@ -2000,7 +1992,7 @@ int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void ( if (rdata) { res = GETRES(rparam); - + if (res == 0 || res == ERRmoredata) { int converter; pstring wsname, username, clitype_name; @@ -2021,7 +2013,7 @@ int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void ( GETDWORD(p, idle_time); GETDWORD(p, user_flags); GETSTRINGP(p, clitype_name, rdata, converter); - + fn(wsname, username, num_conns, num_opens, num_users, sess_time, idle_time, user_flags, clitype_name); } else { @@ -2030,11 +2022,11 @@ int cli_NetSessionGetInfo(struct cli_state *cli, const char *workstation, void ( } else { DEBUG(4,("NetSessionGetInfo no data returned\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); - return res; + return res; } /**************************************************************************** @@ -2057,7 +2049,7 @@ int cli_NetSessionDel(struct cli_state *cli, const char *workstation) p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL); PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1); PUTWORD(p,0); /* reserved word of 0 */ - if (cli_api(cli, + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 200, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ @@ -2065,36 +2057,36 @@ int cli_NetSessionDel(struct cli_state *cli, const char *workstation) { res = GETRES(rparam); cli->rap_error = res; - + if (res == 0) { - /* nothing to do */ + /* nothing to do */ } else { DEBUG(4,("NetFileClose2 res=%d\n", res)); - } + } } else { res = -1; DEBUG(4,("NetFileClose2 failed\n")); } - + SAFE_FREE(rparam); SAFE_FREE(rdata); return res; } - + int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*fn)(uint16 conid, uint16 contype, uint16 numopens, uint16 numusers, uint32 contime, const char *username, const char *netname)) { char param[WORDSIZE /* api number */ +sizeof(RAP_NetConnectionEnum_REQ) /* req string */ - +sizeof(RAP_CONNECTION_INFO_L1) /* return string */ + +sizeof(RAP_CONNECTION_INFO_L1) /* return string */ +RAP_MACHNAME_LEN /* wksta name */ +WORDSIZE /* info level */ +WORDSIZE]; /* buffer size */ char *p; char *rparam = NULL; - char *rdata = NULL; + char *rdata = NULL; unsigned int rprcnt, rdrcnt; int res = -1; @@ -2140,7 +2132,7 @@ int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*f fn(conn_id, conn_type, num_opens, num_users, conn_time, username, netname); } - + } else { DEBUG(4,("NetConnectionEnum res=%d\n", res)); } -- cgit From d19861e29d5e46821548dc54d069cfdf625f08b4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Nov 2007 18:02:19 -0800 Subject: Ensure we have 2 bytes of zeros as a pad-buffer at the end of all returned trans/trans2/nttrans client replies. Not included in a count - for safety purposes. Jeremy. (This used to be commit 3e65fa5bcf5d1af3983f2e576698eccaad79fcda) --- source3/libsmb/clitrans.c | 125 +++++++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 40 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 5db624150d..739c8ba1d1 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. client transaction calls Copyright (C) Andrew Tridgell 1994-1998 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -24,8 +24,8 @@ Send a SMB trans or trans2 request. ****************************************************************************/ -bool cli_send_trans(struct cli_state *cli, int trans, - const char *pipe_name, +bool cli_send_trans(struct cli_state *cli, int trans, + const char *pipe_name, int fid, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, const char *param, unsigned int lparam, unsigned int mparam, @@ -107,17 +107,17 @@ bool cli_send_trans(struct cli_state *cli, int trans, tot_data = this_ldata; tot_param = this_lparam; - + while (tot_data < ldata || tot_param < lparam) { this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); - + outparam = smb_buf(cli->outbuf); outdata = outparam+this_lparam; - + /* secondary request */ SSVAL(cli->outbuf,smb_tpscnt,lparam); /* tpscnt */ SSVAL(cli->outbuf,smb_tdscnt,ldata); /* tdscnt */ @@ -134,7 +134,7 @@ bool cli_send_trans(struct cli_state *cli, int trans, if (this_ldata) /* data[] */ memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); - + /* * Save the mid we're using. We need this for finding * signing replies. @@ -149,7 +149,7 @@ bool cli_send_trans(struct cli_state *cli, int trans, /* Ensure we use the same mid for the secondaries. */ cli->mid = mid; - + tot_data += this_ldata; tot_param += this_lparam; } @@ -179,11 +179,11 @@ bool cli_receive_trans(struct cli_state *cli,int trans, } show_msg(cli->inbuf); - + /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", - trans==SMBtrans?"SMBtrans":"SMBtrans2", + trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); return False; } @@ -202,7 +202,7 @@ bool cli_receive_trans(struct cli_state *cli,int trans, * length). */ status = cli_nt_error(cli); - + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { if (NT_STATUS_IS_ERR(status) || NT_STATUS_EQUAL(status,STATUS_NO_MORE_FILES) || @@ -217,7 +217,9 @@ bool cli_receive_trans(struct cli_state *cli,int trans, /* allocate it */ if (total_data!=0) { - *data = (char *)SMB_REALLOC(*data,total_data); + /* We know adding 2 is safe as total_data is an + * SVAL <= 0xFFFF. */ + *data = (char *)SMB_REALLOC(*data,total_data+2); if (!(*data)) { DEBUG(0,("cli_receive_trans: failed to enlarge data buffer\n")); goto out; @@ -225,7 +227,9 @@ bool cli_receive_trans(struct cli_state *cli,int trans, } if (total_param!=0) { - *param = (char *)SMB_REALLOC(*param,total_param); + /* We know adding 2 is safe as total_param is an + * SVAL <= 0xFFFF. */ + *param = (char *)SMB_REALLOC(*param,total_param+2); if (!(*param)) { DEBUG(0,("cli_receive_trans: failed to enlarge param buffer\n")); goto out; @@ -299,13 +303,13 @@ bool cli_receive_trans(struct cli_state *cli,int trans, ret = True; break; } - + if (!cli_receive_smb(cli)) { goto out; } show_msg(cli->inbuf); - + /* sanity check */ if (CVAL(cli->inbuf,smb_com) != trans) { DEBUG(0,("Expected %s response, got command 0x%02x\n", @@ -324,7 +328,7 @@ bool cli_receive_trans(struct cli_state *cli,int trans, total_data = SVAL(cli->inbuf,smb_tdrcnt); if (SVAL(cli->inbuf,smb_tprcnt) < total_param) total_param = SVAL(cli->inbuf,smb_tprcnt); - + if (total_data <= *data_len && total_param <= *param_len) { ret = True; break; @@ -333,6 +337,19 @@ bool cli_receive_trans(struct cli_state *cli,int trans, out: + if (ret) { + /* Ensure the last 2 bytes of param and data are 2 null + * bytes. These are malloc'ed, but not included in any + * length counts. This allows cli_XX string reading functions + * to safely null terminate. */ + if (total_data) { + SSVAL(*data,total_data,0); + } + if (total_param) { + SSVAL(*param,total_param,0); + } + } + client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } @@ -341,8 +358,8 @@ bool cli_receive_trans(struct cli_state *cli,int trans, Send a SMB nttrans request. ****************************************************************************/ -bool cli_send_nt_trans(struct cli_state *cli, - int function, +bool cli_send_nt_trans(struct cli_state *cli, + int function, int flags, uint16 *setup, unsigned int lsetup, unsigned int msetup, char *param, unsigned int lparam, unsigned int mparam, @@ -388,7 +405,7 @@ bool cli_send_nt_trans(struct cli_state *cli, SIVAL(cli->outbuf,smb_nt_Function, function); for (i=0;ioutbuf,smb_nt_SetupStart+i*2,setup[i]); - + if (this_lparam) /* param[] */ memcpy(outparam,param,this_lparam); if (this_ldata) /* data[] */ @@ -399,7 +416,7 @@ bool cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { return False; - } + } /* Note we're in a trans state. Save the sequence * numbers for replies. */ @@ -414,7 +431,7 @@ bool cli_send_nt_trans(struct cli_state *cli, tot_data = this_ldata; tot_param = this_lparam; - + while (tot_data < ldata || tot_param < lparam) { this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); @@ -425,7 +442,7 @@ bool cli_send_nt_trans(struct cli_state *cli, /* XXX - these should probably be aligned */ outparam = smb_buf(cli->outbuf); outdata = outparam+this_lparam; - + /* secondary request */ SIVAL(cli->outbuf,smb_nts_TotalParameterCount,lparam); SIVAL(cli->outbuf,smb_nts_TotalDataCount,ldata); @@ -440,7 +457,7 @@ bool cli_send_nt_trans(struct cli_state *cli, if (this_ldata) /* data[] */ memcpy(outdata,data+tot_data,this_ldata); cli_setup_bcc(cli, outdata+this_ldata); - + /* * Save the mid we're using. We need this for finding * signing replies. @@ -453,10 +470,10 @@ bool cli_send_nt_trans(struct cli_state *cli, client_set_trans_sign_state_off(cli, mid); return False; } - + /* Ensure we use the same mid for the secondaries. */ cli->mid = mid; - + tot_data += this_ldata; tot_param += this_lparam; } @@ -487,7 +504,7 @@ bool cli_receive_nt_trans(struct cli_state *cli, } show_msg(cli->inbuf); - + /* sanity check */ if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", @@ -518,12 +535,25 @@ bool cli_receive_nt_trans(struct cli_state *cli, } /* parse out the lengths */ - total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); - total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); + total_data = IVAL(cli->inbuf,smb_ntr_TotalDataCount); + total_param = IVAL(cli->inbuf,smb_ntr_TotalParameterCount); + /* Only allow 16 megs. */ + if (total_param > 16*1024*1024) { + DEBUG(0,("cli_receive_nt_trans: param buffer too large %d\n", + total_param)); + goto out; + } + if (total_data > 16*1024*1024) { + DEBUG(0,("cli_receive_nt_trans: data buffer too large %d\n", + total_data)); + goto out; + } /* allocate it */ if (total_data) { - *data = (char *)SMB_REALLOC(*data,total_data); + /* We know adding 2 is safe as total_data is less + * than 16mb (above). */ + *data = (char *)SMB_REALLOC(*data,total_data+2); if (!(*data)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge data buffer to %d\n",total_data)); goto out; @@ -531,7 +561,9 @@ bool cli_receive_nt_trans(struct cli_state *cli, } if (total_param) { - *param = (char *)SMB_REALLOC(*param,total_param); + /* We know adding 2 is safe as total_param is less + * than 16mb (above). */ + *param = (char *)SMB_REALLOC(*param,total_param+2); if (!(*param)) { DEBUG(0,("cli_receive_nt_trans: failed to enlarge param buffer to %d\n", total_param)); goto out; @@ -607,13 +639,13 @@ bool cli_receive_nt_trans(struct cli_state *cli, ret = True; break; } - + if (!cli_receive_smb(cli)) { goto out; } show_msg(cli->inbuf); - + /* sanity check */ if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", @@ -637,11 +669,11 @@ bool cli_receive_nt_trans(struct cli_state *cli, } /* parse out the total lengths again - they can shrink! */ - if (SVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) - total_data = SVAL(cli->inbuf,smb_ntr_TotalDataCount); - if (SVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) - total_param = SVAL(cli->inbuf,smb_ntr_TotalParameterCount); - + if (IVAL(cli->inbuf,smb_ntr_TotalDataCount) < total_data) + total_data = IVAL(cli->inbuf,smb_ntr_TotalDataCount); + if (IVAL(cli->inbuf,smb_ntr_TotalParameterCount) < total_param) + total_param = IVAL(cli->inbuf,smb_ntr_TotalParameterCount); + if (total_data <= *data_len && total_param <= *param_len) { ret = True; break; @@ -650,6 +682,19 @@ bool cli_receive_nt_trans(struct cli_state *cli, out: + if (ret) { + /* Ensure the last 2 bytes of param and data are 2 null + * bytes. These are malloc'ed, but not included in any + * length counts. This allows cli_XX string reading functions + * to safely null terminate. */ + if (total_data) { + SSVAL(*data,total_data,0); + } + if (total_param) { + SSVAL(*param,total_param,0); + } + } + client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } -- cgit From a17a13f7ce27c316c4304ddb6e33de1df6be86ca Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 30 Nov 2007 21:57:43 -0800 Subject: Fix missing error cleanup noticed by Derrell. Jeremy. (This used to be commit 37f00926c29c22f27e7192c1fff0a08ce136cb86) --- source3/libsmb/libsmbclient.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 3990a29f4a..26ff339a1a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2777,7 +2777,6 @@ smbc_opendir_ctx(SMBCCTX *context, struct ip_service *ip_list; struct ip_service server_addr; struct user_auth_info u_info; - struct cli_state *cli; if (share[0] != (char)0 || path[0] != (char)0) { @@ -2838,6 +2837,7 @@ smbc_opendir_ctx(SMBCCTX *context, for (i = 0; i < count && i < max_lmb_count; i++) { char addr[INET6_ADDRSTRLEN]; char *wg_ptr = NULL; + struct cli_state *cli = NULL; print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); DEBUG(99, ("Found master browser %d of %d: %s\n", @@ -2850,17 +2850,20 @@ smbc_opendir_ctx(SMBCCTX *context, &wg_ptr); /* cli == NULL is the master browser refused to talk or could not be found */ - if ( !cli ) + if (!cli) { continue; + } workgroup = talloc_strdup(frame, wg_ptr); server = talloc_strdup(frame, cli->desthost); + + cli_shutdown(cli); + if (!workgroup || !server) { errno = ENOMEM; TALLOC_FREE(frame); return NULL; } - cli_shutdown(cli); DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); -- cgit From 4a3ee48de5a4aa4bacb547fa39138d66af6719c2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Dec 2007 11:43:00 +0100 Subject: Fix an uninitialized variable (This used to be commit edce7bd7a9dd1064ba8aec34b334c7395228f40b) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 26ff339a1a..b654ea07f0 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4172,7 +4172,7 @@ convert_string_to_sid(struct cli_state *ipc_cli, enum lsa_SidType *types = NULL; DOM_SID *sids = NULL; bool result = True; - TALLOC_CTX *ctx; + TALLOC_CTX *ctx = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); if (!pipe_hnd) { -- cgit From bbf2cb6da994ac73dd7ea26d81f724aa04b5a3cb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Dec 2007 11:43:12 +0100 Subject: Fix some C++ warnings (This used to be commit 156c7f10bb63a610f85b52242cfd1b67bfa73c29) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index e438b6d926..cd50cfc03c 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1478,7 +1478,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) if (len <= 0 || len > PATH_MAX) return -1; if (tmp_path) { - char *path2 = SMB_MALLOC(len+1); + char *path2 = SMB_MALLOC_ARRAY(char, len+1); if (!path2) { return -1; } -- cgit From 41418ed682f0b407a6b8d1f04ae87e60f36a2feb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 3 Dec 2007 14:06:22 +0100 Subject: Add decode_wkssvc_join_password_buffer(). Guenther (This used to be commit ba2a544baf1e1cc3652512ed5df2bb408fa8bdfd) --- source3/libsmb/smbencrypt.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 6060669e49..8793fdcb55 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -730,3 +730,32 @@ void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, data_blob_free(&confounded_session_key); } + +void decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + struct wkssvc_PasswordBuffer *pwd_buf, + DATA_BLOB *session_key, + char **pwd) +{ + uint8_t buffer[516]; + struct MD5Context ctx; + uint32_t pwd_len; + + DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); + + int confounder_len = 8; + uint8_t confounder[8]; + + memcpy(&confounder, &pwd_buf->data[0], confounder_len); + memcpy(&buffer, &pwd_buf->data[8], 516); + + MD5Init(&ctx); + MD5Update(&ctx, session_key->data, session_key->length); + MD5Update(&ctx, confounder, confounder_len); + MD5Final(confounded_session_key.data, &ctx); + + SamOEMhashBlob(buffer, 516, &confounded_session_key); + + decode_pw_buffer(mem_ctx, buffer, pwd, &pwd_len, STR_UNICODE); + + data_blob_free(&confounded_session_key); +} -- cgit From fe1a12b22fd81ac01d30c0f561cacba82532cd0e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 3 Dec 2007 14:09:48 -0800 Subject: Remove pstring from clirap2 by completely rewriting the damn thing :-). Now with added paranoia. Jeremy. (This used to be commit b6b5f92bc9457220df384bdb13530c393d294ce7) --- source3/libsmb/clirap2.c | 3895 ++++++++++++++++++++++++++-------------------- 1 file changed, 2211 insertions(+), 1684 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index f522e13345..d5795643e8 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -3,6 +3,7 @@ More client RAP (SMB Remote Procedure Calls) functions Copyright (C) 2001 Steve French (sfrench@us.ibm.com) Copyright (C) 2001 Jim McDonough (jmcd@us.ibm.com) + Copyright (C) 2007 Jeremy Allison. jra@samba.org This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -80,916 +81,1140 @@ #define DWORDSIZE 4 #define PUTBYTE(p,b) do {SCVAL(p,0,b); p++;} while(0) -#define GETBYTE(p,b) do {b = CVAL(p,0); p++;} while(0) + +#define GETBYTE(p,b,endp) \ + do {\ + if (p+1 < endp) {\ + b = CVAL(p,0);\ + }\ + p++;\ + } while(0) + #define PUTWORD(p,w) do {SSVAL(p,0,w); p += WORDSIZE;} while(0) -#define GETWORD(p,w) do {w = SVAL(p,0); p += WORDSIZE;} while(0) + +#define GETWORD(p,w,endp) \ + do {\ + if (p+WORDSIZE < endp) {\ + w = SVAL(p,0);\ + }\ + p += WORDSIZE;\ + } while(0) + #define PUTDWORD(p,d) do {SIVAL(p,0,d); p += DWORDSIZE;} while(0) -#define GETDWORD(p,d) do {d = IVAL(p,0); p += DWORDSIZE;} while(0) -#define GETRES(p) p ? SVAL(p,0) : -1 + +#define GETDWORD(p,d,endp) \ + do {\ + if (p+DWORDSIZE < endp) {\ + d = IVAL(p,0);\ + }\ + p += DWORDSIZE;\ + } while(0) + +#define GETRES(p,endp) ((p && p+2 < endp) ? SVAL(p,0) : -1) + /* put string s at p with max len n and increment p past string */ -#define PUTSTRING(p,s,n) do {\ - push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\ - p = push_skip_string(p);\ - } while(0) +#define PUTSTRING(p,s,n) \ + do {\ + push_ascii(p,s?s:"",n?n:256,STR_TERMINATE);\ + p = push_skip_string(p);\ + } while(0) + /* put string s and p, using fixed len l, and increment p by l */ -#define PUTSTRINGF(p,s,l) do {\ - push_ascii(p,s?s:"",l,STR_TERMINATE);\ - p += l;\ - } while (0) +#define PUTSTRINGF(p,s,l) \ + do {\ + push_ascii(p,s?s:"",l,STR_TERMINATE);\ + p += l;\ + } while (0) + /* put string pointer at p, supplying offset o from rdata r, store */ /* dword offset at p, increment p by 4 and o by length of s. This */ /* means on the first call, you must calc the offset yourself! */ -#define PUTSTRINGP(p,s,r,o) do {\ - if (s) {\ - push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\ - PUTDWORD(p,o);\ - o += strlen(s) + 1;\ - } else PUTDWORD(p,0);\ - }while(0); -/* get asciiz string s from p, increment p past string */ -#define GETSTRING(p,s) do {\ - pull_ascii_pstring(s,p);\ - p = push_skip_string(p);\ - } while(0) -/* get fixed length l string s from p, increment p by l */ -#define GETSTRINGF(p,s,l) do {\ - pull_ascii_pstring(s,p);\ - p += l;\ - } while(0) -/* get string s from offset (obtained at p) from rdata r - converter c */ -#define GETSTRINGP(p,s,r,c) do {\ - uint32 off;\ - GETDWORD(p,off);\ - off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */ \ - pull_ascii_pstring(s, off?(r+off-c):"");\ - } while(0) + +#define PUTSTRINGP(p,s,r,o) \ + do {\ + if (s) {\ + push_ascii(r+o,s,strlen(s)+1,STR_TERMINATE);\ + PUTDWORD(p,o);\ + o += strlen(s) + 1;\ + } else {\ + PUTDWORD(p,0);\ + }\ + }while(0); + +/* get asciiz string dest from src, return increment past string */ + +static size_t rap_getstring(TALLOC_CTX *ctx, char *src, char **dest, const char *endp) +{ + char *p1; + size_t len; + + *dest = NULL; + for (p1 = src, len = 0; *p1 && p1 < endp; len++) + p1++; + if (!*p1) { + len++; + } + pull_string_talloc(ctx,src,0,dest,src,len,STR_ASCII); + return len; +} + +/* get fixed length l string dest from src, return increment for src */ + +static size_t rap_getstringf(char *src, char *dest, size_t l, size_t dlen, char *endp) +{ + char *p1; + size_t len; + + if (dlen) { + dest[0] = '\0'; + } + for (p1 = src, len = 0; *p1 && p1 < endp; len++) { + p1++; + } + if (!*p1) { + len++; + } + if (len > l) { + len = l; + } + if (len) { + pull_ascii(dest,src,len,len,STR_ASCII); + } + return l; +} + +/* get string dest from offset (obtained at p) from rdata r - converter c */ +static size_t rap_getstringp(TALLOC_CTX *ctx, char *p, char **dest, char *r, uint16_t c, char *endp) +{ + uint32_t off = 0; + const char *src; + size_t len=0; + + *dest = NULL; + if (p+4 < endp) { + GETDWORD(p,off,endp); + off &= 0x0000FFFF; /* mask the obsolete segment number from the offset */ + off -= c; + } + if (r+off > endp || r+off < r) { + src=""; + len=1; + } else { + const char *p1; + src=r+off; + for (p1 = src, len = 0; *p1 && p1 < endp; len++) { + p1++; + } + if (!*p1) { + len++; + } + } + pull_string_talloc(ctx,src,0,dest,src,len,STR_ASCII); + return len; +} static char *make_header(char *param, uint16 apinum, const char *reqfmt, const char *datafmt) { - PUTWORD(param,apinum); - if (reqfmt) - PUTSTRING(param,reqfmt,0); - else - *param++ = (char) 0; - - if (datafmt) - PUTSTRING(param,datafmt,0); - else - *param++ = (char) 0; - - return param; + PUTWORD(param,apinum); + if (reqfmt) + PUTSTRING(param,reqfmt,0); + else + *param++ = (char) 0; + + if (datafmt) + PUTSTRING(param,datafmt,0); + else + *param++ = (char) 0; + + return param; } /**************************************************************************** call a NetGroupDelete - delete user group from remote server ****************************************************************************/ -int cli_NetGroupDelete(struct cli_state *cli, const char *group_name ) + +int cli_NetGroupDelete(struct cli_state *cli, const char *group_name) { - char *rparam = NULL; - char *rdata = NULL; - char *p; - unsigned int rdrcnt,rprcnt; - int res; - char param[WORDSIZE /* api number */ + char *rparam = NULL; + char *rdata = NULL; + char *p; + unsigned int rdrcnt,rprcnt; + int res = -1; + char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupDel_REQ) /* parm string */ +1 /* no ret string */ +RAP_GROUPNAME_LEN /* group to del */ +WORDSIZE]; /* reserved word */ - /* now send a SMBtrans command with api GroupDel */ - p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL); - PUTSTRING(p, group_name, RAP_GROUPNAME_LEN); - PUTWORD(p,0); /* reserved word MBZ on input */ + /* now send a SMBtrans command with api GroupDel */ + p = make_header(param, RAP_WGroupDel, RAP_NetGroupDel_REQ, NULL); + PUTSTRING(p, group_name, RAP_GROUPNAME_LEN); + PUTWORD(p,0); /* reserved word MBZ on input */ - if (cli_api(cli, + if (cli_api(cli, param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ NULL, 0, 200, /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ - { - res = GETRES(rparam); - - if (res == 0) { - /* nothing to do */ - } - else if ((res == 5) || (res == 65)) { - DEBUG(1, ("Access Denied\n")); - } - else if (res == 2220) { - DEBUG (1, ("Group does not exist\n")); - } - else { - DEBUG(4,("NetGroupDelete res=%d\n", res)); - } - } else { - res = -1; - DEBUG(4,("NetGroupDelete failed\n")); - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return res; + { + char *endp = rparam + rprcnt; + res = GETRES(rparam,endp); + + if (res == 0) { + /* nothing to do */ + } else if ((res == 5) || (res == 65)) { + DEBUG(1, ("Access Denied\n")); + } else if (res == 2220) { + DEBUG (1, ("Group does not exist\n")); + } else { + DEBUG(4,("NetGroupDelete res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetGroupDelete failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; } /**************************************************************************** call a NetGroupAdd - add user group to remote server ****************************************************************************/ -int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 * grinfo ) + +int cli_NetGroupAdd(struct cli_state *cli, RAP_GROUP_INFO_1 *grinfo) { - char *rparam = NULL; - char *rdata = NULL; - char *p; - unsigned int rdrcnt,rprcnt; - int res; - char param[WORDSIZE /* api number */ + char *rparam = NULL; + char *rdata = NULL; + char *p; + unsigned int rdrcnt,rprcnt; + int res = -1; + char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupAdd_REQ) /* req string */ +sizeof(RAP_GROUP_INFO_L1) /* return string */ +WORDSIZE /* info level */ +WORDSIZE]; /* reserved word */ - /* offset into data of free format strings. Will be updated */ - /* by PUTSTRINGP macro and end up with total data length. */ - int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE; - char *data; - size_t data_size; + /* offset into data of free format strings. Will be updated */ + /* by PUTSTRINGP macro and end up with total data length. */ + int soffset = RAP_GROUPNAME_LEN + 1 + DWORDSIZE; + char *data; + size_t data_size; - /* Allocate data. */ - data_size = MAX(soffset + strlen(grinfo->comment) + 1, 1024); + /* Allocate data. */ + data_size = MAX(soffset + strlen(grinfo->comment) + 1, 1024); - data = SMB_MALLOC_ARRAY(char, data_size); - if (!data) { - DEBUG (1, ("Malloc fail\n")); - return -1; - } + data = SMB_MALLOC_ARRAY(char, data_size); + if (!data) { + DEBUG (1, ("Malloc fail\n")); + return -1; + } - /* now send a SMBtrans command with api WGroupAdd */ + /* now send a SMBtrans command with api WGroupAdd */ - p = make_header(param, RAP_WGroupAdd, - RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1); - PUTWORD(p, 1); /* info level */ - PUTWORD(p, 0); /* reserved word 0 */ + p = make_header(param, RAP_WGroupAdd, + RAP_NetGroupAdd_REQ, RAP_GROUP_INFO_L1); + PUTWORD(p, 1); /* info level */ + PUTWORD(p, 0); /* reserved word 0 */ - p = data; - PUTSTRINGF(p, grinfo->group_name, RAP_GROUPNAME_LEN); - PUTBYTE(p, 0); /* pad byte 0 */ - PUTSTRINGP(p, grinfo->comment, data, soffset); + p = data; + PUTSTRINGF(p, grinfo->group_name, RAP_GROUPNAME_LEN); + PUTBYTE(p, 0); /* pad byte 0 */ + PUTSTRINGP(p, grinfo->comment, data, soffset); - if (cli_api(cli, + if (cli_api(cli, param, sizeof(param), 1024, /* Param, length, maxlen */ data, soffset, sizeof(data), /* data, length, maxlen */ &rparam, &rprcnt, /* return params, length */ &rdata, &rdrcnt)) /* return data, length */ - { - res = GETRES(rparam); - - if (res == 0) { - /* nothing to do */ - } else if ((res == 5) || (res == 65)) { - DEBUG(1, ("Access Denied\n")); - } - else if (res == 2223) { - DEBUG (1, ("Group already exists\n")); - } - else { - DEBUG(4,("NetGroupAdd res=%d\n", res)); - } - } else { - res = -1; - DEBUG(4,("NetGroupAdd failed\n")); - } - - SAFE_FREE(data); - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return res; + { + char *endp = rparam + rprcnt; + res = GETRES(rparam, endp); + + if (res == 0) { + /* nothing to do */ + } else if ((res == 5) || (res == 65)) { + DEBUG(1, ("Access Denied\n")); + } else if (res == 2223) { + DEBUG (1, ("Group already exists\n")); + } else { + DEBUG(4,("NetGroupAdd res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetGroupAdd failed\n")); + } + + SAFE_FREE(data); + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; } /**************************************************************************** -call a NetGroupEnum - try and list user groups on a different host + Call a NetGroupEnum - try and list user groups on a different host. ****************************************************************************/ + int cli_RNetGroupEnum(struct cli_state *cli, void (*fn)(const char *, const char *, void *), void *state) { - char param[WORDSIZE /* api number */ + char param[WORDSIZE /* api number */ +sizeof(RAP_NetGroupEnum_REQ) /* parm string */ +sizeof(RAP_GROUP_INFO_L1) /* return string */ +WORDSIZE /* info level */ +WORDSIZE]; /* buffer size */ - char *p; - char *rparam = NULL; - char *rdata = NULL; - unsigned int rprcnt, rdrcnt; - int res = -1; - + char *p; + char *rparam = NULL; + char *rdata = NULL; + unsigned int rprcnt, rdrcnt; + int res = -1; - memset(param, '\0', sizeof(param)); - p = make_header(param, RAP_WGroupEnum, + memset(param, '\0', sizeof(param)); + p = make_header(param, RAP_WGroupEnum, RAP_NetGroupEnum_REQ, RAP_GROUP_INFO_L1); - PUTWORD(p,1); /* Info level 1 */ /* add level 0 */ - PUTWORD(p,0xFFE0); /* Return buffer size */ + PUTWORD(p,1); /* Info level 1 */ /* add level 0 */ + PUTWORD(p,0xFFE0); /* Return buffer size */ - if (cli_api(cli, + if (cli_api(cli, param, PTR_DIFF(p,param),8, NULL, 0, 0xFFE0 /* data area size */, &rparam, &rprcnt, &rdata, &rdrcnt)) { - res = GETRES(rparam); - cli->rap_error = res; - if(cli->rap_error == 234) - DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n")); - else if (cli->rap_error != 0) { - DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error)); - } - } - - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, converter, count; - - p = rparam + WORDSIZE; /* skip result */ - GETWORD(p, converter); - GETWORD(p, count); - - for (i=0,p=rdata;irap_error = res; + if(cli->rap_error == 234) { + DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n")); + } else if (cli->rap_error != 0) { + DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error)); + } + } + + if (!rdata) { + DEBUG(4,("NetGroupEnum no data returned\n")); + goto out; + } + + if (res == 0 || res == ERRmoredata) { + char *endp = rparam + rprcnt; + int i, converter = 0, count = 0; + TALLOC_CTX *frame = talloc_stackframe(); + + p = rparam + WORDSIZE; /* skip result */ + GETWORD(p, converter, endp); + GETWORD(p, count, endp); + + endp = rdata + rdrcnt; + for (i=0,p=rdata; irap_error = res; + if(cli->rap_error == 234) { + DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n")); + } else if (cli->rap_error != 0) { + DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error)); + } + } - if (cli_api(cli, - param, PTR_DIFF(p,param),8, - NULL, 0, 0xFFE0 /* data area size */, - &rparam, &rprcnt, - &rdata, &rdrcnt)) { - res = GETRES(rparam); - cli->rap_error = res; - if(cli->rap_error == 234) - DEBUG(1,("Not all group names were returned (such as those longer than 21 characters)\n")); - else if (cli->rap_error != 0) { - DEBUG(1,("NetGroupEnum gave error %d\n", cli->rap_error)); - } - } - - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, count; - - p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ - GETWORD(p, count); - - for (i=0,p=rdata;irap_error = res; - if (res != 0) { - DEBUG(1,("NetGroupGetUsers gave error %d\n", res)); - } - } - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, count; - fstring username; - p = rparam + WORDSIZE + WORDSIZE; - GETWORD(p, count); - - for (i=0,p=rdata; irap_error = res; + if (res != 0) { + DEBUG(1,("NetGroupGetUsers gave error %d\n", res)); + } + } + + if (!rdata) { + DEBUG(4,("NetGroupGetUsers no data returned\n")); + goto out; + } + + if (res == 0 || res == ERRmoredata) { + char *endp = rparam + rprcnt; + int i, count = 0; + char username[RAP_USERNAME_LEN]; + + p = rparam + WORDSIZE + WORDSIZE; + GETWORD(p, count, endp); + + endp = rdata + rdrcnt; + for (i=0,p=rdata; irap_error = res; - if (res != 0) { - DEBUG(1,("NetUserGetGroups gave error %d\n", res)); - } - } - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, count; - fstring groupname; - p = rparam + WORDSIZE + WORDSIZE; - GETWORD(p, count); - - for (i=0,p=rdata; irap_error = res; + if (res != 0) { + DEBUG(1,("NetUserGetGroups gave error %d\n", res)); + } + } + + if (!rdata) { + DEBUG(4,("NetUserGetGroups no data returned\n")); + goto out; + } + if (res == 0 || res == ERRmoredata) { + char *endp = rparam + rprcnt; + int i, count = 0; + char groupname[RAP_GROUPNAME_LEN]; + + p = rparam + WORDSIZE + WORDSIZE; + GETWORD(p, count, endp); + + endp = rdata + rdrcnt; + for (i=0,p=rdata; ipasswrd) - PUTWORD(p,MIN(strlen(userinfo->passwrd), RAP_UPASSWD_LEN)); - else - PUTWORD(p, 0); /* password length */ - - p = data; - memset(data, '\0', soffset); - - PUTSTRINGF(p, userinfo->user_name, RAP_USERNAME_LEN); - PUTBYTE(p, 0); /* pad byte 0 */ - PUTSTRINGF(p, userinfo->passwrd, RAP_UPASSWD_LEN); - PUTDWORD(p, 0); /* pw age - n.a. on user add */ - PUTWORD(p, userinfo->priv); - PUTSTRINGP(p, userinfo->home_dir, data, soffset); - PUTSTRINGP(p, userinfo->comment, data, soffset); - PUTWORD(p, userinfo->userflags); - PUTSTRINGP(p, userinfo->logon_script, data, soffset); - - if (cli_api(cli, - param, sizeof(param), 1024, /* Param, length, maxlen */ - data, soffset, sizeof(data), /* data, length, maxlen */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) /* return data, length */ - { - res = GETRES(rparam); - - if (res == 0) { - /* nothing to do */ - } - else if ((res == 5) || (res == 65)) { - DEBUG(1, ("Access Denied\n")); - } - else if (res == 2224) { - DEBUG (1, ("User already exists\n")); - } - else { - DEBUG(4,("NetUserAdd res=%d\n", res)); - } - } else { - res = -1; - DEBUG(4,("NetUserAdd failed\n")); - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return res; + char *rparam = NULL; + char *rdata = NULL; + char *p; + unsigned int rdrcnt,rprcnt; + int res = -1; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetUserAdd2_REQ) /* req string */ + +sizeof(RAP_USER_INFO_L1) /* data string */ + +WORDSIZE /* info level */ + +WORDSIZE /* buffer length */ + +WORDSIZE]; /* reserved */ + + char data[1024]; + /* offset into data of free format strings. Will be updated */ + /* by PUTSTRINGP macro and end up with total data length. */ + int soffset=RAP_USERNAME_LEN+1 /* user name + pad */ + + RAP_UPASSWD_LEN /* password */ + + DWORDSIZE /* password age */ + + WORDSIZE /* privilege */ + + DWORDSIZE /* home dir ptr */ + + DWORDSIZE /* comment ptr */ + + WORDSIZE /* flags */ + + DWORDSIZE; /* login script ptr*/ + + /* now send a SMBtrans command with api NetUserAdd */ + p = make_header(param, RAP_WUserAdd2, + RAP_NetUserAdd2_REQ, RAP_USER_INFO_L1); + + PUTWORD(p, 1); /* info level */ + PUTWORD(p, 0); /* pwencrypt */ + if(userinfo->passwrd) + PUTWORD(p,MIN(strlen(userinfo->passwrd), RAP_UPASSWD_LEN)); + else + PUTWORD(p, 0); /* password length */ + + p = data; + memset(data, '\0', soffset); + + PUTSTRINGF(p, userinfo->user_name, RAP_USERNAME_LEN); + PUTBYTE(p, 0); /* pad byte 0 */ + PUTSTRINGF(p, userinfo->passwrd, RAP_UPASSWD_LEN); + PUTDWORD(p, 0); /* pw age - n.a. on user add */ + PUTWORD(p, userinfo->priv); + PUTSTRINGP(p, userinfo->home_dir, data, soffset); + PUTSTRINGP(p, userinfo->comment, data, soffset); + PUTWORD(p, userinfo->userflags); + PUTSTRINGP(p, userinfo->logon_script, data, soffset); + + if (cli_api(cli, + param, sizeof(param), 1024, /* Param, length, maxlen */ + data, soffset, sizeof(data), /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + char *endp = rparam + rprcnt; + res = GETRES(rparam, endp); + + if (res == 0) { + /* nothing to do */ + } else if ((res == 5) || (res == 65)) { + DEBUG(1, ("Access Denied\n")); + } else if (res == 2224) { + DEBUG (1, ("User already exists\n")); + } else { + DEBUG(4,("NetUserAdd res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetUserAdd failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; } /**************************************************************************** call a NetUserEnum - try and list users on a different host ****************************************************************************/ + int cli_RNetUserEnum(struct cli_state *cli, void (*fn)(const char *, const char *, const char *, const char *, void *), void *state) { - char param[WORDSIZE /* api number */ - +sizeof(RAP_NetUserEnum_REQ) /* parm string */ - +sizeof(RAP_USER_INFO_L1) /* return string */ - +WORDSIZE /* info level */ - +WORDSIZE]; /* buffer size */ - char *p; - char *rparam = NULL; - char *rdata = NULL; - unsigned int rprcnt, rdrcnt; - int res = -1; - - memset(param, '\0', sizeof(param)); - p = make_header(param, RAP_WUserEnum, - RAP_NetUserEnum_REQ, RAP_USER_INFO_L1); - PUTWORD(p,1); /* Info level 1 */ - PUTWORD(p,0xFF00); /* Return buffer size */ - -/* BB Fix handling of large numbers of users to be returned */ - if (cli_api(cli, - param, PTR_DIFF(p,param),8, - NULL, 0, CLI_BUFFER_SIZE, - &rparam, &rprcnt, - &rdata, &rdrcnt)) { - res = GETRES(rparam); - cli->rap_error = res; - if (cli->rap_error != 0) { - DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error)); - } - } - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, converter, count; - char username[RAP_USERNAME_LEN]; - char userpw[RAP_UPASSWD_LEN]; - pstring comment, homedir, logonscript; - - p = rparam + WORDSIZE; /* skip result */ - GETWORD(p, converter); - GETWORD(p, count); - - for (i=0,p=rdata;irap_error = res; + if (cli->rap_error != 0) { + DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error)); + } + } + + if (!rdata) { + DEBUG(4,("NetUserEnum no data returned\n")); + goto out; + } + + if (res == 0 || res == ERRmoredata) { + int i, converter = 0, count = 0; + char username[RAP_USERNAME_LEN]; + char userpw[RAP_UPASSWD_LEN]; + char *endp = rparam + rprcnt; + char *comment, *homedir, *logonscript; + TALLOC_CTX *frame = talloc_stackframe(); + + p = rparam + WORDSIZE; /* skip result */ + GETWORD(p, converter, endp); + GETWORD(p, count, endp); + + endp = rdata + rdrcnt; + for (i=0,p=rdata;irap_error = res; - if (cli->rap_error != 0) { - DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error)); - } - } - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, count; - char username[RAP_USERNAME_LEN]; - - p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ - GETWORD(p, count); - - for (i=0,p=rdata;irap_error = res; + if (cli->rap_error != 0) { + DEBUG(1,("NetUserEnum gave error %d\n", cli->rap_error)); + } + } + + if (!rdata) { + DEBUG(4,("NetUserEnum no data returned\n")); + goto out; + } + + if (res == 0 || res == ERRmoredata) { + int i, count = 0; + char *endp = rparam + rprcnt; + char username[RAP_USERNAME_LEN]; + + p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ + GETWORD(p, count, endp); + + endp = rdata + rdrcnt; + for (i=0,p=rdata;ishare_name, RAP_SHARENAME_LEN); - PUTBYTE(p, 0); /* pad byte 0 */ - - PUTWORD(p, sinfo->share_type); - PUTSTRINGP(p, sinfo->comment, data, soffset); - PUTWORD(p, sinfo->perms); - PUTWORD(p, sinfo->maximum_users); - PUTWORD(p, sinfo->active_users); - PUTSTRINGP(p, sinfo->path, data, soffset); - PUTSTRINGF(p, sinfo->password, RAP_SPASSWD_LEN); - SCVAL(p,-1,0x0A); /* required 0x0A at end of password */ - - if (cli_api(cli, - param, sizeof(param), 1024, /* Param, length, maxlen */ - data, soffset, sizeof(data), /* data, length, maxlen */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) /* return data, length */ - { - res = rparam? SVAL(rparam,0) : -1; - - if (res == 0) { - /* nothing to do */ - } - else { - DEBUG(4,("NetShareAdd res=%d\n", res)); - } - } else { - res = -1; - DEBUG(4,("NetShareAdd failed\n")); - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return res; + char *rparam = NULL; + char *rdata = NULL; + char *p; + unsigned int rdrcnt,rprcnt; + int res = -1; + char param[WORDSIZE /* api number */ + +sizeof(RAP_WShareAdd_REQ) /* req string */ + +sizeof(RAP_SHARE_INFO_L2) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* reserved word */ + char data[1024]; + /* offset to free format string section following fixed length data. */ + /* will be updated by PUTSTRINGP macro and will end up with total len */ + int soffset = RAP_SHARENAME_LEN + 1 /* share name + pad */ + + WORDSIZE /* share type */ + + DWORDSIZE /* comment pointer */ + + WORDSIZE /* permissions */ + + WORDSIZE /* max users */ + + WORDSIZE /* active users */ + + DWORDSIZE /* share path */ + + RAP_SPASSWD_LEN + 1; /* share password + pad */ + + memset(param,'\0',sizeof(param)); + /* now send a SMBtrans command with api RNetShareAdd */ + p = make_header(param, RAP_WshareAdd, + RAP_WShareAdd_REQ, RAP_SHARE_INFO_L2); + PUTWORD(p, 2); /* info level */ + PUTWORD(p, 0); /* reserved word 0 */ + + p = data; + PUTSTRINGF(p, sinfo->share_name, RAP_SHARENAME_LEN); + PUTBYTE(p, 0); /* pad byte 0 */ + + PUTWORD(p, sinfo->share_type); + PUTSTRINGP(p, sinfo->comment, data, soffset); + PUTWORD(p, sinfo->perms); + PUTWORD(p, sinfo->maximum_users); + PUTWORD(p, sinfo->active_users); + PUTSTRINGP(p, sinfo->path, data, soffset); + PUTSTRINGF(p, sinfo->password, RAP_SPASSWD_LEN); + SCVAL(p,-1,0x0A); /* required 0x0A at end of password */ + + if (cli_api(cli, + param, sizeof(param), 1024, /* Param, length, maxlen */ + data, soffset, sizeof(data), /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + char *endp = rparam + rprcnt; + res = GETRES(rparam, endp); + + if (res == 0) { + /* nothing to do */ + } else { + DEBUG(4,("NetShareAdd res=%d\n", res)); + } + } else { + DEBUG(4,("NetShareAdd failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; } + /**************************************************************************** - call a NetShareDelete - unshare exported directory on remote server + Call a NetShareDelete - unshare exported directory on remote server. ****************************************************************************/ + int cli_NetShareDelete(struct cli_state *cli, const char * share_name ) { - char *rparam = NULL; - char *rdata = NULL; - char *p; - unsigned int rdrcnt,rprcnt; - int res; - char param[WORDSIZE /* api number */ - +sizeof(RAP_WShareDel_REQ) /* req string */ - +1 /* no ret string */ - +RAP_SHARENAME_LEN /* share to del */ - +WORDSIZE]; /* reserved word */ - - /* now send a SMBtrans command with api RNetShareDelete */ - p = make_header(param, RAP_WshareDel, RAP_WShareDel_REQ, NULL); - PUTSTRING(p,share_name,RAP_SHARENAME_LEN); - PUTWORD(p,0); /* reserved word MBZ on input */ - - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 200, /* data, length, maxlen */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) /* return data, length */ - { - res = GETRES(rparam); - - if (res == 0) { - /* nothing to do */ - } - else { - DEBUG(4,("NetShareDelete res=%d\n", res)); - } - } else { - res = -1; - DEBUG(4,("NetShareDelete failed\n")); - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return res; + char *rparam = NULL; + char *rdata = NULL; + char *p; + unsigned int rdrcnt,rprcnt; + int res = -1; + char param[WORDSIZE /* api number */ + +sizeof(RAP_WShareDel_REQ) /* req string */ + +1 /* no ret string */ + +RAP_SHARENAME_LEN /* share to del */ + +WORDSIZE]; /* reserved word */ + + /* now send a SMBtrans command with api RNetShareDelete */ + p = make_header(param, RAP_WshareDel, RAP_WShareDel_REQ, NULL); + PUTSTRING(p,share_name,RAP_SHARENAME_LEN); + PUTWORD(p,0); /* reserved word MBZ on input */ + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, 200, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + char *endp = rparam + rprcnt; + res = GETRES(rparam, endp); + + if (res == 0) { + /* nothing to do */ + } else { + DEBUG(4,("NetShareDelete res=%d\n", res)); + } + } else { + DEBUG(4,("NetShareDelete failed\n")); + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; } + /************************************************************************* * * Function Name: cli_get_pdc_name @@ -1223,63 +1468,77 @@ int cli_NetShareDelete(struct cli_state *cli, const char * share_name ) * False - failure * ************************************************************************/ -bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) + +bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char **pdc_name) { - char *rparam = NULL; - char *rdata = NULL; - unsigned int rdrcnt,rprcnt; - char *p; - char param[WORDSIZE /* api number */ - +sizeof(RAP_NetServerEnum2_REQ) /* req string */ - +sizeof(RAP_SERVER_INFO_L1) /* return string */ - +WORDSIZE /* info level */ - +WORDSIZE /* buffer size */ - +DWORDSIZE /* server type */ - +RAP_MACHNAME_LEN]; /* workgroup */ - int count = -1; - - *pdc_name = '\0'; - - /* send a SMBtrans command with api NetServerEnum */ - p = make_header(param, RAP_NetServerEnum2, - RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L1); - PUTWORD(p, 1); /* info level */ - PUTWORD(p, CLI_BUFFER_SIZE); - PUTDWORD(p, SV_TYPE_DOMAIN_CTRL); - PUTSTRING(p, workgroup, RAP_MACHNAME_LEN); - - if (cli_api(cli, - param, PTR_DIFF(p,param), 8, /* params, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt /* return data, return size */ - )) { - cli->rap_error = GETRES(rparam); - - /* - * We only really care to copy a name if the - * API succeeded and we got back a name. - */ - if (cli->rap_error == 0) { - p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ - GETWORD(p, count); - p = rdata; - - if (count > 0) - GETSTRING(p, pdc_name); - } - else { - DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. " - "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); - } - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return(count > 0); -} + char *rparam = NULL; + char *rdata = NULL; + unsigned int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetServerEnum2_REQ) /* req string */ + +sizeof(RAP_SERVER_INFO_L1) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE /* buffer size */ + +DWORDSIZE /* server type */ + +RAP_MACHNAME_LEN]; /* workgroup */ + int count = -1; + int res = -1; + + *pdc_name = NULL; + + /* send a SMBtrans command with api NetServerEnum */ + p = make_header(param, RAP_NetServerEnum2, + RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L1); + PUTWORD(p, 1); /* info level */ + PUTWORD(p, CLI_BUFFER_SIZE); + PUTDWORD(p, SV_TYPE_DOMAIN_CTRL); + PUTSTRING(p, workgroup, RAP_MACHNAME_LEN); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + + char *endp = rparam + rprcnt; + res = GETRES(rparam, endp); + cli->rap_error = res; + + /* + * We only really care to copy a name if the + * API succeeded and we got back a name. + */ + if (cli->rap_error == 0) { + p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ + GETWORD(p, count, endp); + p = rdata; + endp = rdata + rdrcnt; + + if (count > 0) { + TALLOC_CTX *frame = talloc_stackframe(); + char *dcname; + p += rap_getstring(frame, + p, + &dcname, + endp); + if (dcname) { + *pdc_name = SMB_STRDUP(dcname); + } + TALLOC_FREE(frame); + } + } else { + DEBUG(4,("cli_get_pdc_name: machine %s failed the NetServerEnum call. " + "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return(count > 0); +} /************************************************************************* * @@ -1303,49 +1562,62 @@ bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char *pdc_name) * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum() * ************************************************************************/ + bool cli_get_server_domain(struct cli_state *cli) { - char *rparam = NULL; - char *rdata = NULL; - unsigned int rdrcnt,rprcnt; - char *p; - char param[WORDSIZE /* api number */ - +sizeof(RAP_WWkstaGetInfo_REQ) /* req string */ - +sizeof(RAP_WKSTA_INFO_L10) /* return string */ - +WORDSIZE /* info level */ - +WORDSIZE]; /* buffer size */ - int res = -1; - - /* send a SMBtrans command with api NetWkstaGetInfo */ - p = make_header(param, RAP_WWkstaGetInfo, - RAP_WWkstaGetInfo_REQ, RAP_WKSTA_INFO_L10); - PUTWORD(p, 10); /* info level */ - PUTWORD(p, CLI_BUFFER_SIZE); - - if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt)) { /* return data, return size */ - res = GETRES(rparam); - p = rdata; - - if (res == 0) { - int converter; - - p = rparam + WORDSIZE; - GETWORD(p, converter); - - p = rdata + DWORDSIZE + DWORDSIZE; /* skip computer & user names */ - GETSTRINGP(p, cli->server_domain, rdata, converter); - } - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return(res == 0); -} + char *rparam = NULL; + char *rdata = NULL; + unsigned int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_WWkstaGetInfo_REQ) /* req string */ + +sizeof(RAP_WKSTA_INFO_L10) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + int res = -1; + + /* send a SMBtrans command with api NetWkstaGetInfo */ + p = make_header(param, RAP_WWkstaGetInfo, + RAP_WWkstaGetInfo_REQ, RAP_WKSTA_INFO_L10); + PUTWORD(p, 10); /* info level */ + PUTWORD(p, CLI_BUFFER_SIZE); + + if (cli_api(cli, param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt)) { /* return data, return size */ + char *endp = rparam + rprcnt; + res = GETRES(rparam, endp); + + if (res == 0) { + TALLOC_CTX *frame = talloc_stackframe(); + char *server_domain; + int converter = 0; + + p = rparam + WORDSIZE; + GETWORD(p, converter, endp); + + p = rdata + DWORDSIZE + DWORDSIZE; /* skip computer & user names */ + endp = rdata + rdrcnt; + p += rap_getstringp(frame, + p, + &server_domain, + rdata, + converter, + endp); + + if (server_domain) { + fstrcpy(cli->server_domain, server_domain); + } + TALLOC_FREE(frame); + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return(res == 0); +} /************************************************************************* * @@ -1368,44 +1640,48 @@ bool cli_get_server_domain(struct cli_state *cli) * Origins: samba 2.0.6 source/libsmb/clientgen.c cli_NetServerEnum() * ************************************************************************/ + bool cli_get_server_type(struct cli_state *cli, uint32 *pstype) { - char *rparam = NULL; - char *rdata = NULL; - unsigned int rdrcnt,rprcnt; - char *p; - char param[WORDSIZE /* api number */ - +sizeof(RAP_WserverGetInfo_REQ) /* req string */ - +sizeof(RAP_SERVER_INFO_L1) /* return string */ - +WORDSIZE /* info level */ - +WORDSIZE]; /* buffer size */ - int res = -1; - - /* send a SMBtrans command with api NetServerGetInfo */ - p = make_header(param, RAP_WserverGetInfo, - RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1); - PUTWORD(p, 1); /* info level */ - PUTWORD(p, CLI_BUFFER_SIZE); - - if (cli_api(cli, - param, PTR_DIFF(p,param), 8, /* params, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt /* return data, return size */ - )) { - - res = GETRES(rparam); - - if (res == 0 || res == ERRmoredata) { - p = rdata; - *pstype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; - } - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return(res == 0 || res == ERRmoredata); + char *rparam = NULL; + char *rdata = NULL; + unsigned int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_WserverGetInfo_REQ) /* req string */ + +sizeof(RAP_SERVER_INFO_L1) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + int res = -1; + + /* send a SMBtrans command with api NetServerGetInfo */ + p = make_header(param, RAP_WserverGetInfo, + RAP_WserverGetInfo_REQ, RAP_SERVER_INFO_L1); + PUTWORD(p, 1); /* info level */ + PUTWORD(p, CLI_BUFFER_SIZE); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + char *endp = rparam + rprcnt; + res = GETRES(rparam,endp); + + if (res == 0 || res == ERRmoredata) { + p = rdata; + endp = rparam + rprcnt; + p += 18; + GETDWORD(p,*pstype,endp); + *pstype &= ~SV_TYPE_LOCAL_LIST_ONLY; + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return(res == 0 || res == ERRmoredata); } bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, @@ -1420,7 +1696,8 @@ bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, +sizeof(RAP_SERVER_INFO_L1) /* return string */ +WORDSIZE /* info level */ +WORDSIZE]; /* buffer size */ - bool res = False; + bool res = false; + char *endp; fstring tmp; /* send a SMBtrans command with api NetServerGetInfo */ @@ -1438,7 +1715,8 @@ bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, goto failed; } - if (GETRES(rparam) != 0) { + endp = rparam + rprcnt; + if (GETRES(rparam, endp) != 0) { goto failed; } @@ -1457,7 +1735,7 @@ bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, goto failed; } - res = True; + res = true; failed: SAFE_FREE(rparam); @@ -1491,655 +1769,904 @@ bool cli_get_server_name(TALLOC_CTX *mem_ctx, struct cli_state *cli, * False - failure * ************************************************************************/ + bool cli_ns_check_server_type(struct cli_state *cli, char *workgroup, uint32 stype) { - char *rparam = NULL; - char *rdata = NULL; - unsigned int rdrcnt,rprcnt; - char *p; - char param[WORDSIZE /* api number */ - +sizeof(RAP_NetServerEnum2_REQ) /* req string */ - +sizeof(RAP_SERVER_INFO_L0) /* return string */ - +WORDSIZE /* info level */ - +WORDSIZE /* buffer size */ - +DWORDSIZE /* server type */ - +RAP_MACHNAME_LEN]; /* workgroup */ - bool found_server = False; - int res = -1; - - /* send a SMBtrans command with api NetServerEnum */ - p = make_header(param, RAP_NetServerEnum2, - RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L0); - PUTWORD(p, 0); /* info level 0 */ - PUTWORD(p, CLI_BUFFER_SIZE); - PUTDWORD(p, stype); - PUTSTRING(p, workgroup, RAP_MACHNAME_LEN); - - if (cli_api(cli, - param, PTR_DIFF(p,param), 8, /* params, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt /* return data, return size */ - )) { - - res = GETRES(rparam); - cli->rap_error = res; - - if (res == 0 || res == ERRmoredata) { - int i, count; - - p = rparam + WORDSIZE + WORDSIZE; - GETWORD(p, count); - - p = rdata; - for (i = 0;i < count;i++, p += 16) { - char ret_server[RAP_MACHNAME_LEN]; - - GETSTRINGF(p, ret_server, RAP_MACHNAME_LEN); - if (strequal(ret_server, cli->desthost)) { - found_server = True; - break; - } - } - } - else { - DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. " - "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); - } - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return found_server; - } + char *rparam = NULL; + char *rdata = NULL; + unsigned int rdrcnt,rprcnt; + char *p; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetServerEnum2_REQ) /* req string */ + +sizeof(RAP_SERVER_INFO_L0) /* return string */ + +WORDSIZE /* info level */ + +WORDSIZE /* buffer size */ + +DWORDSIZE /* server type */ + +RAP_MACHNAME_LEN]; /* workgroup */ + bool found_server = false; + int res = -1; + + /* send a SMBtrans command with api NetServerEnum */ + p = make_header(param, RAP_NetServerEnum2, + RAP_NetServerEnum2_REQ, RAP_SERVER_INFO_L0); + PUTWORD(p, 0); /* info level 0 */ + PUTWORD(p, CLI_BUFFER_SIZE); + PUTDWORD(p, stype); + PUTSTRING(p, workgroup, RAP_MACHNAME_LEN); + + if (cli_api(cli, + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + char *endp = rparam + rprcnt; + res = GETRES(rparam,endp); + cli->rap_error = res; + + if (res == 0 || res == ERRmoredata) { + int i, count = 0; + + p = rparam + WORDSIZE + WORDSIZE; + GETWORD(p, count,endp); + + p = rdata; + endp = rdata + rdrcnt; + for (i = 0;i < count && p < endp;i++, p += 16) { + char ret_server[RAP_MACHNAME_LEN]; + + p += rap_getstringf(p, + ret_server, + RAP_MACHNAME_LEN, + RAP_MACHNAME_LEN, + endp); + if (strequal(ret_server, cli->desthost)) { + found_server = true; + break; + } + } + } else { + DEBUG(4,("cli_ns_check_server_type: machine %s failed the NetServerEnum call. " + "Error was : %s.\n", cli->desthost, cli_errstr(cli) )); + } + } + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return found_server; +} /**************************************************************************** - perform a NetWkstaUserLogoff + Perform a NetWkstaUserLogoff. ****************************************************************************/ -bool cli_NetWkstaUserLogoff(struct cli_state *cli,char *user, char *workstation) + +bool cli_NetWkstaUserLogoff(struct cli_state *cli, const char *user, const char *workstation) { - char *rparam = NULL; - char *rdata = NULL; - char *p; - unsigned int rdrcnt,rprcnt; - char param[WORDSIZE /* api number */ - +sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string */ - +sizeof(RAP_USER_LOGOFF_INFO_L1) /* return string */ - +RAP_USERNAME_LEN+1 /* user name+pad */ - +RAP_MACHNAME_LEN /* wksta name */ - +WORDSIZE /* buffer size */ - +WORDSIZE]; /* buffer size? */ - fstring upperbuf; - - memset(param, 0, sizeof(param)); - - /* send a SMBtrans command with api NetWkstaUserLogoff */ - p = make_header(param, RAP_WWkstaUserLogoff, - RAP_NetWkstaUserLogoff_REQ, RAP_USER_LOGOFF_INFO_L1); - PUTDWORD(p, 0); /* Null pointer */ - PUTDWORD(p, 0); /* Null pointer */ - fstrcpy(upperbuf, user); - strupper_m(upperbuf); - PUTSTRINGF(p, upperbuf, RAP_USERNAME_LEN); - p++; /* strange format, but ok */ - fstrcpy(upperbuf, workstation); - strupper_m(upperbuf); - PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN); - PUTWORD(p, CLI_BUFFER_SIZE); - PUTWORD(p, CLI_BUFFER_SIZE); - - if (cli_api(cli, - param, PTR_DIFF(p,param),1024, /* param, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt /* return data, return size */ - )) { - cli->rap_error = GETRES(rparam); - - if (cli->rap_error != 0) { - DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli->rap_error)); - } - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - return (cli->rap_error == 0); + char *rparam = NULL; + char *rdata = NULL; + char *p; + unsigned int rdrcnt,rprcnt; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetWkstaUserLogoff_REQ) /* req string */ + +sizeof(RAP_USER_LOGOFF_INFO_L1) /* return string */ + +RAP_USERNAME_LEN+1 /* user name+pad */ + +RAP_MACHNAME_LEN /* wksta name */ + +WORDSIZE /* buffer size */ + +WORDSIZE]; /* buffer size? */ + char upperbuf[MAX(RAP_USERNAME_LEN,RAP_MACHNAME_LEN)]; + int res = -1; + + memset(param, 0, sizeof(param)); + + /* send a SMBtrans command with api NetWkstaUserLogoff */ + p = make_header(param, RAP_WWkstaUserLogoff, + RAP_NetWkstaUserLogoff_REQ, RAP_USER_LOGOFF_INFO_L1); + PUTDWORD(p, 0); /* Null pointer */ + PUTDWORD(p, 0); /* Null pointer */ + strlcpy(upperbuf, user, sizeof(upperbuf)); + strupper_m(upperbuf); + PUTSTRINGF(p, upperbuf, RAP_USERNAME_LEN); + p++; /* strange format, but ok */ + strlcpy(upperbuf, workstation, sizeof(upperbuf)); + strupper_m(upperbuf); + PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN); + PUTWORD(p, CLI_BUFFER_SIZE); + PUTWORD(p, CLI_BUFFER_SIZE); + + if (cli_api(cli, + param, PTR_DIFF(p,param),1024, /* param, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt /* return data, return size */ + )) { + char *endp = rparam + rprcnt; + res = GETRES(rparam,endp); + cli->rap_error = res; + + if (cli->rap_error != 0) { + DEBUG(4,("NetwkstaUserLogoff gave error %d\n", cli->rap_error)); + } + } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return (cli->rap_error == 0); } int cli_NetPrintQEnum(struct cli_state *cli, void (*qfn)(const char*,uint16,uint16,uint16,const char*,const char*,const char*,const char*,const char*,uint16,uint16), void (*jfn)(uint16,const char*,const char*,const char*,const char*,uint16,uint16,const char*,uint,uint,const char*)) { - char param[WORDSIZE /* api number */ - +sizeof(RAP_NetPrintQEnum_REQ) /* req string */ - +sizeof(RAP_PRINTQ_INFO_L2) /* return string */ - +WORDSIZE /* info level */ - +WORDSIZE /* buffer size */ - +sizeof(RAP_SMB_PRINT_JOB_L1)]; /* more ret data */ - char *p; - char *rparam = NULL; - char *rdata = NULL; - unsigned int rprcnt, rdrcnt; - int res = -1; - - - memset(param, '\0',sizeof(param)); - p = make_header(param, RAP_WPrintQEnum, - RAP_NetPrintQEnum_REQ, RAP_PRINTQ_INFO_L2); - PUTWORD(p,2); /* Info level 2 */ - PUTWORD(p,0xFFE0); /* Return buffer size */ - PUTSTRING(p, RAP_SMB_PRINT_JOB_L1, 0); - - if (cli_api(cli, - param, PTR_DIFF(p,param),1024, - NULL, 0, CLI_BUFFER_SIZE, - &rparam, &rprcnt, - &rdata, &rdrcnt)) { - res = GETRES(rparam); - cli->rap_error = res; - if (res != 0) { - DEBUG(1,("NetPrintQEnum gave error %d\n", res)); - } - } - - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, converter, count; - - p = rparam + WORDSIZE; - GETWORD(p, converter); - GETWORD(p, count); - - p = rdata; - for (i=0;irap_error = res; + if (res != 0) { + DEBUG(1,("NetPrintQEnum gave error %d\n", res)); + } + } + + if (!rdata) { + DEBUG(4,("NetPrintQEnum no data returned\n")); + goto out; + } + + if (res == 0 || res == ERRmoredata) { + TALLOC_CTX *frame = talloc_stackframe(); + char *endp = rparam + rprcnt; + int i, converter = 0, count = 0; + + p = rparam + WORDSIZE; + GETWORD(p, converter, endp); + GETWORD(p, count, endp); + + p = rdata; + endp = rdata + rdrcnt; + for (i=0;irap_error = res; - if (res != 0) { - DEBUG(1,("NetPrintQGetInfo gave error %d\n", res)); - } - } - - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int rsize, converter; - pstring qname, sep_file, print_proc, dest, parms, comment; - uint16 jobcount, priority, start_time, until_time, status; - - p = rparam + WORDSIZE; - GETWORD(p, converter); - GETWORD(p, rsize); - - p = rdata; - GETSTRINGF(p, qname, RAP_SHARENAME_LEN); - p++; /* pad */ - GETWORD(p, priority); - GETWORD(p, start_time); - GETWORD(p, until_time); - GETSTRINGP(p, sep_file, rdata, converter); - GETSTRINGP(p, print_proc, rdata, converter); - GETSTRINGP(p, dest, rdata, converter); - GETSTRINGP(p, parms, rdata, converter); - GETSTRINGP(p, comment, rdata, converter); - GETWORD(p, status); - GETWORD(p, jobcount); - qfn(qname, priority, start_time, until_time, sep_file, print_proc, - dest, parms, comment, status, jobcount); - if (jobcount) { - int j; - for (j=0;(jrap_error = res; + if (res != 0) { + DEBUG(1,("NetPrintQGetInfo gave error %d\n", res)); + } + } + + if (!rdata) { + DEBUG(4,("NetPrintQGetInfo no data returned\n")); + goto out; + } + + if (res == 0 || res == ERRmoredata) { + TALLOC_CTX *frame = talloc_stackframe(); + char *endp = rparam + rprcnt; + int rsize = 0, converter = 0; + char qname[RAP_SHARENAME_LEN]; + char *sep_file, *print_proc, *dest, *parms, *comment; + uint16_t jobcount = 0, priority = 0; + uint16_t start_time = 0, until_time = 0, status = 0; + + p = rparam + WORDSIZE; + GETWORD(p, converter, endp); + GETWORD(p, rsize, endp); + + p = rdata; + endp = rdata + rdrcnt; + p += rap_getstringf(p, + qname, + RAP_SHARENAME_LEN, + RAP_SHARENAME_LEN, + endp); + p++; /* pad */ + GETWORD(p, priority, endp); + GETWORD(p, start_time, endp); + GETWORD(p, until_time, endp); + p += rap_getstringp(frame, + p, + &sep_file, + rdata, + converter, + endp); + p += rap_getstringp(frame, + p, + &print_proc, + rdata, + converter, + endp); + p += rap_getstringp(frame, + p, + &dest, + rdata, + converter, + endp); + p += rap_getstringp(frame, + p, + &parms, + rdata, + converter, + endp); + p += rap_getstringp(frame, + p, + &comment, + rdata, + converter, + endp); + GETWORD(p, status, endp); + GETWORD(p, jobcount, endp); + + if (sep_file && print_proc && dest && + parms && comment) { + qfn(qname, priority, start_time, until_time, sep_file, print_proc, + dest, parms, comment, status, jobcount); + } + if (jobcount) { + int j; + for (j=0;(jrap_error = res; + if(cli->rap_error == 234) { + DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n")); + } else if (cli->rap_error != 0) { + DEBUG(1,("NetServiceEnum gave error %d\n", cli->rap_error)); + } + } + if (!rdata) { + DEBUG(4,("NetServiceEnum no data returned\n")); + goto out; + } - memset(param, '\0', sizeof(param)); - p = make_header(param, RAP_WServiceEnum, - RAP_NetServiceEnum_REQ, RAP_SERVICE_INFO_L2); - PUTWORD(p,2); /* Info level 2 */ - PUTWORD(p,0xFFE0); /* Return buffer size */ + if (res == 0 || res == ERRmoredata) { + char *endp = rparam + rprcnt; + int i, count = 0; + + p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ + GETWORD(p, count,endp); + + endp = rdata + rdrcnt; + for (i=0,p=rdata;irap_error = res; - if(cli->rap_error == 234) - DEBUG(1,("Not all service names were returned (such as those longer than 15 characters)\n")); - else if (cli->rap_error != 0) { - DEBUG(1,("NetServiceEnum gave error %d\n", cli->rap_error)); - } - } - - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, count; - - p = rparam + WORDSIZE + WORDSIZE; /* skip result and converter */ - GETWORD(p, count); - - for (i=0,p=rdata;irap_error = res; - if (res != 0) { - DEBUG(1,("NetSessionEnum gave error %d\n", res)); - } - } - - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, converter, count; - - p = rparam + WORDSIZE; - GETWORD(p, converter); - GETWORD(p, count); - - for (i=0,p=rdata;irap_error = res; + if (res != 0) { + DEBUG(1,("NetSessionEnum gave error %d\n", res)); + } + } + + if (!rdata) { + DEBUG(4,("NetSesssionEnum no data returned\n")); + goto out; + } + + if (res == 0 || res == ERRmoredata) { + TALLOC_CTX *frame = talloc_stackframe(); + char *endp = rparam + rprcnt; + int i, converter = 0, count = 0; + + p = rparam + WORDSIZE; + GETWORD(p, converter, endp); + GETWORD(p, count, endp); + + endp = rdata + rdrcnt; + for (i=0,p=rdata;irap_error = SVAL(rparam,0); - if (cli->rap_error != 0) { - DEBUG(1,("NetSessionGetInfo gave error %d\n", cli->rap_error)); - } - } - - if (rdata) { - res = GETRES(rparam); - - if (res == 0 || res == ERRmoredata) { - int converter; - pstring wsname, username, clitype_name; - uint16 num_conns, num_opens, num_users; - unsigned int sess_time, idle_time, user_flags; - - p = rparam + WORDSIZE; - GETWORD(p, converter); - p += WORDSIZE; /* skip rsize */ - - p = rdata; - GETSTRINGP(p, wsname, rdata, converter); - GETSTRINGP(p, username, rdata, converter); - GETWORD(p, num_conns); - GETWORD(p, num_opens); - GETWORD(p, num_users); - GETDWORD(p, sess_time); - GETDWORD(p, idle_time); - GETDWORD(p, user_flags); - GETSTRINGP(p, clitype_name, rdata, converter); - - fn(wsname, username, num_conns, num_opens, num_users, sess_time, - idle_time, user_flags, clitype_name); - } else { - DEBUG(4,("NetSessionGetInfo res=%d\n", res)); - } - } else { - DEBUG(4,("NetSessionGetInfo no data returned\n")); - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return res; + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetSessionGetInfo_REQ) /* req string */ + +sizeof(RAP_SESSION_INFO_L2) /* return string */ + +RAP_MACHNAME_LEN /* wksta name */ + +WORDSIZE /* info level */ + +WORDSIZE]; /* buffer size */ + char *p; + char *rparam = NULL; + char *rdata = NULL; + unsigned int rprcnt, rdrcnt; + char *endp; + int res = -1; + + memset(param, '\0', sizeof(param)); + p = make_header(param, RAP_WsessionGetInfo, + RAP_NetSessionGetInfo_REQ, RAP_SESSION_INFO_L2); + PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1); + PUTWORD(p,2); /* Info level 2 */ + PUTWORD(p,0xFF); /* Return buffer size */ + + if (cli_api(cli, + param, PTR_DIFF(p,param),PTR_DIFF(p,param), + NULL, 0, CLI_BUFFER_SIZE, + &rparam, &rprcnt, + &rdata, &rdrcnt)) { + endp = rparam + rprcnt; + res = GETRES(rparam, endp); + cli->rap_error = res; + if (cli->rap_error != 0) { + DEBUG(1,("NetSessionGetInfo gave error %d\n", cli->rap_error)); + } + } + + if (!rdata) { + DEBUG(4,("NetSessionGetInfo no data returned\n")); + goto out; + } + + endp = rparam + rprcnt; + res = GETRES(rparam, endp); + + if (res == 0 || res == ERRmoredata) { + TALLOC_CTX *frame = talloc_stackframe(); + int converter = 0; + char *wsname, *username, *clitype_name; + uint16_t num_conns = 0, num_opens = 0, num_users = 0; + unsigned int sess_time = 0, idle_time = 0, user_flags = 0; + + p = rparam + WORDSIZE; + GETWORD(p, converter,endp); + p += WORDSIZE; /* skip rsize */ + + p = rdata; + endp = rdata + rdrcnt; + p += rap_getstringp(frame, + p, + &wsname, + rdata, + converter, + endp); + p += rap_getstringp(frame, + p, + &username, + rdata, + converter, + endp); + GETWORD(p, num_conns, endp); + GETWORD(p, num_opens, endp); + GETWORD(p, num_users, endp); + GETDWORD(p, sess_time, endp); + GETDWORD(p, idle_time, endp); + GETDWORD(p, user_flags, endp); + p += rap_getstringp(frame, + p, + &clitype_name, + rdata, + converter, + endp); + + if (wsname && username && clitype_name) { + fn(wsname, username, num_conns, num_opens, num_users, sess_time, + idle_time, user_flags, clitype_name); + } + TALLOC_FREE(frame); + } else { + DEBUG(4,("NetSessionGetInfo res=%d\n", res)); + } + + out: + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + + return res; } /**************************************************************************** -call a NetSessionDel - close a session to an SMB server + Call a NetSessionDel - close a session to an SMB server. ****************************************************************************/ + int cli_NetSessionDel(struct cli_state *cli, const char *workstation) { - char param[WORDSIZE /* api number */ - +sizeof(RAP_NetSessionDel_REQ) /* req string */ - +1 /* no return string */ - +RAP_MACHNAME_LEN /* workstation name */ - +WORDSIZE]; /* reserved (0) */ - char *p; - char *rparam = NULL; - char *rdata = NULL; - unsigned int rprcnt, rdrcnt; - int res; - - memset(param, '\0', sizeof(param)); - p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL); - PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1); - PUTWORD(p,0); /* reserved word of 0 */ - if (cli_api(cli, - param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ - NULL, 0, 200, /* data, length, maxlen */ - &rparam, &rprcnt, /* return params, length */ - &rdata, &rdrcnt)) /* return data, length */ - { - res = GETRES(rparam); - cli->rap_error = res; - - if (res == 0) { - /* nothing to do */ - } - else { - DEBUG(4,("NetFileClose2 res=%d\n", res)); - } - } else { - res = -1; - DEBUG(4,("NetFileClose2 failed\n")); - } - - SAFE_FREE(rparam); - SAFE_FREE(rdata); - - return res; -} + char param[WORDSIZE /* api number */ + +sizeof(RAP_NetSessionDel_REQ) /* req string */ + +1 /* no return string */ + +RAP_MACHNAME_LEN /* workstation name */ + +WORDSIZE]; /* reserved (0) */ + char *p; + char *rparam = NULL; + char *rdata = NULL; + unsigned int rprcnt, rdrcnt; + int res = -1; + + memset(param, '\0', sizeof(param)); + p = make_header(param, RAP_WsessionDel, RAP_NetSessionDel_REQ, NULL); + PUTSTRING(p, workstation, RAP_MACHNAME_LEN-1); + PUTWORD(p,0); /* reserved word of 0 */ + + if (cli_api(cli, + param, PTR_DIFF(p,param), 1024, /* Param, length, maxlen */ + NULL, 0, 200, /* data, length, maxlen */ + &rparam, &rprcnt, /* return params, length */ + &rdata, &rdrcnt)) /* return data, length */ + { + char *endp = rparam + rprcnt; + res = GETRES(rparam, endp); + cli->rap_error = res; + + if (res == 0) { + /* nothing to do */ + } else { + DEBUG(4,("NetFileClose2 res=%d\n", res)); + } + } else { + res = -1; + DEBUG(4,("NetFileClose2 failed\n")); + } + SAFE_FREE(rparam); + SAFE_FREE(rdata); -int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, void (*fn)(uint16 conid, uint16 contype, uint16 numopens, uint16 numusers, uint32 contime, const char *username, const char *netname)) + return res; +} + +int cli_NetConnectionEnum(struct cli_state *cli, const char *qualifier, + void (*fn)(uint16_t conid, uint16_t contype, + uint16_t numopens, uint16_t numusers, + uint32_t contime, const char *username, + const char *netname)) { - char param[WORDSIZE /* api number */ - +sizeof(RAP_NetConnectionEnum_REQ) /* req string */ - +sizeof(RAP_CONNECTION_INFO_L1) /* return string */ - +RAP_MACHNAME_LEN /* wksta name */ - +WORDSIZE /* info level */ - +WORDSIZE]; /* buffer size */ - char *p; - char *rparam = NULL; - char *rdata = NULL; - unsigned int rprcnt, rdrcnt; - int res = -1; - - memset(param, '\0', sizeof(param)); - p = make_header(param, RAP_WconnectionEnum, - RAP_NetConnectionEnum_REQ, RAP_CONNECTION_INFO_L1); - PUTSTRING(p, qualifier, RAP_MACHNAME_LEN-1);/* Workstation name */ - PUTWORD(p,1); /* Info level 1 */ - PUTWORD(p,0xFFE0); /* Return buffer size */ - - if (cli_api(cli, - param, PTR_DIFF(p,param),PTR_DIFF(p,param), - NULL, 0, CLI_BUFFER_SIZE, - &rparam, &rprcnt, - &rdata, &rdrcnt)) { - res = GETRES(rparam); - cli->rap_error = res; - if (res != 0) { - DEBUG(1,("NetConnectionEnum gave error %d\n", res)); - } - } - if (rdata) { - if (res == 0 || res == ERRmoredata) { - int i, converter, count; - - p = rparam + WORDSIZE; - GETWORD(p, converter); - GETWORD(p, count); - - for (i=0,p=rdata;irap_error = res; + if (res != 0) { + DEBUG(1,("NetConnectionEnum gave error %d\n", res)); + } + } + + if (!rdata) { + DEBUG(4,("NetConnectionEnum no data returned\n")); + goto out; + } + + if (res == 0 || res == ERRmoredata) { + TALLOC_CTX *frame = talloc_stackframe(); + char *endp = rparam + rprcnt; + int i, converter = 0, count = 0; + + p = rparam + WORDSIZE; + GETWORD(p, converter, endp); + GETWORD(p, count, endp); + + endp = rdata + rdrcnt; + for (i=0,p=rdata;i Date: Mon, 3 Dec 2007 18:56:54 -0800 Subject: Don't forget to delete the stackframe. Jeremy. (This used to be commit 0551ee3402daebe5b96a66162d7702ca5a31da52) --- source3/libsmb/clidfs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 8ff358e26f..32a2c31c83 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -873,6 +873,7 @@ bool cli_resolve_path_pstring( const char *mountpt, if (tpath) { pstrcpy(targetpath, tpath); } + TALLOC_FREE(ctx); return ret; } -- cgit From 774a30989af4879cc6c3f5a270a20a645983edfa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Dec 2007 13:30:22 -0800 Subject: Fix signing bug found by Volker. That one was *subtle*. Jeremy (This used to be commit 816aea6c1a426eb2450061b847729e22bdac33a0) --- source3/libsmb/clitrans.c | 14 -------- source3/libsmb/smb_signing.c | 79 +++----------------------------------------- 2 files changed, 5 insertions(+), 88 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 739c8ba1d1..a6f7f7fec1 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -94,14 +94,9 @@ bool cli_send_trans(struct cli_state *cli, int trans, return False; } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - client_set_trans_sign_state_on(cli, mid); - if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - client_set_trans_sign_state_off(cli, mid); return(False); } @@ -143,7 +138,6 @@ bool cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { - client_set_trans_sign_state_off(cli, mid); return False; } @@ -350,7 +344,6 @@ bool cli_receive_trans(struct cli_state *cli,int trans, } } - client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } @@ -418,14 +411,9 @@ bool cli_send_nt_trans(struct cli_state *cli, return False; } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - client_set_trans_sign_state_on(cli, mid); - if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - client_set_trans_sign_state_off(cli, mid); return(False); } @@ -467,7 +455,6 @@ bool cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { - client_set_trans_sign_state_off(cli, mid); return False; } @@ -695,6 +682,5 @@ bool cli_receive_nt_trans(struct cli_state *cli, } } - client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index 1e150525ba..d5cbe3b125 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,7 +25,6 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; - bool can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -42,7 +41,9 @@ static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, /* Ensure we only add a mid once. */ for (t = *list; t; t = t->next) { if (t->mid == mid) { - return False; + DLIST_REMOVE(*list, t); + SAFE_FREE(t); + break; } } @@ -51,7 +52,6 @@ static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, t->mid = mid; t->reply_seq_num = reply_seq_num; - t->can_delete = True; /* * Add to the *start* of the list not the end of the list. @@ -78,23 +78,8 @@ static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, *reply_seq_num = t->reply_seq_num; DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - if (t->can_delete) { - DLIST_REMOVE(*list, t); - SAFE_FREE(t); - } - return True; - } - } - return False; -} - -static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) -{ - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - t->can_delete = can_delete_entry; + DLIST_REMOVE(*list, t); + SAFE_FREE(t); return True; } } @@ -608,60 +593,6 @@ bool cli_check_sign_mac(struct cli_state *cli) return True; } -/*********************************************************** - Enter trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) -{ - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { - return False; - } - - return True; -} - -/*********************************************************** - Leave trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) -{ - uint32 reply_seq_num; - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { - return False; - } - - /* Now delete the stored mid entry. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { - return False; - } - - return True; -} - /*********************************************************** Is client signing on ? ************************************************************/ -- cgit From 78c6ee0090f4122bc25baaacb5546517ad4b7bc6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 24 Nov 2007 17:27:54 +0100 Subject: Remove some globals (This used to be commit 31d0a846db08d845e6cdfd85def4ac1c34031e02) --- source3/libsmb/dsgetdcname.c | 3 +-- source3/libsmb/namecache.c | 6 +++--- source3/libsmb/namequery.c | 2 +- source3/libsmb/trustdom_cache.c | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index b0870e249e..f8089cbd6a 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -265,8 +265,7 @@ static char *DsGetDcName_cache_key(TALLOC_CTX *mem_ctx, const char *domain) return NULL; } - return talloc_asprintf(mem_ctx, DSGETDCNAME_FMT, - strupper_static(domain)); + return talloc_asprintf_strupper_m(mem_ctx, DSGETDCNAME_FMT, domain); } /**************************************************************** diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 6a675d2ef2..ba706e5ee2 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -98,7 +98,7 @@ static char* namecache_key(const char *name, int name_type) { char *keystr; - asprintf(&keystr, NBTKEY_FMT, strupper_static(name), name_type); + asprintf_strupper_m(&keystr, NBTKEY_FMT, name, name_type); return keystr; } @@ -318,8 +318,8 @@ static char *namecache_status_record_key(const char *name, char *keystr; print_sockaddr(addr, sizeof(addr), keyip); - asprintf(&keystr, "NBT/%s#%02X.%02X.%s", - strupper_static(name), name_type1, name_type2, addr); + asprintf_strupper_m(&keystr, "NBT/%s#%02X.%02X.%s", name, + name_type1, name_type2, addr); return keystr; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 71d7096914..04db3322ca 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -39,7 +39,7 @@ static char *saf_key(const char *domain) { char *keystr; - asprintf( &keystr, SAFKEY_FMT, strupper_static(domain) ); + asprintf_strupper_m(&keystr, SAFKEY_FMT, domain); return keystr; } diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index f350cd0bc8..be73381aa3 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -90,7 +90,7 @@ bool trustdom_cache_shutdown(void) static char* trustdom_cache_key(const char* name) { char* keystr = NULL; - asprintf(&keystr, TDOMKEY_FMT, strupper_static(name)); + asprintf_strupper_m(&keystr, TDOMKEY_FMT, name); return keystr; } -- cgit From 195d6be38d9d721837a8d44ff918829528059cda Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 24 Nov 2007 15:47:04 +0100 Subject: remove some statics (This used to be commit 97c9a4042d36178a728b5e0f8923091c7069366d) --- source3/libsmb/credentials.c | 12 ++++++----- source3/libsmb/nmblib.c | 49 +++++++------------------------------------- source3/libsmb/unexpected.c | 43 +++++++++++++++++++++----------------- 3 files changed, 38 insertions(+), 66 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 973bb6ad28..1256a6210e 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -26,11 +26,13 @@ char *credstr(const unsigned char *cred) { - static fstring buf; - slprintf(buf, sizeof(buf) - 1, "%02X%02X%02X%02X%02X%02X%02X%02X", - cred[0], cred[1], cred[2], cred[3], - cred[4], cred[5], cred[6], cred[7]); - return buf; + char *result; + result = talloc_asprintf(talloc_tos(), + "%02X%02X%02X%02X%02X%02X%02X%02X", + cred[0], cred[1], cred[2], cred[3], + cred[4], cred[5], cred[6], cred[7]); + SMB_ASSERT(result != NULL); + return result; } /**************************************************************************** diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 7e152ab324..2ff925ef36 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -347,20 +347,19 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name) char *nmb_namestr(const struct nmb_name *n) { - static int i=0; - static fstring ret[4]; fstring name; - char *p = ret[i]; + char *result; pull_ascii_fstring(name, n->name); if (!n->scope[0]) - slprintf(p,sizeof(fstring)-1, "%s<%02x>",name,n->name_type); + result = talloc_asprintf(talloc_tos(), "%s<%02x>", name, + n->name_type); else - slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s", - name,n->name_type,n->scope); + result = talloc_asprintf(talloc_tos(), "%s<%02x>.%s", name, + n->name_type, n->scope); - i = (i+1)%4; - return(p); + SMB_ASSERT(result != NULL); + return result; } /******************************************************************* @@ -1239,40 +1238,6 @@ void sort_query_replies(char *data, int n, struct in_addr ip) qsort(data, n, 6, QSORT_CAST name_query_comp); } -/******************************************************************* - Convert, possibly using a stupid microsoft-ism which has destroyed - the transport independence of netbios (for CIFS vendors that usually - use the Win95-type methods, not for NT to NT communication, which uses - DCE/RPC and therefore full-length unicode strings...) a dns name into - a netbios name. - - The netbios name (NOT necessarily null-terminated) is truncated to 15 - characters. - - ******************************************************************/ - -char *dns_to_netbios_name(const char *dns_name) -{ - static nstring netbios_name; - int i; - StrnCpy(netbios_name, dns_name, MAX_NETBIOSNAME_LEN-1); - netbios_name[15] = 0; - - /* ok. this is because of a stupid microsoft-ism. if the called host - name contains a '.', microsoft clients expect you to truncate the - netbios name up to and including the '.' this even applies, by - mistake, to workgroup (domain) names, which is _really_ daft. - */ - for (i = 0; i < 15; i++) { - if (netbios_name[i] == '.') { - netbios_name[i] = 0; - break; - } - } - - return netbios_name; -} - /**************************************************************************** Interpret the weird netbios "name" into a unix fstring. Return the name type. ****************************************************************************/ diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index f5837f321c..92a609c42b 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -112,18 +112,22 @@ void clear_unexpected(time_t t) tdb_traverse(tdbd, traverse_fn, NULL); } - -static struct packet_struct *matched_packet; -static int match_id; -static enum packet_type match_type; -static const char *match_name; +struct receive_unexpected_state { + struct packet_struct *matched_packet; + int match_id; + enum packet_type match_type; + const char *match_name; +}; /**************************************************************************** tdb traversal fn to find a matching 137 packet. **************************************************************************/ -static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *state) +static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, + void *private_data) { + struct receive_unexpected_state *state = + (struct receive_unexpected_state *)private_data; struct unexpected_key key; struct in_addr ip; uint32_t enc_ip; @@ -132,7 +136,7 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void memcpy(&key, kbuf.dptr, sizeof(key)); - if (key.packet_type != match_type) return 0; + if (key.packet_type != state->match_type) return 0; if (dbuf.dsize < 6) { return 0; @@ -145,15 +149,15 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void p = parse_packet((char *)&dbuf.dptr[6], dbuf.dsize-6, - match_type, + state->match_type, ip, port); - if ((match_type == NMB_PACKET && - p->packet.nmb.header.name_trn_id == match_id) || - (match_type == DGRAM_PACKET && - match_mailslot_name(p, match_name))) { - matched_packet = p; + if ((state->match_type == NMB_PACKET && + p->packet.nmb.header.name_trn_id == state->match_id) || + (state->match_type == DGRAM_PACKET && + match_mailslot_name(p, state->match_name))) { + state->matched_packet = p; return -1; } @@ -170,18 +174,19 @@ struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, const char *mailslot_name) { TDB_CONTEXT *tdb2; + struct receive_unexpected_state state; tdb2 = tdb_open_log(lock_path("unexpected.tdb"), 0, 0, O_RDONLY, 0); if (!tdb2) return NULL; - matched_packet = NULL; - match_id = id; - match_type = packet_type; - match_name = mailslot_name; + state.matched_packet = NULL; + state.match_id = id; + state.match_type = packet_type; + state.match_name = mailslot_name; - tdb_traverse(tdb2, traverse_match, NULL); + tdb_traverse(tdb2, traverse_match, &state); tdb_close(tdb2); - return matched_packet; + return state.matched_packet; } -- cgit From 1938e861d0081fd5a28b8b345df70f22b3d841a5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Dec 2007 13:31:24 -0800 Subject: Remove arbitrary 1k limit on pathnames. Malloc them. Jeremy. (This used to be commit 71770b4c1d021d829deeb53a6ea3b747fce55c84) --- source3/libsmb/clifile.c | 462 ++++++++++++++++++++++++++++------------------- source3/libsmb/clirap.c | 97 ++++++---- 2 files changed, 347 insertions(+), 212 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index cd50cfc03c..70b4fe7cb3 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -30,44 +30,57 @@ static bool cli_link_internal(struct cli_state *cli, const char *oldname, const unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; - char param[1024+6]; - char data[1024]; + char *param; + char *data; char *rparam=NULL, *rdata=NULL; char *p; size_t oldlen = 2*(strlen(oldname)+1); size_t newlen = 2*(strlen(newname)+1); - memset(param, 0, sizeof(param)); + param = SMB_MALLOC(6+newlen+2); + data = SMB_MALLOC(oldlen+2); + if (!param || !data) { + return false; + } + SSVAL(param,0,hard_link ? SMB_SET_FILE_UNIX_HLINK : SMB_SET_FILE_UNIX_LINK); + SIVAL(param,2,0); p = ¶m[6]; - p += clistr_push(cli, p, newname, MIN(newlen, sizeof(param)-6), STR_TERMINATE); + p += clistr_push(cli, p, newname, newlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); p = data; - p += clistr_push(cli, p, oldname, MIN(oldlen,sizeof(data)), STR_TERMINATE); + p += clistr_push(cli, p, oldname, oldlen, STR_TERMINATE); data_len = PTR_DIFF(p, data); if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + SAFE_FREE(data); + SAFE_FREE(param); + return false; } + SAFE_FREE(data); + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; + &rparam, ¶m_len, + &rdata, &data_len)) { + return false; } + SAFE_FREE(data); + SAFE_FREE(param); SAFE_FREE(rdata); SAFE_FREE(rparam); - return True; + return true; } /**************************************************************************** @@ -131,7 +144,7 @@ mode_t wire_perms_to_unix(uint32 perms) /**************************************************************************** Return the file type from the wire filetype for UNIX extensions. ****************************************************************************/ - + static mode_t unix_filetype_from_wire(uint32 wire_type) { switch (wire_type) { @@ -173,15 +186,21 @@ bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, unsigned int param_len = 0; unsigned int data_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - char param[1024+6]; + char *param; + size_t nlen = 2*(strlen(name)+1); char *rparam=NULL, *rdata=NULL; char *p; + param = SMB_MALLOC(6+nlen+2); + if (!param) { + return false; + } + p = param; - memset(p, 0, 6); + memset(p, '\0', 6); SSVAL(p, 0, SMB_QUERY_POSIX_ACL); p += 6; - p += clistr_push(cli, p, name, sizeof(param)-6, STR_TERMINATE); + p += clistr_push(cli, p, name, nlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, @@ -191,26 +210,29 @@ bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, param, param_len, 2, /* param, length, max */ NULL, 0, cli->max_xmit /* data, length, max */ )) { - return False; + SAFE_FREE(param); + return false; } + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; + &rparam, ¶m_len, + &rdata, &data_len)) { + return false; } if (data_len < 6) { SAFE_FREE(rdata); SAFE_FREE(rparam); - return False; + return false; } SAFE_FREE(rparam); *retbuf = rdata; *prb_size = (size_t)data_len; - return True; + return true; } /**************************************************************************** @@ -222,39 +244,47 @@ bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu unsigned int param_len = 0; unsigned int data_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - char param[1024+6]; + char *param; + size_t nlen = 2*(strlen(name)+1); char *rparam=NULL, *rdata=NULL; char *p; ZERO_STRUCTP(sbuf); + param = SMB_MALLOC(6+nlen+2); + if (!param) { + return false; + } p = param; - memset(p, 0, 6); + memset(p, '\0', 6); SSVAL(p, 0, SMB_QUERY_FILE_UNIX_BASIC); p += 6; - p += clistr_push(cli, p, name, sizeof(param)-6, STR_TERMINATE); + p += clistr_push(cli, p, name, nlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, 0, cli->max_xmit /* data, length, max */ - )) { - return False; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, 0, cli->max_xmit /* data, length, max */ + )) { + SAFE_FREE(param); + return false; } + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; + &rparam, ¶m_len, + &rdata, &data_len)) { + return false; } if (data_len < 96) { SAFE_FREE(rdata); SAFE_FREE(rparam); - return False; + return false; } sbuf->st_size = IVAL2_TO_SMB_BIG_UINT(rdata,0); /* total size, in bytes */ @@ -286,7 +316,7 @@ bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu SAFE_FREE(rdata); SAFE_FREE(rparam); - return True; + return true; } /**************************************************************************** @@ -316,17 +346,23 @@ static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; - char param[1024+6]; + size_t nlen = 2*(strlen(fname)+1); + char *param; char data[100]; char *rparam=NULL, *rdata=NULL; char *p; - memset(param, 0, sizeof(param)); + param = SMB_MALLOC(6+nlen+2); + if (!param) { + return false; + } + memset(param, '\0', 6); memset(data, 0, sizeof(data)); + SSVAL(param,0,SMB_SET_FILE_UNIX_BASIC); p = ¶m[6]; - p += clistr_push(cli, p, fname, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); memset(data, 0xff, 40); /* Set all sizes/times to no change. */ @@ -338,25 +374,28 @@ static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna data_len = 100; if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + SAFE_FREE(param); + return False; } + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; + &rparam, ¶m_len, + &rdata, &data_len)) { + return false; } SAFE_FREE(rdata); SAFE_FREE(rparam); - return True; + return true; } /**************************************************************************** @@ -365,7 +404,7 @@ static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) { - return cli_unix_chmod_chown_internal(cli, fname, + return cli_unix_chmod_chown_internal(cli, fname, unix_perms_to_wire(mode), SMB_UID_NO_CHANGE, SMB_GID_NO_CHANGE); } @@ -375,7 +414,8 @@ bool cli_unix_chmod(struct cli_state *cli, const char *fname, mode_t mode) bool cli_unix_chown(struct cli_state *cli, const char *fname, uid_t uid, gid_t gid) { - return cli_unix_chmod_chown_internal(cli, fname, SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid); + return cli_unix_chmod_chown_internal(cli, fname, + SMB_MODE_NO_CHANGE, (uint32)uid, (uint32)gid); } /**************************************************************************** @@ -389,7 +429,7 @@ bool cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 0, True); + set_message(cli->outbuf,1, 0, true); SCVAL(cli->outbuf,smb_com,SMBmv); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -399,20 +439,24 @@ bool cli_rename(struct cli_state *cli, const char *fname_src, const char *fname_ p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_src, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); *p++ = 4; - p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_dst, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_receive_smb(cli)) { + return false; + } - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return false; + } - return True; + return true; } /**************************************************************************** @@ -426,7 +470,7 @@ bool cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 4, 0, True); + set_message(cli->outbuf, 4, 0, true); SCVAL(cli->outbuf,smb_com,SMBntrename); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -437,20 +481,24 @@ bool cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_src, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); *p++ = 4; - p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_dst, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_receive_smb(cli)) { + return false; + } - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return false; + } - return True; + return true; } /**************************************************************************** @@ -464,7 +512,7 @@ bool cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *f memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 4, 0, True); + set_message(cli->outbuf, 4, 0, true); SCVAL(cli->outbuf,smb_com,SMBntrename); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -475,20 +523,24 @@ bool cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *f p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname_src, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_src, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); *p++ = 4; - p += clistr_push(cli, p, fname_dst, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname_dst, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); - if (!cli_receive_smb(cli)) - return False; + if (!cli_receive_smb(cli)) { + return false; + } - if (cli_is_error(cli)) - return False; + if (cli_is_error(cli)) { + return false; + } - return True; + return true; } /**************************************************************************** @@ -502,29 +554,30 @@ bool cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 0,True); + set_message(cli->outbuf,1, 0, true); SCVAL(cli->outbuf,smb_com,SMBunlink); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0, attrs); - + p = smb_buf(cli->outbuf); - *p++ = 4; - p += clistr_push(cli, p, fname, -1, STR_TERMINATE); + *p++ = 4; + p += clistr_push(cli, p, fname, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { - return False; + return false; } if (cli_is_error(cli)) { - return False; + return false; } - return True; + return true; } /**************************************************************************** @@ -547,15 +600,16 @@ bool cli_mkdir(struct cli_state *cli, const char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 0,True); + set_message(cli->outbuf,0, 0, true); SCVAL(cli->outbuf,smb_com,SMBmkdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); - *p++ = 4; - p += clistr_push(cli, p, dname, -1, STR_TERMINATE); + *p++ = 4; + p += clistr_push(cli, p, dname, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); @@ -582,28 +636,29 @@ bool cli_rmdir(struct cli_state *cli, const char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 0, True); + set_message(cli->outbuf,0, 0, true); SCVAL(cli->outbuf,smb_com,SMBrmdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); p = smb_buf(cli->outbuf); - *p++ = 4; - p += clistr_push(cli, p, dname, -1, STR_TERMINATE); + *p++ = 4; + p += clistr_push(cli, p, dname, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { - return False; + return false; } if (cli_is_error(cli)) { - return False; + return false; } - return True; + return true; } /**************************************************************************** @@ -626,25 +681,25 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, bool flag) data = flag ? 1 : 0; if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + return false; } if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; + &rparam, ¶m_len, + &rdata, &data_len)) { + return false; } SAFE_FREE(rdata); SAFE_FREE(rparam); - return True; + return true; } /**************************************************************************** @@ -652,7 +707,7 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, bool flag) Used in smbtorture. ****************************************************************************/ -int cli_nt_create_full(struct cli_state *cli, const char *fname, +int cli_nt_create_full(struct cli_state *cli, const char *fname, uint32 CreatFlags, uint32 DesiredAccess, uint32 FileAttributes, uint32 ShareAccess, uint32 CreateDisposition, uint32 CreateOptions, @@ -664,7 +719,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,24,0,True); + set_message(cli->outbuf,24,0, true); SCVAL(cli->outbuf,smb_com,SMBntcreateX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -673,7 +728,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, SSVAL(cli->outbuf,smb_vwv0,0xFF); if (cli->use_oplocks) CreatFlags |= (REQUEST_OPLOCK|REQUEST_BATCH_OPLOCK); - + SIVAL(cli->outbuf,smb_ntcreate_Flags, CreatFlags); SIVAL(cli->outbuf,smb_ntcreate_RootDirectoryFid, 0x0); SIVAL(cli->outbuf,smb_ntcreate_DesiredAccess, DesiredAccess); @@ -687,11 +742,13 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ p += clistr_align_out(cli, p, 0); - len = clistr_push(cli, p, fname, -1, 0); + len = clistr_push(cli, p, fname, + cli->bufsize - PTR_DIFF(p,cli->outbuf), 0); p += len; SSVAL(cli->outbuf,smb_ntcreate_NameLength, len); /* sigh. this copes with broken netapp filer behaviour */ - p += clistr_push(cli, p, "", -1, STR_TERMINATE); + p += clistr_push(cli, p, "", + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); @@ -743,7 +800,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode accessmode |= 2; } else if ((flags & O_ACCMODE) == O_WRONLY) { accessmode |= 1; - } + } #if defined(O_SYNC) if ((flags & O_SYNC) == O_SYNC) { @@ -758,7 +815,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,15,0,True); + set_message(cli->outbuf,15,0, true); SCVAL(cli->outbuf,smb_com,SMBopenX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -778,9 +835,10 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK); SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); } - + p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, fname, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); @@ -824,12 +882,13 @@ bool cli_close(struct cli_state *cli, int fnum) /**************************************************************************** - send a lock with a specified locktype + send a lock with a specified locktype this is used for testing LOCKING_ANDX_CANCEL_LOCK ****************************************************************************/ -NTSTATUS cli_locktype(struct cli_state *cli, int fnum, - uint32 offset, uint32 len, int timeout, unsigned char locktype) +NTSTATUS cli_locktype(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, + int timeout, unsigned char locktype) { char *p; int saved_timeout = cli->timeout; @@ -880,7 +939,7 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, note that timeout is in units of 2 milliseconds ****************************************************************************/ -bool cli_lock(struct cli_state *cli, int fnum, +bool cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout, enum brl_type lock_type) { char *p; @@ -977,7 +1036,7 @@ bool cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) Lock a file with 64 bit offsets. ****************************************************************************/ -bool cli_lock64(struct cli_state *cli, int fnum, +bool cli_lock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len, int timeout, enum brl_type lock_type) { char *p; @@ -1084,7 +1143,7 @@ bool cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ Get/unlock a POSIX lock on a file - internal function. ****************************************************************************/ -static bool cli_posix_lock_internal(struct cli_state *cli, int fnum, +static bool cli_posix_lock_internal(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_UINT len, bool wait_lock, enum brl_type lock_type) { unsigned int param_len = 4; @@ -1124,12 +1183,12 @@ static bool cli_posix_lock_internal(struct cli_state *cli, int fnum, SOFF_T(data, POSIX_LOCK_LEN_OFFSET, len); if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { cli->timeout = saved_timeout; return False; } @@ -1187,8 +1246,8 @@ bool cli_posix_getlock(struct cli_state *cli, int fnum, SMB_BIG_UINT *poffset, S Do a SMBgetattrE call. ****************************************************************************/ -bool cli_getattrE(struct cli_state *cli, int fd, - uint16 *attr, SMB_OFF_T *size, +bool cli_getattrE(struct cli_state *cli, int fd, + uint16 *attr, SMB_OFF_T *size, time_t *change_time, time_t *access_time, time_t *write_time) @@ -1208,7 +1267,7 @@ bool cli_getattrE(struct cli_state *cli, int fd, if (!cli_receive_smb(cli)) { return False; } - + if (cli_is_error(cli)) { return False; } @@ -1240,7 +1299,7 @@ bool cli_getattrE(struct cli_state *cli, int fd, Do a SMBgetatr call ****************************************************************************/ -bool cli_getatr(struct cli_state *cli, const char *fname, +bool cli_getatr(struct cli_state *cli, const char *fname, uint16 *attr, SMB_OFF_T *size, time_t *write_time) { char *p; @@ -1256,7 +1315,8 @@ bool cli_getatr(struct cli_state *cli, const char *fname, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); @@ -1264,7 +1324,7 @@ bool cli_getatr(struct cli_state *cli, const char *fname, if (!cli_receive_smb(cli)) { return False; } - + if (cli_is_error(cli)) { return False; } @@ -1281,7 +1341,6 @@ bool cli_getatr(struct cli_state *cli, const char *fname, *attr = SVAL(cli->inbuf,smb_vwv0); } - return True; } @@ -1320,7 +1379,7 @@ bool cli_setattrE(struct cli_state *cli, int fd, if (!cli_receive_smb(cli)) { return False; } - + if (cli_is_error(cli)) { return False; } @@ -1350,7 +1409,8 @@ bool cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, fname, -1, STR_TERMINATE); + p += clistr_push(cli, p, fname, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); *p++ = 4; cli_setup_bcc(cli, p); @@ -1383,8 +1443,13 @@ bool cli_chkpath(struct cli_state *cli, const char *path) return false; } trim_char(path2,'\0','\\'); - if (!*path2) - *path2 = '\\'; + if (!*path2) { + path2 = talloc_strdup(frame, "\\"); + if (!path2) { + TALLOC_FREE(frame); + return false; + } + } memset(cli->outbuf,'\0',smb_size); set_message(cli->outbuf,0,0,True); @@ -1393,7 +1458,8 @@ bool cli_chkpath(struct cli_state *cli, const char *path) cli_setup_packet(cli); p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, path2, -1, STR_TERMINATE); + p += clistr_push(cli, p, path2, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); @@ -1430,7 +1496,7 @@ bool cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) *bsize = SVAL(cli->inbuf,smb_vwv1)*SVAL(cli->inbuf,smb_vwv2); *total = SVAL(cli->inbuf,smb_vwv0); *avail = SVAL(cli->inbuf,smb_vwv3); - + return True; } @@ -1457,7 +1523,8 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, path, -1, STR_TERMINATE); + p += clistr_push(cli, p, path, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); cli_setup_bcc(cli, p); @@ -1526,7 +1593,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * static bool cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigned int param_len, const char *ea_name, const char *ea_val, size_t ea_len) -{ +{ unsigned int data_len = 0; char *data = NULL; char *rparam=NULL, *rdata=NULL; @@ -1558,19 +1625,21 @@ static bool cli_set_ea(struct cli_state *cli, uint16 setup, char *param, unsigne } if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - data, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + data, data_len, cli->max_xmit /* data, length, max */ + )) { + SAFE_FREE(data); + return False; } if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; + &rparam, ¶m_len, + &rdata, &data_len)) { + SAFE_FREE(data); + return false; } SAFE_FREE(data); @@ -1588,18 +1657,25 @@ bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_nam { uint16 setup = TRANSACT2_SETPATHINFO; unsigned int param_len = 0; - char param[1024+6]; + char *param; size_t srclen = 2*(strlen(path)+1); char *p; + bool ret; - memset(param, 0, sizeof(param)); + param = SMB_MALLOC(6+srclen+2); + if (!param) { + return false; + } + memset(param, '\0', 6); SSVAL(param,0,SMB_INFO_SET_EA); p = ¶m[6]; - p += clistr_push(cli, p, path, MIN(srclen, sizeof(param)-6), STR_TERMINATE); + p += clistr_push(cli, p, path, srclen, STR_TERMINATE); param_len = PTR_DIFF(p, param); - return cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len); + ret = cli_set_ea(cli, setup, param, param_len, ea_name, ea_val, ea_len); + SAFE_FREE(param); + return ret; } /********************************************************* @@ -1754,17 +1830,25 @@ bool cli_get_ea_list_path(struct cli_state *cli, const char *path, { uint16 setup = TRANSACT2_QPATHINFO; unsigned int param_len = 0; - char param[1024+6]; + char *param; char *p; + size_t srclen = 2*(strlen(path)+1); + bool ret; + param = SMB_MALLOC(6+srclen+2); + if (!param) { + return false; + } p = param; memset(p, 0, 6); SSVAL(p, 0, SMB_INFO_QUERY_ALL_EAS); p += 6; - p += clistr_push(cli, p, path, sizeof(param)-6, STR_TERMINATE); + p += clistr_push(cli, p, path, srclen, STR_TERMINATE); param_len = PTR_DIFF(p, param); - return cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list); + ret = cli_get_ea_list(cli, setup, param, param_len, ctx, pnum_eas, pea_list); + SAFE_FREE(param); + return ret; } /********************************************************* @@ -1848,18 +1932,23 @@ static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; - char param[1024+6]; + char *param; char data[18]; char *rparam=NULL, *rdata=NULL; char *p; int fnum = -1; uint32 wire_flags = open_flags_to_wire(flags); + size_t srclen = 2*(strlen(fname)+1); - memset(param, 0, sizeof(param)); + param = SMB_MALLOC(6+srclen+2); + if (!param) { + return false; + } + memset(param, '\0', 6); SSVAL(param,0, SMB_POSIX_PATH_OPEN); p = ¶m[6]; - p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); + p += clistr_push(cli, p, fname, srclen, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (is_dir) { @@ -1877,15 +1966,18 @@ static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int data_len = 18; if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { - return -1; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + SAFE_FREE(param); + return -1; } + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { @@ -1927,16 +2019,21 @@ static bool cli_posix_unlink_internal(struct cli_state *cli, const char *fname, unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_SETPATHINFO; - char param[1024+6]; + char *param; char data[2]; char *rparam=NULL, *rdata=NULL; char *p; + size_t srclen = 2*(strlen(fname)+1); - memset(param, 0, sizeof(param)); + param = SMB_MALLOC(6+srclen+2); + if (!param) { + return false; + } + memset(param, '\0', 6); SSVAL(param,0, SMB_POSIX_PATH_UNLINK); p = ¶m[6]; - p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); + p += clistr_push(cli, p, fname, srclen, STR_TERMINATE); param_len = PTR_DIFF(p, param); SSVAL(data, 0, is_dir ? SMB_POSIX_UNLINK_DIRECTORY_TARGET : @@ -1944,15 +2041,18 @@ static bool cli_posix_unlink_internal(struct cli_state *cli, const char *fname, data_len = 2; if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - (char *)&data, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len, cli->max_xmit /* data, length, max */ + )) { + SAFE_FREE(param); + return False; } + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index d8d8f2608c..c10900cf43 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -451,29 +451,35 @@ bool cli_oem_change_password(struct cli_state *cli, const char *user, const char Send a qpathinfo call. ****************************************************************************/ -bool cli_qpathinfo(struct cli_state *cli, const char *fname, - time_t *change_time, - time_t *access_time, - time_t *write_time, - SMB_OFF_T *size, uint16 *mode) +bool cli_qpathinfo(struct cli_state *cli, + const char *fname, + time_t *change_time, + time_t *access_time, + time_t *write_time, + SMB_OFF_T *size, + uint16 *mode) { unsigned int data_len = 0; unsigned int param_len = 0; unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_QPATHINFO; - char param[1024]; + char *param; char *rparam=NULL, *rdata=NULL; int count=8; bool ret; time_t (*date_fn)(struct cli_state *, const void *); char *p; + size_t nlen = 2*(strlen(fname)+1); + param = SMB_MALLOC(6+nlen+2); + if (!param) { + return false; + } p = param; - memset(p, 0, 6); + memset(p, '\0', 6); SSVAL(p, 0, SMB_INFO_STANDARD); p += 6; - p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); - + p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); do { @@ -499,6 +505,7 @@ bool cli_qpathinfo(struct cli_state *cli, const char *fname, } } while (count-- && ret==False); + SAFE_FREE(param); if (!ret || !rdata || rdata_len < 22) { return False; } @@ -545,14 +552,19 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, unsigned int param_len = 0; unsigned int rparam_len, rdata_len; uint16 setup = TRANSACT2_SETPATHINFO; - char param[1024]; - char data[1024]; + char *param; + char data[40]; char *rparam=NULL, *rdata=NULL; int count=8; bool ret; char *p; + size_t nlen = 2*(strlen(fname)+1); - memset(param, 0, sizeof(param)); + param = SMB_MALLOC(6+nlen+2); + if (!param) { + return false; + } + memset(param, '\0', 6); memset(data, 0, sizeof(data)); p = param; @@ -564,7 +576,7 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, p += 6; /* Add the file name */ - p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); + p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); @@ -618,6 +630,7 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, } } while (count-- && ret==False); + SAFE_FREE(param); if (!ret) { return False; } @@ -642,15 +655,20 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - char param[1024]; + char *param; char *rparam=NULL, *rdata=NULL; char *p; + size_t nlen = 2*(strlen(fname)+1); + param = SMB_MALLOC(6+nlen+2); + if (!param) { + return false; + } p = param; - memset(p, 0, 6); + memset(param, '\0', 6); SSVAL(p, 0, SMB_QUERY_FILE_ALL_INFO); p += 6; - p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); + p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); @@ -661,9 +679,11 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, param, param_len, 10, /* param, length, max */ NULL, data_len, cli->max_xmit /* data, length, max */ )) { + SAFE_FREE(param); return False; } + SAFE_FREE(param); if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { @@ -826,11 +846,12 @@ bool cli_qpathinfo_basic( struct cli_state *cli, const char *name, unsigned int param_len = 0; unsigned int data_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - char param[1024+6]; + char *param; char *rparam=NULL, *rdata=NULL; char *p; char *path; int len; + size_t nlen; TALLOC_CTX *frame = talloc_stackframe(); path = talloc_strdup(frame, name); @@ -844,26 +865,34 @@ bool cli_qpathinfo_basic( struct cli_state *cli, const char *name, if ( path[len-1] == '\\' || path[len-1] == '/') { path[len-1] = '\0'; } + nlen = 2*(strlen(path)+1); + param = TALLOC_ARRAY(frame,char,6+nlen+2); + if (!param) { + return false; + } p = param; - memset(p, 0, 6); + memset(param, '\0', 6); + SSVAL(p, 0, SMB_QUERY_FILE_BASIC_INFO); p += 6; - p += clistr_push(cli, p, path, sizeof(param)-6, STR_TERMINATE); + p += clistr_push(cli, p, path, nlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); - TALLOC_FREE(frame); if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, 0, cli->max_xmit /* data, length, max */ - )) { - return False; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, 0, cli->max_xmit /* data, length, max */ + )) { + TALLOC_FREE(frame); + return False; } + TALLOC_FREE(frame); + if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { @@ -952,19 +981,23 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QPATHINFO; - char param[1024+6]; + char *param; char *rparam=NULL, *rdata=NULL; int count=8; char *p; bool ret; unsigned int len; + size_t nlen = 2*(strlen(fname)+1); + param = SMB_MALLOC(6+nlen+2); + if (!param) { + return NT_STATUS_NO_MEMORY; + } p = param; - memset(p, 0, 6); + memset(param, '\0', 6); SSVAL(p, 0, SMB_QUERY_FILE_ALT_NAME_INFO); p += 6; - p += clistr_push(cli, p, fname, sizeof(param)-6, STR_TERMINATE); - + p += clistr_push(cli, p, fname, nlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); do { @@ -989,6 +1022,8 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin } } while (count-- && ret==False); + SAFE_FREE(param); + if (!ret || !rdata || data_len < 4) { return NT_STATUS_UNSUCCESSFUL; } -- cgit From 8ab33fc33593d829258990b208c4636e3fe321e0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Dec 2007 16:56:19 -0800 Subject: Fix path length limits on cli_list (outgoing. Incoming will be fixed with pstring elimination). Jeremy. (This used to be commit cd43b93d405bf892d1d8941b2d1e64d7d53adf69) --- source3/libsmb/clilist.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 64cb3e8fe3..284538541a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -218,7 +218,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, char *rparam=NULL, *rdata=NULL; unsigned int param_len, data_len; uint16 setup; - char param[1024]; + char *param; const char *mnt; uint32 resume_key = 0; DATA_BLOB last_name_raw = data_blob(NULL, 0); @@ -232,12 +232,19 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } while (ff_eos == 0) { + size_t nlen = 2*(strlen(mask)+1); + loop_count++; if (loop_count > 200) { DEBUG(0,("Error: Looping in FIND_NEXT??\n")); break; } + param = SMB_MALLOC(12+nlen+last_name_raw.length+2); + if (!param) { + break; + } + if (First) { setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ @@ -246,8 +253,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; - p += clistr_push(cli, param+12, mask, sizeof(param)-12, - STR_TERMINATE); + p += clistr_push(cli, param+12, mask, + nlen, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -260,11 +267,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; - if (last_name_raw.length && (last_name_raw.length < (sizeof(param)-12))) { + if (last_name_raw.length) { memcpy(p, last_name_raw.data, last_name_raw.length); p += last_name_raw.length; } else { - p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); + p += clistr_push(cli, param+12, mask, + nlen, STR_TERMINATE); } } @@ -283,9 +291,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, cli->max_xmit /* data, length, max. */ #endif )) { + SAFE_FREE(param); break; } + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len) && -- cgit From 4acfce6b036ae1a0bf152a94bb5d6194e93f4004 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Dec 2007 10:10:16 -0800 Subject: Don't understand this. I have no changes here.... Jeremy. (This used to be commit 49534432d4c63d0dfd7bf080c30adecef06deade) --- source3/libsmb/clilist.c | 97 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 33 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 284538541a..fc47f94aa1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -19,8 +19,6 @@ #include "includes.h" -extern file_info def_finfo; - /**************************************************************************** Calculate a safe next_entry_offset. ****************************************************************************/ @@ -44,7 +42,8 @@ static size_t calc_next_entry_offset(const char *base, const char *pdata_end) by NT and 2 is used by OS/2 ****************************************************************************/ -static size_t interpret_long_filename(struct cli_state *cli, +static size_t interpret_long_filename(TALLOC_CTX *ctx, + struct cli_state *cli, int level, const char *p, const char *pdata_end, @@ -52,20 +51,16 @@ static size_t interpret_long_filename(struct cli_state *cli, uint32 *p_resume_key, DATA_BLOB *p_last_name_raw) { - file_info finfo2; int len; + size_t ret; const char *base = p; data_blob_free(p_last_name_raw); - if (!finfo) { - finfo = &finfo2; - } - if (p_resume_key) { *p_resume_key = 0; } - memcpy(finfo,&def_finfo,sizeof(*finfo)); + ZERO_STRUCTP(finfo); finfo->cli = cli; switch (level) { @@ -90,10 +85,16 @@ static size_t interpret_long_filename(struct cli_state *cli, important to cope with the differences between win2000 and win9x for this call (tridge) */ - p += clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - len+2, - STR_TERMINATE); + ret = clistr_pull_talloc(ctx, + cli, + &finfo->name, + p, + len+2, + STR_TERMINATE); + if (ret == (size_t)-1) { + return pdata_end - base; + } + p += ret; return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ @@ -113,10 +114,16 @@ static size_t interpret_long_filename(struct cli_state *cli, if (p + len + 1 > pdata_end) { return pdata_end - base; } - p += clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - len, - STR_NOALIGN); + ret = clistr_pull_talloc(ctx, + cli, + &finfo->name, + p, + len, + STR_NOALIGN); + if (ret == (size_t)-1) { + return pdata_end - base; + } + p += ret; return PTR_DIFF(p, base) + 1; case 260: /* NT uses this, but also accepts 2 */ @@ -168,9 +175,15 @@ static size_t interpret_long_filename(struct cli_state *cli, if (p + namelen < p || p + namelen > pdata_end) { return pdata_end - base; } - clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - namelen, 0); + ret = clistr_pull_talloc(ctx, + cli, + &finfo->name, + p, + namelen, + 0); + if (ret == (size_t)-1) { + return pdata_end - base; + } /* To be robust in the face of unicode conversion failures we need to copy the raw bytes of the last name seen here. @@ -221,6 +234,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, char *param; const char *mnt; uint32 resume_key = 0; + TALLOC_CTX *frame = talloc_stackframe(); DATA_BLOB last_name_raw = data_blob(NULL, 0); /* NT uses 260, OS/2 uses 2. Both accept 1. */ @@ -228,6 +242,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mask = SMB_STRDUP(Mask); if (!mask) { + TALLOC_FREE(frame); return -1; } @@ -292,6 +307,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, #endif )) { SAFE_FREE(param); + TALLOC_FREE(frame); break; } @@ -352,7 +368,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* Last entry - fixup the last offset length. */ SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); } - p2 += interpret_long_filename(cli, + p2 += interpret_long_filename(frame, + cli, info_level, p2, rdata_end, @@ -417,14 +434,15 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* no connection problem. let user function add each entry */ rdata_end = dirlist + dirlist_len; for (p=dirlist,i=0;icli = cli; finfo->mode = CVAL(p,21); @@ -454,16 +475,21 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec; finfo->mtime_ts.tv_nsec = finfo->atime_ts.tv_nsec = 0; finfo->size = IVAL(p,26); - clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); - if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { - strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1); - finfo->short_name[sizeof(finfo->short_name)-1] = '\0'; + clistr_pull_talloc(ctx, + cli, + &finfo->name, + p+30, + 12, + STR_ASCII); + if (!finfo->name) { + finfo->name = talloc_strdup(ctx, finfo->short_name); + } else if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { + finfo->name = talloc_strdup(ctx, finfo->short_name); } return(DIR_STRUCT_SIZE); } - /**************************************************************************** Do a directory listing, calling fn on each file found. this uses the old SMBsearch interface. It is needed for testing Samba, @@ -482,6 +508,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, int i; char *dirlist = NULL; char *mask = NULL; + TALLOC_CTX *frame = NULL; ZERO_ARRAY(status); @@ -507,7 +534,9 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE); + p += clistr_push(cli, p, first?mask:"", + cli->bufsize - PTR_DIFF(p,cli->outbuf), + STR_TERMINATE); *p++ = 5; if (first) { SSVAL(p,0,0); @@ -577,11 +606,13 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, } } + frame = talloc_stackframe(); for (p=dirlist,i=0;i Date: Thu, 6 Dec 2007 17:16:33 -0800 Subject: Remove pstrings from client/client.c by doing a large rewrite. Mostly compiles.... Jeremy. (This used to be commit c87f3eba9aa52f4ab25d77e2167262bf5c43b1a6) --- source3/libsmb/clidfs.c | 60 ++++++++++++++++++------------------------- source3/libsmb/clifsinfo.c | 62 ++++++++++++++++++++++----------------------- source3/libsmb/climessage.c | 46 +++++++++++++++++++-------------- source3/libsmb/clistr.c | 43 +++++++++++++++++++++++++------ 4 files changed, 117 insertions(+), 94 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 32a2c31c83..4cf37a250b 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -266,7 +266,8 @@ const char *cli_cm_get_mntpoint(struct cli_state *c) ********************************************************************/ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, - const char *server, + struct cli_state *referring_cli, + const char *server, const char *share, bool show_hdr) { @@ -289,8 +290,17 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, cli_cm_set_mntpoint(node->cli, ""); - return node->cli; + if (referring_cli && referring_cli->posix_capabilities) { + uint16 major, minor; + uint32 caplow, caphigh; + if (cli_unix_extensions_version(cli, &major, + &minor, &caplow, &caphigh)) { + cli_set_unix_extensions_capabilities(cli, major, minor, + caplow, caphigh); + } + } + return node->cli; } /******************************************************************** @@ -317,6 +327,7 @@ static struct cli_state *cli_cm_find(const char *server, const char *share) ****************************************************************************/ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, + struct cli_state *referring_cli, const char *server, const char *share, bool show_hdr) @@ -327,7 +338,7 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, c = cli_cm_find(server, share); if (!c) { - c = cli_cm_connect(ctx, server, share, show_hdr); + c = cli_cm_connect(ctx, referring_cli, server, share, show_hdr); } return c; @@ -378,17 +389,17 @@ static void cm_set_password(const char *newpass) } } -void cli_cm_set_credentials(struct user_auth_info *user) +void cli_cm_set_credentials(void) { SAFE_FREE(cm_creds.username); - cm_creds.username = SMB_STRDUP(user->username); + cm_creds.username = SMB_STRDUP(get_cmdline_auth_info_username()); - if (user->got_pass) { - cm_set_password(user->password); + if (get_cmdline_auth_info_got_pass()) { + cm_set_password(get_cmdline_auth_info_password()); } - cm_creds.use_kerberos = user->use_kerberos; - cm_creds.signing_state = user->signing_state; + cm_creds.use_kerberos = get_cmdline_auth_info_use_kerberos(); + cm_creds.signing_state = get_cmdline_auth_info_signing_state(); } /**************************************************************************** @@ -729,7 +740,8 @@ bool cli_resolve_path(TALLOC_CTX *ctx, /* Check for the referral. */ - if (!(cli_ipc = cli_cm_open(ctx, rootcli->desthost, "IPC$", false))) { + if (!(cli_ipc = cli_cm_open(ctx, rootcli, + rootcli->desthost, "IPC$", false))) { return false; } @@ -768,7 +780,8 @@ bool cli_resolve_path(TALLOC_CTX *ctx, */ /* Open the connection to the target server & share */ - if ((*targetcli = cli_cm_open(ctx, server, share, false)) == NULL) { + if ((*targetcli = cli_cm_open(ctx, rootcli, + server, share, false)) == NULL) { d_printf("Unable to follow dfs referral [\\%s\\%s]\n", server, share ); return false; @@ -852,31 +865,6 @@ bool cli_resolve_path(TALLOC_CTX *ctx, return true; } -/******************************************************************** - Temporary hack - remove when pstring is dead. JRA. -********************************************************************/ - -bool cli_resolve_path_pstring( const char *mountpt, - struct cli_state *rootcli, - const char *path, - struct cli_state **targetcli, - pstring targetpath) -{ - char *tpath = NULL; - TALLOC_CTX *ctx = talloc_stackframe(); - bool ret = cli_resolve_path(ctx, - mountpt, - rootcli, - path, - targetcli, - &tpath); - if (tpath) { - pstrcpy(targetpath, tpath); - } - TALLOC_FREE(ctx); - return ret; -} - /******************************************************************** ********************************************************************/ diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index a45623b9e4..1a75d144b2 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -22,7 +22,7 @@ /**************************************************************************** Get UNIX extensions version info. ****************************************************************************/ - + bool cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 *pminor, uint32 *pcaplow, uint32 *pcaphigh) { @@ -33,18 +33,18 @@ bool cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 * unsigned int rparam_count=0, rdata_count=0; setup = TRANSACT2_QFSINFO; - + SSVAL(param,0,SMB_QUERY_CIFS_UNIX_INFO); - if (!cli_send_trans(cli, SMBtrans2, - NULL, + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, 0, &setup, 1, 0, param, 2, 0, NULL, 0, 560)) { goto cleanup; } - + if (!cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_count, &rdata, &rdata_count)) { @@ -67,7 +67,7 @@ bool cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor, uint16 * cli->posix_capabilities = *pcaplow = IVAL(rdata,4); *pcaphigh = IVAL(rdata,8); - /* todo: but not yet needed + /* todo: but not yet needed * return the other stuff */ @@ -75,13 +75,13 @@ cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); - return ret; + return ret; } /**************************************************************************** Set UNIX extensions capabilities. ****************************************************************************/ - + bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, uint16 minor, uint32 caplow, uint32 caphigh) { @@ -93,7 +93,7 @@ bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, u unsigned int rparam_count=0, rdata_count=0; setup = TRANSACT2_SETFSINFO; - + SSVAL(param,0,0); SSVAL(param,2,SMB_SET_CIFS_UNIX_INFO); @@ -102,15 +102,15 @@ bool cli_set_unix_extensions_capabilities(struct cli_state *cli, uint16 major, u SIVAL(data,4,caplow); SIVAL(data,8,caphigh); - if (!cli_send_trans(cli, SMBtrans2, - NULL, + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, 0, &setup, 1, 0, param, 4, 0, data, 12, 560)) { goto cleanup; } - + if (!cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_count, &rdata, &rdata_count)) { @@ -128,7 +128,7 @@ cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); - return ret; + return ret; } bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) @@ -143,18 +143,18 @@ bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) smb_panic("cli_get_fs_attr_info() called with NULL Pionter!"); setup = TRANSACT2_QFSINFO; - + SSVAL(param,0,SMB_QUERY_FS_ATTRIBUTE_INFO); - if (!cli_send_trans(cli, SMBtrans2, - NULL, + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, 0, &setup, 1, 0, param, 2, 0, NULL, 0, 560)) { goto cleanup; } - + if (!cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_count, &rdata, &rdata_count)) { @@ -174,7 +174,7 @@ bool cli_get_fs_attr_info(struct cli_state *cli, uint32 *fs_attr) *fs_attr = IVAL(rdata,0); - /* todo: but not yet needed + /* todo: but not yet needed * return the other stuff */ @@ -182,7 +182,7 @@ cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); - return ret; + return ret; } bool cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint32 *pserial_number) @@ -195,18 +195,18 @@ bool cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint unsigned char nlen; setup = TRANSACT2_QFSINFO; - + SSVAL(param,0,SMB_INFO_VOLUME); - if (!cli_send_trans(cli, SMBtrans2, - NULL, + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, 0, &setup, 1, 0, param, 2, 0, NULL, 0, 560)) { goto cleanup; } - + if (!cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_count, &rdata, &rdata_count)) { @@ -230,7 +230,7 @@ bool cli_get_fs_volume_info_old(struct cli_state *cli, fstring volume_name, uint nlen = CVAL(rdata,l2_vol_cch); clistr_pull(cli, volume_name, rdata + l2_vol_szVolLabel, sizeof(fstring), nlen, STR_NOALIGN); - /* todo: but not yet needed + /* todo: but not yet needed * return the other stuff */ @@ -238,7 +238,7 @@ cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); - return ret; + return ret; } bool cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 *pserial_number, time_t *pdate) @@ -251,18 +251,18 @@ bool cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 * unsigned int nlen; setup = TRANSACT2_QFSINFO; - + SSVAL(param,0,SMB_QUERY_FS_VOLUME_INFO); - if (!cli_send_trans(cli, SMBtrans2, - NULL, + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, 0, &setup, 1, 0, param, 2, 0, NULL, 0, 560)) { goto cleanup; } - + if (!cli_receive_trans(cli, SMBtrans2, &rparam, &rparam_count, &rdata, &rdata_count)) { @@ -291,7 +291,7 @@ bool cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name, uint32 * nlen = IVAL(rdata,12); clistr_pull(cli, volume_name, rdata + 18, sizeof(fstring), nlen, STR_UNICODE); - /* todo: but not yet needed + /* todo: but not yet needed * return the other stuff */ @@ -299,5 +299,5 @@ cleanup: SAFE_FREE(rparam); SAFE_FREE(rdata); - return ret; + return ret; } diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 2a195753ae..13ef1d43d4 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -19,11 +19,11 @@ #include "includes.h" - /**************************************************************************** -start a message sequence + Start a message sequence. ****************************************************************************/ -int cli_message_start_build(struct cli_state *cli, char *host, char *username) + +int cli_message_start_build(struct cli_state *cli, const char *host, const char *username) { char *p; @@ -33,25 +33,26 @@ int cli_message_start_build(struct cli_state *cli, char *host, char *username) SCVAL(cli->outbuf,smb_com,SMBsendstrt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); - + p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, username, -1, STR_ASCII|STR_TERMINATE); + p += clistr_push(cli, p, username, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_ASCII|STR_TERMINATE); *p++ = 4; - p += clistr_push(cli, p, host, -1, STR_ASCII|STR_TERMINATE); - + p += clistr_push(cli, p, host, + cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_ASCII|STR_TERMINATE); + cli_setup_bcc(cli, p); return(PTR_DIFF(p, cli->outbuf)); } -bool cli_message_start(struct cli_state *cli, char *host, char *username, +bool cli_message_start(struct cli_state *cli, const char *host, const char *username, int *grp) { cli_message_start_build(cli, host, username); - - cli_send_smb(cli); - + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { return False; } @@ -63,11 +64,11 @@ bool cli_message_start(struct cli_state *cli, char *host, char *username, return True; } - /**************************************************************************** -send a message + Send a message ****************************************************************************/ -int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) + +int cli_message_text_build(struct cli_state *cli, const char *msg, int len, int grp) { char *msgdos; int lendos; @@ -80,17 +81,23 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,grp); - + p = smb_buf(cli->outbuf); *p++ = 1; if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **)(void *)&msgdos, True)) < 0 || !msgdos) { DEBUG(3,("Conversion failed, sending message in UNIX charset\n")); SSVAL(p, 0, len); p += 2; + if (len > cli->bufsize - PTR_DIFF(p,cli->outbuf)) { + return -1; + } memcpy(p, msg, len); p += len; } else { SSVAL(p, 0, lendos); p += 2; + if (lendos > cli->bufsize - PTR_DIFF(p,cli->outbuf)) { + return -1; + } memcpy(p, msgdos, lendos); p += lendos; SAFE_FREE(msgdos); @@ -101,7 +108,7 @@ int cli_message_text_build(struct cli_state *cli, char *msg, int len, int grp) return(PTR_DIFF(p, cli->outbuf)); } -bool cli_message_text(struct cli_state *cli, char *msg, int len, int grp) +bool cli_message_text(struct cli_state *cli, const char *msg, int len, int grp) { cli_message_text_build(cli, msg, len, grp); @@ -114,11 +121,12 @@ bool cli_message_text(struct cli_state *cli, char *msg, int len, int grp) if (cli_is_error(cli)) return False; return True; -} +} /**************************************************************************** -end a message + End a message. ****************************************************************************/ + int cli_message_end_build(struct cli_state *cli, int grp) { char *p; @@ -150,4 +158,4 @@ bool cli_message_end(struct cli_state *cli, int grp) if (cli_is_error(cli)) return False; return True; -} +} diff --git a/source3/libsmb/clistr.c b/source3/libsmb/clistr.c index 39315729c4..5d20d632aa 100644 --- a/source3/libsmb/clistr.c +++ b/source3/libsmb/clistr.c @@ -20,9 +20,13 @@ #include "includes.h" -size_t clistr_push_fn(const char *function, unsigned int line, - struct cli_state *cli, void *dest, - const char *src, int dest_len, int flags) +size_t clistr_push_fn(const char *function, + unsigned int line, + struct cli_state *cli, + void *dest, + const char *src, + int dest_len, + int flags) { size_t buf_used = PTR_DIFF(dest, cli->outbuf); if (dest_len == -1) { @@ -38,23 +42,46 @@ size_t clistr_push_fn(const char *function, unsigned int line, dest, src, cli->bufsize - buf_used, flags); } - + /* 'normal' push into size-specified buffer */ return push_string_fn(function, line, cli->outbuf, SVAL(cli->outbuf, smb_flg2), dest, src, dest_len, flags); } -size_t clistr_pull_fn(const char *function, unsigned int line, - struct cli_state *cli, char *dest, const void *src, - int dest_len, int src_len, - int flags) +size_t clistr_pull_fn(const char *function, + unsigned int line, + struct cli_state *cli, + char *dest, + const void *src, + int dest_len, + int src_len, + int flags) { return pull_string_fn(function, line, cli->inbuf, SVAL(cli->inbuf, smb_flg2), dest, src, dest_len, src_len, flags); } +size_t clistr_pull_talloc_fn(const char *function, + unsigned int line, + TALLOC_CTX *ctx, + struct cli_state *cli, + char **pp_dest, + const void *src, + int src_len, + int flags) +{ + return pull_string_talloc_fn(function, + line, + ctx, + cli->inbuf, + SVAL(cli->inbuf, smb_flg2), + pp_dest, + src, + src_len, + flags); +} size_t clistr_align_out(struct cli_state *cli, const void *p, int flags) { -- cgit From 364b00295fca9dbf9c2be854b198b5e2bdc88ae1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Dec 2007 17:17:03 -0800 Subject: Fix clidfs.c compile. Jeremy. (This used to be commit 76034d1529a594837725cf599d97019eed7226b4) --- source3/libsmb/clidfs.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 4cf37a250b..ef3d0e8db3 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -293,9 +293,10 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, if (referring_cli && referring_cli->posix_capabilities) { uint16 major, minor; uint32 caplow, caphigh; - if (cli_unix_extensions_version(cli, &major, + if (cli_unix_extensions_version(node->cli, &major, &minor, &caplow, &caphigh)) { - cli_set_unix_extensions_capabilities(cli, major, minor, + cli_set_unix_extensions_capabilities(node->cli, + major, minor, caplow, caphigh); } } -- cgit From d3b4b69a270efd85728ac77fe23a0fb39d9dce10 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 7 Dec 2007 16:19:34 +0100 Subject: Add NT_STATUS_DOWNGRADE_DETECTED (thanks to Magnus Mertens). Guenther (This used to be commit 970daaa0a620d8e47475909cd7b5e54869602530) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index cf443f2339..608fe9db20 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -534,6 +534,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, { "NT_STATUS_DS_NO_MORE_RIDS", NT_STATUS_DS_NO_MORE_RIDS }, { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT }, + { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, { "NT_STATUS_NO_MORE_ENTRIES", NT_STATUS_NO_MORE_ENTRIES }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, -- cgit From 9e8180b9835fc100c25ef230747f7b44ef03d685 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Dec 2007 12:02:44 -0800 Subject: Remove pstrings completely except for smbctool (what does this do ?). Don't build this for now. Jeremy. (This used to be commit 46b67fd82c795d1a34a1efca9e409c0f3fa4f3a2) --- source3/libsmb/clidfs.c | 110 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 73 insertions(+), 37 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index ef3d0e8db3..5f95487d3f 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -570,7 +570,8 @@ static bool cli_dfs_check_error( struct cli_state *cli, NTSTATUS status ) Get the dfs referral link. ********************************************************************/ -bool cli_dfs_get_referral(struct cli_state *cli, +bool cli_dfs_get_referral(TALLOC_CTX *ctx, + struct cli_state *cli, const char *path, CLIENT_DFS_REFERRAL**refs, size_t *num_refs, @@ -579,83 +580,116 @@ bool cli_dfs_get_referral(struct cli_state *cli, unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_GET_DFS_REFERRAL; - char param[1024+2]; + char *param; char *rparam=NULL, *rdata=NULL; char *p; + char *endp; size_t pathlen = 2*(strlen(path)+1); uint16 num_referrals; CLIENT_DFS_REFERRAL *referrals = NULL; + bool ret = false; - memset(param, 0, sizeof(param)); + *num_refs = 0; + *refs = NULL; + + param = SMB_MALLOC(2+pathlen+2); + if (!param) { + return false; + } SSVAL(param, 0, 0x03); /* max referral level */ p = ¶m[2]; - p += clistr_push(cli, p, path, MIN(pathlen, sizeof(param)-2), - STR_TERMINATE); + p += clistr_push(cli, p, path, pathlen, STR_TERMINATE); param_len = PTR_DIFF(p, param); if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, 0, cli->max_xmit /* data, length, max */ - )) { - return false; + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, 0, cli->max_xmit /* data, length, max */ + )) { + SAFE_FREE(param); + return false; } + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len)) { return false; } - *consumed = SVAL( rdata, 0 ); - num_referrals = SVAL( rdata, 2 ); + if (data_len < 4) { + goto out; + } - if ( num_referrals != 0 ) { + endp = rdata + data_len; + + *consumed = SVAL(rdata, 0); + num_referrals = SVAL(rdata, 2); + + if (num_referrals != 0) { uint16 ref_version; uint16 ref_size; int i; uint16 node_offset; - referrals = SMB_XMALLOC_ARRAY( CLIENT_DFS_REFERRAL, + referrals = TALLOC_ARRAY(ctx, CLIENT_DFS_REFERRAL, num_referrals); + if (!referrals) { + goto out; + } /* start at the referrals array */ p = rdata+8; - for ( i=0; i endp) { + goto out; + } + ref_version = SVAL(p, 0); + ref_size = SVAL(p, 2); + node_offset = SVAL(p, 16); - if ( ref_version != 3 ) { + if (ref_version != 3) { p += ref_size; continue; } - referrals[i].proximity = SVAL( p, 8 ); - referrals[i].ttl = SVAL( p, 10 ); + referrals[i].proximity = SVAL(p, 8); + referrals[i].ttl = SVAL(p, 10); - clistr_pull( cli, referrals[i].dfspath, p+node_offset, - sizeof(referrals[i].dfspath), -1, + if (p + node_offset > endp) { + goto out; + } + clistr_pull_talloc(ctx, cli, &referrals[i].dfspath, + p+node_offset, STR_TERMINATE|STR_UNICODE ); + if (!referrals[i].dfspath) { + goto out; + } p += ref_size; } + if (i < num_referrals) { + goto out; + } } + ret = true; + *num_refs = num_referrals; *refs = referrals; + out: + SAFE_FREE(rdata); SAFE_FREE(rparam); - - return true; + return ret; } - /******************************************************************** ********************************************************************/ @@ -667,7 +701,7 @@ bool cli_resolve_path(TALLOC_CTX *ctx, char **pp_targetpath) { CLIENT_DFS_REFERRAL *refs = NULL; - size_t num_refs; + size_t num_refs = 0; uint16 consumed; struct cli_state *cli_ipc = NULL; char *dfs_path = NULL; @@ -746,15 +780,17 @@ bool cli_resolve_path(TALLOC_CTX *ctx, return false; } - if (!cli_dfs_get_referral(cli_ipc, dfs_path, &refs, + if (!cli_dfs_get_referral(ctx, cli_ipc, dfs_path, &refs, &num_refs, &consumed) || !num_refs) { return false; } /* Just store the first referral for now. */ + if (!refs[0].dfspath) { + return false; + } split_dfs_path(ctx, refs[0].dfspath, &server, &share, &extrapath ); - SAFE_FREE(refs); if (!server || !share) { return false; @@ -876,7 +912,7 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, char **pp_newshare ) { CLIENT_DFS_REFERRAL *refs = NULL; - size_t num_refs; + size_t num_refs = 0; uint16 consumed; char *fullpath = NULL; bool res; @@ -908,25 +944,25 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, return false; } - res = cli_dfs_get_referral(cli, fullpath, &refs, &num_refs, &consumed); + res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed); if (!cli_tdis(cli)) { - SAFE_FREE(refs); return false; } cli->cnum = cnum; if (!res || !num_refs) { - SAFE_FREE(refs); + return false; + } + + if (!refs[0].dfspath) { return false; } split_dfs_path(ctx, refs[0].dfspath, pp_newserver, pp_newshare, &newextrapath ); - SAFE_FREE(refs); - if (!pp_newserver || !pp_newshare) { return false; } -- cgit From 590da03ba342ea51561822512322d846bc4faade Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Dec 2007 12:08:55 -0800 Subject: Fix call to clistr_pull_talloc. Jeremy. (This used to be commit 86700b7e2e79e634b41c272632e42b2e64f58ba3) --- source3/libsmb/clidfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 5f95487d3f..f124821e62 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -665,7 +665,7 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx, goto out; } clistr_pull_talloc(ctx, cli, &referrals[i].dfspath, - p+node_offset, + p+node_offset, -1, STR_TERMINATE|STR_UNICODE ); if (!referrals[i].dfspath) { -- cgit From acf15ae730c95443681404c76b67ccfca0253d8b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Dec 2007 12:26:32 -0800 Subject: Don't build rpctorture anymore - not maintained. Just remove. Remove all vestiges of pstring (except for smbctool as noted in previous commit). Jeremy (This used to be commit 4c32a22ac50ada3275d2ffba3c1aa08bee7d1549) --- source3/libsmb/cliconnect.c | 10 ++++++---- source3/libsmb/libsmbclient.c | 19 ++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 14140811d2..fdf7491d80 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1776,13 +1776,15 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, struct cli_state *get_ipc_connect(char *server, struct sockaddr_storage *server_ss, - struct user_auth_info *user_info) + const struct user_auth_info *user_info) { struct cli_state *cli; NTSTATUS nt_status; nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", - user_info->username, lp_workgroup(), user_info->password, + user_info->username ? user_info->username : "", + lp_workgroup(), + user_info->password ? user_info->password : "", CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { @@ -1814,7 +1816,7 @@ struct cli_state *get_ipc_connect(char *server, struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, struct ip_service *mb_ip, - struct user_auth_info *user_info, + const struct user_auth_info *user_info, char **pp_workgroup_out) { char addr[INET6_ADDRSTRLEN]; @@ -1868,7 +1870,7 @@ struct cli_state *get_ipc_connect_master_ip(TALLOC_CTX *ctx, */ struct cli_state *get_ipc_connect_master_ip_bcast(TALLOC_CTX *ctx, - struct user_auth_info *user_info, + const struct user_auth_info *user_info, char **pp_workgroup_out) { struct ip_service *ip_list; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index b654ea07f0..de2eaa7cfa 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2794,8 +2794,17 @@ smbc_opendir_ctx(SMBCCTX *context, ? INT_MAX : context->options.browse_max_lmb_count); - pstrcpy(u_info.username, user); - pstrcpy(u_info.password, password); + memset(&u_info, '\0', sizeof(u_info)); + u_info.username = talloc_strdup(frame,user); + u_info.password = talloc_strdup(frame,password); + if (!u_info.username || !u_info.password) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } /* * We have server and share and path empty but options @@ -2912,7 +2921,7 @@ smbc_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } /* @@ -3181,19 +3190,15 @@ smbc_closedir_ctx(SMBCCTX *context, if (!context || !context->internal || !context->internal->_initialized) { - errno = EINVAL; TALLOC_FREE(frame); return -1; - } if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - errno = EBADF; TALLOC_FREE(frame); return -1; - } smbc_remove_dir(dir); /* Clean it up */ -- cgit From 42cfffae80480eae4381902fff3f7c61f858a933 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 7 Dec 2007 17:32:32 -0800 Subject: Remove next_token - all uses must now be next_token_talloc. No more temptations to use static length strings. Jeremy. (This used to be commit ec003f39369910dee852b7cafb883ddaa321c2de) --- source3/libsmb/clikrb5.c | 17 +++++++------ source3/libsmb/libsmbclient.c | 55 ++++++++++++++++++++++++++++--------------- source3/libsmb/namequery.c | 30 +++++++++++++---------- 3 files changed, 61 insertions(+), 41 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index d996d61a48..549574caad 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1592,6 +1592,7 @@ done: krb5_error_code ret = 0; TALLOC_CTX *mem_ctx; char keytab_string[MAX_KEYTAB_NAME_LEN]; + char *kt_str = NULL; bool found_valid_name = False; const char *pragma = "FILE"; const char *tmp = NULL; @@ -1654,29 +1655,27 @@ done: ret = ENOMEM; goto out; } - + if (strncmp(tmp, "ANY:", 4) == 0) { tmp += 4; } memset(&keytab_string, '\0', sizeof(keytab_string)); - while (next_token(&tmp, keytab_string, ",", sizeof(keytab_string))) { - - if (strncmp(keytab_string, "WRFILE:", 7) == 0) { + while (next_token_talloc(mem_ctx, &tmp, &kt_str, ",")) { + if (strncmp(kt_str, "WRFILE:", 7) == 0) { found_valid_name = True; - tmp = keytab_string; + tmp = kt_str; tmp += 7; } - if (strncmp(keytab_string, "FILE:", 5) == 0) { + if (strncmp(kt_str, "FILE:", 5) == 0) { found_valid_name = True; - tmp = keytab_string; + tmp = kt_str; tmp += 5; } if (found_valid_name) { - if (tmp[0] != '/') { ret = KRB5_KT_BADNAME; goto out; @@ -1690,7 +1689,7 @@ done: break; } } - + if (!found_valid_name) { ret = KRB5_KT_UNKNOWN_TYPE; goto out; diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index de2eaa7cfa..9f5567576f 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4219,7 +4219,7 @@ parse_ace(struct cli_state *ipc_cli, { char *p; const char *cp; - fstring tok; + char *tok; unsigned int atype; unsigned int aflags; unsigned int amask; @@ -4230,6 +4230,7 @@ parse_ace(struct cli_state *ipc_cli, const char *perm; uint32 mask; }; + TALLOC_CTX *frame = talloc_stackframe(); /* These values discovered by inspection */ static const struct perm_value special_values[] = { @@ -4252,7 +4253,10 @@ parse_ace(struct cli_state *ipc_cli, ZERO_STRUCTP(ace); p = strchr_m(str,':'); - if (!p) return False; + if (!p) { + TALLOC_FREE(frame); + return False; + } *p = '\0'; p++; /* Try to parse numeric form */ @@ -4265,12 +4269,14 @@ parse_ace(struct cli_state *ipc_cli, /* Try to parse text form */ if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { - return False; + TALLOC_FREE(frame); + return false; } cp = p; - if (!next_token(&cp, tok, "/", sizeof(fstring))) { - return False; + if (!next_token_talloc(frame, &cp, &tok, "/")) { + TALLOC_FREE(frame); + return false; } if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { @@ -4278,23 +4284,27 @@ parse_ace(struct cli_state *ipc_cli, } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { atype = SEC_ACE_TYPE_ACCESS_DENIED; } else { - return False; + TALLOC_FREE(frame); + return false; } /* Only numeric form accepted for flags at present */ - if (!(next_token(&cp, tok, "/", sizeof(fstring)) && + if (!(next_token_talloc(frame, &cp, &tok, "/") && sscanf(tok, "%i", &aflags))) { - return False; + TALLOC_FREE(frame); + return false; } - if (!next_token(&cp, tok, "/", sizeof(fstring))) { - return False; + if (!next_token_talloc(frame, &cp, &tok, "/")) { + TALLOC_FREE(frame); + return false; } if (strncmp(tok, "0x", 2) == 0) { if (sscanf(tok, "%i", &amask) != 1) { - return False; + TALLOC_FREE(frame); + return false; } goto done; } @@ -4318,18 +4328,23 @@ parse_ace(struct cli_state *ipc_cli, } } - if (!found) return False; + if (!found) { + TALLOC_FREE(frame); + return false; + } p++; } if (*p) { - return False; + TALLOC_FREE(frame); + return false; } done: mask = amask; init_sec_ace(ace, &sid, atype, mask, aflags); - return True; + TALLOC_FREE(frame); + return true; } /* add an ACE to a list of ACEs in a SEC_ACL */ @@ -4368,7 +4383,7 @@ sec_desc_parse(TALLOC_CTX *ctx, char *str) { const char *p = str; - fstring tok; + char *tok; SEC_DESC *ret = NULL; size_t sd_size; DOM_SID *group_sid=NULL; @@ -4376,7 +4391,7 @@ sec_desc_parse(TALLOC_CTX *ctx, SEC_ACL *dacl=NULL; int revision=1; - while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) { + while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { revision = strtol(tok+9, NULL, 16); @@ -4544,7 +4559,8 @@ dos_attr_parse(SMBCCTX *context, { int n; const char *p = str; - fstring tok; + char *tok = NULL; + TALLOC_CTX *frame = NULL; struct { const char * create_time_attr; const char * access_time_attr; @@ -4577,8 +4593,8 @@ dos_attr_parse(SMBCCTX *context, } } - while (next_token(&p, tok, "\t,\r\n", sizeof(tok))) { - + frame = talloc_stackframe(); + while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { if (StrnCaseCmp(tok, "MODE:", 5) == 0) { dad->mode = strtol(tok+5, NULL, 16); continue; @@ -4622,6 +4638,7 @@ dos_attr_parse(SMBCCTX *context, continue; } } + TALLOC_FREE(frame); } /***************************************************** diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 04db3322ca..9650b5fc45 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -791,10 +791,10 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, *pp_name = NULL; while(!x_feof(fp) && !x_ferror(fp)) { - char ip[INET6_ADDRSTRLEN]; - fstring flags; - fstring extra; - fstring name; + char *ip; + char *flags; + char *extra; + char *name; const char *ptr; char *ptr1; int count = 0; @@ -815,13 +815,13 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, ptr = line; - if (next_token(&ptr,ip ,NULL,sizeof(ip))) + if (next_token_talloc(ctx, &ptr, &ip, NULL)) ++count; - if (next_token(&ptr,name ,NULL, sizeof(name))) + if (next_token_talloc(ctx, &ptr, &name, NULL)) ++count; - if (next_token(&ptr,flags,NULL, sizeof(flags))) + if (next_token_talloc(ctx, &ptr, &flags, NULL)) ++count; - if (next_token(&ptr,extra,NULL, sizeof(extra))) + if (next_token_talloc(ctx, &ptr, &extra, NULL)) ++count; if (count <= 0) @@ -1422,10 +1422,11 @@ NTSTATUS internal_resolve_name(const char *name, const char *resolve_order) { const char *name_resolve_list; - fstring tok; + char *tok; const char *ptr; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; int i; + TALLOC_CTX *frame = NULL; *return_iplist = NULL; *return_count = 0; @@ -1488,7 +1489,8 @@ NTSTATUS internal_resolve_name(const char *name, /* iterate through the name resolution backends */ - while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) { + frame = talloc_stackframe(); + while (next_token_talloc(frame, &ptr, &tok, LIST_SEP)) { if((strequal(tok, "host") || strequal(tok, "hosts"))) { status = resolve_hosts(name, name_type, return_iplist, return_count); @@ -1545,6 +1547,7 @@ NTSTATUS internal_resolve_name(const char *name, /* All of the resolve_* functions above have returned false. */ + TALLOC_FREE(frame); SAFE_FREE(*return_iplist); *return_count = 0; @@ -1595,6 +1598,7 @@ NTSTATUS internal_resolve_name(const char *name, DEBUG(10, ("\n")); } + TALLOC_FREE(frame); return status; } @@ -1738,7 +1742,7 @@ static NTSTATUS get_dc_list(const char *domain, const char *p; char *port_str = NULL; int port; - fstring name; + char *name; int num_addresses = 0; int local_count, i, j; struct ip_service *return_iplist = NULL; @@ -1826,7 +1830,7 @@ static NTSTATUS get_dc_list(const char *domain, */ p = pserver; - while (next_token(&p,name,LIST_SEP,sizeof(name))) { + while (next_token_talloc(ctx, &p, &name, LIST_SEP)) { if (strequal(name, "*")) { status = internal_resolve_name(domain, 0x1C, sitename, &auto_ip_list, @@ -1870,7 +1874,7 @@ static NTSTATUS get_dc_list(const char *domain, /* fill in the return list now with real IP's */ while ((local_count Date: Sat, 8 Dec 2007 11:21:08 +0100 Subject: Fix C++ warnings (This used to be commit 01a5c3ea4bf18d99ca1c35e8c38367046e4c867b) --- source3/libsmb/clidfs.c | 2 +- source3/libsmb/clifile.c | 18 +++++++++--------- source3/libsmb/clilist.c | 2 +- source3/libsmb/clirap.c | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index f124821e62..e0c40b52ed 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -592,7 +592,7 @@ bool cli_dfs_get_referral(TALLOC_CTX *ctx, *num_refs = 0; *refs = NULL; - param = SMB_MALLOC(2+pathlen+2); + param = SMB_MALLOC_ARRAY(char, 2+pathlen+2); if (!param) { return false; } diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 70b4fe7cb3..001a42d4b9 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -37,8 +37,8 @@ static bool cli_link_internal(struct cli_state *cli, const char *oldname, const size_t oldlen = 2*(strlen(oldname)+1); size_t newlen = 2*(strlen(newname)+1); - param = SMB_MALLOC(6+newlen+2); - data = SMB_MALLOC(oldlen+2); + param = SMB_MALLOC_ARRAY(char, 6+newlen+2); + data = SMB_MALLOC_ARRAY(char, oldlen+2); if (!param || !data) { return false; } @@ -191,7 +191,7 @@ bool cli_unix_getfacl(struct cli_state *cli, const char *name, size_t *prb_size, char *rparam=NULL, *rdata=NULL; char *p; - param = SMB_MALLOC(6+nlen+2); + param = SMB_MALLOC_ARRAY(char, 6+nlen+2); if (!param) { return false; } @@ -251,7 +251,7 @@ bool cli_unix_stat(struct cli_state *cli, const char *name, SMB_STRUCT_STAT *sbu ZERO_STRUCTP(sbuf); - param = SMB_MALLOC(6+nlen+2); + param = SMB_MALLOC_ARRAY(char, 6+nlen+2); if (!param) { return false; } @@ -352,7 +352,7 @@ static bool cli_unix_chmod_chown_internal(struct cli_state *cli, const char *fna char *rparam=NULL, *rdata=NULL; char *p; - param = SMB_MALLOC(6+nlen+2); + param = SMB_MALLOC_ARRAY(char, 6+nlen+2); if (!param) { return false; } @@ -1662,7 +1662,7 @@ bool cli_set_ea_path(struct cli_state *cli, const char *path, const char *ea_nam char *p; bool ret; - param = SMB_MALLOC(6+srclen+2); + param = SMB_MALLOC_ARRAY(char, 6+srclen+2); if (!param) { return false; } @@ -1835,7 +1835,7 @@ bool cli_get_ea_list_path(struct cli_state *cli, const char *path, size_t srclen = 2*(strlen(path)+1); bool ret; - param = SMB_MALLOC(6+srclen+2); + param = SMB_MALLOC_ARRAY(char, 6+srclen+2); if (!param) { return false; } @@ -1940,7 +1940,7 @@ static int cli_posix_open_internal(struct cli_state *cli, const char *fname, int uint32 wire_flags = open_flags_to_wire(flags); size_t srclen = 2*(strlen(fname)+1); - param = SMB_MALLOC(6+srclen+2); + param = SMB_MALLOC_ARRAY(char, 6+srclen+2); if (!param) { return false; } @@ -2025,7 +2025,7 @@ static bool cli_posix_unlink_internal(struct cli_state *cli, const char *fname, char *p; size_t srclen = 2*(strlen(fname)+1); - param = SMB_MALLOC(6+srclen+2); + param = SMB_MALLOC_ARRAY(char, 6+srclen+2); if (!param) { return false; } diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index fc47f94aa1..2e4c360507 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -255,7 +255,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - param = SMB_MALLOC(12+nlen+last_name_raw.length+2); + param = SMB_MALLOC_ARRAY(char, 12+nlen+last_name_raw.length+2); if (!param) { break; } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index c10900cf43..410b7cb138 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -471,7 +471,7 @@ bool cli_qpathinfo(struct cli_state *cli, char *p; size_t nlen = 2*(strlen(fname)+1); - param = SMB_MALLOC(6+nlen+2); + param = SMB_MALLOC_ARRAY(char, 6+nlen+2); if (!param) { return false; } @@ -560,7 +560,7 @@ bool cli_setpathinfo(struct cli_state *cli, const char *fname, char *p; size_t nlen = 2*(strlen(fname)+1); - param = SMB_MALLOC(6+nlen+2); + param = SMB_MALLOC_ARRAY(char, 6+nlen+2); if (!param) { return false; } @@ -660,7 +660,7 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, char *p; size_t nlen = 2*(strlen(fname)+1); - param = SMB_MALLOC(6+nlen+2); + param = SMB_MALLOC_ARRAY(char, 6+nlen+2); if (!param) { return false; } @@ -989,7 +989,7 @@ NTSTATUS cli_qpathinfo_alt_name(struct cli_state *cli, const char *fname, fstrin unsigned int len; size_t nlen = 2*(strlen(fname)+1); - param = SMB_MALLOC(6+nlen+2); + param = SMB_MALLOC_ARRAY(char, 6+nlen+2); if (!param) { return NT_STATUS_NO_MEMORY; } -- cgit From 39f0e6d22cc9ffed65cfe16b7fa9d69940261532 Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 9 Dec 2007 14:01:57 -0800 Subject: Specifically ask for IP4 addresses if we don't have IP6 support. (This used to be commit 4786654992e3cb2280b77406f9217fcec981602c) --- source3/libsmb/namequery.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 9650b5fc45..e4206e6065 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1244,6 +1244,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_ADDRCONFIG; +#if !defined(HAVE_IPV6) + /* Unless we have IPv6, we really only want IPv4 addresses back. */ + hints.ai_family = AF_INET; +#endif + ret = getaddrinfo(name, NULL, &hints, -- cgit From f78ce189c29c873b45ada282edce050fb0186c39 Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 9 Dec 2007 14:18:54 -0800 Subject: Support fetching very long server lists with RAP_NetServerEnum3. Use the RAP_NetServerEnum3 server list continuation API for retrieving server lists that are too long to fit in a single reply. Patch from George Colley . (This used to be commit 40c26d55736ae08934e18c27168fff10dd15442f) --- source3/libsmb/clirap.c | 167 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 125 insertions(+), 42 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 410b7cb138..54504f608d 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -3,6 +3,7 @@ client RAP calls Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Gerald (Jerry) Carter 2004 + Copyright (C) James Peach 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -244,57 +245,118 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, { char *rparam = NULL; char *rdata = NULL; + char *rdata_end = NULL; unsigned int rdrcnt,rprcnt; char *p; char param[1024]; int uLevel = 1; - int count = -1; size_t len; + uint32 func = RAP_NetServerEnum2; + char *last_entry = NULL; + int total_cnt = 0; + int return_cnt = 0; + int res; errno = 0; /* reset */ - /* send a SMBtrans command with api NetServerEnum */ - p = param; - SSVAL(p,0,0x68); /* api number */ - p += 2; - strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param)); - p = skip_string(param,sizeof(param),p); + /* + * This may take more than one transaction, so we should loop until + * we no longer get a more data to process or we have all of the + * items. + */ + do { + /* send a SMBtrans command with api NetServerEnum */ + p = param; + SIVAL(p,0,func); /* api number */ + p += 2; + /* Next time through we need to use the continue api */ + func = RAP_NetServerEnum3; + + if (last_entry) { + strlcpy(p,"WrLehDOz", sizeof(param)-PTR_DIFF(p,param)); + } else { + strlcpy(p,"WrLehDz", sizeof(param)-PTR_DIFF(p,param)); + } - strlcpy(p,"B16BBDz", sizeof(param)-PTR_DIFF(p,param)); + p = skip_string(param, sizeof(param), p); + strlcpy(p,"B16BBDz", sizeof(param)-PTR_DIFF(p,param)); + + p = skip_string(param, sizeof(param), p); + SSVAL(p,0,uLevel); + SSVAL(p,2,CLI_BUFFER_SIZE); + p += 4; + SIVAL(p,0,stype); + p += 4; + + /* If we have more data, tell the server where + * to continue from. + */ + len = push_ascii(p, + last_entry ? last_entry : workgroup, + sizeof(param) - PTR_DIFF(p,param) - 1, + STR_TERMINATE|STR_UPPER); + + if (len == (size_t)-1) { + return false; + } + p += len; - p = skip_string(param,sizeof(param),p); - SSVAL(p,0,uLevel); - SSVAL(p,2,CLI_BUFFER_SIZE); - p += 4; - SIVAL(p,0,stype); - p += 4; + if (!cli_api(cli, + param, PTR_DIFF(p,param), 8, /* params, length, max */ + NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ + &rparam, &rprcnt, /* return params, return size */ + &rdata, &rdrcnt)) { /* return data, return size */ - len = push_ascii(p, workgroup, sizeof(param)-PTR_DIFF(p,param)-1, - STR_TERMINATE|STR_UPPER); - if (len == (size_t)-1) { - return false; - } - p += len; + /* break out of the loop on error */ + res = -1; + break; + } - if (cli_api(cli, - param, PTR_DIFF(p,param), 8, /* params, length, max */ - NULL, 0, CLI_BUFFER_SIZE, /* data, length, max */ - &rparam, &rprcnt, /* return params, return size */ - &rdata, &rdrcnt /* return data, return size */ - )) { - int res = rparam? SVAL(rparam,0) : -1; - char *rdata_end = rdata + rdrcnt; + rdata_end = rdata + rdrcnt; + res = rparam ? SVAL(rparam,0) : -1; if (res == 0 || res == ERRmoredata || (res != -1 && cli_errno(cli) == 0)) { - int i; + char *sname = NULL; + int i, count; int converter=SVAL(rparam,2); - count=SVAL(rparam,4); + /* Get the number of items returned in this buffer */ + count = SVAL(rparam, 4); + + /* The next field contains the number of items left, + * including those returned in this buffer. So the + * first time through this should contain all of the + * entries. + */ + if (total_cnt == 0) { + total_cnt = SVAL(rparam, 6); + } + + /* Keep track of how many we have read */ + return_cnt += count; p = rdata; - for (i = 0;i < count;i++, p += 26) { - char *sname; + /* The last name in the previous NetServerEnum reply is + * sent back to server in the NetServerEnum3 request + * (last_entry). The next reply should repeat this entry + * as the first element. We have no proof that this is + * always true, but from traces that seems to be the + * behavior from Window Servers. So first lets do a lot + * of checking, just being paranoid. If the string + * matches then we already saw this entry so skip it. + * + * NOTE: sv1_name field must be null terminated and has + * a max size of 16 (NetBIOS Name). + */ + if (last_entry && count && p && + (strncmp(last_entry, p, 16) == 0)) { + count -= 1; /* Skip this entry */ + return_cnt = -1; /* Not part of total, so don't count. */ + p = rdata + 26; /* Skip the whole record */ + } + + for (i = 0; i < count; i++, p += 26) { int comment_offset; const char *cmnt; const char *p1; @@ -338,24 +400,45 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, fn(s1, stype, s2, state); TALLOC_FREE(frame); } + + /* We are done with the old last entry, so now we can free it */ + if (last_entry) { + SAFE_FREE(last_entry); /* This will set it to null */ + } + + /* We always make a copy of the last entry if we have one */ + if (sname) { + last_entry = smb_xstrdup(sname); + } + + /* If we have more data, but no last entry then error out */ + if (!last_entry && (res == ERRmoredata)) { + errno = EINVAL; + res = 0; + } + } - } + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + } while ((res == ERRmoredata) && (total_cnt > return_cnt)); SAFE_FREE(rparam); SAFE_FREE(rdata); + SAFE_FREE(last_entry); - if (count < 0) { - errno = cli_errno(cli); + if (res == -1) { + errno = cli_errno(cli); } else { - if (!count) { - /* this is a very special case, when the domain master for the - work group isn't part of the work group itself, there is something - wild going on */ - errno = ENOENT; + if (!return_cnt) { + /* this is a very special case, when the domain master for the + work group isn't part of the work group itself, there is something + wild going on */ + errno = ENOENT; + } } - } - return(count > 0); + return(return_cnt > 0); } /**************************************************************************** -- cgit From 7faee02d0d351c5c039e8f1be7e82ce3a93cbe96 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Dec 2007 11:30:37 -0800 Subject: Remove the char[1024] strings from dynconfig. Replace them with malloc'ing accessor functions. Should save a lot of static space :-). Jeremy. (This used to be commit 52dc5eaef2106015b3a8b659e818bdb15ad94b05) --- source3/libsmb/libsmbclient.c | 6 +++--- source3/libsmb/namequery.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 9f5567576f..9b8d5edb4a 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -6900,15 +6900,15 @@ smbc_init_context(SMBCCTX *context) if (!conf_loaded) { /* - * Well, if that failed, try the dyn_CONFIGFILE + * Well, if that failed, try the get_dyn_CONFIGFILE * Which points to the standard locn, and if that * fails, silently ignore it and use the internal * defaults ... */ - if (!lp_load(dyn_CONFIGFILE, True, False, False, False)) { + if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { DEBUG(5, ("Could not load config file: %s\n", - dyn_CONFIGFILE)); + get_dyn_CONFIGFILE())); } else if (home) { char *conf; /* diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index e4206e6065..0decc59ed7 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1157,7 +1157,7 @@ static NTSTATUS resolve_lmhosts(const char *name, int name_type, "Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type)); - fp = startlmhosts(dyn_LMHOSTSFILE); + fp = startlmhosts(get_dyn_LMHOSTSFILE()); if ( fp == NULL ) return NT_STATUS_NO_SUCH_FILE; -- cgit From 921bbc1331d35785e2c691551d4c103c9c29ed4d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Dec 2007 14:21:28 -0800 Subject: Fix errors from next_token conversion. Spotted by Andreas Schneider . Jeremy. (This used to be commit b40efc2fe63a3420b62fbf1ea8936112c5a24bdc) --- source3/libsmb/namequery.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0decc59ed7..c0d6b6e91e 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -791,12 +791,12 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, *pp_name = NULL; while(!x_feof(fp) && !x_ferror(fp)) { - char *ip; - char *flags; - char *extra; - char *name; + char *ip = NULL; + char *flags = NULL; + char *extra = NULL; + char *name = NULL; const char *ptr; - char *ptr1; + char *ptr1 = NULL; int count = 0; *name_type = -1; @@ -809,10 +809,6 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, continue; } - ip[0] = '\0'; - name[0] = '\0'; - flags[0] = '\0'; - ptr = line; if (next_token_talloc(ctx, &ptr, &ip, NULL)) -- cgit From 8596a1b60996eda7e51bfd30d625d3201881d2af Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Dec 2007 15:06:31 -0800 Subject: Ensure we have a non-null flags. Pointed out by Andreas Schneider . Jeremy. (This used to be commit cafde6c37259de587d3775a2d229abd253d2376d) --- source3/libsmb/namequery.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c0d6b6e91e..819147d48f 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -835,6 +835,13 @@ bool getlmhostsent(TALLOC_CTX *ctx, XFILE *fp, char **pp_name, int *name_type, continue; } + if (!flags) { + flags = talloc_strdup(ctx, ""); + if (!flags) { + continue; + } + } + DEBUG(4, ("getlmhostsent: lmhost entry: %s %s %s\n", ip, name, flags)); -- cgit From f0d2edb9a0a98e732c23a3661933a2bf6c50cacd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 12 Dec 2007 00:44:10 +0100 Subject: Make decode_wkssvc_join_password_buffer() return WERRORs. Guenther (This used to be commit 88e9da2f14b41a62bdb478f9ffc2de66643bbf14) --- source3/libsmb/smbencrypt.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 8793fdcb55..9e37d1d6cf 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -731,10 +731,10 @@ void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, data_blob_free(&confounded_session_key); } -void decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, - struct wkssvc_PasswordBuffer *pwd_buf, - DATA_BLOB *session_key, - char **pwd) +WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, + struct wkssvc_PasswordBuffer *pwd_buf, + DATA_BLOB *session_key, + char **pwd) { uint8_t buffer[516]; struct MD5Context ctx; @@ -745,6 +745,11 @@ void decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, int confounder_len = 8; uint8_t confounder[8]; + if (session_key->length != 16) { + DEBUG(10,("invalid session key\n")); + return WERR_BAD_PASSWORD; + } + memcpy(&confounder, &pwd_buf->data[0], confounder_len); memcpy(&buffer, &pwd_buf->data[8], 516); @@ -755,7 +760,11 @@ void decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, SamOEMhashBlob(buffer, 516, &confounded_session_key); - decode_pw_buffer(mem_ctx, buffer, pwd, &pwd_len, STR_UNICODE); + if (!decode_pw_buffer(mem_ctx, buffer, pwd, &pwd_len, STR_UNICODE)) { + return WERR_BAD_PASSWORD; + } data_blob_free(&confounded_session_key); + + return WERR_OK; } -- cgit From e3e16928c057b35b66bc814a507fc79b9e02084c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 12 Dec 2007 09:42:58 -0800 Subject: Allow cliconnect to loop through multiple ip addresses for a server. We should have been doing this for a while, but it's more critical with IPv6. Original patch fixed up by James. Jeremy. (This used to be commit 5c7f7629a97ef0929e00e52f1fae4386c984000b) --- source3/libsmb/cliconnect.c | 72 +++++++++++++++++++++++++++------------- source3/libsmb/namequery.c | 81 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index fdf7491d80..45c202090e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1424,7 +1424,11 @@ NTSTATUS cli_connect(struct cli_state *cli, { int name_type = 0x20; - char *p; + TALLOC_CTX *frame = talloc_stackframe(); + unsigned int num_addrs = 0; + unsigned int i = 0; + struct sockaddr_storage *ss_arr = NULL; + char *p = NULL; /* reasonable default hostname */ if (!host) { @@ -1440,44 +1444,66 @@ NTSTATUS cli_connect(struct cli_state *cli, } if (!dest_ss || is_zero_addr(dest_ss)) { - if (!resolve_name(cli->desthost, &cli->dest_ss, name_type)) { + NTSTATUS status =resolve_name_list(frame, + cli->desthost, + name_type, + &ss_arr, + &num_addrs); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(frame); return NT_STATUS_BAD_NETWORK_NAME; } - if (dest_ss) { - *dest_ss = cli->dest_ss; - } } else { - cli->dest_ss = *dest_ss; + num_addrs = 1; + ss_arr = TALLOC_P(frame, struct sockaddr_storage); + if (!ss_arr) { + TALLOC_FREE(frame); + return NT_STATUS_NO_MEMORY; + } + *ss_arr = *dest_ss; } - if (getenv("LIBSMB_PROG")) { - cli->fd = sock_exec(getenv("LIBSMB_PROG")); - } else { - /* try 445 first, then 139 */ - uint16_t port = cli->port?cli->port:445; - cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss, - port, cli->timeout); - if (cli->fd == -1 && cli->port == 0) { - port = 139; + for (i = 0; i < num_addrs; i++) { + cli->dest_ss = ss_arr[i]; + if (getenv("LIBSMB_PROG")) { + cli->fd = sock_exec(getenv("LIBSMB_PROG")); + } else { + /* try 445 first, then 139 */ + uint16_t port = cli->port?cli->port:445; cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss, port, cli->timeout); + if (cli->fd == -1 && cli->port == 0) { + port = 139; + cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ss, + port, cli->timeout); + } + if (cli->fd != -1) { + cli->port = port; + } } - if (cli->fd != -1) { - cli->port = port; + if (cli->fd == -1) { + char addr[INET6_ADDRSTRLEN]; + print_sockaddr(addr, sizeof(addr), &ss_arr[i]); + DEBUG(2,("Error connecting to %s (%s)\n", + dest_ss?addr:host,strerror(errno))); + } else { + /* Exit from loop on first connection. */ + break; } } + if (cli->fd == -1) { - char addr[INET6_ADDRSTRLEN]; - if (dest_ss) { - print_sockaddr(addr, sizeof(addr), dest_ss); - } - DEBUG(1,("Error connecting to %s (%s)\n", - dest_ss?addr:host,strerror(errno))); + TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } + if (dest_ss) { + *dest_ss = cli->dest_ss; + } + set_socket_options(cli->fd, lp_socket_options()); + TALLOC_FREE(frame); return NT_STATUS_OK; } diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 819147d48f..853fe979b7 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1653,6 +1653,87 @@ bool resolve_name(const char *name, return False; } +/******************************************************** + Internal interface to resolve a name into a list of IP addresses. + Use this function if the string is either an IP address, DNS + or host name or NetBIOS name. This uses the name switch in the + smb.conf to determine the order of name resolution. +*********************************************************/ + +NTSTATUS resolve_name_list(TALLOC_CTX *ctx, + const char *name, + int name_type, + struct sockaddr_storage **return_ss_arr, + unsigned int *p_num_entries) +{ + struct ip_service *ss_list = NULL; + char *sitename = NULL; + int count = 0; + int i; + unsigned int num_entries; + NTSTATUS status; + + *p_num_entries = 0; + *return_ss_arr = NULL; + + if (is_ipaddress(name)) { + *return_ss_arr = TALLOC_P(ctx, struct sockaddr_storage); + if (!*return_ss_arr) { + return NT_STATUS_NO_MEMORY; + } + if (!interpret_string_addr(*return_ss_arr, name, AI_NUMERICHOST)) { + TALLOC_FREE(*return_ss_arr); + return NT_STATUS_BAD_NETWORK_NAME; + } + *p_num_entries = 1; + return NT_STATUS_OK; + } + + sitename = sitename_fetch(lp_realm()); /* wild guess */ + + status = internal_resolve_name(name, name_type, sitename, + &ss_list, &count, + lp_name_resolve_order()); + SAFE_FREE(sitename); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* only return valid addresses for TCP connections */ + for (i=0, num_entries = 0; i Date: Wed, 12 Dec 2007 13:38:28 +0100 Subject: Vista SP1-rc1 appears to break against Samba-3.0.27a MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Jason, Jason Haar wrote: > Patched 3.0.28, compiled, installed and here's the log file. > > Hope it helps. BTW I don't think it matters, but this is on 32bit > CentOS4.5 systems. yes, it helps. Thanks for that. Very interesting, there are two auth data structures where the first one is a PAC and the second something unknown (yet). Can you please try the attached fix ? It should make it work again. Guenther - -- Günther Deschner GPG-ID: 8EE11688 Red Hat gdeschner@redhat.com Samba Team gd@samba.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.7 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iD8DBQFHX9ZESOk3aI7hFogRAivSAJ9bMcD+PcsIzjYYLtAUoLNfVVEl1QCfV/Qd MPsZW4G31VOVu64SPjgnJiI= =Co+H -----END PGP SIGNATURE----- (This used to be commit c9adc07ca2a3bb1e0ea98e3b4f68e1a87e5c0196) --- source3/libsmb/clikrb5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 549574caad..1bbd765965 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -427,9 +427,9 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ /* check if it is a PAC */ got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data); data_blob_free(&auth_data_wrapped); - - if (!got_auth_data_pac) { - continue; + + if (got_auth_data_pac) { + return true; } } -- cgit From 022014dba281a50d98ac2f00a4c941124065914f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 12 Dec 2007 18:57:45 +0100 Subject: Make heimdal and MIT happy when iterating through auth data. Guenther (This used to be commit 507247dcbf0ef02825a6c5c5f313813714df2d99) --- source3/libsmb/clikrb5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 1bbd765965..844a3b35c0 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -399,9 +399,9 @@ bool unwrap_pac(TALLOC_CTX *mem_ctx, DATA_BLOB *auth_data, DATA_BLOB *unwrapped_ /* check if it is a PAC */ got_auth_data_pac = unwrap_pac(mem_ctx, &auth_data_wrapped, auth_data); data_blob_free(&auth_data_wrapped); - - if (!got_auth_data_pac) { - continue; + + if (got_auth_data_pac) { + return true; } } -- cgit From 9e733924d9119a3a7a8b755557ffe458dda96d63 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Dec 2007 16:44:24 -0800 Subject: Arg. The fix for CVE-2007-6015 hadn't been merged into 3.2. Do so now.... Jeremy. (This used to be commit 6b1246c29a0241c8e4bb98d659d847d010826b36) --- source3/libsmb/clidgram.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 82f874f383..76630bd504 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -75,6 +75,12 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, /* Setup the smb part. */ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */ memcpy(tmp,ptr,4); + + if (smb_size + 17*2 + strlen(mailslot) + 1 + len > MAX_DGRAM_SIZE) { + DEBUG(0, ("cli_send_mailslot: Cannot write beyond end of packet\n")); + return False; + } + set_message(ptr,17,strlen(mailslot) + 1 + len,True); memcpy(ptr,tmp,4); -- cgit From 900288a2b86abd247f9eb4cd15dc5617a17cfef1 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:11:36 +0100 Subject: Replace sid_string_static by sid_string_dbg in DEBUGs (This used to be commit bb35e794ec129805e874ceba882bcc1e84791a09) --- source3/libsmb/trustdom_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index be73381aa3..498a0221f2 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -123,7 +123,7 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, return False; DEBUG(5, ("trustdom_store: storing SID %s of domain %s\n", - sid_string_static(sid), name)); + sid_string_dbg(sid), name)); key = trustdom_cache_key(name); alt_key = alt_name ? trustdom_cache_key(alt_name) : NULL; -- cgit From d899b8c56ad6556baf2d2374704cc8cd1b15d5ad Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 21:58:28 +0100 Subject: Use sid_to_string directly It seems a bit pointless to do a fstrcpy(dst, sid_string_static(src)) (This used to be commit c221c246b10e2dbbd54a9af2dc45de2eae237380) --- source3/libsmb/cliquota.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 690da5928c..3c794240bc 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -608,7 +608,7 @@ void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, bool _verbose, bool _numeric, void (*_ if (_sidtostring) { _sidtostring(username_str,&qt->sid,_numeric); } else { - fstrcpy(username_str,sid_string_static(&qt->sid)); + sid_to_string(username_str, &qt->sid); } if (_verbose) { -- cgit From 14ef4cdec1ab6be55c97d0f32780cbddbcdde218 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 22:00:39 +0100 Subject: Replace sid_string_static with sid_to_string This adds 28 fstrings on the stack, but I think an fstring on the stack is still far better than a static one. (This used to be commit c7c885078be8fd3024c186044ac28275d7609679) --- source3/libsmb/samlogon_cache.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index b1d6c8d8f3..a15a3b228d 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -107,7 +107,7 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) bool netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) { TDB_DATA data; - fstring keystr; + fstring keystr, tmp; prs_struct ps; bool result = False; DOM_SID user_sid; @@ -124,7 +124,7 @@ bool netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) sid_append_rid( &user_sid, user->user_rid ); /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s", sid_string_static(&user_sid)); + slprintf(keystr, sizeof(keystr), "%s", sid_to_string(tmp, &user_sid)); DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); @@ -177,7 +177,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user NET_USER_INFO_3 *user = NULL; TDB_DATA data; prs_struct ps; - fstring keystr; + fstring keystr, tmp; uint32 t; if (!netsamlogon_cache_init()) { @@ -186,7 +186,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user } /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s", sid_string_static(user_sid)); + slprintf(keystr, sizeof(keystr), "%s", sid_to_string(tmp, user_sid)); DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); data = tdb_fetch_bystring( netsamlogon_tdb, keystr ); -- cgit From 2e07c2ade89f4ff281c61f74cb88e09990cf5f46 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Dec 2007 22:47:30 +0100 Subject: s/sid_to_string/sid_to_fstring/ least surprise for callers (This used to be commit eb523ba77697346a365589101aac379febecd546) --- source3/libsmb/cliquota.c | 2 +- source3/libsmb/libsmbclient.c | 2 +- source3/libsmb/samlogon_cache.c | 8 ++++---- source3/libsmb/trustdom_cache.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 3c794240bc..206576f040 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -608,7 +608,7 @@ void dump_ntquota(SMB_NTQUOTA_STRUCT *qt, bool _verbose, bool _numeric, void (*_ if (_sidtostring) { _sidtostring(username_str,&qt->sid,_numeric); } else { - sid_to_string(username_str, &qt->sid); + sid_to_fstring(username_str, &qt->sid); } if (_verbose) { diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 9b8d5edb4a..2ff2830256 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4136,7 +4136,7 @@ convert_sid_to_string(struct cli_state *ipc_cli, struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); TALLOC_CTX *ctx; - sid_to_string(str, sid); + sid_to_fstring(str, sid); if (numeric) { return; /* no lookup desired */ diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index a15a3b228d..4f791f66f6 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -81,7 +81,7 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) /* Clear U/SID cache entry */ - fstr_sprintf(key_str, "U/%s", sid_to_string(sid_string, &sid)); + fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, &sid)); DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str)); @@ -89,7 +89,7 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) /* Clear UG/SID cache entry */ - fstr_sprintf(key_str, "UG/%s", sid_to_string(sid_string, &sid)); + fstr_sprintf(key_str, "UG/%s", sid_to_fstring(sid_string, &sid)); DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str)); @@ -124,7 +124,7 @@ bool netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) sid_append_rid( &user_sid, user->user_rid ); /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s", sid_to_string(tmp, &user_sid)); + slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid)); DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); @@ -186,7 +186,7 @@ NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user } /* Prepare key as DOMAIN-SID/USER-RID string */ - slprintf(keystr, sizeof(keystr), "%s", sid_to_string(tmp, user_sid)); + slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, user_sid)); DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); data = tdb_fetch_bystring( netsamlogon_tdb, keystr ); diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 498a0221f2..6755de3814 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -129,7 +129,7 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, alt_key = alt_name ? trustdom_cache_key(alt_name) : NULL; /* Generate string representation domain SID */ - sid_to_string(sid_string, sid); + sid_to_fstring(sid_string, sid); /* * try to put the names in the cache -- cgit From 5dbc4a23bcae0087ab4319b5343cf6f44a4819e3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 15 Dec 2007 23:22:25 -0800 Subject: Added patch originally by Andreas Schneider to cause us to behave like Vista when looking for remote machine principal. Modified by me. Jeremy. (This used to be commit d0e33840fb4cfc85990d3ee327428b0854a22722) --- source3/libsmb/cliconnect.c | 50 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 45c202090e..52ff69953e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -37,6 +37,8 @@ static const struct { {-1,NULL} }; +static const char *star_smbserver_name = "*SMBSERVER"; + /** * Set the user session key for a connection * @param cli The cli structure to add it too @@ -858,10 +860,42 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, } } - rc = cli_session_setup_kerberos(cli, principal, domain); - if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) { + /* If we get a bad principal, try to guess it if + we have a valid host NetBIOS name. + */ + if (strequal(principal, + "not_defined_in_RFC4178@please_ignore")) { SAFE_FREE(principal); - return rc; + } + + if (principal == NULL && + !is_ipaddress(cli->desthost) && + !strequal(star_smbserver_name, + cli->desthost)) { + char *realm = NULL; + DEBUG(3,("cli_session_setup_spnego: got a " + "bad server principal, trying to guess ...\n")); + + realm = kerberos_get_default_realm_from_ccache(); + if (realm && *realm) { + if (asprintf(&principal, "%s$@%s", + cli->desthost, realm) < 0) { + SAFE_FREE(realm); + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + DEBUG(3,("cli_session_setup_spnego: guessed " + "server principal=%s\n", + principal ? principal : "")); + } + SAFE_FREE(realm); + } + + if (principal) { + rc = cli_session_setup_kerberos(cli, principal, domain); + if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) { + SAFE_FREE(principal); + return rc; + } } } #endif @@ -1432,7 +1466,7 @@ NTSTATUS cli_connect(struct cli_state *cli, /* reasonable default hostname */ if (!host) { - host = "*SMBSERVER"; + host = star_smbserver_name; } fstrcpy(cli->desthost, host); @@ -1580,8 +1614,8 @@ again: *p = 0; goto again; } - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); + if (strcmp(called.name, star_smbserver_name)) { + make_nmb_name(&called , star_smbserver_name, 0x20); goto again; } return NT_STATUS_BAD_NETWORK_NAME; @@ -1706,7 +1740,7 @@ bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho */ if(is_ipaddress(desthost)) { - make_nmb_name(&called, "*SMBSERVER", 0x20); + make_nmb_name(&called, star_smbserver_name, 0x20); } else { make_nmb_name(&called, desthost, 0x20); } @@ -1715,7 +1749,7 @@ bool attempt_netbios_session_request(struct cli_state **ppcli, const char *srcho NTSTATUS status; struct nmb_name smbservername; - make_nmb_name(&smbservername , "*SMBSERVER", 0x20); + make_nmb_name(&smbservername, star_smbserver_name, 0x20); /* * If the name wasn't *SMBSERVER then -- cgit From 713e1536fe4914e6df11cf10316d0b1c7c3685a3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 18 Dec 2007 13:38:14 +0100 Subject: Merge WERR_NO_SUCH_LOGON_SESSION from Samba4. Guenther (This used to be commit 7b528647879bb55c9c85243a3e2906c09490edc9) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 84cc898187..5bdd85da1b 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -60,6 +60,7 @@ werror_code_struct dos_errs[] = { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, + { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, -- cgit From 2197801ef1d9a942c8f8ec8b8e81b9f25cffc02f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 16:48:04 +0100 Subject: Zero the tdb key, there might be padding This leads to uninitialized variable warnings if nmbd is run under valgrind. (This used to be commit 9ec4f91f35696e5a00e24fe9ae2dd06119482c80) --- source3/libsmb/unexpected.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 92a609c42b..195668c44a 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -63,6 +63,8 @@ void unexpected_packet(struct packet_struct *p) len = build_packet(&buf[6], sizeof(buf)-6, p) + 6; + ZERO_STRUCT(key); /* needed for potential alignment */ + key.packet_type = p->packet_type; key.timestamp = p->timestamp; key.count = count++; -- cgit From 0743d384a634ad9c124673f52b9c2d17aab1ac89 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 16:48:18 +0100 Subject: Some paranoia checks (This used to be commit ff644cfa1b123e9d0f8f4817504e5b209b85dedd) --- source3/libsmb/unexpected.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 195668c44a..5fbc33cdf5 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -88,6 +88,10 @@ static int traverse_fn(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, void *st { struct unexpected_key key; + if (kbuf.dsize != sizeof(key)) { + tdb_delete(ttdb, kbuf); + } + memcpy(&key, kbuf.dptr, sizeof(key)); if (lastt - key.timestamp > NMBD_UNEXPECTED_TIMEOUT) { @@ -136,6 +140,10 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, int port; struct packet_struct *p; + if (kbuf.dsize != sizeof(key)) { + return 0; + } + memcpy(&key, kbuf.dptr, sizeof(key)); if (key.packet_type != state->match_type) return 0; -- cgit From a37873490f2c4e89e98780203d13e2f21a6ecebf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 17:05:26 +0100 Subject: packet_struct is used in several places as raw memory -> Fix more uninitialized variable warnings (This used to be commit 0af02db6f2f84a8ce5d614e5baec27f20b413c26) --- source3/libsmb/nmblib.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 2ff925ef36..15a9a93ff2 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -740,6 +740,8 @@ struct packet_struct *parse_packet(char *buf,int length, if (!p) return(NULL); + ZERO_STRUCTP(p); /* initialize for possible padding */ + p->next = NULL; p->prev = NULL; p->ip = ip; -- cgit From 5f1d36ce9abdb33ebb4f21c66c0885ea70097f6f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 20:24:33 +0100 Subject: Fix debug messages When warning that "client plaintext auth" is not enabled where the server requested them we should not talk about "client use plaintext auth" (This used to be commit 7799e18994354b2705ee8c64ae8c75e062ace460) --- source3/libsmb/cliconnect.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 52ff69953e..d370808bba 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -959,8 +959,8 @@ NTSTATUS cli_session_setup(struct cli_state *cli, if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0 && !lp_client_plaintext_auth() && (*pass)) { - DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" - " is disabled\n")); + DEBUG(1, ("Server requested plaintext password but " + "'client plaintext auth' is disabled\n")); return NT_STATUS_ACCESS_DENIED; } @@ -986,8 +986,8 @@ NTSTATUS cli_session_setup(struct cli_state *cli, if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { if (!lp_client_plaintext_auth() && (*pass)) { - DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" - " is disabled\n")); + DEBUG(1, ("Server requested plaintext password but " + "'client plaintext auth' is disabled\n")); return NT_STATUS_ACCESS_DENIED; } return cli_session_setup_plaintext(cli, user, pass, workgroup); @@ -1086,8 +1086,9 @@ bool cli_send_tconX(struct cli_state *cli, } else { if((cli->sec_mode & (NEGOTIATE_SECURITY_USER_LEVEL|NEGOTIATE_SECURITY_CHALLENGE_RESPONSE)) == 0) { if (!lp_client_plaintext_auth() && (*pass)) { - DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" - " is disabled\n")); + DEBUG(1, ("Server requested plaintext " + "password but 'client plaintext " + "auth' is disabled\n")); return False; } @@ -1798,8 +1799,8 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, char *p; if (!lp_client_plaintext_auth() && (*pass)) { - DEBUG(1, ("Server requested plaintext password but 'client use plaintext auth'" - " is disabled\n")); + DEBUG(1, ("Server requested plaintext password but 'client " + "plaintext auth' is disabled\n")); return NT_STATUS_ACCESS_DENIED; } -- cgit From addf598cde41d17ad4cf497a64b9a2b27e4028c5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 20 Dec 2007 22:17:16 +0100 Subject: Some C++ warnings (This used to be commit 5ab82d4f574f2a2e2761e9e414c66a70aeffb05d) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 1a6fb8f93f..0544b3d879 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -471,7 +471,7 @@ struct cli_state *cli_initialise(void) cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = False; - cli->smb_rw_error = 0; + cli->smb_rw_error = SMB_READ_OK; cli->use_spnego = lp_client_use_spnego(); @@ -606,7 +606,7 @@ void cli_shutdown(struct cli_state *cli) close(cli->fd); } cli->fd = -1; - cli->smb_rw_error = 0; + cli->smb_rw_error = SMB_READ_OK; SAFE_FREE(cli); } -- cgit From 574354a7ec76e85e0f5a1172de9e59ae5bc52d48 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Dec 2007 13:40:11 +0100 Subject: Use ADS_IGNORE_PRINCIPAL define. Guenther (This used to be commit 763e13315fc71237b14a186810bc201e725648f5) --- source3/libsmb/cliconnect.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d370808bba..33110c803f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -863,8 +863,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, /* If we get a bad principal, try to guess it if we have a valid host NetBIOS name. */ - if (strequal(principal, - "not_defined_in_RFC4178@please_ignore")) { + if (strequal(principal, ADS_IGNORE_PRINCIPAL)) { SAFE_FREE(principal); } -- cgit From c000a166459468e0cfd5277fa717f8fc9ed8311f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 21 Dec 2007 15:28:01 +0100 Subject: Add get_friendly_werror_msg(). Guenther (This used to be commit b1ad3def98911c91ed55a3b7aec7d0894b2dd8fd) --- source3/libsmb/doserr.c | 52 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 45 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 5bdd85da1b..dd556bba5a 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -1,18 +1,18 @@ -/* +/* * Unix SMB/CIFS implementation. * DOS error routines * Copyright (C) Tim Potter 2002. - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ @@ -21,12 +21,16 @@ #include "includes.h" -typedef const struct -{ +typedef const struct { const char *dos_errstr; WERROR werror; } werror_code_struct; +typedef const struct { + WERROR werror; + const char *friendly_errstr; +} werror_str_struct; + werror_code_struct dos_errs[] = { { "WERR_OK", WERR_OK }, @@ -92,6 +96,22 @@ werror_code_struct dos_errs[] = { NULL, W_ERROR(0) } }; +werror_str_struct dos_err_strs[] = { + { WERR_OK, "Success" }, + { WERR_ACCESS_DENIED, "Access is denied" }, + { WERR_INVALID_PARAM, "Invalid parameter" }, + { WERR_NOT_SUPPORTED, "Not supported" }, + { WERR_BAD_PASSWORD, "A bad password was supplied" }, + { WERR_NOMEM, "Out of memory" }, + { WERR_NO_LOGON_SERVERS, "No logon servers found" }, + { WERR_NO_SUCH_LOGON_SESSION, "No such logon session" }, + { WERR_DOMAIN_CONTROLLER_NOT_FOUND, "A domain controller could not be found" }, + { WERR_SETUP_NOT_JOINED, "Join failed" }, + { WERR_SETUP_ALREADY_JOINED, "Machine is already joined" }, + { WERR_SETUP_DOMAIN_CONTROLLER, "Machine is a Domain Controller" }, + { WERR_LOGON_FAILURE, "Invalid logon credentials" }, +}; + /***************************************************************************** Returns a DOS error message. not amazingly helpful, but better than a number. *****************************************************************************/ @@ -102,7 +122,7 @@ const char *dos_errstr(WERROR werror) int idx = 0; while (dos_errs[idx].dos_errstr != NULL) { - if (W_ERROR_V(dos_errs[idx].werror) == + if (W_ERROR_V(dos_errs[idx].werror) == W_ERROR_V(werror)) return dos_errs[idx].dos_errstr; idx++; @@ -114,6 +134,24 @@ const char *dos_errstr(WERROR werror) return result; } +/***************************************************************************** + Get friendly error string for WERRORs + *****************************************************************************/ + +const char *get_friendly_werror_msg(WERROR werror) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(dos_err_strs); i++) { + if (W_ERROR_V(dos_err_strs[i].werror) == + W_ERROR_V(werror)) { + return dos_err_strs[i].friendly_errstr; + } + } + + return dos_errstr(werror); +} + /* compat function for samba4 */ const char *win_errstr(WERROR werror) { -- cgit From afc93255d183eefb68e45b8ec6275f6a62cf9795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/libsmb/cliconnect.c | 22 +- source3/libsmb/clidgram.c | 2 +- source3/libsmb/clientgen.c | 108 ++++++--- source3/libsmb/clifile.c | 44 ++-- source3/libsmb/clifsinfo.c | 333 ++++++++++++++++++++++++++++ source3/libsmb/clilist.c | 4 +- source3/libsmb/climessage.c | 6 +- source3/libsmb/clioplock.c | 2 +- source3/libsmb/cliprint.c | 4 +- source3/libsmb/clireadwrite.c | 31 +-- source3/libsmb/clitrans.c | 8 +- source3/libsmb/errormap.c | 105 +++++++++ source3/libsmb/smb_seal.c | 496 ++++++++++++++++++++++++++++++++++++++++++ 13 files changed, 1070 insertions(+), 95 deletions(-) create mode 100644 source3/libsmb/smb_seal.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 33110c803f..4560521d4a 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -98,7 +98,7 @@ static NTSTATUS cli_session_setup_lanman2(struct cli_state *cli, /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,10, 0, True); + cli_set_message(cli->outbuf,10, 0, True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -168,7 +168,7 @@ static NTSTATUS cli_session_setup_guest(struct cli_state *cli) uint32 capabilities = cli_session_setup_capabilities(cli); memset(cli->outbuf, '\0', smb_size); - set_message(cli->outbuf,13,0,True); + cli_set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -228,7 +228,7 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, fstr_sprintf( lanman, "Samba %s", SAMBA_VERSION_STRING); memset(cli->outbuf, '\0', smb_size); - set_message(cli->outbuf,13,0,True); + cli_set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -377,7 +377,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,13,0,True); + cli_set_message(cli->outbuf,13,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -457,7 +457,7 @@ static bool cli_session_setup_blob_send(struct cli_state *cli, DATA_BLOB blob) /* send a session setup command */ memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,12,0,True); + cli_set_message(cli->outbuf,12,0,True); SCVAL(cli->outbuf,smb_com,SMBsesssetupX); cli_setup_packet(cli); @@ -1028,7 +1028,7 @@ NTSTATUS cli_session_setup(struct cli_state *cli, bool cli_ulogoff(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + cli_set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBulogoffX); cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,0xFF); @@ -1106,7 +1106,7 @@ bool cli_send_tconX(struct cli_state *cli, slprintf(fullshare, sizeof(fullshare)-1, "\\\\%s\\%s", cli->desthost, share); - set_message(cli->outbuf,4, 0, True); + cli_set_message(cli->outbuf,4, 0, True); SCVAL(cli->outbuf,smb_com,SMBtconX); cli_setup_packet(cli); @@ -1157,7 +1157,7 @@ bool cli_send_tconX(struct cli_state *cli, bool cli_tdis(struct cli_state *cli) { memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + cli_set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBtdis); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1189,7 +1189,7 @@ void cli_negprot_send(struct cli_state *cli) memset(cli->outbuf,'\0',smb_size); /* setup the protocol strings */ - set_message(cli->outbuf,0,0,True); + cli_set_message(cli->outbuf,0,0,True); p = smb_buf(cli->outbuf); for (numprots=0; @@ -1229,7 +1229,7 @@ bool cli_negprot(struct cli_state *cli) numprots++) plength += strlen(prots[numprots].name)+2; - set_message(cli->outbuf,0,plength,True); + cli_set_message(cli->outbuf,0,plength,True); p = smb_buf(cli->outbuf); for (numprots=0; @@ -1806,7 +1806,7 @@ NTSTATUS cli_raw_tcon(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 0, 0, True); + cli_set_message(cli->outbuf, 0, 0, True); SCVAL(cli->outbuf,smb_com,SMBtcon); cli_setup_packet(cli); diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 76630bd504..66c6ee1022 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -81,7 +81,7 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, return False; } - set_message(ptr,17,strlen(mailslot) + 1 + len,True); + cli_set_message(ptr,17,strlen(mailslot) + 1 + len,True); memcpy(ptr,tmp,4); SCVAL(ptr,smb_com,SMBtrans); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 0544b3d879..da225ebc24 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -20,6 +20,21 @@ #include "includes.h" +/******************************************************************* + Setup the word count and byte count for a client smb message. +********************************************************************/ + +int cli_set_message(char *buf,int num_words,int num_bytes,bool zero) +{ + if (zero && (num_words || num_bytes)) { + memset(buf + smb_size,'\0',num_words*2 + num_bytes); + } + SCVAL(buf,smb_wct,num_words); + SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes); + smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4); + return (smb_size + num_words*2 + num_bytes); +} + /**************************************************************************** Change the timeout (in milliseconds). ****************************************************************************/ @@ -85,7 +100,7 @@ bool cli_receive_smb(struct cli_state *cli) /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) - return False; + return false; again: len = client_receive_smb(cli, 0); @@ -100,7 +115,7 @@ bool cli_receive_smb(struct cli_state *cli) int fnum = SVAL(cli->inbuf,smb_vwv2); unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); if (!cli->oplock_handler(cli, fnum, level)) { - return False; + return false; } } /* try to prevent loops */ @@ -114,7 +129,7 @@ bool cli_receive_smb(struct cli_state *cli) DEBUG(0, ("Receiving SMB: Server stopped responding\n")); close(cli->fd); cli->fd = -1; - return False; + return false; } if (!cli_check_sign_mac(cli)) { @@ -135,16 +150,16 @@ bool cli_receive_smb(struct cli_state *cli) * Set bad sig but don't close fd. */ cli->smb_rw_error = SMB_READ_BAD_SIG; - return True; + return true; } DEBUG(0, ("SMB Signature verification failed on incoming packet!\n")); cli->smb_rw_error = SMB_READ_BAD_SIG; close(cli->fd); cli->fd = -1; - return False; + return false; }; - return True; + return true; } /**************************************************************************** @@ -164,6 +179,7 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) /**************************************************************************** Read a smb readX header. + We can only use this if encryption and signing are off. ****************************************************************************/ bool cli_receive_smb_readX_header(struct cli_state *cli) @@ -171,7 +187,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) ssize_t len, offset; if (cli->fd == -1) - return False; + return false; again: @@ -199,7 +215,7 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) if (cli->oplock_handler) { int fnum = SVAL(cli->inbuf,smb_vwv2); unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); - if (!cli->oplock_handler(cli, fnum, level)) return False; + if (!cli->oplock_handler(cli, fnum, level)) return false; } /* try to prevent loops */ SCVAL(cli->inbuf,smb_com,0xFF); @@ -238,14 +254,14 @@ bool cli_receive_smb_readX_header(struct cli_state *cli) } } - return True; + return true; read_err: cli->smb_rw_error = SMB_READ_ERROR; close(cli->fd); cli->fd = -1; - return False; + return false; } static ssize_t write_socket(int fd, const char *buf, size_t len) @@ -272,32 +288,54 @@ bool cli_send_smb(struct cli_state *cli) size_t len; size_t nwritten=0; ssize_t ret; + char *buf_out = cli->outbuf; + bool enc_on = cli_encryption_on(cli); /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) - return False; + return false; cli_calculate_sign_mac(cli); - len = smb_len(cli->outbuf) + 4; + if (enc_on) { + NTSTATUS status = cli_encrypt_message(cli, &buf_out); + if (!NT_STATUS_IS_OK(status)) { + close(cli->fd); + cli->fd = -1; + cli->smb_rw_error = SMB_WRITE_ERROR; + DEBUG(0,("Error in encrypting client message. Error %s\n", + nt_errstr(status) )); + return false; + } + } + + len = smb_len(buf_out) + 4; while (nwritten < len) { - ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten); + ret = write_socket(cli->fd,buf_out+nwritten,len - nwritten); if (ret <= 0) { + if (enc_on) { + cli_free_enc_buffer(cli, buf_out); + } close(cli->fd); cli->fd = -1; cli->smb_rw_error = SMB_WRITE_ERROR; DEBUG(0,("Error writing %d bytes to client. %d (%s)\n", (int)len,(int)ret, strerror(errno) )); - return False; + return false; } nwritten += ret; } + + if (enc_on) { + cli_free_enc_buffer(cli, buf_out); + } + /* Increment the mid so we can tell between responses. */ cli->mid++; if (!cli->mid) cli->mid++; - return True; + return true; } /**************************************************************************** @@ -347,7 +385,7 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, DEBUG(0,("Error writing %d extradata " "bytes to client. %d (%s)\n", (int)extradata,(int)ret, strerror(errno) )); - return False; + return false; } nwritten += ret; } @@ -409,7 +447,7 @@ void cli_init_creds(struct cli_state *cli, const char *username, const char *dom fstrcpy(cli->user_name, username); pwd_set_cleartext(&cli->pwd, password); if (!*username) { - cli->pwd.null_pwd = True; + cli->pwd.null_pwd = true; } DEBUG(10,("cli_init_creds: user %s domain %s\n", cli->user_name, cli->domain)); @@ -424,16 +462,16 @@ void cli_setup_signing_state(struct cli_state *cli, int signing_state) if (signing_state == Undefined) return; - if (signing_state == False) { - cli->sign_info.allow_smb_signing = False; - cli->sign_info.mandatory_signing = False; + if (signing_state == false) { + cli->sign_info.allow_smb_signing = false; + cli->sign_info.mandatory_signing = false; return; } - cli->sign_info.allow_smb_signing = True; + cli->sign_info.allow_smb_signing = true; if (signing_state == Required) - cli->sign_info.mandatory_signing = True; + cli->sign_info.mandatory_signing = true; } /**************************************************************************** @@ -470,7 +508,7 @@ struct cli_state *cli_initialise(void) cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; - cli->case_sensitive = False; + cli->case_sensitive = false; cli->smb_rw_error = SMB_READ_OK; cli->use_spnego = lp_client_use_spnego(); @@ -481,13 +519,13 @@ struct cli_state *cli_initialise(void) client routines using DOS errors instead of STATUS32 ones. This intended only as a temporary hack. */ if (getenv("CLI_FORCE_DOSERR")) - cli->force_dos_errors = True; + cli->force_dos_errors = true; if (lp_client_signing()) - cli->sign_info.allow_smb_signing = True; + cli->sign_info.allow_smb_signing = true; if (lp_client_signing() == Required) - cli->sign_info.mandatory_signing = True; + cli->sign_info.mandatory_signing = true; if (!cli->outbuf || !cli->inbuf) goto error; @@ -522,7 +560,7 @@ struct cli_state *cli_initialise(void) /**************************************************************************** External interface. Close an open named pipe over SMB. Free any authentication data. - Returns False if the cli_close call failed. + Returns false if the cli_close call failed. ****************************************************************************/ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) @@ -530,7 +568,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) bool ret; if (!cli) { - return False; + return false; } ret = cli_close(cli->cli, cli->fnum); @@ -650,15 +688,15 @@ bool cli_send_keepalive(struct cli_state *cli) { if (cli->fd == -1) { DEBUG(3, ("cli_send_keepalive: fd == -1\n")); - return False; + return false; } if (!send_keepalive(cli->fd)) { close(cli->fd); cli->fd = -1; DEBUG(0,("Error sending keepalive packet to client.\n")); - return False; + return false; } - return True; + return true; } /**************************************************************************** @@ -674,7 +712,7 @@ bool cli_echo(struct cli_state *cli, uint16 num_echos, SMB_ASSERT(length < 1024); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,length,True); + cli_set_message(cli->outbuf,1,length,true); SCVAL(cli->outbuf,smb_com,SMBecho); SSVAL(cli->outbuf,smb_tid,65535); SSVAL(cli->outbuf,smb_vwv0,num_echos); @@ -689,13 +727,13 @@ bool cli_echo(struct cli_state *cli, uint16 num_echos, for (i=0; ioutbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 0, true); + cli_set_message(cli->outbuf,1, 0, true); SCVAL(cli->outbuf,smb_com,SMBmv); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -470,7 +470,7 @@ bool cli_ntrename(struct cli_state *cli, const char *fname_src, const char *fnam memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 4, 0, true); + cli_set_message(cli->outbuf, 4, 0, true); SCVAL(cli->outbuf,smb_com,SMBntrename); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -512,7 +512,7 @@ bool cli_nt_hardlink(struct cli_state *cli, const char *fname_src, const char *f memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 4, 0, true); + cli_set_message(cli->outbuf, 4, 0, true); SCVAL(cli->outbuf,smb_com,SMBntrename); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -554,7 +554,7 @@ bool cli_unlink_full(struct cli_state *cli, const char *fname, uint16 attrs) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1, 0, true); + cli_set_message(cli->outbuf,1, 0, true); SCVAL(cli->outbuf,smb_com,SMBunlink); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -600,7 +600,7 @@ bool cli_mkdir(struct cli_state *cli, const char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 0, true); + cli_set_message(cli->outbuf,0, 0, true); SCVAL(cli->outbuf,smb_com,SMBmkdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -636,7 +636,7 @@ bool cli_rmdir(struct cli_state *cli, const char *dname) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0, 0, true); + cli_set_message(cli->outbuf,0, 0, true); SCVAL(cli->outbuf,smb_com,SMBrmdir); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -719,7 +719,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,24,0, true); + cli_set_message(cli->outbuf,24,0, true); SCVAL(cli->outbuf,smb_com,SMBntcreateX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -815,7 +815,7 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,15,0, true); + cli_set_message(cli->outbuf,15,0, true); SCVAL(cli->outbuf,smb_com,SMBopenX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -863,7 +863,7 @@ bool cli_close(struct cli_state *cli, int fnum) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,3,0,True); + cli_set_message(cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -896,7 +896,7 @@ NTSTATUS cli_locktype(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,0,True); + cli_set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -948,7 +948,7 @@ bool cli_lock(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,0,True); + cli_set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1001,7 +1001,7 @@ bool cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,0,True); + cli_set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1053,7 +1053,7 @@ bool cli_lock64(struct cli_state *cli, int fnum, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0', smb_size); - set_message(cli->outbuf,8,0,True); + cli_set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1108,7 +1108,7 @@ bool cli_unlock64(struct cli_state *cli, int fnum, SMB_BIG_UINT offset, SMB_BIG_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,0,True); + cli_set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBlockingX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1255,7 +1255,7 @@ bool cli_getattrE(struct cli_state *cli, int fd, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); + cli_set_message(cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBgetattrE); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1307,7 +1307,7 @@ bool cli_getatr(struct cli_state *cli, const char *fname, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + cli_set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBgetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1359,7 +1359,7 @@ bool cli_setattrE(struct cli_state *cli, int fd, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,7,0,True); + cli_set_message(cli->outbuf,7,0,True); SCVAL(cli->outbuf,smb_com,SMBsetattrE); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1398,7 +1398,7 @@ bool cli_setatr(struct cli_state *cli, const char *fname, uint16 attr, time_t t) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,8,0,True); + cli_set_message(cli->outbuf,8,0,True); SCVAL(cli->outbuf,smb_com,SMBsetatr); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1452,7 +1452,7 @@ bool cli_chkpath(struct cli_state *cli, const char *path) } memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + cli_set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBcheckpath); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1483,7 +1483,7 @@ bool cli_chkpath(struct cli_state *cli, const char *path) bool cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail) { memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + cli_set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBdskattr); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -1512,7 +1512,7 @@ int cli_ctemp(struct cli_state *cli, const char *path, char **tmp_path) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,3,0,True); + cli_set_message(cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBctemp); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -1565,7 +1565,7 @@ NTSTATUS cli_raw_ioctl(struct cli_state *cli, int fnum, uint32 code, DATA_BLOB * memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf, 3, 0, True); + cli_set_message(cli->outbuf, 3, 0, True); SCVAL(cli->outbuf,smb_com,SMBioctl); cli_setup_packet(cli); diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 1a75d144b2..107613c618 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. FS info functions Copyright (C) Stefan (metze) Metzmacher 2003 + Copyright (C) Jeremy Allison 2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -301,3 +302,335 @@ cleanup: return ret; } + +/****************************************************************************** + Send/receive the request encryption blob. +******************************************************************************/ + +static NTSTATUS enc_blob_send_receive(struct cli_state *cli, DATA_BLOB *in, DATA_BLOB *out, DATA_BLOB *param_out) +{ + uint16 setup; + char param[4]; + char *rparam=NULL, *rdata=NULL; + unsigned int rparam_count=0, rdata_count=0; + NTSTATUS status = NT_STATUS_OK; + + setup = TRANSACT2_SETFSINFO; + + SSVAL(param,0,0); + SSVAL(param,2,SMB_REQUEST_TRANSPORT_ENCRYPTION); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, + 0, 0, + &setup, 1, 0, + param, 4, 0, + (char *)in->data, in->length, CLI_BUFFER_SIZE)) { + status = cli_nt_error(cli); + goto out; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, &rparam_count, + &rdata, &rdata_count)) { + status = cli_nt_error(cli); + goto out; + } + + if (cli_is_error(cli)) { + status = cli_nt_error(cli); + if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto out; + } + } + + *out = data_blob(rdata, rdata_count); + *param_out = data_blob(rparam, rparam_count); + + out: + + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return status; +} + +/****************************************************************************** + Make a client state struct. +******************************************************************************/ + +static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type smb_enc_type) +{ + struct smb_trans_enc_state *es = NULL; + es = SMB_MALLOC_P(struct smb_trans_enc_state); + if (!es) { + return NULL; + } + ZERO_STRUCTP(es); + es->smb_enc_type = smb_enc_type; + + if (smb_enc_type == SMB_TRANS_ENC_GSS) { +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss); + if (!es->s.gss_state) { + SAFE_FREE(es); + return NULL; + } + ZERO_STRUCTP(es->s.gss_state); +#else + DEBUG(0,("make_cli_enc_state: no krb5 compiled.\n")); + SAFE_FREE(es); + return NULL; +#endif + } + return es; +} + +/****************************************************************************** + Start a raw ntlmssp encryption. +******************************************************************************/ + +NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli, + const char *user, + const char *pass, + const char *domain) +{ + DATA_BLOB blob_in = data_blob_null; + DATA_BLOB blob_out = data_blob_null; + DATA_BLOB param_out = data_blob_null; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_NTLM); + + if (!es) { + return NT_STATUS_NO_MEMORY; + } + status = ntlmssp_client_start(&es->s.ntlmssp_state); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + + ntlmssp_want_feature(es->s.ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY); + es->s.ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL); + + if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->s.ntlmssp_state, user))) { + goto fail; + } + if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->s.ntlmssp_state, domain))) { + goto fail; + } + if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->s.ntlmssp_state, pass))) { + goto fail; + } + + do { + status = ntlmssp_update(es->s.ntlmssp_state, blob_in, &blob_out); + data_blob_free(&blob_in); + data_blob_free(¶m_out); + if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) || NT_STATUS_IS_OK(status)) { + NTSTATUS trans_status = enc_blob_send_receive(cli, + &blob_out, + &blob_in, + ¶m_out); + if (!NT_STATUS_EQUAL(trans_status, + NT_STATUS_MORE_PROCESSING_REQUIRED) && + !NT_STATUS_IS_OK(trans_status)) { + status = trans_status; + } else { + if (param_out.length == 2) { + es->enc_ctx_num = SVAL(param_out.data, 0); + } + } + } + data_blob_free(&blob_out); + } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); + + data_blob_free(&blob_in); + + if (NT_STATUS_IS_OK(status)) { + /* Replace the old state, if any. */ + if (cli->trans_enc_state) { + common_free_encryption_state(&cli->trans_enc_state); + } + cli->trans_enc_state = es; + cli->trans_enc_state->enc_on = True; + es = NULL; + } + + fail: + + common_free_encryption_state(&es); + return status; +} + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + +#ifndef SMB_GSS_REQUIRED_FLAGS +#define SMB_GSS_REQUIRED_FLAGS (GSS_C_CONF_FLAG|GSS_C_INTEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG) +#endif + +/****************************************************************************** + Get client gss blob to send to a server. +******************************************************************************/ + +static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, + const char *service, + const char *host, + NTSTATUS status_in, + DATA_BLOB spnego_blob_in, + DATA_BLOB *p_blob_out) +{ + const char *krb_mechs[] = {OID_KERBEROS5, NULL}; + OM_uint32 ret; + OM_uint32 min; + gss_name_t srv_name; + gss_buffer_desc input_name; + gss_buffer_desc *p_tok_in; + gss_buffer_desc tok_out, tok_in; + DATA_BLOB blob_out = data_blob_null; + DATA_BLOB blob_in = data_blob_null; + char *host_princ_s = NULL; + OM_uint32 ret_flags = 0; + NTSTATUS status = NT_STATUS_OK; + + gss_OID_desc nt_hostbased_service = + {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")}; + + memset(&tok_out, '\0', sizeof(tok_out)); + + /* Get a ticket for the service@host */ + asprintf(&host_princ_s, "%s@%s", service, host); + if (host_princ_s == NULL) { + return NT_STATUS_NO_MEMORY; + } + + input_name.value = host_princ_s; + input_name.length = strlen(host_princ_s) + 1; + + ret = gss_import_name(&min, + &input_name, + &nt_hostbased_service, + &srv_name); + + if (ret != GSS_S_COMPLETE) { + SAFE_FREE(host_princ_s); + return map_nt_error_from_gss(ret, min); + } + + if (spnego_blob_in.length == 0) { + p_tok_in = GSS_C_NO_BUFFER; + } else { + /* Remove the SPNEGO wrapper */ + if (!spnego_parse_auth_response(spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) { + status = NT_STATUS_UNSUCCESSFUL; + goto fail; + } + tok_in.value = blob_in.data; + tok_in.length = blob_in.length; + p_tok_in = &tok_in; + } + + ret = gss_init_sec_context(&min, + GSS_C_NO_CREDENTIAL, /* Use our default cred. */ + &es->s.gss_state->gss_ctx, + srv_name, + GSS_C_NO_OID, /* default OID. */ + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, + GSS_C_INDEFINITE, /* requested ticket lifetime. */ + NULL, /* no channel bindings */ + p_tok_in, + NULL, /* ignore mech type */ + &tok_out, + &ret_flags, + NULL); /* ignore time_rec */ + + status = map_nt_error_from_gss(ret, min); + if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, min); + DEBUG(10,("make_cli_gss_blob: gss_init_sec_context failed with %s\n", + ads_errstr(adss))); + goto fail; + } + + if ((ret_flags & SMB_GSS_REQUIRED_FLAGS) != SMB_GSS_REQUIRED_FLAGS) { + status = NT_STATUS_ACCESS_DENIED; + } + + blob_out = data_blob(tok_out.value, tok_out.length); + + /* Wrap in an SPNEGO wrapper */ + *p_blob_out = gen_negTokenTarg(krb_mechs, blob_out); + + fail: + + data_blob_free(&blob_out); + data_blob_free(&blob_in); + SAFE_FREE(host_princ_s); + gss_release_name(&min, &srv_name); + if (tok_out.value) { + gss_release_buffer(&min, &tok_out); + } + return status; +} + +/****************************************************************************** + Start a SPNEGO gssapi encryption context. +******************************************************************************/ + +NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) +{ + DATA_BLOB blob_recv = data_blob_null; + DATA_BLOB blob_send = data_blob_null; + DATA_BLOB param_out = data_blob_null; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + fstring fqdn; + const char *servicename; + struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_GSS); + + if (!es) { + return NT_STATUS_NO_MEMORY; + } + + name_to_fqdn(fqdn, cli->desthost); + strlower_m(fqdn); + + servicename = "cifs"; + status = make_cli_gss_blob(es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); + if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { + servicename = "host"; + status = make_cli_gss_blob(es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send); + if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) { + goto fail; + } + } + + do { + data_blob_free(&blob_recv); + status = enc_blob_send_receive(cli, &blob_send, &blob_recv, ¶m_out); + if (param_out.length == 2) { + es->enc_ctx_num = SVAL(param_out.data, 0); + } + data_blob_free(&blob_send); + status = make_cli_gss_blob(es, servicename, fqdn, status, blob_recv, &blob_send); + } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)); + data_blob_free(&blob_recv); + + if (NT_STATUS_IS_OK(status)) { + /* Replace the old state, if any. */ + if (cli->trans_enc_state) { + common_free_encryption_state(&cli->trans_enc_state); + } + cli->trans_enc_state = es; + cli->trans_enc_state->enc_on = True; + es = NULL; + } + + fail: + + common_free_encryption_state(&es); + return status; +} +#else +NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) +{ + return NT_STATUS_NOT_SUPPORTED; +} +#endif diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2e4c360507..d5c7db09e9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -521,7 +521,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + cli_set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBsearch); @@ -581,7 +581,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + cli_set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 13ef1d43d4..00c25aa725 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -29,7 +29,7 @@ int cli_message_start_build(struct cli_state *cli, const char *host, const char /* construct a SMBsendstrt command */ memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,0,0,True); + cli_set_message(cli->outbuf,0,0,True); SCVAL(cli->outbuf,smb_com,SMBsendstrt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -75,7 +75,7 @@ int cli_message_text_build(struct cli_state *cli, const char *msg, int len, int char *p; memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); + cli_set_message(cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBsendtxt); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -132,7 +132,7 @@ int cli_message_end_build(struct cli_state *cli, int grp) char *p; memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,1,0,True); + cli_set_message(cli->outbuf,1,0,True); SCVAL(cli->outbuf,smb_com,SMBsendend); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c index 2e54f5a781..ef8b396461 100644 --- a/source3/libsmb/clioplock.c +++ b/source3/libsmb/clioplock.c @@ -32,7 +32,7 @@ bool cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) cli->outbuf = buf; memset(buf,'\0',smb_size); - set_message(buf,8,0,True); + cli_set_message(buf,8,0,True); SCVAL(buf,smb_com,SMBlockingX); SSVAL(buf,smb_tid, cli->cnum); diff --git a/source3/libsmb/cliprint.c b/source3/libsmb/cliprint.c index 7fbdb97c01..223ddb4186 100644 --- a/source3/libsmb/cliprint.c +++ b/source3/libsmb/cliprint.c @@ -195,7 +195,7 @@ int cli_spl_open(struct cli_state *cli, const char *fname, int flags, int share_ memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,15,0,True); + cli_set_message(cli->outbuf,15,0,True); SCVAL(cli->outbuf,smb_com,SMBsplopen); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -242,7 +242,7 @@ bool cli_spl_close(struct cli_state *cli, int fnum) memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,3,0,True); + cli_set_message(cli->outbuf,3,0,True); SCVAL(cli->outbuf,smb_com,SMBsplclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index d77875bae5..0b33e43563 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -34,7 +34,7 @@ static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset, if ((SMB_BIG_UINT)offset >> 32) bigoffset = True; - set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); + cli_set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); SCVAL(cli->outbuf,smb_com,SMBreadX); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -65,8 +65,8 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ size_t size2; size_t readsize; ssize_t total = 0; - /* We can only do direct reads if not signing. */ - bool direct_reads = !client_is_signing_on(cli); + /* We can only do direct reads if not signing or encrypting. */ + bool direct_reads = !client_is_signing_on(cli) && !cli_encryption_on(cli); if (size == 0) return 0; @@ -76,7 +76,9 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ * rounded down to a multiple of 1024. */ - if (client_is_signing_on(cli) == False && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { + if (client_is_signing_on(cli) == false && + cli_encryption_on(cli) == false && + (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { readsize = CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; } else if (cli->capabilities & CAP_LARGE_READX) { if (cli->is_samba) { @@ -203,7 +205,7 @@ static bool cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,10,0,True); + cli_set_message(cli->outbuf,10,0,True); SCVAL(cli->outbuf,smb_com,SMBreadbraw); SSVAL(cli->outbuf,smb_tid,cli->cnum); @@ -295,8 +297,8 @@ static bool cli_issue_write(struct cli_state *cli, { char *p; bool large_writex = false; - /* We can only do direct writes if not signing. */ - bool direct_writes = !client_is_signing_on(cli); + /* We can only do direct writes if not signing and not encrypting. */ + bool direct_writes = !client_is_signing_on(cli) && !cli_encryption_on(cli); if (!direct_writes && size + 1 > cli->bufsize) { cli->outbuf = (char *)SMB_REALLOC(cli->outbuf, size + 1024); @@ -319,9 +321,9 @@ static bool cli_issue_write(struct cli_state *cli, } if (large_writex) { - set_message(cli->outbuf,14,0,True); + cli_set_message(cli->outbuf,14,0,True); } else { - set_message(cli->outbuf,12,0,True); + cli_set_message(cli->outbuf,12,0,True); } SCVAL(cli->outbuf,smb_com,SMBwriteX); @@ -404,16 +406,17 @@ ssize_t cli_write(struct cli_state *cli, if (write_mode == 0 && !client_is_signing_on(cli) && + !cli_encryption_on(cli) && (cli->posix_capabilities & CIFS_UNIX_LARGE_WRITE_CAP) && (cli->capabilities & CAP_LARGE_FILES)) { /* Only do massive writes if we can do them direct - * with no signing - not on a pipe. */ + * with no signing or encrypting - not on a pipe. */ writesize = CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE; - } else if (cli->capabilities & CAP_LARGE_READX) { + } else if (cli->capabilities & CAP_LARGE_WRITEX) { if (cli->is_samba) { - writesize = CLI_SAMBA_MAX_LARGE_READX_SIZE; + writesize = CLI_SAMBA_MAX_LARGE_WRITEX_SIZE; } else { - writesize = CLI_WINDOWS_MAX_LARGE_READX_SIZE; + writesize = CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE; } } else { writesize = (cli->max_xmit - (smb_size+32)) & ~1023; @@ -471,7 +474,7 @@ ssize_t cli_smbwrite(struct cli_state *cli, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,5, 0,True); + cli_set_message(cli->outbuf,5, 0,True); SCVAL(cli->outbuf,smb_com,SMBwrite); SSVAL(cli->outbuf,smb_tid,cli->cnum); diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index a6f7f7fec1..bfb31fdb74 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -43,7 +43,7 @@ bool cli_send_trans(struct cli_state *cli, int trans, this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,14+lsetup,0,True); + cli_set_message(cli->outbuf,14+lsetup,0,True); SCVAL(cli->outbuf,smb_com,trans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); @@ -107,7 +107,7 @@ bool cli_send_trans(struct cli_state *cli, int trans, this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); + cli_set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); outparam = smb_buf(cli->outbuf); @@ -368,7 +368,7 @@ bool cli_send_nt_trans(struct cli_state *cli, this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam)); memset(cli->outbuf,'\0',smb_size); - set_message(cli->outbuf,19+lsetup,0,True); + cli_set_message(cli->outbuf,19+lsetup,0,True); SCVAL(cli->outbuf,smb_com,SMBnttrans); SSVAL(cli->outbuf,smb_tid, cli->cnum); cli_setup_packet(cli); @@ -424,7 +424,7 @@ bool cli_send_nt_trans(struct cli_state *cli, this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); - set_message(cli->outbuf,18,0,True); + cli_set_message(cli->outbuf,18,0,True); SCVAL(cli->outbuf,smb_com,SMBnttranss); /* XXX - these should probably be aligned */ diff --git a/source3/libsmb/errormap.c b/source3/libsmb/errormap.c index ce826ae999..4ec30f7e17 100644 --- a/source3/libsmb/errormap.c +++ b/source3/libsmb/errormap.c @@ -1502,3 +1502,108 @@ WERROR ntstatus_to_werror(NTSTATUS error) /* a lame guess */ return W_ERROR(NT_STATUS_V(error) & 0xffff); } + +#if defined(HAVE_GSSAPI) +/******************************************************************************* + Map between gssapi errors and NT status. I made these up :-(. JRA. +*******************************************************************************/ + +static const struct { + unsigned long gss_err; + NTSTATUS ntstatus; +} gss_to_ntstatus_errormap[] = { +#if defined(GSS_S_CALL_INACCESSIBLE_READ) + {GSS_S_CALL_INACCESSIBLE_READ, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_CALL_INACCESSIBLE_WRITE) + {GSS_S_CALL_INACCESSIBLE_WRITE, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_CALL_BAD_STRUCTURE) + {GSS_S_CALL_BAD_STRUCTURE, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_MECH) + {GSS_S_BAD_MECH, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_NAME) + {GSS_S_BAD_NAME, NT_STATUS_INVALID_ACCOUNT_NAME}, +#endif +#if defined(GSS_S_BAD_NAMETYPE) + {GSS_S_BAD_NAMETYPE, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_BINDINGS) + {GSS_S_BAD_BINDINGS, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_BAD_STATUS) + {GSS_S_BAD_STATUS, NT_STATUS_UNSUCCESSFUL}, +#endif +#if defined(GSS_S_BAD_SIG) + {GSS_S_BAD_SIG, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_NO_CRED) + {GSS_S_NO_CRED, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_NO_CONTEXT) + {GSS_S_NO_CONTEXT, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_DEFECTIVE_TOKEN) + {GSS_S_DEFECTIVE_TOKEN, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_DEFECTIVE_CREDENTIAL) + {GSS_S_DEFECTIVE_CREDENTIAL, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_CREDENTIALS_EXPIRED) + {GSS_S_CREDENTIALS_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, +#endif +#if defined(GSS_S_CONTEXT_EXPIRED) + {GSS_S_CONTEXT_EXPIRED, NT_STATUS_PASSWORD_EXPIRED}, +#endif +#if defined(GSS_S_BAD_QOP) + {GSS_S_BAD_QOP, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_UNAUTHORIZED) + {GSS_S_UNAUTHORIZED, NT_STATUS_ACCESS_DENIED}, +#endif +#if defined(GSS_S_UNAVAILABLE) + {GSS_S_UNAVAILABLE, NT_STATUS_UNSUCCESSFUL}, +#endif +#if defined(GSS_S_DUPLICATE_ELEMENT) + {GSS_S_DUPLICATE_ELEMENT, NT_STATUS_INVALID_PARAMETER}, +#endif +#if defined(GSS_S_NAME_NOT_MN) + {GSS_S_NAME_NOT_MN, NT_STATUS_INVALID_PARAMETER}, +#endif + { 0, NT_STATUS_OK } +}; + +/********************************************************************* + Map an NT error code from a gssapi error code. +*********************************************************************/ + +NTSTATUS map_nt_error_from_gss(uint32 gss_maj, uint32 minor) +{ + int i = 0; + + if (gss_maj == GSS_S_COMPLETE) { + return NT_STATUS_OK; + } + + if (gss_maj == GSS_S_CONTINUE_NEEDED) { + return NT_STATUS_MORE_PROCESSING_REQUIRED; + } + + if (gss_maj == GSS_S_FAILURE) { + return map_nt_error_from_unix((int)minor); + } + + /* Look through list */ + while(gss_to_ntstatus_errormap[i].gss_err != 0) { + if (gss_to_ntstatus_errormap[i].gss_err == gss_maj) { + return gss_to_ntstatus_errormap[i].ntstatus; + } + i++; + } + + /* Default return */ + return NT_STATUS_ACCESS_DENIED; +} +#endif diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c new file mode 100644 index 0000000000..055a27d05a --- /dev/null +++ b/source3/libsmb/smb_seal.c @@ -0,0 +1,496 @@ +/* + Unix SMB/CIFS implementation. + SMB Transport encryption (sealing) code. + Copyright (C) Jeremy Allison 2007. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +/****************************************************************************** + Pull out the encryption context for this packet. 0 means global context. +******************************************************************************/ + +NTSTATUS get_enc_ctx_num(const char *buf, uint16 *p_enc_ctx_num) +{ + if (smb_len(buf) < 8) { + return NT_STATUS_INVALID_BUFFER_SIZE; + } + + if (buf[4] == (char)0xFF) { + if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') { + /* Not an encrypted buffer. */ + return NT_STATUS_NOT_FOUND; + } + if (buf[5] == 'E') { + *p_enc_ctx_num = SVAL(buf,6); + return NT_STATUS_OK; + } + } + return NT_STATUS_INVALID_NETWORK_RESPONSE; +} + +/****************************************************************************** + Generic code for client and server. + Is encryption turned on ? +******************************************************************************/ + +bool common_encryption_on(struct smb_trans_enc_state *es) +{ + return ((es != NULL) && es->enc_on); +} + +/****************************************************************************** + Generic code for client and server. + NTLM decrypt an incoming buffer. + Abartlett tells me that SSPI puts the signature first before the encrypted + output, so cope with the same for compatibility. +******************************************************************************/ + +NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) +{ + NTSTATUS status; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + size_t data_len; + char *inbuf; + DATA_BLOB sig; + + if (buf_len < 8 + NTLMSSP_SIG_SIZE) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + inbuf = (char *)smb_xmemdup(buf, buf_len); + + /* Adjust for the signature. */ + data_len = buf_len - 8 - NTLMSSP_SIG_SIZE; + + /* Point at the signature. */ + sig = data_blob_const(inbuf+8, NTLMSSP_SIG_SIZE); + + status = ntlmssp_unseal_packet(ntlmssp_state, + (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'E' */ + data_len, + (unsigned char *)inbuf + 8 + NTLMSSP_SIG_SIZE, + data_len, + &sig); + + if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(inbuf); + return status; + } + + memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); + + /* Reset the length. */ + _smb_setlen(buf,data_len + 4); + + SAFE_FREE(inbuf); + return NT_STATUS_OK; +} + +/****************************************************************************** + Generic code for client and server. + NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out. + Abartlett tells me that SSPI puts the signature first before the encrypted + output, so do the same for compatibility. +******************************************************************************/ + +NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, + uint16 enc_ctx_num, + char *buf, + char **ppbuf_out) +{ + NTSTATUS status; + char *buf_out; + size_t data_len = smb_len(buf) - 4; /* Ignore the 0xFF SMB bytes. */ + DATA_BLOB sig; + + *ppbuf_out = NULL; + + if (data_len == 0) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + /* + * We know smb_len can't return a value > 128k, so no int overflow + * check needed. + */ + + buf_out = SMB_XMALLOC_ARRAY(char, 8 + NTLMSSP_SIG_SIZE + data_len); + + /* Copy the data from the original buffer. */ + + memcpy(buf_out + 8 + NTLMSSP_SIG_SIZE, buf + 8, data_len); + + smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); + + sig = data_blob(NULL, NTLMSSP_SIG_SIZE); + + status = ntlmssp_seal_packet(ntlmssp_state, + (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' */ + data_len, + (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, + data_len, + &sig); + + if (!NT_STATUS_IS_OK(status)) { + data_blob_free(&sig); + SAFE_FREE(buf_out); + return status; + } + + /* First 16 data bytes are signature for SSPI compatibility. */ + memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); + *ppbuf_out = buf_out; + return NT_STATUS_OK; +} + +/****************************************************************************** + Generic code for client and server. + gss-api decrypt an incoming buffer. We insist that the size of the + unwrapped buffer must be smaller or identical to the incoming buffer. +******************************************************************************/ + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) +static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf) +{ + gss_ctx_id_t gss_ctx = gss_state->gss_ctx; + OM_uint32 ret = 0; + OM_uint32 minor = 0; + int flags_got = 0; + gss_buffer_desc in_buf, out_buf; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + + if (buf_len < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + in_buf.value = buf + 8; + in_buf.length = buf_len - 8; + + ret = gss_unwrap(&minor, + gss_ctx, + &in_buf, + &out_buf, + &flags_got, /* did we get sign+seal ? */ + (gss_qop_t *) NULL); + + if (ret != GSS_S_COMPLETE) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); + DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap failed. Error %s\n", + ads_errstr(adss) )); + return map_nt_error_from_gss(ret, minor); + } + + if (out_buf.length > in_buf.length) { + DEBUG(0,("common_gss_encrypt_buffer: gss_unwrap size (%u) too large (%u) !\n", + (unsigned int)out_buf.length, + (unsigned int)in_buf.length )); + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_INVALID_PARAMETER; + } + + memcpy(buf + 8, out_buf.value, out_buf.length); + _smb_setlen(buf, out_buf.length + 4); + + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_OK; +} + +/****************************************************************************** + Generic code for client and server. + gss-api encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. +******************************************************************************/ + +static NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, + uint16 enc_ctx_num, + char *buf, + char **ppbuf_out) +{ + gss_ctx_id_t gss_ctx = gss_state->gss_ctx; + OM_uint32 ret = 0; + OM_uint32 minor = 0; + int flags_got = 0; + gss_buffer_desc in_buf, out_buf; + size_t buf_len = smb_len(buf) + 4; /* Don't forget the 4 length bytes. */ + + *ppbuf_out = NULL; + + if (buf_len < 8) { + return NT_STATUS_BUFFER_TOO_SMALL; + } + + in_buf.value = buf + 8; + in_buf.length = buf_len - 8; + + ret = gss_wrap(&minor, + gss_ctx, + true, /* we want sign+seal. */ + GSS_C_QOP_DEFAULT, + &in_buf, + &flags_got, /* did we get sign+seal ? */ + &out_buf); + + if (ret != GSS_S_COMPLETE) { + ADS_STATUS adss = ADS_ERROR_GSS(ret, minor); + DEBUG(0,("common_gss_encrypt_buffer: gss_wrap failed. Error %s\n", + ads_errstr(adss) )); + return map_nt_error_from_gss(ret, minor); + } + + if (!flags_got) { + /* Sign+seal not supported. */ + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_NOT_SUPPORTED; + } + + /* Ya see - this is why I *hate* gss-api. I don't + * want to have to malloc another buffer of the + * same size + 8 bytes just to get a continuous + * header + buffer, but gss won't let me pass in + * a pre-allocated buffer. Bastards (and you know + * who you are....). I might fix this by + * going to "encrypt_and_send" passing in a file + * descriptor and doing scatter-gather write with + * TCP cork on Linux. But I shouldn't have to + * bother :-*(. JRA. + */ + + *ppbuf_out = (char *)SMB_MALLOC(out_buf.length + 8); /* We know this can't wrap. */ + if (!*ppbuf_out) { + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_NO_MEMORY; + } + + memcpy(*ppbuf_out+8, out_buf.value, out_buf.length); + smb_set_enclen(*ppbuf_out, out_buf.length + 4, enc_ctx_num); + + gss_release_buffer(&minor, &out_buf); + return NT_STATUS_OK; +} +#endif + +/****************************************************************************** + Generic code for client and server. + Encrypt an outgoing buffer. Return the alloced encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, char **buf_out) +{ + if (!common_encryption_on(es)) { + /* Not encrypting. */ + *buf_out = buffer; + return NT_STATUS_OK; + } + + switch (es->smb_enc_type) { + case SMB_TRANS_ENC_NTLM: + return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, es->enc_ctx_num, buffer, buf_out); +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + case SMB_TRANS_ENC_GSS: + return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out); +#endif + default: + return NT_STATUS_NOT_SUPPORTED; + } +} + +/****************************************************************************** + Generic code for client and server. + Decrypt an incoming SMB buffer. Replaces the data within it. + New data must be less than or equal to the current length. +******************************************************************************/ + +NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf) +{ + if (!common_encryption_on(es)) { + /* Not decrypting. */ + return NT_STATUS_OK; + } + + switch (es->smb_enc_type) { + case SMB_TRANS_ENC_NTLM: + return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf); +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + case SMB_TRANS_ENC_GSS: + return common_gss_decrypt_buffer(es->s.gss_state, buf); +#endif + default: + return NT_STATUS_NOT_SUPPORTED; + } +} + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) +/****************************************************************************** + Shutdown a gss encryption state. +******************************************************************************/ + +static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state) +{ + OM_uint32 minor = 0; + struct smb_tran_enc_state_gss *gss_state = *pp_gss_state; + + if (gss_state->creds != GSS_C_NO_CREDENTIAL) { + gss_release_cred(&minor, &gss_state->creds); + } + if (gss_state->gss_ctx != GSS_C_NO_CONTEXT) { + gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL); + } + SAFE_FREE(*pp_gss_state); +} +#endif + +/****************************************************************************** + Shutdown an encryption state. +******************************************************************************/ + +void common_free_encryption_state(struct smb_trans_enc_state **pp_es) +{ + struct smb_trans_enc_state *es = *pp_es; + + if (es == NULL) { + return; + } + + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + if (es->s.ntlmssp_state) { + ntlmssp_end(&es->s.ntlmssp_state); + } + } +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { + /* Free the gss context handle. */ + if (es->s.gss_state) { + common_free_gss_state(&es->s.gss_state); + } + } +#endif + SAFE_FREE(es); + *pp_es = NULL; +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void common_free_enc_buffer(struct smb_trans_enc_state *es, char *buf) +{ + if (!common_encryption_on(es)) { + return; + } + + if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) { + SAFE_FREE(buf); + return; + } + +#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + if (es->smb_enc_type == SMB_TRANS_ENC_GSS) { + OM_uint32 min; + gss_buffer_desc rel_buf; + rel_buf.value = buf; + rel_buf.length = smb_len(buf) + 4; + gss_release_buffer(&min, &rel_buf); + } +#endif +} + +/****************************************************************************** + Client side encryption. +******************************************************************************/ + +/****************************************************************************** + Is client encryption on ? +******************************************************************************/ + +bool cli_encryption_on(struct cli_state *cli) +{ + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ + return common_encryption_on(cli->trans_enc_state); +} + +/****************************************************************************** + Shutdown a client encryption state. +******************************************************************************/ + +void cli_free_encryption_context(struct cli_state *cli) +{ + common_free_encryption_state(&cli->trans_enc_state); +} + +/****************************************************************************** + Free an encryption-allocated buffer. +******************************************************************************/ + +void cli_free_enc_buffer(struct cli_state *cli, char *buf) +{ + /* We know this is an smb buffer, and we + * didn't malloc, only copy, for a keepalive, + * so ignore session keepalives. */ + + if(CVAL(buf,0) == SMBkeepalive) { + return; + } + + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ + common_free_enc_buffer(cli->trans_enc_state, buf); +} + +/****************************************************************************** + Decrypt an incoming buffer. +******************************************************************************/ + +NTSTATUS cli_decrypt_message(struct cli_state *cli) +{ + NTSTATUS status; + uint16 enc_ctx_num; + + /* Ignore session keepalives. */ + if(CVAL(cli->inbuf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + + status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { + return NT_STATUS_INVALID_HANDLE; + } + + return common_decrypt_buffer(cli->trans_enc_state, cli->inbuf); +} + +/****************************************************************************** + Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. +******************************************************************************/ + +NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) +{ + /* Ignore session keepalives. */ + if(CVAL(cli->outbuf,0) == SMBkeepalive) { + return NT_STATUS_OK; + } + + /* If we supported multiple encrytion contexts + * here we'd look up based on tid. + */ + return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); +} -- cgit From 3a52874815b2b58f361ef4eb104f0bebd0cdb6ae Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:17:36 -0800 Subject: Encryption works better when you add the client decrypt code :-). Jeremy. (This used to be commit d67b2634068be9c69082a2b8c22c831aba371cd9) --- source3/libsmb/clientgen.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index da225ebc24..ecef293d07 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -86,6 +86,17 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) break; } } + + if (cli_encryption_on(cli)) { + NTSTATUS status = cli_decrypt_message(cli); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("SMB decryption failed on incoming packet! Error %s\n", + nt_errstr(status))); + cli->smb_rw_error = SMB_READ_BAD_DECRYPT; + return -1; + } + } + show_msg(cli->inbuf); return len; } -- cgit From 533d6f617efc4dfe1e145785cb9736df07671bdf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Dec 2007 17:02:34 +0100 Subject: Remove static zeros (This used to be commit dbcc213710a9af31b6094d4741a6f68f573dcdad) --- source3/libsmb/ntlm_check.c | 5 ++++- source3/libsmb/ntlmssp.c | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index f8ed044f8a..ae10d7373d 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -182,7 +182,10 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) { - static const unsigned char zeros[8] = { 0, }; + unsigned char zeros[8]; + + ZERO_STRUCT(zeros); + if (nt_pw == NULL) { DEBUG(3,("ntlm_password_check: NO NT password stored for user %s.\n", username)); diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index ed08e8102b..35c20ed647 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -823,7 +823,8 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state, session_key.data); DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n")); } else { - static const uint8 zeros[24] = { 0, }; + uint8 zeros[24]; + ZERO_STRUCT(zeros); session_key = data_blob_talloc( ntlmssp_state->mem_ctx, NULL, 16); if (session_key.data == NULL) { @@ -1066,9 +1067,11 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state, } if (!ntlmssp_state->nt_hash || !ntlmssp_state->lm_hash) { - static const uchar zeros[16] = { 0, }; + uchar zeros[16]; /* do nothing - blobs are zero length */ + ZERO_STRUCT(zeros); + /* session key is all zeros */ session_key = data_blob_talloc(ntlmssp_state->mem_ctx, zeros, 16); -- cgit From a59280792cab616f5b269960ab68bc44ccc1fd38 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Dec 2007 22:16:31 +0100 Subject: Remove tiny code duplication sid_size did the same as ndr_size_dom_sid (This used to be commit 8aec5d09ba023413bd8ecbdfbc7d23904df94389) --- source3/libsmb/cliquota.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliquota.c b/source3/libsmb/cliquota.c index 206576f040..f369d28dff 100644 --- a/source3/libsmb/cliquota.c +++ b/source3/libsmb/cliquota.c @@ -150,7 +150,7 @@ bool cli_get_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUC SIVAL(params, 8,0x00000000); SIVAL(params,12,0x00000024); - sid_len = sid_size(&pqt->sid); + sid_len = ndr_size_dom_sid(&pqt->sid, 0); data_len = sid_len+8; SIVAL(data, 0, 0x00000000); SIVAL(data, 4, sid_len); @@ -213,7 +213,7 @@ bool cli_set_user_quota(struct cli_state *cli, int quota_fnum, SMB_NTQUOTA_STRUC SSVAL(params,0,quota_fnum); - sid_len = sid_size(&pqt->sid); + sid_len = ndr_size_dom_sid(&pqt->sid, 0); SIVAL(data,0,0); SIVAL(data,4,sid_len); SBIG_UINT(data, 8,(SMB_BIG_UINT)0); -- cgit From 240391be5345aef88a25c1221942202ba33588b8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Dec 2007 22:47:03 +0100 Subject: Make use of [un]marshall_sec_desc (This used to be commit 54576733d6c0511dc7379f964b1cb035913b7c8d) --- source3/libsmb/clisecdesc.c | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index 46a6609415..adc6fba9af 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -28,9 +28,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, char param[8]; char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; - prs_struct pd; - bool pd_initialized = False; SEC_DESC *psd = NULL; + NTSTATUS status; SIVAL(param, 0, fnum); SIVAL(param, 4, 0x7); @@ -56,15 +55,12 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, if (cli_is_error(cli)) goto cleanup; - if (!prs_init(&pd, rdata_count, mem_ctx, UNMARSHALL)) { - goto cleanup; - } - pd_initialized = True; - prs_copy_data_in(&pd, rdata, rdata_count); - prs_set_offset(&pd,0); + status = unmarshall_sec_desc(mem_ctx, (uint8 *)rdata, rdata_count, + &psd); - if (!sec_io_desc("sd data", &psd, &pd, 1)) { - DEBUG(1,("Failed to parse secdesc\n")); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("unmarshall_sec_desc failed: %s\n", + nt_errstr(status))); goto cleanup; } @@ -73,8 +69,6 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, SAFE_FREE(rparam); SAFE_FREE(rdata); - if (pd_initialized) - prs_mem_free(&pd); return psd; } @@ -87,20 +81,16 @@ bool cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) char *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; uint32 sec_info = 0; - TALLOC_CTX *mem_ctx; - prs_struct pd; + TALLOC_CTX *frame = talloc_stackframe(); bool ret = False; - - if ((mem_ctx = talloc_init("cli_set_secdesc")) == NULL) { - DEBUG(0,("talloc_init failed.\n")); - goto cleanup; - } - - prs_init(&pd, 0, mem_ctx, MARSHALL); - prs_give_memory(&pd, NULL, 0, True); - - if (!sec_io_desc("sd data", &sd, &pd, 1)) { - DEBUG(1,("Failed to marshall secdesc\n")); + uint8 *data; + size_t len; + NTSTATUS status; + + status = marshall_sec_desc(talloc_tos(), sd, &data, &len); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("marshall_sec_desc failed: %s\n", + nt_errstr(status))); goto cleanup; } @@ -119,7 +109,7 @@ bool cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) 0, NULL, 0, 0, param, 8, 0, - prs_data_p(&pd), prs_offset(&pd), 0)) { + (char *)data, len, 0)) { DEBUG(1,("Failed to send NT_TRANSACT_SET_SECURITY_DESC\n")); goto cleanup; } @@ -139,8 +129,7 @@ bool cli_set_secdesc(struct cli_state *cli, int fnum, SEC_DESC *sd) SAFE_FREE(rparam); SAFE_FREE(rdata); - talloc_destroy(mem_ctx); + TALLOC_FREE(frame); - prs_mem_free(&pd); return ret; } -- cgit From 6d9b2439d2d0459cbd2e74581c15f4b39d05ce5d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 29 Dec 2007 22:39:52 -0800 Subject: Added -e, --encrypt option to smbclient that immediately forces encrypted smb after initial connect. Will document for 3.2 official release. Jeremy. (This used to be commit f02bf419282419950471deae74c4a6fe1543ed26) --- source3/libsmb/clidfs.c | 121 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index e0c40b52ed..7800d10e8b 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -58,6 +58,70 @@ static struct sockaddr_storage dest_ss; static struct client_connection *connections; +static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, + struct cli_state *cli, + const char *sharename, + char **pp_newserver, + char **pp_newshare, + bool force_encrypt, + const char *username, + const char *password, + const char *domain); + +/******************************************************************** + Ensure a connection is encrypted. +********************************************************************/ + +static bool force_cli_encryption(struct cli_state *c, + const char *username, + const char *password, + const char *domain, + const char *sharename) +{ + uint16 major, minor; + uint32 caplow, caphigh; + NTSTATUS status; + + if (!SERVER_HAS_UNIX_CIFS(c)) { + d_printf("Encryption required and " + "server that doesn't support " + "UNIX extensions - failing connect\n"); + return false; + } + + if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) { + d_printf("Encryption required and " + "can't get UNIX CIFS extensions " + "version from server.\n"); + return false; + } + + if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) { + d_printf("Encryption required and " + "share %s doesn't support " + "encryption.\n", sharename); + return false; + } + + if (c->use_kerberos) { + status = cli_gss_smb_encryption_start(c); + } else { + status = cli_raw_ntlm_smb_encryption_start(c, + username, + password, + domain); + } + + if (!NT_STATUS_IS_OK(status)) { + d_printf("Encryption required and " + "setup failed with error %s.\n", + nt_errstr(status)); + return false; + } + + return true; +} + /******************************************************************** Return a connection to a server. ********************************************************************/ @@ -65,7 +129,8 @@ static struct client_connection *connections; static struct cli_state *do_connect(TALLOC_CTX *ctx, const char *server, const char *share, - bool show_sessetup) + bool show_sessetup, + bool force_encrypt) { struct cli_state *c = NULL; struct nmb_name called, calling; @@ -197,9 +262,14 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, if ((c->capabilities & CAP_DFS) && cli_check_msdfs_proxy(ctx, c, sharename, - &newserver, &newshare)) { + &newserver, &newshare, + force_encrypt, + username, + password, + lp_workgroup())) { cli_shutdown(c); - return do_connect(ctx, newserver, newshare, false); + return do_connect(ctx, newserver, + newshare, false, force_encrypt); } /* must be a normal share */ @@ -211,6 +281,15 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, return NULL; } + if (force_encrypt && !force_cli_encryption(c, + username, + password, + lp_workgroup(), + sharename)) { + cli_shutdown(c); + return NULL; + } + DEBUG(4,(" tconx ok\n")); return c; } @@ -269,7 +348,8 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, const char *share, - bool show_hdr) + bool show_hdr, + bool force_encrypt) { struct client_connection *node; @@ -279,7 +359,7 @@ static struct cli_state *cli_cm_connect(TALLOC_CTX *ctx, return NULL; } - node->cli = do_connect(ctx, server, share, show_hdr); + node->cli = do_connect(ctx, server, share, show_hdr, force_encrypt); if ( !node->cli ) { TALLOC_FREE( node ); @@ -331,7 +411,8 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, struct cli_state *referring_cli, const char *server, const char *share, - bool show_hdr) + bool show_hdr, + bool force_encrypt) { struct cli_state *c; @@ -339,7 +420,8 @@ struct cli_state *cli_cm_open(TALLOC_CTX *ctx, c = cli_cm_find(server, share); if (!c) { - c = cli_cm_connect(ctx, referring_cli, server, share, show_hdr); + c = cli_cm_connect(ctx, referring_cli, + server, share, show_hdr, force_encrypt); } return c; @@ -776,7 +858,9 @@ bool cli_resolve_path(TALLOC_CTX *ctx, /* Check for the referral. */ if (!(cli_ipc = cli_cm_open(ctx, rootcli, - rootcli->desthost, "IPC$", false))) { + rootcli->desthost, + "IPC$", false, + (rootcli->trans_enc_state != NULL)))) { return false; } @@ -818,7 +902,10 @@ bool cli_resolve_path(TALLOC_CTX *ctx, /* Open the connection to the target server & share */ if ((*targetcli = cli_cm_open(ctx, rootcli, - server, share, false)) == NULL) { + server, + share, + false, + (rootcli->trans_enc_state != NULL))) == NULL) { d_printf("Unable to follow dfs referral [\\%s\\%s]\n", server, share ); return false; @@ -905,11 +992,15 @@ bool cli_resolve_path(TALLOC_CTX *ctx, /******************************************************************** ********************************************************************/ -bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, +static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, struct cli_state *cli, const char *sharename, char **pp_newserver, - char **pp_newshare ) + char **pp_newshare, + bool force_encrypt, + const char *username, + const char *password, + const char *domain) { CLIENT_DFS_REFERRAL *refs = NULL; size_t num_refs = 0; @@ -944,6 +1035,14 @@ bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, return false; } + if (force_encrypt && !force_cli_encryption(cli, + username, + password, + lp_workgroup(), + "IPC$")) { + return false; + } + res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed); if (!cli_tdis(cli)) { -- cgit From f8dacb9860dfcf1b19191ebeb4a1c0279955464f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 3 Jan 2008 16:40:04 +0100 Subject: Add some more join related werror codes. Guenther (This used to be commit 62e7d467ab1b2f98327960eec3a3a925b2f04bda) --- source3/libsmb/doserr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index dd556bba5a..ba68b5a1e8 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -63,6 +63,7 @@ werror_code_struct dos_errs[] = { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, + { "WERR_USER_EXISTS", WERR_USER_EXISTS }, { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, @@ -77,6 +78,7 @@ werror_code_struct dos_errs[] = { "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED }, { "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED }, { "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER }, + { "WERR_DEFAULT_JOIN_REQUIRED", WERR_DEFAULT_JOIN_REQUIRED }, { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, @@ -110,6 +112,7 @@ werror_str_struct dos_err_strs[] = { { WERR_SETUP_ALREADY_JOINED, "Machine is already joined" }, { WERR_SETUP_DOMAIN_CONTROLLER, "Machine is a Domain Controller" }, { WERR_LOGON_FAILURE, "Invalid logon credentials" }, + { WERR_USER_EXISTS, "User account already exists" }, }; /***************************************************************************** -- cgit From f215dec8311b733c2db52c87a4e34dafecbea736 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 4 Jan 2008 19:58:19 +0100 Subject: Map WERR_NO_SUCH_SERVICE with dos_errstr(). Michael (This used to be commit df5839b5376e903486982ddc7c4f4fbd4550c60a) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index ba68b5a1e8..79445a2410 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -92,6 +92,7 @@ werror_code_struct dos_errs[] = { "WERR_REG_CORRUPT", WERR_REG_CORRUPT }, { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, + { "WERR_NO_SUCH_SERVICE", WERR_NO_SUCH_SERVICE }, { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE}, { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS}, -- cgit From 9254bb4ef1c3c3a52ea8e935edb0e7a86ec3ea7a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Jan 2008 12:56:23 -0800 Subject: Refactor the crypto code after a very helpful conversation with Volker. Mostly making sure we have data on the incoming packet type, not stored in the smb header. Jeremy. (This used to be commit c4e5a505043965eec77b5bb9bc60957e8f3b97c8) --- source3/libsmb/smb_seal.c | 25 +++++++++++++------------ source3/libsmb/smb_signing.c | 8 ++++---- 2 files changed, 17 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 055a27d05a..b5befbf7cd 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -23,13 +23,13 @@ Pull out the encryption context for this packet. 0 means global context. ******************************************************************************/ -NTSTATUS get_enc_ctx_num(const char *buf, uint16 *p_enc_ctx_num) +NTSTATUS get_enc_ctx_num(const uint8_t *buf, uint16 *p_enc_ctx_num) { if (smb_len(buf) < 8) { return NT_STATUS_INVALID_BUFFER_SIZE; } - if (buf[4] == (char)0xFF) { + if (buf[4] == 0xFF) { if (buf[5] == 'S' && buf [6] == 'M' && buf[7] == 'B') { /* Not an encrypted buffer. */ return NT_STATUS_NOT_FOUND; @@ -93,8 +93,8 @@ NTSTATUS common_ntlm_decrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf) memcpy(buf + 8, inbuf + 8 + NTLMSSP_SIG_SIZE, data_len); - /* Reset the length. */ - _smb_setlen(buf,data_len + 4); + /* Reset the length and overwrite the header. */ + smb_setlen(buf,data_len + 4); SAFE_FREE(inbuf); return NT_STATUS_OK; @@ -203,7 +203,8 @@ static NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_sta } memcpy(buf + 8, out_buf.value, out_buf.length); - _smb_setlen(buf, out_buf.length + 4); + /* Reset the length and overwrite the header. */ + smb_setlen(buf, out_buf.length + 4); gss_release_buffer(&minor, &out_buf); return NT_STATUS_OK; @@ -440,9 +441,9 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf) { /* We know this is an smb buffer, and we * didn't malloc, only copy, for a keepalive, - * so ignore session keepalives. */ + * so ignore non-session messages. */ - if(CVAL(buf,0) == SMBkeepalive) { + if(CVAL(buf,0)) { return; } @@ -461,12 +462,12 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS status; uint16 enc_ctx_num; - /* Ignore session keepalives. */ - if(CVAL(cli->inbuf,0) == SMBkeepalive) { + /* Ignore non-session messages. */ + if(CVAL(cli->inbuf,0)) { return NT_STATUS_OK; } - status = get_enc_ctx_num(cli->inbuf, &enc_ctx_num); + status = get_enc_ctx_num((const uint8_t *)cli->inbuf, &enc_ctx_num); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -484,8 +485,8 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) { - /* Ignore session keepalives. */ - if(CVAL(cli->outbuf,0) == SMBkeepalive) { + /* Ignore non-session messages. */ + if(CVAL(cli->outbuf,0)) { return NT_STATUS_OK; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index d5cbe3b125..f03c21bd0e 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -745,8 +745,8 @@ bool srv_oplock_set_signing(bool onoff) bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) { - /* Check if it's a session keepalive. */ - if(CVAL(inbuf,0) == SMBkeepalive) { + /* Check if it's a non-session message. */ + if(CVAL(inbuf,0)) { return True; } @@ -759,8 +759,8 @@ bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) void srv_calculate_sign_mac(char *outbuf) { - /* Check if it's a session keepalive. */ - if(CVAL(outbuf,0) == SMBkeepalive) { + /* Check if it's a non-session message. */ + if(CVAL(outbuf,0)) { return; } -- cgit From 395c366237dec1a38a53248d2e8df17f877207aa Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Jan 2008 22:56:31 +0100 Subject: Do not pass emtpy wkssvc_PasswordBuffers to rpc functions. Guenther (This used to be commit fe75e5ccdfc2609380367e59215637b0de1ef241) --- source3/libsmb/smbencrypt.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 9e37d1d6cf..d7f6f604f7 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -704,16 +704,22 @@ char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in) void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, const char *pwd, DATA_BLOB *session_key, - struct wkssvc_PasswordBuffer *pwd_buf) + struct wkssvc_PasswordBuffer **pwd_buf) { uint8_t buffer[516]; struct MD5Context ctx; - - DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); - + struct wkssvc_PasswordBuffer *my_pwd_buf = NULL; + DATA_BLOB confounded_session_key; int confounder_len = 8; uint8_t confounder[8]; + my_pwd_buf = talloc_zero(mem_ctx, struct wkssvc_PasswordBuffer); + if (!my_pwd_buf) { + return; + } + + confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); + encode_pw_buffer(buffer, pwd, STR_UNICODE); generate_random_buffer((uint8_t *)confounder, confounder_len); @@ -725,10 +731,12 @@ void encode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, SamOEMhashBlob(buffer, 516, &confounded_session_key); - memcpy(&pwd_buf->data[0], confounder, confounder_len); - memcpy(&pwd_buf->data[8], buffer, 516); + memcpy(&my_pwd_buf->data[0], confounder, confounder_len); + memcpy(&my_pwd_buf->data[8], buffer, 516); data_blob_free(&confounded_session_key); + + *pwd_buf = my_pwd_buf; } WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, -- cgit From 9baa97a46ebb92a5968ceba0fb5c2de51e6fa8f0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Jan 2008 00:23:35 -0800 Subject: Add general '-e' option to enable smb encryption on tools. Jeremy. (This used to be commit 757653966fc1384159bd2d57c5670cd8af0cae96) --- source3/libsmb/clidfs.c | 58 ++++++++++++++++++---------------------------- source3/libsmb/clifsinfo.c | 33 ++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 35 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 7800d10e8b..77419b4a1a 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -72,54 +72,36 @@ static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, Ensure a connection is encrypted. ********************************************************************/ -static bool force_cli_encryption(struct cli_state *c, +NTSTATUS cli_cm_force_encryption(struct cli_state *c, const char *username, const char *password, const char *domain, const char *sharename) { - uint16 major, minor; - uint32 caplow, caphigh; - NTSTATUS status; + NTSTATUS status = cli_force_encryption(c, + username, + password, + domain); - if (!SERVER_HAS_UNIX_CIFS(c)) { + if (NT_STATUS_EQUAL(status,NT_STATUS_NOT_SUPPORTED)) { d_printf("Encryption required and " "server that doesn't support " "UNIX extensions - failing connect\n"); - return false; - } - - if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) { + } else if (NT_STATUS_EQUAL(status,NT_STATUS_UNKNOWN_REVISION)) { d_printf("Encryption required and " "can't get UNIX CIFS extensions " "version from server.\n"); - return false; - } - - if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) { + } else if (NT_STATUS_EQUAL(status,NT_STATUS_UNSUPPORTED_COMPRESSION)) { d_printf("Encryption required and " "share %s doesn't support " "encryption.\n", sharename); - return false; - } - - if (c->use_kerberos) { - status = cli_gss_smb_encryption_start(c); - } else { - status = cli_raw_ntlm_smb_encryption_start(c, - username, - password, - domain); - } - - if (!NT_STATUS_IS_OK(status)) { + } else if (!NT_STATUS_IS_OK(status)) { d_printf("Encryption required and " "setup failed with error %s.\n", nt_errstr(status)); - return false; } - return true; + return status; } /******************************************************************** @@ -281,13 +263,16 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, return NULL; } - if (force_encrypt && !force_cli_encryption(c, + if (force_encrypt) { + status = cli_cm_force_encryption(c, username, password, lp_workgroup(), - sharename)) { - cli_shutdown(c); - return NULL; + sharename); + if (!NT_STATUS_IS_OK(status)) { + cli_shutdown(c); + return NULL; + } } DEBUG(4,(" tconx ok\n")); @@ -1035,12 +1020,15 @@ static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, return false; } - if (force_encrypt && !force_cli_encryption(cli, + if (force_encrypt) { + NTSTATUS status = cli_cm_force_encryption(cli, username, password, lp_workgroup(), - "IPC$")) { - return false; + "IPC$"); + if (!NT_STATUS_IS_OK(status)) { + return false; + } } res = cli_dfs_get_referral(ctx, cli, fullpath, &refs, &num_refs, &consumed); diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 107613c618..fb923378ab 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -634,3 +634,36 @@ NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli) return NT_STATUS_NOT_SUPPORTED; } #endif + +/******************************************************************** + Ensure a connection is encrypted. +********************************************************************/ + +NTSTATUS cli_force_encryption(struct cli_state *c, + const char *username, + const char *password, + const char *domain) +{ + uint16 major, minor; + uint32 caplow, caphigh; + + if (!SERVER_HAS_UNIX_CIFS(c)) { + return NT_STATUS_NOT_SUPPORTED; + } + + if (!cli_unix_extensions_version(c, &major, &minor, &caplow, &caphigh)) { + return NT_STATUS_UNKNOWN_REVISION; + } + + if (!(caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP)) { + return NT_STATUS_UNSUPPORTED_COMPRESSION; + } + + if (c->use_kerberos) { + return cli_gss_smb_encryption_start(c); + } + return cli_raw_ntlm_smb_encryption_start(c, + username, + password, + domain); +} -- cgit From 1be3fcbf2f897b559bf72b72d54aa40805abd819 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Jan 2008 00:51:18 -0800 Subject: Add the options smb_encrypt_level to set the requested encrypt level and smb_encrypt_on to query it. Jeremy. (This used to be commit 07d47996f9535731ccdc1792c405c8bee1a082ae) --- source3/libsmb/libsmbclient.c | 98 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2ff2830256..da8f1e332b 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -6,6 +6,7 @@ Copyright (C) John Terpstra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003, 2004 + Copyright (C) Jeremy Allison 2007, 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -739,6 +740,12 @@ smbc_server(SMBCCTX *context, password, strlen(password)+1); } + /* + * We don't need to renegotiate encryption + * here as the encryption context is not per + * tid. + */ + if (! cli_send_tconX(srv->cli, share, "?????", password, strlen(password)+1)) { @@ -903,6 +910,30 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" tconx ok\n")); + if (context->internal->_smb_encryption_level) { + /* Attempt UNIX smb encryption. */ + if (!NT_STATUS_IS_OK(cli_force_encryption(c, + username_used, + password, + workgroup))) { + + /* + * context->internal->_smb_encryption_level == 1 + * means don't fail if encryption can't be negotiated, + * == 2 means fail if encryption can't be negotiated. + */ + + DEBUG(4,(" SMB encrypt failed\n")); + + if (context->internal->_smb_encryption_level == 2) { + cli_shutdown(c); + errno = EPERM; + return NULL; + } + } + DEBUG(4,(" SMB encrypt ok\n")); + } + /* * Ok, we have got a nice connection * Let's allocate a server structure. @@ -1019,6 +1050,30 @@ smbc_attr_server(SMBCCTX *context, return NULL; } + if (context->internal->_smb_encryption_level) { + /* Attempt UNIX smb encryption. */ + if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, + username, + password, + workgroup))) { + + /* + * context->internal->_smb_encryption_level == 1 + * means don't fail if encryption can't be negotiated, + * == 2 means fail if encryption can't be negotiated. + */ + + DEBUG(4,(" SMB encrypt failed on IPC$\n")); + + if (context->internal->_smb_encryption_level == 2) { + cli_shutdown(ipc_cli); + errno = EPERM; + return NULL; + } + } + DEBUG(4,(" SMB encrypt ok on IPC$\n")); + } + ipc_srv = SMB_MALLOC_P(SMBCSRV); if (!ipc_srv) { errno = ENOMEM; @@ -6724,6 +6779,7 @@ smbc_option_set(SMBCCTX *context, bool b; smbc_get_auth_data_with_context_fn auth_fn; void *v; + const char *s; } option_value; va_start(ap, option_name); @@ -6772,6 +6828,19 @@ smbc_option_set(SMBCCTX *context, */ option_value.v = va_arg(ap, void *); context->internal->_user_data = option_value.v; + } else if (strcmp(option_name, "smb_encrypt_level") == 0) { + /* + * Save an encoded value for encryption level. + * 0 = off, 1 = attempt, 2 = required. + */ + option_value.s = va_arg(ap, const char *); + if (strcmp(option_value.s, "none") == 0) { + context->internal->_smb_encryption_level = 0; + } else if (strcmp(option_value.s, "request") == 0) { + context->internal->_smb_encryption_level = 1; + } else if (strcmp(option_value.s, "require") == 0) { + context->internal->_smb_encryption_level = 2; + } } va_end(ap); @@ -6821,6 +6890,35 @@ smbc_option_get(SMBCCTX *context, * with smbc_option_get() */ return context->internal->_user_data; + } else if (strcmp(option_name, "smb_encrypt_level") == 0) { + /* + * Return the current smb encrypt negotiate option as a string. + */ + switch (context->internal->_smb_encryption_level) { + case 0: + return (void *) "none"; + case 1: + return (void *) "request"; + case 2: + return (void *) "require"; + } + } else if (strcmp(option_name, "smb_encrypt_on") == 0) { + /* + * Return the current smb encrypt status option as a bool. + * false = off, true = on. We don't know what server is + * being requested, so we only return true if all servers + * are using an encrypted connection. + */ + SMBCSRV *s; + unsigned int num_servers = 0; + + for (s = context->internal->_servers; s; s = s->next) { + num_servers++; + if (s->cli->trans_enc_state == NULL) { + return (void *)false; + } + } + return (void *) (bool) (num_servers > 0); } return NULL; -- cgit From a8d200893a0a7bfbd5a33a52fbe47c4d14a6ed50 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 7 Jan 2008 23:05:58 +0100 Subject: Refactor our DsGetDcName call a bit (before it will move into libnetapi). Guenther (This used to be commit 41c129da3d33f9fc2864d360e4b6ec5a72caf2a3) --- source3/libsmb/dsgetdcname.c | 117 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index f8089cbd6a..fa6cbe146f 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -4,7 +4,7 @@ DsGetDcname Copyright (C) Gerald Carter 2006 - Copyright (C) Guenther Deschner 2007 + Copyright (C) Guenther Deschner 2007-2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -891,28 +891,72 @@ static NTSTATUS DsGetDcName_rediscover(TALLOC_CTX *mem_ctx, } /******************************************************************** - DsGetDcName. +********************************************************************/ - This will be the only public function here. +NTSTATUS DsGetDcName_remote(TALLOC_CTX *mem_ctx, + const char *computer_name, + const char *domain_name, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags, + struct DS_DOMAIN_CONTROLLER_INFO **info) +{ + WERROR werr; + NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + struct cli_state *cli = NULL; + struct rpc_pipe_client *pipe_cli = NULL; + + status = cli_full_connection(&cli, NULL, computer_name, + NULL, 0, + "IPC$", "IPC", + "", + "", + "", + 0, Undefined, NULL); + + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + + pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, + &status); + if (!pipe_cli) { + goto done; + } + + werr = rpccli_netlogon_dsr_getdcname(pipe_cli, + mem_ctx, + computer_name, + domain_name, + domain_guid, + NULL, + flags, + info); + status = werror_to_ntstatus(werr); + + done: + cli_rpc_pipe_close(pipe_cli); + if (cli) { + cli_shutdown(cli); + } + + return status; +} + +/******************************************************************** ********************************************************************/ -NTSTATUS DsGetDcName(TALLOC_CTX *mem_ctx, - const char *computer_name, - const char *domain_name, - struct GUID *domain_guid, - const char *site_name, - uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info) +NTSTATUS DsGetDcName_local(TALLOC_CTX *mem_ctx, + const char *computer_name, + const char *domain_name, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags, + struct DS_DOMAIN_CONTROLLER_INFO **info) { NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct DS_DOMAIN_CONTROLLER_INFO *myinfo = NULL; - DEBUG(10,("DsGetDcName: computer_name: %s, domain_name: %s, " - "domain_guid: %s, site_name: %s, flags: 0x%08x\n", - computer_name, domain_name, - domain_guid ? GUID_string(mem_ctx, domain_guid) : "(null)", - site_name, flags)); - *info = NULL; if (!check_allowed_required_flags(flags)) { @@ -947,3 +991,44 @@ NTSTATUS DsGetDcName(TALLOC_CTX *mem_ctx, return status; } + +/******************************************************************** + DsGetDcName. + + This will be the only public function here. +********************************************************************/ + +NTSTATUS DsGetDcName(TALLOC_CTX *mem_ctx, + const char *computer_name, + const char *domain_name, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags, + struct DS_DOMAIN_CONTROLLER_INFO **info) +{ + DEBUG(10,("DsGetDcName: computer_name: %s, domain_name: %s, " + "domain_guid: %s, site_name: %s, flags: 0x%08x\n", + computer_name, domain_name, + domain_guid ? GUID_string(mem_ctx, domain_guid) : "(null)", + site_name, flags)); + + *info = NULL; + + if (computer_name) { + return DsGetDcName_remote(mem_ctx, + computer_name, + domain_name, + domain_guid, + site_name, + flags, + info); + } + + return DsGetDcName_local(mem_ctx, + computer_name, + domain_name, + domain_guid, + site_name, + flags, + info); +} -- cgit From 3eb2cfc1ad3e7592ce3711265507a6a1c4253280 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 8 Jan 2008 18:51:55 -0800 Subject: Fix CID 461 - resource leak on error. Jeremy. (This used to be commit eea07b0c83985af60395f8a31de5bac4e5398cff) --- source3/libsmb/clidfs.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 77419b4a1a..16582f8049 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -156,6 +156,9 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, /* have to open a new connection */ if (!(c=cli_initialise()) || (cli_set_port(c, port) != port)) { d_printf("Connection to %s failed\n", server_n); + if (c) { + cli_shutdown(c); + } return NULL; } status = cli_connect(c, server_n, &ss); @@ -163,6 +166,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, d_printf("Connection to %s failed (Error %s)\n", server_n, nt_errstr(status)); + cli_shutdown(c); return NULL; } -- cgit From c0c299cb267f6c559a0a407fde536aa32efc29f6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 9 Jan 2008 22:25:52 +0100 Subject: Fix a memleak found by the IBM checker. Michael (This used to be commit b4a37a66bbd8f5346de743d4ab427d6671e29075) --- source3/libsmb/clirap.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 54504f608d..aab77a3d54 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -297,6 +297,7 @@ bool cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, STR_TERMINATE|STR_UPPER); if (len == (size_t)-1) { + SAFE_FREE(last_entry); return false; } p += len; -- cgit From c79ce2ffa3f7d00ce6a2cd6008c203e3042b0b02 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 11 Jan 2008 15:32:20 +0100 Subject: As long as DsGetDcName is not part of libnetapi, lowercase the fn name. Guenther (This used to be commit 19a980f52044a170618629e5b0484c1f6b586e5f) --- source3/libsmb/dsgetdcname.c | 76 ++++++++++++++++++++++---------------------- 1 file changed, 38 insertions(+), 38 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index fa6cbe146f..2a66d51400 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. - DsGetDcname + dsgetdcname Copyright (C) Gerald Carter 2006 Copyright (C) Guenther Deschner 2007-2008 @@ -259,7 +259,7 @@ static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static char *DsGetDcName_cache_key(TALLOC_CTX *mem_ctx, const char *domain) +static char *dsgetdcname_cache_key(TALLOC_CTX *mem_ctx, const char *domain) { if (!mem_ctx || !domain) { return NULL; @@ -271,7 +271,7 @@ static char *DsGetDcName_cache_key(TALLOC_CTX *mem_ctx, const char *domain) /**************************************************************** ****************************************************************/ -static NTSTATUS DsGetDcName_cache_delete(TALLOC_CTX *mem_ctx, +static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx, const char *domain_name) { char *key; @@ -280,7 +280,7 @@ static NTSTATUS DsGetDcName_cache_delete(TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_DB_ERROR; } - key = DsGetDcName_cache_key(mem_ctx, domain_name); + key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; } @@ -295,13 +295,13 @@ static NTSTATUS DsGetDcName_cache_delete(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static NTSTATUS DsGetDcName_cache_store(TALLOC_CTX *mem_ctx, +static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, const char *domain_name, struct DS_DOMAIN_CONTROLLER_INFO *info) { time_t expire_time; char *key; - bool ret = False; + bool ret = false; DATA_BLOB blob; unsigned char *buf = NULL; int len = 0; @@ -310,7 +310,7 @@ static NTSTATUS DsGetDcName_cache_store(TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_DB_ERROR; } - key = DsGetDcName_cache_key(mem_ctx, domain_name); + key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; } @@ -341,7 +341,7 @@ static NTSTATUS DsGetDcName_cache_store(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static NTSTATUS DsGetDcName_cache_refresh(TALLOC_CTX *mem_ctx, +static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, @@ -358,9 +358,9 @@ static NTSTATUS DsGetDcName_cache_refresh(TALLOC_CTX *mem_ctx, if (ads_cldap_netlogon(info->domain_controller_name, info->domain_name, &r)) { - DsGetDcName_cache_delete(mem_ctx, domain_name); + dsgetdcname_cache_delete(mem_ctx, domain_name); - return DsGetDcName_cache_store(mem_ctx, + return dsgetdcname_cache_store(mem_ctx, info->domain_name, info); } @@ -371,7 +371,7 @@ static NTSTATUS DsGetDcName_cache_refresh(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -#define RETURN_ON_FALSE(x) if (!x) return False; +#define RETURN_ON_FALSE(x) if (!x) return false; static bool check_cldap_reply_required_flags(uint32_t ret_flags, uint32_t req_flags) @@ -398,13 +398,13 @@ static bool check_cldap_reply_required_flags(uint32_t ret_flags, if (req_flags & DS_WRITABLE_REQUIRED) RETURN_ON_FALSE(ret_flags & ADS_WRITABLE); - return True; + return true; } /**************************************************************** ****************************************************************/ -static NTSTATUS DsGetDcName_cache_fetch(TALLOC_CTX *mem_ctx, +static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, @@ -420,7 +420,7 @@ static NTSTATUS DsGetDcName_cache_fetch(TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_DB_ERROR; } - key = DsGetDcName_cache_key(mem_ctx, domain_name); + key = dsgetdcname_cache_key(mem_ctx, domain_name); if (!key) { return NT_STATUS_NO_MEMORY; } @@ -454,7 +454,7 @@ static NTSTATUS DsGetDcName_cache_fetch(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static NTSTATUS DsGetDcName_cached(TALLOC_CTX *mem_ctx, +static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, @@ -462,12 +462,12 @@ static NTSTATUS DsGetDcName_cached(TALLOC_CTX *mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO **info) { NTSTATUS status; - bool expired = False; + bool expired = false; - status = DsGetDcName_cache_fetch(mem_ctx, domain_name, domain_guid, + status = dsgetdcname_cache_fetch(mem_ctx, domain_name, domain_guid, flags, site_name, info, &expired); if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("DsGetDcName_cached: cache fetch failed with: %s\n", + DEBUG(10,("dsgetdcname_cached: cache fetch failed with: %s\n", nt_errstr(status))); return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; } @@ -477,7 +477,7 @@ static NTSTATUS DsGetDcName_cached(TALLOC_CTX *mem_ctx, } if (expired) { - status = DsGetDcName_cache_refresh(mem_ctx, domain_name, + status = dsgetdcname_cache_refresh(mem_ctx, domain_name, domain_guid, flags, site_name, *info); if (!NT_STATUS_IS_OK(status)) { @@ -503,24 +503,24 @@ static bool check_allowed_required_flags(uint32_t flags) debug_dsdcinfo_flags(10, flags); if (return_type == (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME)) { - return False; + return false; } if (offered_type == (DS_IS_DNS_NAME|DS_IS_FLAT_NAME)) { - return False; + return false; } if (query_type == (DS_BACKGROUND_ONLY|DS_FORCE_REDISCOVERY)) { - return False; + return false; } #if 0 if ((flags & DS_RETURN_DNS_NAME) && (!(flags & DS_IP_REQUIRED))) { printf("gd: here5 \n"); - return False; + return false; } #endif - return True; + return true; } /**************************************************************** @@ -739,7 +739,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO **info) { int i = 0; - bool valid_dc = False; + bool valid_dc = false; struct cldap_netlogon_reply r; const char *dc_hostname, *dc_domain_name; const char *dc_address; @@ -754,7 +754,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, if ((ads_cldap_netlogon(dclist[i]->hostname, domain_name, &r)) && (check_cldap_reply_required_flags(r.flags, flags))) { - valid_dc = True; + valid_dc = true; break; } @@ -837,7 +837,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static NTSTATUS DsGetDcName_rediscover(TALLOC_CTX *mem_ctx, +static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, @@ -848,7 +848,7 @@ static NTSTATUS DsGetDcName_rediscover(TALLOC_CTX *mem_ctx, struct ip_service_name *dclist; int num_dcs; - DEBUG(10,("DsGetDcName_rediscover\n")); + DEBUG(10,("dsgetdcname_rediscover\n")); if (flags & DS_IS_FLAT_NAME) { @@ -893,7 +893,7 @@ static NTSTATUS DsGetDcName_rediscover(TALLOC_CTX *mem_ctx, /******************************************************************** ********************************************************************/ -NTSTATUS DsGetDcName_remote(TALLOC_CTX *mem_ctx, +NTSTATUS dsgetdcname_remote(TALLOC_CTX *mem_ctx, const char *computer_name, const char *domain_name, struct GUID *domain_guid, @@ -946,7 +946,7 @@ NTSTATUS DsGetDcName_remote(TALLOC_CTX *mem_ctx, /******************************************************************** ********************************************************************/ -NTSTATUS DsGetDcName_local(TALLOC_CTX *mem_ctx, +NTSTATUS dsgetdcname_local(TALLOC_CTX *mem_ctx, const char *computer_name, const char *domain_name, struct GUID *domain_guid, @@ -968,7 +968,7 @@ NTSTATUS DsGetDcName_local(TALLOC_CTX *mem_ctx, goto rediscover; } - status = DsGetDcName_cached(mem_ctx, domain_name, domain_guid, + status = dsgetdcname_cached(mem_ctx, domain_name, domain_guid, flags, site_name, &myinfo); if (NT_STATUS_IS_OK(status)) { *info = myinfo; @@ -980,12 +980,12 @@ NTSTATUS DsGetDcName_local(TALLOC_CTX *mem_ctx, } rediscover: - status = DsGetDcName_rediscover(mem_ctx, domain_name, + status = dsgetdcname_rediscover(mem_ctx, domain_name, domain_guid, flags, site_name, &myinfo); if (NT_STATUS_IS_OK(status)) { - DsGetDcName_cache_store(mem_ctx, domain_name, myinfo); + dsgetdcname_cache_store(mem_ctx, domain_name, myinfo); *info = myinfo; } @@ -993,12 +993,12 @@ NTSTATUS DsGetDcName_local(TALLOC_CTX *mem_ctx, } /******************************************************************** - DsGetDcName. + dsgetdcname. This will be the only public function here. ********************************************************************/ -NTSTATUS DsGetDcName(TALLOC_CTX *mem_ctx, +NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, const char *computer_name, const char *domain_name, struct GUID *domain_guid, @@ -1006,7 +1006,7 @@ NTSTATUS DsGetDcName(TALLOC_CTX *mem_ctx, uint32_t flags, struct DS_DOMAIN_CONTROLLER_INFO **info) { - DEBUG(10,("DsGetDcName: computer_name: %s, domain_name: %s, " + DEBUG(10,("dsgetdcname: computer_name: %s, domain_name: %s, " "domain_guid: %s, site_name: %s, flags: 0x%08x\n", computer_name, domain_name, domain_guid ? GUID_string(mem_ctx, domain_guid) : "(null)", @@ -1015,7 +1015,7 @@ NTSTATUS DsGetDcName(TALLOC_CTX *mem_ctx, *info = NULL; if (computer_name) { - return DsGetDcName_remote(mem_ctx, + return dsgetdcname_remote(mem_ctx, computer_name, domain_name, domain_guid, @@ -1024,7 +1024,7 @@ NTSTATUS DsGetDcName(TALLOC_CTX *mem_ctx, info); } - return DsGetDcName_local(mem_ctx, + return dsgetdcname_local(mem_ctx, computer_name, domain_name, domain_guid, -- cgit From 76d904e6d84ea41d824f2ecb4682d84718ff1bdd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 12 Jan 2008 00:05:07 -0800 Subject: Fix CID 470. resolve_order can't be NULL here so simplify code. Jeremy. (This used to be commit 2e75f3ecdf9890b9d7d4bd03f3fa15ef74816d5d) --- source3/libsmb/namequery.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 853fe979b7..ad999b34b4 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1422,14 +1422,13 @@ NTSTATUS resolve_ads(const char *name, resolve_hosts() when looking up DC's via SRV RR entries in DNS **********************************************************************/ -NTSTATUS internal_resolve_name(const char *name, +static NTSTATUS internal_resolve_name(const char *name, int name_type, const char *sitename, struct ip_service **return_iplist, int *return_count, const char *resolve_order) { - const char *name_resolve_list; char *tok; const char *ptr; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -1483,16 +1482,10 @@ NTSTATUS internal_resolve_name(const char *name, return NT_STATUS_INVALID_PARAMETER; } - if (!resolve_order) { - name_resolve_list = lp_name_resolve_order(); - } else { - name_resolve_list = resolve_order; - } - - if (!name_resolve_list[0]) { + if (!resolve_order[0]) { ptr = "host"; } else { - ptr = name_resolve_list; + ptr = resolve_order; } /* iterate through the name resolution backends */ -- cgit From 011e89c85868ec8f16e475a560a0e5bd41995920 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 13 Jan 2008 17:10:06 -0500 Subject: Fix smbc_listxattr() and friends (bug #5189) When the capability of using full names for DOS attributes was added, a bug was introduced which caused the wrong number of bytes to be returned. This patch to smbc_listxattr_ctx() fixes the problem. Thanks to Jack Schmidt for this patch. Derrell (This used to be commit 913c335d21c503d32b35bf65da7b2bddf0473875) --- source3/libsmb/libsmbclient.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index da8f1e332b..179f6eba5d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -6241,6 +6241,7 @@ smbc_listxattr_ctx(SMBCCTX *context, * the complete set of attribute names, always, rather than only those * attribute names which actually exist for a file. Hmmm... */ + size_t retsize; const char supported_old[] = "system.*\0" "system.*+\0" @@ -6284,22 +6285,24 @@ smbc_listxattr_ctx(SMBCCTX *context, if (context->internal->_full_time_names) { supported = supported_new; + retsize = sizeof(supported_new); } else { supported = supported_old; + retsize = sizeof(supported_old); } if (size == 0) { - return sizeof(supported); + return retsize; } - if (sizeof(supported) > size) { + if (retsize > size) { errno = ERANGE; return -1; } /* this can't be strcpy() because there are embedded null characters */ - memcpy(list, supported, sizeof(supported)); - return sizeof(supported); + memcpy(list, supported, retsize); + return retsize; } -- cgit From d7582b51863c44fdbffc8140a95950a3762d4b40 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 14 Jan 2008 13:46:06 -0800 Subject: Windows insists on write sizes < max_xmit on signed connections. Jeremy. (This used to be commit ef9b278b6289a9ecdd6b103927058f64fbb7eb97) --- source3/libsmb/clireadwrite.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 0b33e43563..6b39a885f0 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -404,6 +404,9 @@ ssize_t cli_write(struct cli_state *cli, mpx = 1; } + /* Default (small) writesize. */ + writesize = (cli->max_xmit - (smb_size+32)) & ~1023; + if (write_mode == 0 && !client_is_signing_on(cli) && !cli_encryption_on(cli) && @@ -415,11 +418,11 @@ ssize_t cli_write(struct cli_state *cli, } else if (cli->capabilities & CAP_LARGE_WRITEX) { if (cli->is_samba) { writesize = CLI_SAMBA_MAX_LARGE_WRITEX_SIZE; - } else { + } else if (!client_is_signing_on(cli)) { + /* Windows restricts signed writes to max_xmit. + * Found by Volker. */ writesize = CLI_WINDOWS_MAX_LARGE_WRITEX_SIZE; } - } else { - writesize = (cli->max_xmit - (smb_size+32)) & ~1023; } blocks = (size + (writesize-1)) / writesize; -- cgit From ce9e918c95a81470056eef74878aeb10aadbaacf Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Tue, 15 Jan 2008 19:28:23 +0100 Subject: libsmb: Do not upper-case target name on NTLMv2 hash generation This makes our NTLMv2 hash generation compatible to the Davenport example and fixes a bug when ntlm_auth is called with a non-upper-case --domain parameter and client ntlmv2 auth = yes Jerry, please consider for 3.2.0 (This used to be commit ecbe08897c9cc47790f3d4f5680d25202bc0f6c3) --- source3/libsmb/smbencrypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index d7f6f604f7..c547a4a003 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -443,7 +443,7 @@ bool SMBNTLMv2encrypt_hash(const char *user, const char *domain, const uchar nt_ the username and domain. This prevents username swapping during the auth exchange */ - if (!ntv2_owf_gen(nt_hash, user, domain, True, ntlm_v2_hash)) { + if (!ntv2_owf_gen(nt_hash, user, domain, False, ntlm_v2_hash)) { return False; } -- cgit From 9a6a5fff9ca387ec698eaae2b3abc6a1937f2bab Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Jan 2008 16:13:11 -0800 Subject: Fix the API exported for auth_functions. Ensure we call passing 3 fstrings/sizeof(fstrings) as 3.0.x did. Found by Derrell. Derrell please test ! Thanks, Jeremy. (This used to be commit 5467db388355a4769e48fed7eb80920d1820f727) --- source3/libsmb/libsmbclient.c | 582 ++++++++++++++++++++++-------------------- 1 file changed, 310 insertions(+), 272 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index da8f1e332b..f266c16c97 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -592,13 +592,58 @@ smbc_remove_unused_server(SMBCCTX * context, return 0; } +/**************************************************************** + * Call the auth_fn with fixed size (fstring) buffers. + ***************************************************************/ + +static void call_auth_fn(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + fstring workgroup; + fstring username; + fstring password; + + strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); + strlcpy(username, *pp_username, sizeof(username)); + strlcpy(password, *pp_password, sizeof(password)); + + if (context->internal->_auth_fn_with_context != NULL) { + (context->internal->_auth_fn_with_context)( + context, + server, share, + workgroup, sizeof(workgroup), + username, sizeof(username), + password, sizeof(password)); + } else { + (context->callbacks.auth_fn)( + server, share, + workgroup, sizeof(workgroup), + username, sizeof(username), + password, sizeof(password)); + } + + TALLOC_FREE(*pp_workgroup); + TALLOC_FREE(*pp_username); + TALLOC_FREE(*pp_password); + + *pp_workgroup = talloc_strdup(ctx, workgroup); + *pp_username = talloc_strdup(ctx, username); + *pp_password = talloc_strdup(ctx, password); +} + static SMBCSRV * -find_server(SMBCCTX *context, +find_server(TALLOC_CTX *ctx, + SMBCCTX *context, const char *server, const char *share, - char *workgroup, - char *username, - char *password) + char **pp_workgroup, + char **pp_username, + char **pp_password) { SMBCSRV *srv; int auth_called = 0; @@ -606,22 +651,15 @@ find_server(SMBCCTX *context, check_server_cache: srv = (context->callbacks.get_cached_srv_fn)(context, server, share, - workgroup, username); - - if (!auth_called && !srv && (!username[0] || !password[0])) { - if (context->internal->_auth_fn_with_context != NULL) { - (context->internal->_auth_fn_with_context)( - context, - server, share, - workgroup, strlen(workgroup)+1, - username, strlen(username)+1, - password, strlen(password)+1); - } else { - (context->callbacks.auth_fn)( - server, share, - workgroup, strlen(workgroup)+1, - username, strlen(username)+1, - password, strlen(password)+1); + *pp_workgroup, *pp_username); + + if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] || + !*pp_password || !(*pp_password)[0])) { + call_auth_fn(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + + if (!pp_workgroup || !pp_username || !pp_password) { + return NULL; } /* @@ -652,12 +690,12 @@ find_server(SMBCCTX *context, (context->callbacks.remove_cached_srv_fn)(context, srv); } - + /* * Maybe there are more cached connections to this * server */ - goto check_server_cache; + goto check_server_cache; } return srv; @@ -678,13 +716,14 @@ find_server(SMBCCTX *context, */ static SMBCSRV * -smbc_server(SMBCCTX *context, +smbc_server(TALLOC_CTX *ctx, + SMBCCTX *context, bool connect_if_not_found, const char *server, const char *share, - char *workgroup, - char *username, - char *password) + char **pp_workgroup, + char **pp_username, + char **pp_password) { SMBCSRV *srv=NULL; struct cli_state *c; @@ -706,8 +745,8 @@ smbc_server(SMBCCTX *context, } /* Look for a cached connection */ - srv = find_server(context, server, share, - workgroup, username, password); + srv = find_server(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); /* * If we found a connection and we're only allowed one share per @@ -725,20 +764,17 @@ smbc_server(SMBCCTX *context, */ if (srv->cli->cnum == (uint16) -1) { /* Ensure we have accurate auth info */ - if (context->internal->_auth_fn_with_context != NULL) { - (context->internal->_auth_fn_with_context)( - context, - server, share, - workgroup, strlen(workgroup)+1, - username, strlen(username)+1, - password, strlen(password)+1); - } else { - (context->callbacks.auth_fn)( - server, share, - workgroup, strlen(workgroup)+1, - username, strlen(username)+1, - password, strlen(password)+1); - } + call_auth_fn(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + cli_shutdown(srv->cli); + srv->cli = NULL; + (context->callbacks.remove_cached_srv_fn)(context, + srv); + return NULL; + } /* * We don't need to renegotiate encryption @@ -746,8 +782,9 @@ smbc_server(SMBCCTX *context, * tid. */ - if (! cli_send_tconX(srv->cli, share, "?????", - password, strlen(password)+1)) { + if (!cli_send_tconX(srv->cli, share, "?????", + *pp_password, + strlen(*pp_password)+1)) { errno = smbc_errno(context, srv->cli); cli_shutdown(srv->cli); @@ -781,6 +818,11 @@ smbc_server(SMBCCTX *context, return NULL; } + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + return NULL; + } + make_nmb_name(&calling, context->netbios_name, 0x0); make_nmb_name(&called , server, 0x20); @@ -877,21 +919,21 @@ smbc_server(SMBCCTX *context, return NULL; } - username_used = username; + username_used = *pp_username; if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, - password, strlen(password), - password, strlen(password), - workgroup))) { + *pp_password, strlen(*pp_password), + *pp_password, strlen(*pp_password), + *pp_workgroup))) { /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || !NT_STATUS_IS_OK(cli_session_setup(c, username_used, - password, 1, - password, 0, - workgroup))) { + *pp_password, 1, + *pp_password, 0, + *pp_workgroup))) { cli_shutdown(c); errno = EPERM; @@ -902,7 +944,7 @@ smbc_server(SMBCCTX *context, DEBUG(4,(" session setup ok\n")); if (!cli_send_tconX(c, share, "?????", - password, strlen(password)+1)) { + *pp_password, strlen(*pp_password)+1)) { errno = smbc_errno(context, c); cli_shutdown(c); return NULL; @@ -914,8 +956,8 @@ smbc_server(SMBCCTX *context, /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(c, username_used, - password, - workgroup))) { + *pp_password, + *pp_workgroup))) { /* * context->internal->_smb_encryption_level == 1 @@ -956,8 +998,9 @@ smbc_server(SMBCCTX *context, /* Let the cache function set errno if it wants to */ errno = 0; if ((context->callbacks.add_cached_srv_fn)(context, srv, - server, share, - workgroup, username)) { + server, share, + *pp_workgroup, + *pp_username)) { int saved_errno = errno; DEBUG(3, (" Failed to add server to cache\n")); errno = saved_errno; @@ -988,13 +1031,14 @@ smbc_server(SMBCCTX *context, * connection. This works similarly to smbc_server(). */ static SMBCSRV * -smbc_attr_server(SMBCCTX *context, - const char *server, - const char *share, - char *workgroup, - char *username, - char *password, - POLICY_HND *pol) +smbc_attr_server(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password, + POLICY_HND *pol) { int flags; struct sockaddr_storage ss; @@ -1008,27 +1052,19 @@ smbc_attr_server(SMBCCTX *context, * our "special" share name '*IPC$', which is an impossible real share * name due to the leading asterisk. */ - ipc_srv = find_server(context, server, "*IPC$", - workgroup, username, password); + ipc_srv = find_server(ctx, context, server, "*IPC$", + pp_workgroup, pp_username, pp_password); if (!ipc_srv) { /* We didn't find a cached connection. Get the password */ - if (*password == '\0') { + if (!*pp_password || (*pp_password)[0] == '\0') { /* ... then retrieve it now. */ - if (context->internal->_auth_fn_with_context != NULL) { - (context->internal->_auth_fn_with_context)( - context, - server, share, - workgroup, strlen(workgroup)+1, - username, strlen(username)+1, - password, strlen(password)+1); - } else { - (context->callbacks.auth_fn)( - server, share, - workgroup, strlen(workgroup)+1, - username, strlen(username)+1, - password, strlen(password)+1); - } + call_auth_fn(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + return NULL; + } } flags = 0; @@ -1038,11 +1074,13 @@ smbc_attr_server(SMBCCTX *context, zero_addr(&ss); nt_status = cli_full_connection(&ipc_cli, - global_myname(), server, - &ss, 0, "IPC$", "?????", - username, workgroup, - password, flags, - Undefined, NULL); + global_myname(), server, + &ss, 0, "IPC$", "?????", + *pp_username, + *pp_workgroup, + *pp_password, + flags, + Undefined, NULL); if (! NT_STATUS_IS_OK(nt_status)) { DEBUG(1,("cli_full_connection failed! (%s)\n", nt_errstr(nt_status))); @@ -1053,9 +1091,9 @@ smbc_attr_server(SMBCCTX *context, if (context->internal->_smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, - username, - password, - workgroup))) { + *pp_username, + *pp_password, + *pp_workgroup))) { /* * context->internal->_smb_encryption_level == 1 @@ -1101,14 +1139,14 @@ smbc_attr_server(SMBCCTX *context, * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 * so we might as well do it too. */ - + nt_status = rpccli_lsa_open_policy( pipe_hnd, talloc_tos(), - True, + True, GENERIC_EXECUTE_ACCESS, pol); - + if (!NT_STATUS_IS_OK(nt_status)) { errno = smbc_errno(context, ipc_srv->cli); cli_shutdown(ipc_srv->cli); @@ -1120,10 +1158,10 @@ smbc_attr_server(SMBCCTX *context, errno = 0; /* let cache function set errno if it likes */ if ((context->callbacks.add_cached_srv_fn)(context, ipc_srv, - server, - "*IPC$", - workgroup, - username)) { + server, + "*IPC$", + *pp_workgroup, + *pp_username)) { DEBUG(3, (" Failed to add server to cache\n")); if (errno == 0) { errno = ENOMEM; @@ -1149,10 +1187,10 @@ smbc_open_ctx(SMBCCTX *context, int flags, mode_t mode) { - char *server, *share, *user, *password, *workgroup; - char *path; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; + char *path = NULL; char *targetpath = NULL; - struct cli_state *targetcli; + struct cli_state *targetcli = NULL; SMBCSRV *srv = NULL; SMBCFILE *file = NULL; int fd; @@ -1199,8 +1237,8 @@ smbc_open_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { if (errno == EPERM) errno = EACCES; @@ -1343,10 +1381,10 @@ smbc_read_ctx(SMBCCTX *context, size_t count) { int ret; - char *server, *share, *user, *password; - char *path; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; char *targetpath = NULL; - struct cli_state *targetcli; + struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); /* @@ -1444,10 +1482,10 @@ smbc_write_ctx(SMBCCTX *context, { int ret; off_t offset; - char *server, *share, *user, *password; - char *path; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; char *targetpath = NULL; - struct cli_state *targetcli; + struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); /* First check all pointers before dereferencing them */ @@ -1526,10 +1564,10 @@ smbc_close_ctx(SMBCCTX *context, SMBCFILE *file) { SMBCSRV *srv; - char *server, *share, *user, *password; - char *path; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; char *targetpath = NULL; - struct cli_state *targetcli; + struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || @@ -1618,9 +1656,9 @@ smbc_getatr(SMBCCTX * context, struct timespec *change_time_ts, SMB_INO_T *ino) { - char *fixedpath; + char *fixedpath = NULL; char *targetpath = NULL; - struct cli_state *targetcli; + struct cli_state *targetcli = NULL; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); @@ -1689,11 +1727,11 @@ smbc_getatr(SMBCCTX * context, if (create_time_ts != NULL) { *create_time_ts = w_time_ts; } - + if (access_time_ts != NULL) { *access_time_ts = w_time_ts; } - + if (change_time_ts != NULL) { *change_time_ts = w_time_ts; } @@ -1804,10 +1842,10 @@ static int smbc_unlink_ctx(SMBCCTX *context, const char *fname) { - char *server, *share, *user, *password, *workgroup; - char *path; - char *targetpath; - struct cli_state *targetcli; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); @@ -1850,8 +1888,8 @@ smbc_unlink_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); @@ -1926,21 +1964,21 @@ smbc_rename_ctx(SMBCCTX *ocontext, SMBCCTX *ncontext, const char *nname) { - char *server1; - char *share1; - char *server2; - char *share2; - char *user1; - char *user2; - char *password1; - char *password2; - char *workgroup; - char *path1; - char *path2; - char *targetpath1; - char *targetpath2; - struct cli_state *targetcli1; - struct cli_state *targetcli2; + char *server1 = NULL; + char *share1 = NULL; + char *server2 = NULL; + char *share2 = NULL; + char *user1 = NULL; + char *user2 = NULL; + char *password1 = NULL; + char *password2 = NULL; + char *workgroup = NULL; + char *path1 = NULL; + char *path2 = NULL; + char *targetpath1 = NULL; + char *targetpath2 = NULL; + struct cli_state *targetcli1 = NULL; + struct cli_state *targetcli2 = NULL; SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); @@ -2017,8 +2055,8 @@ smbc_rename_ctx(SMBCCTX *ocontext, return -1; } - srv = smbc_server(ocontext, True, - server1, share1, workgroup, user1, password1); + srv = smbc_server(frame, ocontext, True, + server1, share1, &workgroup, &user1, &password1); if (!srv) { TALLOC_FREE(frame); return -1; @@ -2080,10 +2118,10 @@ smbc_lseek_ctx(SMBCCTX *context, int whence) { SMB_OFF_T size; - char *server, *share, *user, *password; - char *path; - char *targetpath; - struct cli_state *targetcli; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || @@ -2253,13 +2291,13 @@ smbc_stat_ctx(SMBCCTX *context, const char *fname, struct stat *st) { - SMBCSRV *srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; struct timespec write_time_ts; struct timespec access_time_ts; struct timespec change_time_ts; @@ -2308,8 +2346,8 @@ smbc_stat_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); @@ -2355,13 +2393,13 @@ smbc_fstat_ctx(SMBCCTX *context, struct timespec write_time_ts; SMB_OFF_T size; uint16 mode; - char *server; - char *share; - char *user; - char *password; - char *path; - char *targetpath; - struct cli_state *targetcli; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); @@ -2743,14 +2781,14 @@ smbc_opendir_ctx(SMBCCTX *context, const char *fname) { int saved_errno; - char *server, *share, *user, *password, *options; - char *workgroup; - char *path; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *options = NULL; + char *workgroup = NULL; + char *path = NULL; uint16 mode; - char *p; + char *p = NULL; SMBCSRV *srv = NULL; SMBCFILE *dir = NULL; - struct _smbc_callbacks *cb; + struct _smbc_callbacks *cb = NULL; struct sockaddr_storage rem_ss; TALLOC_CTX *frame = talloc_stackframe(); @@ -2939,8 +2977,8 @@ smbc_opendir_ctx(SMBCCTX *context, * workgroups/domains that it knows about. */ - srv = smbc_server(context, True, server, "IPC$", - workgroup, user, password); + srv = smbc_server(frame, context, True, server, "IPC$", + &workgroup, &user, &password); if (!srv) { continue; } @@ -2993,8 +3031,8 @@ smbc_opendir_ctx(SMBCCTX *context, * establish a connection if one does not already * exist. */ - srv = smbc_server(context, False, server, "IPC$", - workgroup, user, password); + srv = smbc_server(frame, context, False, server, "IPC$", + &workgroup, &user, &password); /* * If no existing server and not an IP addr, look for @@ -3032,9 +3070,9 @@ smbc_opendir_ctx(SMBCCTX *context, * Get a connection to IPC$ on the server if * we do not already have one */ - srv = smbc_server(context, True, + srv = smbc_server(frame, context, True, buserver, "IPC$", - workgroup, user, password); + &workgroup, &user, &password); if (!srv) { DEBUG(0, ("got no contact to IPC$\n")); if (dir) { @@ -3065,10 +3103,10 @@ smbc_opendir_ctx(SMBCCTX *context, /* If we hadn't found the server, get one now */ if (!srv) { - srv = smbc_server(context, True, + srv = smbc_server(frame, context, True, server, "IPC$", - workgroup, - user, password); + &workgroup, + &user, &password); } if (!srv) { @@ -3127,8 +3165,8 @@ smbc_opendir_ctx(SMBCCTX *context, /* We connect to the server and list the directory */ dir->dir_type = SMBC_FILE_SHARE; - srv = smbc_server(context, True, server, share, - workgroup, user, password); + srv = smbc_server(frame, context, True, server, share, + &workgroup, &user, &password); if (!srv) { if (dir) { @@ -3495,15 +3533,15 @@ smbc_mkdir_ctx(SMBCCTX *context, const char *fname, mode_t mode) { - SMBCSRV *srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; - char *targetpath; - struct cli_state *targetcli; + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || @@ -3545,8 +3583,8 @@ smbc_mkdir_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { @@ -3603,15 +3641,15 @@ static int smbc_rmdir_ctx(SMBCCTX *context, const char *fname) { - SMBCSRV *srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; - char *targetpath; - struct cli_state *targetcli; + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || @@ -3653,8 +3691,8 @@ smbc_rmdir_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { @@ -3888,13 +3926,13 @@ smbc_chmod_ctx(SMBCCTX *context, const char *fname, mode_t newmode) { - SMBCSRV *srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; uint16 mode; TALLOC_CTX *frame = talloc_stackframe(); @@ -3937,8 +3975,8 @@ smbc_chmod_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); @@ -3967,13 +4005,13 @@ smbc_utimes_ctx(SMBCCTX *context, const char *fname, struct timeval *tbuf) { - SMBCSRV *srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; time_t access_time; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); @@ -4043,8 +4081,8 @@ smbc_utimes_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); @@ -5679,16 +5717,16 @@ smbc_setxattr_ctx(SMBCCTX *context, { int ret; int ret2; - SMBCSRV *srv; - SMBCSRV *ipc_srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; POLICY_HND pol; - DOS_ATTR_DESC *dad; + DOS_ATTR_DESC *dad = NULL; struct { const char * create_time_attr; const char * access_time_attr; @@ -5737,16 +5775,16 @@ smbc_setxattr_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password, + ipc_srv = smbc_attr_server(frame, context, server, share, + &workgroup, &user, &password, &pol); if (! ipc_srv) { srv->no_nt_session = True; @@ -5977,14 +6015,14 @@ smbc_getxattr_ctx(SMBCCTX *context, size_t size) { int ret; - SMBCSRV *srv; - SMBCSRV *ipc_srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; POLICY_HND pol; struct { const char * create_time_attr; @@ -6033,16 +6071,16 @@ smbc_getxattr_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password, + ipc_srv = smbc_attr_server(frame, context, server, share, + &workgroup, &user, &password, &pol); if (! ipc_srv) { srv->no_nt_session = True; @@ -6119,14 +6157,14 @@ smbc_removexattr_ctx(SMBCCTX *context, const char *name) { int ret; - SMBCSRV *srv; - SMBCSRV *ipc_srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; POLICY_HND pol; TALLOC_CTX *frame = talloc_stackframe(); @@ -6169,16 +6207,16 @@ smbc_removexattr_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by smbc_server */ } if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(context, server, share, - workgroup, user, password, + ipc_srv = smbc_attr_server(frame, context, server, share, + &workgroup, &user, &password, &pol); if (! ipc_srv) { srv->no_nt_session = True; @@ -6311,11 +6349,11 @@ static SMBCFILE * smbc_open_print_job_ctx(SMBCCTX *context, const char *fname) { - char *server; - char *share; - char *user; - char *password; - char *path; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || @@ -6454,13 +6492,13 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, const char *fname, smbc_list_print_job_fn fn) { - SMBCSRV *srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || @@ -6502,8 +6540,8 @@ smbc_list_print_jobs_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); @@ -6531,13 +6569,13 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, const char *fname, int id) { - SMBCSRV *srv; - char *server; - char *share; - char *user; - char *password; - char *workgroup; - char *path; + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; int err; TALLOC_CTX *frame = talloc_stackframe(); @@ -6580,8 +6618,8 @@ smbc_unlink_print_job_ctx(SMBCCTX *context, } } - srv = smbc_server(context, True, - server, share, workgroup, user, password); + srv = smbc_server(frame, context, True, + server, share, &workgroup, &user, &password); if (!srv) { -- cgit From d06559c1e6ac0d9a9092e21c703397eb588aef94 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 16 Jan 2008 15:52:53 +0100 Subject: Make resolve_ads() static. Guenther (This used to be commit 57dc747136e880a25c03bdc4a1431fc41afd93a1) --- source3/libsmb/namequery.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index ad999b34b4..ad16452e3e 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1299,11 +1299,11 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, Resolve via "ADS" method. *********************************************************/ -NTSTATUS resolve_ads(const char *name, - int name_type, - const char *sitename, - struct ip_service **return_iplist, - int *return_count) +static NTSTATUS resolve_ads(const char *name, + int name_type, + const char *sitename, + struct ip_service **return_iplist, + int *return_count) { int i, j; NTSTATUS status; -- cgit From f44713df4d636203354c55d9a9bc2538073cf0af Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 16 Jan 2008 17:33:19 -0800 Subject: Fix bug found by Derrell - windows returns an read return offset of zero if return size is zero. Should fix testread libsmbclient code. Jeremy. (This used to be commit df3c4648399f8d62ff6fe0013be8b89abc18f0f0) --- source3/libsmb/clireadwrite.c | 49 ++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 6b39a885f0..af13ed8f73 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -134,6 +134,8 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return -1; } + /* size2 is the number of bytes the server returned. + * Might be zero. */ size2 = SVAL(cli->inbuf, smb_vwv5); size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7))) << 16); @@ -145,27 +147,32 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_ return -1; } - if (!direct_reads) { - /* Copy data into buffer */ - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - memcpy(buf + total, p, size2); - } else { - /* Ensure the remaining data matches the return size. */ - ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6); - - /* Ensure the size is correct. */ - if (toread != size2) { - DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n", - (int)toread, (unsigned int)size2 )); - return -1; - } - - /* Read data directly into buffer */ - toread = cli_receive_smb_data(cli,buf+total,size2); - if (toread != size2) { - DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n", - (int)toread, (unsigned int)size2 )); - return -1; + if (size2) { + /* smb_vwv6 is the offset in the packet of the returned + * data bytes. Only valid if size2 != 0. */ + + if (!direct_reads) { + /* Copy data into buffer */ + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf + total, p, size2); + } else { + /* Ensure the remaining data matches the return size. */ + ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6); + + /* Ensure the size is correct. */ + if (toread != size2) { + DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n", + (int)toread, (unsigned int)size2 )); + return -1; + } + + /* Read data directly into buffer */ + toread = cli_receive_smb_data(cli,buf+total,size2); + if (toread != size2) { + DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n", + (int)toread, (unsigned int)size2 )); + return -1; + } } } -- cgit From 096e40c9169b2121a82c42d3cf31cbfb869603ce Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 17 Jan 2008 09:29:13 -0500 Subject: Fix stat results to be consistent between smbc_stat and smbc_fstat. We create a kludged inode based on the checksum of the path. We therefore need to use the same (full) path when calculating it in both smbc_stat() and smbc_fstat(). If struct stat has an rdev field, set it to zero. Derrell (This used to be commit b4282fbd6d27d868b2d5c04bb72d2d7421822da1) --- source3/libsmb/libsmbclient.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index fb04d143a5..077970647d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2263,6 +2263,9 @@ smbc_setup_stat(SMBCCTX *context, #endif #ifdef HAVE_STAT_ST_BLOCKS st->st_blocks = (size+511)/512; +#endif +#ifdef HAVE_STRUCT_STAT_ST_RDEV + st->st_rdev = 0; #endif st->st_uid = getuid(); st->st_gid = getgid(); @@ -2367,7 +2370,7 @@ smbc_stat_ctx(SMBCCTX *context, st->st_ino = ino; - smbc_setup_stat(context, st, path, size, mode); + smbc_setup_stat(context, st, (char *) fname, size, mode); set_atimespec(st, access_time_ts); set_ctimespec(st, change_time_ts); -- cgit From 4f09727df8502c3a66cbf0cb423da1067d215c90 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 17 Jan 2008 11:49:17 -0500 Subject: Fix bug 5185: repeated calls to smbc_getxattr() lose sid-name mapping If we're going to cache connections to IPC$, we'd better also cache the policy handle and not use a stack-based handle that's invalid on subsequent calls. Derrell (This used to be commit 67c415661f6466c21cd0eaafabe58cba049d2af3) --- source3/libsmb/libsmbclient.c | 83 +++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 46 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 077970647d..2fd8294d04 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -1037,8 +1037,7 @@ smbc_attr_server(TALLOC_CTX *ctx, const char *share, char **pp_workgroup, char **pp_username, - char **pp_password, - POLICY_HND *pol) + char **pp_password) { int flags; struct sockaddr_storage ss; @@ -1122,36 +1121,34 @@ smbc_attr_server(TALLOC_CTX *ctx, ZERO_STRUCTP(ipc_srv); ipc_srv->cli = ipc_cli; - if (pol) { - pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, - PI_LSARPC, - &nt_status); - if (!pipe_hnd) { - DEBUG(1, ("cli_nt_session_open fail!\n")); - errno = ENOTSUP; - cli_shutdown(ipc_srv->cli); - free(ipc_srv); - return NULL; - } - - /* - * Some systems don't support - * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 - * so we might as well do it too. - */ + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, + PI_LSARPC, + &nt_status); + if (!pipe_hnd) { + DEBUG(1, ("cli_nt_session_open fail!\n")); + errno = ENOTSUP; + cli_shutdown(ipc_srv->cli); + free(ipc_srv); + return NULL; + } - nt_status = rpccli_lsa_open_policy( - pipe_hnd, - talloc_tos(), - True, - GENERIC_EXECUTE_ACCESS, - pol); + /* + * Some systems don't support + * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 + * so we might as well do it too. + */ - if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, ipc_srv->cli); - cli_shutdown(ipc_srv->cli); - return NULL; - } + nt_status = rpccli_lsa_open_policy( + pipe_hnd, + talloc_tos(), + True, + GENERIC_EXECUTE_ACCESS, + &ipc_srv->pol); + + if (!NT_STATUS_IS_OK(nt_status)) { + errno = smbc_errno(context, ipc_srv->cli); + cli_shutdown(ipc_srv->cli); + return NULL; } /* now add it to the cache (internal or external) */ @@ -5728,7 +5725,6 @@ smbc_setxattr_ctx(SMBCCTX *context, char *password = NULL; char *workgroup = NULL; char *path = NULL; - POLICY_HND pol; DOS_ATTR_DESC *dad = NULL; struct { const char * create_time_attr; @@ -5787,8 +5783,7 @@ smbc_setxattr_ctx(SMBCCTX *context, if (! srv->no_nt_session) { ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password, - &pol); + &workgroup, &user, &password); if (! ipc_srv) { srv->no_nt_session = True; } @@ -5814,7 +5809,7 @@ smbc_setxattr_ctx(SMBCCTX *context, if (ipc_srv) { ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &pol, path, + ipc_srv->cli, &ipc_srv->pol, path, namevalue, (*namevalue == '*' ? SMBC_XATTR_MODE_SET @@ -5878,7 +5873,7 @@ smbc_setxattr_ctx(SMBCCTX *context, ret = -1; } else { ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &pol, path, + ipc_srv->cli, &ipc_srv->pol, path, namevalue, (*namevalue == '*' ? SMBC_XATTR_MODE_SET @@ -5908,7 +5903,7 @@ smbc_setxattr_ctx(SMBCCTX *context, ret = -1; } else { ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &pol, path, + ipc_srv->cli, &ipc_srv->pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } TALLOC_FREE(frame); @@ -5935,7 +5930,7 @@ smbc_setxattr_ctx(SMBCCTX *context, ret = -1; } else { ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &pol, path, + ipc_srv->cli, &ipc_srv->pol, path, namevalue, SMBC_XATTR_MODE_CHOWN, 0); } TALLOC_FREE(frame); @@ -6026,7 +6021,6 @@ smbc_getxattr_ctx(SMBCCTX *context, char *password = NULL; char *workgroup = NULL; char *path = NULL; - POLICY_HND pol; struct { const char * create_time_attr; const char * access_time_attr; @@ -6083,8 +6077,7 @@ smbc_getxattr_ctx(SMBCCTX *context, if (! srv->no_nt_session) { ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password, - &pol); + &workgroup, &user, &password); if (! ipc_srv) { srv->no_nt_session = True; } @@ -6137,7 +6130,7 @@ smbc_getxattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_get(context, talloc_tos(), srv, ipc_srv == NULL ? NULL : ipc_srv->cli, - &pol, path, + &ipc_srv->pol, path, CONST_DISCARD(char *, name), CONST_DISCARD(char *, value), size); if (ret < 0 && errno == 0) { @@ -6168,7 +6161,6 @@ smbc_removexattr_ctx(SMBCCTX *context, char *password = NULL; char *workgroup = NULL; char *path = NULL; - POLICY_HND pol; TALLOC_CTX *frame = talloc_stackframe(); if (!context || !context->internal || @@ -6219,8 +6211,7 @@ smbc_removexattr_ctx(SMBCCTX *context, if (! srv->no_nt_session) { ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password, - &pol); + &workgroup, &user, &password); if (! ipc_srv) { srv->no_nt_session = True; } @@ -6239,7 +6230,7 @@ smbc_removexattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &pol, path, + ipc_srv->cli, &ipc_srv->pol, path, NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); TALLOC_FREE(frame); return ret; @@ -6259,7 +6250,7 @@ smbc_removexattr_ctx(SMBCCTX *context, /* Yup. */ ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &pol, path, + ipc_srv->cli, &ipc_srv->pol, path, name + 19, SMBC_XATTR_MODE_REMOVE, 0); TALLOC_FREE(frame); return ret; -- cgit From 80d7cccfe7d6179da75c00481f2116dae6755682 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 18 Jan 2008 01:04:40 +0100 Subject: Add and correct some WERROR codes. Michael (This used to be commit 7aec862ddc2aa2b5152c3a452971e55ba43646a5) --- source3/libsmb/doserr.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 79445a2410..174db312c8 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -74,7 +74,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, - { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, + { "WERR_DC_NOT_FOUND", WERR_DC_NOT_FOUND }, { "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED }, { "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED }, { "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER }, @@ -96,6 +96,9 @@ werror_code_struct dos_errs[] = { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE}, { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS}, + { "WERR_PASSWORD_MUST_CHANGE", WERR_PASSWORD_MUST_CHANGE }, + { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, + { "WERR_ACCOUNT_LOCKED_OUT", WERR_ACCOUNT_LOCKED_OUT }, { NULL, W_ERROR(0) } }; @@ -109,11 +112,14 @@ werror_str_struct dos_err_strs[] = { { WERR_NO_LOGON_SERVERS, "No logon servers found" }, { WERR_NO_SUCH_LOGON_SESSION, "No such logon session" }, { WERR_DOMAIN_CONTROLLER_NOT_FOUND, "A domain controller could not be found" }, + { WERR_DC_NOT_FOUND, "A domain controller could not be found" }, { WERR_SETUP_NOT_JOINED, "Join failed" }, { WERR_SETUP_ALREADY_JOINED, "Machine is already joined" }, { WERR_SETUP_DOMAIN_CONTROLLER, "Machine is a Domain Controller" }, { WERR_LOGON_FAILURE, "Invalid logon credentials" }, { WERR_USER_EXISTS, "User account already exists" }, + { WERR_PASSWORD_MUST_CHANGE, "The password must be changed" }, + { WERR_ACCOUNT_LOCKED_OUT, "Account locked out" }, }; /***************************************************************************** -- cgit From 3d3d6e7020749c63455e16ba110bc46862d3c146 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 18 Jan 2008 11:08:17 +0100 Subject: Add the "allinfo" command to smbclient Modeled after the Samba4 allinfo command (This used to be commit 3fa0cf3fe5f819f6e76df6f7cef3bb4e1c307a52) --- source3/libsmb/clirap.c | 131 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index aab77a3d54..4c5e338606 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -805,6 +805,137 @@ bool cli_qpathinfo2(struct cli_state *cli, const char *fname, return True; } +/**************************************************************************** + Get the stream info +****************************************************************************/ + +bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname, + TALLOC_CTX *mem_ctx, + unsigned int *pnum_streams, + struct stream_struct **pstreams) +{ + unsigned int data_len = 0; + unsigned int param_len = 0; + uint16 setup = TRANSACT2_QPATHINFO; + char *param; + char *rparam=NULL, *rdata=NULL; + char *p; + unsigned int num_streams; + struct stream_struct *streams; + unsigned int ofs; + size_t namelen = 2*(strlen(fname)+1); + + param = SMB_MALLOC_ARRAY(char, 6+namelen+2); + if (param == NULL) { + return false; + } + p = param; + memset(p, 0, 6); + SSVAL(p, 0, SMB_FILE_STREAM_INFORMATION); + p += 6; + p += clistr_push(cli, p, fname, namelen, STR_TERMINATE); + + param_len = PTR_DIFF(p, param); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, len, max */ + param, param_len, 10, /* param, len, max */ + NULL, data_len, cli->max_xmit /* data, len, max */ + )) { + return false; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + return false; + } + + if (!rdata) { + SAFE_FREE(rparam); + return false; + } + + num_streams = 0; + streams = NULL; + ofs = 0; + + while ((data_len > ofs) && (data_len - ofs >= 24)) { + uint32_t nlen, len; + ssize_t size; + void *vstr; + struct stream_struct *tmp; + uint8_t *tmp_buf; + + tmp = TALLOC_REALLOC_ARRAY(mem_ctx, streams, + struct stream_struct, + num_streams+1); + + if (tmp == NULL) { + goto fail; + } + streams = tmp; + + nlen = IVAL(rdata, ofs + 0x04); + + streams[num_streams].size = IVAL_TO_SMB_OFF_T( + rdata, ofs + 0x08); + streams[num_streams].alloc_size = IVAL_TO_SMB_OFF_T( + rdata, ofs + 0x10); + + if (nlen > data_len - (ofs + 24)) { + goto fail; + } + + /* + * We need to null-terminate src, how do I do this with + * convert_string_talloc?? + */ + + tmp_buf = TALLOC_ARRAY(streams, uint8_t, nlen+2); + if (tmp_buf == NULL) { + goto fail; + } + + memcpy(tmp_buf, rdata+ofs+24, nlen); + tmp_buf[nlen] = 0; + tmp_buf[nlen+1] = 0; + + size = convert_string_talloc(streams, CH_UTF16, CH_UNIX, + tmp_buf, nlen+2, &vstr, + false); + TALLOC_FREE(tmp_buf); + + if (size == -1) { + goto fail; + } + streams[num_streams].name = (char *)vstr; + num_streams++; + + len = IVAL(rdata, ofs); + if (len > data_len - ofs) { + goto fail; + } + if (len == 0) break; + ofs += len; + } + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + *pnum_streams = num_streams; + *pstreams = streams; + return true; + + fail: + TALLOC_FREE(streams); + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return false; +} + /**************************************************************************** Send a qfileinfo QUERY_FILE_NAME_INFO call. ****************************************************************************/ -- cgit From bb707b1db6add166a7887284281fa4b65776be08 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 18 Jan 2008 14:22:49 -0500 Subject: Fix typo that disabled setting group id. Thanks, Henrik. (This used to be commit 843e1694cfe4a999ed14a9c215b8e77723d0fe79) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2fd8294d04..fbcb7f64e2 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -5931,7 +5931,7 @@ smbc_setxattr_ctx(SMBCCTX *context, } else { ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, - namevalue, SMBC_XATTR_MODE_CHOWN, 0); + namevalue, SMBC_XATTR_MODE_CHGRP, 0); } TALLOC_FREE(frame); return ret; -- cgit From a925a53f61ebdc6b4386b7c0853f2f87cbe2e166 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 16:42:31 +0100 Subject: read_socket_with_timeout has timeout=0 handling (This used to be commit 7101026061c470ed962267b43ac0aa67cc761a64) --- source3/libsmb/clientgen.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ecef293d07..042b3bdfb0 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -180,12 +180,8 @@ bool cli_receive_smb(struct cli_state *cli) ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) { - if (cli->timeout > 0) { - return read_socket_with_timeout(cli->fd, buffer, len, - len, cli->timeout, &cli->smb_rw_error); - } else { - return read_data(cli->fd, buffer, len, &cli->smb_rw_error); - } + return read_socket_with_timeout(cli->fd, buffer, len, len, + cli->timeout, &cli->smb_rw_error); } /**************************************************************************** -- cgit From 691c4b1a4175e3d4a073c396a2a7d8d315cd42bd Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 17 Jan 2008 10:11:11 +0100 Subject: Windows 2008 (Longhorn) auth2 flag fixes. Interop fixes for AD specific flags. Original patch from Todd Stetcher. (This used to be commit 5aadfcdaacd6f136eab9e107a88b8544e6d2105f) --- source3/libsmb/trusts_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 732dc78c75..1ca7d56a83 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -40,7 +40,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX already have valid creds. If not we must set them up. */ if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - uint32 neg_flags = NETLOGON_NEG_AUTH2_FLAGS; + uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; result = rpccli_netlogon_setup_creds(cli, cli->cli->desthost, /* server name */ -- cgit From cfe7b54e96d39d19ad6b28c0d7db380907171e21 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 17 Jan 2008 11:35:40 +0100 Subject: Fix Windows 2008 (Longhorn) join. During 'net ads join' the cli->desthost is a hostname (e.g. rupert.galaxy.site). Check if we have a hostname and use only the first part, the machine name, of the string. (This used to be commit 5f60ed4af680ba2811db8d9f8267348ce05f26d2) --- source3/libsmb/cliconnect.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4560521d4a..de5813df6b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -872,13 +872,26 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, !strequal(star_smbserver_name, cli->desthost)) { char *realm = NULL; + char *machine = NULL; + char *host = NULL; DEBUG(3,("cli_session_setup_spnego: got a " "bad server principal, trying to guess ...\n")); + host = strchr(cli->desthost, '.'); + if (host) { + machine = SMB_STRNDUP(cli->desthost, + host - cli->desthost); + } else { + machine = SMB_STRDUP(cli->desthost); + } + if (machine == NULL) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } + realm = kerberos_get_default_realm_from_ccache(); if (realm && *realm) { if (asprintf(&principal, "%s$@%s", - cli->desthost, realm) < 0) { + machine, realm) < 0) { SAFE_FREE(realm); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } @@ -886,6 +899,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, "server principal=%s\n", principal ? principal : "")); } + SAFE_FREE(machine); SAFE_FREE(realm); } -- cgit From fe8a8f47e0eefd064031e87fec4cdd2736716550 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jan 2008 15:00:40 -0800 Subject: Use strchr_m in seaching for '.' in the hostname to make sure we're mb safe. Jeremy. (This used to be commit 090061b73a1c086ff8a7797e1a63532eacd91148) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index de5813df6b..fd860ae7f0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -877,7 +877,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, DEBUG(3,("cli_session_setup_spnego: got a " "bad server principal, trying to guess ...\n")); - host = strchr(cli->desthost, '.'); + host = strchr_m(cli->desthost, '.'); if (host) { machine = SMB_STRNDUP(cli->desthost, host - cli->desthost); -- cgit From ffc84a10447a1bd3329b874b9e1bd4c6e6c2ff66 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Jan 2008 15:23:16 -0800 Subject: Don't leak memory in error path. Jeremy. (This used to be commit 2df0cdaafdced798f81e30d34371aa1d8e963208) --- source3/libsmb/cliconnect.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index fd860ae7f0..f3926b777b 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -892,6 +892,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, if (realm && *realm) { if (asprintf(&principal, "%s$@%s", machine, realm) < 0) { + SAFE_FREE(machine); SAFE_FREE(realm); return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } -- cgit From e0021b586d0c882fcc5ce0566dbbbd76f163d170 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 23 Jan 2008 20:44:54 -0500 Subject: Allow clearing all settable DOS mode bits. A mode value of zero is ignored by Windows. If the requested mode is zero, we instead send the appropriate one of 0x80 (NORMAL) or 0x10 (DIRECTORY). Thanks Jeremy! Derrell (This used to be commit 54abf7d0e595e9cbeea115a40d4f7b995252a150) --- source3/libsmb/libsmbclient.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index fbcb7f64e2..2eb580a52d 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -4689,7 +4689,15 @@ dos_attr_parse(SMBCCTX *context, frame = talloc_stackframe(); while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { if (StrnCaseCmp(tok, "MODE:", 5) == 0) { - dad->mode = strtol(tok+5, NULL, 16); + long request = strtol(tok+5, NULL, 16); + if (request == 0) { + dad->mode = (request | + (IS_DOS_DIR(dad->mode) + ? FILE_ATTRIBUTE_DIRECTORY + : FILE_ATTRIBUTE_NORMAL)); + } else { + dad->mode = request; + } continue; } -- cgit From 372f74bba2650cb4f4c8f262c6cf8d761a753e81 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 24 Jan 2008 23:39:38 +0100 Subject: Add WERR_INVALID_COMPUTER_NAME. Guenther (This used to be commit cb1ff32eff06031150a6821658152e02a4077bbd) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 174db312c8..a3043a2152 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -73,6 +73,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, + { "WERR_INVALID_COMPUTER_NAME", WERR_INVALID_COMPUTER_NAME }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, { "WERR_DC_NOT_FOUND", WERR_DC_NOT_FOUND }, { "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED }, -- cgit From 54db1839878641be1a9987ad3e0ddedbd6123b7c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 27 Jan 2008 17:31:56 +1100 Subject: Adding missing calls to va_end(). Just a small commit to get a handle on this git thingy. This patch fixes some missing calls to va_end() to match various calls to va_start() and VA_COPY(). Tim. (This used to be commit ec367f307dff7948722b9ac97beb960efd91991f) --- source3/libsmb/ntlmssp_parse.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp_parse.c b/source3/libsmb/ntlmssp_parse.c index ac8846ad1e..70377cba7d 100644 --- a/source3/libsmb/ntlmssp_parse.c +++ b/source3/libsmb/ntlmssp_parse.c @@ -170,6 +170,7 @@ bool msrpc_gen(DATA_BLOB *blob, /* a helpful macro to avoid running over the end of our blob */ #define NEED_DATA(amount) \ if ((head_ofs + amount) > blob->length) { \ + va_end(ap); \ return False; \ } @@ -216,16 +217,20 @@ bool msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + va_end(ap); return false; } if (len1 & 1) { /* if odd length and unicode */ + va_end(ap); return false; } if (blob->data + ptr < (uint8 *)(unsigned long)ptr || - blob->data + ptr < blob->data) + blob->data + ptr < blob->data) { + va_end(ap); return false; + } if (0 < len1) { char *p = NULL; @@ -261,13 +266,16 @@ bool msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + va_end(ap); return false; } if (blob->data + ptr < (uint8 *)(unsigned long)ptr || - blob->data + ptr < blob->data) + blob->data + ptr < blob->data) { + va_end(ap); return false; + } if (0 < len1) { char *p = NULL; @@ -304,13 +312,16 @@ bool msrpc_parse(const DATA_BLOB *blob, if ((len1 != len2) || (ptr + len1 < ptr) || (ptr + len1 < len1) || (ptr + len1 > blob->length)) { + va_end(ap); return false; } if (blob->data + ptr < (uint8 *)(unsigned long)ptr || - blob->data + ptr < blob->data) + blob->data + ptr < blob->data) { + va_end(ap); return false; + } *b = data_blob(blob->data + ptr, len1); } @@ -322,6 +333,7 @@ bool msrpc_parse(const DATA_BLOB *blob, NEED_DATA(len1); if (blob->data + head_ofs < (uint8 *)head_ofs || blob->data + head_ofs < blob->data) { + va_end(ap); return false; } @@ -337,7 +349,8 @@ bool msrpc_parse(const DATA_BLOB *blob, s = va_arg(ap, char *); if (blob->data + head_ofs < (uint8 *)head_ofs || - blob->data + head_ofs < blob->data) { + blob->data + head_ofs < blob->data) { + va_end(ap); return false; } @@ -351,11 +364,13 @@ bool msrpc_parse(const DATA_BLOB *blob, blob->length - head_ofs, STR_ASCII|STR_TERMINATE); if (ret == (size_t)-1 || p == NULL) { + va_end(ap); return false; } head_ofs += ret; if (strcmp(s, p) != 0) { TALLOC_FREE(p); + va_end(ap); return false; } TALLOC_FREE(p); -- cgit From 5ab43ae0d8e66a1fd4c877089df52282367be7dd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 26 Jan 2008 01:39:33 +0100 Subject: Eliminate remote tree of dsgetdcname (which will happen in libnetapi then). Guenther (This used to be commit fd490d236b1fb73a75c457b75128c9b98719418f) --- source3/libsmb/dsgetdcname.c | 114 ++++++------------------------------------- 1 file changed, 14 insertions(+), 100 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 2a66d51400..e0be76cc85 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -891,72 +891,27 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, } /******************************************************************** -********************************************************************/ - -NTSTATUS dsgetdcname_remote(TALLOC_CTX *mem_ctx, - const char *computer_name, - const char *domain_name, - struct GUID *domain_guid, - const char *site_name, - uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info) -{ - WERROR werr; - NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - struct cli_state *cli = NULL; - struct rpc_pipe_client *pipe_cli = NULL; - - status = cli_full_connection(&cli, NULL, computer_name, - NULL, 0, - "IPC$", "IPC", - "", - "", - "", - 0, Undefined, NULL); - - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - - pipe_cli = cli_rpc_pipe_open_noauth(cli, PI_NETLOGON, - &status); - if (!pipe_cli) { - goto done; - } - - werr = rpccli_netlogon_dsr_getdcname(pipe_cli, - mem_ctx, - computer_name, - domain_name, - domain_guid, - NULL, - flags, - info); - status = werror_to_ntstatus(werr); - - done: - cli_rpc_pipe_close(pipe_cli); - if (cli) { - cli_shutdown(cli); - } - - return status; -} + dsgetdcname. -/******************************************************************** + This will be the only public function here. ********************************************************************/ -NTSTATUS dsgetdcname_local(TALLOC_CTX *mem_ctx, - const char *computer_name, - const char *domain_name, - struct GUID *domain_guid, - const char *site_name, - uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info) +NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, + const char *domain_name, + struct GUID *domain_guid, + const char *site_name, + uint32_t flags, + struct DS_DOMAIN_CONTROLLER_INFO **info) { NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct DS_DOMAIN_CONTROLLER_INFO *myinfo = NULL; + DEBUG(10,("dsgetdcname: domain_name: %s, " + "domain_guid: %s, site_name: %s, flags: 0x%08x\n", + domain_name, + domain_guid ? GUID_string(mem_ctx, domain_guid) : "(null)", + site_name, flags)); + *info = NULL; if (!check_allowed_required_flags(flags)) { @@ -991,44 +946,3 @@ NTSTATUS dsgetdcname_local(TALLOC_CTX *mem_ctx, return status; } - -/******************************************************************** - dsgetdcname. - - This will be the only public function here. -********************************************************************/ - -NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, - const char *computer_name, - const char *domain_name, - struct GUID *domain_guid, - const char *site_name, - uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info) -{ - DEBUG(10,("dsgetdcname: computer_name: %s, domain_name: %s, " - "domain_guid: %s, site_name: %s, flags: 0x%08x\n", - computer_name, domain_name, - domain_guid ? GUID_string(mem_ctx, domain_guid) : "(null)", - site_name, flags)); - - *info = NULL; - - if (computer_name) { - return dsgetdcname_remote(mem_ctx, - computer_name, - domain_name, - domain_guid, - site_name, - flags, - info); - } - - return dsgetdcname_local(mem_ctx, - computer_name, - domain_name, - domain_guid, - site_name, - flags, - info); -} -- cgit From 5e43eeb1b6eef7ea7a88ffc51a0a0535e9bd8023 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:41:48 +0100 Subject: Get rid of read_socket_with_timeout (This used to be commit f9c8ac83ff42137d2101d3bb17e5dcc3c3d70a8f) --- source3/libsmb/clientgen.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 042b3bdfb0..086c158ed2 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -180,8 +180,28 @@ bool cli_receive_smb(struct cli_state *cli) ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) { - return read_socket_with_timeout(cli->fd, buffer, len, len, - cli->timeout, &cli->smb_rw_error); + NTSTATUS status; + + set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); + + status = read_socket_with_timeout_ntstatus( + cli->fd, buffer, len, len, cli->timeout, NULL); + if (NT_STATUS_IS_OK(status)) { + return len; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(&cli->smb_rw_error, SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(&cli->smb_rw_error, SMB_READ_TIMEOUT); + return -1; + } + + set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR); + return -1; } /**************************************************************************** -- cgit From 6ddfa6ae7734ffdd26ac38478c27cc9d646ddadd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:43:50 +0100 Subject: read_socket_with_timeout_ntstatus->read_socket_with_timeout (This used to be commit 90554799afa42855c3e7b87dc632e67f0952f988) --- source3/libsmb/clientgen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 086c158ed2..7a7377f148 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -184,7 +184,7 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); - status = read_socket_with_timeout_ntstatus( + status = read_socket_with_timeout( cli->fd, buffer, len, len, cli->timeout, NULL); if (NT_STATUS_IS_OK(status)) { return len; -- cgit From 88c27f83d449fa20cba47cbf0a5dbaedc99859d8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 25 Jan 2008 23:54:22 +0100 Subject: Convert receive_smb_raw to NTSTATUS (This used to be commit ba771bd858602452a9e58c3aab1336f2ac8a25ef) --- source3/libsmb/clientgen.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 7a7377f148..3b7669f33e 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -69,15 +69,36 @@ int cli_set_port(struct cli_state *cli, int port) static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) { - ssize_t len; + size_t len; for(;;) { - len = receive_smb_raw(cli->fd, cli->inbuf, cli->timeout, - maxlen, &cli->smb_rw_error); + NTSTATUS status; - if (len < 0) { + set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); + + status = receive_smb_raw(cli->fd, cli->inbuf, cli->timeout, + maxlen, &len); + if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("client_receive_smb failed\n")); show_msg(cli->inbuf); + + if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { + set_smb_read_error(&cli->smb_rw_error, + SMB_READ_EOF); + return -1; + } + + if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { + set_smb_read_error(&cli->smb_rw_error, + SMB_READ_TIMEOUT); + return -1; + } + + set_smb_read_error(&cli->smb_rw_error, SMB_READ_ERROR); + return -1; + } + + if (len < 0) { return len; } -- cgit From 2a6a2288c5fae908f431bd79332554e0a23dbeed Mon Sep 17 00:00:00 2001 From: Karolin Seeger Date: Fri, 8 Feb 2008 09:28:57 +0100 Subject: Fix some typos. Karolin (This used to be commit 2bec0a1fb7857e6fb8ec15e5f597b2d4125f105b) --- source3/libsmb/libsmbclient.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index 2eb580a52d..e84de59637 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -6797,7 +6797,7 @@ smbc_free_context(SMBCCTX *context, SAFE_FREE(context->netbios_name); SAFE_FREE(context->user); - DEBUG(3, ("Context %p succesfully freed\n", context)); + DEBUG(3, ("Context %p successfully freed\n", context)); SAFE_FREE(context->internal); SAFE_FREE(context); return 0; -- cgit From c0e92cd4b8eae573848dc1587eecd2946715d754 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Feb 2008 10:07:05 -0800 Subject: Fix bug reported on IRC enumerating shares with OS/2. Report and fix from kukks (thanks once again !). Jeremy. (This used to be commit 3ca58b792fb10ff2a4c25283c587f8270ed82d74) --- source3/libsmb/clirap.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 4c5e338606..8c167e1257 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -191,12 +191,13 @@ int cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, co sname = p; type = SVAL(p,14); - comment_offset = IVAL(p,16) & 0xFFFF; - if (comment_offset < 0 || comment_offset > (int)rdrcnt) { + comment_offset = (IVAL(p,16) & 0xFFFF) - converter; + if (comment_offset < 0 || + comment_offset > (int)rdrcnt) { TALLOC_FREE(frame); break; } - cmnt = comment_offset?(rdata+comment_offset-converter):""; + cmnt = comment_offset?(rdata+comment_offset):""; /* Work out the comment length. */ for (p1 = cmnt, len = 0; *p1 && -- cgit From 48ea5852b6854f051754574b27807972426ebbbe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Feb 2008 11:22:53 -0800 Subject: Try and fix length and finfo calls for older clients. Working on issues reported by kukks. Jeremy. (This used to be commit dcd77dd4f480db3273a56c5740b6e5d78f8be4a9) --- source3/libsmb/clilist.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d5c7db09e9..2bad3e508b 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -459,11 +459,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, The length of the structure is returned. ****************************************************************************/ -static int interpret_short_filename(TALLOC_CTX *ctx, +static bool interpret_short_filename(TALLOC_CTX *ctx, struct cli_state *cli, char *p, file_info *finfo) { + size_t ret; ZERO_STRUCTP(finfo); finfo->cli = cli; @@ -475,18 +476,22 @@ static int interpret_short_filename(TALLOC_CTX *ctx, finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec; finfo->mtime_ts.tv_nsec = finfo->atime_ts.tv_nsec = 0; finfo->size = IVAL(p,26); - clistr_pull_talloc(ctx, + ret = clistr_pull_talloc(ctx, cli, &finfo->name, p+30, 12, STR_ASCII); - if (!finfo->name) { - finfo->name = talloc_strdup(ctx, finfo->short_name); - } else if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { - finfo->name = talloc_strdup(ctx, finfo->short_name); + if (ret == (size_t)-1) { + return false; } + if (finfo->name) { + strlcpy(finfo->short_name, + finfo->name, + sizeof(finfo->short_name)); + } + return true; return(DIR_STRUCT_SIZE); } @@ -555,6 +560,12 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, received = SVAL(cli->inbuf,smb_vwv0); if (received <= 0) break; + /* Ensure we received enough data. */ + if ((cli->inbuf+4+smb_len(cli->inbuf) - (smb_buf(cli->inbuf)+3)) < + received*DIR_STRUCT_SIZE) { + break; + } + first = False; dirlist = (char *)SMB_REALLOC( @@ -609,7 +620,10 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, frame = talloc_stackframe(); for (p=dirlist,i=0;i Date: Fri, 8 Feb 2008 18:44:33 -0800 Subject: From kukks - prevent crashes if finfo.name == NULL. Jeremy. (This used to be commit 101f194795f87c709abfdfbcde710131a88f9d20) --- source3/libsmb/clilist.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2bad3e508b..2b5e7518c5 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -377,6 +377,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &resume_key, &last_name_raw); + if (!finfo.name) { + DEBUG(0,("cli_list_new: Error: unable to parse name from info level %d\n", + info_level)); + ff_eos = 1; + break; + } if (!First && *mask && strcsequal(finfo.name, mask)) { DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n", finfo.name)); @@ -442,6 +448,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &finfo, NULL, NULL); + if (!finfo.name) { + DEBUG(0,("cli_list_new: unable to parse name from info level %d\n", + info_level)); + break; + } fn(mnt,&finfo, Mask, state); } } -- cgit From 0b583e4329a4a47918329d9022feb6ab8c54bb33 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Feb 2008 19:02:49 -0800 Subject: Make clilist work again with OS/2 (kukks help!). Jeremy. (This used to be commit 2e27309401faa554620886b0e369db9d9c08e4fd) --- source3/libsmb/clilist.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2b5e7518c5..d913096b12 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -78,9 +78,25 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); - if (p + len + 2 > pdata_end) { + + /* We can safely use +1 here (which is required by OS/2) + * instead of +2 as the STR_TERMINATE flag below is + * actually used as the length calculation. + * The len+2 is merely an upper bound. + * We ensure we don't get a one byte overread by + * doing a zero termination at pdata_end[-1]; + * JRA + kukks */ + + if (p + len + 1 > pdata_end) { return pdata_end - base; } + + /* Ensure the null termination (see above). */ + { + char *pend = CONST_DISCARD(char *, pdata_end); + pend[-1] = '\0'; + } + /* the len+2 below looks strange but it is important to cope with the differences between win2000 and win9x for this call -- cgit From 20d6ebe813955866e70c0b91ef316830e1612437 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Feb 2008 22:02:00 -0800 Subject: We don't need the extra null termination - we've already got this in the cli_receive_trans calls. Jeremy. (This used to be commit 99424bba7bb45b05d970bab4a5e93f2cb636fcbb) --- source3/libsmb/clilist.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d913096b12..e1b16154f2 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -83,20 +83,15 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, * instead of +2 as the STR_TERMINATE flag below is * actually used as the length calculation. * The len+2 is merely an upper bound. - * We ensure we don't get a one byte overread by - * doing a zero termination at pdata_end[-1]; - * JRA + kukks */ + * Due to the explicit 2 byte null termination + * in cli_receive_trans/cli_receive_nt_trans + * we know this is safe. JRA + kukks + */ if (p + len + 1 > pdata_end) { return pdata_end - base; } - /* Ensure the null termination (see above). */ - { - char *pend = CONST_DISCARD(char *, pdata_end); - pend[-1] = '\0'; - } - /* the len+2 below looks strange but it is important to cope with the differences between win2000 and win9x for this call -- cgit From b4dd60efa9d59dc70f0f0e58be6fa769c543d059 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 11 Feb 2008 18:36:06 +0100 Subject: Add a missing return If I'm not completely blind, we should return here. Not doing it here seems not to be a major flaw, as far as I can see we're only missing the error code. This might account for some of the very unhelpful NT_STATUS_UNSUCCESSFUL error messages people see during joins. All with stake in Samba client, please check! (This used to be commit eadd15c9363a57c214ede3c489057646baca48f8) --- source3/libsmb/cliconnect.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index f3926b777b..e97be98fc1 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -627,7 +627,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * if (!cli_session_setup_blob(cli, negTokenTarg, session_key_krb5)) { data_blob_free(&negTokenTarg); data_blob_free(&session_key_krb5); - ADS_ERROR_NT(cli_nt_error(cli)); + return ADS_ERROR_NT(cli_nt_error(cli)); } cli_set_session_key(cli, session_key_krb5); -- cgit From 0ba3d44f7321cb235eb214194395d5da02824690 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 13 Feb 2008 00:25:40 +0100 Subject: Use rpccli_lsa_EnumTrustDom all over the place. Guenther (This used to be commit a25e7ffbca9c2c97dd36b0596e7cb38a72aaf9d9) --- source3/libsmb/trusts_util.c | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 1ca7d56a83..11f691bee6 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -152,6 +152,8 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, struct cli_state *cli = NULL; struct rpc_pipe_client *lsa_pipe; bool retry; + struct lsa_DomainList dom_list; + int i; *domain_names = NULL; *num_domains = 0; @@ -188,11 +190,33 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* Lookup list of trusted domains */ - result = rpccli_lsa_enum_trust_dom(lsa_pipe, mem_ctx, &pol, &enum_ctx, - num_domains, domain_names, sids); + result = rpccli_lsa_EnumTrustDom(lsa_pipe, mem_ctx, + &pol, + &enum_ctx, + &dom_list, + (uint32_t)-1); if ( !NT_STATUS_IS_OK(result) ) goto done; + *num_domains = dom_list.count; + + *domain_names = TALLOC_ZERO_ARRAY(mem_ctx, char *, *num_domains); + if (!*domain_names) { + result = NT_STATUS_NO_MEMORY; + goto done; + } + + *sids = TALLOC_ZERO_ARRAY(mem_ctx, DOM_SID, *num_domains); + if (!*sids) { + result = NT_STATUS_NO_MEMORY; + goto done; + } + + for (i=0; i< *num_domains; i++) { + (*domain_names)[i] = CONST_DISCARD(char *, dom_list.domains[i].name.string); + (*sids)[i] = *dom_list.domains[i].sid; + } + done: /* cleanup */ if (cli) { -- cgit From 39e0dbcf07251670b5475e9d0533c08a2712fffa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Feb 2008 11:29:54 -0800 Subject: Allow the mechOID to be written separately. Jeremy. (This used to be commit e3e08c6e7d270e1be7a9d3042b1f36f5a291f90a) --- source3/libsmb/clispnego.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index f95b11e4cd..a75032a47d 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -498,11 +498,13 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (reply->data != NULL) { + if (mechOID) { asn1_push_tag(&data,ASN1_CONTEXT(1)); asn1_write_OID(&data, mechOID); asn1_pop_tag(&data); - + } + + if (reply && reply->data != NULL) { asn1_push_tag(&data,ASN1_CONTEXT(2)); asn1_write_OctetString(&data, reply->data, reply->length); asn1_pop_tag(&data); -- cgit From 401c0a6551efe2ac574d4fa0337c15ee2dd61da7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 15 Feb 2008 13:51:54 +0100 Subject: Add netlogon_creds_client_check and netlogon_creds_client_step. Guenther (This used to be commit 41d33a2507e3fae7837bb8e42b1ac30cc31c31dc) --- source3/libsmb/credentials.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 1256a6210e..f03bf22df1 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -329,6 +329,25 @@ bool creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in return True; } +bool netlogon_creds_client_check(const struct dcinfo *dc, + const struct netr_Credential *rcv_srv_chal_in) +{ + if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, + sizeof(dc->srv_chal.data))) { + + DEBUG(0,("netlogon_creds_client_check: credentials check failed.\n")); + DEBUGADD(5,("netlogon_creds_client_check: challenge : %s\n", + credstr(rcv_srv_chal_in->data))); + DEBUGADD(5,("calculated: %s\n", credstr(dc->srv_chal.data))); + return false; + } + + DEBUG(10,("netlogon_creds_client_check: credentials check OK.\n")); + + return true; +} + + /**************************************************************************** Step the client credentials to the next element in the chain, updating the current client and server credentials and the seed @@ -345,3 +364,15 @@ void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out) next_cred_out->challenge = dc->clnt_chal; next_cred_out->timestamp.time = dc->sequence; } + +void netlogon_creds_client_step(struct dcinfo *dc, + struct netr_Authenticator *next_cred_out) +{ + dc->sequence += 2; + creds_step(dc); + creds_reseed(dc); + + memcpy(&next_cred_out->cred.data, &dc->clnt_chal.data, + sizeof(next_cred_out->cred.data)); + next_cred_out->timestamp = dc->sequence; +} -- cgit From f8bd3e82e5eda052ede2d294f08165cb23df9d90 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 15 Feb 2008 17:30:38 +0100 Subject: Add netlogon_creds_server_check and netlogon_creds_server_step. Guenther (This used to be commit ea0bf74918e7b009439452ea14ed68b0ce620787) --- source3/libsmb/credentials.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index f03bf22df1..0043f4e6a9 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -225,6 +225,21 @@ bool creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in return True; } +bool netlogon_creds_server_check(const struct dcinfo *dc, + const struct netr_Credential *rcv_cli_chal_in) +{ + if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) { + DEBUG(5,("netlogon_creds_server_check: challenge : %s\n", + credstr(rcv_cli_chal_in->data))); + DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data))); + DEBUG(2,("netlogon_creds_server_check: credentials check failed.\n")); + return false; + } + + DEBUG(10,("netlogon_creds_server_check: credentials check OK.\n")); + + return true; +} /**************************************************************************** Replace current seed chal. Internal function - due to split server step below. ****************************************************************************/ @@ -273,6 +288,36 @@ bool creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRE return True; } +bool netlogon_creds_server_step(struct dcinfo *dc, + const struct netr_Authenticator *received_cred, + struct netr_Authenticator *cred_out) +{ + bool ret; + struct dcinfo tmp_dc = *dc; + + /* Do all operations on a temporary copy of the dc, + which we throw away if the checks fail. */ + + tmp_dc.sequence = received_cred->timestamp; + + creds_step(&tmp_dc); + + /* Create the outgoing credentials */ + cred_out->timestamp = tmp_dc.sequence + 1; + memcpy(&cred_out->cred, &tmp_dc.srv_chal, sizeof(cred_out->cred)); + + creds_reseed(&tmp_dc); + + ret = netlogon_creds_server_check(&tmp_dc, &received_cred->cred); + if (!ret) { + return false; + } + + /* creds step succeeded - replace the current creds. */ + *dc = tmp_dc; + return true; +} + /**************************************************************************** Create a client credential struct. ****************************************************************************/ -- cgit From 3f24ef18481417fd7d52856b3d68bec099a7b643 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 15 Feb 2008 23:57:19 +0100 Subject: Replace DOM_CHAL with "struct netr_Credential" where we can right now. This allows to remove some more old netlogon client calls. Guenther (This used to be commit c0b1a876583230a5130f5df1965d6c742961bcdc) --- source3/libsmb/credentials.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 0043f4e6a9..328b931df0 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -42,9 +42,9 @@ char *credstr(const unsigned char *cred) ****************************************************************************/ static void creds_init_128(struct dcinfo *dc, - const DOM_CHAL *clnt_chal_in, - const DOM_CHAL *srv_chal_in, - const unsigned char mach_pw[16]) + const struct netr_Credential *clnt_chal_in, + const struct netr_Credential *srv_chal_in, + const unsigned char mach_pw[16]) { unsigned char zero[4], tmp[16]; HMACMD5Context ctx; @@ -94,9 +94,9 @@ static void creds_init_128(struct dcinfo *dc, ****************************************************************************/ static void creds_init_64(struct dcinfo *dc, - const DOM_CHAL *clnt_chal_in, - const DOM_CHAL *srv_chal_in, - const unsigned char mach_pw[16]) + const struct netr_Credential *clnt_chal_in, + const struct netr_Credential *srv_chal_in, + const unsigned char mach_pw[16]) { uint32 sum[2]; unsigned char sum2[8]; @@ -177,10 +177,10 @@ static void creds_step(struct dcinfo *dc) void creds_server_init(uint32 neg_flags, struct dcinfo *dc, - DOM_CHAL *clnt_chal, - DOM_CHAL *srv_chal, + struct netr_Credential *clnt_chal, + struct netr_Credential *srv_chal, const unsigned char mach_pw[16], - DOM_CHAL *init_chal_out) + struct netr_Credential *init_chal_out) { DEBUG(10,("creds_server_init: neg_flags : %x\n", (unsigned int)neg_flags)); DEBUG(10,("creds_server_init: client chal : %s\n", credstr(clnt_chal->data) )); @@ -246,7 +246,7 @@ bool netlogon_creds_server_check(const struct dcinfo *dc, static void creds_reseed(struct dcinfo *dc) { - DOM_CHAL time_chal; + struct netr_Credential time_chal; SIVAL(time_chal.data, 0, IVAL(dc->seed_chal.data, 0) + dc->sequence + 1); SIVAL(time_chal.data, 4, IVAL(dc->seed_chal.data, 4)); @@ -274,7 +274,8 @@ bool creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRE /* Create the outgoing credentials */ cred_out->timestamp.time = tmp_dc.sequence + 1; - cred_out->challenge = tmp_dc.srv_chal; + memcpy(&cred_out->challenge.data, tmp_dc.srv_chal.data, + sizeof(cred_out->challenge.data)); creds_reseed(&tmp_dc); @@ -324,10 +325,10 @@ bool netlogon_creds_server_step(struct dcinfo *dc, void creds_client_init(uint32 neg_flags, struct dcinfo *dc, - DOM_CHAL *clnt_chal, - DOM_CHAL *srv_chal, + struct netr_Credential *clnt_chal, + struct netr_Credential *srv_chal, const unsigned char mach_pw[16], - DOM_CHAL *init_chal_out) + struct netr_Credential *init_chal_out) { dc->sequence = time(NULL); @@ -406,7 +407,8 @@ void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out) creds_step(dc); creds_reseed(dc); - next_cred_out->challenge = dc->clnt_chal; + memcpy(&next_cred_out->challenge.data, dc->clnt_chal.data, + sizeof(next_cred_out->challenge.data)); next_cred_out->timestamp.time = dc->sequence; } -- cgit From b6285fc0526ff15250242489047bb8d49a1948e6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 16 Feb 2008 15:14:04 +0100 Subject: Remove unused creds_server_check and creds_server_step. Guenther (This used to be commit 2fb73a3545634982d17d3823cb629f06c5779fc0) --- source3/libsmb/credentials.c | 41 ----------------------------------------- 1 file changed, 41 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 328b931df0..2dcbdf3cf9 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -213,18 +213,6 @@ void creds_server_init(uint32 neg_flags, Check a credential sent by the client. ****************************************************************************/ -bool creds_server_check(const struct dcinfo *dc, const DOM_CHAL *rcv_cli_chal_in) -{ - if (memcmp(dc->clnt_chal.data, rcv_cli_chal_in->data, 8)) { - DEBUG(5,("creds_server_check: challenge : %s\n", credstr(rcv_cli_chal_in->data))); - DEBUG(5,("calculated: %s\n", credstr(dc->clnt_chal.data))); - DEBUG(2,("creds_server_check: credentials check failed.\n")); - return False; - } - DEBUG(10,("creds_server_check: credentials check OK.\n")); - return True; -} - bool netlogon_creds_server_check(const struct dcinfo *dc, const struct netr_Credential *rcv_cli_chal_in) { @@ -260,35 +248,6 @@ static void creds_reseed(struct dcinfo *dc) Step the server credential chain one forward. ****************************************************************************/ -bool creds_server_step(struct dcinfo *dc, const DOM_CRED *received_cred, DOM_CRED *cred_out) -{ - bool ret; - struct dcinfo tmp_dc = *dc; - - /* Do all operations on a temporary copy of the dc, - which we throw away if the checks fail. */ - - tmp_dc.sequence = received_cred->timestamp.time; - - creds_step(&tmp_dc); - - /* Create the outgoing credentials */ - cred_out->timestamp.time = tmp_dc.sequence + 1; - memcpy(&cred_out->challenge.data, tmp_dc.srv_chal.data, - sizeof(cred_out->challenge.data)); - - creds_reseed(&tmp_dc); - - ret = creds_server_check(&tmp_dc, &received_cred->challenge); - if (!ret) { - return False; - } - - /* creds step succeeded - replace the current creds. */ - *dc = tmp_dc; - return True; -} - bool netlogon_creds_server_step(struct dcinfo *dc, const struct netr_Authenticator *received_cred, struct netr_Authenticator *cred_out) -- cgit From dd65a349350717eb17257ccf281561dd878ead12 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 16 Feb 2008 16:04:01 +0100 Subject: Use rpccli_netr_ServerPasswordSet in "just_change_the_password()". Guenther (This used to be commit 33f91c894488687a42500e751eb9016d99d9129c) --- source3/libsmb/trusts_util.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 11f691bee6..1e92bf21de 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -58,7 +58,32 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX } } - result = rpccli_net_srv_pwset(cli, mem_ctx, global_myname(), new_trust_passwd_hash); + { + struct netr_Authenticator clnt_creds, srv_cred; + struct samr_Password new_password; + + netlogon_creds_client_step(cli->dc, &clnt_creds); + + cred_hash3(new_password.hash, + new_trust_passwd_hash, + cli->dc->sess_key, 1); + + result = rpccli_netr_ServerPasswordSet(cli, mem_ctx, + cli->dc->remote_machine, + cli->dc->mach_acct, + sec_channel_type, + global_myname(), + &clnt_creds, + &srv_cred, + &new_password); + + /* Always check returned credentials. */ + if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { + DEBUG(0,("rpccli_netr_ServerPasswordSet: " + "credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + } if (!NT_STATUS_IS_OK(result)) { DEBUG(0,("just_change_the_password: unable to change password (%s)!\n", -- cgit From 8027b7c25dfa5b4617c4fafbf1e4aaf4f7fee43a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 17 Feb 2008 01:47:01 +0100 Subject: Use netr_SamInfo3 in samlogon cache and use ndr functions for storing the blob. Guenther (This used to be commit bf860ae1ac6765b1eb6e2ca9b667b19b4e661fda) --- source3/libsmb/samlogon_cache.c | 217 ++++++++++++++++++++++------------------ 1 file changed, 119 insertions(+), 98 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 4f791f66f6..e2a4b3898f 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -1,21 +1,21 @@ -/* +/* Unix SMB/CIFS implementation. Net_sam_logon info3 helpers Copyright (C) Alexander Bokovoy 2002. Copyright (C) Andrew Bartlett 2002. Copyright (C) Gerald Carter 2003. Copyright (C) Tim Potter 2003. - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -29,12 +29,12 @@ static TDB_CONTEXT *netsamlogon_tdb = NULL; /*********************************************************************** open the tdb ***********************************************************************/ - + bool netsamlogon_cache_init(void) { if (!netsamlogon_tdb) { netsamlogon_tdb = tdb_open_log(lock_path(NETSAMLOGON_TDB), 0, - TDB_DEFAULT, O_RDWR | O_CREAT, 0600); + TDB_DEFAULT, O_RDWR | O_CREAT, 0600); } return (netsamlogon_tdb != NULL); @@ -47,37 +47,39 @@ bool netsamlogon_cache_init(void) bool netsamlogon_cache_shutdown(void) { - if(netsamlogon_tdb) + if (netsamlogon_tdb) { return (tdb_close(netsamlogon_tdb) == 0); - - return True; + } + + return true; } /*********************************************************************** Clear cache getpwnam and getgroups entries from the winbindd cache ***********************************************************************/ -void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) + +void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, struct netr_SamInfo3 *info3) { - bool got_tdb = False; + bool got_tdb = false; DOM_SID sid; fstring key_str, sid_string; /* We may need to call this function from smbd which will not have - winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ + winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ if (!tdb) { - tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), + tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, TDB_DEFAULT, O_RDWR, 0600); if (!tdb) { DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n")); return; } - got_tdb = True; + got_tdb = true; } - sid_copy(&sid, &user->dom_sid.sid); - sid_append_rid(&sid, user->user_rid); + sid_copy(&sid, info3->base.domain_sid); + sid_append_rid(&sid, info3->base.rid); /* Clear U/SID cache entry */ @@ -95,157 +97,176 @@ void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, NET_USER_INFO_3 *user) tdb_delete(tdb, string_tdb_data(key_str)); - if (got_tdb) + if (got_tdb) { tdb_close(tdb); + } } /*********************************************************************** - Store a NET_USER_INFO_3 structure in a tdb for later user + Store a netr_SamInfo3 structure in a tdb for later user username should be in UTF-8 format ***********************************************************************/ -bool netsamlogon_cache_store( const char *username, NET_USER_INFO_3 *user ) +bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3) { - TDB_DATA data; - fstring keystr, tmp; - prs_struct ps; - bool result = False; - DOM_SID user_sid; - time_t t = time(NULL); - TALLOC_CTX *mem_ctx; - + TDB_DATA data; + fstring keystr, tmp; + bool result = false; + DOM_SID user_sid; + time_t t = time(NULL); + TALLOC_CTX *mem_ctx; + DATA_BLOB blob; + enum ndr_err_code ndr_err; + struct netsamlogoncache_entry r; + + if (!info3) { + return false; + } if (!netsamlogon_cache_init()) { - DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", NETSAMLOGON_TDB)); - return False; + DEBUG(0,("netsamlogon_cache_store: cannot open %s for write!\n", + NETSAMLOGON_TDB)); + return false; } - sid_copy( &user_sid, &user->dom_sid.sid ); - sid_append_rid( &user_sid, user->user_rid ); + sid_copy(&user_sid, info3->base.domain_sid); + sid_append_rid(&user_sid, info3->base.rid); /* Prepare key as DOMAIN-SID/USER-RID string */ slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid)); DEBUG(10,("netsamlogon_cache_store: SID [%s]\n", keystr)); - + + /* Prepare data */ + + if (!(mem_ctx = TALLOC_P( NULL, int))) { + DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n")); + return false; + } + /* only Samba fills in the username, not sure why NT doesn't */ /* so we fill it in since winbindd_getpwnam() makes use of it */ - - if ( !user->uni_user_name.buffer ) { - init_unistr2( &user->uni_user_name, username, UNI_STR_TERMINATE ); - init_uni_hdr( &user->hdr_user_name, &user->uni_user_name ); + + if (!info3->base.account_name.string) { + info3->base.account_name.string = talloc_strdup(mem_ctx, username); } - - /* Prepare data */ - - if ( !(mem_ctx = TALLOC_P( NULL, int )) ) { - DEBUG(0,("netsamlogon_cache_store: talloc() failed!\n")); - return False; + + r.timestamp = t; + r.info3 = *info3; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(netsamlogoncache_entry, &r); } - prs_init( &ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); - - { - uint32 ts = (uint32)t; - if ( !prs_uint32( "timestamp", &ps, 0, &ts ) ) - return False; + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &r, + (ndr_push_flags_fn_t)ndr_push_netsamlogoncache_entry); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("netsamlogon_cache_store: failed to push entry to cache\n")); + TALLOC_FREE(mem_ctx); + return false; } - - if ( net_io_user_info3("", user, &ps, 0, 3, 0) ) - { - data.dsize = prs_offset( &ps ); - data.dptr = (uint8 *)prs_data_p( &ps ); - if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) - result = True; - - prs_mem_free( &ps ); + data.dsize = blob.length; + data.dptr = blob.data; + + if (tdb_store_bystring(netsamlogon_tdb, keystr, data, TDB_REPLACE) != -1) { + result = true; } - TALLOC_FREE( mem_ctx ); - + TALLOC_FREE(mem_ctx); + return result; } /*********************************************************************** - Retrieves a NET_USER_INFO_3 structure from a tdb. Caller must + Retrieves a netr_SamInfo3 structure from a tdb. Caller must free the user_info struct (malloc()'d memory) ***********************************************************************/ -NET_USER_INFO_3* netsamlogon_cache_get( TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) +struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid) { - NET_USER_INFO_3 *user = NULL; - TDB_DATA data; - prs_struct ps; - fstring keystr, tmp; - uint32 t; - + struct netr_SamInfo3 *info3 = NULL; + TDB_DATA data; + fstring keystr, tmp; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct netsamlogoncache_entry r; + if (!netsamlogon_cache_init()) { - DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n", NETSAMLOGON_TDB)); - return False; + DEBUG(0,("netsamlogon_cache_get: cannot open %s for write!\n", + NETSAMLOGON_TDB)); + return false; } /* Prepare key as DOMAIN-SID/USER-RID string */ slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, user_sid)); DEBUG(10,("netsamlogon_cache_get: SID [%s]\n", keystr)); data = tdb_fetch_bystring( netsamlogon_tdb, keystr ); - - if ( data.dptr ) { - user = TALLOC_ZERO_P(mem_ctx, NET_USER_INFO_3); - if (user == NULL) { - return NULL; - } + if (!data.dptr) { + return NULL; + } - prs_init( &ps, 0, mem_ctx, UNMARSHALL ); - prs_give_memory( &ps, (char *)data.dptr, data.dsize, True ); - - if ( !prs_uint32( "timestamp", &ps, 0, &t ) ) { - prs_mem_free( &ps ); - TALLOC_FREE(user); - return False; - } - - if ( !net_io_user_info3("", user, &ps, 0, 3, 0) ) { - TALLOC_FREE( user ); - } - - prs_mem_free( &ps ); + info3 = TALLOC_ZERO_P(mem_ctx, struct netr_SamInfo3); + if (!info3) { + goto done; + } + + blob.data = (uint8 *)data.dptr; + blob.length = data.dsize; + + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, + (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry); -#if 0 /* The netsamlogon cache needs to hang around. Something about + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(netsamlogoncache_entry, &r); + } + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("netsamlogon_cache_get: failed to pull entry from cache\n")); + tdb_delete(netsamlogon_tdb, data); + goto done; + } + + info3 = talloc_memdup(mem_ctx, &r.info3, sizeof(r.info3)); + + done: + SAFE_FREE(data.dptr); + + return info3; + +#if 0 /* The netsamlogon cache needs to hang around. Something about this feels wrong, but it is the only way we can get all of the groups. The old universal groups cache didn't expire either. --jerry */ { time_t now = time(NULL); uint32 time_diff; - + /* is the entry expired? */ time_diff = now - t; - + if ( (time_diff < 0 ) || (time_diff > lp_winbind_cache_time()) ) { DEBUG(10,("netsamlogon_cache_get: cache entry expired \n")); tdb_delete( netsamlogon_tdb, key ); TALLOC_FREE( user ); } -#endif } - - return user; +#endif } bool netsamlogon_cache_have(const DOM_SID *user_sid) { TALLOC_CTX *mem_ctx = talloc_init("netsamlogon_cache_have"); - NET_USER_INFO_3 *user = NULL; + struct netr_SamInfo3 *info3 = NULL; bool result; if (!mem_ctx) return False; - user = netsamlogon_cache_get(mem_ctx, user_sid); + info3 = netsamlogon_cache_get(mem_ctx, user_sid); - result = (user != NULL); + result = (info3 != NULL); talloc_destroy(mem_ctx); -- cgit From c1793b2b316a8f912dde14f806c84ac7d1491bf3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 17 Feb 2008 01:59:02 +0100 Subject: Use new IDL based PAC structures in clikrb5.c Guenther (This used to be commit 3b0135d57e1e70175a5eec49b603a2e5f700c770) --- source3/libsmb/clikrb5.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 844a3b35c0..c289740ab2 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -835,22 +835,22 @@ failed: #endif } - void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, - PAC_SIGNATURE_DATA *sig) + void smb_krb5_checksum_from_pac_sig(krb5_checksum *cksum, + struct PAC_SIGNATURE_DATA *sig) { #ifdef HAVE_CHECKSUM_IN_KRB5_CHECKSUM cksum->cksumtype = (krb5_cksumtype)sig->type; - cksum->checksum.length = sig->signature.buf_len; - cksum->checksum.data = sig->signature.buffer; + cksum->checksum.length = sig->signature.length; + cksum->checksum.data = sig->signature.data; #else cksum->checksum_type = (krb5_cksumtype)sig->type; - cksum->length = sig->signature.buf_len; - cksum->contents = sig->signature.buffer; + cksum->length = sig->signature.length; + cksum->contents = sig->signature.data; #endif } krb5_error_code smb_krb5_verify_checksum(krb5_context context, - krb5_keyblock *keyblock, + const krb5_keyblock *keyblock, krb5_keyusage usage, krb5_checksum *cksum, uint8 *data, -- cgit From 5b8ebcf397e40bf1f9555c34fadbab2d7b5bf717 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 17 Feb 2008 03:08:42 +0100 Subject: Remove unused creds_client_check and creds_client_step. Guenther (This used to be commit 1dcb32424d16cff968a8713352c93c48dec58674) --- source3/libsmb/credentials.c | 23 ----------------------- 1 file changed, 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/credentials.c b/source3/libsmb/credentials.c index 2dcbdf3cf9..9d33e6d93d 100644 --- a/source3/libsmb/credentials.c +++ b/source3/libsmb/credentials.c @@ -322,18 +322,6 @@ void creds_client_init(uint32 neg_flags, Check a credential returned by the server. ****************************************************************************/ -bool creds_client_check(const struct dcinfo *dc, const DOM_CHAL *rcv_srv_chal_in) -{ - if (memcmp(dc->srv_chal.data, rcv_srv_chal_in->data, 8)) { - DEBUG(5,("creds_client_check: challenge : %s\n", credstr(rcv_srv_chal_in->data))); - DEBUG(5,("calculated: %s\n", credstr(dc->srv_chal.data))); - DEBUG(0,("creds_client_check: credentials check failed.\n")); - return False; - } - DEBUG(10,("creds_client_check: credentials check OK.\n")); - return True; -} - bool netlogon_creds_client_check(const struct dcinfo *dc, const struct netr_Credential *rcv_srv_chal_in) { @@ -360,17 +348,6 @@ bool netlogon_creds_client_check(const struct dcinfo *dc, the server ****************************************************************************/ -void creds_client_step(struct dcinfo *dc, DOM_CRED *next_cred_out) -{ - dc->sequence += 2; - creds_step(dc); - creds_reseed(dc); - - memcpy(&next_cred_out->challenge.data, dc->clnt_chal.data, - sizeof(next_cred_out->challenge.data)); - next_cred_out->timestamp.time = dc->sequence; -} - void netlogon_creds_client_step(struct dcinfo *dc, struct netr_Authenticator *next_cred_out) { -- cgit From 441de75e58daf734c412a3e741608822289cac59 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 18 Feb 2008 21:00:51 +1100 Subject: Fix memory leaks on error path (This used to be commit 47dd0700b4320bf5ac9a80e71ae82d82d4554e6a) --- source3/libsmb/clifile.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 9b4c380d40..10c35a30cc 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -38,8 +38,15 @@ static bool cli_link_internal(struct cli_state *cli, const char *oldname, const size_t newlen = 2*(strlen(newname)+1); param = SMB_MALLOC_ARRAY(char, 6+newlen+2); + + if (!param) { + return false; + } + data = SMB_MALLOC_ARRAY(char, oldlen+2); - if (!param || !data) { + + if (!data) { + SAFE_FREE(param); return false; } -- cgit From 6548493de7680dedd429bf851fc57b577e06c673 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 23 Feb 2008 10:50:12 +0100 Subject: Fix a C++ warning (This used to be commit ac027a9b2e84d319f961ac0e84654a0e48920138) --- source3/libsmb/samlogon_cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index e2a4b3898f..3cc0dcf0fb 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -228,7 +228,8 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID * goto done; } - info3 = talloc_memdup(mem_ctx, &r.info3, sizeof(r.info3)); + info3 = (struct netr_SamInfo3 *)talloc_memdup(mem_ctx, &r.info3, + sizeof(r.info3)); done: SAFE_FREE(data.dptr); -- cgit From a5e43bc81711e25cb07224df5e64f0120d4ef500 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 23 Feb 2008 21:40:39 +0100 Subject: Fix typo (This used to be commit 621db68f32f7007de8b2c4d7cf604a5778725615) --- source3/libsmb/cliconnect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index e97be98fc1..d88a5d6242 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -581,8 +581,8 @@ static bool cli_session_setup_blob(struct cli_state *cli, DATA_BLOB blob, DATA_B if (cli_is_error(cli) && !NT_STATUS_EQUAL( cli_get_nt_error(cli), NT_STATUS_MORE_PROCESSING_REQUIRED)) { - DEBUG(0, ("cli_session_setup_blob: recieve failed (%s)\n", - nt_errstr(cli_get_nt_error(cli)) )); + DEBUG(0, ("cli_session_setup_blob: receive failed " + "(%s)\n", nt_errstr(cli_get_nt_error(cli)))); cli->vuid = 0; return False; } -- cgit From 317639287886181edf08ccecad1b324e4cc55d0b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Feb 2008 15:24:49 +0100 Subject: Fix some warnings warning: ignoring return value of 'asprintf', declared with attribute warn_unused_result (This used to be commit ad37b7b0aee265a3e4d8b7552610f4b9a105434d) --- source3/libsmb/clifsinfo.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index fb923378ab..f4945f812a 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -497,8 +497,7 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, memset(&tok_out, '\0', sizeof(tok_out)); /* Get a ticket for the service@host */ - asprintf(&host_princ_s, "%s@%s", service, host); - if (host_princ_s == NULL) { + if (asprintf(&host_princ_s, "%s@%s", service, host) == -1) { return NT_STATUS_NO_MEMORY; } -- cgit From c58e7427bf7200ad413c259f429f020b98d723ec Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 26 Feb 2008 21:42:26 -0500 Subject: add a function to truncate a file to a specified size (This used to be commit 7e5752812d6d9e3bcf9a545cbdcf3afe2175dbc4) --- source3/libsmb/clifile.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 10c35a30cc..12c427a6fa 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -888,6 +888,55 @@ bool cli_close(struct cli_state *cli, int fnum) } +/**************************************************************************** + Truncate a file to a specified size +****************************************************************************/ + +bool cli_ftruncate(struct cli_state *cli, int fnum, uint64_t size) +{ + unsigned int param_len = 6; + unsigned int data_len = 8; + uint16 setup = TRANSACT2_SETFILEINFO; + char param[6]; + unsigned char data[8]; + char *rparam=NULL, *rdata=NULL; + int saved_timeout = cli->timeout; + + SSVAL(param,0,fnum); + SSVAL(param,2,SMB_SET_FILE_END_OF_FILE_INFO); + SSVAL(param,4,0); + + SBVAL(data, 0, size); + + if (!cli_send_trans(cli, SMBtrans2, + NULL, /* name */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + (char *)&data, data_len,/* data, length, ... */ + cli->max_xmit)) { /* ... max */ + cli->timeout = saved_timeout; + return False; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + cli->timeout = saved_timeout; + SAFE_FREE(rdata); + SAFE_FREE(rparam); + return False; + } + + cli->timeout = saved_timeout; + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + + return True; +} + + /**************************************************************************** send a lock with a specified locktype this is used for testing LOCKING_ANDX_CANCEL_LOCK -- cgit From fa341d526293f4d986f2f3d838a728ce4223ee88 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 26 Feb 2008 21:44:51 -0500 Subject: add smbc_ftruncate() to emulate POSIX ftruncate() (This used to be commit 6f5051b9c1405ab1dc3e697419ceedb3acac46d8) --- source3/libsmb/libsmb_compat.c | 6 ++++ source3/libsmb/libsmbclient.c | 75 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 573d087d6e..6042464fd2 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -289,6 +289,12 @@ int smbc_fstat(int fd, struct stat *st) return (statcont->fstat)(statcont, file, st); } +int smbc_ftruncate(int fd, off_t size) +{ + SMBCFILE * file = find_fd(fd); + return (statcont->ftruncate)(statcont, file, size); +} + int smbc_chmod(const char *url, mode_t mode) { return (statcont->chmod)(statcont, url, mode); diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c index e84de59637..fe008ed6b6 100644 --- a/source3/libsmb/libsmbclient.c +++ b/source3/libsmb/libsmbclient.c @@ -2482,6 +2482,80 @@ smbc_fstat_ctx(SMBCCTX *context, } +/* + * Routine to truncate a file given by its file descriptor, to a specified size + */ + +static int +smbc_ftruncate_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t length) +{ + SMB_OFF_T size = length; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->internal || + !context->internal->_initialized) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + if (!file->file) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ + if (smbc_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + if (!cli_ftruncate(targetcli, file->cli_fd, size)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; + +} + /* * Routine to open a directory * We accept the URL syntax explained in smbc_parse_path(), above. @@ -6703,6 +6777,7 @@ smbc_new_context(void) context->telldir = smbc_telldir_ctx; context->lseekdir = smbc_lseekdir_ctx; context->fstatdir = smbc_fstatdir_ctx; + context->ftruncate = smbc_ftruncate_ctx; context->chmod = smbc_chmod_ctx; context->utimes = smbc_utimes_ctx; context->setxattr = smbc_setxattr_ctx; -- cgit From 2d01ec2c390f8dd753600f22cefb17e7b8916ffd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 27 Feb 2008 15:49:31 +0100 Subject: Use new LSA_POLICY defines in lsa rpc server code and other places. Guenther (This used to be commit 58cca9faf9db506bd2f6eab4a99ef85153797ab2) --- source3/libsmb/trusts_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 1e92bf21de..c079fb149a 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -209,7 +209,7 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* get a handle */ result = rpccli_lsa_open_policy(lsa_pipe, mem_ctx, True, - POLICY_VIEW_LOCAL_INFORMATION, &pol); + LSA_POLICY_VIEW_LOCAL_INFORMATION, &pol); if ( !NT_STATUS_IS_OK(result) ) goto done; -- cgit From 7269a504fdd06fbbe24c2df8e084b41382d71269 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 27 Feb 2008 19:38:48 +0100 Subject: Add my copyright. Guenther (This used to be commit d078a8757182d84dfd3307a2e1b751cf173aaa97) --- source3/libsmb/samlogon_cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 3cc0dcf0fb..0d855f4c6c 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -5,6 +5,7 @@ Copyright (C) Andrew Bartlett 2002. Copyright (C) Gerald Carter 2003. Copyright (C) Tim Potter 2003. + Copyright (C) Guenther Deschner 2008. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 1d940490e815bbdb7e4af23ace05ec9ac8fddae8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 Feb 2008 02:22:13 -0800 Subject: Fix from Guenter Kukkukk to fix listing against OS/2 servers. OS/2 returns eclass == ERRDOS && ecode == ERRnofiles for a zero entry directory listing. Jeremy. (This used to be commit b34da627053581a9584367e177566d4a2cef7e82) --- source3/libsmb/clierror.c | 12 ++++++++++++ source3/libsmb/clilist.c | 16 +++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clierror.c b/source3/libsmb/clierror.c index 587abade59..36746419f7 100644 --- a/source3/libsmb/clierror.c +++ b/source3/libsmb/clierror.c @@ -483,3 +483,15 @@ void cli_set_nt_error(struct cli_state *cli, NTSTATUS status) SSVAL(cli->inbuf,smb_flg2, SVAL(cli->inbuf,smb_flg2)|FLAGS2_32_BIT_ERROR_CODES); SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); } + +/* Reset an error. */ + +void cli_reset_error(struct cli_state *cli) +{ + if (SVAL(cli->inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES) { + SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(NT_STATUS_OK)); + } else { + SCVAL(cli->inbuf,smb_rcls,0); + SSVAL(cli->inbuf,smb_err,0); + } +} diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e1b16154f2..50918458b0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -328,7 +328,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &rparam, ¶m_len, &rdata, &data_len) && cli_is_dos_error(cli)) { - /* we need to work around a Win95 bug - sometimes + /* We need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; @@ -337,6 +337,20 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SAFE_FREE(rparam); cli_dos_error(cli, &eclass, &ecode); + + /* + * OS/2 might return "no more files", + * which just tells us, that searchcount is zero + * in this search. + * Guenter Kukkukk + */ + + if (eclass == ERRDOS && ecode == ERRnofiles) { + ff_searchcount = 0; + cli_reset_error(cli); + break; + } + if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); -- cgit From 0d8985f2da43d35d8f940af112ad74a199778dd8 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 Feb 2008 12:30:18 +0100 Subject: Let dsgetdcname() return a struct netr_DsRGetDCNameInfo. Guenther (This used to be commit b1a4b21f8c35dc23e5c986ebe44d3806055eb39b) --- source3/libsmb/dsgetdcname.c | 144 ++++++++++++++++++++----------------------- 1 file changed, 67 insertions(+), 77 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index e0be76cc85..bc9f4b92c8 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -110,7 +110,7 @@ void debug_dsdcinfo_flags(int lvl, uint32_t flags) /********************************************************************* ********************************************************************/ -static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, +static int pack_dsdcinfo(struct netr_DsRGetDCNameInfo *info, unsigned char **buf) { unsigned char *buffer = NULL; @@ -122,9 +122,8 @@ static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, ZERO_STRUCT(guid_flat); - if (info->domain_guid) { - const struct GUID *guid = info->domain_guid; - smb_uuid_pack(*guid, &guid_flat); + if (!GUID_all_zero(&info->domain_guid)) { + smb_uuid_pack(info->domain_guid, &guid_flat); } again: @@ -132,17 +131,17 @@ static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, if (buflen > 0) { DEBUG(10,("pack_dsdcinfo: Packing domain %s (%s)\n", - info->domain_name, info->domain_controller_name)); + info->domain_name, info->dc_unc)); } len += tdb_pack(buffer+len, buflen-len, "ffdBffdff", - info->domain_controller_name, - info->domain_controller_address, - info->domain_controller_address_type, + info->dc_unc, + info->dc_address, + info->dc_address_type, UUID_FLAT_SIZE, guid_flat.info, info->domain_name, - info->dns_forest_name, - info->flags, + info->forest_name, + info->dc_flags, info->dc_site_name, info->client_site_name); @@ -169,33 +168,33 @@ static int pack_dsdcinfo(struct DS_DOMAIN_CONTROLLER_INFO *info, static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, unsigned char *buf, int buflen, - struct DS_DOMAIN_CONTROLLER_INFO **info_ret) + struct netr_DsRGetDCNameInfo **info_ret) { int len = 0; - struct DS_DOMAIN_CONTROLLER_INFO *info = NULL; + struct netr_DsRGetDCNameInfo *info = NULL; uint32_t guid_len = 0; unsigned char *guid_buf = NULL; UUID_FLAT guid_flat; /* forgive me 6 times */ - fstring domain_controller_name; - fstring domain_controller_address; + fstring dc_unc; + fstring dc_address; fstring domain_name; - fstring dns_forest_name; + fstring forest_name; fstring dc_site_name; fstring client_site_name; - info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO); + info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); NT_STATUS_HAVE_NO_MEMORY(info); len += tdb_unpack(buf+len, buflen-len, "ffdBffdff", - &domain_controller_name, - &domain_controller_address, - &info->domain_controller_address_type, + &dc_unc, + &dc_address, + &info->dc_address_type, &guid_len, &guid_buf, &domain_name, - &dns_forest_name, - &info->flags, + &forest_name, + &info->dc_flags, &dc_site_name, &client_site_name); if (len == -1) { @@ -203,23 +202,23 @@ static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, goto failed; } - info->domain_controller_name = - talloc_strdup(mem_ctx, domain_controller_name); - info->domain_controller_address = - talloc_strdup(mem_ctx, domain_controller_address); + info->dc_unc = + talloc_strdup(mem_ctx, dc_unc); + info->dc_address = + talloc_strdup(mem_ctx, dc_address); info->domain_name = talloc_strdup(mem_ctx, domain_name); - info->dns_forest_name = - talloc_strdup(mem_ctx, dns_forest_name); + info->forest_name = + talloc_strdup(mem_ctx, forest_name); info->dc_site_name = talloc_strdup(mem_ctx, dc_site_name); info->client_site_name = talloc_strdup(mem_ctx, client_site_name); - if (!info->domain_controller_name || - !info->domain_controller_address || + if (!info->dc_unc || + !info->dc_address || !info->domain_name || - !info->dns_forest_name || + !info->forest_name || !info->dc_site_name || !info->client_site_name) { goto failed; @@ -235,16 +234,12 @@ static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, memcpy(&guid_flat.info, guid_buf, guid_len); smb_uuid_unpack(guid_flat, &guid); - info->domain_guid = (struct GUID *)talloc_memdup( - mem_ctx, &guid, sizeof(guid)); - if (!info->domain_guid) { - goto failed; - } + info->domain_guid = guid; SAFE_FREE(guid_buf); } DEBUG(10,("unpack_dcscinfo: Unpacked domain %s (%s)\n", - info->domain_name, info->domain_controller_name)); + info->domain_name, info->dc_unc)); *info_ret = info; @@ -297,7 +292,7 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx, static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, const char *domain_name, - struct DS_DOMAIN_CONTROLLER_INFO *info) + struct netr_DsRGetDCNameInfo *info) { time_t expire_time; char *key; @@ -346,7 +341,7 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct DS_DOMAIN_CONTROLLER_INFO *info) + struct netr_DsRGetDCNameInfo *info) { struct cldap_netlogon_reply r; @@ -355,7 +350,7 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, ZERO_STRUCT(r); - if (ads_cldap_netlogon(info->domain_controller_name, + if (ads_cldap_netlogon(info->dc_unc, info->domain_name, &r)) { dsgetdcname_cache_delete(mem_ctx, domain_name); @@ -409,7 +404,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct DS_DOMAIN_CONTROLLER_INFO **info, + struct netr_DsRGetDCNameInfo **info, bool *expired) { char *key; @@ -438,13 +433,13 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, data_blob_free(&blob); /* check flags */ - if (!check_cldap_reply_required_flags((*info)->flags, flags)) { + if (!check_cldap_reply_required_flags((*info)->dc_flags, flags)) { DEBUG(10,("invalid flags\n")); return NT_STATUS_INVALID_PARAMETER; } if ((flags & DS_IP_REQUIRED) && - ((*info)->domain_controller_address_type != ADS_INET_ADDRESS)) { + ((*info)->dc_address_type != DS_ADDRESS_TYPE_INET)) { return NT_STATUS_INVALID_PARAMETER_MIX; } @@ -459,7 +454,7 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { NTSTATUS status; bool expired = false; @@ -663,40 +658,36 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, ****************************************************************/ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, - const char *domain_controller_name, - const char *domain_controller_address, - uint32_t domain_controller_address_type, + const char *dc_unc, + const char *dc_address, + uint32_t dc_address_type, const struct GUID *domain_guid, const char *domain_name, - const char *dns_forest_name, + const char *forest_name, uint32_t flags, const char *dc_site_name, const char *client_site_name, - struct DS_DOMAIN_CONTROLLER_INFO **info_out) + struct netr_DsRGetDCNameInfo **info_out) { - struct DS_DOMAIN_CONTROLLER_INFO *info; + struct netr_DsRGetDCNameInfo *info; - info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO); + info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); NT_STATUS_HAVE_NO_MEMORY(info); - if (domain_controller_name) { - info->domain_controller_name = talloc_strdup(mem_ctx, - domain_controller_name); - NT_STATUS_HAVE_NO_MEMORY(info->domain_controller_name); + if (dc_unc) { + info->dc_unc = talloc_strdup(mem_ctx, dc_unc); + NT_STATUS_HAVE_NO_MEMORY(info->dc_unc); } - if (domain_controller_address) { - info->domain_controller_address = talloc_strdup(mem_ctx, - domain_controller_address); - NT_STATUS_HAVE_NO_MEMORY(info->domain_controller_address); + if (dc_address) { + info->dc_address = talloc_strdup(mem_ctx, dc_address); + NT_STATUS_HAVE_NO_MEMORY(info->dc_address); } - info->domain_controller_address_type = domain_controller_address_type; + info->dc_address_type = dc_address_type; if (domain_guid) { - info->domain_guid = (struct GUID *)talloc_memdup( - mem_ctx, domain_guid, sizeof(*domain_guid)); - NT_STATUS_HAVE_NO_MEMORY(info->domain_guid); + info->domain_guid = *domain_guid; } if (domain_name) { @@ -704,13 +695,12 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, NT_STATUS_HAVE_NO_MEMORY(info->domain_name); } - if (dns_forest_name) { - info->dns_forest_name = talloc_strdup(mem_ctx, - dns_forest_name); - NT_STATUS_HAVE_NO_MEMORY(info->dns_forest_name); + if (forest_name) { + info->forest_name = talloc_strdup(mem_ctx, forest_name); + NT_STATUS_HAVE_NO_MEMORY(info->forest_name); } - info->flags = flags; + info->dc_flags = flags; if (dc_site_name) { info->dc_site_name = talloc_strdup(mem_ctx, dc_site_name); @@ -736,7 +726,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, uint32_t flags, struct ip_service_name **dclist, int num_dcs, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { int i = 0; bool valid_dc = false; @@ -779,12 +769,12 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, } dc_hostname = r.hostname; dc_domain_name = r.domain; - dc_flags |= ADS_DNS_DOMAIN | ADS_DNS_CONTROLLER; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; } else { /* FIXME */ dc_hostname = r.hostname; dc_domain_name = r.domain; - dc_flags |= ADS_DNS_DOMAIN | ADS_DNS_CONTROLLER; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; } if (flags & DS_IP_REQUIRED) { @@ -792,17 +782,17 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, print_sockaddr(addr, sizeof(addr), &dclist[i]->ss); dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr); - dc_address_type = ADS_INET_ADDRESS; + dc_address_type = DS_ADDRESS_TYPE_INET; } else { dc_address = talloc_asprintf(mem_ctx, "\\\\%s", r.netbios_hostname); - dc_address_type = ADS_NETBIOS_ADDRESS; + dc_address_type = DS_ADDRESS_TYPE_NETBIOS; } NT_STATUS_HAVE_NO_MEMORY(dc_address); smb_uuid_unpack(r.guid, &dc_guid); if (r.forest) { - dc_flags |= ADS_DNS_FOREST; + dc_flags |= DS_DNS_FOREST; } return make_domain_controller_info(mem_ctx, @@ -827,7 +817,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, uint32_t flags, struct ip_service_name **dclist, int num_dcs, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { /* FIXME: code here */ @@ -842,7 +832,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct ip_service_name *dclist; @@ -901,10 +891,10 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, const char *site_name, uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info) + struct netr_DsRGetDCNameInfo **info) { NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - struct DS_DOMAIN_CONTROLLER_INFO *myinfo = NULL; + struct netr_DsRGetDCNameInfo *myinfo = NULL; DEBUG(10,("dsgetdcname: domain_name: %s, " "domain_guid: %s, site_name: %s, flags: 0x%08x\n", -- cgit From 4b5169f590425334d9ae3f2b7be2201e2e0b747e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 12 Feb 2008 11:54:37 +0100 Subject: Add explicit buf arg to cli_encrypt_message and cli_calculate_sign_mac (This used to be commit db6ae9ed2326e6cd68475375d049084cf1d5a98c) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 5 +++-- source3/libsmb/smb_seal.c | 6 +++--- source3/libsmb/smb_signing.c | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index d88a5d6242..9c27d30166 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -757,7 +757,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use /* 'resign' the last message, so we get the right sequence numbers for checking the first reply from the server */ - cli_calculate_sign_mac(cli); + cli_calculate_sign_mac(cli, cli->outbuf); if (!cli_check_sign_mac(cli)) { nt_status = NT_STATUS_ACCESS_DENIED; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3b7669f33e..2fd304f135 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -343,10 +343,11 @@ bool cli_send_smb(struct cli_state *cli) if (cli->fd == -1) return false; - cli_calculate_sign_mac(cli); + cli_calculate_sign_mac(cli, cli->outbuf); if (enc_on) { - NTSTATUS status = cli_encrypt_message(cli, &buf_out); + NTSTATUS status = cli_encrypt_message(cli, cli->outbuf, + &buf_out); if (!NT_STATUS_IS_OK(status)) { close(cli->fd); cli->fd = -1; diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index b5befbf7cd..a81ae9afd5 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -483,15 +483,15 @@ NTSTATUS cli_decrypt_message(struct cli_state *cli) Encrypt an outgoing buffer. Return the encrypted pointer in buf_out. ******************************************************************************/ -NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out) +NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out) { /* Ignore non-session messages. */ - if(CVAL(cli->outbuf,0)) { + if (CVAL(buf,0)) { return NT_STATUS_OK; } /* If we supported multiple encrytion contexts * here we'd look up based on tid. */ - return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out); + return common_encrypt_buffer(cli->trans_enc_state, buf, buf_out); } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index f03c21bd0e..eeaf28c3d1 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -573,9 +573,9 @@ void cli_free_signing_context(struct cli_state *cli) * Sign a packet with the current mechanism */ -void cli_calculate_sign_mac(struct cli_state *cli) +void cli_calculate_sign_mac(struct cli_state *cli, char *buf) { - cli->sign_info.sign_outgoing_message(cli->outbuf, &cli->sign_info); + cli->sign_info.sign_outgoing_message(buf, &cli->sign_info); } /** -- cgit From b9f7dd2909487f8e306774ee0475f8b20331a866 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 12 Feb 2008 23:16:37 +0100 Subject: Add explicit buf arg to cli_check_sign_mac (This used to be commit ffc1c8cc03e6bad40ed2be91392074b4f038a1bf) --- source3/libsmb/cliconnect.c | 2 +- source3/libsmb/clientgen.c | 2 +- source3/libsmb/smb_signing.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9c27d30166..912b841d5e 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -759,7 +759,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use for checking the first reply from the server */ cli_calculate_sign_mac(cli, cli->outbuf); - if (!cli_check_sign_mac(cli)) { + if (!cli_check_sign_mac(cli, cli->inbuf)) { nt_status = NT_STATUS_ACCESS_DENIED; } } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2fd304f135..ccd1cc67d5 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -164,7 +164,7 @@ bool cli_receive_smb(struct cli_state *cli) return false; } - if (!cli_check_sign_mac(cli)) { + if (!cli_check_sign_mac(cli, cli->inbuf)) { /* * If we get a signature failure in sessionsetup, then * the server sometimes just reflects the sent signature diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index eeaf28c3d1..bd6d97123d 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -584,9 +584,9 @@ void cli_calculate_sign_mac(struct cli_state *cli, char *buf) * which had a bad checksum, True otherwise. */ -bool cli_check_sign_mac(struct cli_state *cli) +bool cli_check_sign_mac(struct cli_state *cli, char *buf) { - if (!cli->sign_info.check_incoming_message(cli->inbuf, &cli->sign_info, True)) { + if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) { free_signing_context(&cli->sign_info); return False; } -- cgit From 11b81cb8e419315abc8bf2d7b1a93424aa9788e9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 Feb 2008 13:58:34 +0100 Subject: Add WERR_TIME_SKEW to werror mapping tables. Guenther (This used to be commit 74767be627d48eb1a8deea3784847159b536a0fb) --- source3/libsmb/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index a3043a2152..203f682599 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -84,6 +84,7 @@ werror_code_struct dos_errs[] = { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_TIME_SKEW", WERR_TIME_SKEW }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, { "WERR_IO_PENDING", WERR_IO_PENDING }, @@ -121,6 +122,7 @@ werror_str_struct dos_err_strs[] = { { WERR_USER_EXISTS, "User account already exists" }, { WERR_PASSWORD_MUST_CHANGE, "The password must be changed" }, { WERR_ACCOUNT_LOCKED_OUT, "Account locked out" }, + { WERR_TIME_SKEW, "Time difference between client and server" }, }; /***************************************************************************** -- cgit From 57a9fba097a5f5af7833eaf4355667dbfacaec43 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 14:03:38 +0100 Subject: Make cli_struct a talloc parent (This used to be commit e69244a5c8c7c6b7c1897adc4b4b1cfdfc7a7999) --- source3/libsmb/clientgen.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ccd1cc67d5..592f050e90 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -537,7 +537,7 @@ struct cli_state *cli_initialise(void) return NULL; } - cli = SMB_MALLOC_P(struct cli_state); + cli = talloc(NULL, struct cli_state); if (!cli) { return NULL; } @@ -695,7 +695,7 @@ void cli_shutdown(struct cli_state *cli) cli->fd = -1; cli->smb_rw_error = SMB_READ_OK; - SAFE_FREE(cli); + TALLOC_FREE(cli); } /**************************************************************************** -- cgit From be4a76a861f3a152f1d1aebf937b06e1628f2d55 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 14:04:54 +0100 Subject: Add cli_setup_packet_buf This is == cli_setup_packet but takes an explicit buffer argument (This used to be commit f64b46dc278899c3449cfd3dbb614aadcf5614d3) --- source3/libsmb/clientgen.c | 54 +++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 592f050e90..64191239d3 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -450,31 +450,41 @@ bool cli_send_smb_direct_writeX(struct cli_state *cli, Setup basics in a outgoing packet. ****************************************************************************/ -void cli_setup_packet(struct cli_state *cli) +void cli_setup_packet_buf(struct cli_state *cli, char *buf) { + uint16 flags2; cli->rap_error = 0; - SSVAL(cli->outbuf,smb_pid,cli->pid); - SSVAL(cli->outbuf,smb_uid,cli->vuid); - SSVAL(cli->outbuf,smb_mid,cli->mid); - if (cli->protocol > PROTOCOL_CORE) { - uint16 flags2; - if (cli->case_sensitive) { - SCVAL(cli->outbuf,smb_flg,0x0); - } else { - /* Default setting, case insensitive. */ - SCVAL(cli->outbuf,smb_flg,0x8); - } - flags2 = FLAGS2_LONG_PATH_COMPONENTS; - if (cli->capabilities & CAP_UNICODE) - flags2 |= FLAGS2_UNICODE_STRINGS; - if ((cli->capabilities & CAP_DFS) && cli->dfsroot) - flags2 |= FLAGS2_DFS_PATHNAMES; - if (cli->capabilities & CAP_STATUS32) - flags2 |= FLAGS2_32_BIT_ERROR_CODES; - if (cli->use_spnego) - flags2 |= FLAGS2_EXTENDED_SECURITY; - SSVAL(cli->outbuf,smb_flg2, flags2); + SIVAL(buf,smb_rcls,0); + SSVAL(buf,smb_pid,cli->pid); + memset(buf+smb_pidhigh, 0, 12); + SSVAL(buf,smb_uid,cli->vuid); + SSVAL(buf,smb_mid,cli->mid); + + if (cli->protocol <= PROTOCOL_CORE) { + return; + } + + if (cli->case_sensitive) { + SCVAL(buf,smb_flg,0x0); + } else { + /* Default setting, case insensitive. */ + SCVAL(buf,smb_flg,0x8); } + flags2 = FLAGS2_LONG_PATH_COMPONENTS; + if (cli->capabilities & CAP_UNICODE) + flags2 |= FLAGS2_UNICODE_STRINGS; + if ((cli->capabilities & CAP_DFS) && cli->dfsroot) + flags2 |= FLAGS2_DFS_PATHNAMES; + if (cli->capabilities & CAP_STATUS32) + flags2 |= FLAGS2_32_BIT_ERROR_CODES; + if (cli->use_spnego) + flags2 |= FLAGS2_EXTENDED_SECURITY; + SSVAL(buf,smb_flg2, flags2); +} + +void cli_setup_packet(struct cli_state *cli) +{ + cli_setup_packet_buf(cli, cli->outbuf); } /**************************************************************************** -- cgit From 6e2e0e2ce7ebef473cf8f8787363500eb090d692 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 Feb 2008 06:01:09 -0800 Subject: Fix the build - don't use SMB_TRANS_ENC_GSS without KRB5. Jeremy. (This used to be commit d16c295642c3df49be02440427ded0cd9b4179f5) --- source3/libsmb/clifsinfo.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index f4945f812a..0005c3908a 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -368,20 +368,16 @@ static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type sm ZERO_STRUCTP(es); es->smb_enc_type = smb_enc_type; - if (smb_enc_type == SMB_TRANS_ENC_GSS) { #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5) + if (smb_enc_type == SMB_TRANS_ENC_GSS) { es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss); if (!es->s.gss_state) { SAFE_FREE(es); return NULL; } ZERO_STRUCTP(es->s.gss_state); -#else - DEBUG(0,("make_cli_enc_state: no krb5 compiled.\n")); - SAFE_FREE(es); - return NULL; -#endif } +#endif return es; } -- cgit From 1d41b5bd2a58dcc6966a3a49ccb063ff05e46125 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 14:41:25 +0100 Subject: Add infrastructure to support async SMB requests (This used to be commit f5356825698a02df2d400b51dd95d1f857c83e81) --- source3/libsmb/async_smb.c | 483 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 483 insertions(+) create mode 100644 source3/libsmb/async_smb.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c new file mode 100644 index 0000000000..21bcd5b9b1 --- /dev/null +++ b/source3/libsmb/async_smb.c @@ -0,0 +1,483 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async SMB client requests + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +/* + * Fetch an error out of a NBT packet + */ + +NTSTATUS cli_pull_error(char *buf) +{ + uint32_t flags2 = SVAL(buf, smb_flg2); + + if (flags2 & FLAGS2_32_BIT_ERROR_CODES) { + return NT_STATUS(IVAL(buf, smb_rcls)); + } + + return NT_STATUS_DOS(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); +} + +/* + * Compatibility helper for the sync APIs: Fake NTSTATUS in cli->inbuf + */ + +void cli_set_error(struct cli_state *cli, NTSTATUS status) +{ + uint32_t flags2 = SVAL(cli->inbuf, smb_flg2); + + if (NT_STATUS_IS_DOS(status)) { + SSVAL(cli->inbuf, smb_flg2, + flags2 & ~FLAGS2_32_BIT_ERROR_CODES); + SCVAL(cli->inbuf, smb_rcls, NT_STATUS_DOS_CLASS(status)); + SSVAL(cli->inbuf, smb_err, NT_STATUS_DOS_CODE(status)); + return; + } + + SSVAL(cli->inbuf, smb_flg2, flags2 | FLAGS2_32_BIT_ERROR_CODES); + SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); + return; +} + +/* + * Allocate a new mid + */ + +static uint16_t cli_new_mid(struct cli_state *cli) +{ + uint16_t result; + struct cli_request *req; + + while (true) { + result = cli->mid++; + if (result == 0) { + continue; + } + + for (req = cli->outstanding_requests; req; req = req->next) { + if (result == req->mid) { + break; + } + } + + if (req == NULL) { + return result; + } + } +} + +static char *cli_request_print(TALLOC_CTX *mem_ctx, struct async_req *req) +{ + char *result = async_req_print(mem_ctx, req); + struct cli_request *cli_req = cli_request_get(req); + + if (result == NULL) { + return NULL; + } + + return talloc_asprintf_append_buffer( + result, "mid=%d\n", cli_req->mid); +} + +static int cli_request_destructor(struct cli_request *req) +{ + if (req->enc_state != NULL) { + common_free_enc_buffer(req->enc_state, req->outbuf); + } + DLIST_REMOVE(req->cli->outstanding_requests, req); + return 0; +} + +/* + * Create a fresh async smb request + */ + +struct async_req *cli_request_new(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint8_t num_words, size_t num_bytes, + struct cli_request **preq) +{ + struct async_req *result; + struct cli_request *cli_req; + size_t bufsize = smb_size + num_words * 2 + num_bytes; + + result = async_req_new(mem_ctx, ev); + if (result == NULL) { + return NULL; + } + + cli_req = (struct cli_request *)talloc_size( + result, sizeof(*cli_req) + bufsize); + if (cli_req == NULL) { + TALLOC_FREE(result); + return NULL; + } + talloc_set_name_const(cli_req, "struct cli_request"); + result->private_data = cli_req; + result->print = cli_request_print; + + cli_req->async = result; + cli_req->cli = cli; + cli_req->outbuf = ((char *)cli_req + sizeof(*cli_req)); + cli_req->sent = 0; + cli_req->mid = cli_new_mid(cli); + cli_req->inbuf = NULL; + cli_req->enc_state = NULL; + + SCVAL(cli_req->outbuf, smb_wct, num_words); + SSVAL(cli_req->outbuf, smb_vwv + num_words * 2, num_bytes); + + DLIST_ADD_END(cli->outstanding_requests, cli_req, + struct cli_request *); + talloc_set_destructor(cli_req, cli_request_destructor); + + DEBUG(10, ("cli_request_new: mid=%d\n", cli_req->mid)); + + *preq = cli_req; + return result; +} + +/* + * Convenience function to get the SMB part out of an async_req + */ + +struct cli_request *cli_request_get(struct async_req *req) +{ + if (req == NULL) { + return NULL; + } + return talloc_get_type_abort(req->private_data, struct cli_request); +} + +/* + * A PDU has arrived on cli->evt_inbuf + */ + +static void handle_incoming_pdu(struct cli_state *cli) +{ + struct cli_request *req; + uint16_t mid; + size_t raw_pdu_len, buf_len, pdu_len; + size_t rest_len; + NTSTATUS status; + + /* + * The encrypted PDU len might differ from the unencrypted one + */ + raw_pdu_len = smb_len(cli->evt_inbuf) + 4; + + /* + * TODO: Handle oplock break requests + */ + + if (cli_encryption_on(cli) && CVAL(cli->evt_inbuf, 0) == 0) { + uint16_t enc_ctx_num; + + status = get_enc_ctx_num((uint8_t *)cli->evt_inbuf, + &enc_ctx_num); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("get_enc_ctx_num returned %s\n", + nt_errstr(status))); + goto invalidate_requests; + } + + if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { + DEBUG(10, ("wrong enc_ctx %d, expected %d\n", + enc_ctx_num, + cli->trans_enc_state->enc_ctx_num)); + status = NT_STATUS_INVALID_HANDLE; + goto invalidate_requests; + } + + status = common_decrypt_buffer(cli->trans_enc_state, + cli->evt_inbuf); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("common_decrypt_buffer returned %s\n", + nt_errstr(status))); + goto invalidate_requests; + } + } + + if (!cli_check_sign_mac(cli, cli->evt_inbuf)) { + DEBUG(10, ("cli_check_sign_mac failed\n")); + status = NT_STATUS_ACCESS_DENIED; + goto invalidate_requests; + } + + mid = SVAL(cli->evt_inbuf, smb_mid); + + DEBUG(10, ("handle_incoming_pdu: got mid %d\n", mid)); + + for (req = cli->outstanding_requests; req; req = req->next) { + if (req->mid == mid) { + break; + } + } + + buf_len = talloc_get_size(cli->evt_inbuf); + pdu_len = smb_len(cli->evt_inbuf) + 4; + rest_len = buf_len - raw_pdu_len; + + if (req == NULL) { + DEBUG(3, ("Request for mid %d not found, dumping PDU\n", mid)); + + memmove(cli->evt_inbuf, cli->evt_inbuf + raw_pdu_len, + buf_len - raw_pdu_len); + + cli->evt_inbuf = TALLOC_REALLOC_ARRAY(NULL, cli->evt_inbuf, + char, rest_len); + return; + } + + if (buf_len == pdu_len) { + /* + * Optimal case: Exactly one PDU was in the socket buffer + */ + req->inbuf = talloc_move(req, &cli->evt_inbuf); + goto done; + } + + DEBUG(11, ("buf_len = %d, pdu_len = %d, splitting buffer\n", + (int)buf_len, (int)pdu_len)); + + if (pdu_len < rest_len) { + /* + * The PDU is shorter, talloc_memdup that one. + */ + req->inbuf = (char *)talloc_memdup( + req, cli->evt_inbuf, pdu_len); + + memmove(cli->evt_inbuf, + cli->evt_inbuf + raw_pdu_len, + buf_len - raw_pdu_len); + + cli->evt_inbuf = TALLOC_REALLOC_ARRAY( + NULL, cli->evt_inbuf, char, rest_len); + } + else { + /* + * The PDU is larger than the rest, + * talloc_memdup the rest + */ + req->inbuf = talloc_move(req, &cli->evt_inbuf); + + cli->evt_inbuf = (char *)talloc_memdup( + cli, req->inbuf + raw_pdu_len, + rest_len); + } + + if ((req->inbuf == NULL) || (cli->evt_inbuf == NULL)) { + status = NT_STATUS_NO_MEMORY; + goto invalidate_requests; + } + + done: + async_req_done(req->async); + return; + + invalidate_requests: + + DEBUG(10, ("handle_incoming_pdu: Aborting with %s\n", + nt_errstr(status))); + + for (req = cli->outstanding_requests; req; req = req->next) { + async_req_error(req->async, status); + } + return; +} + +/* + * fd event callback. This is the basic connection to the socket + */ + +static void cli_state_handler(struct event_context *event_ctx, + struct fd_event *event, uint16 flags, void *p) +{ + struct cli_state *cli = (struct cli_state *)p; + struct cli_request *req; + + DEBUG(11, ("cli_state_handler called with flags %d\n", flags)); + + if (flags & EVENT_FD_READ) { + int res, available; + size_t old_size, new_size; + char *tmp; + + res = ioctl(cli->fd, FIONREAD, &available); + if (res == -1) { + DEBUG(10, ("ioctl(FIONREAD) failed: %s\n", + strerror(errno))); + goto sock_error; + } + + if (available == 0) { + /* EOF */ + goto sock_error; + } + + old_size = talloc_get_size(cli->evt_inbuf); + new_size = old_size + available; + + if (new_size < old_size) { + /* wrap */ + goto sock_error; + } + + tmp = TALLOC_REALLOC_ARRAY(cli, cli->evt_inbuf, char, + new_size); + if (tmp == NULL) { + /* nomem */ + goto sock_error; + } + cli->evt_inbuf = tmp; + + res = recv(cli->fd, cli->evt_inbuf + old_size, available, 0); + if (res == -1) { + DEBUG(10, ("recv failed: %s\n", strerror(errno))); + goto sock_error; + } + + DEBUG(11, ("cli_state_handler: received %d bytes, " + "smb_len(evt_inbuf) = %d\n", (int)res, + smb_len(cli->evt_inbuf))); + + /* recv *might* have returned less than announced */ + new_size = old_size + res; + + /* shrink, so I don't expect errors here */ + cli->evt_inbuf = TALLOC_REALLOC_ARRAY(cli, cli->evt_inbuf, + char, new_size); + + while ((cli->evt_inbuf != NULL) + && ((smb_len(cli->evt_inbuf) + 4) <= new_size)) { + /* + * we've got a complete NBT level PDU in evt_inbuf + */ + handle_incoming_pdu(cli); + new_size = talloc_get_size(cli->evt_inbuf); + } + } + + if (flags & EVENT_FD_WRITE) { + size_t to_send; + ssize_t sent; + + for (req = cli->outstanding_requests; req; req = req->next) { + to_send = smb_len(req->outbuf)+4; + if (to_send > req->sent) { + break; + } + } + + if (req == NULL) { + event_fd_set_not_writeable(event); + return; + } + + sent = send(cli->fd, req->outbuf + req->sent, + to_send - req->sent, 0); + + if (sent < 0) { + goto sock_error; + } + + req->sent += sent; + + if (req->sent == to_send) { + return; + } + } + return; + + sock_error: + for (req = cli->outstanding_requests; req; req = req->next) { + req->async->state = ASYNC_REQ_ERROR; + req->async->status = map_nt_error_from_unix(errno); + } + TALLOC_FREE(cli->fd_event); + close(cli->fd); + cli->fd = -1; +} + +/* + * Holder for a talloc_destructor, we need to zero out the pointers in cli + * when deleting + */ +struct cli_tmp_event { + struct cli_state *cli; +}; + +static int cli_tmp_event_destructor(struct cli_tmp_event *e) +{ + TALLOC_FREE(e->cli->fd_event); + TALLOC_FREE(e->cli->event_ctx); + return 0; +} + +/* + * Create a temporary event context for use in the sync helper functions + */ + +struct cli_tmp_event *cli_tmp_event_ctx(TALLOC_CTX *mem_ctx, + struct cli_state *cli) +{ + struct cli_tmp_event *state; + + if (cli->event_ctx != NULL) { + return NULL; + } + + state = talloc(mem_ctx, struct cli_tmp_event); + if (state == NULL) { + return NULL; + } + state->cli = cli; + talloc_set_destructor(state, cli_tmp_event_destructor); + + cli->event_ctx = event_context_init(state); + if (cli->event_ctx == NULL) { + TALLOC_FREE(state); + return NULL; + } + + cli->fd_event = event_add_fd(cli->event_ctx, state, cli->fd, + EVENT_FD_READ, cli_state_handler, cli); + if (cli->fd_event == NULL) { + TALLOC_FREE(state); + return NULL; + } + return state; +} + +/* + * Attach an event context permanently to a cli_struct + */ + +NTSTATUS cli_add_event_ctx(struct cli_state *cli, + struct event_context *event_ctx) +{ + cli->event_ctx = event_ctx; + cli->fd_event = event_add_fd(event_ctx, cli, cli->fd, EVENT_FD_READ, + cli_state_handler, cli); + if (cli->fd_event == NULL) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} -- cgit From 525aac775ecef275dbd0732830a9bac0fd023135 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 15:21:33 +0100 Subject: Add async cli_pull support This is the big (and potentially controversial) one. It took a phone call to explain to metze what is going on inside cli_pull_read_done, but I would really like everybody to understand this function. It is a very good and reasonably complex example of async programming. If we want more asynchronism in s3, this is what we will have to deal with :-) Make use of it in the smbclient "get" command. Volker (This used to be commit 844a163458c7585e4306a21ffdae5d08e03d6e4d) --- source3/libsmb/clireadwrite.c | 425 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index af13ed8f73..5aee8f18bd 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -19,6 +19,431 @@ #include "includes.h" +/**************************************************************************** + Calculate the recommended read buffer size +****************************************************************************/ +static size_t cli_read_max_bufsize(struct cli_state *cli) +{ + if (!client_is_signing_on(cli) && !cli_encryption_on(cli) == false + && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { + return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; + } + if (cli->capabilities & CAP_LARGE_READX) { + return cli->is_samba + ? CLI_SAMBA_MAX_LARGE_READX_SIZE + : CLI_WINDOWS_MAX_LARGE_READX_SIZE; + } + return (cli->max_xmit - (smb_size+32)) & ~1023; +} + +/* + * Send a read&x request + */ + +struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, + struct cli_state *cli, int fnum, + off_t offset, size_t size) +{ + struct async_req *result; + struct cli_request *req; + bool bigoffset = False; + char *enc_buf; + + if (size > cli_read_max_bufsize(cli)) { + DEBUG(0, ("cli_read_andx_send got size=%d, can only handle " + "size=%d\n", (int)size, + (int)cli_read_max_bufsize(cli))); + return NULL; + } + + result = cli_request_new(mem_ctx, cli->event_ctx, cli, 12, 0, &req); + if (result == NULL) { + DEBUG(0, ("cli_request_new failed\n")); + return NULL; + } + + req = cli_request_get(result); + + req->data.read.ofs = offset; + req->data.read.size = size; + req->data.read.received = 0; + req->data.read.rcvbuf = NULL; + + if ((SMB_BIG_UINT)offset >> 32) + bigoffset = True; + + cli_set_message(req->outbuf, bigoffset ? 12 : 10, 0, False); + + SCVAL(req->outbuf,smb_com,SMBreadX); + SSVAL(req->outbuf,smb_tid,cli->cnum); + cli_setup_packet_buf(cli, req->outbuf); + + SCVAL(req->outbuf,smb_vwv0,0xFF); + SCVAL(req->outbuf,smb_vwv0+1,0); + SSVAL(req->outbuf,smb_vwv1,0); + SSVAL(req->outbuf,smb_vwv2,fnum); + SIVAL(req->outbuf,smb_vwv3,offset); + SSVAL(req->outbuf,smb_vwv5,size); + SSVAL(req->outbuf,smb_vwv6,size); + SSVAL(req->outbuf,smb_vwv7,(size >> 16)); + SSVAL(req->outbuf,smb_vwv8,0); + SSVAL(req->outbuf,smb_vwv9,0); + SSVAL(req->outbuf,smb_mid,req->mid); + + if (bigoffset) { + SIVAL(req->outbuf, smb_vwv10, + (((SMB_BIG_UINT)offset)>>32) & 0xffffffff); + } + + cli_calculate_sign_mac(cli, req->outbuf); + + event_fd_set_writeable(cli->fd_event); + + if (cli_encryption_on(cli)) { + NTSTATUS status; + status = cli_encrypt_message(cli, req->outbuf, &enc_buf); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Error in encrypting client message. " + "Error %s\n", nt_errstr(status))); + TALLOC_FREE(req); + return NULL; + } + req->outbuf = enc_buf; + req->enc_state = cli->trans_enc_state; + } + + return result; +} + +/* + * Pull the data out of a finished async read_and_x request. rcvbuf is + * talloced from the request, so better make sure that you copy it away before + * you talloc_free(req). "rcvbuf" is NOT a talloc_ctx of its own, so do not + * talloc_move it! + */ + +NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, + uint8_t **rcvbuf) +{ + struct cli_request *cli_req = cli_request_get(req); + NTSTATUS status; + size_t size; + + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; + } + + status = cli_pull_error(cli_req->inbuf); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* size is the number of bytes the server returned. + * Might be zero. */ + size = SVAL(cli_req->inbuf, smb_vwv5); + size |= (((unsigned int)(SVAL(cli_req->inbuf, smb_vwv7))) << 16); + + if (size > cli_req->data.read.size) { + DEBUG(5,("server returned more than we wanted!\n")); + return NT_STATUS_UNEXPECTED_IO_ERROR; + } + + if (size < 0) { + DEBUG(5,("read return < 0!\n")); + return NT_STATUS_UNEXPECTED_IO_ERROR; + } + + *rcvbuf = (uint8_t *) + (smb_base(cli_req->inbuf) + SVAL(cli_req->inbuf, smb_vwv6)); + *received = size; + return NT_STATUS_OK; +} + +/* + * Parallel read support. + * + * cli_pull sends as many read&x requests as the server would allow via + * max_mux at a time. When replies flow back in, the data is written into + * the callback function "sink" in the right order. + */ + +struct cli_pull_state { + struct async_req *req; + + struct cli_state *cli; + uint16_t fnum; + off_t start_offset; + size_t size; + + NTSTATUS (*sink)(char *buf, size_t n, void *priv); + void *priv; + + size_t chunk_size; + + /* + * Outstanding requests + */ + int num_reqs; + struct async_req **reqs; + + /* + * For how many bytes did we send requests already? + */ + off_t requested; + + /* + * Next request index to push into "sink". This walks around the "req" + * array, taking care that the requests are pushed to "sink" in the + * right order. If necessary (i.e. replies don't come in in the right + * order), replies are held back in "reqs". + */ + int top_req; + + /* + * How many bytes did we push into "sink"? + */ + + off_t pushed; +}; + +static char *cli_pull_print(TALLOC_CTX *mem_ctx, struct async_req *req) +{ + struct cli_pull_state *state = talloc_get_type_abort( + req->private_data, struct cli_pull_state); + char *result; + + result = async_req_print(mem_ctx, req); + if (result == NULL) { + return NULL; + } + + return talloc_asprintf_append_buffer( + result, "num_reqs=%d, top_req=%d", + state->num_reqs, state->top_req); +} + +static void cli_pull_read_done(struct async_req *read_req); + +/* + * Prepare an async pull request + */ + +struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, + uint16_t fnum, off_t start_offset, + size_t size, size_t window_size, + NTSTATUS (*sink)(char *buf, size_t n, + void *priv), + void *priv) +{ + struct async_req *result; + struct cli_pull_state *state; + int i; + + result = async_req_new(mem_ctx, cli->event_ctx); + if (result == NULL) { + goto failed; + } + state = talloc(result, struct cli_pull_state); + if (state == NULL) { + goto failed; + } + result->private_data = state; + result->print = cli_pull_print; + state->req = result; + + state->cli = cli; + state->fnum = fnum; + state->start_offset = start_offset; + state->size = size; + state->sink = sink; + state->priv = priv; + + state->pushed = 0; + state->top_req = 0; + state->chunk_size = cli_read_max_bufsize(cli); + + state->num_reqs = MAX(window_size/state->chunk_size, 1); + state->num_reqs = MIN(state->num_reqs, cli->max_mux); + + state->reqs = TALLOC_ZERO_ARRAY(state, struct async_req *, + state->num_reqs); + if (state->reqs == NULL) { + goto failed; + } + + state->requested = 0; + + for (i=0; inum_reqs; i++) { + size_t size_left, request_thistime; + + if (state->requested >= size) { + state->num_reqs = i; + break; + } + + size_left = size - state->requested; + request_thistime = MIN(size_left, state->chunk_size); + + state->reqs[i] = cli_read_andx_send( + state->reqs, cli, fnum, + state->start_offset + state->requested, + request_thistime); + + if (state->reqs[i] == NULL) { + goto failed; + } + + state->reqs[i]->async.fn = cli_pull_read_done; + state->reqs[i]->async.priv = result; + + state->requested += request_thistime; + } + return result; + +failed: + TALLOC_FREE(result); + return NULL; +} + +/* + * Handle incoming read replies, push the data into sink and send out new + * requests if necessary. + */ + +static void cli_pull_read_done(struct async_req *read_req) +{ + struct async_req *pull_req = talloc_get_type_abort( + read_req->async.priv, struct async_req); + struct cli_pull_state *state = talloc_get_type_abort( + pull_req->private_data, struct cli_pull_state); + struct cli_request *read_state = cli_request_get(read_req); + NTSTATUS status; + + status = cli_read_andx_recv(read_req, &read_state->data.read.received, + &read_state->data.read.rcvbuf); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(state->req, status); + return; + } + + /* + * This loop is the one to take care of out-of-order replies. All + * pending requests are in state->reqs, state->reqs[top_req] is the + * one that is to be pushed next. If however a request later than + * top_req is replied to, then we can't push yet. If top_req is + * replied to at a later point then, we need to push all the finished + * requests. + */ + + while (state->reqs[state->top_req] != NULL) { + struct cli_request *top_read; + + DEBUG(11, ("cli_pull_read_done: top_req = %d\n", + state->top_req)); + + if (state->reqs[state->top_req]->state < ASYNC_REQ_DONE) { + DEBUG(11, ("cli_pull_read_done: top request not yet " + "done\n")); + return; + } + + top_read = cli_request_get(state->reqs[state->top_req]); + + DEBUG(10, ("cli_pull_read_done: Pushing %d bytes, %d already " + "pushed\n", (int)top_read->data.read.received, + (int)state->pushed)); + + status = state->sink((char *)top_read->data.read.rcvbuf, + top_read->data.read.received, + state->priv); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(state->req, status); + return; + } + state->pushed += top_read->data.read.received; + + TALLOC_FREE(state->reqs[state->top_req]); + + if (state->requested < state->size) { + struct async_req *new_req; + size_t size_left, request_thistime; + + size_left = state->size - state->requested; + request_thistime = MIN(size_left, state->chunk_size); + + DEBUG(10, ("cli_pull_read_done: Requesting %d bytes " + "at %d, position %d\n", + (int)request_thistime, + (int)(state->start_offset + + state->requested), + state->top_req)); + + new_req = cli_read_andx_send( + state->reqs, state->cli, state->fnum, + state->start_offset + state->requested, + request_thistime); + + if (async_req_nomem(new_req, state->req)) { + return; + } + + new_req->async.fn = cli_pull_read_done; + new_req->async.priv = pull_req; + + state->reqs[state->top_req] = new_req; + state->requested += request_thistime; + } + + state->top_req = (state->top_req+1) % state->num_reqs; + } + + async_req_done(pull_req); +} + +NTSTATUS cli_pull_recv(struct async_req *req, ssize_t *received) +{ + struct cli_pull_state *state = talloc_get_type_abort( + req->private_data, struct cli_pull_state); + + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; + } + *received = state->pushed; + return NT_STATUS_OK; +} + +NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, + off_t start_offset, size_t size, size_t window_size, + NTSTATUS (*sink)(char *buf, size_t n, void *priv), + void *priv, ssize_t *received) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct async_req *req; + NTSTATUS result = NT_STATUS_NO_MEMORY; + + if (cli_tmp_event_ctx(frame, cli) == NULL) { + goto nomem; + } + + req = cli_pull_send(frame, cli, fnum, start_offset, size, window_size, + sink, priv); + if (req == NULL) { + goto nomem; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(cli->event_ctx); + } + + result = cli_pull_recv(req, received); + nomem: + TALLOC_FREE(frame); + return result; +} + /**************************************************************************** Issue a single SMBread and don't wait for a reply. ****************************************************************************/ -- cgit From 95222d115a1ab676ecebdaa30d627608afb9758f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 15:26:01 +0100 Subject: Convert cli_read to use cli_pull (This used to be commit 719527f55e88f0c5fdceda5c807475aba299c79f) --- source3/libsmb/clireadwrite.c | 178 ++++-------------------------------------- 1 file changed, 15 insertions(+), 163 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 5aee8f18bd..c618509f01 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -444,175 +444,27 @@ NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, return result; } -/**************************************************************************** -Issue a single SMBread and don't wait for a reply. -****************************************************************************/ - -static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset, - size_t size, int i) +static NTSTATUS cli_read_sink(char *buf, size_t n, void *priv) { - bool bigoffset = False; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - if ((SMB_BIG_UINT)offset >> 32) - bigoffset = True; - - cli_set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); - - SCVAL(cli->outbuf,smb_com,SMBreadX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - SSVAL(cli->outbuf,smb_vwv5,size); - SSVAL(cli->outbuf,smb_vwv6,size); - SSVAL(cli->outbuf,smb_vwv7,(size >> 16)); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - if (bigoffset) { - SIVAL(cli->outbuf,smb_vwv10,(((SMB_BIG_UINT)offset)>>32) & 0xffffffff); - } - - return cli_send_smb(cli); + char **pbuf = (char **)priv; + memcpy(*pbuf, buf, n); + *pbuf += n; + return NT_STATUS_OK; } -/**************************************************************************** - Read size bytes at offset offset using SMBreadX. -****************************************************************************/ - -ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, + off_t offset, size_t size) { - char *p; - size_t size2; - size_t readsize; - ssize_t total = 0; - /* We can only do direct reads if not signing or encrypting. */ - bool direct_reads = !client_is_signing_on(cli) && !cli_encryption_on(cli); - - if (size == 0) - return 0; - - /* - * Set readsize to the maximum size we can handle in one readX, - * rounded down to a multiple of 1024. - */ - - if (client_is_signing_on(cli) == false && - cli_encryption_on(cli) == false && - (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { - readsize = CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; - } else if (cli->capabilities & CAP_LARGE_READX) { - if (cli->is_samba) { - readsize = CLI_SAMBA_MAX_LARGE_READX_SIZE; - } else { - readsize = CLI_WINDOWS_MAX_LARGE_READX_SIZE; - } - } else { - readsize = (cli->max_xmit - (smb_size+32)) & ~1023; - } - - while (total < size) { - readsize = MIN(readsize, size-total); - - /* Issue a read and receive a reply */ - - if (!cli_issue_read(cli, fnum, offset, readsize, 0)) - return -1; - - if (direct_reads) { - if (!cli_receive_smb_readX_header(cli)) - return -1; - } else { - if (!cli_receive_smb(cli)) - return -1; - } - - /* Check for error. Make sure to check for DOS and NT - errors. */ - - if (cli_is_error(cli)) { - bool recoverable_error = False; - NTSTATUS status = NT_STATUS_OK; - uint8 eclass = 0; - uint32 ecode = 0; - - if (cli_is_nt_error(cli)) - status = cli_nt_error(cli); - else - cli_dos_error(cli, &eclass, &ecode); - - /* - * ERRDOS ERRmoredata or STATUS_MORE_ENRTIES is a - * recoverable error, plus we have valid data in the - * packet so don't error out here. - */ - - if ((eclass == ERRDOS && ecode == ERRmoredata) || - NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES)) - recoverable_error = True; - - if (!recoverable_error) - return -1; - } - - /* size2 is the number of bytes the server returned. - * Might be zero. */ - size2 = SVAL(cli->inbuf, smb_vwv5); - size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7))) << 16); - - if (size2 > readsize) { - DEBUG(5,("server returned more than we wanted!\n")); - return -1; - } else if (size2 < 0) { - DEBUG(5,("read return < 0!\n")); - return -1; - } - - if (size2) { - /* smb_vwv6 is the offset in the packet of the returned - * data bytes. Only valid if size2 != 0. */ - - if (!direct_reads) { - /* Copy data into buffer */ - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - memcpy(buf + total, p, size2); - } else { - /* Ensure the remaining data matches the return size. */ - ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6); - - /* Ensure the size is correct. */ - if (toread != size2) { - DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n", - (int)toread, (unsigned int)size2 )); - return -1; - } - - /* Read data directly into buffer */ - toread = cli_receive_smb_data(cli,buf+total,size2); - if (toread != size2) { - DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n", - (int)toread, (unsigned int)size2 )); - return -1; - } - } - } - - total += size2; - offset += size2; - - /* - * If the server returned less than we asked for we're at EOF. - */ + NTSTATUS status; + ssize_t ret; - if (size2 < readsize) - break; + status = cli_pull(cli, fnum, offset, size, size, + cli_read_sink, &buf, &ret); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + return -1; } - - return total; + return ret; } #if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */ -- cgit From bddceee09a12e6308b5e27bf666d8948b2a894d1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 28 Feb 2008 23:15:11 +0100 Subject: Fix memleak in netsamlogon_cache_get(). Guenther (This used to be commit b736c77dc6c36dcdb601903fadf0ef7f163052a3) --- source3/libsmb/samlogon_cache.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 0d855f4c6c..73b570c383 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -226,6 +226,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID * if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { DEBUG(0,("netsamlogon_cache_get: failed to pull entry from cache\n")); tdb_delete(netsamlogon_tdb, data); + TALLOC_FREE(info3); goto done; } -- cgit From 45615d62838123bdf620a9c409d9868d47977800 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 29 Feb 2008 22:33:35 +0100 Subject: Check the right variable for being NULL (This used to be commit f2c67803792f1fd3929e922c1f626f8247e08992) --- source3/libsmb/ntlmssp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 35c20ed647..8355669d9f 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -571,7 +571,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, strlower_m(dnsdomname); dnsname = get_mydnsfullname(); - if (!dnsdomname) { + if (!dnsname) { return NT_STATUS_INVALID_COMPUTER_NAME; } -- cgit From 5e0d86c4076f9b04a2c79ab47b497924248050aa Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 29 Feb 2008 22:38:10 +0100 Subject: Restore 3.0 behaviour with empty /etc/hosts Jeremy, in 3.0 we allowed get_mydnsdomname and get_mydnsfullname to fail without filling in anything useful. Worked fine. Without this patch and a empty /etc/hosts and no DNS configured, session setup would return NT_STATUS_BAD_NETWORK_NAME. This is confusing at best, BAD_NETWORK_NAME afaik is only ever returned from tcon normally. This restores the 3.0 behaviour. Comments? Volker (This used to be commit 2bd3b7d474768f842921945d283eac10da2a1684) --- source3/libsmb/ntlmssp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 8355669d9f..7082ea7e4e 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -566,13 +566,16 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state, /* This should be a 'netbios domain -> DNS domain' mapping */ dnsdomname = get_mydnsdomname(ntlmssp_state->mem_ctx); if (!dnsdomname) { - return NT_STATUS_BAD_NETWORK_NAME; + dnsdomname = talloc_strdup(ntlmssp_state->mem_ctx, ""); + } + if (!dnsdomname) { + return NT_STATUS_NO_MEMORY; } strlower_m(dnsdomname); dnsname = get_mydnsfullname(); if (!dnsname) { - return NT_STATUS_INVALID_COMPUTER_NAME; + dnsname = ""; } /* This creates the 'blob' of names that appears at the end of the packet */ -- cgit From 342859edfc244f2c80b6d080aa4edb214eb34a7b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Mar 2008 09:26:06 +0100 Subject: Revert "Convert cli_read to use cli_pull" This reverts commit 719527f55e88f0c5fdceda5c807475aba299c79f. (This used to be commit ac301fada257e2d3b50148109a3d44fa1421b0b4) --- source3/libsmb/clireadwrite.c | 178 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 163 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index c618509f01..5aee8f18bd 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -444,27 +444,175 @@ NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, return result; } -static NTSTATUS cli_read_sink(char *buf, size_t n, void *priv) +/**************************************************************************** +Issue a single SMBread and don't wait for a reply. +****************************************************************************/ + +static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset, + size_t size, int i) { - char **pbuf = (char **)priv; - memcpy(*pbuf, buf, n); - *pbuf += n; - return NT_STATUS_OK; + bool bigoffset = False; + + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + if ((SMB_BIG_UINT)offset >> 32) + bigoffset = True; + + cli_set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); + + SCVAL(cli->outbuf,smb_com,SMBreadX); + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SCVAL(cli->outbuf,smb_vwv0,0xFF); + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + SSVAL(cli->outbuf,smb_vwv5,size); + SSVAL(cli->outbuf,smb_vwv6,size); + SSVAL(cli->outbuf,smb_vwv7,(size >> 16)); + SSVAL(cli->outbuf,smb_mid,cli->mid + i); + + if (bigoffset) { + SIVAL(cli->outbuf,smb_vwv10,(((SMB_BIG_UINT)offset)>>32) & 0xffffffff); + } + + return cli_send_smb(cli); } -ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, - off_t offset, size_t size) +/**************************************************************************** + Read size bytes at offset offset using SMBreadX. +****************************************************************************/ + +ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { - NTSTATUS status; - ssize_t ret; + char *p; + size_t size2; + size_t readsize; + ssize_t total = 0; + /* We can only do direct reads if not signing or encrypting. */ + bool direct_reads = !client_is_signing_on(cli) && !cli_encryption_on(cli); - status = cli_pull(cli, fnum, offset, size, size, - cli_read_sink, &buf, &ret); - if (!NT_STATUS_IS_OK(status)) { - cli_set_error(cli, status); - return -1; + if (size == 0) + return 0; + + /* + * Set readsize to the maximum size we can handle in one readX, + * rounded down to a multiple of 1024. + */ + + if (client_is_signing_on(cli) == false && + cli_encryption_on(cli) == false && + (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { + readsize = CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; + } else if (cli->capabilities & CAP_LARGE_READX) { + if (cli->is_samba) { + readsize = CLI_SAMBA_MAX_LARGE_READX_SIZE; + } else { + readsize = CLI_WINDOWS_MAX_LARGE_READX_SIZE; + } + } else { + readsize = (cli->max_xmit - (smb_size+32)) & ~1023; + } + + while (total < size) { + readsize = MIN(readsize, size-total); + + /* Issue a read and receive a reply */ + + if (!cli_issue_read(cli, fnum, offset, readsize, 0)) + return -1; + + if (direct_reads) { + if (!cli_receive_smb_readX_header(cli)) + return -1; + } else { + if (!cli_receive_smb(cli)) + return -1; + } + + /* Check for error. Make sure to check for DOS and NT + errors. */ + + if (cli_is_error(cli)) { + bool recoverable_error = False; + NTSTATUS status = NT_STATUS_OK; + uint8 eclass = 0; + uint32 ecode = 0; + + if (cli_is_nt_error(cli)) + status = cli_nt_error(cli); + else + cli_dos_error(cli, &eclass, &ecode); + + /* + * ERRDOS ERRmoredata or STATUS_MORE_ENRTIES is a + * recoverable error, plus we have valid data in the + * packet so don't error out here. + */ + + if ((eclass == ERRDOS && ecode == ERRmoredata) || + NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES)) + recoverable_error = True; + + if (!recoverable_error) + return -1; + } + + /* size2 is the number of bytes the server returned. + * Might be zero. */ + size2 = SVAL(cli->inbuf, smb_vwv5); + size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7))) << 16); + + if (size2 > readsize) { + DEBUG(5,("server returned more than we wanted!\n")); + return -1; + } else if (size2 < 0) { + DEBUG(5,("read return < 0!\n")); + return -1; + } + + if (size2) { + /* smb_vwv6 is the offset in the packet of the returned + * data bytes. Only valid if size2 != 0. */ + + if (!direct_reads) { + /* Copy data into buffer */ + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + memcpy(buf + total, p, size2); + } else { + /* Ensure the remaining data matches the return size. */ + ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6); + + /* Ensure the size is correct. */ + if (toread != size2) { + DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n", + (int)toread, (unsigned int)size2 )); + return -1; + } + + /* Read data directly into buffer */ + toread = cli_receive_smb_data(cli,buf+total,size2); + if (toread != size2) { + DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n", + (int)toread, (unsigned int)size2 )); + return -1; + } + } + } + + total += size2; + offset += size2; + + /* + * If the server returned less than we asked for we're at EOF. + */ + + if (size2 < readsize) + break; } - return ret; + + return total; } #if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */ -- cgit From a34d158880b84cb4d14cc8055f4d5122d873bfbf Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Mar 2008 09:26:18 +0100 Subject: Revert "Add async cli_pull support" This reverts commit 844a163458c7585e4306a21ffdae5d08e03d6e4d. (This used to be commit 5ab1cfda500de07ff3c712442ab2fc74eecc8886) --- source3/libsmb/clireadwrite.c | 425 ------------------------------------------ 1 file changed, 425 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 5aee8f18bd..af13ed8f73 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -19,431 +19,6 @@ #include "includes.h" -/**************************************************************************** - Calculate the recommended read buffer size -****************************************************************************/ -static size_t cli_read_max_bufsize(struct cli_state *cli) -{ - if (!client_is_signing_on(cli) && !cli_encryption_on(cli) == false - && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { - return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; - } - if (cli->capabilities & CAP_LARGE_READX) { - return cli->is_samba - ? CLI_SAMBA_MAX_LARGE_READX_SIZE - : CLI_WINDOWS_MAX_LARGE_READX_SIZE; - } - return (cli->max_xmit - (smb_size+32)) & ~1023; -} - -/* - * Send a read&x request - */ - -struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, - struct cli_state *cli, int fnum, - off_t offset, size_t size) -{ - struct async_req *result; - struct cli_request *req; - bool bigoffset = False; - char *enc_buf; - - if (size > cli_read_max_bufsize(cli)) { - DEBUG(0, ("cli_read_andx_send got size=%d, can only handle " - "size=%d\n", (int)size, - (int)cli_read_max_bufsize(cli))); - return NULL; - } - - result = cli_request_new(mem_ctx, cli->event_ctx, cli, 12, 0, &req); - if (result == NULL) { - DEBUG(0, ("cli_request_new failed\n")); - return NULL; - } - - req = cli_request_get(result); - - req->data.read.ofs = offset; - req->data.read.size = size; - req->data.read.received = 0; - req->data.read.rcvbuf = NULL; - - if ((SMB_BIG_UINT)offset >> 32) - bigoffset = True; - - cli_set_message(req->outbuf, bigoffset ? 12 : 10, 0, False); - - SCVAL(req->outbuf,smb_com,SMBreadX); - SSVAL(req->outbuf,smb_tid,cli->cnum); - cli_setup_packet_buf(cli, req->outbuf); - - SCVAL(req->outbuf,smb_vwv0,0xFF); - SCVAL(req->outbuf,smb_vwv0+1,0); - SSVAL(req->outbuf,smb_vwv1,0); - SSVAL(req->outbuf,smb_vwv2,fnum); - SIVAL(req->outbuf,smb_vwv3,offset); - SSVAL(req->outbuf,smb_vwv5,size); - SSVAL(req->outbuf,smb_vwv6,size); - SSVAL(req->outbuf,smb_vwv7,(size >> 16)); - SSVAL(req->outbuf,smb_vwv8,0); - SSVAL(req->outbuf,smb_vwv9,0); - SSVAL(req->outbuf,smb_mid,req->mid); - - if (bigoffset) { - SIVAL(req->outbuf, smb_vwv10, - (((SMB_BIG_UINT)offset)>>32) & 0xffffffff); - } - - cli_calculate_sign_mac(cli, req->outbuf); - - event_fd_set_writeable(cli->fd_event); - - if (cli_encryption_on(cli)) { - NTSTATUS status; - status = cli_encrypt_message(cli, req->outbuf, &enc_buf); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Error in encrypting client message. " - "Error %s\n", nt_errstr(status))); - TALLOC_FREE(req); - return NULL; - } - req->outbuf = enc_buf; - req->enc_state = cli->trans_enc_state; - } - - return result; -} - -/* - * Pull the data out of a finished async read_and_x request. rcvbuf is - * talloced from the request, so better make sure that you copy it away before - * you talloc_free(req). "rcvbuf" is NOT a talloc_ctx of its own, so do not - * talloc_move it! - */ - -NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, - uint8_t **rcvbuf) -{ - struct cli_request *cli_req = cli_request_get(req); - NTSTATUS status; - size_t size; - - SMB_ASSERT(req->state >= ASYNC_REQ_DONE); - if (req->state == ASYNC_REQ_ERROR) { - return req->status; - } - - status = cli_pull_error(cli_req->inbuf); - - if (!NT_STATUS_IS_OK(status)) { - return status; - } - - /* size is the number of bytes the server returned. - * Might be zero. */ - size = SVAL(cli_req->inbuf, smb_vwv5); - size |= (((unsigned int)(SVAL(cli_req->inbuf, smb_vwv7))) << 16); - - if (size > cli_req->data.read.size) { - DEBUG(5,("server returned more than we wanted!\n")); - return NT_STATUS_UNEXPECTED_IO_ERROR; - } - - if (size < 0) { - DEBUG(5,("read return < 0!\n")); - return NT_STATUS_UNEXPECTED_IO_ERROR; - } - - *rcvbuf = (uint8_t *) - (smb_base(cli_req->inbuf) + SVAL(cli_req->inbuf, smb_vwv6)); - *received = size; - return NT_STATUS_OK; -} - -/* - * Parallel read support. - * - * cli_pull sends as many read&x requests as the server would allow via - * max_mux at a time. When replies flow back in, the data is written into - * the callback function "sink" in the right order. - */ - -struct cli_pull_state { - struct async_req *req; - - struct cli_state *cli; - uint16_t fnum; - off_t start_offset; - size_t size; - - NTSTATUS (*sink)(char *buf, size_t n, void *priv); - void *priv; - - size_t chunk_size; - - /* - * Outstanding requests - */ - int num_reqs; - struct async_req **reqs; - - /* - * For how many bytes did we send requests already? - */ - off_t requested; - - /* - * Next request index to push into "sink". This walks around the "req" - * array, taking care that the requests are pushed to "sink" in the - * right order. If necessary (i.e. replies don't come in in the right - * order), replies are held back in "reqs". - */ - int top_req; - - /* - * How many bytes did we push into "sink"? - */ - - off_t pushed; -}; - -static char *cli_pull_print(TALLOC_CTX *mem_ctx, struct async_req *req) -{ - struct cli_pull_state *state = talloc_get_type_abort( - req->private_data, struct cli_pull_state); - char *result; - - result = async_req_print(mem_ctx, req); - if (result == NULL) { - return NULL; - } - - return talloc_asprintf_append_buffer( - result, "num_reqs=%d, top_req=%d", - state->num_reqs, state->top_req); -} - -static void cli_pull_read_done(struct async_req *read_req); - -/* - * Prepare an async pull request - */ - -struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, - uint16_t fnum, off_t start_offset, - size_t size, size_t window_size, - NTSTATUS (*sink)(char *buf, size_t n, - void *priv), - void *priv) -{ - struct async_req *result; - struct cli_pull_state *state; - int i; - - result = async_req_new(mem_ctx, cli->event_ctx); - if (result == NULL) { - goto failed; - } - state = talloc(result, struct cli_pull_state); - if (state == NULL) { - goto failed; - } - result->private_data = state; - result->print = cli_pull_print; - state->req = result; - - state->cli = cli; - state->fnum = fnum; - state->start_offset = start_offset; - state->size = size; - state->sink = sink; - state->priv = priv; - - state->pushed = 0; - state->top_req = 0; - state->chunk_size = cli_read_max_bufsize(cli); - - state->num_reqs = MAX(window_size/state->chunk_size, 1); - state->num_reqs = MIN(state->num_reqs, cli->max_mux); - - state->reqs = TALLOC_ZERO_ARRAY(state, struct async_req *, - state->num_reqs); - if (state->reqs == NULL) { - goto failed; - } - - state->requested = 0; - - for (i=0; inum_reqs; i++) { - size_t size_left, request_thistime; - - if (state->requested >= size) { - state->num_reqs = i; - break; - } - - size_left = size - state->requested; - request_thistime = MIN(size_left, state->chunk_size); - - state->reqs[i] = cli_read_andx_send( - state->reqs, cli, fnum, - state->start_offset + state->requested, - request_thistime); - - if (state->reqs[i] == NULL) { - goto failed; - } - - state->reqs[i]->async.fn = cli_pull_read_done; - state->reqs[i]->async.priv = result; - - state->requested += request_thistime; - } - return result; - -failed: - TALLOC_FREE(result); - return NULL; -} - -/* - * Handle incoming read replies, push the data into sink and send out new - * requests if necessary. - */ - -static void cli_pull_read_done(struct async_req *read_req) -{ - struct async_req *pull_req = talloc_get_type_abort( - read_req->async.priv, struct async_req); - struct cli_pull_state *state = talloc_get_type_abort( - pull_req->private_data, struct cli_pull_state); - struct cli_request *read_state = cli_request_get(read_req); - NTSTATUS status; - - status = cli_read_andx_recv(read_req, &read_state->data.read.received, - &read_state->data.read.rcvbuf); - if (!NT_STATUS_IS_OK(status)) { - async_req_error(state->req, status); - return; - } - - /* - * This loop is the one to take care of out-of-order replies. All - * pending requests are in state->reqs, state->reqs[top_req] is the - * one that is to be pushed next. If however a request later than - * top_req is replied to, then we can't push yet. If top_req is - * replied to at a later point then, we need to push all the finished - * requests. - */ - - while (state->reqs[state->top_req] != NULL) { - struct cli_request *top_read; - - DEBUG(11, ("cli_pull_read_done: top_req = %d\n", - state->top_req)); - - if (state->reqs[state->top_req]->state < ASYNC_REQ_DONE) { - DEBUG(11, ("cli_pull_read_done: top request not yet " - "done\n")); - return; - } - - top_read = cli_request_get(state->reqs[state->top_req]); - - DEBUG(10, ("cli_pull_read_done: Pushing %d bytes, %d already " - "pushed\n", (int)top_read->data.read.received, - (int)state->pushed)); - - status = state->sink((char *)top_read->data.read.rcvbuf, - top_read->data.read.received, - state->priv); - if (!NT_STATUS_IS_OK(status)) { - async_req_error(state->req, status); - return; - } - state->pushed += top_read->data.read.received; - - TALLOC_FREE(state->reqs[state->top_req]); - - if (state->requested < state->size) { - struct async_req *new_req; - size_t size_left, request_thistime; - - size_left = state->size - state->requested; - request_thistime = MIN(size_left, state->chunk_size); - - DEBUG(10, ("cli_pull_read_done: Requesting %d bytes " - "at %d, position %d\n", - (int)request_thistime, - (int)(state->start_offset - + state->requested), - state->top_req)); - - new_req = cli_read_andx_send( - state->reqs, state->cli, state->fnum, - state->start_offset + state->requested, - request_thistime); - - if (async_req_nomem(new_req, state->req)) { - return; - } - - new_req->async.fn = cli_pull_read_done; - new_req->async.priv = pull_req; - - state->reqs[state->top_req] = new_req; - state->requested += request_thistime; - } - - state->top_req = (state->top_req+1) % state->num_reqs; - } - - async_req_done(pull_req); -} - -NTSTATUS cli_pull_recv(struct async_req *req, ssize_t *received) -{ - struct cli_pull_state *state = talloc_get_type_abort( - req->private_data, struct cli_pull_state); - - SMB_ASSERT(req->state >= ASYNC_REQ_DONE); - if (req->state == ASYNC_REQ_ERROR) { - return req->status; - } - *received = state->pushed; - return NT_STATUS_OK; -} - -NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, - off_t start_offset, size_t size, size_t window_size, - NTSTATUS (*sink)(char *buf, size_t n, void *priv), - void *priv, ssize_t *received) -{ - TALLOC_CTX *frame = talloc_stackframe(); - struct async_req *req; - NTSTATUS result = NT_STATUS_NO_MEMORY; - - if (cli_tmp_event_ctx(frame, cli) == NULL) { - goto nomem; - } - - req = cli_pull_send(frame, cli, fnum, start_offset, size, window_size, - sink, priv); - if (req == NULL) { - goto nomem; - } - - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(cli->event_ctx); - } - - result = cli_pull_recv(req, received); - nomem: - TALLOC_FREE(frame); - return result; -} - /**************************************************************************** Issue a single SMBread and don't wait for a reply. ****************************************************************************/ -- cgit From 45a877f392a5449f4c3b7d39f9f8c78b57733d39 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Mar 2008 09:26:27 +0100 Subject: Revert "Add infrastructure to support async SMB requests" This reverts commit f5356825698a02df2d400b51dd95d1f857c83e81. (This used to be commit 5f53a62be8a21b8d92ac44b18d202882500356e8) --- source3/libsmb/async_smb.c | 483 --------------------------------------------- 1 file changed, 483 deletions(-) delete mode 100644 source3/libsmb/async_smb.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c deleted file mode 100644 index 21bcd5b9b1..0000000000 --- a/source3/libsmb/async_smb.c +++ /dev/null @@ -1,483 +0,0 @@ -/* - Unix SMB/CIFS implementation. - Infrastructure for async SMB client requests - Copyright (C) Volker Lendecke 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -/* - * Fetch an error out of a NBT packet - */ - -NTSTATUS cli_pull_error(char *buf) -{ - uint32_t flags2 = SVAL(buf, smb_flg2); - - if (flags2 & FLAGS2_32_BIT_ERROR_CODES) { - return NT_STATUS(IVAL(buf, smb_rcls)); - } - - return NT_STATUS_DOS(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); -} - -/* - * Compatibility helper for the sync APIs: Fake NTSTATUS in cli->inbuf - */ - -void cli_set_error(struct cli_state *cli, NTSTATUS status) -{ - uint32_t flags2 = SVAL(cli->inbuf, smb_flg2); - - if (NT_STATUS_IS_DOS(status)) { - SSVAL(cli->inbuf, smb_flg2, - flags2 & ~FLAGS2_32_BIT_ERROR_CODES); - SCVAL(cli->inbuf, smb_rcls, NT_STATUS_DOS_CLASS(status)); - SSVAL(cli->inbuf, smb_err, NT_STATUS_DOS_CODE(status)); - return; - } - - SSVAL(cli->inbuf, smb_flg2, flags2 | FLAGS2_32_BIT_ERROR_CODES); - SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); - return; -} - -/* - * Allocate a new mid - */ - -static uint16_t cli_new_mid(struct cli_state *cli) -{ - uint16_t result; - struct cli_request *req; - - while (true) { - result = cli->mid++; - if (result == 0) { - continue; - } - - for (req = cli->outstanding_requests; req; req = req->next) { - if (result == req->mid) { - break; - } - } - - if (req == NULL) { - return result; - } - } -} - -static char *cli_request_print(TALLOC_CTX *mem_ctx, struct async_req *req) -{ - char *result = async_req_print(mem_ctx, req); - struct cli_request *cli_req = cli_request_get(req); - - if (result == NULL) { - return NULL; - } - - return talloc_asprintf_append_buffer( - result, "mid=%d\n", cli_req->mid); -} - -static int cli_request_destructor(struct cli_request *req) -{ - if (req->enc_state != NULL) { - common_free_enc_buffer(req->enc_state, req->outbuf); - } - DLIST_REMOVE(req->cli->outstanding_requests, req); - return 0; -} - -/* - * Create a fresh async smb request - */ - -struct async_req *cli_request_new(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct cli_state *cli, - uint8_t num_words, size_t num_bytes, - struct cli_request **preq) -{ - struct async_req *result; - struct cli_request *cli_req; - size_t bufsize = smb_size + num_words * 2 + num_bytes; - - result = async_req_new(mem_ctx, ev); - if (result == NULL) { - return NULL; - } - - cli_req = (struct cli_request *)talloc_size( - result, sizeof(*cli_req) + bufsize); - if (cli_req == NULL) { - TALLOC_FREE(result); - return NULL; - } - talloc_set_name_const(cli_req, "struct cli_request"); - result->private_data = cli_req; - result->print = cli_request_print; - - cli_req->async = result; - cli_req->cli = cli; - cli_req->outbuf = ((char *)cli_req + sizeof(*cli_req)); - cli_req->sent = 0; - cli_req->mid = cli_new_mid(cli); - cli_req->inbuf = NULL; - cli_req->enc_state = NULL; - - SCVAL(cli_req->outbuf, smb_wct, num_words); - SSVAL(cli_req->outbuf, smb_vwv + num_words * 2, num_bytes); - - DLIST_ADD_END(cli->outstanding_requests, cli_req, - struct cli_request *); - talloc_set_destructor(cli_req, cli_request_destructor); - - DEBUG(10, ("cli_request_new: mid=%d\n", cli_req->mid)); - - *preq = cli_req; - return result; -} - -/* - * Convenience function to get the SMB part out of an async_req - */ - -struct cli_request *cli_request_get(struct async_req *req) -{ - if (req == NULL) { - return NULL; - } - return talloc_get_type_abort(req->private_data, struct cli_request); -} - -/* - * A PDU has arrived on cli->evt_inbuf - */ - -static void handle_incoming_pdu(struct cli_state *cli) -{ - struct cli_request *req; - uint16_t mid; - size_t raw_pdu_len, buf_len, pdu_len; - size_t rest_len; - NTSTATUS status; - - /* - * The encrypted PDU len might differ from the unencrypted one - */ - raw_pdu_len = smb_len(cli->evt_inbuf) + 4; - - /* - * TODO: Handle oplock break requests - */ - - if (cli_encryption_on(cli) && CVAL(cli->evt_inbuf, 0) == 0) { - uint16_t enc_ctx_num; - - status = get_enc_ctx_num((uint8_t *)cli->evt_inbuf, - &enc_ctx_num); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("get_enc_ctx_num returned %s\n", - nt_errstr(status))); - goto invalidate_requests; - } - - if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { - DEBUG(10, ("wrong enc_ctx %d, expected %d\n", - enc_ctx_num, - cli->trans_enc_state->enc_ctx_num)); - status = NT_STATUS_INVALID_HANDLE; - goto invalidate_requests; - } - - status = common_decrypt_buffer(cli->trans_enc_state, - cli->evt_inbuf); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("common_decrypt_buffer returned %s\n", - nt_errstr(status))); - goto invalidate_requests; - } - } - - if (!cli_check_sign_mac(cli, cli->evt_inbuf)) { - DEBUG(10, ("cli_check_sign_mac failed\n")); - status = NT_STATUS_ACCESS_DENIED; - goto invalidate_requests; - } - - mid = SVAL(cli->evt_inbuf, smb_mid); - - DEBUG(10, ("handle_incoming_pdu: got mid %d\n", mid)); - - for (req = cli->outstanding_requests; req; req = req->next) { - if (req->mid == mid) { - break; - } - } - - buf_len = talloc_get_size(cli->evt_inbuf); - pdu_len = smb_len(cli->evt_inbuf) + 4; - rest_len = buf_len - raw_pdu_len; - - if (req == NULL) { - DEBUG(3, ("Request for mid %d not found, dumping PDU\n", mid)); - - memmove(cli->evt_inbuf, cli->evt_inbuf + raw_pdu_len, - buf_len - raw_pdu_len); - - cli->evt_inbuf = TALLOC_REALLOC_ARRAY(NULL, cli->evt_inbuf, - char, rest_len); - return; - } - - if (buf_len == pdu_len) { - /* - * Optimal case: Exactly one PDU was in the socket buffer - */ - req->inbuf = talloc_move(req, &cli->evt_inbuf); - goto done; - } - - DEBUG(11, ("buf_len = %d, pdu_len = %d, splitting buffer\n", - (int)buf_len, (int)pdu_len)); - - if (pdu_len < rest_len) { - /* - * The PDU is shorter, talloc_memdup that one. - */ - req->inbuf = (char *)talloc_memdup( - req, cli->evt_inbuf, pdu_len); - - memmove(cli->evt_inbuf, - cli->evt_inbuf + raw_pdu_len, - buf_len - raw_pdu_len); - - cli->evt_inbuf = TALLOC_REALLOC_ARRAY( - NULL, cli->evt_inbuf, char, rest_len); - } - else { - /* - * The PDU is larger than the rest, - * talloc_memdup the rest - */ - req->inbuf = talloc_move(req, &cli->evt_inbuf); - - cli->evt_inbuf = (char *)talloc_memdup( - cli, req->inbuf + raw_pdu_len, - rest_len); - } - - if ((req->inbuf == NULL) || (cli->evt_inbuf == NULL)) { - status = NT_STATUS_NO_MEMORY; - goto invalidate_requests; - } - - done: - async_req_done(req->async); - return; - - invalidate_requests: - - DEBUG(10, ("handle_incoming_pdu: Aborting with %s\n", - nt_errstr(status))); - - for (req = cli->outstanding_requests; req; req = req->next) { - async_req_error(req->async, status); - } - return; -} - -/* - * fd event callback. This is the basic connection to the socket - */ - -static void cli_state_handler(struct event_context *event_ctx, - struct fd_event *event, uint16 flags, void *p) -{ - struct cli_state *cli = (struct cli_state *)p; - struct cli_request *req; - - DEBUG(11, ("cli_state_handler called with flags %d\n", flags)); - - if (flags & EVENT_FD_READ) { - int res, available; - size_t old_size, new_size; - char *tmp; - - res = ioctl(cli->fd, FIONREAD, &available); - if (res == -1) { - DEBUG(10, ("ioctl(FIONREAD) failed: %s\n", - strerror(errno))); - goto sock_error; - } - - if (available == 0) { - /* EOF */ - goto sock_error; - } - - old_size = talloc_get_size(cli->evt_inbuf); - new_size = old_size + available; - - if (new_size < old_size) { - /* wrap */ - goto sock_error; - } - - tmp = TALLOC_REALLOC_ARRAY(cli, cli->evt_inbuf, char, - new_size); - if (tmp == NULL) { - /* nomem */ - goto sock_error; - } - cli->evt_inbuf = tmp; - - res = recv(cli->fd, cli->evt_inbuf + old_size, available, 0); - if (res == -1) { - DEBUG(10, ("recv failed: %s\n", strerror(errno))); - goto sock_error; - } - - DEBUG(11, ("cli_state_handler: received %d bytes, " - "smb_len(evt_inbuf) = %d\n", (int)res, - smb_len(cli->evt_inbuf))); - - /* recv *might* have returned less than announced */ - new_size = old_size + res; - - /* shrink, so I don't expect errors here */ - cli->evt_inbuf = TALLOC_REALLOC_ARRAY(cli, cli->evt_inbuf, - char, new_size); - - while ((cli->evt_inbuf != NULL) - && ((smb_len(cli->evt_inbuf) + 4) <= new_size)) { - /* - * we've got a complete NBT level PDU in evt_inbuf - */ - handle_incoming_pdu(cli); - new_size = talloc_get_size(cli->evt_inbuf); - } - } - - if (flags & EVENT_FD_WRITE) { - size_t to_send; - ssize_t sent; - - for (req = cli->outstanding_requests; req; req = req->next) { - to_send = smb_len(req->outbuf)+4; - if (to_send > req->sent) { - break; - } - } - - if (req == NULL) { - event_fd_set_not_writeable(event); - return; - } - - sent = send(cli->fd, req->outbuf + req->sent, - to_send - req->sent, 0); - - if (sent < 0) { - goto sock_error; - } - - req->sent += sent; - - if (req->sent == to_send) { - return; - } - } - return; - - sock_error: - for (req = cli->outstanding_requests; req; req = req->next) { - req->async->state = ASYNC_REQ_ERROR; - req->async->status = map_nt_error_from_unix(errno); - } - TALLOC_FREE(cli->fd_event); - close(cli->fd); - cli->fd = -1; -} - -/* - * Holder for a talloc_destructor, we need to zero out the pointers in cli - * when deleting - */ -struct cli_tmp_event { - struct cli_state *cli; -}; - -static int cli_tmp_event_destructor(struct cli_tmp_event *e) -{ - TALLOC_FREE(e->cli->fd_event); - TALLOC_FREE(e->cli->event_ctx); - return 0; -} - -/* - * Create a temporary event context for use in the sync helper functions - */ - -struct cli_tmp_event *cli_tmp_event_ctx(TALLOC_CTX *mem_ctx, - struct cli_state *cli) -{ - struct cli_tmp_event *state; - - if (cli->event_ctx != NULL) { - return NULL; - } - - state = talloc(mem_ctx, struct cli_tmp_event); - if (state == NULL) { - return NULL; - } - state->cli = cli; - talloc_set_destructor(state, cli_tmp_event_destructor); - - cli->event_ctx = event_context_init(state); - if (cli->event_ctx == NULL) { - TALLOC_FREE(state); - return NULL; - } - - cli->fd_event = event_add_fd(cli->event_ctx, state, cli->fd, - EVENT_FD_READ, cli_state_handler, cli); - if (cli->fd_event == NULL) { - TALLOC_FREE(state); - return NULL; - } - return state; -} - -/* - * Attach an event context permanently to a cli_struct - */ - -NTSTATUS cli_add_event_ctx(struct cli_state *cli, - struct event_context *event_ctx) -{ - cli->event_ctx = event_ctx; - cli->fd_event = event_add_fd(event_ctx, cli, cli->fd, EVENT_FD_READ, - cli_state_handler, cli); - if (cli->fd_event == NULL) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} -- cgit From 257b7b09298f7cb983b2f31b87fc5e46e0f62f0c Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 28 Feb 2008 11:23:20 -0500 Subject: Initial revamp of the libsmbclient interface. The libsmbclient interface has suffered from difficulty of improvement and feature enrichment without causing ABI breakage. Although there were a number of issues, the primary ones were: (a) the user of the library would manually manipulate the context structure members, meaning that nothing in the context structure could change other than adding stuff at the end; (b) there were three methods of setting options: setting bits in a flags field within the context structure, setting explicit options variables within an options structure in the context structure, and by calling the smbc_option_set() function; (c) the authentication callback did not traditionally provide enough information to the callee which required adding an option for a callback with a different signature, and now there are requests for even more information at the callback, requiring yet a third signature and option to set it (if we implement that feature). This commit provides a reorganization of the code which fixes (a) and (b). The context structure is now entirely opaque, and there are setter and getter functions for manipulating it. This makes maintaining ABI consistency much, much easier. Additionally, the options setting/getting has been unified into a single mechanism using smbc_option_set() and smbc_option_get(). Yet to be completed is a refactoring of the authentication callback (c). The test programs in examples/libsmbclient have been modified (if necessary; some applications require no changes at all) for the new API and a few have been minimally tested. Derrell (This used to be commit d4b4bae8ded824d06ad5ab0e219f71187ee5c771) --- source3/libsmb/libsmb_cache.c | 74 +- source3/libsmb/libsmb_compat.c | 329 +- source3/libsmb/libsmb_context.c | 1283 +++++++ source3/libsmb/libsmb_dir.c | 1928 ++++++++++ source3/libsmb/libsmb_file.c | 859 +++++ source3/libsmb/libsmb_misc.c | 73 + source3/libsmb/libsmb_path.c | 399 +++ source3/libsmb/libsmb_printjob.c | 334 ++ source3/libsmb/libsmb_server.c | 675 ++++ source3/libsmb/libsmb_stat.c | 302 ++ source3/libsmb/libsmb_xattr.c | 2293 ++++++++++++ source3/libsmb/libsmbclient.c | 7233 -------------------------------------- 12 files changed, 8385 insertions(+), 7397 deletions(-) create mode 100644 source3/libsmb/libsmb_context.c create mode 100644 source3/libsmb/libsmb_dir.c create mode 100644 source3/libsmb/libsmb_file.c create mode 100644 source3/libsmb/libsmb_misc.c create mode 100644 source3/libsmb/libsmb_path.c create mode 100644 source3/libsmb/libsmb_printjob.c create mode 100644 source3/libsmb/libsmb_server.c create mode 100644 source3/libsmb/libsmb_stat.c create mode 100644 source3/libsmb/libsmb_xattr.c delete mode 100644 source3/libsmb/libsmbclient.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index b98df024fa..e0571fa9fe 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -22,11 +22,8 @@ */ #include "includes.h" - -#include "include/libsmbclient.h" -#include "../include/libsmb_internal.h" - -int smbc_default_cache_functions(SMBCCTX * context); +#include "libsmbclient.h" +#include "libsmb_internal.h" /* * Structure we use if internal caching mechanism is used @@ -48,9 +45,13 @@ struct smbc_server_cache { * Add a new connection to the server cache. * This function is only used if the external cache is not enabled */ -static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv, - const char * server, const char * share, - const char * workgroup, const char * username) +int +SMBC_add_cached_server(SMBCCTX * context, + SMBCSRV * newsrv, + const char * server, + const char * share, + const char * workgroup, + const char * username) { struct smbc_server_cache * srvcache = NULL; @@ -88,7 +89,7 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv, goto failed; } - DLIST_ADD((context->server_cache), srvcache); + DLIST_ADD((context->cache.server_cache_data), srvcache); return 0; failed: @@ -108,13 +109,17 @@ static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv, * returns server handle on success, NULL on error (not found) * This function is only used if the external cache is not enabled */ -static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, - const char * share, const char * workgroup, const char * user) +SMBCSRV * +SMBC_get_cached_server(SMBCCTX * context, + const char * server, + const char * share, + const char * workgroup, + const char * user) { struct smbc_server_cache * srv = NULL; /* Search the cache lines */ - for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { + for (srv = context->cache.server_cache_data; srv; srv = srv->next) { if (strcmp(server,srv->server_name) == 0 && strcmp(workgroup,srv->workgroup) == 0 && @@ -146,7 +151,7 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, * a connection to the server (other than the * attribute server connection) is cool. */ - if (context->options.one_share_per_server) { + if (context->one_share_per_server) { /* * The currently connected share name * doesn't match the requested share, so @@ -156,7 +161,7 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, /* Sigh. Couldn't disconnect. */ cli_shutdown(srv->server->cli); srv->server->cli = NULL; - context->callbacks.remove_cached_srv_fn(context, srv->server); + context->cache.remove_cached_server_fn(context, srv->server); continue; } @@ -171,7 +176,7 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, /* Out of memory. */ cli_shutdown(srv->server->cli); srv->server->cli = NULL; - context->callbacks.remove_cached_srv_fn(context, srv->server); + context->cache.remove_cached_server_fn(context, srv->server); continue; } @@ -190,15 +195,17 @@ static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server, * returns 0 on success * This function is only used if the external cache is not enabled */ -static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) +int +SMBC_remove_cached_server(SMBCCTX * context, + SMBCSRV * server) { struct smbc_server_cache * srv = NULL; - for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) { + for (srv = context->cache.server_cache_data; srv; srv = srv->next) { if (server == srv->server) { /* remove this sucker */ - DLIST_REMOVE(context->server_cache, srv); + DLIST_REMOVE(context->cache.server_cache_data, srv); SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv->workgroup); @@ -216,40 +223,23 @@ static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server) * Try to remove all the servers in cache * returns 1 on failure and 0 if all servers could be removed. */ -static int smbc_purge_cached(SMBCCTX * context) +int +SMBC_purge_cached_servers(SMBCCTX * context) { struct smbc_server_cache * srv; struct smbc_server_cache * next; int could_not_purge_all = 0; - for (srv = ((struct smbc_server_cache *) context->server_cache), - next = (srv ? srv->next :NULL); + for (srv = context->cache.server_cache_data, + next = (srv ? srv->next :NULL); srv; - srv = next, next = (srv ? srv->next : NULL)) { + srv = next, + next = (srv ? srv->next : NULL)) { - if (smbc_remove_unused_server(context, srv->server)) { + if (SMBC_remove_unused_server(context, srv->server)) { /* could not be removed */ could_not_purge_all = 1; } } return could_not_purge_all; } - - - -/* - * This functions initializes all server-cache related functions - * to the default (internal) system. - * - * We use this to make the rest of the cache system static. - */ - -int smbc_default_cache_functions(SMBCCTX * context) -{ - context->callbacks.add_cached_srv_fn = smbc_add_cached_server; - context->callbacks.get_cached_srv_fn = smbc_get_cached_server; - context->callbacks.remove_cached_srv_fn = smbc_remove_cached_server; - context->callbacks.purge_cached_fn = smbc_purge_cached; - - return 0; -} diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 6042464fd2..7a0536a92d 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -5,7 +5,7 @@ Copyright (C) Richard Sharpe 2000 Copyright (C) John Terpstra 2000 Copyright (C) Tom Jansen (Ninja ISD) 2002 - Copyright (C) Derrell Lipman 2003 + Copyright (C) Derrell Lipman 2003, 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -23,8 +23,7 @@ #include "includes.h" - -#include "include/libsmb_internal.h" +#include "libsmb_internal.h" struct smbc_compat_fdlist { SMBCFILE * file; @@ -39,7 +38,8 @@ static struct smbc_compat_fdlist * smbc_compat_fd_in_use = NULL; static struct smbc_compat_fdlist * smbc_compat_fd_avail = NULL; /* Find an fd and return the SMBCFILE * or NULL on failure */ -static SMBCFILE * find_fd(int fd) +static SMBCFILE * +find_fd(int fd) { struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; while (f) { @@ -51,7 +51,8 @@ static SMBCFILE * find_fd(int fd) } /* Add an fd, returns 0 on success, -1 on error with errno set */ -static int add_fd(SMBCFILE * file) +static int +add_fd(SMBCFILE * file) { struct smbc_compat_fdlist * f = smbc_compat_fd_avail; @@ -90,7 +91,8 @@ static int add_fd(SMBCFILE * file) /* Delete an fd, returns 0 on success */ -static int del_fd(int fd) +static int +del_fd(int fd) { struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; @@ -112,15 +114,17 @@ static int del_fd(int fd) -int smbc_init(smbc_get_auth_data_fn fn, int debug) +int +smbc_init(smbc_get_auth_data_fn fn, + int debug) { if (!smbc_compat_initialized) { statcont = smbc_new_context(); if (!statcont) return -1; - statcont->debug = debug; - statcont->callbacks.auth_fn = fn; + smbc_setDebug(statcont, debug); + smbc_setFunctionAuthData(statcont, fn); if (!smbc_init_context(statcont)) { smbc_free_context(statcont, False); @@ -135,7 +139,8 @@ int smbc_init(smbc_get_auth_data_fn fn, int debug) } -SMBCCTX *smbc_set_context(SMBCCTX * context) +SMBCCTX * +smbc_set_context(SMBCCTX * context) { SMBCCTX *old_context = statcont; @@ -151,307 +156,387 @@ SMBCCTX *smbc_set_context(SMBCCTX * context) } -int smbc_open(const char *furl, int flags, mode_t mode) +int +smbc_open(const char *furl, + int flags, + mode_t mode) { SMBCFILE * file; int fd; - file = (statcont->open)(statcont, furl, flags, mode); + file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode); if (!file) return -1; fd = add_fd(file); if (fd == -1) - (statcont->close_fn)(statcont, file); + smbc_getFunctionClose(statcont)(statcont, file); return fd; } -int smbc_creat(const char *furl, mode_t mode) +int +smbc_creat(const char *furl, + mode_t mode) { SMBCFILE * file; int fd; - file = (statcont->creat)(statcont, furl, mode); + file = smbc_getFunctionCreat(statcont)(statcont, furl, mode); if (!file) return -1; fd = add_fd(file); if (fd == -1) { /* Hmm... should we delete the file too ? I guess we could try */ - (statcont->close_fn)(statcont, file); - (statcont->unlink)(statcont, furl); + smbc_getFunctionClose(statcont)(statcont, file); + smbc_getFunctionUnlink(statcont)(statcont, furl); } return fd; } -ssize_t smbc_read(int fd, void *buf, size_t bufsize) +ssize_t +smbc_read(int fd, + void *buf, + size_t bufsize) { SMBCFILE * file = find_fd(fd); - return (statcont->read)(statcont, file, buf, bufsize); + return smbc_getFunctionRead(statcont)(statcont, file, buf, bufsize); } -ssize_t smbc_write(int fd, void *buf, size_t bufsize) +ssize_t +smbc_write(int fd, + void *buf, + size_t bufsize) { SMBCFILE * file = find_fd(fd); - return (statcont->write)(statcont, file, buf, bufsize); + return smbc_getFunctionWrite(statcont)(statcont, file, buf, bufsize); } -off_t smbc_lseek(int fd, off_t offset, int whence) +off_t +smbc_lseek(int fd, + off_t offset, + int whence) { SMBCFILE * file = find_fd(fd); - return (statcont->lseek)(statcont, file, offset, whence); + return smbc_getFunctionLseek(statcont)(statcont, file, offset, whence); } -int smbc_close(int fd) +int +smbc_close(int fd) { SMBCFILE * file = find_fd(fd); del_fd(fd); - return (statcont->close_fn)(statcont, file); + return smbc_getFunctionClose(statcont)(statcont, file); } -int smbc_unlink(const char *fname) +int +smbc_unlink(const char *fname) { - return (statcont->unlink)(statcont, fname); + return smbc_getFunctionUnlink(statcont)(statcont, fname); } -int smbc_rename(const char *ourl, const char *nurl) +int +smbc_rename(const char *ourl, + const char *nurl) { - return (statcont->rename)(statcont, ourl, statcont, nurl); + return smbc_getFunctionRename(statcont)(statcont, ourl, + statcont, nurl); } -int smbc_opendir(const char *durl) +int +smbc_opendir(const char *durl) { SMBCFILE * file; int fd; - file = (statcont->opendir)(statcont, durl); + file = smbc_getFunctionOpendir(statcont)(statcont, durl); if (!file) return -1; fd = add_fd(file); if (fd == -1) - (statcont->closedir)(statcont, file); + smbc_getFunctionClosedir(statcont)(statcont, file); return fd; } -int smbc_closedir(int dh) +int +smbc_closedir(int dh) { SMBCFILE * file = find_fd(dh); del_fd(dh); - return (statcont->closedir)(statcont, file); + return smbc_getFunctionClosedir(statcont)(statcont, file); } -int smbc_getdents(unsigned int dh, struct smbc_dirent *dirp, int count) +int +smbc_getdents(unsigned int dh, + struct smbc_dirent *dirp, + int count) { SMBCFILE * file = find_fd(dh); - return (statcont->getdents)(statcont, file,dirp, count); + return smbc_getFunctionGetdents(statcont)(statcont, file, dirp, count); } -struct smbc_dirent* smbc_readdir(unsigned int dh) +struct smbc_dirent * +smbc_readdir(unsigned int dh) { SMBCFILE * file = find_fd(dh); - return (statcont->readdir)(statcont, file); + return smbc_getFunctionReaddir(statcont)(statcont, file); } -off_t smbc_telldir(int dh) +off_t +smbc_telldir(int dh) { SMBCFILE * file = find_fd(dh); - return (statcont->telldir)(statcont, file); + return smbc_getFunctionTelldir(statcont)(statcont, file); } -int smbc_lseekdir(int fd, off_t offset) +int +smbc_lseekdir(int fd, + off_t offset) { SMBCFILE * file = find_fd(fd); - return (statcont->lseekdir)(statcont, file, offset); + return smbc_getFunctionLseekdir(statcont)(statcont, file, offset); } -int smbc_mkdir(const char *durl, mode_t mode) +int +smbc_mkdir(const char *durl, + mode_t mode) { - return (statcont->mkdir)(statcont, durl, mode); + return smbc_getFunctionMkdir(statcont)(statcont, durl, mode); } -int smbc_rmdir(const char *durl) +int +smbc_rmdir(const char *durl) { - return (statcont->rmdir)(statcont, durl); + return smbc_getFunctionRmdir(statcont)(statcont, durl); } -int smbc_stat(const char *url, struct stat *st) +int +smbc_stat(const char *url, + struct stat *st) { - return (statcont->stat)(statcont, url, st); + return smbc_getFunctionStat(statcont)(statcont, url, st); } -int smbc_fstat(int fd, struct stat *st) +int +smbc_fstat(int fd, + struct stat *st) { SMBCFILE * file = find_fd(fd); - return (statcont->fstat)(statcont, file, st); + return smbc_getFunctionFstat(statcont)(statcont, file, st); } -int smbc_ftruncate(int fd, off_t size) +int +smbc_ftruncate(int fd, + off_t size) { SMBCFILE * file = find_fd(fd); - return (statcont->ftruncate)(statcont, file, size); + return smbc_getFunctionFtruncate(statcont)(statcont, file, size); } -int smbc_chmod(const char *url, mode_t mode) +int +smbc_chmod(const char *url, + mode_t mode) { - return (statcont->chmod)(statcont, url, mode); + return smbc_getFunctionChmod(statcont)(statcont, url, mode); } -int smbc_utimes(const char *fname, struct timeval *tbuf) +int +smbc_utimes(const char *fname, + struct timeval *tbuf) { - return (statcont->utimes)(statcont, fname, tbuf); + return smbc_getFunctionUtimes(statcont)(statcont, fname, tbuf); } #ifdef HAVE_UTIME_H -int smbc_utime(const char *fname, struct utimbuf *utbuf) +int +smbc_utime(const char *fname, + struct utimbuf *utbuf) { struct timeval tv[2]; if (utbuf == NULL) - return (statcont->utimes)(statcont, fname, NULL); + return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL); tv[0].tv_sec = utbuf->actime; tv[1].tv_sec = utbuf->modtime; tv[0].tv_usec = tv[1].tv_usec = 0; - return (statcont->utimes)(statcont, fname, tv); + return smbc_getFunctionUtimes(statcont)(statcont, fname, tv); } #endif -int smbc_setxattr(const char *fname, - const char *name, - const void *value, - size_t size, - int flags) +int +smbc_setxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) { - return (statcont->setxattr)(statcont, fname, name, value, size, flags); + return smbc_getFunctionSetxattr(statcont)(statcont, + fname, name, + value, size, flags); } -int smbc_lsetxattr(const char *fname, - const char *name, - const void *value, - size_t size, - int flags) +int +smbc_lsetxattr(const char *fname, + const char *name, + const void *value, + size_t size, + int flags) { - return (statcont->setxattr)(statcont, fname, name, value, size, flags); + return smbc_getFunctionSetxattr(statcont)(statcont, + fname, name, + value, size, flags); } -int smbc_fsetxattr(int fd, - const char *name, - const void *value, - size_t size, - int flags) +int +smbc_fsetxattr(int fd, + const char *name, + const void *value, + size_t size, + int flags) { SMBCFILE * file = find_fd(fd); if (file == NULL) { errno = EBADF; return -1; } - return (statcont->setxattr)(statcont, file->fname, - name, value, size, flags); + return smbc_getFunctionSetxattr(statcont)(statcont, + file->fname, name, + value, size, flags); } -int smbc_getxattr(const char *fname, - const char *name, - const void *value, - size_t size) +int +smbc_getxattr(const char *fname, + const char *name, + const void *value, + size_t size) { - return (statcont->getxattr)(statcont, fname, name, value, size); + return smbc_getFunctionGetxattr(statcont)(statcont, + fname, name, + value, size); } -int smbc_lgetxattr(const char *fname, - const char *name, - const void *value, - size_t size) +int +smbc_lgetxattr(const char *fname, + const char *name, + const void *value, + size_t size) { - return (statcont->getxattr)(statcont, fname, name, value, size); + return smbc_getFunctionGetxattr(statcont)(statcont, + fname, name, + value, size); } -int smbc_fgetxattr(int fd, - const char *name, - const void *value, - size_t size) +int +smbc_fgetxattr(int fd, + const char *name, + const void *value, + size_t size) { SMBCFILE * file = find_fd(fd); if (file == NULL) { errno = EBADF; return -1; } - return (statcont->getxattr)(statcont, file->fname, name, value, size); + return smbc_getFunctionGetxattr(statcont)(statcont, + file->fname, name, + value, size); } -int smbc_removexattr(const char *fname, - const char *name) +int +smbc_removexattr(const char *fname, + const char *name) { - return (statcont->removexattr)(statcont, fname, name); + return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name); } -int smbc_lremovexattr(const char *fname, - const char *name) +int +smbc_lremovexattr(const char *fname, + const char *name) { - return (statcont->removexattr)(statcont, fname, name); + return smbc_getFunctionRemovexattr(statcont)(statcont, fname, name); } -int smbc_fremovexattr(int fd, - const char *name) +int +smbc_fremovexattr(int fd, + const char *name) { SMBCFILE * file = find_fd(fd); if (file == NULL) { errno = EBADF; return -1; } - return (statcont->removexattr)(statcont, file->fname, name); + return smbc_getFunctionRemovexattr(statcont)(statcont, + file->fname, name); } -int smbc_listxattr(const char *fname, - char *list, - size_t size) +int +smbc_listxattr(const char *fname, + char *list, + size_t size) { - return (statcont->listxattr)(statcont, fname, list, size); + return smbc_getFunctionListxattr(statcont)(statcont, + fname, list, size); } -int smbc_llistxattr(const char *fname, - char *list, - size_t size) +int +smbc_llistxattr(const char *fname, + char *list, + size_t size) { - return (statcont->listxattr)(statcont, fname, list, size); + return smbc_getFunctionListxattr(statcont)(statcont, + fname, list, size); } -int smbc_flistxattr(int fd, - char *list, - size_t size) +int +smbc_flistxattr(int fd, + char *list, + size_t size) { SMBCFILE * file = find_fd(fd); if (file == NULL) { errno = EBADF; return -1; } - return (statcont->listxattr)(statcont, file->fname, list, size); + return smbc_getFunctionListxattr(statcont)(statcont, + file->fname, list, size); } -int smbc_print_file(const char *fname, const char *printq) +int +smbc_print_file(const char *fname, + const char *printq) { - return (statcont->print_file)(statcont, fname, statcont, printq); + return smbc_getFunctionPrintFile(statcont)(statcont, fname, + statcont, printq); } -int smbc_open_print_job(const char *fname) +int +smbc_open_print_job(const char *fname) { - SMBCFILE * file = (statcont->open_print_job)(statcont, fname); + SMBCFILE * file; + + file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname); if (!file) return -1; return file->cli_fd; } -int smbc_list_print_jobs(const char *purl, smbc_list_print_job_fn fn) +int +smbc_list_print_jobs(const char *purl, + smbc_list_print_job_fn fn) { - return (statcont->list_print_jobs)(statcont, purl, fn); + return smbc_getFunctionListPrintJobs(statcont)(statcont, purl, fn); } -int smbc_unlink_print_job(const char *purl, int id) +int +smbc_unlink_print_job(const char *purl, + int id) { - return (statcont->unlink_print_job)(statcont, purl, id); + return smbc_getFunctionUnlinkPrintJob(statcont)(statcont, purl, id); } diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c new file mode 100644 index 0000000000..1505d50a43 --- /dev/null +++ b/source3/libsmb/libsmb_context.c @@ -0,0 +1,1283 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Is the logging working / configfile read ? + */ +static int SMBC_initialized = 0; + + + +/* + * Get a new empty handle to fill in with your own info + */ +SMBCCTX * +smbc_new_context(void) +{ + SMBCCTX *context; + + context = SMB_MALLOC_P(SMBCCTX); + if (!context) { + errno = ENOMEM; + return NULL; + } + + + /* Initialize the context and establish reasonable defaults */ + ZERO_STRUCTP(context); + + context->debug = 0; + context->timeout = 20000; /* 20 seconds */ + + context->full_time_names = False; + context->share_mode = SMBC_SHAREMODE_DENY_NONE; + context->smb_encryption_level = 0; + context->browse_max_lmb_count = 3; /* # LMBs to query */ + context->urlencode_readdir_entries = False; + context->one_share_per_server = False; + context->use_kerberos = False; + context->fallback_after_kerberos = False; + context->no_auto_anonymous_login = False; + + context->server.get_auth_data_fn = SMBC_get_auth_data; + context->server.check_server_fn = SMBC_check_server; + context->server.remove_unused_server_fn = SMBC_remove_unused_server; + + context->cache.server_cache_data = NULL; + context->cache.add_cached_server_fn = SMBC_add_cached_server; + context->cache.get_cached_server_fn = SMBC_get_cached_server; + context->cache.remove_cached_server_fn = SMBC_remove_cached_server; + context->cache.purge_cached_server_fn = SMBC_purge_cached_servers; + + context->posix_emu.open_fn = SMBC_open_ctx; + context->posix_emu.creat_fn = SMBC_creat_ctx; + context->posix_emu.read_fn = SMBC_read_ctx; + context->posix_emu.write_fn = SMBC_write_ctx; + context->posix_emu.close_fn = SMBC_close_ctx; + context->posix_emu.unlink_fn = SMBC_unlink_ctx; + context->posix_emu.rename_fn = SMBC_rename_ctx; + context->posix_emu.lseek_fn = SMBC_lseek_ctx; + context->posix_emu.ftruncate_fn = SMBC_ftruncate_ctx; + context->posix_emu.stat_fn = SMBC_stat_ctx; + context->posix_emu.fstat_fn = SMBC_fstat_ctx; + context->posix_emu.opendir_fn = SMBC_opendir_ctx; + context->posix_emu.closedir_fn = SMBC_closedir_ctx; + context->posix_emu.readdir_fn = SMBC_readdir_ctx; + context->posix_emu.getdents_fn = SMBC_getdents_ctx; + context->posix_emu.mkdir_fn = SMBC_mkdir_ctx; + context->posix_emu.rmdir_fn = SMBC_rmdir_ctx; + context->posix_emu.telldir_fn = SMBC_telldir_ctx; + context->posix_emu.lseekdir_fn = SMBC_lseekdir_ctx; + context->posix_emu.fstatdir_fn = SMBC_fstatdir_ctx; + context->posix_emu.chmod_fn = SMBC_chmod_ctx; + context->posix_emu.utimes_fn = SMBC_utimes_ctx; + context->posix_emu.setxattr_fn = SMBC_setxattr_ctx; + context->posix_emu.getxattr_fn = SMBC_getxattr_ctx; + context->posix_emu.removexattr_fn = SMBC_removexattr_ctx; + context->posix_emu.listxattr_fn = SMBC_listxattr_ctx; + + context->printing.open_print_job_fn = SMBC_open_print_job_ctx; + context->printing.print_file_fn = SMBC_print_file_ctx; + context->printing.list_print_jobs_fn = SMBC_list_print_jobs_ctx; + context->printing.unlink_print_job_fn = SMBC_unlink_print_job_ctx; + + return context; +} + +/* + * Free a context + * + * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed + * and thus you'll be leaking memory if not handled properly. + * + */ +int +smbc_free_context(SMBCCTX *context, + int shutdown_ctx) +{ + if (!context) { + errno = EBADF; + return 1; + } + + if (shutdown_ctx) { + SMBCFILE * f; + DEBUG(1,("Performing aggressive shutdown.\n")); + + f = context->files; + while (f) { + (context->posix_emu.close_fn)(context, f); + f = f->next; + } + context->files = NULL; + + /* First try to remove the servers the nice way. */ + if (context->cache.purge_cached_server_fn(context)) { + SMBCSRV * s; + SMBCSRV * next; + DEBUG(1, ("Could not purge all servers, " + "Nice way shutdown failed.\n")); + s = context->servers; + while (s) { + DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", + s, s->cli->fd)); + cli_shutdown(s->cli); + (context->cache.remove_cached_server_fn)(context, + s); + next = s->next; + DLIST_REMOVE(context->servers, s); + SAFE_FREE(s); + s = next; + } + context->servers = NULL; + } + } + else { + /* This is the polite way */ + if ((context->cache.purge_cached_server_fn)(context)) { + DEBUG(1, ("Could not purge all servers, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->servers) { + DEBUG(1, ("Active servers in context, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->files) { + DEBUG(1, ("Active files in context, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } + } + + /* Things we have to clean up */ + SAFE_FREE(context->workgroup); + SAFE_FREE(context->netbios_name); + SAFE_FREE(context->user); + + DEBUG(3, ("Context %p successfully freed\n", context)); + SAFE_FREE(context); + return 0; +} + + +/* + * Each time the context structure is changed, we have binary backward + * compatibility issues. Instead of modifying the public portions of the + * context structure to add new options, instead, we put them in the internal + * portion of the context structure and provide a set function for these new + * options. + */ +void +smbc_option_set(SMBCCTX *context, + char *option_name, + ... /* option_value */) +{ + va_list ap; + union { + int i; + bool b; + smbc_get_auth_data_with_context_fn auth_fn; + void *v; + const char *s; + } option_value; + + va_start(ap, option_name); + + if (strcmp(option_name, "debug_to_stderr") == 0) { + /* + * Log to standard error instead of standard output. + */ + option_value.b = (bool) va_arg(ap, int); + context->debug_stderr = option_value.b; + + } else if (strcmp(option_name, "full_time_names") == 0) { + /* + * Use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also + * setting/getting CREATE_TIME which was previously + * unimplemented. (Note that the old C_TIME was supposed to + * be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ + option_value.b = (bool) va_arg(ap, int); + context->full_time_names = option_value.b; + + } else if (strcmp(option_name, "open_share_mode") == 0) { + /* + * The share mode to use for files opened with + * SMBC_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE. + */ + option_value.i = va_arg(ap, int); + context->share_mode = (smbc_share_mode) option_value.i; + + } else if (strcmp(option_name, "user_data") == 0) { + /* + * Save a user data handle which may be retrieved by the user + * with smbc_option_get() + */ + option_value.v = va_arg(ap, void *); + context->user_data = option_value.v; + } else if (strcmp(option_name, "smb_encrypt_level") == 0) { + /* + * Save an encoded value for encryption level. + * 0 = off, 1 = attempt, 2 = required. + */ + option_value.s = va_arg(ap, const char *); + if (strcmp(option_value.s, "none") == 0) { + context->smb_encryption_level = 0; + } else if (strcmp(option_value.s, "request") == 0) { + context->smb_encryption_level = 1; + } else if (strcmp(option_value.s, "require") == 0) { + context->smb_encryption_level = 2; + } + } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { + /* + * From how many local master browsers should the list of + * workgroups be retrieved? It can take up to 12 minutes or + * longer after a server becomes a local master browser, for + * it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client + * never knows which local master browser will be found first, + * the one which is found first and used to retrieve a browse + * list may have an incomplete or empty browse list. By + * requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small + * networks (few workgroups), it is recommended that this + * value be set to 0, causing the browse lists from all found + * local master browsers to be retrieved and merged. For + * networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ + option_value.i = va_arg(ap, int); + context->browse_max_lmb_count = option_value.i; + + } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { + /* + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ + option_value.b = (bool) va_arg(ap, int); + context->urlencode_readdir_entries = option_value.b; + + } else if (strcmp(option_name, "one_share_per_server") == 0) { + /* + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ + option_value.b = (bool) va_arg(ap, int); + context->one_share_per_server = option_value.b; + + } else if (strcmp(option_name, "use_kerberos") == 0) { + option_value.b = (bool) va_arg(ap, int); + context->use_kerberos = option_value.b; + + } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { + option_value.b = (bool) va_arg(ap, int); + context->fallback_after_kerberos = option_value.b; + + } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { + option_value.b = (bool) va_arg(ap, int); + context->no_auto_anonymous_login = option_value.b; + } + + va_end(ap); +} + + +/* + * Retrieve the current value of an option + */ +void * +smbc_option_get(SMBCCTX *context, + char *option_name) +{ + if (strcmp(option_name, "debug_stderr") == 0) { + /* + * Log to standard error instead of standard output. + */ +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->debug_stderr; +#else + return (void *) context->debug_stderr; +#endif + + } else if (strcmp(option_name, "full_time_names") == 0) { + /* + * Use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also + * setting/getting CREATE_TIME which was previously + * unimplemented. (Note that the old C_TIME was supposed to + * be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->full_time_names; +#else + return (void *) context->full_time_names; +#endif + + } else if (strcmp(option_name, "user_data") == 0) { + /* + * Return the user data handle which was saved by the user + * with smbc_option_set() + */ + return context->user_data; + + } else if (strcmp(option_name, "smb_encrypt_level") == 0) { + /* + * Return the current smb encrypt negotiate option as a string. + */ + switch (context->smb_encryption_level) { + case 0: + return (void *) "none"; + case 1: + return (void *) "request"; + case 2: + return (void *) "require"; + } + + } else if (strcmp(option_name, "smb_encrypt_on") == 0) { + /* + * Return the current smb encrypt status option as a bool. + * false = off, true = on. We don't know what server is + * being requested, so we only return true if all servers + * are using an encrypted connection. + */ + SMBCSRV *s; + unsigned int num_servers = 0; + + for (s = context->servers; s; s = s->next) { + num_servers++; + if (s->cli->trans_enc_state == NULL) { + return (void *)false; + } + } +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) (bool) (num_servers > 0); +#else + return (void *) (bool) (num_servers > 0); +#endif + + } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { + /* + * From how many local master browsers should the list of + * workgroups be retrieved? It can take up to 12 minutes or + * longer after a server becomes a local master browser, for + * it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client + * never knows which local master browser will be found first, + * the one which is found first and used to retrieve a browse + * list may have an incomplete or empty browse list. By + * requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small + * networks (few workgroups), it is recommended that this + * value be set to 0, causing the browse lists from all found + * local master browsers to be retrieved and merged. For + * networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->browse_max_lmb_count; +#else + return (void *) context->browse_max_lmb_count; +#endif + + } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { + /* + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->urlencode_readdir_entries; +#else + return (void *) (bool) context->urlencode_readdir_entries; +#endif + + } else if (strcmp(option_name, "one_share_per_server") == 0) { + /* + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->one_share_per_server; +#else + return (void *) (bool) context->one_share_per_server; +#endif + + } else if (strcmp(option_name, "use_kerberos") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->use_kerberos; +#else + return (void *) (bool) context->use_kerberos; +#endif + + } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->fallback_after_kerberos; +#else + return (void *) (bool) context->fallback_after_kerberos; +#endif + + } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) context->no_auto_anonymous_login; +#else + return (void *) (bool) context->no_auto_anonymous_login; +#endif + } + + return NULL; +} + + +/* + * Initialize the library, etc. + * + * We accept a struct containing handle information. + * valid values for info->debug from 0 to 100, + * and insist that info->fn must be non-null. + */ +SMBCCTX * +smbc_init_context(SMBCCTX *context) +{ + int pid; + char *user = NULL; + char *home = NULL; + extern bool in_client; + + if (!context) { + errno = EBADF; + return NULL; + } + + /* Do not initialise the same client twice */ + if (context->initialized) { + return 0; + } + + if (!context->server.get_auth_data_fn || + context->debug < 0 || + context->debug > 100) { + + errno = EINVAL; + return NULL; + + } + + if (!SMBC_initialized) { + /* + * Do some library-wide intializations the first time we get + * called + */ + bool conf_loaded = False; + TALLOC_CTX *frame = talloc_stackframe(); + + /* Set this to what the user wants */ + DEBUGLEVEL = context->debug; + + load_case_tables(); + + setup_logging("libsmbclient", True); + if (context->debug_stderr) { + dbf = x_stderr; + x_setbuf(x_stderr, NULL); + } + + /* Here we would open the smb.conf file if needed ... */ + + in_client = True; /* FIXME, make a param */ + + home = getenv("HOME"); + if (home) { + char *conf = NULL; + if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) { + if (lp_load(conf, True, False, False, True)) { + conf_loaded = True; + } else { + DEBUG(5, ("Could not load config file: %s\n", + conf)); + } + SAFE_FREE(conf); + } + } + + if (!conf_loaded) { + /* + * Well, if that failed, try the get_dyn_CONFIGFILE + * Which points to the standard locn, and if that + * fails, silently ignore it and use the internal + * defaults ... + */ + + if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { + DEBUG(5, ("Could not load config file: %s\n", + get_dyn_CONFIGFILE())); + } else if (home) { + char *conf; + /* + * We loaded the global config file. Now lets + * load user-specific modifications to the + * global config. + */ + if (asprintf(&conf, + "%s/.smb/smb.conf.append", + home) > 0) { + if (!lp_load(conf, True, False, False, False)) { + DEBUG(10, + ("Could not append config file: " + "%s\n", + conf)); + } + SAFE_FREE(conf); + } + } + } + + load_interfaces(); /* Load the list of interfaces ... */ + + reopen_logs(); /* Get logging working ... */ + + /* + * Block SIGPIPE (from lib/util_sock.c: write()) + * It is not needed and should not stop execution + */ + BlockSignals(True, SIGPIPE); + + /* Done with one-time initialisation */ + SMBC_initialized = 1; + + TALLOC_FREE(frame); + } + + if (!context->user) { + /* + * FIXME: Is this the best way to get the user info? + */ + user = getenv("USER"); + /* walk around as "guest" if no username can be found */ + if (!user) context->user = SMB_STRDUP("guest"); + else context->user = SMB_STRDUP(user); + } + + if (!context->netbios_name) { + /* + * We try to get our netbios name from the config. If that + * fails we fall back on constructing our netbios name from + * our hostname etc + */ + if (global_myname()) { + context->netbios_name = SMB_STRDUP(global_myname()); + } + else { + /* + * Hmmm, I want to get hostname as well, but I am too + * lazy for the moment + */ + pid = sys_getpid(); + context->netbios_name = (char *)SMB_MALLOC(17); + if (!context->netbios_name) { + errno = ENOMEM; + return NULL; + } + slprintf(context->netbios_name, 16, + "smbc%s%d", context->user, pid); + } + } + + DEBUG(1, ("Using netbios name %s.\n", context->netbios_name)); + + if (!context->workgroup) { + if (lp_workgroup()) { + context->workgroup = SMB_STRDUP(lp_workgroup()); + } + else { + /* TODO: Think about a decent default workgroup */ + context->workgroup = SMB_STRDUP("samba"); + } + } + + DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); + + /* shortest timeout is 1 second */ + if (context->timeout > 0 && context->timeout < 1000) + context->timeout = 1000; + + /* + * FIXME: Should we check the function pointers here? + */ + + context->initialized = True; + + return context; +} + + +/* Return the verion of samba, and thus libsmbclient */ +const char * +smbc_version(void) +{ + return samba_version_string(); +} + + +/** Get the netbios name used for making connections */ +char * +smbc_getNetbiosName(SMBCCTX *c) +{ + return c->netbios_name; +} + +/** Set the netbios name used for making connections */ +void +smbc_setNetbiosName(SMBCCTX *c, char * netbios_name) +{ + c->netbios_name = netbios_name; +} + +/** Get the workgroup used for making connections */ +char * +smbc_getWorkgroup(SMBCCTX *c) +{ + return c->workgroup; +} + +/** Set the workgroup used for making connections */ +void +smbc_setWorkgroup(SMBCCTX *c, char * workgroup) +{ + c->workgroup = workgroup; +} + +/** Get the username used for making connections */ +char * +smbc_getUser(SMBCCTX *c) +{ + return c->user; +} + +/** Set the username used for making connections */ +void +smbc_setUser(SMBCCTX *c, char * user) +{ + c->user = user; +} + +/** Get the debug level */ +int +smbc_getDebug(SMBCCTX *c) +{ + return c->debug; +} + +/** Set the debug level */ +void +smbc_setDebug(SMBCCTX *c, int debug) +{ + c->debug = debug; +} + +/** + * Get the timeout used for waiting on connections and response data + * (in milliseconds) + */ +int +smbc_getTimeout(SMBCCTX *c) +{ + return c->timeout; +} + +/** + * Set the timeout used for waiting on connections and response data + * (in milliseconds) + */ +void +smbc_setTimeout(SMBCCTX *c, int timeout) +{ + c->timeout = timeout; +} + +/** Get the function for obtaining authentication data */ + +smbc_get_auth_data_fn +smbc_getFunctionAuthData(SMBCCTX *c) +{ + return c->server.get_auth_data_fn; +} + +/** Set the function for obtaining authentication data */ +void +smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn) +{ + c->server.get_auth_data_fn = fn; +} + +/** Get the function for checking if a server is still good */ +smbc_check_server_fn +smbc_getFunctionCheckServer(SMBCCTX *c) +{ + return c->server.check_server_fn; +} + +/** Set the function for checking if a server is still good */ +void +smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn) +{ + c->server.check_server_fn = fn; +} + +/** Get the function for removing a server if unused */ +smbc_remove_unused_server_fn +smbc_getFunctionRemoveUnusedServer(SMBCCTX *c) +{ + return c->server.remove_unused_server_fn; +} + +/** Set the function for removing a server if unused */ +void +smbc_setFunctionRemoveUnusedServer(SMBCCTX *c, + smbc_remove_unused_server_fn fn) +{ + c->server.remove_unused_server_fn = fn; +} + +/** Get the function to store private data of the server cache */ +struct +smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c) +{ + return c->cache.server_cache_data; +} + +/** Set the function to store private data of the server cache */ +void +smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache) +{ + c->cache.server_cache_data = cache; +} + + +/** Get the function for adding a cached server */ +smbc_add_cached_srv_fn +smbc_getFunctionAddCachedServer(SMBCCTX *c) +{ + return c->cache.add_cached_server_fn; +} + +/** Set the function for adding a cached server */ +void +smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn) +{ + c->cache.add_cached_server_fn = fn; +} + +/** Get the function for server cache lookup */ +smbc_get_cached_srv_fn +smbc_getFunctionGetCachedServer(SMBCCTX *c) +{ + return c->cache.get_cached_server_fn; +} + +/** Set the function for server cache lookup */ +void +smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn) +{ + c->cache.get_cached_server_fn = fn; +} + +/** Get the function for server cache removal */ +smbc_remove_cached_srv_fn +smbc_getFunctionRemoveCachedServer(SMBCCTX *c) +{ + return c->cache.remove_cached_server_fn; +} + +/** Set the function for server cache removal */ +void +smbc_setFunctionRemoveCachedServer(SMBCCTX *c, + smbc_remove_cached_srv_fn fn) +{ + c->cache.remove_cached_server_fn = fn; +} + +/** + * Get the function for server cache purging. This function tries to + * remove all cached servers (e.g. on disconnect) + */ +smbc_purge_cached_srv_fn +smbc_getFunctionPurgeCachedServers(SMBCCTX *c) +{ + return c->cache.purge_cached_server_fn; +} + +/** + * Set the function for server cache purging. This function tries to + * remove all cached servers (e.g. on disconnect) + */ +void +smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn) +{ + c->cache.purge_cached_server_fn = fn; +} + +/** + * Callable functions for files. + */ + +smbc_open_fn +smbc_getFunctionOpen(SMBCCTX *c) +{ + return c->posix_emu.open_fn; +} + +void +smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn) +{ + c->posix_emu.open_fn = fn; +} + +smbc_creat_fn +smbc_getFunctionCreat(SMBCCTX *c) +{ + return c->posix_emu.creat_fn; +} + +void +smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn) +{ + c->posix_emu.creat_fn = fn; +} + +smbc_read_fn +smbc_getFunctionRead(SMBCCTX *c) +{ + return c->posix_emu.read_fn; +} + +void +smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn) +{ + c->posix_emu.read_fn = fn; +} + +smbc_write_fn +smbc_getFunctionWrite(SMBCCTX *c) +{ + return c->posix_emu.write_fn; +} + +void +smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn) +{ + c->posix_emu.write_fn = fn; +} + +smbc_unlink_fn +smbc_getFunctionUnlink(SMBCCTX *c) +{ + return c->posix_emu.unlink_fn; +} + +void +smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn) +{ + c->posix_emu.unlink_fn = fn; +} + +smbc_rename_fn +smbc_getFunctionRename(SMBCCTX *c) +{ + return c->posix_emu.rename_fn; +} + +void +smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn) +{ + c->posix_emu.rename_fn = fn; +} + +smbc_lseek_fn +smbc_getFunctionLseek(SMBCCTX *c) +{ + return c->posix_emu.lseek_fn; +} + +void +smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn) +{ + c->posix_emu.lseek_fn = fn; +} + +smbc_stat_fn +smbc_getFunctionStat(SMBCCTX *c) +{ + return c->posix_emu.stat_fn; +} + +void +smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn) +{ + c->posix_emu.stat_fn = fn; +} + +smbc_fstat_fn +smbc_getFunctionFstat(SMBCCTX *c) +{ + return c->posix_emu.fstat_fn; +} + +void +smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn) +{ + c->posix_emu.fstat_fn = fn; +} + +smbc_ftruncate_fn +smbc_getFunctionFtruncate(SMBCCTX *c) +{ + return c->posix_emu.ftruncate_fn; +} + +void +smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn) +{ + c->posix_emu.ftruncate_fn = fn; +} + +smbc_close_fn +smbc_getFunctionClose(SMBCCTX *c) +{ + return c->posix_emu.close_fn; +} + +void +smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn) +{ + c->posix_emu.close_fn = fn; +} + + +/** + * Callable functions for directories. + */ + +smbc_opendir_fn +smbc_getFunctionOpendir(SMBCCTX *c) +{ + return c->posix_emu.opendir_fn; +} + +void +smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn) +{ + c->posix_emu.opendir_fn = fn; +} + +smbc_closedir_fn +smbc_getFunctionClosedir(SMBCCTX *c) +{ + return c->posix_emu.closedir_fn; +} + +void +smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn) +{ + c->posix_emu.closedir_fn = fn; +} + +smbc_readdir_fn +smbc_getFunctionReaddir(SMBCCTX *c) +{ + return c->posix_emu.readdir_fn; +} + +void +smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn) +{ + c->posix_emu.readdir_fn = fn; +} + +smbc_getdents_fn +smbc_getFunctionGetdents(SMBCCTX *c) +{ + return c->posix_emu.getdents_fn; +} + +void +smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn) +{ + c->posix_emu.getdents_fn = fn; +} + +smbc_mkdir_fn +smbc_getFunctionMkdir(SMBCCTX *c) +{ + return c->posix_emu.mkdir_fn; +} + +void +smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn) +{ + c->posix_emu.mkdir_fn = fn; +} + +smbc_rmdir_fn +smbc_getFunctionRmdir(SMBCCTX *c) +{ + return c->posix_emu.rmdir_fn; +} + +void +smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn) +{ + c->posix_emu.rmdir_fn = fn; +} + +smbc_telldir_fn +smbc_getFunctionTelldir(SMBCCTX *c) +{ + return c->posix_emu.telldir_fn; +} + +void +smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn) +{ + c->posix_emu.telldir_fn = fn; +} + +smbc_lseekdir_fn +smbc_getFunctionLseekdir(SMBCCTX *c) +{ + return c->posix_emu.lseekdir_fn; +} + +void +smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn) +{ + c->posix_emu.lseekdir_fn = fn; +} + +smbc_fstatdir_fn +smbc_getFunctionFstatdir(SMBCCTX *c) +{ + return c->posix_emu.fstatdir_fn; +} + +void +smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn) +{ + c->posix_emu.fstatdir_fn = fn; +} + + +/** + * Callable functions applicable to both files and directories. + */ + +smbc_chmod_fn +smbc_getFunctionChmod(SMBCCTX *c) +{ + return c->posix_emu.chmod_fn; +} + +void +smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn) +{ + c->posix_emu.chmod_fn = fn; +} + +smbc_utimes_fn +smbc_getFunctionUtimes(SMBCCTX *c) +{ + return c->posix_emu.utimes_fn; +} + +void +smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn) +{ + c->posix_emu.utimes_fn = fn; +} + +smbc_setxattr_fn +smbc_getFunctionSetxattr(SMBCCTX *c) +{ + return c->posix_emu.setxattr_fn; +} + +void +smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn) +{ + c->posix_emu.setxattr_fn = fn; +} + +smbc_getxattr_fn +smbc_getFunctionGetxattr(SMBCCTX *c) +{ + return c->posix_emu.getxattr_fn; +} + +void +smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn) +{ + c->posix_emu.getxattr_fn = fn; +} + +smbc_removexattr_fn +smbc_getFunctionRemovexattr(SMBCCTX *c) +{ + return c->posix_emu.removexattr_fn; +} + +void +smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn) +{ + c->posix_emu.removexattr_fn = fn; +} + +smbc_listxattr_fn +smbc_getFunctionListxattr(SMBCCTX *c) +{ + return c->posix_emu.listxattr_fn; +} + +void +smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn) +{ + c->posix_emu.listxattr_fn = fn; +} + + +/** + * Callable functions related to printing + */ + +smbc_print_file_fn +smbc_getFunctionPrintFile(SMBCCTX *c) +{ + return c->printing.print_file_fn; +} + +void +smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn) +{ + c->printing.print_file_fn = fn; +} + +smbc_open_print_job_fn +smbc_getFunctionOpenPrintJob(SMBCCTX *c) +{ + return c->printing.open_print_job_fn; +} + +void +smbc_setFunctionOpenPrintJob(SMBCCTX *c, + smbc_open_print_job_fn fn) +{ + c->printing.open_print_job_fn = fn; +} + +smbc_list_print_jobs_fn +smbc_getFunctionListPrintJobs(SMBCCTX *c) +{ + return c->printing.list_print_jobs_fn; +} + +void +smbc_setFunctionListPrintJobs(SMBCCTX *c, + smbc_list_print_jobs_fn fn) +{ + c->printing.list_print_jobs_fn = fn; +} + +smbc_unlink_print_job_fn +smbc_getFunctionUnlinkPrintJob(SMBCCTX *c) +{ + return c->printing.unlink_print_job_fn; +} + +void +smbc_setFunctionUnlinkPrintJob(SMBCCTX *c, + smbc_unlink_print_job_fn fn) +{ + c->printing.unlink_print_job_fn = fn; +} + diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c new file mode 100644 index 0000000000..9cb3351433 --- /dev/null +++ b/source3/libsmb/libsmb_dir.c @@ -0,0 +1,1928 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Routine to open a directory + * We accept the URL syntax explained in SMBC_parse_path(), above. + */ + +static void +remove_dir(SMBCFILE *dir) +{ + struct smbc_dir_list *d,*f; + + d = dir->dir_list; + while (d) { + + f = d; d = d->next; + + SAFE_FREE(f->dirent); + SAFE_FREE(f); + + } + + dir->dir_list = dir->dir_end = dir->dir_next = NULL; + +} + +static int +add_dirent(SMBCFILE *dir, + const char *name, + const char *comment, + uint32 type) +{ + struct smbc_dirent *dirent; + int size; + int name_length = (name == NULL ? 0 : strlen(name)); + int comment_len = (comment == NULL ? 0 : strlen(comment)); + + /* + * Allocate space for the dirent, which must be increased by the + * size of the name and the comment and 1 each for the null terminator. + */ + + size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; + + dirent = (struct smbc_dirent *)SMB_MALLOC(size); + + if (!dirent) { + + dir->dir_error = ENOMEM; + return -1; + + } + + ZERO_STRUCTP(dirent); + + if (dir->dir_list == NULL) { + + dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); + if (!dir->dir_list) { + + SAFE_FREE(dirent); + dir->dir_error = ENOMEM; + return -1; + + } + ZERO_STRUCTP(dir->dir_list); + + dir->dir_end = dir->dir_next = dir->dir_list; + } + else { + + dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); + + if (!dir->dir_end->next) { + + SAFE_FREE(dirent); + dir->dir_error = ENOMEM; + return -1; + + } + ZERO_STRUCTP(dir->dir_end->next); + + dir->dir_end = dir->dir_end->next; + } + + dir->dir_end->next = NULL; + dir->dir_end->dirent = dirent; + + dirent->smbc_type = type; + dirent->namelen = name_length; + dirent->commentlen = comment_len; + dirent->dirlen = size; + + /* + * dirent->namelen + 1 includes the null (no null termination needed) + * Ditto for dirent->commentlen. + * The space for the two null bytes was allocated. + */ + strncpy(dirent->name, (name?name:""), dirent->namelen + 1); + dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); + strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); + + return 0; + +} + +static void +list_unique_wg_fn(const char *name, + uint32 type, + const char *comment, + void *state) +{ + SMBCFILE *dir = (SMBCFILE *)state; + struct smbc_dir_list *dir_list; + struct smbc_dirent *dirent; + int dirent_type; + int do_remove = 0; + + dirent_type = dir->dir_type; + + if (add_dirent(dir, name, comment, dirent_type) < 0) { + + /* An error occurred, what do we do? */ + /* FIXME: Add some code here */ + } + + /* Point to the one just added */ + dirent = dir->dir_end->dirent; + + /* See if this was a duplicate */ + for (dir_list = dir->dir_list; + dir_list != dir->dir_end; + dir_list = dir_list->next) { + if (! do_remove && + strcmp(dir_list->dirent->name, dirent->name) == 0) { + /* Duplicate. End end of list need to be removed. */ + do_remove = 1; + } + + if (do_remove && dir_list->next == dir->dir_end) { + /* Found the end of the list. Remove it. */ + dir->dir_end = dir_list; + free(dir_list->next); + free(dirent); + dir_list->next = NULL; + break; + } + } +} + +static void +list_fn(const char *name, + uint32 type, + const char *comment, + void *state) +{ + SMBCFILE *dir = (SMBCFILE *)state; + int dirent_type; + + /* + * We need to process the type a little ... + * + * Disk share = 0x00000000 + * Print share = 0x00000001 + * Comms share = 0x00000002 (obsolete?) + * IPC$ share = 0x00000003 + * + * administrative shares: + * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 + */ + + if (dir->dir_type == SMBC_FILE_SHARE) { + switch (type) { + case 0 | 0x80000000: + case 0: + dirent_type = SMBC_FILE_SHARE; + break; + + case 1: + dirent_type = SMBC_PRINTER_SHARE; + break; + + case 2: + dirent_type = SMBC_COMMS_SHARE; + break; + + case 3 | 0x80000000: + case 3: + dirent_type = SMBC_IPC_SHARE; + break; + + default: + dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ + break; + } + } + else { + dirent_type = dir->dir_type; + } + + if (add_dirent(dir, name, comment, dirent_type) < 0) { + + /* An error occurred, what do we do? */ + /* FIXME: Add some code here */ + + } +} + +static void +dir_list_fn(const char *mnt, + file_info *finfo, + const char *mask, + void *state) +{ + + if (add_dirent((SMBCFILE *)state, finfo->name, "", + (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { + + /* Handle an error ... */ + + /* FIXME: Add some code ... */ + + } + +} + +static int +net_share_enum_rpc(struct cli_state *cli, + void (*fn)(const char *name, + uint32 type, + const char *comment, + void *state), + void *state) +{ + int i; + WERROR result; + ENUM_HND enum_hnd; + uint32 info_level = 1; + uint32 preferred_len = 0xffffffff; + uint32 type; + SRV_SHARE_INFO_CTR ctr; + fstring name = ""; + fstring comment = ""; + struct rpc_pipe_client *pipe_hnd; + NTSTATUS nt_status; + + /* Open the server service pipe */ + pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); + if (!pipe_hnd) { + DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); + return -1; + } + + /* Issue the NetShareEnum RPC call and retrieve the response */ + init_enum_hnd(&enum_hnd, 0); + result = rpccli_srvsvc_net_share_enum(pipe_hnd, + talloc_tos(), + info_level, + &ctr, + preferred_len, + &enum_hnd); + + /* Was it successful? */ + if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { + /* Nope. Go clean up. */ + goto done; + } + + /* For each returned entry... */ + for (i = 0; i < ctr.num_entries; i++) { + + /* pull out the share name */ + rpcstr_pull_unistr2_fstring( + name, &ctr.share.info1[i].info_1_str.uni_netname); + + /* pull out the share's comment */ + rpcstr_pull_unistr2_fstring( + comment, &ctr.share.info1[i].info_1_str.uni_remark); + + /* Get the type value */ + type = ctr.share.info1[i].info_1.type; + + /* Add this share to the list */ + (*fn)(name, type, comment, state); + } + +done: + /* Close the server service pipe */ + cli_rpc_pipe_close(pipe_hnd); + + /* Tell 'em if it worked */ + return W_ERROR_IS_OK(result) ? 0 : -1; +} + + +/* + * Verify that the options specified in a URL are valid + */ +int +SMBC_check_options(char *server, + char *share, + char *path, + char *options) +{ + DEBUG(4, ("SMBC_check_options(): server='%s' share='%s' " + "path='%s' options='%s'\n", + server, share, path, options)); + + /* No options at all is always ok */ + if (! *options) return 0; + + /* Currently, we don't support any options. */ + return -1; +} + + +SMBCFILE * +SMBC_opendir_ctx(SMBCCTX *context, + const char *fname) +{ + int saved_errno; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *options = NULL; + char *workgroup = NULL; + char *path = NULL; + uint16 mode; + char *p = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *dir = NULL; + struct sockaddr_storage rem_ss; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + DEBUG(4, ("no valid context\n")); + errno = EINVAL + 8192; + TALLOC_FREE(frame); + return NULL; + + } + + if (!fname) { + DEBUG(4, ("no valid fname\n")); + errno = EINVAL + 8193; + TALLOC_FREE(frame); + return NULL; + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + &options)) { + DEBUG(4, ("no valid path\n")); + errno = EINVAL + 8194; + TALLOC_FREE(frame); + return NULL; + } + + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' " + "path='%s' options='%s'\n", + fname, server, share, path, options)); + + /* Ensure the options are valid */ + if (SMBC_check_options(server, share, path, options)) { + DEBUG(4, ("unacceptable options (%s)\n", options)); + errno = EINVAL + 8195; + TALLOC_FREE(frame); + return NULL; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + } + + dir = SMB_MALLOC_P(SMBCFILE); + + if (!dir) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + + ZERO_STRUCTP(dir); + + dir->cli_fd = 0; + dir->fname = SMB_STRDUP(fname); + dir->srv = NULL; + dir->offset = 0; + dir->file = False; + dir->dir_list = dir->dir_next = dir->dir_end = NULL; + + if (server[0] == (char)0) { + + int i; + int count; + int max_lmb_count; + struct ip_service *ip_list; + struct ip_service server_addr; + struct user_auth_info u_info; + + if (share[0] != (char)0 || path[0] != (char)0) { + + errno = EINVAL + 8196; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + /* Determine how many local master browsers to query */ + max_lmb_count = (context->browse_max_lmb_count == 0 + ? INT_MAX + : context->browse_max_lmb_count); + + memset(&u_info, '\0', sizeof(u_info)); + u_info.username = talloc_strdup(frame,user); + u_info.password = talloc_strdup(frame,password); + if (!u_info.username || !u_info.password) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + /* + * We have server and share and path empty but options + * requesting that we scan all master browsers for their list + * of workgroups/domains. This implies that we must first try + * broadcast queries to find all master browsers, and if that + * doesn't work, then try our other methods which return only + * a single master browser. + */ + + ip_list = NULL; + if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, + &count))) + { + + SAFE_FREE(ip_list); + + if (!find_master_ip(workgroup, &server_addr.ss)) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + errno = ENOENT; + TALLOC_FREE(frame); + return NULL; + } + + ip_list = (struct ip_service *)memdup( + &server_addr, sizeof(server_addr)); + if (ip_list == NULL) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + count = 1; + } + + for (i = 0; i < count && i < max_lmb_count; i++) { + char addr[INET6_ADDRSTRLEN]; + char *wg_ptr = NULL; + struct cli_state *cli = NULL; + + print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); + DEBUG(99, ("Found master browser %d of %d: %s\n", + i+1, MAX(count, max_lmb_count), + addr)); + + cli = get_ipc_connect_master_ip(talloc_tos(), + &ip_list[i], + &u_info, + &wg_ptr); + /* cli == NULL is the master browser refused to talk or + could not be found */ + if (!cli) { + continue; + } + + workgroup = talloc_strdup(frame, wg_ptr); + server = talloc_strdup(frame, cli->desthost); + + cli_shutdown(cli); + + if (!workgroup || !server) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + + DEBUG(4, ("using workgroup %s %s\n", + workgroup, server)); + + /* + * For each returned master browser IP address, get a + * connection to IPC$ on the server if we do not + * already have one, and determine the + * workgroups/domains that it knows about. + */ + + srv = SMBC_server(frame, context, True, server, "IPC$", + &workgroup, &user, &password); + if (!srv) { + continue; + } + + dir->srv = srv; + dir->dir_type = SMBC_WORKGROUP; + + /* Now, list the stuff ... */ + + if (!cli_NetServerEnum(srv->cli, + workgroup, + SV_TYPE_DOMAIN_ENUM, + list_unique_wg_fn, + (void *)dir)) { + continue; + } + } + + SAFE_FREE(ip_list); + } else { + /* + * Server not an empty string ... Check the rest and see what + * gives + */ + if (*share == '\0') { + if (*path != '\0') { + + /* Should not have empty share with path */ + errno = EINVAL + 8197; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + + } + + /* + * We don't know if is really a server name + * or is a workgroup/domain name. If we already have + * a server structure for it, we'll use it. + * Otherwise, check to see if <1D>, + * <1B>, or <20> translates. We check + * to see if is an IP address first. + */ + + /* + * See if we have an existing server. Do not + * establish a connection if one does not already + * exist. + */ + srv = SMBC_server(frame, context, False, server, "IPC$", + &workgroup, &user, &password); + + /* + * If no existing server and not an IP addr, look for + * LMB or DMB + */ + if (!srv && + !is_ipaddress(server) && + (resolve_name(server, &rem_ss, 0x1d) || /* LMB */ + resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */ + + fstring buserver; + + dir->dir_type = SMBC_SERVER; + + /* + * Get the backup list ... + */ + if (!name_status_find(server, 0, 0, + &rem_ss, buserver)) { + + DEBUG(0, ("Could not get name of " + "local/domain master browser " + "for server %s\n", server)); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + errno = EPERM; + TALLOC_FREE(frame); + return NULL; + + } + + /* + * Get a connection to IPC$ on the server if + * we do not already have one + */ + srv = SMBC_server(frame, context, True, + buserver, "IPC$", + &workgroup, &user, &password); + if (!srv) { + DEBUG(0, ("got no contact to IPC$\n")); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + + } + + dir->srv = srv; + + /* Now, list the servers ... */ + if (!cli_NetServerEnum(srv->cli, server, + 0x0000FFFE, list_fn, + (void *)dir)) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + } else if (srv || + (resolve_name(server, &rem_ss, 0x20))) { + + /* If we hadn't found the server, get one now */ + if (!srv) { + srv = SMBC_server(frame, context, True, + server, "IPC$", + &workgroup, + &user, &password); + } + + if (!srv) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + + } + + dir->dir_type = SMBC_FILE_SHARE; + dir->srv = srv; + + /* List the shares ... */ + + if (net_share_enum_rpc( + srv->cli, + list_fn, + (void *) dir) < 0 && + cli_RNetShareEnum( + srv->cli, + list_fn, + (void *)dir) < 0) { + + errno = cli_errno(srv->cli); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + + } + } else { + /* Neither the workgroup nor server exists */ + errno = ECONNREFUSED; + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + } + else { + /* + * The server and share are specified ... work from + * there ... + */ + char *targetpath; + struct cli_state *targetcli; + + /* We connect to the server and list the directory */ + dir->dir_type = SMBC_FILE_SHARE; + + srv = SMBC_server(frame, context, True, server, share, + &workgroup, &user, &password); + + if (!srv) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + dir->srv = srv; + + /* Now, list the files ... */ + + p = path + strlen(path); + path = talloc_asprintf_append(path, "\\*"); + if (!path) { + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + TALLOC_FREE(frame); + return NULL; + } + + if (cli_list(targetcli, targetpath, + aDIR | aSYSTEM | aHIDDEN, + dir_list_fn, (void *)dir) < 0) { + + if (dir) { + SAFE_FREE(dir->fname); + SAFE_FREE(dir); + } + saved_errno = SMBC_errno(context, targetcli); + + if (saved_errno == EINVAL) { + /* + * See if they asked to opendir something + * other than a directory. If so, the + * converted error value we got would have + * been EINVAL rather than ENOTDIR. + */ + *p = '\0'; /* restore original path */ + + if (SMBC_getatr(context, srv, path, + &mode, NULL, + NULL, NULL, NULL, NULL, + NULL) && + ! IS_DOS_DIR(mode)) { + + /* It is. Correct the error value */ + saved_errno = ENOTDIR; + } + } + + /* + * If there was an error and the server is no + * good any more... + */ + if (cli_is_error(targetcli) && + (context->server.check_server_fn)(context, srv)) { + + /* ... then remove it. */ + if ((context->server.remove_unused_server_fn)(context, + srv)) { + /* + * We could not remove the + * server completely, remove + * it from the cache so we + * will not get it again. It + * will be removed when the + * last file/dir is closed. + */ + (context->cache.remove_cached_server_fn)(context, srv); + } + } + + errno = saved_errno; + TALLOC_FREE(frame); + return NULL; + } + } + + } + + DLIST_ADD(context->files, dir); + TALLOC_FREE(frame); + return dir; + +} + +/* + * Routine to close a directory + */ + +int +SMBC_closedir_ctx(SMBCCTX *context, + SMBCFILE *dir) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!dir || !SMBC_dlist_contains(context->files, dir)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + remove_dir(dir); /* Clean it up */ + + DLIST_REMOVE(context->files, dir); + + if (dir) { + + SAFE_FREE(dir->fname); + SAFE_FREE(dir); /* Free the space too */ + } + + TALLOC_FREE(frame); + return 0; + +} + +static void +smbc_readdir_internal(SMBCCTX * context, + struct smbc_dirent *dest, + struct smbc_dirent *src, + int max_namebuf_len) +{ + if (context->urlencode_readdir_entries) { + + /* url-encode the name. get back remaining buffer space */ + max_namebuf_len = + SMBC_urlencode(dest->name, src->name, max_namebuf_len); + + /* We now know the name length */ + dest->namelen = strlen(dest->name); + + /* Save the pointer to the beginning of the comment */ + dest->comment = dest->name + dest->namelen + 1; + + /* Copy the comment */ + strncpy(dest->comment, src->comment, max_namebuf_len - 1); + dest->comment[max_namebuf_len - 1] = '\0'; + + /* Save other fields */ + dest->smbc_type = src->smbc_type; + dest->commentlen = strlen(dest->comment); + dest->dirlen = ((dest->comment + dest->commentlen + 1) - + (char *) dest); + } else { + + /* No encoding. Just copy the entry as is. */ + memcpy(dest, src, src->dirlen); + dest->comment = (char *)(&dest->name + src->namelen + 1); + } + +} + +/* + * Routine to get a directory entry + */ + +struct smbc_dirent * +SMBC_readdir_ctx(SMBCCTX *context, + SMBCFILE *dir) +{ + int maxlen; + struct smbc_dirent *dirp, *dirent; + TALLOC_CTX *frame = talloc_stackframe(); + + /* Check that all is ok first ... */ + + if (!context || !context->initialized) { + + errno = EINVAL; + DEBUG(0, ("Invalid context in SMBC_readdir_ctx()\n")); + TALLOC_FREE(frame); + return NULL; + + } + + if (!dir || !SMBC_dlist_contains(context->files, dir)) { + + errno = EBADF; + DEBUG(0, ("Invalid dir in SMBC_readdir_ctx()\n")); + TALLOC_FREE(frame); + return NULL; + + } + + if (dir->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + DEBUG(0, ("Found file vs directory in SMBC_readdir_ctx()\n")); + TALLOC_FREE(frame); + return NULL; + + } + + if (!dir->dir_next) { + TALLOC_FREE(frame); + return NULL; + } + + dirent = dir->dir_next->dirent; + if (!dirent) { + + errno = ENOENT; + TALLOC_FREE(frame); + return NULL; + + } + + dirp = (struct smbc_dirent *)context->dirent; + maxlen = (sizeof(context->dirent) - + sizeof(struct smbc_dirent)); + + smbc_readdir_internal(context, dirp, dirent, maxlen); + + dir->dir_next = dir->dir_next->next; + + TALLOC_FREE(frame); + return dirp; +} + +/* + * Routine to get directory entries + */ + +int +SMBC_getdents_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct smbc_dirent *dirp, + int count) +{ + int rem = count; + int reqd; + int maxlen; + char *ndir = (char *)dirp; + struct smbc_dir_list *dirlist; + TALLOC_CTX *frame = talloc_stackframe(); + + /* Check that all is ok first ... */ + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!dir || !SMBC_dlist_contains(context->files, dir)) { + + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + if (dir->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + TALLOC_FREE(frame); + return -1; + + } + + /* + * Now, retrieve the number of entries that will fit in what was passed + * We have to figure out if the info is in the list, or we need to + * send a request to the server to get the info. + */ + + while ((dirlist = dir->dir_next)) { + struct smbc_dirent *dirent; + + if (!dirlist->dirent) { + + errno = ENOENT; /* Bad error */ + TALLOC_FREE(frame); + return -1; + + } + + /* Do urlencoding of next entry, if so selected */ + dirent = (struct smbc_dirent *)context->dirent; + maxlen = (sizeof(context->dirent) - + sizeof(struct smbc_dirent)); + smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen); + + reqd = dirent->dirlen; + + if (rem < reqd) { + + if (rem < count) { /* We managed to copy something */ + + errno = 0; + TALLOC_FREE(frame); + return count - rem; + + } + else { /* Nothing copied ... */ + + errno = EINVAL; /* Not enough space ... */ + TALLOC_FREE(frame); + return -1; + + } + + } + + memcpy(ndir, dirent, reqd); /* Copy the data in ... */ + + ((struct smbc_dirent *)ndir)->comment = + (char *)(&((struct smbc_dirent *)ndir)->name + + dirent->namelen + + 1); + + ndir += reqd; + + rem -= reqd; + + dir->dir_next = dirlist = dirlist -> next; + } + + TALLOC_FREE(frame); + + if (rem == count) + return 0; + else + return count - rem; + +} + +/* + * Routine to create a directory ... + */ + +int +SMBC_mkdir_ctx(SMBCCTX *context, + const char *fname, + mode_t mode) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_mkdir(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + + } + + /*d_printf(">>>mkdir: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ + + if (!cli_mkdir(targetcli, targetpath)) { + + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return 0; + +} + +/* + * Our list function simply checks to see if a directory is not empty + */ + +static int smbc_rmdir_dirempty = True; + +static void +rmdir_list_fn(const char *mnt, + file_info *finfo, + const char *mask, + void *state) +{ + if (strncmp(finfo->name, ".", 1) != 0 && + strncmp(finfo->name, "..", 2) != 0) { + smbc_rmdir_dirempty = False; + } +} + +/* + * Routine to remove a directory + */ + +int +SMBC_rmdir_ctx(SMBCCTX *context, + const char *fname) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_rmdir(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + + } + + /*d_printf(">>>rmdir: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ + + + if (!cli_rmdir(targetcli, targetpath)) { + + errno = SMBC_errno(context, targetcli); + + if (errno == EACCES) { /* Check if the dir empty or not */ + + /* Local storage to avoid buffer overflows */ + char *lpath; + + smbc_rmdir_dirempty = True; /* Make this so ... */ + + lpath = talloc_asprintf(frame, "%s\\*", + targetpath); + if (!lpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + + if (cli_list(targetcli, lpath, + aDIR | aSYSTEM | aHIDDEN, + rmdir_list_fn, NULL) < 0) { + + /* Fix errno to ignore latest error ... */ + DEBUG(5, ("smbc_rmdir: " + "cli_list returned an error: %d\n", + SMBC_errno(context, targetcli))); + errno = EACCES; + + } + + if (smbc_rmdir_dirempty) + errno = EACCES; + else + errno = ENOTEMPTY; + + } + + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return 0; + +} + +/* + * Routine to return the current directory position + */ + +off_t +SMBC_telldir_ctx(SMBCCTX *context, + SMBCFILE *dir) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!dir || !SMBC_dlist_contains(context->files, dir)) { + + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + if (dir->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + TALLOC_FREE(frame); + return -1; + + } + + /* See if we're already at the end. */ + if (dir->dir_next == NULL) { + /* We are. */ + TALLOC_FREE(frame); + return -1; + } + + /* + * We return the pointer here as the offset + */ + TALLOC_FREE(frame); + return (off_t)(long)dir->dir_next->dirent; +} + +/* + * A routine to run down the list and see if the entry is OK + */ + +static struct smbc_dir_list * +check_dir_ent(struct smbc_dir_list *list, + struct smbc_dirent *dirent) +{ + + /* Run down the list looking for what we want */ + + if (dirent) { + + struct smbc_dir_list *tmp = list; + + while (tmp) { + + if (tmp->dirent == dirent) + return tmp; + + tmp = tmp->next; + + } + + } + + return NULL; /* Not found, or an error */ + +} + + +/* + * Routine to seek on a directory + */ + +int +SMBC_lseekdir_ctx(SMBCCTX *context, + SMBCFILE *dir, + off_t offset) +{ + long int l_offset = offset; /* Handle problems of size */ + struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; + struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (dir->file != False) { /* FIXME, should be dir, perhaps */ + + errno = ENOTDIR; + TALLOC_FREE(frame); + return -1; + + } + + /* Now, check what we were passed and see if it is OK ... */ + + if (dirent == NULL) { /* Seek to the begining of the list */ + + dir->dir_next = dir->dir_list; + TALLOC_FREE(frame); + return 0; + + } + + if (offset == -1) { /* Seek to the end of the list */ + dir->dir_next = NULL; + TALLOC_FREE(frame); + return 0; + } + + /* Now, run down the list and make sure that the entry is OK */ + /* This may need to be changed if we change the format of the list */ + + if ((list_ent = check_dir_ent(dir->dir_list, dirent)) == NULL) { + errno = EINVAL; /* Bad entry */ + TALLOC_FREE(frame); + return -1; + } + + dir->dir_next = list_ent; + + TALLOC_FREE(frame); + return 0; +} + +/* + * Routine to fstat a dir + */ + +int +SMBC_fstatdir_ctx(SMBCCTX *context, + SMBCFILE *dir, + struct stat *st) +{ + + if (!context || !context->initialized) { + + errno = EINVAL; + return -1; + } + + /* No code yet ... */ + return 0; +} + +int +SMBC_chmod_ctx(SMBCCTX *context, + const char *fname, + mode_t newmode) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + uint16 mode; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + mode = 0; + + if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; + if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; + if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; + if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; + + if (!cli_setatr(srv->cli, path, mode, 0)) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; +} + +int +SMBC_utimes_ctx(SMBCCTX *context, + const char *fname, + struct timeval *tbuf) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + time_t access_time; + time_t write_time; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (tbuf == NULL) { + access_time = write_time = time(NULL); + } else { + access_time = tbuf[0].tv_sec; + write_time = tbuf[1].tv_sec; + } + + if (DEBUGLVL(4)) { + char *p; + char atimebuf[32]; + char mtimebuf[32]; + + strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1); + atimebuf[sizeof(atimebuf) - 1] = '\0'; + if ((p = strchr(atimebuf, '\n')) != NULL) { + *p = '\0'; + } + + strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1); + mtimebuf[sizeof(mtimebuf) - 1] = '\0'; + if ((p = strchr(mtimebuf, '\n')) != NULL) { + *p = '\0'; + } + + dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n", + fname, atimebuf, mtimebuf); + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (!SMBC_setatr(context, srv, path, + 0, access_time, write_time, 0, 0)) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_setatr */ + } + + TALLOC_FREE(frame); + return 0; +} + +/* + * Routine to unlink() a file + */ + +int +SMBC_unlink_ctx(SMBCCTX *context, + const char *fname) +{ + char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + SMBCSRV *srv = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* SMBC_server sets errno */ + + } + + /*d_printf(">>>unlink: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ + + if (!cli_unlink(targetcli, targetpath)) { + + errno = SMBC_errno(context, targetcli); + + if (errno == EACCES) { /* Check if the file is a directory */ + + int saverr = errno; + SMB_OFF_T size = 0; + uint16 mode = 0; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + SMB_INO_T ino = 0; + + if (!SMBC_getatr(context, srv, path, &mode, &size, + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + + /* Hmmm, bad error ... What? */ + + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + else { + + if (IS_DOS_DIR(mode)) + errno = EISDIR; + else + errno = saverr; /* Restore this */ + + } + } + + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return 0; /* Success ... */ + +} + +/* + * Routine to rename() a file + */ + +int +SMBC_rename_ctx(SMBCCTX *ocontext, + const char *oname, + SMBCCTX *ncontext, + const char *nname) +{ + char *server1 = NULL; + char *share1 = NULL; + char *server2 = NULL; + char *share2 = NULL; + char *user1 = NULL; + char *user2 = NULL; + char *password1 = NULL; + char *password2 = NULL; + char *workgroup = NULL; + char *path1 = NULL; + char *path2 = NULL; + char *targetpath1 = NULL; + char *targetpath2 = NULL; + struct cli_state *targetcli1 = NULL; + struct cli_state *targetcli2 = NULL; + SMBCSRV *srv = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!ocontext || !ncontext || + !ocontext->initialized || + !ncontext->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!oname || !nname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); + + if (SMBC_parse_path(frame, + ocontext, + oname, + &workgroup, + &server1, + &share1, + &path1, + &user1, + &password1, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user1 || user1[0] == (char)0) { + user1 = talloc_strdup(frame, ocontext->user); + if (!user1) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + if (SMBC_parse_path(frame, + ncontext, + nname, + NULL, + &server2, + &share2, + &path2, + &user2, + &password2, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user2 || user2[0] == (char)0) { + user2 = talloc_strdup(frame, ncontext->user); + if (!user2) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + if (strcmp(server1, server2) || strcmp(share1, share2) || + strcmp(user1, user2)) { + /* Can't rename across file systems, or users?? */ + errno = EXDEV; + TALLOC_FREE(frame); + return -1; + } + + srv = SMBC_server(frame, ocontext, True, + server1, share1, &workgroup, &user1, &password1); + if (!srv) { + TALLOC_FREE(frame); + return -1; + + } + + /*d_printf(">>>rename: resolving %s\n", path1);*/ + if (!cli_resolve_path(frame, "", srv->cli, path1, + &targetcli1, &targetpath1)) { + d_printf("Could not resolve %s\n", path1); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ + /*d_printf(">>>rename: resolving %s\n", path2);*/ + if (!cli_resolve_path(frame, "", srv->cli, path2, + &targetcli2, &targetpath2)) { + d_printf("Could not resolve %s\n", path2); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ + + if (strcmp(targetcli1->desthost, targetcli2->desthost) || + strcmp(targetcli1->share, targetcli2->share)) + { + /* can't rename across file systems */ + errno = EXDEV; + TALLOC_FREE(frame); + return -1; + } + + if (!cli_rename(targetcli1, targetpath1, targetpath2)) { + int eno = SMBC_errno(ocontext, targetcli1); + + if (eno != EEXIST || + !cli_unlink(targetcli1, targetpath2) || + !cli_rename(targetcli1, targetpath1, targetpath2)) { + + errno = eno; + TALLOC_FREE(frame); + return -1; + + } + } + + TALLOC_FREE(frame); + return 0; /* Success */ +} + diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c new file mode 100644 index 0000000000..619176697b --- /dev/null +++ b/source3/libsmb/libsmb_file.c @@ -0,0 +1,859 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Routine to open() a file ... + */ + +SMBCFILE * +SMBC_open_ctx(SMBCCTX *context, + const char *fname, + int flags, + mode_t mode) +{ + char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + SMBCSRV *srv = NULL; + SMBCFILE *file = NULL; + int fd; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return NULL; + + } + + if (!fname) { + + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + + } + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + if (errno == EPERM) errno = EACCES; + TALLOC_FREE(frame); + return NULL; /* SMBC_server sets errno */ + } + + /* Hmmm, the test for a directory is suspect here ... FIXME */ + + if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { + fd = -1; + } else { + file = SMB_MALLOC_P(SMBCFILE); + + if (!file) { + errno = ENOMEM; + TALLOC_FREE(frame); + return NULL; + } + + ZERO_STRUCTP(file); + + /*d_printf(">>>open: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + SAFE_FREE(file); + TALLOC_FREE(frame); + return NULL; + } + /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ + + if ((fd = cli_open(targetcli, targetpath, flags, + context->share_mode)) < 0) { + + /* Handle the error ... */ + + SAFE_FREE(file); + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return NULL; + + } + + /* Fill in file struct */ + + file->cli_fd = fd; + file->fname = SMB_STRDUP(fname); + file->srv = srv; + file->offset = 0; + file->file = True; + + DLIST_ADD(context->files, file); + + /* + * If the file was opened in O_APPEND mode, all write + * operations should be appended to the file. To do that, + * though, using this protocol, would require a getattrE() + * call for each and every write, to determine where the end + * of the file is. (There does not appear to be an append flag + * in the protocol.) Rather than add all of that overhead of + * retrieving the current end-of-file offset prior to each + * write operation, we'll assume that most append operations + * will continuously write, so we'll just set the offset to + * the end of the file now and hope that's adequate. + * + * Note to self: If this proves inadequate, and O_APPEND + * should, in some cases, be forced for each write, add a + * field in the context options structure, for + * "strict_append_mode" which would select between the current + * behavior (if FALSE) or issuing a getattrE() prior to each + * write and forcing the write to the end of the file (if + * TRUE). Adding that capability will likely require adding + * an "append" flag into the _SMBCFILE structure to track + * whether a file was opened in O_APPEND mode. -- djl + */ + if (flags & O_APPEND) { + if (SMBC_lseek_ctx(context, file, 0, SEEK_END) < 0) { + (void) SMBC_close_ctx(context, file); + errno = ENXIO; + TALLOC_FREE(frame); + return NULL; + } + } + + TALLOC_FREE(frame); + return file; + + } + + /* Check if opendir needed ... */ + + if (fd == -1) { + int eno = 0; + + eno = SMBC_errno(context, srv->cli); + file = (context->posix_emu.opendir_fn)(context, fname); + if (!file) errno = eno; + TALLOC_FREE(frame); + return file; + + } + + errno = EINVAL; /* FIXME, correct errno ? */ + TALLOC_FREE(frame); + return NULL; + +} + +/* + * Routine to create a file + */ + +static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ + +SMBCFILE * +SMBC_creat_ctx(SMBCCTX *context, + const char *path, + mode_t mode) +{ + + if (!context || !context->initialized) { + + errno = EINVAL; + return NULL; + + } + + return SMBC_open_ctx(context, path, creat_bits, mode); +} + +/* + * Routine to read() a file ... + */ + +ssize_t +SMBC_read_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count) +{ + int ret; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + /* + * offset: + * + * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- + * appears to pass file->offset (which is type off_t) differently than + * a local variable of type off_t. Using local variable "offset" in + * the call to cli_read() instead of file->offset fixes a problem + * retrieving data at an offset greater than 4GB. + */ + off_t offset; + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); + + if (!file || !SMBC_dlist_contains(context->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + offset = file->offset; + + /* Check that the buffer exists ... */ + + if (buf == NULL) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + /*d_printf(">>>read: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>read: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); + + if (ret < 0) { + + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + + file->offset += ret; + + DEBUG(4, (" --> %d\n", ret)); + + TALLOC_FREE(frame); + return ret; /* Success, ret bytes of data ... */ + +} + +/* + * Routine to write() a file ... + */ + +ssize_t +SMBC_write_ctx(SMBCCTX *context, + SMBCFILE *file, + void *buf, + size_t count) +{ + int ret; + off_t offset; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + /* First check all pointers before dereferencing them */ + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!file || !SMBC_dlist_contains(context->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + /* Check that the buffer exists ... */ + + if (buf == NULL) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */ + + /*d_printf(">>>write: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>write: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ + + ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); + + if (ret <= 0) { + errno = SMBC_errno(context, targetcli); + TALLOC_FREE(frame); + return -1; + + } + + file->offset += ret; + + TALLOC_FREE(frame); + return ret; /* Success, 0 bytes of data ... */ +} + +/* + * Routine to close() a file ... + */ + +int +SMBC_close_ctx(SMBCCTX *context, + SMBCFILE *file) +{ + SMBCSRV *srv; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + /* IS a dir ... */ + if (!file->file) { + TALLOC_FREE(frame); + return (context->posix_emu.closedir_fn)(context, file); + } + + /*d_printf(">>>close: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>close: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ + + if (!cli_close(targetcli, file->cli_fd)) { + + DEBUG(3, ("cli_close failed on %s. purging server.\n", + file->fname)); + /* Deallocate slot and remove the server + * from the server cache if unused */ + errno = SMBC_errno(context, targetcli); + srv = file->srv; + DLIST_REMOVE(context->files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + (context->server.remove_unused_server_fn)(context, srv); + TALLOC_FREE(frame); + return -1; + + } + + DLIST_REMOVE(context->files, file); + SAFE_FREE(file->fname); + SAFE_FREE(file); + TALLOC_FREE(frame); + + return 0; +} + +/* + * Get info from an SMB server on a file. Use a qpathinfo call first + * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo + */ +bool +SMBC_getatr(SMBCCTX * context, + SMBCSRV *srv, + char *path, + uint16 *mode, + SMB_OFF_T *size, + struct timespec *create_time_ts, + struct timespec *access_time_ts, + struct timespec *write_time_ts, + struct timespec *change_time_ts, + SMB_INO_T *ino) +{ + char *fixedpath = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + time_t write_time; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /* path fixup for . and .. */ + if (strequal(path, ".") || strequal(path, "..")) { + fixedpath = talloc_strdup(frame, "\\"); + if (!fixedpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } else { + fixedpath = talloc_strdup(frame, path); + if (!fixedpath) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + trim_string(fixedpath, NULL, "\\.."); + trim_string(fixedpath, NULL, "\\."); + } + DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); + + if (!cli_resolve_path(frame, "", srv->cli, fixedpath, + &targetcli, &targetpath)) { + d_printf("Couldn't resolve %s\n", path); + TALLOC_FREE(frame); + return False; + } + + if (!srv->no_pathinfo2 && + cli_qpathinfo2(targetcli, targetpath, + create_time_ts, + access_time_ts, + write_time_ts, + change_time_ts, + size, mode, ino)) { + TALLOC_FREE(frame); + return True; + } + + /* if this is NT then don't bother with the getatr */ + if (targetcli->capabilities & CAP_NT_SMBS) { + errno = EPERM; + TALLOC_FREE(frame); + return False; + } + + if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { + + struct timespec w_time_ts; + + w_time_ts = convert_time_t_to_timespec(write_time); + + if (write_time_ts != NULL) { + *write_time_ts = w_time_ts; + } + + if (create_time_ts != NULL) { + *create_time_ts = w_time_ts; + } + + if (access_time_ts != NULL) { + *access_time_ts = w_time_ts; + } + + if (change_time_ts != NULL) { + *change_time_ts = w_time_ts; + } + + srv->no_pathinfo2 = True; + TALLOC_FREE(frame); + return True; + } + + errno = EPERM; + TALLOC_FREE(frame); + return False; + +} + +/* + * Set file info on an SMB server. Use setpathinfo call first. If that + * fails, use setattrE.. + * + * Access and modification time parameters are always used and must be + * provided. Create time, if zero, will be determined from the actual create + * time of the file. If non-zero, the create time will be set as well. + * + * "mode" (attributes) parameter may be set to -1 if it is not to be set. + */ +bool +SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, + time_t create_time, + time_t access_time, + time_t write_time, + time_t change_time, + uint16 mode) +{ + int fd; + int ret; + TALLOC_CTX *frame = talloc_stackframe(); + + /* + * First, try setpathinfo (if qpathinfo succeeded), for it is the + * modern function for "new code" to be using, and it works given a + * filename rather than requiring that the file be opened to have its + * attributes manipulated. + */ + if (srv->no_pathinfo || + ! cli_setpathinfo(srv->cli, path, + create_time, + access_time, + write_time, + change_time, + mode)) { + + /* + * setpathinfo is not supported; go to plan B. + * + * cli_setatr() does not work on win98, and it also doesn't + * support setting the access time (only the modification + * time), so in all cases, we open the specified file and use + * cli_setattrE() which should work on all OS versions, and + * supports both times. + */ + + /* Don't try {q,set}pathinfo() again, with this server */ + srv->no_pathinfo = True; + + /* Open the file */ + if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { + + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + /* Set the new attributes */ + ret = cli_setattrE(srv->cli, fd, + change_time, + access_time, + write_time); + + /* Close the file */ + cli_close(srv->cli, fd); + + /* + * Unfortunately, setattrE() doesn't have a provision for + * setting the access mode (attributes). We'll have to try + * cli_setatr() for that, and with only this parameter, it + * seems to work on win98. + */ + if (ret && mode != (uint16) -1) { + ret = cli_setatr(srv->cli, path, mode, 0); + } + + if (! ret) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return False; + } + } + + TALLOC_FREE(frame); + return True; +} + +/* + * A routine to lseek() a file + */ + +off_t +SMBC_lseek_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t offset, + int whence) +{ + SMB_OFF_T size; + char *server = NULL, *share = NULL, *user = NULL, *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->files, file)) { + + errno = EBADF; + TALLOC_FREE(frame); + return -1; + + } + + if (!file->file) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; /* Can't lseek a dir ... */ + + } + + switch (whence) { + case SEEK_SET: + file->offset = offset; + break; + + case SEEK_CUR: + file->offset += offset; + break; + + case SEEK_END: + /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>lseek: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ + + if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, + &size, NULL, NULL, NULL, NULL, NULL)) + { + SMB_OFF_T b_size = size; + if (!cli_getattrE(targetcli, file->cli_fd, + NULL, &b_size, NULL, NULL, NULL)) + { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } else + size = b_size; + } + file->offset = size + offset; + break; + + default: + errno = EINVAL; + break; + + } + + TALLOC_FREE(frame); + return file->offset; + +} + + +/* + * Routine to truncate a file given by its file descriptor, to a specified size + */ + +int +SMBC_ftruncate_ctx(SMBCCTX *context, + SMBCFILE *file, + off_t length) +{ + SMB_OFF_T size = length; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + if (!file->file) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + if (!cli_ftruncate(targetcli, file->cli_fd, size)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; + +} diff --git a/source3/libsmb/libsmb_misc.c b/source3/libsmb/libsmb_misc.c new file mode 100644 index 0000000000..f2fd919ef6 --- /dev/null +++ b/source3/libsmb/libsmb_misc.c @@ -0,0 +1,73 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * check if an element is part of the list. + */ +int +SMBC_dlist_contains(SMBCFILE * list, SMBCFILE *p) +{ + if (!p || !list) return False; + do { + if (p == list) return True; + list = list->next; + } while (list); + return False; +} + + +/* + * Convert an SMB error into a UNIX error ... + */ +int +SMBC_errno(SMBCCTX *context, + struct cli_state *c) +{ + int ret = cli_errno(c); + + if (cli_is_dos_error(c)) { + uint8 eclass; + uint32 ecode; + + cli_dos_error(c, &eclass, &ecode); + + DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", + (int)eclass, (int)ecode, (int)ecode, ret)); + } else { + NTSTATUS status; + + status = cli_nt_error(c); + + DEBUG(3,("smbc errno %s -> %d\n", + nt_errstr(status), ret)); + } + + return ret; +} + diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c new file mode 100644 index 0000000000..2533f536c3 --- /dev/null +++ b/source3/libsmb/libsmb_path.c @@ -0,0 +1,399 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* Used by urldecode_talloc() */ +static int +hex2int( unsigned int _char ) +{ + if ( _char >= 'A' && _char <='F') + return _char - 'A' + 10; + if ( _char >= 'a' && _char <='f') + return _char - 'a' + 10; + if ( _char >= '0' && _char <='9') + return _char - '0'; + return -1; +} + +/* + * SMBC_urldecode() + * and urldecode_talloc() (internal fn.) + * + * Convert strings of %xx to their single character equivalent. Each 'x' must + * be a valid hexadecimal digit, or that % sequence is left undecoded. + * + * dest may, but need not be, the same pointer as src. + * + * Returns the number of % sequences which could not be converted due to lack + * of two following hexadecimal digits. + */ +static int +urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) +{ + int old_length = strlen(src); + int i = 0; + int err_count = 0; + size_t newlen = 1; + char *p, *dest; + + if (old_length == 0) { + return 0; + } + + *pp_dest = NULL; + for (i = 0; i < old_length; ) { + unsigned char character = src[i++]; + + if (character == '%') { + int a = i+1 < old_length ? hex2int(src[i]) : -1; + int b = i+1 < old_length ? hex2int(src[i+1]) : -1; + + /* Replace valid sequence */ + if (a != -1 && b != -1) { + /* Replace valid %xx sequence with %dd */ + character = (a * 16) + b; + if (character == '\0') { + break; /* Stop at %00 */ + } + i += 2; + } else { + err_count++; + } + } + newlen++; + } + + dest = TALLOC_ARRAY(ctx, char, newlen); + if (!dest) { + return err_count; + } + + err_count = 0; + for (p = dest, i = 0; i < old_length; ) { + unsigned char character = src[i++]; + + if (character == '%') { + int a = i+1 < old_length ? hex2int(src[i]) : -1; + int b = i+1 < old_length ? hex2int(src[i+1]) : -1; + + /* Replace valid sequence */ + if (a != -1 && b != -1) { + /* Replace valid %xx sequence with %dd */ + character = (a * 16) + b; + if (character == '\0') { + break; /* Stop at %00 */ + } + i += 2; + } else { + err_count++; + } + } + *p++ = character; + } + + *p = '\0'; + *pp_dest = dest; + return err_count; +} + +int +SMBC_urldecode(char *dest, + char *src, + size_t max_dest_len) +{ + TALLOC_CTX *frame = talloc_stackframe(); + char *pdest; + int ret = urldecode_talloc(frame, &pdest, src); + + if (pdest) { + strlcpy(dest, pdest, max_dest_len); + } + TALLOC_FREE(frame); + return ret; +} + +/* + * SMBC_urlencode() + * + * Convert any characters not specifically allowed in a URL into their %xx + * equivalent. + * + * Returns the remaining buffer length. + */ +int +SMBC_urlencode(char *dest, + char *src, + int max_dest_len) +{ + char hex[] = "0123456789ABCDEF"; + + for (; *src != '\0' && max_dest_len >= 3; src++) { + + if ((*src < '0' && + *src != '-' && + *src != '.') || + (*src > '9' && + *src < 'A') || + (*src > 'Z' && + *src < 'a' && + *src != '_') || + (*src > 'z')) { + *dest++ = '%'; + *dest++ = hex[(*src >> 4) & 0x0f]; + *dest++ = hex[*src & 0x0f]; + max_dest_len -= 3; + } else { + *dest++ = *src; + max_dest_len--; + } + } + + *dest++ = '\0'; + max_dest_len--; + + return max_dest_len; +} + +/* + * Function to parse a path and turn it into components + * + * The general format of an SMB URI is explain in Christopher Hertel's CIFS + * book, at http://ubiqx.org/cifs/Appendix-D.html. We accept a subset of the + * general format ("smb:" only; we do not look for "cifs:"). + * + * + * We accept: + * smb://[[[domain;]user[:password]@]server[/share[/path[/file]]]][?options] + * + * Meaning of URLs: + * + * smb:// Show all workgroups. + * + * The method of locating the list of workgroups varies + * depending upon the setting of the context variable + * context->browse_max_lmb_count. This value determines + * the maximum number of local master browsers to query + * for the list of workgroups. In order to ensure that + * a complete list of workgroups is obtained, all master + * browsers must be queried, but if there are many + * workgroups, the time spent querying can begin to add up. + * For small networks (not many workgroups), it is suggested + * that this variable be set to 0, indicating query all local + * master browsers. When the network has many workgroups, a + * reasonable setting for this variable might be around 3. + * + * smb://name/ if name<1D> or name<1B> exists, list servers in + * workgroup, else, if name<20> exists, list all shares + * for server ... + * + * If "options" are provided, this function returns the entire option list as a + * string, for later parsing by the caller. Note that currently, no options + * are supported. + */ + +static const char *smbc_prefix = "smb:"; + +int +SMBC_parse_path(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *fname, + char **pp_workgroup, + char **pp_server, + char **pp_share, + char **pp_path, + char **pp_user, + char **pp_password, + char **pp_options) +{ + char *s; + const char *p; + char *q, *r; + int len; + + /* Ensure these returns are at least valid pointers. */ + *pp_server = talloc_strdup(ctx, ""); + *pp_share = talloc_strdup(ctx, ""); + *pp_path = talloc_strdup(ctx, ""); + *pp_user = talloc_strdup(ctx, ""); + *pp_password = talloc_strdup(ctx, ""); + + if (!*pp_server || !*pp_share || !*pp_path || + !*pp_user || !*pp_password) { + return -1; + } + + /* + * Assume we wont find an authentication domain to parse, so default + * to the workgroup in the provided context. + */ + if (pp_workgroup != NULL) { + *pp_workgroup = talloc_strdup(ctx, context->workgroup); + } + + if (pp_options) { + *pp_options = talloc_strdup(ctx, ""); + } + s = talloc_strdup(ctx, fname); + + /* see if it has the right prefix */ + len = strlen(smbc_prefix); + if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { + return -1; /* What about no smb: ? */ + } + + p = s + len; + + /* Watch the test below, we are testing to see if we should exit */ + + if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { + DEBUG(1, ("Invalid path (does not begin with smb://")); + return -1; + } + + p += 2; /* Skip the double slash */ + + /* See if any options were specified */ + if ((q = strrchr(p, '?')) != NULL ) { + /* There are options. Null terminate here and point to them */ + *q++ = '\0'; + + DEBUG(4, ("Found options '%s'", q)); + + /* Copy the options */ + if (*pp_options != NULL) { + TALLOC_FREE(*pp_options); + *pp_options = talloc_strdup(ctx, q); + } + } + + if (*p == '\0') { + goto decoding; + } + + if (*p == '/') { + int wl = strlen(context->workgroup); + + if (wl > 16) { + wl = 16; + } + + *pp_server = talloc_strdup(ctx, context->workgroup); + if (!*pp_server) { + return -1; + } + *pp_server[wl] = '\0'; + return 0; + } + + /* + * ok, its for us. Now parse out the server, share etc. + * + * However, we want to parse out [[domain;]user[:password]@] if it + * exists ... + */ + + /* check that '@' occurs before '/', if '/' exists at all */ + q = strchr_m(p, '@'); + r = strchr_m(p, '/'); + if (q && (!r || q < r)) { + char *userinfo = NULL; + const char *u; + + next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@"); + if (!userinfo) { + return -1; + } + u = userinfo; + + if (strchr_m(u, ';')) { + char *workgroup; + next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); + if (!workgroup) { + return -1; + } + if (pp_workgroup) { + *pp_workgroup = workgroup; + } + } + + if (strchr_m(u, ':')) { + next_token_no_ltrim_talloc(ctx, &u, pp_user, ":"); + if (!*pp_user) { + return -1; + } + *pp_password = talloc_strdup(ctx, u); + if (!*pp_password) { + return -1; + } + } else { + *pp_user = talloc_strdup(ctx, u); + if (!*pp_user) { + return -1; + } + } + } + + if (!next_token_talloc(ctx, &p, pp_server, "/")) { + return -1; + } + + if (*p == (char)0) { + goto decoding; /* That's it ... */ + } + + if (!next_token_talloc(ctx, &p, pp_share, "/")) { + return -1; + } + + /* + * Prepend a leading slash if there's a file path, as required by + * NetApp filers. + */ + if (*p != '\0') { + *pp_path = talloc_asprintf(ctx, + "\\%s", + p); + } else { + *pp_path = talloc_strdup(ctx, ""); + } + if (!*pp_path) { + return -1; + } + string_replace(*pp_path, '/', '\\'); + + decoding: + + (void) urldecode_talloc(ctx, pp_path, *pp_path); + (void) urldecode_talloc(ctx, pp_server, *pp_server); + (void) urldecode_talloc(ctx, pp_share, *pp_share); + (void) urldecode_talloc(ctx, pp_user, *pp_user); + (void) urldecode_talloc(ctx, pp_password, *pp_password); + + return 0; +} + diff --git a/source3/libsmb/libsmb_printjob.c b/source3/libsmb/libsmb_printjob.c new file mode 100644 index 0000000000..f106080b6f --- /dev/null +++ b/source3/libsmb/libsmb_printjob.c @@ -0,0 +1,334 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Open a print file to be written to by other calls + */ + +SMBCFILE * +SMBC_open_print_job_ctx(SMBCCTX *context, + const char *fname) +{ + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + DEBUG(4, ("SMBC_open_print_job_ctx(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return NULL; + } + + /* What if the path is empty, or the file exists? */ + + TALLOC_FREE(frame); + return (context->posix_emu.open_fn)(context, fname, O_WRONLY, 666); +} + +/* + * Routine to print a file on a remote server ... + * + * We open the file, which we assume to be on a remote server, and then + * copy it to a print file on the share specified by printq. + */ + +int +SMBC_print_file_ctx(SMBCCTX *c_file, + const char *fname, + SMBCCTX *c_print, + const char *printq) +{ + SMBCFILE *fid1; + SMBCFILE *fid2; + int bytes; + int saverr; + int tot_bytes = 0; + char buf[4096]; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!c_file || !c_file->initialized || + !c_print || !c_print->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + if (!fname && !printq) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + /* Try to open the file for reading ... */ + + if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname, O_RDONLY, 0666)) < 0) { + DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); + TALLOC_FREE(frame); + return -1; /* smbc_open sets errno */ + } + + /* Now, try to open the printer file for writing */ + + if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print, printq)) < 0) { + + saverr = errno; /* Save errno */ + smbc_getFunctionClose(c_file)(c_file, fid1); + errno = saverr; + TALLOC_FREE(frame); + return -1; + + } + + while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1, + buf, sizeof(buf))) > 0) { + + tot_bytes += bytes; + + if ((smbc_getFunctionWrite(c_print)(c_print, fid2, + buf, bytes)) < 0) { + + saverr = errno; + smbc_getFunctionClose(c_file)(c_file, fid1); + smbc_getFunctionClose(c_print)(c_print, fid2); + errno = saverr; + + } + + } + + saverr = errno; + + smbc_getFunctionClose(c_file)(c_file, fid1); /* We have to close these anyway */ + smbc_getFunctionClose(c_print)(c_print, fid2); + + if (bytes < 0) { + + errno = saverr; + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return tot_bytes; + +} + +/* + * Routine to list print jobs on a printer share ... + */ + +int +SMBC_list_print_jobs_ctx(SMBCCTX *context, + const char *fname, + smbc_list_print_job_fn fn) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (cli_print_queue(srv->cli, + (void (*)(struct print_job_info *))fn) < 0) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + TALLOC_FREE(frame); + return 0; + +} + +/* + * Delete a print job from a remote printer share + */ + +int +SMBC_unlink_print_job_ctx(SMBCCTX *context, + const char *fname, + int id) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + int err; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + + } + + if ((err = cli_printjob_del(srv->cli, id)) != 0) { + + if (err < 0) + errno = SMBC_errno(context, srv->cli); + else if (err == ERRnosuchprintjob) + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + + } + + TALLOC_FREE(frame); + return 0; + +} + diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c new file mode 100644 index 0000000000..978a843d30 --- /dev/null +++ b/source3/libsmb/libsmb_server.c @@ -0,0 +1,675 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Check a server for being alive and well. + * returns 0 if the server is in shape. Returns 1 on error + * + * Also useable outside libsmbclient to enable external cache + * to do some checks too. + */ +int +SMBC_check_server(SMBCCTX * context, + SMBCSRV * server) +{ + socklen_t size; + struct sockaddr addr; + + size = sizeof(addr); + return (getpeername(server->cli->fd, &addr, &size) == -1); +} + +/* + * Remove a server from the cached server list it's unused. + * On success, 0 is returned. 1 is returned if the server could not be removed. + * + * Also useable outside libsmbclient + */ +int +SMBC_remove_unused_server(SMBCCTX * context, + SMBCSRV * srv) +{ + SMBCFILE * file; + + /* are we being fooled ? */ + if (!context || !context->initialized || !srv) { + return 1; + } + + /* Check all open files/directories for a relation with this server */ + for (file = context->files; file; file = file->next) { + if (file->srv == srv) { + /* Still used */ + DEBUG(3, ("smbc_remove_usused_server: " + "%p still used by %p.\n", + srv, file)); + return 1; + } + } + + DLIST_REMOVE(context->servers, srv); + + cli_shutdown(srv->cli); + srv->cli = NULL; + + DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); + + (context->cache.remove_cached_server_fn)(context, srv); + + SAFE_FREE(srv); + return 0; +} + +/**************************************************************** + * Call the auth_fn with fixed size (fstring) buffers. + ***************************************************************/ +void +SMBC_call_auth_fn(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + fstring workgroup; + fstring username; + fstring password; + + strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); + strlcpy(username, *pp_username, sizeof(username)); + strlcpy(password, *pp_password, sizeof(password)); + + (context->server.get_auth_data_fn)( + server, share, + workgroup, sizeof(workgroup), + username, sizeof(username), + password, sizeof(password)); + + TALLOC_FREE(*pp_workgroup); + TALLOC_FREE(*pp_username); + TALLOC_FREE(*pp_password); + + *pp_workgroup = talloc_strdup(ctx, workgroup); + *pp_username = talloc_strdup(ctx, username); + *pp_password = talloc_strdup(ctx, password); +} + + +void +SMBC_get_auth_data(const char *server, const char *share, + char *workgroup_buf, int workgroup_buf_len, + char *username_buf, int username_buf_len, + char *password_buf, int password_buf_len) +{ + /* Default function just uses provided data. Nothing to do. */ +} + + + +SMBCSRV * +SMBC_find_server(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + SMBCSRV *srv; + int auth_called = 0; + + check_server_cache: + + srv = (context->cache.get_cached_server_fn)(context, + server, share, + *pp_workgroup, + *pp_username); + + if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] || + !*pp_password || !(*pp_password)[0])) { + SMBC_call_auth_fn(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + + if (!pp_workgroup || !pp_username || !pp_password) { + return NULL; + } + + /* + * However, smbc_auth_fn may have picked up info relating to + * an existing connection, so try for an existing connection + * again ... + */ + auth_called = 1; + goto check_server_cache; + + } + + if (srv) { + if ((context->server.check_server_fn)(context, srv)) { + /* + * This server is no good anymore + * Try to remove it and check for more possible + * servers in the cache + */ + if ((context->server.remove_unused_server_fn)(context, + srv)) { + /* + * We could not remove the server completely, + * remove it from the cache so we will not get + * it again. It will be removed when the last + * file/dir is closed. + */ + (context->cache.remove_cached_server_fn)(context, + srv); + } + + /* + * Maybe there are more cached connections to this + * server + */ + goto check_server_cache; + } + + return srv; + } + + return NULL; +} + +/* + * Connect to a server, possibly on an existing connection + * + * Here, what we want to do is: If the server and username + * match an existing connection, reuse that, otherwise, establish a + * new connection. + * + * If we have to create a new connection, call the auth_fn to get the + * info we need, unless the username and password were passed in. + */ + +SMBCSRV * +SMBC_server(TALLOC_CTX *ctx, + SMBCCTX *context, + bool connect_if_not_found, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + SMBCSRV *srv=NULL; + struct cli_state *c; + struct nmb_name called, calling; + const char *server_n = server; + struct sockaddr_storage ss; + int tried_reverse = 0; + int port_try_first; + int port_try_next; + const char *username_used; + NTSTATUS status; + + zero_addr(&ss); + ZERO_STRUCT(c); + + if (server[0] == 0) { + errno = EPERM; + return NULL; + } + + /* Look for a cached connection */ + srv = SMBC_find_server(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + + /* + * If we found a connection and we're only allowed one share per + * server... + */ + if (srv && *share != '\0' && context->one_share_per_server) { + + /* + * ... then if there's no current connection to the share, + * connect to it. SMBC_find_server(), or rather the function + * pointed to by context->cache.get_cached_srv_fn which + * was called by SMBC_find_server(), will have issued a tree + * disconnect if the requested share is not the same as the + * one that was already connected. + */ + if (srv->cli->cnum == (uint16) -1) { + /* Ensure we have accurate auth info */ + SMBC_call_auth_fn(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + cli_shutdown(srv->cli); + srv->cli = NULL; + (context->cache.remove_cached_server_fn)(context, + srv); + return NULL; + } + + /* + * We don't need to renegotiate encryption + * here as the encryption context is not per + * tid. + */ + + if (!cli_send_tconX(srv->cli, share, "?????", + *pp_password, + strlen(*pp_password)+1)) { + + errno = SMBC_errno(context, srv->cli); + cli_shutdown(srv->cli); + srv->cli = NULL; + (context->cache.remove_cached_server_fn)(context, + srv); + srv = NULL; + } + + /* + * Regenerate the dev value since it's based on both + * server and share + */ + if (srv) { + srv->dev = (dev_t)(str_checksum(server) ^ + str_checksum(share)); + } + } + } + + /* If we have a connection... */ + if (srv) { + + /* ... then we're done here. Give 'em what they came for. */ + return srv; + } + + /* If we're not asked to connect when a connection doesn't exist... */ + if (! connect_if_not_found) { + /* ... then we're done here. */ + return NULL; + } + + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + return NULL; + } + + make_nmb_name(&calling, context->netbios_name, 0x0); + make_nmb_name(&called , server, 0x20); + + DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server)); + + DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); + + again: + + zero_addr(&ss); + + /* have to open a new connection */ + if ((c = cli_initialise()) == NULL) { + errno = ENOMEM; + return NULL; + } + + if (context->use_kerberos) { + c->use_kerberos = True; + } + if (context->fallback_after_kerberos) { + c->fallback_after_kerberos = True; + } + + c->timeout = context->timeout; + + /* + * Force use of port 139 for first try if share is $IPC, empty, or + * null, so browse lists can work + */ + if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) { + port_try_first = 139; + port_try_next = 445; + } else { + port_try_first = 445; + port_try_next = 139; + } + + c->port = port_try_first; + + status = cli_connect(c, server_n, &ss); + if (!NT_STATUS_IS_OK(status)) { + + /* First connection attempt failed. Try alternate port. */ + c->port = port_try_next; + + status = cli_connect(c, server_n, &ss); + if (!NT_STATUS_IS_OK(status)) { + cli_shutdown(c); + errno = ETIMEDOUT; + return NULL; + } + } + + if (!cli_session_request(c, &calling, &called)) { + cli_shutdown(c); + if (strcmp(called.name, "*SMBSERVER")) { + make_nmb_name(&called , "*SMBSERVER", 0x20); + goto again; + } else { /* Try one more time, but ensure we don't loop */ + + /* Only try this if server is an IP address ... */ + + if (is_ipaddress(server) && !tried_reverse) { + fstring remote_name; + struct sockaddr_storage rem_ss; + + if (!interpret_string_addr(&rem_ss, server, + NI_NUMERICHOST)) { + DEBUG(4, ("Could not convert IP address " + "%s to struct sockaddr_storage\n", + server)); + errno = ETIMEDOUT; + return NULL; + } + + tried_reverse++; /* Yuck */ + + if (name_status_find("*", 0, 0, &rem_ss, remote_name)) { + make_nmb_name(&called, remote_name, 0x20); + goto again; + } + } + } + errno = ETIMEDOUT; + return NULL; + } + + DEBUG(4,(" session request ok\n")); + + if (!cli_negprot(c)) { + cli_shutdown(c); + errno = ETIMEDOUT; + return NULL; + } + + username_used = *pp_username; + + if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, + *pp_password, strlen(*pp_password), + *pp_password, strlen(*pp_password), + *pp_workgroup))) { + + /* Failed. Try an anonymous login, if allowed by flags. */ + username_used = ""; + + if (context->no_auto_anonymous_login || + !NT_STATUS_IS_OK(cli_session_setup(c, username_used, + *pp_password, 1, + *pp_password, 0, + *pp_workgroup))) { + + cli_shutdown(c); + errno = EPERM; + return NULL; + } + } + + DEBUG(4,(" session setup ok\n")); + + if (!cli_send_tconX(c, share, "?????", + *pp_password, strlen(*pp_password)+1)) { + errno = SMBC_errno(context, c); + cli_shutdown(c); + return NULL; + } + + DEBUG(4,(" tconx ok\n")); + + if (context->smb_encryption_level) { + /* Attempt UNIX smb encryption. */ + if (!NT_STATUS_IS_OK(cli_force_encryption(c, + username_used, + *pp_password, + *pp_workgroup))) { + + /* + * context->smb_encryption_level == 1 + * means don't fail if encryption can't be negotiated, + * == 2 means fail if encryption can't be negotiated. + */ + + DEBUG(4,(" SMB encrypt failed\n")); + + if (context->smb_encryption_level == 2) { + cli_shutdown(c); + errno = EPERM; + return NULL; + } + } + DEBUG(4,(" SMB encrypt ok\n")); + } + + /* + * Ok, we have got a nice connection + * Let's allocate a server structure. + */ + + srv = SMB_MALLOC_P(SMBCSRV); + if (!srv) { + errno = ENOMEM; + goto failed; + } + + ZERO_STRUCTP(srv); + srv->cli = c; + srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); + srv->no_pathinfo = False; + srv->no_pathinfo2 = False; + srv->no_nt_session = False; + + /* now add it to the cache (internal or external) */ + /* Let the cache function set errno if it wants to */ + errno = 0; + if ((context->cache.add_cached_server_fn)(context, srv, + server, share, + *pp_workgroup, + *pp_username)) { + int saved_errno = errno; + DEBUG(3, (" Failed to add server to cache\n")); + errno = saved_errno; + if (errno == 0) { + errno = ENOMEM; + } + goto failed; + } + + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", + server, share, srv)); + + DLIST_ADD(context->servers, srv); + return srv; + + failed: + cli_shutdown(c); + if (!srv) { + return NULL; + } + + SAFE_FREE(srv); + return NULL; +} + +/* + * Connect to a server for getting/setting attributes, possibly on an existing + * connection. This works similarly to SMBC_server(). + */ +SMBCSRV * +SMBC_attr_server(TALLOC_CTX *ctx, + SMBCCTX *context, + const char *server, + const char *share, + char **pp_workgroup, + char **pp_username, + char **pp_password) +{ + int flags; + struct sockaddr_storage ss; + struct cli_state *ipc_cli; + struct rpc_pipe_client *pipe_hnd; + NTSTATUS nt_status; + SMBCSRV *ipc_srv=NULL; + + /* + * See if we've already created this special connection. Reference + * our "special" share name '*IPC$', which is an impossible real share + * name due to the leading asterisk. + */ + ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", + pp_workgroup, pp_username, pp_password); + if (!ipc_srv) { + + /* We didn't find a cached connection. Get the password */ + if (!*pp_password || (*pp_password)[0] == '\0') { + /* ... then retrieve it now. */ + SMBC_call_auth_fn(ctx, context, server, share, + pp_workgroup, pp_username, pp_password); + if (!*pp_workgroup || !*pp_username || !*pp_password) { + errno = ENOMEM; + return NULL; + } + } + + flags = 0; + if (context->use_kerberos) { + flags |= CLI_FULL_CONNECTION_USE_KERBEROS; + } + + zero_addr(&ss); + nt_status = cli_full_connection(&ipc_cli, + global_myname(), server, + &ss, 0, "IPC$", "?????", + *pp_username, + *pp_workgroup, + *pp_password, + flags, + Undefined, NULL); + if (! NT_STATUS_IS_OK(nt_status)) { + DEBUG(1,("cli_full_connection failed! (%s)\n", + nt_errstr(nt_status))); + errno = ENOTSUP; + return NULL; + } + + if (context->smb_encryption_level) { + /* Attempt UNIX smb encryption. */ + if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, + *pp_username, + *pp_password, + *pp_workgroup))) { + + /* + * context->smb_encryption_level == + * 1 means don't fail if encryption can't be + * negotiated, == 2 means fail if encryption + * can't be negotiated. + */ + + DEBUG(4,(" SMB encrypt failed on IPC$\n")); + + if (context->smb_encryption_level == 2) { + cli_shutdown(ipc_cli); + errno = EPERM; + return NULL; + } + } + DEBUG(4,(" SMB encrypt ok on IPC$\n")); + } + + ipc_srv = SMB_MALLOC_P(SMBCSRV); + if (!ipc_srv) { + errno = ENOMEM; + cli_shutdown(ipc_cli); + return NULL; + } + + ZERO_STRUCTP(ipc_srv); + ipc_srv->cli = ipc_cli; + + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, + PI_LSARPC, + &nt_status); + if (!pipe_hnd) { + DEBUG(1, ("cli_nt_session_open fail!\n")); + errno = ENOTSUP; + cli_shutdown(ipc_srv->cli); + free(ipc_srv); + return NULL; + } + + /* + * Some systems don't support + * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 + * so we might as well do it too. + */ + + nt_status = rpccli_lsa_open_policy( + pipe_hnd, + talloc_tos(), + True, + GENERIC_EXECUTE_ACCESS, + &ipc_srv->pol); + + if (!NT_STATUS_IS_OK(nt_status)) { + errno = SMBC_errno(context, ipc_srv->cli); + cli_shutdown(ipc_srv->cli); + return NULL; + } + + /* now add it to the cache (internal or external) */ + + errno = 0; /* let cache function set errno if it likes */ + if ((context->cache.add_cached_server_fn)(context, ipc_srv, + server, + "*IPC$", + *pp_workgroup, + *pp_username)) { + DEBUG(3, (" Failed to add server to cache\n")); + if (errno == 0) { + errno = ENOMEM; + } + cli_shutdown(ipc_srv->cli); + free(ipc_srv); + return NULL; + } + + DLIST_ADD(context->servers, ipc_srv); + } + + return ipc_srv; +} diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c new file mode 100644 index 0000000000..06238863b7 --- /dev/null +++ b/source3/libsmb/libsmb_stat.c @@ -0,0 +1,302 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Generate an inode number from file name for those things that need it + */ + +static ino_t +generate_inode(SMBCCTX *context, + const char *name) +{ + if (!context || !context->initialized) { + + errno = EINVAL; + return -1; + + } + + if (!*name) return 2; /* FIXME, why 2 ??? */ + return (ino_t)str_checksum(name); + +} + +/* + * Routine to put basic stat info into a stat structure ... Used by stat and + * fstat below. + */ + +static int +setup_stat(SMBCCTX *context, + struct stat *st, + char *fname, + SMB_OFF_T size, + int mode) +{ + TALLOC_CTX *frame = talloc_stackframe(); + + st->st_mode = 0; + + if (IS_DOS_DIR(mode)) { + st->st_mode = SMBC_DIR_MODE; + } else { + st->st_mode = SMBC_FILE_MODE; + } + + if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; + if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; + if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; + if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; + + st->st_size = size; +#ifdef HAVE_STAT_ST_BLKSIZE + st->st_blksize = 512; +#endif +#ifdef HAVE_STAT_ST_BLOCKS + st->st_blocks = (size+511)/512; +#endif +#ifdef HAVE_STRUCT_STAT_ST_RDEV + st->st_rdev = 0; +#endif + st->st_uid = getuid(); + st->st_gid = getgid(); + + if (IS_DOS_DIR(mode)) { + st->st_nlink = 2; + } else { + st->st_nlink = 1; + } + + if (st->st_ino == 0) { + st->st_ino = generate_inode(context, fname); + } + + TALLOC_FREE(frame); + return True; /* FIXME: Is this needed ? */ + +} + +/* + * Routine to stat a file given a name + */ + +int +SMBC_stat_ctx(SMBCCTX *context, + const char *fname, + struct stat *st) +{ + SMBCSRV *srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + SMB_OFF_T size = 0; + uint16 mode = 0; + SMB_INO_T ino = 0; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_stat(%s)\n", fname)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame,context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (!SMBC_getatr(context, srv, path, &mode, &size, + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + errno = SMBC_errno(context, srv->cli); + TALLOC_FREE(frame); + return -1; + } + + st->st_ino = ino; + + setup_stat(context, st, (char *) fname, size, mode); + + set_atimespec(st, access_time_ts); + set_ctimespec(st, change_time_ts); + set_mtimespec(st, write_time_ts); + st->st_dev = srv->dev; + + TALLOC_FREE(frame); + return 0; + +} + +/* + * Routine to stat a file given an fd + */ + +int +SMBC_fstat_ctx(SMBCCTX *context, + SMBCFILE *file, + struct stat *st) +{ + struct timespec change_time_ts; + struct timespec access_time_ts; + struct timespec write_time_ts; + SMB_OFF_T size; + uint16 mode; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *path = NULL; + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + SMB_INO_T ino = 0; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!file || !SMBC_dlist_contains(context->files, file)) { + errno = EBADF; + TALLOC_FREE(frame); + return -1; + } + + if (!file->file) { + TALLOC_FREE(frame); + return (context->posix_emu.fstatdir_fn)(context, file, st); + } + + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ + if (SMBC_parse_path(frame, + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + /*d_printf(">>>fstat: resolving %s\n", path);*/ + if (!cli_resolve_path(frame, "", file->srv->cli, path, + &targetcli, &targetpath)) { + d_printf("Could not resolve %s\n", path); + TALLOC_FREE(frame); + return -1; + } + /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ + + if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, + NULL, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + + time_t change_time, access_time, write_time; + + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, + &change_time, &access_time, &write_time)) { + + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + change_time_ts = convert_time_t_to_timespec(change_time); + access_time_ts = convert_time_t_to_timespec(access_time); + write_time_ts = convert_time_t_to_timespec(write_time); + } + + st->st_ino = ino; + + setup_stat(context, st, file->fname, size, mode); + + set_atimespec(st, access_time_ts); + set_ctimespec(st, change_time_ts); + set_mtimespec(st, write_time_ts); + st->st_dev = file->srv->dev; + + TALLOC_FREE(frame); + return 0; + +} diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c new file mode 100644 index 0000000000..93ca0706b2 --- /dev/null +++ b/source3/libsmb/libsmb_xattr.c @@ -0,0 +1,2293 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/* + * Find an lsa pipe handle associated with a cli struct. + */ +static struct rpc_pipe_client * +find_lsa_pipe_hnd(struct cli_state *ipc_cli) +{ + struct rpc_pipe_client *pipe_hnd; + + for (pipe_hnd = ipc_cli->pipe_list; + pipe_hnd; + pipe_hnd = pipe_hnd->next) { + + if (pipe_hnd->pipe_idx == PI_LSARPC) { + return pipe_hnd; + } + } + + return NULL; +} + +/* + * Sort ACEs according to the documentation at + * http://support.microsoft.com/kb/269175, at least as far as it defines the + * order. + */ + +static int +ace_compare(SEC_ACE *ace1, + SEC_ACE *ace2) +{ + bool b1; + bool b2; + + /* If the ACEs are equal, we have nothing more to do. */ + if (sec_ace_equal(ace1, ace2)) { + return 0; + } + + /* Inherited follow non-inherited */ + b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); + b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * What shall we do with AUDITs and ALARMs? It's undefined. We'll + * sort them after DENY and ALLOW. + */ + b1 = (ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED && + ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && + ace1->type != SEC_ACE_TYPE_ACCESS_DENIED && + ace1->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + b2 = (ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED && + ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && + ace2->type != SEC_ACE_TYPE_ACCESS_DENIED && + ace2->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* Allowed ACEs follow denied ACEs */ + b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || + ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); + b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED || + ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * ACEs applying to an entity's object follow those applying to the + * entity itself + */ + b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || + ace2->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); + if (b1 != b2) { + return (b1 ? 1 : -1); + } + + /* + * If we get this far, the ACEs are similar as far as the + * characteristics we typically care about (those defined by the + * referenced MS document). We'll now sort by characteristics that + * just seems reasonable. + */ + + if (ace1->type != ace2->type) { + return ace2->type - ace1->type; + } + + if (sid_compare(&ace1->trustee, &ace2->trustee)) { + return sid_compare(&ace1->trustee, &ace2->trustee); + } + + if (ace1->flags != ace2->flags) { + return ace1->flags - ace2->flags; + } + + if (ace1->access_mask != ace2->access_mask) { + return ace1->access_mask - ace2->access_mask; + } + + if (ace1->size != ace2->size) { + return ace1->size - ace2->size; + } + + return memcmp(ace1, ace2, sizeof(SEC_ACE)); +} + + +static void +sort_acl(SEC_ACL *the_acl) +{ + uint32 i; + if (!the_acl) return; + + qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), + QSORT_CAST ace_compare); + + for (i=1;inum_aces;) { + if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { + int j; + for (j=i; jnum_aces-1; j++) { + the_acl->aces[j] = the_acl->aces[j+1]; + } + the_acl->num_aces--; + } else { + i++; + } + } +} + +/* convert a SID to a string, either numeric or username/group */ +static void +convert_sid_to_string(struct cli_state *ipc_cli, + POLICY_HND *pol, + fstring str, + bool numeric, + DOM_SID *sid) +{ + char **domains = NULL; + char **names = NULL; + enum lsa_SidType *types = NULL; + struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); + TALLOC_CTX *ctx; + + sid_to_fstring(str, sid); + + if (numeric) { + return; /* no lookup desired */ + } + + if (!pipe_hnd) { + return; + } + + /* Ask LSA to convert the sid to a name */ + + ctx = talloc_stackframe(); + + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, + pol, 1, sid, &domains, + &names, &types)) || + !domains || !domains[0] || !names || !names[0]) { + TALLOC_FREE(ctx); + return; + } + + TALLOC_FREE(ctx); + /* Converted OK */ + + slprintf(str, sizeof(fstring) - 1, "%s%s%s", + domains[0], lp_winbind_separator(), + names[0]); +} + +/* convert a string to a SID, either numeric or username/group */ +static bool +convert_string_to_sid(struct cli_state *ipc_cli, + POLICY_HND *pol, + bool numeric, + DOM_SID *sid, + const char *str) +{ + enum lsa_SidType *types = NULL; + DOM_SID *sids = NULL; + bool result = True; + TALLOC_CTX *ctx = NULL; + struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); + + if (!pipe_hnd) { + return False; + } + + if (numeric) { + if (strncmp(str, "S-", 2) == 0) { + return string_to_sid(sid, str); + } + + result = False; + goto done; + } + + ctx = talloc_stackframe(); + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, + pol, 1, &str, NULL, 1, &sids, + &types))) { + result = False; + goto done; + } + + sid_copy(sid, &sids[0]); + done: + + TALLOC_FREE(ctx); + return result; +} + + +/* parse an ACE in the same format as print_ace() */ +static bool +parse_ace(struct cli_state *ipc_cli, + POLICY_HND *pol, + SEC_ACE *ace, + bool numeric, + char *str) +{ + char *p; + const char *cp; + char *tok; + unsigned int atype; + unsigned int aflags; + unsigned int amask; + DOM_SID sid; + SEC_ACCESS mask; + const struct perm_value *v; + struct perm_value { + const char *perm; + uint32 mask; + }; + TALLOC_CTX *frame = talloc_stackframe(); + + /* These values discovered by inspection */ + static const struct perm_value special_values[] = { + { "R", 0x00120089 }, + { "W", 0x00120116 }, + { "X", 0x001200a0 }, + { "D", 0x00010000 }, + { "P", 0x00040000 }, + { "O", 0x00080000 }, + { NULL, 0 }, + }; + + static const struct perm_value standard_values[] = { + { "READ", 0x001200a9 }, + { "CHANGE", 0x001301bf }, + { "FULL", 0x001f01ff }, + { NULL, 0 }, + }; + + + ZERO_STRUCTP(ace); + p = strchr_m(str,':'); + if (!p) { + TALLOC_FREE(frame); + return False; + } + *p = '\0'; + p++; + /* Try to parse numeric form */ + + if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && + convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { + goto done; + } + + /* Try to parse text form */ + + if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { + TALLOC_FREE(frame); + return false; + } + + cp = p; + if (!next_token_talloc(frame, &cp, &tok, "/")) { + TALLOC_FREE(frame); + return false; + } + + if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { + atype = SEC_ACE_TYPE_ACCESS_ALLOWED; + } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { + atype = SEC_ACE_TYPE_ACCESS_DENIED; + } else { + TALLOC_FREE(frame); + return false; + } + + /* Only numeric form accepted for flags at present */ + + if (!(next_token_talloc(frame, &cp, &tok, "/") && + sscanf(tok, "%i", &aflags))) { + TALLOC_FREE(frame); + return false; + } + + if (!next_token_talloc(frame, &cp, &tok, "/")) { + TALLOC_FREE(frame); + return false; + } + + if (strncmp(tok, "0x", 2) == 0) { + if (sscanf(tok, "%i", &amask) != 1) { + TALLOC_FREE(frame); + return false; + } + goto done; + } + + for (v = standard_values; v->perm; v++) { + if (strcmp(tok, v->perm) == 0) { + amask = v->mask; + goto done; + } + } + + p = tok; + + while(*p) { + bool found = False; + + for (v = special_values; v->perm; v++) { + if (v->perm[0] == *p) { + amask |= v->mask; + found = True; + } + } + + if (!found) { + TALLOC_FREE(frame); + return false; + } + p++; + } + + if (*p) { + TALLOC_FREE(frame); + return false; + } + + done: + mask = amask; + init_sec_ace(ace, &sid, atype, mask, aflags); + TALLOC_FREE(frame); + return true; +} + +/* add an ACE to a list of ACEs in a SEC_ACL */ +static bool +add_ace(SEC_ACL **the_acl, + SEC_ACE *ace, + TALLOC_CTX *ctx) +{ + SEC_ACL *newacl; + SEC_ACE *aces; + + if (! *the_acl) { + (*the_acl) = make_sec_acl(ctx, 3, 1, ace); + return True; + } + + if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { + return False; + } + memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); + memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); + newacl = make_sec_acl(ctx, (*the_acl)->revision, + 1+(*the_acl)->num_aces, aces); + SAFE_FREE(aces); + (*the_acl) = newacl; + return True; +} + + +/* parse a ascii version of a security descriptor */ +static SEC_DESC * +sec_desc_parse(TALLOC_CTX *ctx, + struct cli_state *ipc_cli, + POLICY_HND *pol, + bool numeric, + char *str) +{ + const char *p = str; + char *tok; + SEC_DESC *ret = NULL; + size_t sd_size; + DOM_SID *group_sid=NULL; + DOM_SID *owner_sid=NULL; + SEC_ACL *dacl=NULL; + int revision=1; + + while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { + + if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { + revision = strtol(tok+9, NULL, 16); + continue; + } + + if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { + if (owner_sid) { + DEBUG(5, ("OWNER specified more than once!\n")); + goto done; + } + owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!owner_sid || + !convert_string_to_sid(ipc_cli, pol, + numeric, + owner_sid, tok+6)) { + DEBUG(5, ("Failed to parse owner sid\n")); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { + if (owner_sid) { + DEBUG(5, ("OWNER specified more than once!\n")); + goto done; + } + owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!owner_sid || + !convert_string_to_sid(ipc_cli, pol, + False, + owner_sid, tok+7)) { + DEBUG(5, ("Failed to parse owner sid\n")); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { + if (group_sid) { + DEBUG(5, ("GROUP specified more than once!\n")); + goto done; + } + group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!group_sid || + !convert_string_to_sid(ipc_cli, pol, + numeric, + group_sid, tok+6)) { + DEBUG(5, ("Failed to parse group sid\n")); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { + if (group_sid) { + DEBUG(5, ("GROUP specified more than once!\n")); + goto done; + } + group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); + if (!group_sid || + !convert_string_to_sid(ipc_cli, pol, + False, + group_sid, tok+6)) { + DEBUG(5, ("Failed to parse group sid\n")); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"ACL:", 4) == 0) { + SEC_ACE ace; + if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { + DEBUG(5, ("Failed to parse ACL %s\n", tok)); + goto done; + } + if(!add_ace(&dacl, &ace, ctx)) { + DEBUG(5, ("Failed to add ACL %s\n", tok)); + goto done; + } + continue; + } + + if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { + SEC_ACE ace; + if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { + DEBUG(5, ("Failed to parse ACL %s\n", tok)); + goto done; + } + if(!add_ace(&dacl, &ace, ctx)) { + DEBUG(5, ("Failed to add ACL %s\n", tok)); + goto done; + } + continue; + } + + DEBUG(5, ("Failed to parse security descriptor\n")); + goto done; + } + + ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, + owner_sid, group_sid, NULL, dacl, &sd_size); + + done: + SAFE_FREE(group_sid); + SAFE_FREE(owner_sid); + + return ret; +} + + +/* Obtain the current dos attributes */ +static DOS_ATTR_DESC * +dos_attr_query(SMBCCTX *context, + TALLOC_CTX *ctx, + const char *filename, + SMBCSRV *srv) +{ + struct timespec create_time_ts; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + SMB_OFF_T size = 0; + uint16 mode = 0; + SMB_INO_T inode = 0; + DOS_ATTR_DESC *ret; + + ret = TALLOC_P(ctx, DOS_ATTR_DESC); + if (!ret) { + errno = ENOMEM; + return NULL; + } + + /* Obtain the DOS attributes */ + if (!SMBC_getatr(context, srv, CONST_DISCARD(char *, filename), + &mode, &size, + &create_time_ts, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &inode)) { + errno = SMBC_errno(context, srv->cli); + DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); + return NULL; + } + + ret->mode = mode; + ret->size = size; + ret->create_time = convert_timespec_to_time_t(create_time_ts); + ret->access_time = convert_timespec_to_time_t(access_time_ts); + ret->write_time = convert_timespec_to_time_t(write_time_ts); + ret->change_time = convert_timespec_to_time_t(change_time_ts); + ret->inode = inode; + + return ret; +} + + +/* parse a ascii version of a security descriptor */ +static void +dos_attr_parse(SMBCCTX *context, + DOS_ATTR_DESC *dad, + SMBCSRV *srv, + char *str) +{ + int n; + const char *p = str; + char *tok = NULL; + TALLOC_CTX *frame = NULL; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + + /* Determine whether to use old-style or new-style attribute names */ + if (context->full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "CREATE_TIME"; + attr_strings.access_time_attr = "ACCESS_TIME"; + attr_strings.write_time_attr = "WRITE_TIME"; + attr_strings.change_time_attr = "CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "A_TIME"; + attr_strings.write_time_attr = "M_TIME"; + attr_strings.change_time_attr = "C_TIME"; + } + + /* if this is to set the entire ACL... */ + if (*str == '*') { + /* ... then increment past the first colon if there is one */ + if ((p = strchr(str, ':')) != NULL) { + ++p; + } else { + p = str; + } + } + + frame = talloc_stackframe(); + while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { + if (StrnCaseCmp(tok, "MODE:", 5) == 0) { + long request = strtol(tok+5, NULL, 16); + if (request == 0) { + dad->mode = (request | + (IS_DOS_DIR(dad->mode) + ? FILE_ATTRIBUTE_DIRECTORY + : FILE_ATTRIBUTE_NORMAL)); + } else { + dad->mode = request; + } + continue; + } + + if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { + dad->size = (SMB_OFF_T)atof(tok+5); + continue; + } + + n = strlen(attr_strings.access_time_attr); + if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { + dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); + continue; + } + + n = strlen(attr_strings.change_time_attr); + if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { + dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); + continue; + } + + n = strlen(attr_strings.write_time_attr); + if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { + dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); + continue; + } + + if (attr_strings.create_time_attr != NULL) { + n = strlen(attr_strings.create_time_attr); + if (StrnCaseCmp(tok, attr_strings.create_time_attr, + n) == 0) { + dad->create_time = (time_t)strtol(tok+n+1, + NULL, 10); + continue; + } + } + + if (StrnCaseCmp(tok, "INODE:", 6) == 0) { + dad->inode = (SMB_INO_T)atof(tok+6); + continue; + } + } + TALLOC_FREE(frame); +} + +/***************************************************** + Retrieve the acls for a file. +*******************************************************/ + +static int +cacl_get(SMBCCTX *context, + TALLOC_CTX *ctx, + SMBCSRV *srv, + struct cli_state *ipc_cli, + POLICY_HND *pol, + char *filename, + char *attr_name, + char *buf, + int bufsize) +{ + uint32 i; + int n = 0; + int n_used; + bool all; + bool all_nt; + bool all_nt_acls; + bool all_dos; + bool some_nt; + bool some_dos; + bool exclude_nt_revision = False; + bool exclude_nt_owner = False; + bool exclude_nt_group = False; + bool exclude_nt_acl = False; + bool exclude_dos_mode = False; + bool exclude_dos_size = False; + bool exclude_dos_create_time = False; + bool exclude_dos_access_time = False; + bool exclude_dos_write_time = False; + bool exclude_dos_change_time = False; + bool exclude_dos_inode = False; + bool numeric = True; + bool determine_size = (bufsize == 0); + int fnum = -1; + SEC_DESC *sd; + fstring sidstr; + fstring name_sandbox; + char *name; + char *pExclude; + char *p; + struct timespec create_time_ts; + struct timespec write_time_ts; + struct timespec access_time_ts; + struct timespec change_time_ts; + time_t create_time = (time_t)0; + time_t write_time = (time_t)0; + time_t access_time = (time_t)0; + time_t change_time = (time_t)0; + SMB_OFF_T size = 0; + uint16 mode = 0; + SMB_INO_T ino = 0; + struct cli_state *cli = srv->cli; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } excl_attr_strings; + + /* Determine whether to use old-style or new-style attribute names */ + if (context->full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "CREATE_TIME"; + attr_strings.access_time_attr = "ACCESS_TIME"; + attr_strings.write_time_attr = "WRITE_TIME"; + attr_strings.change_time_attr = "CHANGE_TIME"; + + excl_attr_strings.create_time_attr = "CREATE_TIME"; + excl_attr_strings.access_time_attr = "ACCESS_TIME"; + excl_attr_strings.write_time_attr = "WRITE_TIME"; + excl_attr_strings.change_time_attr = "CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "A_TIME"; + attr_strings.write_time_attr = "M_TIME"; + attr_strings.change_time_attr = "C_TIME"; + + excl_attr_strings.create_time_attr = NULL; + excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; + excl_attr_strings.write_time_attr = "dos_attr.M_TIME"; + excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; + } + + /* Copy name so we can strip off exclusions (if any are specified) */ + strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); + + /* Ensure name is null terminated */ + name_sandbox[sizeof(name_sandbox) - 1] = '\0'; + + /* Play in the sandbox */ + name = name_sandbox; + + /* If there are any exclusions, point to them and mask them from name */ + if ((pExclude = strchr(name, '!')) != NULL) + { + *pExclude++ = '\0'; + } + + all = (StrnCaseCmp(name, "system.*", 8) == 0); + all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); + all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); + all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0); + some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); + some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); + numeric = (* (name + strlen(name) - 1) != '+'); + + /* Look for exclusions from "all" requests */ + if (all || all_nt || all_dos) { + + /* Exclusions are delimited by '!' */ + for (; + pExclude != NULL; + pExclude = (p == NULL ? NULL : p + 1)) { + + /* Find end of this exclusion name */ + if ((p = strchr(pExclude, '!')) != NULL) + { + *p = '\0'; + } + + /* Which exclusion name is this? */ + if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) { + exclude_nt_revision = True; + } + else if (StrCaseCmp(pExclude, "nt_sec_desc.owner") == 0) { + exclude_nt_owner = True; + } + else if (StrCaseCmp(pExclude, "nt_sec_desc.group") == 0) { + exclude_nt_group = True; + } + else if (StrCaseCmp(pExclude, "nt_sec_desc.acl") == 0) { + exclude_nt_acl = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.mode") == 0) { + exclude_dos_mode = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) { + exclude_dos_size = True; + } + else if (excl_attr_strings.create_time_attr != NULL && + StrCaseCmp(pExclude, + excl_attr_strings.change_time_attr) == 0) { + exclude_dos_create_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.access_time_attr) == 0) { + exclude_dos_access_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.write_time_attr) == 0) { + exclude_dos_write_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.change_time_attr) == 0) { + exclude_dos_change_time = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { + exclude_dos_inode = True; + } + else { + DEBUG(5, ("cacl_get received unknown exclusion: %s\n", + pExclude)); + errno = ENOATTR; + return -1; + } + } + } + + n_used = 0; + + /* + * If we are (possibly) talking to an NT or new system and some NT + * attributes have been requested... + */ + if (ipc_cli && (all || some_nt || all_nt_acls)) { + /* Point to the portion after "system.nt_sec_desc." */ + name += 19; /* if (all) this will be invalid but unused */ + + /* ... then obtain any NT attributes which were requested */ + fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); + + if (fnum == -1) { + DEBUG(5, ("cacl_get failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; + } + + sd = cli_query_secdesc(cli, fnum, ctx); + + if (!sd) { + DEBUG(5, + ("cacl_get Failed to query old descriptor\n")); + errno = 0; + return -1; + } + + cli_close(cli, fnum); + + if (! exclude_nt_revision) { + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, + "REVISION:%d", + sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "REVISION:%d", + sd->revision); + } + } else if (StrCaseCmp(name, "revision") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%d", + sd->revision); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%d", + sd->revision); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_nt_owner) { + /* Get owner and group sid */ + if (sd->owner_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, + numeric, + sd->owner_sid); + } else { + fstrcpy(sidstr, ""); + } + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, ",OWNER:%s", + sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else if (sidstr[0] != '\0') { + n = snprintf(buf, bufsize, + ",OWNER:%s", sidstr); + } + } else if (StrnCaseCmp(name, "owner", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, "%s", + sidstr); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_nt_group) { + if (sd->group_sid) { + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, + sd->group_sid); + } else { + fstrcpy(sidstr, ""); + } + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf(ctx, ",GROUP:%s", + sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else if (sidstr[0] != '\0') { + n = snprintf(buf, bufsize, + ",GROUP:%s", sidstr); + } + } else if (StrnCaseCmp(name, "group", 5) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%s", sidstr); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%s", sidstr); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_nt_acl) { + /* Add aces to value buffer */ + for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { + + SEC_ACE *ace = &sd->dacl->aces[i]; + convert_sid_to_string(ipc_cli, pol, + sidstr, numeric, + &ace->trustee); + + if (all || all_nt) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",ACL:" + "%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->access_mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf( + buf, bufsize, + ",ACL:%s:%d/%d/0x%08x", + sidstr, + ace->type, + ace->flags, + ace->access_mask); + } + } else if ((StrnCaseCmp(name, "acl", 3) == 0 && + StrCaseCmp(name+3, sidstr) == 0) || + (StrnCaseCmp(name, "acl+", 4) == 0 && + StrCaseCmp(name+4, sidstr) == 0)) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->access_mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%d/%d/0x%08x", + ace->type, + ace->flags, + ace->access_mask); + } + } else if (all_nt_acls) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%s%s:%d/%d/0x%08x", + i ? "," : "", + sidstr, + ace->type, + ace->flags, + ace->access_mask); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%s%s:%d/%d/0x%08x", + i ? "," : "", + sidstr, + ace->type, + ace->flags, + ace->access_mask); + } + } + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + } + + /* Restore name pointer to its original value */ + name -= 19; + } + + if (all || some_dos) { + /* Point to the portion after "system.dos_attr." */ + name += 16; /* if (all) this will be invalid but unused */ + + /* Obtain the DOS attributes */ + if (!SMBC_getatr(context, srv, filename, &mode, &size, + &create_time_ts, + &access_time_ts, + &write_time_ts, + &change_time_ts, + &ino)) { + + errno = SMBC_errno(context, srv->cli); + return -1; + + } + + create_time = convert_timespec_to_time_t(create_time_ts); + access_time = convert_timespec_to_time_t(access_time_ts); + write_time = convert_timespec_to_time_t(write_time_ts); + change_time = convert_timespec_to_time_t(change_time_ts); + + if (! exclude_dos_mode) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + "%sMODE:0x%x", + (ipc_cli && + (all || some_nt) + ? "," + : ""), + mode); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%sMODE:0x%x", + (ipc_cli && + (all || some_nt) + ? "," + : ""), + mode); + } + } else if (StrCaseCmp(name, "mode") == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "0x%x", mode); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "0x%x", mode); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_size) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",SIZE:%.0f", + (double)size); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",SIZE:%.0f", + (double)size); + } + } else if (StrCaseCmp(name, "size") == 0) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%.0f", + (double)size); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%.0f", + (double)size); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_create_time && + attr_strings.create_time_attr != NULL) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.create_time_attr, + create_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.create_time_attr, + create_time); + } + } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", create_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", create_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_access_time) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.access_time_attr, + access_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.access_time_attr, + access_time); + } + } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", access_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", access_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_write_time) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.write_time_attr, + write_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.write_time_attr, + write_time); + } + } else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", write_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", write_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_change_time) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf(ctx, + ",%s:%lu", + attr_strings.change_time_attr, + change_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",%s:%lu", + attr_strings.change_time_attr, + change_time); + } + } else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) { + if (determine_size) { + p = talloc_asprintf(ctx, "%lu", change_time); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%lu", change_time); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + if (! exclude_dos_inode) { + if (all || all_dos) { + if (determine_size) { + p = talloc_asprintf( + ctx, + ",INODE:%.0f", + (double)ino); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + ",INODE:%.0f", + (double) ino); + } + } else if (StrCaseCmp(name, "inode") == 0) { + if (determine_size) { + p = talloc_asprintf( + ctx, + "%.0f", + (double) ino); + if (!p) { + errno = ENOMEM; + return -1; + } + n = strlen(p); + } else { + n = snprintf(buf, bufsize, + "%.0f", + (double) ino); + } + } + + if (!determine_size && n > bufsize) { + errno = ERANGE; + return -1; + } + buf += n; + n_used += n; + bufsize -= n; + n = 0; + } + + /* Restore name pointer to its original value */ + name -= 16; + } + + if (n_used == 0) { + errno = ENOATTR; + return -1; + } + + return n_used; +} + +/***************************************************** +set the ACLs on a file given an ascii description +*******************************************************/ +static int +cacl_set(TALLOC_CTX *ctx, + struct cli_state *cli, + struct cli_state *ipc_cli, + POLICY_HND *pol, + const char *filename, + const char *the_acl, + int mode, + int flags) +{ + int fnum; + int err = 0; + SEC_DESC *sd = NULL, *old; + SEC_ACL *dacl = NULL; + DOM_SID *owner_sid = NULL; + DOM_SID *group_sid = NULL; + uint32 i, j; + size_t sd_size; + int ret = 0; + char *p; + bool numeric = True; + + /* the_acl will be null for REMOVE_ALL operations */ + if (the_acl) { + numeric = ((p = strchr(the_acl, ':')) != NULL && + p > the_acl && + p[-1] != '+'); + + /* if this is to set the entire ACL... */ + if (*the_acl == '*') { + /* ... then increment past the first colon */ + the_acl = p + 1; + } + + sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, + CONST_DISCARD(char *, the_acl)); + + if (!sd) { + errno = EINVAL; + return -1; + } + } + + /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller + that doesn't deref sd */ + + if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { + errno = EINVAL; + return -1; + } + + /* The desired access below is the only one I could find that works + with NT4, W2KP and Samba */ + + fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); + + if (fnum == -1) { + DEBUG(5, ("cacl_set failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; + } + + old = cli_query_secdesc(cli, fnum, ctx); + + if (!old) { + DEBUG(5, ("cacl_set Failed to query old descriptor\n")); + errno = 0; + return -1; + } + + cli_close(cli, fnum); + + switch (mode) { + case SMBC_XATTR_MODE_REMOVE_ALL: + old->dacl->num_aces = 0; + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_REMOVE: + for (i=0;sd->dacl && idacl->num_aces;i++) { + bool found = False; + + for (j=0;old->dacl && jdacl->num_aces;j++) { + if (sec_ace_equal(&sd->dacl->aces[i], + &old->dacl->aces[j])) { + uint32 k; + for (k=j; kdacl->num_aces-1;k++) { + old->dacl->aces[k] = + old->dacl->aces[k+1]; + } + old->dacl->num_aces--; + found = True; + dacl = old->dacl; + break; + } + } + + if (!found) { + err = ENOATTR; + ret = -1; + goto failed; + } + } + break; + + case SMBC_XATTR_MODE_ADD: + for (i=0;sd->dacl && idacl->num_aces;i++) { + bool found = False; + + for (j=0;old->dacl && jdacl->num_aces;j++) { + if (sid_equal(&sd->dacl->aces[i].trustee, + &old->dacl->aces[j].trustee)) { + if (!(flags & SMBC_XATTR_FLAG_CREATE)) { + err = EEXIST; + ret = -1; + goto failed; + } + old->dacl->aces[j] = sd->dacl->aces[i]; + ret = -1; + found = True; + } + } + + if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { + err = ENOATTR; + ret = -1; + goto failed; + } + + for (i=0;sd->dacl && idacl->num_aces;i++) { + add_ace(&old->dacl, &sd->dacl->aces[i], ctx); + } + } + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_SET: + old = sd; + owner_sid = old->owner_sid; + group_sid = old->group_sid; + dacl = old->dacl; + break; + + case SMBC_XATTR_MODE_CHOWN: + owner_sid = sd->owner_sid; + break; + + case SMBC_XATTR_MODE_CHGRP: + group_sid = sd->group_sid; + break; + } + + /* Denied ACE entries must come before allowed ones */ + sort_acl(old->dacl); + + /* Create new security descriptor and set it */ + sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, + owner_sid, group_sid, NULL, dacl, &sd_size); + + fnum = cli_nt_create(cli, filename, + WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); + + if (fnum == -1) { + DEBUG(5, ("cacl_set failed to open %s: %s\n", + filename, cli_errstr(cli))); + errno = 0; + return -1; + } + + if (!cli_set_secdesc(cli, fnum, sd)) { + DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli))); + ret = -1; + } + + /* Clean up */ + + failed: + cli_close(cli, fnum); + + if (err != 0) { + errno = err; + } + + return ret; +} + + +int +SMBC_setxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size, + int flags) +{ + int ret; + int ret2; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + DOS_ATTR_DESC *dad = NULL; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", + fname, name, (int) size, (const char*)value)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (! srv->no_nt_session) { + ipc_srv = SMBC_attr_server(frame, context, server, share, + &workgroup, &user, &password); + if (! ipc_srv) { + srv->no_nt_session = True; + } + } else { + ipc_srv = NULL; + } + + /* + * Are they asking to set the entire set of known attributes? + */ + if (StrCaseCmp(name, "system.*") == 0 || + StrCaseCmp(name, "system.*+") == 0) { + /* Yup. */ + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+7, (const char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + TALLOC_FREE(frame); + return -1; + } + + if (ipc_srv) { + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + namevalue, + (*namevalue == '*' + ? SMBC_XATTR_MODE_SET + : SMBC_XATTR_MODE_ADD), + flags); + } else { + ret = 0; + } + + /* get a DOS Attribute Descriptor with current attributes */ + dad = dos_attr_query(context, talloc_tos(), path, srv); + if (dad) { + /* Overwrite old with new, using what was provided */ + dos_attr_parse(context, dad, srv, namevalue); + + /* Set the new DOS attributes */ + if (! SMBC_setatr(context, srv, path, + dad->create_time, + dad->access_time, + dad->write_time, + dad->change_time, + dad->mode)) { + + /* cause failure if NT failed too */ + dad = NULL; + } + } + + /* we only fail if both NT and DOS sets failed */ + if (ret < 0 && ! dad) { + ret = -1; /* in case dad was null */ + } + else { + ret = 0; + } + + TALLOC_FREE(frame); + return ret; + } + + /* + * Are they asking to set an access control element or to set + * the entire access control list? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+19, (const char *) value); + + if (! ipc_srv) { + ret = -1; /* errno set by SMBC_server() */ + } + else if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + namevalue, + (*namevalue == '*' + ? SMBC_XATTR_MODE_SET + : SMBC_XATTR_MODE_ADD), + flags); + } + TALLOC_FREE(frame); + return ret; + } + + /* + * Are they asking to set the owner? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+19, (const char *) value); + + if (! ipc_srv) { + ret = -1; /* errno set by SMBC_server() */ + } + else if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + namevalue, SMBC_XATTR_MODE_CHOWN, 0); + } + TALLOC_FREE(frame); + return ret; + } + + /* + * Are they asking to set the group? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { + + /* Yup. */ + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+19, (const char *) value); + + if (! ipc_srv) { + /* errno set by SMBC_server() */ + ret = -1; + } + else if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + namevalue, SMBC_XATTR_MODE_CHGRP, 0); + } + TALLOC_FREE(frame); + return ret; + } + + /* Determine whether to use old-style or new-style attribute names */ + if (context->full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; + attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; + attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; + attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "system.dos_attr.A_TIME"; + attr_strings.write_time_attr = "system.dos_attr.M_TIME"; + attr_strings.change_time_attr = "system.dos_attr.C_TIME"; + } + + /* + * Are they asking to set a DOS attribute? + */ + if (StrCaseCmp(name, "system.dos_attr.*") == 0 || + StrCaseCmp(name, "system.dos_attr.mode") == 0 || + (attr_strings.create_time_attr != NULL && + StrCaseCmp(name, attr_strings.create_time_attr) == 0) || + StrCaseCmp(name, attr_strings.access_time_attr) == 0 || + StrCaseCmp(name, attr_strings.write_time_attr) == 0 || + StrCaseCmp(name, attr_strings.change_time_attr) == 0) { + + /* get a DOS Attribute Descriptor with current attributes */ + dad = dos_attr_query(context, talloc_tos(), path, srv); + if (dad) { + char *namevalue = + talloc_asprintf(talloc_tos(), "%s:%s", + name+16, (const char *) value); + if (! namevalue) { + errno = ENOMEM; + ret = -1; + } else { + /* Overwrite old with provided new params */ + dos_attr_parse(context, dad, srv, namevalue); + + /* Set the new DOS attributes */ + ret2 = SMBC_setatr(context, srv, path, + dad->create_time, + dad->access_time, + dad->write_time, + dad->change_time, + dad->mode); + + /* ret2 has True (success) / False (failure) */ + if (ret2) { + ret = 0; + } else { + ret = -1; + } + } + } else { + ret = -1; + } + + TALLOC_FREE(frame); + return ret; + } + + /* Unsupported attribute name */ + errno = EINVAL; + TALLOC_FREE(frame); + return -1; +} + +int +SMBC_getxattr_ctx(SMBCCTX *context, + const char *fname, + const char *name, + const void *value, + size_t size) +{ + int ret; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + struct { + const char * create_time_attr; + const char * access_time_attr; + const char * write_time_attr; + const char * change_time_attr; + } attr_strings; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (! srv->no_nt_session) { + ipc_srv = SMBC_attr_server(frame, context, server, share, + &workgroup, &user, &password); + if (! ipc_srv) { + srv->no_nt_session = True; + } + } else { + ipc_srv = NULL; + } + + /* Determine whether to use old-style or new-style attribute names */ + if (context->full_time_names) { + /* new-style names */ + attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; + attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; + attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; + attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; + } else { + /* old-style names */ + attr_strings.create_time_attr = NULL; + attr_strings.access_time_attr = "system.dos_attr.A_TIME"; + attr_strings.write_time_attr = "system.dos_attr.M_TIME"; + attr_strings.change_time_attr = "system.dos_attr.C_TIME"; + } + + /* Are they requesting a supported attribute? */ + if (StrCaseCmp(name, "system.*") == 0 || + StrnCaseCmp(name, "system.*!", 9) == 0 || + StrCaseCmp(name, "system.*+") == 0 || + StrnCaseCmp(name, "system.*+!", 10) == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 || + StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 || + StrCaseCmp(name, "system.dos_attr.*") == 0 || + StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 || + StrCaseCmp(name, "system.dos_attr.mode") == 0 || + StrCaseCmp(name, "system.dos_attr.size") == 0 || + (attr_strings.create_time_attr != NULL && + StrCaseCmp(name, attr_strings.create_time_attr) == 0) || + StrCaseCmp(name, attr_strings.access_time_attr) == 0 || + StrCaseCmp(name, attr_strings.write_time_attr) == 0 || + StrCaseCmp(name, attr_strings.change_time_attr) == 0 || + StrCaseCmp(name, "system.dos_attr.inode") == 0) { + + /* Yup. */ + ret = cacl_get(context, talloc_tos(), srv, + ipc_srv == NULL ? NULL : ipc_srv->cli, + &ipc_srv->pol, path, + CONST_DISCARD(char *, name), + CONST_DISCARD(char *, value), size); + if (ret < 0 && errno == 0) { + errno = SMBC_errno(context, srv->cli); + } + TALLOC_FREE(frame); + return ret; + } + + /* Unsupported attribute name */ + errno = EINVAL; + TALLOC_FREE(frame); + return -1; +} + + +int +SMBC_removexattr_ctx(SMBCCTX *context, + const char *fname, + const char *name) +{ + int ret; + SMBCSRV *srv = NULL; + SMBCSRV *ipc_srv = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; + char *path = NULL; + TALLOC_CTX *frame = talloc_stackframe(); + + if (!context || !context->initialized) { + + errno = EINVAL; /* Best I can think of ... */ + TALLOC_FREE(frame); + return -1; + } + + if (!fname) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); + + if (SMBC_parse_path(frame, + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } + + if (!user || user[0] == (char)0) { + user = talloc_strdup(frame, context->user); + if (!user) { + errno = ENOMEM; + TALLOC_FREE(frame); + return -1; + } + } + + srv = SMBC_server(frame, context, True, + server, share, &workgroup, &user, &password); + if (!srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_server */ + } + + if (! srv->no_nt_session) { + ipc_srv = SMBC_attr_server(frame, context, server, share, + &workgroup, &user, &password); + if (! ipc_srv) { + srv->no_nt_session = True; + } + } else { + ipc_srv = NULL; + } + + if (! ipc_srv) { + TALLOC_FREE(frame); + return -1; /* errno set by SMBC_attr_server */ + } + + /* Are they asking to set the entire ACL? */ + if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { + + /* Yup. */ + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); + TALLOC_FREE(frame); + return ret; + } + + /* + * Are they asking to remove one or more spceific security descriptor + * attributes? + */ + if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || + StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || + StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { + + /* Yup. */ + ret = cacl_set(talloc_tos(), srv->cli, + ipc_srv->cli, &ipc_srv->pol, path, + name + 19, SMBC_XATTR_MODE_REMOVE, 0); + TALLOC_FREE(frame); + return ret; + } + + /* Unsupported attribute name */ + errno = EINVAL; + TALLOC_FREE(frame); + return -1; +} + +int +SMBC_listxattr_ctx(SMBCCTX *context, + const char *fname, + char *list, + size_t size) +{ + /* + * This isn't quite what listxattr() is supposed to do. This returns + * the complete set of attribute names, always, rather than only those + * attribute names which actually exist for a file. Hmmm... + */ + size_t retsize; + const char supported_old[] = + "system.*\0" + "system.*+\0" + "system.nt_sec_desc.revision\0" + "system.nt_sec_desc.owner\0" + "system.nt_sec_desc.owner+\0" + "system.nt_sec_desc.group\0" + "system.nt_sec_desc.group+\0" + "system.nt_sec_desc.acl.*\0" + "system.nt_sec_desc.acl\0" + "system.nt_sec_desc.acl+\0" + "system.nt_sec_desc.*\0" + "system.nt_sec_desc.*+\0" + "system.dos_attr.*\0" + "system.dos_attr.mode\0" + "system.dos_attr.c_time\0" + "system.dos_attr.a_time\0" + "system.dos_attr.m_time\0" + ; + const char supported_new[] = + "system.*\0" + "system.*+\0" + "system.nt_sec_desc.revision\0" + "system.nt_sec_desc.owner\0" + "system.nt_sec_desc.owner+\0" + "system.nt_sec_desc.group\0" + "system.nt_sec_desc.group+\0" + "system.nt_sec_desc.acl.*\0" + "system.nt_sec_desc.acl\0" + "system.nt_sec_desc.acl+\0" + "system.nt_sec_desc.*\0" + "system.nt_sec_desc.*+\0" + "system.dos_attr.*\0" + "system.dos_attr.mode\0" + "system.dos_attr.create_time\0" + "system.dos_attr.access_time\0" + "system.dos_attr.write_time\0" + "system.dos_attr.change_time\0" + ; + const char * supported; + + if (context->full_time_names) { + supported = supported_new; + retsize = sizeof(supported_new); + } else { + supported = supported_old; + retsize = sizeof(supported_old); + } + + if (size == 0) { + return retsize; + } + + if (retsize > size) { + errno = ERANGE; + return -1; + } + + /* this can't be strcpy() because there are embedded null characters */ + memcpy(list, supported, retsize); + return retsize; +} diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c deleted file mode 100644 index fe008ed6b6..0000000000 --- a/source3/libsmb/libsmbclient.c +++ /dev/null @@ -1,7233 +0,0 @@ -/* - Unix SMB/Netbios implementation. - SMB client library implementation - Copyright (C) Andrew Tridgell 1998 - Copyright (C) Richard Sharpe 2000, 2002 - Copyright (C) John Terpstra 2000 - Copyright (C) Tom Jansen (Ninja ISD) 2002 - Copyright (C) Derrell Lipman 2003, 2004 - Copyright (C) Jeremy Allison 2007, 2008 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#include "includes.h" - -#include "include/libsmb_internal.h" - -struct smbc_dirent *smbc_readdir_ctx(SMBCCTX *context, SMBCFILE *dir); -struct smbc_dir_list *smbc_check_dir_ent(struct smbc_dir_list *list, - struct smbc_dirent *dirent); - -/* - * DOS Attribute values (used internally) - */ -typedef struct DOS_ATTR_DESC { - int mode; - SMB_OFF_T size; - time_t create_time; - time_t access_time; - time_t write_time; - time_t change_time; - SMB_INO_T inode; -} DOS_ATTR_DESC; - - -/* - * Internal flags for extended attributes - */ - -/* internal mode values */ -#define SMBC_XATTR_MODE_ADD 1 -#define SMBC_XATTR_MODE_REMOVE 2 -#define SMBC_XATTR_MODE_REMOVE_ALL 3 -#define SMBC_XATTR_MODE_SET 4 -#define SMBC_XATTR_MODE_CHOWN 5 -#define SMBC_XATTR_MODE_CHGRP 6 - -#define CREATE_ACCESS_READ READ_CONTROL_ACCESS - -/*We should test for this in configure ... */ -#ifndef ENOTSUP -#define ENOTSUP EOPNOTSUPP -#endif - -/* - * Functions exported by libsmb_cache.c that we need here - */ -int smbc_default_cache_functions(SMBCCTX *context); - -/* - * check if an element is part of the list. - * FIXME: Does not belong here ! - * Can anyone put this in a macro in dlinklist.h ? - * -- Tom - */ -static int DLIST_CONTAINS(SMBCFILE * list, SMBCFILE *p) { - if (!p || !list) return False; - do { - if (p == list) return True; - list = list->next; - } while (list); - return False; -} - -/* - * Find an lsa pipe handle associated with a cli struct. - */ -static struct rpc_pipe_client * -find_lsa_pipe_hnd(struct cli_state *ipc_cli) -{ - struct rpc_pipe_client *pipe_hnd; - - for (pipe_hnd = ipc_cli->pipe_list; - pipe_hnd; - pipe_hnd = pipe_hnd->next) { - - if (pipe_hnd->pipe_idx == PI_LSARPC) { - return pipe_hnd; - } - } - - return NULL; -} - -static int -smbc_close_ctx(SMBCCTX *context, - SMBCFILE *file); -static off_t -smbc_lseek_ctx(SMBCCTX *context, - SMBCFILE *file, - off_t offset, - int whence); - -extern bool in_client; - -/* - * Is the logging working / configfile read ? - */ -static int smbc_initialized = 0; - -static int -hex2int( unsigned int _char ) -{ - if ( _char >= 'A' && _char <='F') - return _char - 'A' + 10; - if ( _char >= 'a' && _char <='f') - return _char - 'a' + 10; - if ( _char >= '0' && _char <='9') - return _char - '0'; - return -1; -} - -/* - * smbc_urldecode() - * and smbc_urldecode_talloc() (internal fn.) - * - * Convert strings of %xx to their single character equivalent. Each 'x' must - * be a valid hexadecimal digit, or that % sequence is left undecoded. - * - * dest may, but need not be, the same pointer as src. - * - * Returns the number of % sequences which could not be converted due to lack - * of two following hexadecimal digits. - */ -static int -smbc_urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) -{ - int old_length = strlen(src); - int i = 0; - int err_count = 0; - size_t newlen = 1; - char *p, *dest; - - if (old_length == 0) { - return 0; - } - - *pp_dest = NULL; - for (i = 0; i < old_length; ) { - unsigned char character = src[i++]; - - if (character == '%') { - int a = i+1 < old_length ? hex2int(src[i]) : -1; - int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - - /* Replace valid sequence */ - if (a != -1 && b != -1) { - /* Replace valid %xx sequence with %dd */ - character = (a * 16) + b; - if (character == '\0') { - break; /* Stop at %00 */ - } - i += 2; - } else { - err_count++; - } - } - newlen++; - } - - dest = TALLOC_ARRAY(ctx, char, newlen); - if (!dest) { - return err_count; - } - - err_count = 0; - for (p = dest, i = 0; i < old_length; ) { - unsigned char character = src[i++]; - - if (character == '%') { - int a = i+1 < old_length ? hex2int(src[i]) : -1; - int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - - /* Replace valid sequence */ - if (a != -1 && b != -1) { - /* Replace valid %xx sequence with %dd */ - character = (a * 16) + b; - if (character == '\0') { - break; /* Stop at %00 */ - } - i += 2; - } else { - err_count++; - } - } - *p++ = character; - } - - *p = '\0'; - *pp_dest = dest; - return err_count; -} - -int -smbc_urldecode(char *dest, char *src, size_t max_dest_len) -{ - TALLOC_CTX *frame = talloc_stackframe(); - char *pdest; - int ret = smbc_urldecode_talloc(frame, &pdest, src); - - if (pdest) { - strlcpy(dest, pdest, max_dest_len); - } - TALLOC_FREE(frame); - return ret; -} - -/* - * smbc_urlencode() - * - * Convert any characters not specifically allowed in a URL into their %xx - * equivalent. - * - * Returns the remaining buffer length. - */ -int -smbc_urlencode(char *dest, char *src, int max_dest_len) -{ - char hex[] = "0123456789ABCDEF"; - - for (; *src != '\0' && max_dest_len >= 3; src++) { - - if ((*src < '0' && - *src != '-' && - *src != '.') || - (*src > '9' && - *src < 'A') || - (*src > 'Z' && - *src < 'a' && - *src != '_') || - (*src > 'z')) { - *dest++ = '%'; - *dest++ = hex[(*src >> 4) & 0x0f]; - *dest++ = hex[*src & 0x0f]; - max_dest_len -= 3; - } else { - *dest++ = *src; - max_dest_len--; - } - } - - *dest++ = '\0'; - max_dest_len--; - - return max_dest_len; -} - -/* - * Function to parse a path and turn it into components - * - * The general format of an SMB URI is explain in Christopher Hertel's CIFS - * book, at http://ubiqx.org/cifs/Appendix-D.html. We accept a subset of the - * general format ("smb:" only; we do not look for "cifs:"). - * - * - * We accept: - * smb://[[[domain;]user[:password]@]server[/share[/path[/file]]]][?options] - * - * Meaning of URLs: - * - * smb:// Show all workgroups. - * - * The method of locating the list of workgroups varies - * depending upon the setting of the context variable - * context->options.browse_max_lmb_count. This value - * determine the maximum number of local master browsers to - * query for the list of workgroups. In order to ensure that - * a complete list of workgroups is obtained, all master - * browsers must be queried, but if there are many - * workgroups, the time spent querying can begin to add up. - * For small networks (not many workgroups), it is suggested - * that this variable be set to 0, indicating query all local - * master browsers. When the network has many workgroups, a - * reasonable setting for this variable might be around 3. - * - * smb://name/ if name<1D> or name<1B> exists, list servers in - * workgroup, else, if name<20> exists, list all shares - * for server ... - * - * If "options" are provided, this function returns the entire option list as a - * string, for later parsing by the caller. Note that currently, no options - * are supported. - */ - -static const char *smbc_prefix = "smb:"; - -static int -smbc_parse_path(TALLOC_CTX *ctx, - SMBCCTX *context, - const char *fname, - char **pp_workgroup, - char **pp_server, - char **pp_share, - char **pp_path, - char **pp_user, - char **pp_password, - char **pp_options) -{ - char *s; - const char *p; - char *q, *r; - int len; - - /* Ensure these returns are at least valid pointers. */ - *pp_server = talloc_strdup(ctx, ""); - *pp_share = talloc_strdup(ctx, ""); - *pp_path = talloc_strdup(ctx, ""); - *pp_user = talloc_strdup(ctx, ""); - *pp_password = talloc_strdup(ctx, ""); - - if (!*pp_server || !*pp_share || !*pp_path || - !*pp_user || !*pp_password) { - return -1; - } - - /* - * Assume we wont find an authentication domain to parse, so default - * to the workgroup in the provided context. - */ - if (pp_workgroup != NULL) { - *pp_workgroup = talloc_strdup(ctx, context->workgroup); - } - - if (pp_options) { - *pp_options = talloc_strdup(ctx, ""); - } - s = talloc_strdup(ctx, fname); - - /* see if it has the right prefix */ - len = strlen(smbc_prefix); - if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { - return -1; /* What about no smb: ? */ - } - - p = s + len; - - /* Watch the test below, we are testing to see if we should exit */ - - if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { - DEBUG(1, ("Invalid path (does not begin with smb://")); - return -1; - } - - p += 2; /* Skip the double slash */ - - /* See if any options were specified */ - if ((q = strrchr(p, '?')) != NULL ) { - /* There are options. Null terminate here and point to them */ - *q++ = '\0'; - - DEBUG(4, ("Found options '%s'", q)); - - /* Copy the options */ - if (*pp_options != NULL) { - TALLOC_FREE(*pp_options); - *pp_options = talloc_strdup(ctx, q); - } - } - - if (*p == '\0') { - goto decoding; - } - - if (*p == '/') { - int wl = strlen(context->workgroup); - - if (wl > 16) { - wl = 16; - } - - *pp_server = talloc_strdup(ctx, context->workgroup); - if (!*pp_server) { - return -1; - } - *pp_server[wl] = '\0'; - return 0; - } - - /* - * ok, its for us. Now parse out the server, share etc. - * - * However, we want to parse out [[domain;]user[:password]@] if it - * exists ... - */ - - /* check that '@' occurs before '/', if '/' exists at all */ - q = strchr_m(p, '@'); - r = strchr_m(p, '/'); - if (q && (!r || q < r)) { - char *userinfo = NULL; - const char *u; - - next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@"); - if (!userinfo) { - return -1; - } - u = userinfo; - - if (strchr_m(u, ';')) { - char *workgroup; - next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); - if (!workgroup) { - return -1; - } - if (pp_workgroup) { - *pp_workgroup = workgroup; - } - } - - if (strchr_m(u, ':')) { - next_token_no_ltrim_talloc(ctx, &u, pp_user, ":"); - if (!*pp_user) { - return -1; - } - *pp_password = talloc_strdup(ctx, u); - if (!*pp_password) { - return -1; - } - } else { - *pp_user = talloc_strdup(ctx, u); - if (!*pp_user) { - return -1; - } - } - } - - if (!next_token_talloc(ctx, &p, pp_server, "/")) { - return -1; - } - - if (*p == (char)0) { - goto decoding; /* That's it ... */ - } - - if (!next_token_talloc(ctx, &p, pp_share, "/")) { - return -1; - } - - /* - * Prepend a leading slash if there's a file path, as required by - * NetApp filers. - */ - if (*p != '\0') { - *pp_path = talloc_asprintf(ctx, - "\\%s", - p); - } else { - *pp_path = talloc_strdup(ctx, ""); - } - if (!*pp_path) { - return -1; - } - string_replace(*pp_path, '/', '\\'); - - decoding: - - (void) smbc_urldecode_talloc(ctx, pp_path, *pp_path); - (void) smbc_urldecode_talloc(ctx, pp_server, *pp_server); - (void) smbc_urldecode_talloc(ctx, pp_share, *pp_share); - (void) smbc_urldecode_talloc(ctx, pp_user, *pp_user); - (void) smbc_urldecode_talloc(ctx, pp_password, *pp_password); - - return 0; -} - -/* - * Verify that the options specified in a URL are valid - */ -static int -smbc_check_options(char *server, - char *share, - char *path, - char *options) -{ - DEBUG(4, ("smbc_check_options(): server='%s' share='%s' " - "path='%s' options='%s'\n", - server, share, path, options)); - - /* No options at all is always ok */ - if (! *options) return 0; - - /* Currently, we don't support any options. */ - return -1; -} - -/* - * Convert an SMB error into a UNIX error ... - */ -static int -smbc_errno(SMBCCTX *context, - struct cli_state *c) -{ - int ret = cli_errno(c); - - if (cli_is_dos_error(c)) { - uint8 eclass; - uint32 ecode; - - cli_dos_error(c, &eclass, &ecode); - - DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", - (int)eclass, (int)ecode, (int)ecode, ret)); - } else { - NTSTATUS status; - - status = cli_nt_error(c); - - DEBUG(3,("smbc errno %s -> %d\n", - nt_errstr(status), ret)); - } - - return ret; -} - -/* - * Check a server for being alive and well. - * returns 0 if the server is in shape. Returns 1 on error - * - * Also useable outside libsmbclient to enable external cache - * to do some checks too. - */ -static int -smbc_check_server(SMBCCTX * context, - SMBCSRV * server) -{ - socklen_t size; - struct sockaddr addr; - - size = sizeof(addr); - return (getpeername(server->cli->fd, &addr, &size) == -1); -} - -/* - * Remove a server from the cached server list it's unused. - * On success, 0 is returned. 1 is returned if the server could not be removed. - * - * Also useable outside libsmbclient - */ -int -smbc_remove_unused_server(SMBCCTX * context, - SMBCSRV * srv) -{ - SMBCFILE * file; - - /* are we being fooled ? */ - if (!context || !context->internal || - !context->internal->_initialized || !srv) return 1; - - - /* Check all open files/directories for a relation with this server */ - for (file = context->internal->_files; file; file=file->next) { - if (file->srv == srv) { - /* Still used */ - DEBUG(3, ("smbc_remove_usused_server: " - "%p still used by %p.\n", - srv, file)); - return 1; - } - } - - DLIST_REMOVE(context->internal->_servers, srv); - - cli_shutdown(srv->cli); - srv->cli = NULL; - - DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); - - (context->callbacks.remove_cached_srv_fn)(context, srv); - - SAFE_FREE(srv); - return 0; -} - -/**************************************************************** - * Call the auth_fn with fixed size (fstring) buffers. - ***************************************************************/ - -static void call_auth_fn(TALLOC_CTX *ctx, - SMBCCTX *context, - const char *server, - const char *share, - char **pp_workgroup, - char **pp_username, - char **pp_password) -{ - fstring workgroup; - fstring username; - fstring password; - - strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); - strlcpy(username, *pp_username, sizeof(username)); - strlcpy(password, *pp_password, sizeof(password)); - - if (context->internal->_auth_fn_with_context != NULL) { - (context->internal->_auth_fn_with_context)( - context, - server, share, - workgroup, sizeof(workgroup), - username, sizeof(username), - password, sizeof(password)); - } else { - (context->callbacks.auth_fn)( - server, share, - workgroup, sizeof(workgroup), - username, sizeof(username), - password, sizeof(password)); - } - - TALLOC_FREE(*pp_workgroup); - TALLOC_FREE(*pp_username); - TALLOC_FREE(*pp_password); - - *pp_workgroup = talloc_strdup(ctx, workgroup); - *pp_username = talloc_strdup(ctx, username); - *pp_password = talloc_strdup(ctx, password); -} - -static SMBCSRV * -find_server(TALLOC_CTX *ctx, - SMBCCTX *context, - const char *server, - const char *share, - char **pp_workgroup, - char **pp_username, - char **pp_password) -{ - SMBCSRV *srv; - int auth_called = 0; - - check_server_cache: - - srv = (context->callbacks.get_cached_srv_fn)(context, server, share, - *pp_workgroup, *pp_username); - - if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] || - !*pp_password || !(*pp_password)[0])) { - call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - - if (!pp_workgroup || !pp_username || !pp_password) { - return NULL; - } - - /* - * However, smbc_auth_fn may have picked up info relating to - * an existing connection, so try for an existing connection - * again ... - */ - auth_called = 1; - goto check_server_cache; - - } - - if (srv) { - if ((context->callbacks.check_server_fn)(context, srv)) { - /* - * This server is no good anymore - * Try to remove it and check for more possible - * servers in the cache - */ - if ((context->callbacks.remove_unused_server_fn)(context, - srv)) { - /* - * We could not remove the server completely, - * remove it from the cache so we will not get - * it again. It will be removed when the last - * file/dir is closed. - */ - (context->callbacks.remove_cached_srv_fn)(context, - srv); - } - - /* - * Maybe there are more cached connections to this - * server - */ - goto check_server_cache; - } - - return srv; - } - - return NULL; -} - -/* - * Connect to a server, possibly on an existing connection - * - * Here, what we want to do is: If the server and username - * match an existing connection, reuse that, otherwise, establish a - * new connection. - * - * If we have to create a new connection, call the auth_fn to get the - * info we need, unless the username and password were passed in. - */ - -static SMBCSRV * -smbc_server(TALLOC_CTX *ctx, - SMBCCTX *context, - bool connect_if_not_found, - const char *server, - const char *share, - char **pp_workgroup, - char **pp_username, - char **pp_password) -{ - SMBCSRV *srv=NULL; - struct cli_state *c; - struct nmb_name called, calling; - const char *server_n = server; - struct sockaddr_storage ss; - int tried_reverse = 0; - int port_try_first; - int port_try_next; - const char *username_used; - NTSTATUS status; - - zero_addr(&ss); - ZERO_STRUCT(c); - - if (server[0] == 0) { - errno = EPERM; - return NULL; - } - - /* Look for a cached connection */ - srv = find_server(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - - /* - * If we found a connection and we're only allowed one share per - * server... - */ - if (srv && *share != '\0' && context->options.one_share_per_server) { - - /* - * ... then if there's no current connection to the share, - * connect to it. find_server(), or rather the function - * pointed to by context->callbacks.get_cached_srv_fn which - * was called by find_server(), will have issued a tree - * disconnect if the requested share is not the same as the - * one that was already connected. - */ - if (srv->cli->cnum == (uint16) -1) { - /* Ensure we have accurate auth info */ - call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - - if (!*pp_workgroup || !*pp_username || !*pp_password) { - errno = ENOMEM; - cli_shutdown(srv->cli); - srv->cli = NULL; - (context->callbacks.remove_cached_srv_fn)(context, - srv); - return NULL; - } - - /* - * We don't need to renegotiate encryption - * here as the encryption context is not per - * tid. - */ - - if (!cli_send_tconX(srv->cli, share, "?????", - *pp_password, - strlen(*pp_password)+1)) { - - errno = smbc_errno(context, srv->cli); - cli_shutdown(srv->cli); - srv->cli = NULL; - (context->callbacks.remove_cached_srv_fn)(context, - srv); - srv = NULL; - } - - /* - * Regenerate the dev value since it's based on both - * server and share - */ - if (srv) { - srv->dev = (dev_t)(str_checksum(server) ^ - str_checksum(share)); - } - } - } - - /* If we have a connection... */ - if (srv) { - - /* ... then we're done here. Give 'em what they came for. */ - return srv; - } - - /* If we're not asked to connect when a connection doesn't exist... */ - if (! connect_if_not_found) { - /* ... then we're done here. */ - return NULL; - } - - if (!*pp_workgroup || !*pp_username || !*pp_password) { - errno = ENOMEM; - return NULL; - } - - make_nmb_name(&calling, context->netbios_name, 0x0); - make_nmb_name(&called , server, 0x20); - - DEBUG(4,("smbc_server: server_n=[%s] server=[%s]\n", server_n, server)); - - DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); - - again: - - zero_addr(&ss); - - /* have to open a new connection */ - if ((c = cli_initialise()) == NULL) { - errno = ENOMEM; - return NULL; - } - - if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { - c->use_kerberos = True; - } - if (context->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { - c->fallback_after_kerberos = True; - } - - c->timeout = context->timeout; - - /* - * Force use of port 139 for first try if share is $IPC, empty, or - * null, so browse lists can work - */ - if (share == NULL || *share == '\0' || strcmp(share, "IPC$") == 0) { - port_try_first = 139; - port_try_next = 445; - } else { - port_try_first = 445; - port_try_next = 139; - } - - c->port = port_try_first; - - status = cli_connect(c, server_n, &ss); - if (!NT_STATUS_IS_OK(status)) { - - /* First connection attempt failed. Try alternate port. */ - c->port = port_try_next; - - status = cli_connect(c, server_n, &ss); - if (!NT_STATUS_IS_OK(status)) { - cli_shutdown(c); - errno = ETIMEDOUT; - return NULL; - } - } - - if (!cli_session_request(c, &calling, &called)) { - cli_shutdown(c); - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } else { /* Try one more time, but ensure we don't loop */ - - /* Only try this if server is an IP address ... */ - - if (is_ipaddress(server) && !tried_reverse) { - fstring remote_name; - struct sockaddr_storage rem_ss; - - if (!interpret_string_addr(&rem_ss, server, - NI_NUMERICHOST)) { - DEBUG(4, ("Could not convert IP address " - "%s to struct sockaddr_storage\n", - server)); - errno = ETIMEDOUT; - return NULL; - } - - tried_reverse++; /* Yuck */ - - if (name_status_find("*", 0, 0, &rem_ss, remote_name)) { - make_nmb_name(&called, remote_name, 0x20); - goto again; - } - } - } - errno = ETIMEDOUT; - return NULL; - } - - DEBUG(4,(" session request ok\n")); - - if (!cli_negprot(c)) { - cli_shutdown(c); - errno = ETIMEDOUT; - return NULL; - } - - username_used = *pp_username; - - if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, - *pp_password, strlen(*pp_password), - *pp_password, strlen(*pp_password), - *pp_workgroup))) { - - /* Failed. Try an anonymous login, if allowed by flags. */ - username_used = ""; - - if ((context->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || - !NT_STATUS_IS_OK(cli_session_setup(c, username_used, - *pp_password, 1, - *pp_password, 0, - *pp_workgroup))) { - - cli_shutdown(c); - errno = EPERM; - return NULL; - } - } - - DEBUG(4,(" session setup ok\n")); - - if (!cli_send_tconX(c, share, "?????", - *pp_password, strlen(*pp_password)+1)) { - errno = smbc_errno(context, c); - cli_shutdown(c); - return NULL; - } - - DEBUG(4,(" tconx ok\n")); - - if (context->internal->_smb_encryption_level) { - /* Attempt UNIX smb encryption. */ - if (!NT_STATUS_IS_OK(cli_force_encryption(c, - username_used, - *pp_password, - *pp_workgroup))) { - - /* - * context->internal->_smb_encryption_level == 1 - * means don't fail if encryption can't be negotiated, - * == 2 means fail if encryption can't be negotiated. - */ - - DEBUG(4,(" SMB encrypt failed\n")); - - if (context->internal->_smb_encryption_level == 2) { - cli_shutdown(c); - errno = EPERM; - return NULL; - } - } - DEBUG(4,(" SMB encrypt ok\n")); - } - - /* - * Ok, we have got a nice connection - * Let's allocate a server structure. - */ - - srv = SMB_MALLOC_P(SMBCSRV); - if (!srv) { - errno = ENOMEM; - goto failed; - } - - ZERO_STRUCTP(srv); - srv->cli = c; - srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); - srv->no_pathinfo = False; - srv->no_pathinfo2 = False; - srv->no_nt_session = False; - - /* now add it to the cache (internal or external) */ - /* Let the cache function set errno if it wants to */ - errno = 0; - if ((context->callbacks.add_cached_srv_fn)(context, srv, - server, share, - *pp_workgroup, - *pp_username)) { - int saved_errno = errno; - DEBUG(3, (" Failed to add server to cache\n")); - errno = saved_errno; - if (errno == 0) { - errno = ENOMEM; - } - goto failed; - } - - DEBUG(2, ("Server connect ok: //%s/%s: %p\n", - server, share, srv)); - - DLIST_ADD(context->internal->_servers, srv); - return srv; - - failed: - cli_shutdown(c); - if (!srv) { - return NULL; - } - - SAFE_FREE(srv); - return NULL; -} - -/* - * Connect to a server for getting/setting attributes, possibly on an existing - * connection. This works similarly to smbc_server(). - */ -static SMBCSRV * -smbc_attr_server(TALLOC_CTX *ctx, - SMBCCTX *context, - const char *server, - const char *share, - char **pp_workgroup, - char **pp_username, - char **pp_password) -{ - int flags; - struct sockaddr_storage ss; - struct cli_state *ipc_cli; - struct rpc_pipe_client *pipe_hnd; - NTSTATUS nt_status; - SMBCSRV *ipc_srv=NULL; - - /* - * See if we've already created this special connection. Reference - * our "special" share name '*IPC$', which is an impossible real share - * name due to the leading asterisk. - */ - ipc_srv = find_server(ctx, context, server, "*IPC$", - pp_workgroup, pp_username, pp_password); - if (!ipc_srv) { - - /* We didn't find a cached connection. Get the password */ - if (!*pp_password || (*pp_password)[0] == '\0') { - /* ... then retrieve it now. */ - call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - if (!*pp_workgroup || !*pp_username || !*pp_password) { - errno = ENOMEM; - return NULL; - } - } - - flags = 0; - if (context->flags & SMB_CTX_FLAG_USE_KERBEROS) { - flags |= CLI_FULL_CONNECTION_USE_KERBEROS; - } - - zero_addr(&ss); - nt_status = cli_full_connection(&ipc_cli, - global_myname(), server, - &ss, 0, "IPC$", "?????", - *pp_username, - *pp_workgroup, - *pp_password, - flags, - Undefined, NULL); - if (! NT_STATUS_IS_OK(nt_status)) { - DEBUG(1,("cli_full_connection failed! (%s)\n", - nt_errstr(nt_status))); - errno = ENOTSUP; - return NULL; - } - - if (context->internal->_smb_encryption_level) { - /* Attempt UNIX smb encryption. */ - if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, - *pp_username, - *pp_password, - *pp_workgroup))) { - - /* - * context->internal->_smb_encryption_level == 1 - * means don't fail if encryption can't be negotiated, - * == 2 means fail if encryption can't be negotiated. - */ - - DEBUG(4,(" SMB encrypt failed on IPC$\n")); - - if (context->internal->_smb_encryption_level == 2) { - cli_shutdown(ipc_cli); - errno = EPERM; - return NULL; - } - } - DEBUG(4,(" SMB encrypt ok on IPC$\n")); - } - - ipc_srv = SMB_MALLOC_P(SMBCSRV); - if (!ipc_srv) { - errno = ENOMEM; - cli_shutdown(ipc_cli); - return NULL; - } - - ZERO_STRUCTP(ipc_srv); - ipc_srv->cli = ipc_cli; - - pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, - PI_LSARPC, - &nt_status); - if (!pipe_hnd) { - DEBUG(1, ("cli_nt_session_open fail!\n")); - errno = ENOTSUP; - cli_shutdown(ipc_srv->cli); - free(ipc_srv); - return NULL; - } - - /* - * Some systems don't support - * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 - * so we might as well do it too. - */ - - nt_status = rpccli_lsa_open_policy( - pipe_hnd, - talloc_tos(), - True, - GENERIC_EXECUTE_ACCESS, - &ipc_srv->pol); - - if (!NT_STATUS_IS_OK(nt_status)) { - errno = smbc_errno(context, ipc_srv->cli); - cli_shutdown(ipc_srv->cli); - return NULL; - } - - /* now add it to the cache (internal or external) */ - - errno = 0; /* let cache function set errno if it likes */ - if ((context->callbacks.add_cached_srv_fn)(context, ipc_srv, - server, - "*IPC$", - *pp_workgroup, - *pp_username)) { - DEBUG(3, (" Failed to add server to cache\n")); - if (errno == 0) { - errno = ENOMEM; - } - cli_shutdown(ipc_srv->cli); - free(ipc_srv); - return NULL; - } - - DLIST_ADD(context->internal->_servers, ipc_srv); - } - - return ipc_srv; -} - -/* - * Routine to open() a file ... - */ - -static SMBCFILE * -smbc_open_ctx(SMBCCTX *context, - const char *fname, - int flags, - mode_t mode) -{ - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - SMBCSRV *srv = NULL; - SMBCFILE *file = NULL; - int fd; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return NULL; - - } - - if (!fname) { - - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - - } - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - if (errno == EPERM) errno = EACCES; - TALLOC_FREE(frame); - return NULL; /* smbc_server sets errno */ - } - - /* Hmmm, the test for a directory is suspect here ... FIXME */ - - if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { - fd = -1; - } else { - file = SMB_MALLOC_P(SMBCFILE); - - if (!file) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - - ZERO_STRUCTP(file); - - /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - SAFE_FREE(file); - TALLOC_FREE(frame); - return NULL; - } - /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ - - if ((fd = cli_open(targetcli, targetpath, flags, - context->internal->_share_mode)) < 0) { - - /* Handle the error ... */ - - SAFE_FREE(file); - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return NULL; - - } - - /* Fill in file struct */ - - file->cli_fd = fd; - file->fname = SMB_STRDUP(fname); - file->srv = srv; - file->offset = 0; - file->file = True; - - DLIST_ADD(context->internal->_files, file); - - /* - * If the file was opened in O_APPEND mode, all write - * operations should be appended to the file. To do that, - * though, using this protocol, would require a getattrE() - * call for each and every write, to determine where the end - * of the file is. (There does not appear to be an append flag - * in the protocol.) Rather than add all of that overhead of - * retrieving the current end-of-file offset prior to each - * write operation, we'll assume that most append operations - * will continuously write, so we'll just set the offset to - * the end of the file now and hope that's adequate. - * - * Note to self: If this proves inadequate, and O_APPEND - * should, in some cases, be forced for each write, add a - * field in the context options structure, for - * "strict_append_mode" which would select between the current - * behavior (if FALSE) or issuing a getattrE() prior to each - * write and forcing the write to the end of the file (if - * TRUE). Adding that capability will likely require adding - * an "append" flag into the _SMBCFILE structure to track - * whether a file was opened in O_APPEND mode. -- djl - */ - if (flags & O_APPEND) { - if (smbc_lseek_ctx(context, file, 0, SEEK_END) < 0) { - (void) smbc_close_ctx(context, file); - errno = ENXIO; - TALLOC_FREE(frame); - return NULL; - } - } - - TALLOC_FREE(frame); - return file; - - } - - /* Check if opendir needed ... */ - - if (fd == -1) { - int eno = 0; - - eno = smbc_errno(context, srv->cli); - file = (context->opendir)(context, fname); - if (!file) errno = eno; - TALLOC_FREE(frame); - return file; - - } - - errno = EINVAL; /* FIXME, correct errno ? */ - TALLOC_FREE(frame); - return NULL; - -} - -/* - * Routine to create a file - */ - -static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ - -static SMBCFILE * -smbc_creat_ctx(SMBCCTX *context, - const char *path, - mode_t mode) -{ - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - return NULL; - - } - - return smbc_open_ctx(context, path, creat_bits, mode); -} - -/* - * Routine to read() a file ... - */ - -static ssize_t -smbc_read_ctx(SMBCCTX *context, - SMBCFILE *file, - void *buf, - size_t count) -{ - int ret; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - /* - * offset: - * - * Compiler bug (possibly) -- gcc (GCC) 3.3.5 (Debian 1:3.3.5-2) -- - * appears to pass file->offset (which is type off_t) differently than - * a local variable of type off_t. Using local variable "offset" in - * the call to cli_read() instead of file->offset fixes a problem - * retrieving data at an offset greater than 4GB. - */ - off_t offset; - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - - } - - offset = file->offset; - - /* Check that the buffer exists ... */ - - if (buf == NULL) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - /*d_printf(">>>read: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>read: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - - ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); - - if (ret < 0) { - - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return -1; - - } - - file->offset += ret; - - DEBUG(4, (" --> %d\n", ret)); - - TALLOC_FREE(frame); - return ret; /* Success, ret bytes of data ... */ - -} - -/* - * Routine to write() a file ... - */ - -static ssize_t -smbc_write_ctx(SMBCCTX *context, - SMBCFILE *file, - void *buf, - size_t count) -{ - int ret; - off_t offset; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - /* First check all pointers before dereferencing them */ - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - /* Check that the buffer exists ... */ - - if (buf == NULL) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - offset = file->offset; /* See "offset" comment in smbc_read_ctx() */ - - /*d_printf(">>>write: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>write: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - - ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); - - if (ret <= 0) { - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return -1; - - } - - file->offset += ret; - - TALLOC_FREE(frame); - return ret; /* Success, 0 bytes of data ... */ -} - -/* - * Routine to close() a file ... - */ - -static int -smbc_close_ctx(SMBCCTX *context, - SMBCFILE *file) -{ - SMBCSRV *srv; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - /* IS a dir ... */ - if (!file->file) { - TALLOC_FREE(frame); - return (context->closedir)(context, file); - } - - /*d_printf(">>>close: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>close: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ - - if (!cli_close(targetcli, file->cli_fd)) { - - DEBUG(3, ("cli_close failed on %s. purging server.\n", - file->fname)); - /* Deallocate slot and remove the server - * from the server cache if unused */ - errno = smbc_errno(context, targetcli); - srv = file->srv; - DLIST_REMOVE(context->internal->_files, file); - SAFE_FREE(file->fname); - SAFE_FREE(file); - (context->callbacks.remove_unused_server_fn)(context, srv); - TALLOC_FREE(frame); - return -1; - - } - - DLIST_REMOVE(context->internal->_files, file); - SAFE_FREE(file->fname); - SAFE_FREE(file); - TALLOC_FREE(frame); - - return 0; -} - -/* - * Get info from an SMB server on a file. Use a qpathinfo call first - * and if that fails, use getatr, as Win95 sometimes refuses qpathinfo - */ -static bool -smbc_getatr(SMBCCTX * context, - SMBCSRV *srv, - char *path, - uint16 *mode, - SMB_OFF_T *size, - struct timespec *create_time_ts, - struct timespec *access_time_ts, - struct timespec *write_time_ts, - struct timespec *change_time_ts, - SMB_INO_T *ino) -{ - char *fixedpath = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - time_t write_time; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /* path fixup for . and .. */ - if (strequal(path, ".") || strequal(path, "..")) { - fixedpath = talloc_strdup(frame, "\\"); - if (!fixedpath) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } else { - fixedpath = talloc_strdup(frame, path); - if (!fixedpath) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - trim_string(fixedpath, NULL, "\\.."); - trim_string(fixedpath, NULL, "\\."); - } - DEBUG(4,("smbc_getatr: sending qpathinfo\n")); - - if (!cli_resolve_path(frame, "", srv->cli, fixedpath, - &targetcli, &targetpath)) { - d_printf("Couldn't resolve %s\n", path); - TALLOC_FREE(frame); - return False; - } - - if (!srv->no_pathinfo2 && - cli_qpathinfo2(targetcli, targetpath, - create_time_ts, - access_time_ts, - write_time_ts, - change_time_ts, - size, mode, ino)) { - TALLOC_FREE(frame); - return True; - } - - /* if this is NT then don't bother with the getatr */ - if (targetcli->capabilities & CAP_NT_SMBS) { - errno = EPERM; - TALLOC_FREE(frame); - return False; - } - - if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { - - struct timespec w_time_ts; - - w_time_ts = convert_time_t_to_timespec(write_time); - - if (write_time_ts != NULL) { - *write_time_ts = w_time_ts; - } - - if (create_time_ts != NULL) { - *create_time_ts = w_time_ts; - } - - if (access_time_ts != NULL) { - *access_time_ts = w_time_ts; - } - - if (change_time_ts != NULL) { - *change_time_ts = w_time_ts; - } - - srv->no_pathinfo2 = True; - TALLOC_FREE(frame); - return True; - } - - errno = EPERM; - TALLOC_FREE(frame); - return False; - -} - -/* - * Set file info on an SMB server. Use setpathinfo call first. If that - * fails, use setattrE.. - * - * Access and modification time parameters are always used and must be - * provided. Create time, if zero, will be determined from the actual create - * time of the file. If non-zero, the create time will be set as well. - * - * "mode" (attributes) parameter may be set to -1 if it is not to be set. - */ -static bool -smbc_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, - time_t create_time, - time_t access_time, - time_t write_time, - time_t change_time, - uint16 mode) -{ - int fd; - int ret; - TALLOC_CTX *frame = talloc_stackframe(); - - /* - * First, try setpathinfo (if qpathinfo succeeded), for it is the - * modern function for "new code" to be using, and it works given a - * filename rather than requiring that the file be opened to have its - * attributes manipulated. - */ - if (srv->no_pathinfo || - ! cli_setpathinfo(srv->cli, path, - create_time, - access_time, - write_time, - change_time, - mode)) { - - /* - * setpathinfo is not supported; go to plan B. - * - * cli_setatr() does not work on win98, and it also doesn't - * support setting the access time (only the modification - * time), so in all cases, we open the specified file and use - * cli_setattrE() which should work on all OS versions, and - * supports both times. - */ - - /* Don't try {q,set}pathinfo() again, with this server */ - srv->no_pathinfo = True; - - /* Open the file */ - if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { - - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return -1; - } - - /* Set the new attributes */ - ret = cli_setattrE(srv->cli, fd, - change_time, - access_time, - write_time); - - /* Close the file */ - cli_close(srv->cli, fd); - - /* - * Unfortunately, setattrE() doesn't have a provision for - * setting the access mode (attributes). We'll have to try - * cli_setatr() for that, and with only this parameter, it - * seems to work on win98. - */ - if (ret && mode != (uint16) -1) { - ret = cli_setatr(srv->cli, path, mode, 0); - } - - if (! ret) { - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return False; - } - } - - TALLOC_FREE(frame); - return True; -} - - /* - * Routine to unlink() a file - */ - -static int -smbc_unlink_ctx(SMBCCTX *context, - const char *fname) -{ - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - SMBCSRV *srv = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* smbc_server sets errno */ - - } - - /*d_printf(">>>unlink: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ - - if (!cli_unlink(targetcli, targetpath)) { - - errno = smbc_errno(context, targetcli); - - if (errno == EACCES) { /* Check if the file is a directory */ - - int saverr = errno; - SMB_OFF_T size = 0; - uint16 mode = 0; - struct timespec write_time_ts; - struct timespec access_time_ts; - struct timespec change_time_ts; - SMB_INO_T ino = 0; - - if (!smbc_getatr(context, srv, path, &mode, &size, - NULL, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &ino)) { - - /* Hmmm, bad error ... What? */ - - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return -1; - - } - else { - - if (IS_DOS_DIR(mode)) - errno = EISDIR; - else - errno = saverr; /* Restore this */ - - } - } - - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return 0; /* Success ... */ - -} - -/* - * Routine to rename() a file - */ - -static int -smbc_rename_ctx(SMBCCTX *ocontext, - const char *oname, - SMBCCTX *ncontext, - const char *nname) -{ - char *server1 = NULL; - char *share1 = NULL; - char *server2 = NULL; - char *share2 = NULL; - char *user1 = NULL; - char *user2 = NULL; - char *password1 = NULL; - char *password2 = NULL; - char *workgroup = NULL; - char *path1 = NULL; - char *path2 = NULL; - char *targetpath1 = NULL; - char *targetpath2 = NULL; - struct cli_state *targetcli1 = NULL; - struct cli_state *targetcli2 = NULL; - SMBCSRV *srv = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!ocontext || !ncontext || - !ocontext->internal || !ncontext->internal || - !ocontext->internal->_initialized || - !ncontext->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!oname || !nname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - - if (smbc_parse_path(frame, - ocontext, - oname, - &workgroup, - &server1, - &share1, - &path1, - &user1, - &password1, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user1 || user1[0] == (char)0) { - user1 = talloc_strdup(frame, ocontext->user); - if (!user1) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - if (smbc_parse_path(frame, - ncontext, - nname, - NULL, - &server2, - &share2, - &path2, - &user2, - &password2, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user2 || user2[0] == (char)0) { - user2 = talloc_strdup(frame, ncontext->user); - if (!user2) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - if (strcmp(server1, server2) || strcmp(share1, share2) || - strcmp(user1, user2)) { - /* Can't rename across file systems, or users?? */ - errno = EXDEV; - TALLOC_FREE(frame); - return -1; - } - - srv = smbc_server(frame, ocontext, True, - server1, share1, &workgroup, &user1, &password1); - if (!srv) { - TALLOC_FREE(frame); - return -1; - - } - - /*d_printf(">>>rename: resolving %s\n", path1);*/ - if (!cli_resolve_path(frame, "", srv->cli, path1, - &targetcli1, &targetpath1)) { - d_printf("Could not resolve %s\n", path1); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ - /*d_printf(">>>rename: resolving %s\n", path2);*/ - if (!cli_resolve_path(frame, "", srv->cli, path2, - &targetcli2, &targetpath2)) { - d_printf("Could not resolve %s\n", path2); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ - - if (strcmp(targetcli1->desthost, targetcli2->desthost) || - strcmp(targetcli1->share, targetcli2->share)) - { - /* can't rename across file systems */ - errno = EXDEV; - TALLOC_FREE(frame); - return -1; - } - - if (!cli_rename(targetcli1, targetpath1, targetpath2)) { - int eno = smbc_errno(ocontext, targetcli1); - - if (eno != EEXIST || - !cli_unlink(targetcli1, targetpath2) || - !cli_rename(targetcli1, targetpath1, targetpath2)) { - - errno = eno; - TALLOC_FREE(frame); - return -1; - - } - } - - TALLOC_FREE(frame); - return 0; /* Success */ -} - -/* - * A routine to lseek() a file - */ - -static off_t -smbc_lseek_ctx(SMBCCTX *context, - SMBCFILE *file, - off_t offset, - int whence) -{ - SMB_OFF_T size; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - - errno = EBADF; - TALLOC_FREE(frame); - return -1; - - } - - if (!file->file) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; /* Can't lseek a dir ... */ - - } - - switch (whence) { - case SEEK_SET: - file->offset = offset; - break; - - case SEEK_CUR: - file->offset += offset; - break; - - case SEEK_END: - /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>lseek: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ - - if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, - &size, NULL, NULL, NULL, NULL, NULL)) - { - SMB_OFF_T b_size = size; - if (!cli_getattrE(targetcli, file->cli_fd, - NULL, &b_size, NULL, NULL, NULL)) - { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } else - size = b_size; - } - file->offset = size + offset; - break; - - default: - errno = EINVAL; - break; - - } - - TALLOC_FREE(frame); - return file->offset; - -} - -/* - * Generate an inode number from file name for those things that need it - */ - -static ino_t -smbc_inode(SMBCCTX *context, - const char *name) -{ - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - return -1; - - } - - if (!*name) return 2; /* FIXME, why 2 ??? */ - return (ino_t)str_checksum(name); - -} - -/* - * Routine to put basic stat info into a stat structure ... Used by stat and - * fstat below. - */ - -static int -smbc_setup_stat(SMBCCTX *context, - struct stat *st, - char *fname, - SMB_OFF_T size, - int mode) -{ - TALLOC_CTX *frame = talloc_stackframe(); - - st->st_mode = 0; - - if (IS_DOS_DIR(mode)) { - st->st_mode = SMBC_DIR_MODE; - } else { - st->st_mode = SMBC_FILE_MODE; - } - - if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; - if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; - if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; - if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; - - st->st_size = size; -#ifdef HAVE_STAT_ST_BLKSIZE - st->st_blksize = 512; -#endif -#ifdef HAVE_STAT_ST_BLOCKS - st->st_blocks = (size+511)/512; -#endif -#ifdef HAVE_STRUCT_STAT_ST_RDEV - st->st_rdev = 0; -#endif - st->st_uid = getuid(); - st->st_gid = getgid(); - - if (IS_DOS_DIR(mode)) { - st->st_nlink = 2; - } else { - st->st_nlink = 1; - } - - if (st->st_ino == 0) { - st->st_ino = smbc_inode(context, fname); - } - - TALLOC_FREE(frame); - return True; /* FIXME: Is this needed ? */ - -} - -/* - * Routine to stat a file given a name - */ - -static int -smbc_stat_ctx(SMBCCTX *context, - const char *fname, - struct stat *st) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - struct timespec write_time_ts; - struct timespec access_time_ts; - struct timespec change_time_ts; - SMB_OFF_T size = 0; - uint16 mode = 0; - SMB_INO_T ino = 0; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_stat(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame,context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (!smbc_getatr(context, srv, path, &mode, &size, - NULL, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &ino)) { - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return -1; - } - - st->st_ino = ino; - - smbc_setup_stat(context, st, (char *) fname, size, mode); - - set_atimespec(st, access_time_ts); - set_ctimespec(st, change_time_ts); - set_mtimespec(st, write_time_ts); - st->st_dev = srv->dev; - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Routine to stat a file given an fd - */ - -static int -smbc_fstat_ctx(SMBCCTX *context, - SMBCFILE *file, - struct stat *st) -{ - struct timespec change_time_ts; - struct timespec access_time_ts; - struct timespec write_time_ts; - SMB_OFF_T size; - uint16 mode; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - SMB_INO_T ino = 0; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - if (!file->file) { - TALLOC_FREE(frame); - return (context->fstatdir)(context, file, st); - } - - /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - - if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, - NULL, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &ino)) { - - time_t change_time, access_time, write_time; - - if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, - &change_time, &access_time, &write_time)) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - change_time_ts = convert_time_t_to_timespec(change_time); - access_time_ts = convert_time_t_to_timespec(access_time); - write_time_ts = convert_time_t_to_timespec(write_time); - } - - st->st_ino = ino; - - smbc_setup_stat(context, st, file->fname, size, mode); - - set_atimespec(st, access_time_ts); - set_ctimespec(st, change_time_ts); - set_mtimespec(st, write_time_ts); - st->st_dev = file->srv->dev; - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Routine to truncate a file given by its file descriptor, to a specified size - */ - -static int -smbc_ftruncate_ctx(SMBCCTX *context, - SMBCFILE *file, - off_t length) -{ - SMB_OFF_T size = length; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!file || !DLIST_CONTAINS(context->internal->_files, file)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - if (!file->file) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ - if (smbc_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - /*d_printf(">>>fstat: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", file->srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - - if (!cli_ftruncate(targetcli, file->cli_fd, size)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Routine to open a directory - * We accept the URL syntax explained in smbc_parse_path(), above. - */ - -static void -smbc_remove_dir(SMBCFILE *dir) -{ - struct smbc_dir_list *d,*f; - - d = dir->dir_list; - while (d) { - - f = d; d = d->next; - - SAFE_FREE(f->dirent); - SAFE_FREE(f); - - } - - dir->dir_list = dir->dir_end = dir->dir_next = NULL; - -} - -static int -add_dirent(SMBCFILE *dir, - const char *name, - const char *comment, - uint32 type) -{ - struct smbc_dirent *dirent; - int size; - int name_length = (name == NULL ? 0 : strlen(name)); - int comment_len = (comment == NULL ? 0 : strlen(comment)); - - /* - * Allocate space for the dirent, which must be increased by the - * size of the name and the comment and 1 each for the null terminator. - */ - - size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; - - dirent = (struct smbc_dirent *)SMB_MALLOC(size); - - if (!dirent) { - - dir->dir_error = ENOMEM; - return -1; - - } - - ZERO_STRUCTP(dirent); - - if (dir->dir_list == NULL) { - - dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); - if (!dir->dir_list) { - - SAFE_FREE(dirent); - dir->dir_error = ENOMEM; - return -1; - - } - ZERO_STRUCTP(dir->dir_list); - - dir->dir_end = dir->dir_next = dir->dir_list; - } - else { - - dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); - - if (!dir->dir_end->next) { - - SAFE_FREE(dirent); - dir->dir_error = ENOMEM; - return -1; - - } - ZERO_STRUCTP(dir->dir_end->next); - - dir->dir_end = dir->dir_end->next; - } - - dir->dir_end->next = NULL; - dir->dir_end->dirent = dirent; - - dirent->smbc_type = type; - dirent->namelen = name_length; - dirent->commentlen = comment_len; - dirent->dirlen = size; - - /* - * dirent->namelen + 1 includes the null (no null termination needed) - * Ditto for dirent->commentlen. - * The space for the two null bytes was allocated. - */ - strncpy(dirent->name, (name?name:""), dirent->namelen + 1); - dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); - strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); - - return 0; - -} - -static void -list_unique_wg_fn(const char *name, - uint32 type, - const char *comment, - void *state) -{ - SMBCFILE *dir = (SMBCFILE *)state; - struct smbc_dir_list *dir_list; - struct smbc_dirent *dirent; - int dirent_type; - int do_remove = 0; - - dirent_type = dir->dir_type; - - if (add_dirent(dir, name, comment, dirent_type) < 0) { - - /* An error occurred, what do we do? */ - /* FIXME: Add some code here */ - } - - /* Point to the one just added */ - dirent = dir->dir_end->dirent; - - /* See if this was a duplicate */ - for (dir_list = dir->dir_list; - dir_list != dir->dir_end; - dir_list = dir_list->next) { - if (! do_remove && - strcmp(dir_list->dirent->name, dirent->name) == 0) { - /* Duplicate. End end of list need to be removed. */ - do_remove = 1; - } - - if (do_remove && dir_list->next == dir->dir_end) { - /* Found the end of the list. Remove it. */ - dir->dir_end = dir_list; - free(dir_list->next); - free(dirent); - dir_list->next = NULL; - break; - } - } -} - -static void -list_fn(const char *name, - uint32 type, - const char *comment, - void *state) -{ - SMBCFILE *dir = (SMBCFILE *)state; - int dirent_type; - - /* - * We need to process the type a little ... - * - * Disk share = 0x00000000 - * Print share = 0x00000001 - * Comms share = 0x00000002 (obsolete?) - * IPC$ share = 0x00000003 - * - * administrative shares: - * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 - */ - - if (dir->dir_type == SMBC_FILE_SHARE) { - switch (type) { - case 0 | 0x80000000: - case 0: - dirent_type = SMBC_FILE_SHARE; - break; - - case 1: - dirent_type = SMBC_PRINTER_SHARE; - break; - - case 2: - dirent_type = SMBC_COMMS_SHARE; - break; - - case 3 | 0x80000000: - case 3: - dirent_type = SMBC_IPC_SHARE; - break; - - default: - dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ - break; - } - } - else { - dirent_type = dir->dir_type; - } - - if (add_dirent(dir, name, comment, dirent_type) < 0) { - - /* An error occurred, what do we do? */ - /* FIXME: Add some code here */ - - } -} - -static void -dir_list_fn(const char *mnt, - file_info *finfo, - const char *mask, - void *state) -{ - - if (add_dirent((SMBCFILE *)state, finfo->name, "", - (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { - - /* Handle an error ... */ - - /* FIXME: Add some code ... */ - - } - -} - -static int -net_share_enum_rpc(struct cli_state *cli, - void (*fn)(const char *name, - uint32 type, - const char *comment, - void *state), - void *state) -{ - int i; - WERROR result; - ENUM_HND enum_hnd; - uint32 info_level = 1; - uint32 preferred_len = 0xffffffff; - uint32 type; - SRV_SHARE_INFO_CTR ctr; - fstring name = ""; - fstring comment = ""; - struct rpc_pipe_client *pipe_hnd; - NTSTATUS nt_status; - - /* Open the server service pipe */ - pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); - if (!pipe_hnd) { - DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); - return -1; - } - - /* Issue the NetShareEnum RPC call and retrieve the response */ - init_enum_hnd(&enum_hnd, 0); - result = rpccli_srvsvc_net_share_enum(pipe_hnd, - talloc_tos(), - info_level, - &ctr, - preferred_len, - &enum_hnd); - - /* Was it successful? */ - if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { - /* Nope. Go clean up. */ - goto done; - } - - /* For each returned entry... */ - for (i = 0; i < ctr.num_entries; i++) { - - /* pull out the share name */ - rpcstr_pull_unistr2_fstring( - name, &ctr.share.info1[i].info_1_str.uni_netname); - - /* pull out the share's comment */ - rpcstr_pull_unistr2_fstring( - comment, &ctr.share.info1[i].info_1_str.uni_remark); - - /* Get the type value */ - type = ctr.share.info1[i].info_1.type; - - /* Add this share to the list */ - (*fn)(name, type, comment, state); - } - -done: - /* Close the server service pipe */ - cli_rpc_pipe_close(pipe_hnd); - - /* Tell 'em if it worked */ - return W_ERROR_IS_OK(result) ? 0 : -1; -} - - - -static SMBCFILE * -smbc_opendir_ctx(SMBCCTX *context, - const char *fname) -{ - int saved_errno; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *options = NULL; - char *workgroup = NULL; - char *path = NULL; - uint16 mode; - char *p = NULL; - SMBCSRV *srv = NULL; - SMBCFILE *dir = NULL; - struct _smbc_callbacks *cb = NULL; - struct sockaddr_storage rem_ss; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - DEBUG(4, ("no valid context\n")); - errno = EINVAL + 8192; - TALLOC_FREE(frame); - return NULL; - - } - - if (!fname) { - DEBUG(4, ("no valid fname\n")); - errno = EINVAL + 8193; - TALLOC_FREE(frame); - return NULL; - } - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - &options)) { - DEBUG(4, ("no valid path\n")); - errno = EINVAL + 8194; - TALLOC_FREE(frame); - return NULL; - } - - DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' " - "path='%s' options='%s'\n", - fname, server, share, path, options)); - - /* Ensure the options are valid */ - if (smbc_check_options(server, share, path, options)) { - DEBUG(4, ("unacceptable options (%s)\n", options)); - errno = EINVAL + 8195; - TALLOC_FREE(frame); - return NULL; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - } - - dir = SMB_MALLOC_P(SMBCFILE); - - if (!dir) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - - ZERO_STRUCTP(dir); - - dir->cli_fd = 0; - dir->fname = SMB_STRDUP(fname); - dir->srv = NULL; - dir->offset = 0; - dir->file = False; - dir->dir_list = dir->dir_next = dir->dir_end = NULL; - - if (server[0] == (char)0) { - - int i; - int count; - int max_lmb_count; - struct ip_service *ip_list; - struct ip_service server_addr; - struct user_auth_info u_info; - - if (share[0] != (char)0 || path[0] != (char)0) { - - errno = EINVAL + 8196; - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - /* Determine how many local master browsers to query */ - max_lmb_count = (context->options.browse_max_lmb_count == 0 - ? INT_MAX - : context->options.browse_max_lmb_count); - - memset(&u_info, '\0', sizeof(u_info)); - u_info.username = talloc_strdup(frame,user); - u_info.password = talloc_strdup(frame,password); - if (!u_info.username || !u_info.password) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - /* - * We have server and share and path empty but options - * requesting that we scan all master browsers for their list - * of workgroups/domains. This implies that we must first try - * broadcast queries to find all master browsers, and if that - * doesn't work, then try our other methods which return only - * a single master browser. - */ - - ip_list = NULL; - if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, - &count))) - { - - SAFE_FREE(ip_list); - - if (!find_master_ip(workgroup, &server_addr.ss)) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - errno = ENOENT; - TALLOC_FREE(frame); - return NULL; - } - - ip_list = (struct ip_service *)memdup( - &server_addr, sizeof(server_addr)); - if (ip_list == NULL) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - count = 1; - } - - for (i = 0; i < count && i < max_lmb_count; i++) { - char addr[INET6_ADDRSTRLEN]; - char *wg_ptr = NULL; - struct cli_state *cli = NULL; - - print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); - DEBUG(99, ("Found master browser %d of %d: %s\n", - i+1, MAX(count, max_lmb_count), - addr)); - - cli = get_ipc_connect_master_ip(talloc_tos(), - &ip_list[i], - &u_info, - &wg_ptr); - /* cli == NULL is the master browser refused to talk or - could not be found */ - if (!cli) { - continue; - } - - workgroup = talloc_strdup(frame, wg_ptr); - server = talloc_strdup(frame, cli->desthost); - - cli_shutdown(cli); - - if (!workgroup || !server) { - errno = ENOMEM; - TALLOC_FREE(frame); - return NULL; - } - - DEBUG(4, ("using workgroup %s %s\n", - workgroup, server)); - - /* - * For each returned master browser IP address, get a - * connection to IPC$ on the server if we do not - * already have one, and determine the - * workgroups/domains that it knows about. - */ - - srv = smbc_server(frame, context, True, server, "IPC$", - &workgroup, &user, &password); - if (!srv) { - continue; - } - - dir->srv = srv; - dir->dir_type = SMBC_WORKGROUP; - - /* Now, list the stuff ... */ - - if (!cli_NetServerEnum(srv->cli, - workgroup, - SV_TYPE_DOMAIN_ENUM, - list_unique_wg_fn, - (void *)dir)) { - continue; - } - } - - SAFE_FREE(ip_list); - } else { - /* - * Server not an empty string ... Check the rest and see what - * gives - */ - if (*share == '\0') { - if (*path != '\0') { - - /* Should not have empty share with path */ - errno = EINVAL + 8197; - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - - } - - /* - * We don't know if is really a server name - * or is a workgroup/domain name. If we already have - * a server structure for it, we'll use it. - * Otherwise, check to see if <1D>, - * <1B>, or <20> translates. We check - * to see if is an IP address first. - */ - - /* - * See if we have an existing server. Do not - * establish a connection if one does not already - * exist. - */ - srv = smbc_server(frame, context, False, server, "IPC$", - &workgroup, &user, &password); - - /* - * If no existing server and not an IP addr, look for - * LMB or DMB - */ - if (!srv && - !is_ipaddress(server) && - (resolve_name(server, &rem_ss, 0x1d) || /* LMB */ - resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */ - - fstring buserver; - - dir->dir_type = SMBC_SERVER; - - /* - * Get the backup list ... - */ - if (!name_status_find(server, 0, 0, - &rem_ss, buserver)) { - - DEBUG(0, ("Could not get name of " - "local/domain master browser " - "for server %s\n", server)); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - errno = EPERM; - TALLOC_FREE(frame); - return NULL; - - } - - /* - * Get a connection to IPC$ on the server if - * we do not already have one - */ - srv = smbc_server(frame, context, True, - buserver, "IPC$", - &workgroup, &user, &password); - if (!srv) { - DEBUG(0, ("got no contact to IPC$\n")); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - - } - - dir->srv = srv; - - /* Now, list the servers ... */ - if (!cli_NetServerEnum(srv->cli, server, - 0x0000FFFE, list_fn, - (void *)dir)) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - } else if (srv || - (resolve_name(server, &rem_ss, 0x20))) { - - /* If we hadn't found the server, get one now */ - if (!srv) { - srv = smbc_server(frame, context, True, - server, "IPC$", - &workgroup, - &user, &password); - } - - if (!srv) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - - } - - dir->dir_type = SMBC_FILE_SHARE; - dir->srv = srv; - - /* List the shares ... */ - - if (net_share_enum_rpc( - srv->cli, - list_fn, - (void *) dir) < 0 && - cli_RNetShareEnum( - srv->cli, - list_fn, - (void *)dir) < 0) { - - errno = cli_errno(srv->cli); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - - } - } else { - /* Neither the workgroup nor server exists */ - errno = ECONNREFUSED; - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - } - else { - /* - * The server and share are specified ... work from - * there ... - */ - char *targetpath; - struct cli_state *targetcli; - - /* We connect to the server and list the directory */ - dir->dir_type = SMBC_FILE_SHARE; - - srv = smbc_server(frame, context, True, server, share, - &workgroup, &user, &password); - - if (!srv) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - dir->srv = srv; - - /* Now, list the files ... */ - - p = path + strlen(path); - path = talloc_asprintf_append(path, "\\*"); - if (!path) { - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - TALLOC_FREE(frame); - return NULL; - } - - if (cli_list(targetcli, targetpath, - aDIR | aSYSTEM | aHIDDEN, - dir_list_fn, (void *)dir) < 0) { - - if (dir) { - SAFE_FREE(dir->fname); - SAFE_FREE(dir); - } - saved_errno = smbc_errno(context, targetcli); - - if (saved_errno == EINVAL) { - /* - * See if they asked to opendir something - * other than a directory. If so, the - * converted error value we got would have - * been EINVAL rather than ENOTDIR. - */ - *p = '\0'; /* restore original path */ - - if (smbc_getatr(context, srv, path, - &mode, NULL, - NULL, NULL, NULL, NULL, - NULL) && - ! IS_DOS_DIR(mode)) { - - /* It is. Correct the error value */ - saved_errno = ENOTDIR; - } - } - - /* - * If there was an error and the server is no - * good any more... - */ - cb = &context->callbacks; - if (cli_is_error(targetcli) && - (cb->check_server_fn)(context, srv)) { - - /* ... then remove it. */ - if ((cb->remove_unused_server_fn)(context, - srv)) { - /* - * We could not remove the - * server completely, remove - * it from the cache so we - * will not get it again. It - * will be removed when the - * last file/dir is closed. - */ - (cb->remove_cached_srv_fn)(context, - srv); - } - } - - errno = saved_errno; - TALLOC_FREE(frame); - return NULL; - } - } - - } - - DLIST_ADD(context->internal->_files, dir); - TALLOC_FREE(frame); - return dir; - -} - -/* - * Routine to close a directory - */ - -static int -smbc_closedir_ctx(SMBCCTX *context, - SMBCFILE *dir) -{ - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - errno = EBADF; - TALLOC_FREE(frame); - return -1; - } - - smbc_remove_dir(dir); /* Clean it up */ - - DLIST_REMOVE(context->internal->_files, dir); - - if (dir) { - - SAFE_FREE(dir->fname); - SAFE_FREE(dir); /* Free the space too */ - } - - TALLOC_FREE(frame); - return 0; - -} - -static void -smbc_readdir_internal(SMBCCTX * context, - struct smbc_dirent *dest, - struct smbc_dirent *src, - int max_namebuf_len) -{ - if (context->options.urlencode_readdir_entries) { - - /* url-encode the name. get back remaining buffer space */ - max_namebuf_len = - smbc_urlencode(dest->name, src->name, max_namebuf_len); - - /* We now know the name length */ - dest->namelen = strlen(dest->name); - - /* Save the pointer to the beginning of the comment */ - dest->comment = dest->name + dest->namelen + 1; - - /* Copy the comment */ - strncpy(dest->comment, src->comment, max_namebuf_len - 1); - dest->comment[max_namebuf_len - 1] = '\0'; - - /* Save other fields */ - dest->smbc_type = src->smbc_type; - dest->commentlen = strlen(dest->comment); - dest->dirlen = ((dest->comment + dest->commentlen + 1) - - (char *) dest); - } else { - - /* No encoding. Just copy the entry as is. */ - memcpy(dest, src, src->dirlen); - dest->comment = (char *)(&dest->name + src->namelen + 1); - } - -} - -/* - * Routine to get a directory entry - */ - -struct smbc_dirent * -smbc_readdir_ctx(SMBCCTX *context, - SMBCFILE *dir) -{ - int maxlen; - struct smbc_dirent *dirp, *dirent; - TALLOC_CTX *frame = talloc_stackframe(); - - /* Check that all is ok first ... */ - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - DEBUG(0, ("Invalid context in smbc_readdir_ctx()\n")); - TALLOC_FREE(frame); - return NULL; - - } - - if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - - errno = EBADF; - DEBUG(0, ("Invalid dir in smbc_readdir_ctx()\n")); - TALLOC_FREE(frame); - return NULL; - - } - - if (dir->file != False) { /* FIXME, should be dir, perhaps */ - - errno = ENOTDIR; - DEBUG(0, ("Found file vs directory in smbc_readdir_ctx()\n")); - TALLOC_FREE(frame); - return NULL; - - } - - if (!dir->dir_next) { - TALLOC_FREE(frame); - return NULL; - } - - dirent = dir->dir_next->dirent; - if (!dirent) { - - errno = ENOENT; - TALLOC_FREE(frame); - return NULL; - - } - - dirp = (struct smbc_dirent *)context->internal->_dirent; - maxlen = (sizeof(context->internal->_dirent) - - sizeof(struct smbc_dirent)); - - smbc_readdir_internal(context, dirp, dirent, maxlen); - - dir->dir_next = dir->dir_next->next; - - TALLOC_FREE(frame); - return dirp; -} - -/* - * Routine to get directory entries - */ - -static int -smbc_getdents_ctx(SMBCCTX *context, - SMBCFILE *dir, - struct smbc_dirent *dirp, - int count) -{ - int rem = count; - int reqd; - int maxlen; - char *ndir = (char *)dirp; - struct smbc_dir_list *dirlist; - TALLOC_CTX *frame = talloc_stackframe(); - - /* Check that all is ok first ... */ - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - - errno = EBADF; - TALLOC_FREE(frame); - return -1; - - } - - if (dir->file != False) { /* FIXME, should be dir, perhaps */ - - errno = ENOTDIR; - TALLOC_FREE(frame); - return -1; - - } - - /* - * Now, retrieve the number of entries that will fit in what was passed - * We have to figure out if the info is in the list, or we need to - * send a request to the server to get the info. - */ - - while ((dirlist = dir->dir_next)) { - struct smbc_dirent *dirent; - - if (!dirlist->dirent) { - - errno = ENOENT; /* Bad error */ - TALLOC_FREE(frame); - return -1; - - } - - /* Do urlencoding of next entry, if so selected */ - dirent = (struct smbc_dirent *)context->internal->_dirent; - maxlen = (sizeof(context->internal->_dirent) - - sizeof(struct smbc_dirent)); - smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen); - - reqd = dirent->dirlen; - - if (rem < reqd) { - - if (rem < count) { /* We managed to copy something */ - - errno = 0; - TALLOC_FREE(frame); - return count - rem; - - } - else { /* Nothing copied ... */ - - errno = EINVAL; /* Not enough space ... */ - TALLOC_FREE(frame); - return -1; - - } - - } - - memcpy(ndir, dirent, reqd); /* Copy the data in ... */ - - ((struct smbc_dirent *)ndir)->comment = - (char *)(&((struct smbc_dirent *)ndir)->name + - dirent->namelen + - 1); - - ndir += reqd; - - rem -= reqd; - - dir->dir_next = dirlist = dirlist -> next; - } - - TALLOC_FREE(frame); - - if (rem == count) - return 0; - else - return count - rem; - -} - -/* - * Routine to create a directory ... - */ - -static int -smbc_mkdir_ctx(SMBCCTX *context, - const char *fname, - mode_t mode) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - - } - - /*d_printf(">>>mkdir: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ - - if (!cli_mkdir(targetcli, targetpath)) { - - errno = smbc_errno(context, targetcli); - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Our list function simply checks to see if a directory is not empty - */ - -static int smbc_rmdir_dirempty = True; - -static void -rmdir_list_fn(const char *mnt, - file_info *finfo, - const char *mask, - void *state) -{ - if (strncmp(finfo->name, ".", 1) != 0 && - strncmp(finfo->name, "..", 2) != 0) { - smbc_rmdir_dirempty = False; - } -} - -/* - * Routine to remove a directory - */ - -static int -smbc_rmdir_ctx(SMBCCTX *context, - const char *fname) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - char *targetpath = NULL; - struct cli_state *targetcli = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - - } - - /*d_printf(">>>rmdir: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { - d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); - return -1; - } - /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ - - - if (!cli_rmdir(targetcli, targetpath)) { - - errno = smbc_errno(context, targetcli); - - if (errno == EACCES) { /* Check if the dir empty or not */ - - /* Local storage to avoid buffer overflows */ - char *lpath; - - smbc_rmdir_dirempty = True; /* Make this so ... */ - - lpath = talloc_asprintf(frame, "%s\\*", - targetpath); - if (!lpath) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - - if (cli_list(targetcli, lpath, - aDIR | aSYSTEM | aHIDDEN, - rmdir_list_fn, NULL) < 0) { - - /* Fix errno to ignore latest error ... */ - DEBUG(5, ("smbc_rmdir: " - "cli_list returned an error: %d\n", - smbc_errno(context, targetcli))); - errno = EACCES; - - } - - if (smbc_rmdir_dirempty) - errno = EACCES; - else - errno = ENOTEMPTY; - - } - - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Routine to return the current directory position - */ - -static off_t -smbc_telldir_ctx(SMBCCTX *context, - SMBCFILE *dir) -{ - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (!dir || !DLIST_CONTAINS(context->internal->_files, dir)) { - - errno = EBADF; - TALLOC_FREE(frame); - return -1; - - } - - if (dir->file != False) { /* FIXME, should be dir, perhaps */ - - errno = ENOTDIR; - TALLOC_FREE(frame); - return -1; - - } - - /* See if we're already at the end. */ - if (dir->dir_next == NULL) { - /* We are. */ - TALLOC_FREE(frame); - return -1; - } - - /* - * We return the pointer here as the offset - */ - TALLOC_FREE(frame); - return (off_t)(long)dir->dir_next->dirent; -} - -/* - * A routine to run down the list and see if the entry is OK - */ - -struct smbc_dir_list * -smbc_check_dir_ent(struct smbc_dir_list *list, - struct smbc_dirent *dirent) -{ - - /* Run down the list looking for what we want */ - - if (dirent) { - - struct smbc_dir_list *tmp = list; - - while (tmp) { - - if (tmp->dirent == dirent) - return tmp; - - tmp = tmp->next; - - } - - } - - return NULL; /* Not found, or an error */ - -} - - -/* - * Routine to seek on a directory - */ - -static int -smbc_lseekdir_ctx(SMBCCTX *context, - SMBCFILE *dir, - off_t offset) -{ - long int l_offset = offset; /* Handle problems of size */ - struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; - struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (dir->file != False) { /* FIXME, should be dir, perhaps */ - - errno = ENOTDIR; - TALLOC_FREE(frame); - return -1; - - } - - /* Now, check what we were passed and see if it is OK ... */ - - if (dirent == NULL) { /* Seek to the begining of the list */ - - dir->dir_next = dir->dir_list; - TALLOC_FREE(frame); - return 0; - - } - - if (offset == -1) { /* Seek to the end of the list */ - dir->dir_next = NULL; - TALLOC_FREE(frame); - return 0; - } - - /* Now, run down the list and make sure that the entry is OK */ - /* This may need to be changed if we change the format of the list */ - - if ((list_ent = smbc_check_dir_ent(dir->dir_list, dirent)) == NULL) { - errno = EINVAL; /* Bad entry */ - TALLOC_FREE(frame); - return -1; - } - - dir->dir_next = list_ent; - - TALLOC_FREE(frame); - return 0; -} - -/* - * Routine to fstat a dir - */ - -static int -smbc_fstatdir_ctx(SMBCCTX *context, - SMBCFILE *dir, - struct stat *st) -{ - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - return -1; - } - - /* No code yet ... */ - return 0; -} - -static int -smbc_chmod_ctx(SMBCCTX *context, - const char *fname, - mode_t newmode) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - uint16 mode; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - mode = 0; - - if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; - if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; - if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; - if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - - if (!cli_setatr(srv->cli, path, mode, 0)) { - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return -1; - } - - TALLOC_FREE(frame); - return 0; -} - -static int -smbc_utimes_ctx(SMBCCTX *context, - const char *fname, - struct timeval *tbuf) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - time_t access_time; - time_t write_time; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (tbuf == NULL) { - access_time = write_time = time(NULL); - } else { - access_time = tbuf[0].tv_sec; - write_time = tbuf[1].tv_sec; - } - - if (DEBUGLVL(4)) { - char *p; - char atimebuf[32]; - char mtimebuf[32]; - - strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1); - atimebuf[sizeof(atimebuf) - 1] = '\0'; - if ((p = strchr(atimebuf, '\n')) != NULL) { - *p = '\0'; - } - - strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1); - mtimebuf[sizeof(mtimebuf) - 1] = '\0'; - if ((p = strchr(mtimebuf, '\n')) != NULL) { - *p = '\0'; - } - - dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n", - fname, atimebuf, mtimebuf); - } - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (!smbc_setatr(context, srv, path, - 0, access_time, write_time, 0, 0)) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_setatr */ - } - - TALLOC_FREE(frame); - return 0; -} - - -/* - * Sort ACEs according to the documentation at - * http://support.microsoft.com/kb/269175, at least as far as it defines the - * order. - */ - -static int -ace_compare(SEC_ACE *ace1, - SEC_ACE *ace2) -{ - bool b1; - bool b2; - - /* If the ACEs are equal, we have nothing more to do. */ - if (sec_ace_equal(ace1, ace2)) { - return 0; - } - - /* Inherited follow non-inherited */ - b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); - b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); - if (b1 != b2) { - return (b1 ? 1 : -1); - } - - /* - * What shall we do with AUDITs and ALARMs? It's undefined. We'll - * sort them after DENY and ALLOW. - */ - b1 = (ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED && - ace1->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && - ace1->type != SEC_ACE_TYPE_ACCESS_DENIED && - ace1->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); - b2 = (ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED && - ace2->type != SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT && - ace2->type != SEC_ACE_TYPE_ACCESS_DENIED && - ace2->type != SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); - if (b1 != b2) { - return (b1 ? 1 : -1); - } - - /* Allowed ACEs follow denied ACEs */ - b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || - ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); - b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED || - ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); - if (b1 != b2) { - return (b1 ? 1 : -1); - } - - /* - * ACEs applying to an entity's object follow those applying to the - * entity itself - */ - b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - ace1->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); - b2 = (ace2->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT || - ace2->type == SEC_ACE_TYPE_ACCESS_DENIED_OBJECT); - if (b1 != b2) { - return (b1 ? 1 : -1); - } - - /* - * If we get this far, the ACEs are similar as far as the - * characteristics we typically care about (those defined by the - * referenced MS document). We'll now sort by characteristics that - * just seems reasonable. - */ - - if (ace1->type != ace2->type) { - return ace2->type - ace1->type; - } - - if (sid_compare(&ace1->trustee, &ace2->trustee)) { - return sid_compare(&ace1->trustee, &ace2->trustee); - } - - if (ace1->flags != ace2->flags) { - return ace1->flags - ace2->flags; - } - - if (ace1->access_mask != ace2->access_mask) { - return ace1->access_mask - ace2->access_mask; - } - - if (ace1->size != ace2->size) { - return ace1->size - ace2->size; - } - - return memcmp(ace1, ace2, sizeof(SEC_ACE)); -} - - -static void -sort_acl(SEC_ACL *the_acl) -{ - uint32 i; - if (!the_acl) return; - - qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), - QSORT_CAST ace_compare); - - for (i=1;inum_aces;) { - if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { - int j; - for (j=i; jnum_aces-1; j++) { - the_acl->aces[j] = the_acl->aces[j+1]; - } - the_acl->num_aces--; - } else { - i++; - } - } -} - -/* convert a SID to a string, either numeric or username/group */ -static void -convert_sid_to_string(struct cli_state *ipc_cli, - POLICY_HND *pol, - fstring str, - bool numeric, - DOM_SID *sid) -{ - char **domains = NULL; - char **names = NULL; - enum lsa_SidType *types = NULL; - struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); - TALLOC_CTX *ctx; - - sid_to_fstring(str, sid); - - if (numeric) { - return; /* no lookup desired */ - } - - if (!pipe_hnd) { - return; - } - - /* Ask LSA to convert the sid to a name */ - - ctx = talloc_stackframe(); - - if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, - pol, 1, sid, &domains, - &names, &types)) || - !domains || !domains[0] || !names || !names[0]) { - TALLOC_FREE(ctx); - return; - } - - TALLOC_FREE(ctx); - /* Converted OK */ - - slprintf(str, sizeof(fstring) - 1, "%s%s%s", - domains[0], lp_winbind_separator(), - names[0]); -} - -/* convert a string to a SID, either numeric or username/group */ -static bool -convert_string_to_sid(struct cli_state *ipc_cli, - POLICY_HND *pol, - bool numeric, - DOM_SID *sid, - const char *str) -{ - enum lsa_SidType *types = NULL; - DOM_SID *sids = NULL; - bool result = True; - TALLOC_CTX *ctx = NULL; - struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); - - if (!pipe_hnd) { - return False; - } - - if (numeric) { - if (strncmp(str, "S-", 2) == 0) { - return string_to_sid(sid, str); - } - - result = False; - goto done; - } - - ctx = talloc_stackframe(); - if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, - pol, 1, &str, NULL, 1, &sids, - &types))) { - result = False; - goto done; - } - - sid_copy(sid, &sids[0]); - done: - - TALLOC_FREE(ctx); - return result; -} - - -/* parse an ACE in the same format as print_ace() */ -static bool -parse_ace(struct cli_state *ipc_cli, - POLICY_HND *pol, - SEC_ACE *ace, - bool numeric, - char *str) -{ - char *p; - const char *cp; - char *tok; - unsigned int atype; - unsigned int aflags; - unsigned int amask; - DOM_SID sid; - SEC_ACCESS mask; - const struct perm_value *v; - struct perm_value { - const char *perm; - uint32 mask; - }; - TALLOC_CTX *frame = talloc_stackframe(); - - /* These values discovered by inspection */ - static const struct perm_value special_values[] = { - { "R", 0x00120089 }, - { "W", 0x00120116 }, - { "X", 0x001200a0 }, - { "D", 0x00010000 }, - { "P", 0x00040000 }, - { "O", 0x00080000 }, - { NULL, 0 }, - }; - - static const struct perm_value standard_values[] = { - { "READ", 0x001200a9 }, - { "CHANGE", 0x001301bf }, - { "FULL", 0x001f01ff }, - { NULL, 0 }, - }; - - - ZERO_STRUCTP(ace); - p = strchr_m(str,':'); - if (!p) { - TALLOC_FREE(frame); - return False; - } - *p = '\0'; - p++; - /* Try to parse numeric form */ - - if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && - convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { - goto done; - } - - /* Try to parse text form */ - - if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { - TALLOC_FREE(frame); - return false; - } - - cp = p; - if (!next_token_talloc(frame, &cp, &tok, "/")) { - TALLOC_FREE(frame); - return false; - } - - if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { - atype = SEC_ACE_TYPE_ACCESS_ALLOWED; - } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { - atype = SEC_ACE_TYPE_ACCESS_DENIED; - } else { - TALLOC_FREE(frame); - return false; - } - - /* Only numeric form accepted for flags at present */ - - if (!(next_token_talloc(frame, &cp, &tok, "/") && - sscanf(tok, "%i", &aflags))) { - TALLOC_FREE(frame); - return false; - } - - if (!next_token_talloc(frame, &cp, &tok, "/")) { - TALLOC_FREE(frame); - return false; - } - - if (strncmp(tok, "0x", 2) == 0) { - if (sscanf(tok, "%i", &amask) != 1) { - TALLOC_FREE(frame); - return false; - } - goto done; - } - - for (v = standard_values; v->perm; v++) { - if (strcmp(tok, v->perm) == 0) { - amask = v->mask; - goto done; - } - } - - p = tok; - - while(*p) { - bool found = False; - - for (v = special_values; v->perm; v++) { - if (v->perm[0] == *p) { - amask |= v->mask; - found = True; - } - } - - if (!found) { - TALLOC_FREE(frame); - return false; - } - p++; - } - - if (*p) { - TALLOC_FREE(frame); - return false; - } - - done: - mask = amask; - init_sec_ace(ace, &sid, atype, mask, aflags); - TALLOC_FREE(frame); - return true; -} - -/* add an ACE to a list of ACEs in a SEC_ACL */ -static bool -add_ace(SEC_ACL **the_acl, - SEC_ACE *ace, - TALLOC_CTX *ctx) -{ - SEC_ACL *newacl; - SEC_ACE *aces; - - if (! *the_acl) { - (*the_acl) = make_sec_acl(ctx, 3, 1, ace); - return True; - } - - if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { - return False; - } - memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); - memcpy(aces+(*the_acl)->num_aces, ace, sizeof(SEC_ACE)); - newacl = make_sec_acl(ctx, (*the_acl)->revision, - 1+(*the_acl)->num_aces, aces); - SAFE_FREE(aces); - (*the_acl) = newacl; - return True; -} - - -/* parse a ascii version of a security descriptor */ -static SEC_DESC * -sec_desc_parse(TALLOC_CTX *ctx, - struct cli_state *ipc_cli, - POLICY_HND *pol, - bool numeric, - char *str) -{ - const char *p = str; - char *tok; - SEC_DESC *ret = NULL; - size_t sd_size; - DOM_SID *group_sid=NULL; - DOM_SID *owner_sid=NULL; - SEC_ACL *dacl=NULL; - int revision=1; - - while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { - - if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { - revision = strtol(tok+9, NULL, 16); - continue; - } - - if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { - if (owner_sid) { - DEBUG(5, ("OWNER specified more than once!\n")); - goto done; - } - owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!owner_sid || - !convert_string_to_sid(ipc_cli, pol, - numeric, - owner_sid, tok+6)) { - DEBUG(5, ("Failed to parse owner sid\n")); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { - if (owner_sid) { - DEBUG(5, ("OWNER specified more than once!\n")); - goto done; - } - owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!owner_sid || - !convert_string_to_sid(ipc_cli, pol, - False, - owner_sid, tok+7)) { - DEBUG(5, ("Failed to parse owner sid\n")); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { - if (group_sid) { - DEBUG(5, ("GROUP specified more than once!\n")); - goto done; - } - group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!group_sid || - !convert_string_to_sid(ipc_cli, pol, - numeric, - group_sid, tok+6)) { - DEBUG(5, ("Failed to parse group sid\n")); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { - if (group_sid) { - DEBUG(5, ("GROUP specified more than once!\n")); - goto done; - } - group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); - if (!group_sid || - !convert_string_to_sid(ipc_cli, pol, - False, - group_sid, tok+6)) { - DEBUG(5, ("Failed to parse group sid\n")); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"ACL:", 4) == 0) { - SEC_ACE ace; - if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { - DEBUG(5, ("Failed to parse ACL %s\n", tok)); - goto done; - } - if(!add_ace(&dacl, &ace, ctx)) { - DEBUG(5, ("Failed to add ACL %s\n", tok)); - goto done; - } - continue; - } - - if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { - SEC_ACE ace; - if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { - DEBUG(5, ("Failed to parse ACL %s\n", tok)); - goto done; - } - if(!add_ace(&dacl, &ace, ctx)) { - DEBUG(5, ("Failed to add ACL %s\n", tok)); - goto done; - } - continue; - } - - DEBUG(5, ("Failed to parse security descriptor\n")); - goto done; - } - - ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, - owner_sid, group_sid, NULL, dacl, &sd_size); - - done: - SAFE_FREE(group_sid); - SAFE_FREE(owner_sid); - - return ret; -} - - -/* Obtain the current dos attributes */ -static DOS_ATTR_DESC * -dos_attr_query(SMBCCTX *context, - TALLOC_CTX *ctx, - const char *filename, - SMBCSRV *srv) -{ - struct timespec create_time_ts; - struct timespec write_time_ts; - struct timespec access_time_ts; - struct timespec change_time_ts; - SMB_OFF_T size = 0; - uint16 mode = 0; - SMB_INO_T inode = 0; - DOS_ATTR_DESC *ret; - - ret = TALLOC_P(ctx, DOS_ATTR_DESC); - if (!ret) { - errno = ENOMEM; - return NULL; - } - - /* Obtain the DOS attributes */ - if (!smbc_getatr(context, srv, CONST_DISCARD(char *, filename), - &mode, &size, - &create_time_ts, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &inode)) { - errno = smbc_errno(context, srv->cli); - DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); - return NULL; - } - - ret->mode = mode; - ret->size = size; - ret->create_time = convert_timespec_to_time_t(create_time_ts); - ret->access_time = convert_timespec_to_time_t(access_time_ts); - ret->write_time = convert_timespec_to_time_t(write_time_ts); - ret->change_time = convert_timespec_to_time_t(change_time_ts); - ret->inode = inode; - - return ret; -} - - -/* parse a ascii version of a security descriptor */ -static void -dos_attr_parse(SMBCCTX *context, - DOS_ATTR_DESC *dad, - SMBCSRV *srv, - char *str) -{ - int n; - const char *p = str; - char *tok = NULL; - TALLOC_CTX *frame = NULL; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } attr_strings; - - /* Determine whether to use old-style or new-style attribute names */ - if (context->internal->_full_time_names) { - /* new-style names */ - attr_strings.create_time_attr = "CREATE_TIME"; - attr_strings.access_time_attr = "ACCESS_TIME"; - attr_strings.write_time_attr = "WRITE_TIME"; - attr_strings.change_time_attr = "CHANGE_TIME"; - } else { - /* old-style names */ - attr_strings.create_time_attr = NULL; - attr_strings.access_time_attr = "A_TIME"; - attr_strings.write_time_attr = "M_TIME"; - attr_strings.change_time_attr = "C_TIME"; - } - - /* if this is to set the entire ACL... */ - if (*str == '*') { - /* ... then increment past the first colon if there is one */ - if ((p = strchr(str, ':')) != NULL) { - ++p; - } else { - p = str; - } - } - - frame = talloc_stackframe(); - while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { - if (StrnCaseCmp(tok, "MODE:", 5) == 0) { - long request = strtol(tok+5, NULL, 16); - if (request == 0) { - dad->mode = (request | - (IS_DOS_DIR(dad->mode) - ? FILE_ATTRIBUTE_DIRECTORY - : FILE_ATTRIBUTE_NORMAL)); - } else { - dad->mode = request; - } - continue; - } - - if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { - dad->size = (SMB_OFF_T)atof(tok+5); - continue; - } - - n = strlen(attr_strings.access_time_attr); - if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { - dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); - continue; - } - - n = strlen(attr_strings.change_time_attr); - if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { - dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); - continue; - } - - n = strlen(attr_strings.write_time_attr); - if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { - dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); - continue; - } - - if (attr_strings.create_time_attr != NULL) { - n = strlen(attr_strings.create_time_attr); - if (StrnCaseCmp(tok, attr_strings.create_time_attr, - n) == 0) { - dad->create_time = (time_t)strtol(tok+n+1, - NULL, 10); - continue; - } - } - - if (StrnCaseCmp(tok, "INODE:", 6) == 0) { - dad->inode = (SMB_INO_T)atof(tok+6); - continue; - } - } - TALLOC_FREE(frame); -} - -/***************************************************** - Retrieve the acls for a file. -*******************************************************/ - -static int -cacl_get(SMBCCTX *context, - TALLOC_CTX *ctx, - SMBCSRV *srv, - struct cli_state *ipc_cli, - POLICY_HND *pol, - char *filename, - char *attr_name, - char *buf, - int bufsize) -{ - uint32 i; - int n = 0; - int n_used; - bool all; - bool all_nt; - bool all_nt_acls; - bool all_dos; - bool some_nt; - bool some_dos; - bool exclude_nt_revision = False; - bool exclude_nt_owner = False; - bool exclude_nt_group = False; - bool exclude_nt_acl = False; - bool exclude_dos_mode = False; - bool exclude_dos_size = False; - bool exclude_dos_create_time = False; - bool exclude_dos_access_time = False; - bool exclude_dos_write_time = False; - bool exclude_dos_change_time = False; - bool exclude_dos_inode = False; - bool numeric = True; - bool determine_size = (bufsize == 0); - int fnum = -1; - SEC_DESC *sd; - fstring sidstr; - fstring name_sandbox; - char *name; - char *pExclude; - char *p; - struct timespec create_time_ts; - struct timespec write_time_ts; - struct timespec access_time_ts; - struct timespec change_time_ts; - time_t create_time = (time_t)0; - time_t write_time = (time_t)0; - time_t access_time = (time_t)0; - time_t change_time = (time_t)0; - SMB_OFF_T size = 0; - uint16 mode = 0; - SMB_INO_T ino = 0; - struct cli_state *cli = srv->cli; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } attr_strings; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } excl_attr_strings; - - /* Determine whether to use old-style or new-style attribute names */ - if (context->internal->_full_time_names) { - /* new-style names */ - attr_strings.create_time_attr = "CREATE_TIME"; - attr_strings.access_time_attr = "ACCESS_TIME"; - attr_strings.write_time_attr = "WRITE_TIME"; - attr_strings.change_time_attr = "CHANGE_TIME"; - - excl_attr_strings.create_time_attr = "CREATE_TIME"; - excl_attr_strings.access_time_attr = "ACCESS_TIME"; - excl_attr_strings.write_time_attr = "WRITE_TIME"; - excl_attr_strings.change_time_attr = "CHANGE_TIME"; - } else { - /* old-style names */ - attr_strings.create_time_attr = NULL; - attr_strings.access_time_attr = "A_TIME"; - attr_strings.write_time_attr = "M_TIME"; - attr_strings.change_time_attr = "C_TIME"; - - excl_attr_strings.create_time_attr = NULL; - excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; - excl_attr_strings.write_time_attr = "dos_attr.M_TIME"; - excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; - } - - /* Copy name so we can strip off exclusions (if any are specified) */ - strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); - - /* Ensure name is null terminated */ - name_sandbox[sizeof(name_sandbox) - 1] = '\0'; - - /* Play in the sandbox */ - name = name_sandbox; - - /* If there are any exclusions, point to them and mask them from name */ - if ((pExclude = strchr(name, '!')) != NULL) - { - *pExclude++ = '\0'; - } - - all = (StrnCaseCmp(name, "system.*", 8) == 0); - all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); - all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); - all_dos = (StrnCaseCmp(name, "system.dos_attr.*", 17) == 0); - some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); - some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); - numeric = (* (name + strlen(name) - 1) != '+'); - - /* Look for exclusions from "all" requests */ - if (all || all_nt || all_dos) { - - /* Exclusions are delimited by '!' */ - for (; - pExclude != NULL; - pExclude = (p == NULL ? NULL : p + 1)) { - - /* Find end of this exclusion name */ - if ((p = strchr(pExclude, '!')) != NULL) - { - *p = '\0'; - } - - /* Which exclusion name is this? */ - if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) { - exclude_nt_revision = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.owner") == 0) { - exclude_nt_owner = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.group") == 0) { - exclude_nt_group = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.acl") == 0) { - exclude_nt_acl = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.mode") == 0) { - exclude_dos_mode = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) { - exclude_dos_size = True; - } - else if (excl_attr_strings.create_time_attr != NULL && - StrCaseCmp(pExclude, - excl_attr_strings.change_time_attr) == 0) { - exclude_dos_create_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.access_time_attr) == 0) { - exclude_dos_access_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.write_time_attr) == 0) { - exclude_dos_write_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.change_time_attr) == 0) { - exclude_dos_change_time = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { - exclude_dos_inode = True; - } - else { - DEBUG(5, ("cacl_get received unknown exclusion: %s\n", - pExclude)); - errno = ENOATTR; - return -1; - } - } - } - - n_used = 0; - - /* - * If we are (possibly) talking to an NT or new system and some NT - * attributes have been requested... - */ - if (ipc_cli && (all || some_nt || all_nt_acls)) { - /* Point to the portion after "system.nt_sec_desc." */ - name += 19; /* if (all) this will be invalid but unused */ - - /* ... then obtain any NT attributes which were requested */ - fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - - if (fnum == -1) { - DEBUG(5, ("cacl_get failed to open %s: %s\n", - filename, cli_errstr(cli))); - errno = 0; - return -1; - } - - sd = cli_query_secdesc(cli, fnum, ctx); - - if (!sd) { - DEBUG(5, - ("cacl_get Failed to query old descriptor\n")); - errno = 0; - return -1; - } - - cli_close(cli, fnum); - - if (! exclude_nt_revision) { - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, - "REVISION:%d", - sd->revision); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "REVISION:%d", - sd->revision); - } - } else if (StrCaseCmp(name, "revision") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%d", - sd->revision); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%d", - sd->revision); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_nt_owner) { - /* Get owner and group sid */ - if (sd->owner_sid) { - convert_sid_to_string(ipc_cli, pol, - sidstr, - numeric, - sd->owner_sid); - } else { - fstrcpy(sidstr, ""); - } - - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, ",OWNER:%s", - sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else if (sidstr[0] != '\0') { - n = snprintf(buf, bufsize, - ",OWNER:%s", sidstr); - } - } else if (StrnCaseCmp(name, "owner", 5) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, "%s", - sidstr); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_nt_group) { - if (sd->group_sid) { - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, - sd->group_sid); - } else { - fstrcpy(sidstr, ""); - } - - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf(ctx, ",GROUP:%s", - sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else if (sidstr[0] != '\0') { - n = snprintf(buf, bufsize, - ",GROUP:%s", sidstr); - } - } else if (StrnCaseCmp(name, "group", 5) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%s", sidstr); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%s", sidstr); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_nt_acl) { - /* Add aces to value buffer */ - for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { - - SEC_ACE *ace = &sd->dacl->aces[i]; - convert_sid_to_string(ipc_cli, pol, - sidstr, numeric, - &ace->trustee); - - if (all || all_nt) { - if (determine_size) { - p = talloc_asprintf( - ctx, - ",ACL:" - "%s:%d/%d/0x%08x", - sidstr, - ace->type, - ace->flags, - ace->access_mask); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf( - buf, bufsize, - ",ACL:%s:%d/%d/0x%08x", - sidstr, - ace->type, - ace->flags, - ace->access_mask); - } - } else if ((StrnCaseCmp(name, "acl", 3) == 0 && - StrCaseCmp(name+3, sidstr) == 0) || - (StrnCaseCmp(name, "acl+", 4) == 0 && - StrCaseCmp(name+4, sidstr) == 0)) { - if (determine_size) { - p = talloc_asprintf( - ctx, - "%d/%d/0x%08x", - ace->type, - ace->flags, - ace->access_mask); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%d/%d/0x%08x", - ace->type, - ace->flags, - ace->access_mask); - } - } else if (all_nt_acls) { - if (determine_size) { - p = talloc_asprintf( - ctx, - "%s%s:%d/%d/0x%08x", - i ? "," : "", - sidstr, - ace->type, - ace->flags, - ace->access_mask); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%s%s:%d/%d/0x%08x", - i ? "," : "", - sidstr, - ace->type, - ace->flags, - ace->access_mask); - } - } - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - } - - /* Restore name pointer to its original value */ - name -= 19; - } - - if (all || some_dos) { - /* Point to the portion after "system.dos_attr." */ - name += 16; /* if (all) this will be invalid but unused */ - - /* Obtain the DOS attributes */ - if (!smbc_getatr(context, srv, filename, &mode, &size, - &create_time_ts, - &access_time_ts, - &write_time_ts, - &change_time_ts, - &ino)) { - - errno = smbc_errno(context, srv->cli); - return -1; - - } - - create_time = convert_timespec_to_time_t(create_time_ts); - access_time = convert_timespec_to_time_t(access_time_ts); - write_time = convert_timespec_to_time_t(write_time_ts); - change_time = convert_timespec_to_time_t(change_time_ts); - - if (! exclude_dos_mode) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - "%sMODE:0x%x", - (ipc_cli && - (all || some_nt) - ? "," - : ""), - mode); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%sMODE:0x%x", - (ipc_cli && - (all || some_nt) - ? "," - : ""), - mode); - } - } else if (StrCaseCmp(name, "mode") == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "0x%x", mode); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "0x%x", mode); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_size) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf( - ctx, - ",SIZE:%.0f", - (double)size); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",SIZE:%.0f", - (double)size); - } - } else if (StrCaseCmp(name, "size") == 0) { - if (determine_size) { - p = talloc_asprintf( - ctx, - "%.0f", - (double)size); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%.0f", - (double)size); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_create_time && - attr_strings.create_time_attr != NULL) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",%s:%lu", - attr_strings.create_time_attr, - create_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",%s:%lu", - attr_strings.create_time_attr, - create_time); - } - } else if (StrCaseCmp(name, attr_strings.create_time_attr) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", create_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%lu", create_time); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_access_time) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",%s:%lu", - attr_strings.access_time_attr, - access_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",%s:%lu", - attr_strings.access_time_attr, - access_time); - } - } else if (StrCaseCmp(name, attr_strings.access_time_attr) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", access_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%lu", access_time); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_write_time) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",%s:%lu", - attr_strings.write_time_attr, - write_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",%s:%lu", - attr_strings.write_time_attr, - write_time); - } - } else if (StrCaseCmp(name, attr_strings.write_time_attr) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", write_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%lu", write_time); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_change_time) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf(ctx, - ",%s:%lu", - attr_strings.change_time_attr, - change_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",%s:%lu", - attr_strings.change_time_attr, - change_time); - } - } else if (StrCaseCmp(name, attr_strings.change_time_attr) == 0) { - if (determine_size) { - p = talloc_asprintf(ctx, "%lu", change_time); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%lu", change_time); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - if (! exclude_dos_inode) { - if (all || all_dos) { - if (determine_size) { - p = talloc_asprintf( - ctx, - ",INODE:%.0f", - (double)ino); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - ",INODE:%.0f", - (double) ino); - } - } else if (StrCaseCmp(name, "inode") == 0) { - if (determine_size) { - p = talloc_asprintf( - ctx, - "%.0f", - (double) ino); - if (!p) { - errno = ENOMEM; - return -1; - } - n = strlen(p); - } else { - n = snprintf(buf, bufsize, - "%.0f", - (double) ino); - } - } - - if (!determine_size && n > bufsize) { - errno = ERANGE; - return -1; - } - buf += n; - n_used += n; - bufsize -= n; - n = 0; - } - - /* Restore name pointer to its original value */ - name -= 16; - } - - if (n_used == 0) { - errno = ENOATTR; - return -1; - } - - return n_used; -} - -/***************************************************** -set the ACLs on a file given an ascii description -*******************************************************/ -static int -cacl_set(TALLOC_CTX *ctx, - struct cli_state *cli, - struct cli_state *ipc_cli, - POLICY_HND *pol, - const char *filename, - const char *the_acl, - int mode, - int flags) -{ - int fnum; - int err = 0; - SEC_DESC *sd = NULL, *old; - SEC_ACL *dacl = NULL; - DOM_SID *owner_sid = NULL; - DOM_SID *group_sid = NULL; - uint32 i, j; - size_t sd_size; - int ret = 0; - char *p; - bool numeric = True; - - /* the_acl will be null for REMOVE_ALL operations */ - if (the_acl) { - numeric = ((p = strchr(the_acl, ':')) != NULL && - p > the_acl && - p[-1] != '+'); - - /* if this is to set the entire ACL... */ - if (*the_acl == '*') { - /* ... then increment past the first colon */ - the_acl = p + 1; - } - - sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, - CONST_DISCARD(char *, the_acl)); - - if (!sd) { - errno = EINVAL; - return -1; - } - } - - /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller - that doesn't deref sd */ - - if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { - errno = EINVAL; - return -1; - } - - /* The desired access below is the only one I could find that works - with NT4, W2KP and Samba */ - - fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - - if (fnum == -1) { - DEBUG(5, ("cacl_set failed to open %s: %s\n", - filename, cli_errstr(cli))); - errno = 0; - return -1; - } - - old = cli_query_secdesc(cli, fnum, ctx); - - if (!old) { - DEBUG(5, ("cacl_set Failed to query old descriptor\n")); - errno = 0; - return -1; - } - - cli_close(cli, fnum); - - switch (mode) { - case SMBC_XATTR_MODE_REMOVE_ALL: - old->dacl->num_aces = 0; - dacl = old->dacl; - break; - - case SMBC_XATTR_MODE_REMOVE: - for (i=0;sd->dacl && idacl->num_aces;i++) { - bool found = False; - - for (j=0;old->dacl && jdacl->num_aces;j++) { - if (sec_ace_equal(&sd->dacl->aces[i], - &old->dacl->aces[j])) { - uint32 k; - for (k=j; kdacl->num_aces-1;k++) { - old->dacl->aces[k] = - old->dacl->aces[k+1]; - } - old->dacl->num_aces--; - found = True; - dacl = old->dacl; - break; - } - } - - if (!found) { - err = ENOATTR; - ret = -1; - goto failed; - } - } - break; - - case SMBC_XATTR_MODE_ADD: - for (i=0;sd->dacl && idacl->num_aces;i++) { - bool found = False; - - for (j=0;old->dacl && jdacl->num_aces;j++) { - if (sid_equal(&sd->dacl->aces[i].trustee, - &old->dacl->aces[j].trustee)) { - if (!(flags & SMBC_XATTR_FLAG_CREATE)) { - err = EEXIST; - ret = -1; - goto failed; - } - old->dacl->aces[j] = sd->dacl->aces[i]; - ret = -1; - found = True; - } - } - - if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { - err = ENOATTR; - ret = -1; - goto failed; - } - - for (i=0;sd->dacl && idacl->num_aces;i++) { - add_ace(&old->dacl, &sd->dacl->aces[i], ctx); - } - } - dacl = old->dacl; - break; - - case SMBC_XATTR_MODE_SET: - old = sd; - owner_sid = old->owner_sid; - group_sid = old->group_sid; - dacl = old->dacl; - break; - - case SMBC_XATTR_MODE_CHOWN: - owner_sid = sd->owner_sid; - break; - - case SMBC_XATTR_MODE_CHGRP: - group_sid = sd->group_sid; - break; - } - - /* Denied ACE entries must come before allowed ones */ - sort_acl(old->dacl); - - /* Create new security descriptor and set it */ - sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, - owner_sid, group_sid, NULL, dacl, &sd_size); - - fnum = cli_nt_create(cli, filename, - WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); - - if (fnum == -1) { - DEBUG(5, ("cacl_set failed to open %s: %s\n", - filename, cli_errstr(cli))); - errno = 0; - return -1; - } - - if (!cli_set_secdesc(cli, fnum, sd)) { - DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli))); - ret = -1; - } - - /* Clean up */ - - failed: - cli_close(cli, fnum); - - if (err != 0) { - errno = err; - } - - return ret; -} - - -static int -smbc_setxattr_ctx(SMBCCTX *context, - const char *fname, - const char *name, - const void *value, - size_t size, - int flags) -{ - int ret; - int ret2; - SMBCSRV *srv = NULL; - SMBCSRV *ipc_srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - DOS_ATTR_DESC *dad = NULL; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } attr_strings; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", - fname, name, (int) size, (const char*)value)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password); - if (! ipc_srv) { - srv->no_nt_session = True; - } - } else { - ipc_srv = NULL; - } - - /* - * Are they asking to set the entire set of known attributes? - */ - if (StrCaseCmp(name, "system.*") == 0 || - StrCaseCmp(name, "system.*+") == 0) { - /* Yup. */ - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+7, (const char *) value); - if (! namevalue) { - errno = ENOMEM; - ret = -1; - TALLOC_FREE(frame); - return -1; - } - - if (ipc_srv) { - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - namevalue, - (*namevalue == '*' - ? SMBC_XATTR_MODE_SET - : SMBC_XATTR_MODE_ADD), - flags); - } else { - ret = 0; - } - - /* get a DOS Attribute Descriptor with current attributes */ - dad = dos_attr_query(context, talloc_tos(), path, srv); - if (dad) { - /* Overwrite old with new, using what was provided */ - dos_attr_parse(context, dad, srv, namevalue); - - /* Set the new DOS attributes */ - if (! smbc_setatr(context, srv, path, - dad->create_time, - dad->access_time, - dad->write_time, - dad->change_time, - dad->mode)) { - - /* cause failure if NT failed too */ - dad = NULL; - } - } - - /* we only fail if both NT and DOS sets failed */ - if (ret < 0 && ! dad) { - ret = -1; /* in case dad was null */ - } - else { - ret = 0; - } - - TALLOC_FREE(frame); - return ret; - } - - /* - * Are they asking to set an access control element or to set - * the entire access control list? - */ - if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { - - /* Yup. */ - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+19, (const char *) value); - - if (! ipc_srv) { - ret = -1; /* errno set by smbc_server() */ - } - else if (! namevalue) { - errno = ENOMEM; - ret = -1; - } else { - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - namevalue, - (*namevalue == '*' - ? SMBC_XATTR_MODE_SET - : SMBC_XATTR_MODE_ADD), - flags); - } - TALLOC_FREE(frame); - return ret; - } - - /* - * Are they asking to set the owner? - */ - if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { - - /* Yup. */ - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+19, (const char *) value); - - if (! ipc_srv) { - ret = -1; /* errno set by smbc_server() */ - } - else if (! namevalue) { - errno = ENOMEM; - ret = -1; - } else { - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - namevalue, SMBC_XATTR_MODE_CHOWN, 0); - } - TALLOC_FREE(frame); - return ret; - } - - /* - * Are they asking to set the group? - */ - if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { - - /* Yup. */ - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+19, (const char *) value); - - if (! ipc_srv) { - /* errno set by smbc_server() */ - ret = -1; - } - else if (! namevalue) { - errno = ENOMEM; - ret = -1; - } else { - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - namevalue, SMBC_XATTR_MODE_CHGRP, 0); - } - TALLOC_FREE(frame); - return ret; - } - - /* Determine whether to use old-style or new-style attribute names */ - if (context->internal->_full_time_names) { - /* new-style names */ - attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; - attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; - attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; - attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; - } else { - /* old-style names */ - attr_strings.create_time_attr = NULL; - attr_strings.access_time_attr = "system.dos_attr.A_TIME"; - attr_strings.write_time_attr = "system.dos_attr.M_TIME"; - attr_strings.change_time_attr = "system.dos_attr.C_TIME"; - } - - /* - * Are they asking to set a DOS attribute? - */ - if (StrCaseCmp(name, "system.dos_attr.*") == 0 || - StrCaseCmp(name, "system.dos_attr.mode") == 0 || - (attr_strings.create_time_attr != NULL && - StrCaseCmp(name, attr_strings.create_time_attr) == 0) || - StrCaseCmp(name, attr_strings.access_time_attr) == 0 || - StrCaseCmp(name, attr_strings.write_time_attr) == 0 || - StrCaseCmp(name, attr_strings.change_time_attr) == 0) { - - /* get a DOS Attribute Descriptor with current attributes */ - dad = dos_attr_query(context, talloc_tos(), path, srv); - if (dad) { - char *namevalue = - talloc_asprintf(talloc_tos(), "%s:%s", - name+16, (const char *) value); - if (! namevalue) { - errno = ENOMEM; - ret = -1; - } else { - /* Overwrite old with provided new params */ - dos_attr_parse(context, dad, srv, namevalue); - - /* Set the new DOS attributes */ - ret2 = smbc_setatr(context, srv, path, - dad->create_time, - dad->access_time, - dad->write_time, - dad->change_time, - dad->mode); - - /* ret2 has True (success) / False (failure) */ - if (ret2) { - ret = 0; - } else { - ret = -1; - } - } - } else { - ret = -1; - } - - TALLOC_FREE(frame); - return ret; - } - - /* Unsupported attribute name */ - errno = EINVAL; - TALLOC_FREE(frame); - return -1; -} - -static int -smbc_getxattr_ctx(SMBCCTX *context, - const char *fname, - const char *name, - const void *value, - size_t size) -{ - int ret; - SMBCSRV *srv = NULL; - SMBCSRV *ipc_srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - struct { - const char * create_time_attr; - const char * access_time_attr; - const char * write_time_attr; - const char * change_time_attr; - } attr_strings; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password); - if (! ipc_srv) { - srv->no_nt_session = True; - } - } else { - ipc_srv = NULL; - } - - /* Determine whether to use old-style or new-style attribute names */ - if (context->internal->_full_time_names) { - /* new-style names */ - attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; - attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; - attr_strings.write_time_attr = "system.dos_attr.WRITE_TIME"; - attr_strings.change_time_attr = "system.dos_attr.CHANGE_TIME"; - } else { - /* old-style names */ - attr_strings.create_time_attr = NULL; - attr_strings.access_time_attr = "system.dos_attr.A_TIME"; - attr_strings.write_time_attr = "system.dos_attr.M_TIME"; - attr_strings.change_time_attr = "system.dos_attr.C_TIME"; - } - - /* Are they requesting a supported attribute? */ - if (StrCaseCmp(name, "system.*") == 0 || - StrnCaseCmp(name, "system.*!", 9) == 0 || - StrCaseCmp(name, "system.*+") == 0 || - StrnCaseCmp(name, "system.*+!", 10) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.*!", 21) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.*+!", 22) == 0 || - StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0 || - StrCaseCmp(name, "system.dos_attr.*") == 0 || - StrnCaseCmp(name, "system.dos_attr.*!", 18) == 0 || - StrCaseCmp(name, "system.dos_attr.mode") == 0 || - StrCaseCmp(name, "system.dos_attr.size") == 0 || - (attr_strings.create_time_attr != NULL && - StrCaseCmp(name, attr_strings.create_time_attr) == 0) || - StrCaseCmp(name, attr_strings.access_time_attr) == 0 || - StrCaseCmp(name, attr_strings.write_time_attr) == 0 || - StrCaseCmp(name, attr_strings.change_time_attr) == 0 || - StrCaseCmp(name, "system.dos_attr.inode") == 0) { - - /* Yup. */ - ret = cacl_get(context, talloc_tos(), srv, - ipc_srv == NULL ? NULL : ipc_srv->cli, - &ipc_srv->pol, path, - CONST_DISCARD(char *, name), - CONST_DISCARD(char *, value), size); - if (ret < 0 && errno == 0) { - errno = smbc_errno(context, srv->cli); - } - TALLOC_FREE(frame); - return ret; - } - - /* Unsupported attribute name */ - errno = EINVAL; - TALLOC_FREE(frame); - return -1; -} - - -static int -smbc_removexattr_ctx(SMBCCTX *context, - const char *fname, - const char *name) -{ - int ret; - SMBCSRV *srv = NULL; - SMBCSRV *ipc_srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; /* Best I can think of ... */ - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (! srv->no_nt_session) { - ipc_srv = smbc_attr_server(frame, context, server, share, - &workgroup, &user, &password); - if (! ipc_srv) { - srv->no_nt_session = True; - } - } else { - ipc_srv = NULL; - } - - if (! ipc_srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_attr_server */ - } - - /* Are they asking to set the entire ACL? */ - if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { - - /* Yup. */ - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - NULL, SMBC_XATTR_MODE_REMOVE_ALL, 0); - TALLOC_FREE(frame); - return ret; - } - - /* - * Are they asking to remove one or more spceific security descriptor - * attributes? - */ - if (StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || - StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || - StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { - - /* Yup. */ - ret = cacl_set(talloc_tos(), srv->cli, - ipc_srv->cli, &ipc_srv->pol, path, - name + 19, SMBC_XATTR_MODE_REMOVE, 0); - TALLOC_FREE(frame); - return ret; - } - - /* Unsupported attribute name */ - errno = EINVAL; - TALLOC_FREE(frame); - return -1; -} - -static int -smbc_listxattr_ctx(SMBCCTX *context, - const char *fname, - char *list, - size_t size) -{ - /* - * This isn't quite what listxattr() is supposed to do. This returns - * the complete set of attribute names, always, rather than only those - * attribute names which actually exist for a file. Hmmm... - */ - size_t retsize; - const char supported_old[] = - "system.*\0" - "system.*+\0" - "system.nt_sec_desc.revision\0" - "system.nt_sec_desc.owner\0" - "system.nt_sec_desc.owner+\0" - "system.nt_sec_desc.group\0" - "system.nt_sec_desc.group+\0" - "system.nt_sec_desc.acl.*\0" - "system.nt_sec_desc.acl\0" - "system.nt_sec_desc.acl+\0" - "system.nt_sec_desc.*\0" - "system.nt_sec_desc.*+\0" - "system.dos_attr.*\0" - "system.dos_attr.mode\0" - "system.dos_attr.c_time\0" - "system.dos_attr.a_time\0" - "system.dos_attr.m_time\0" - ; - const char supported_new[] = - "system.*\0" - "system.*+\0" - "system.nt_sec_desc.revision\0" - "system.nt_sec_desc.owner\0" - "system.nt_sec_desc.owner+\0" - "system.nt_sec_desc.group\0" - "system.nt_sec_desc.group+\0" - "system.nt_sec_desc.acl.*\0" - "system.nt_sec_desc.acl\0" - "system.nt_sec_desc.acl+\0" - "system.nt_sec_desc.*\0" - "system.nt_sec_desc.*+\0" - "system.dos_attr.*\0" - "system.dos_attr.mode\0" - "system.dos_attr.create_time\0" - "system.dos_attr.access_time\0" - "system.dos_attr.write_time\0" - "system.dos_attr.change_time\0" - ; - const char * supported; - - if (context->internal->_full_time_names) { - supported = supported_new; - retsize = sizeof(supported_new); - } else { - supported = supported_old; - retsize = sizeof(supported_old); - } - - if (size == 0) { - return retsize; - } - - if (retsize > size) { - errno = ERANGE; - return -1; - } - - /* this can't be strcpy() because there are embedded null characters */ - memcpy(list, supported, retsize); - return retsize; -} - - -/* - * Open a print file to be written to by other calls - */ - -static SMBCFILE * -smbc_open_print_job_ctx(SMBCCTX *context, - const char *fname) -{ - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *path = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - } - - DEBUG(4, ("smbc_open_print_job_ctx(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return NULL; - } - - /* What if the path is empty, or the file exists? */ - - TALLOC_FREE(frame); - return (context->open)(context, fname, O_WRONLY, 666); -} - -/* - * Routine to print a file on a remote server ... - * - * We open the file, which we assume to be on a remote server, and then - * copy it to a print file on the share specified by printq. - */ - -static int -smbc_print_file_ctx(SMBCCTX *c_file, - const char *fname, - SMBCCTX *c_print, - const char *printq) -{ - SMBCFILE *fid1; - SMBCFILE *fid2; - int bytes; - int saverr; - int tot_bytes = 0; - char buf[4096]; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!c_file || !c_file->internal->_initialized || !c_print || - !c_print->internal->_initialized) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - if (!fname && !printq) { - - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - /* Try to open the file for reading ... */ - - if ((long)(fid1 = (c_file->open)(c_file, fname, O_RDONLY, 0666)) < 0) { - DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); - TALLOC_FREE(frame); - return -1; /* smbc_open sets errno */ - } - - /* Now, try to open the printer file for writing */ - - if ((long)(fid2 = (c_print->open_print_job)(c_print, printq)) < 0) { - - saverr = errno; /* Save errno */ - (c_file->close_fn)(c_file, fid1); - errno = saverr; - TALLOC_FREE(frame); - return -1; - - } - - while ((bytes = (c_file->read)(c_file, fid1, buf, sizeof(buf))) > 0) { - - tot_bytes += bytes; - - if (((c_print->write)(c_print, fid2, buf, bytes)) < 0) { - - saverr = errno; - (c_file->close_fn)(c_file, fid1); - (c_print->close_fn)(c_print, fid2); - errno = saverr; - - } - - } - - saverr = errno; - - (c_file->close_fn)(c_file, fid1); /* We have to close these anyway */ - (c_print->close_fn)(c_print, fid2); - - if (bytes < 0) { - - errno = saverr; - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return tot_bytes; - -} - -/* - * Routine to list print jobs on a printer share ... - */ - -static int -smbc_list_print_jobs_ctx(SMBCCTX *context, - const char *fname, - smbc_list_print_job_fn fn) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - } - - if (cli_print_queue(srv->cli, - (void (*)(struct print_job_info *))fn) < 0) { - errno = smbc_errno(context, srv->cli); - TALLOC_FREE(frame); - return -1; - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Delete a print job from a remote printer share - */ - -static int -smbc_unlink_print_job_ctx(SMBCCTX *context, - const char *fname, - int id) -{ - SMBCSRV *srv = NULL; - char *server = NULL; - char *share = NULL; - char *user = NULL; - char *password = NULL; - char *workgroup = NULL; - char *path = NULL; - int err; - TALLOC_CTX *frame = talloc_stackframe(); - - if (!context || !context->internal || - !context->internal->_initialized) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!fname) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - - if (smbc_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } - - if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); - if (!user) { - errno = ENOMEM; - TALLOC_FREE(frame); - return -1; - } - } - - srv = smbc_server(frame, context, True, - server, share, &workgroup, &user, &password); - - if (!srv) { - - TALLOC_FREE(frame); - return -1; /* errno set by smbc_server */ - - } - - if ((err = cli_printjob_del(srv->cli, id)) != 0) { - - if (err < 0) - errno = smbc_errno(context, srv->cli); - else if (err == ERRnosuchprintjob) - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - - } - - TALLOC_FREE(frame); - return 0; - -} - -/* - * Get a new empty handle to fill in with your own info - */ -SMBCCTX * -smbc_new_context(void) -{ - SMBCCTX *context; - - context = SMB_MALLOC_P(SMBCCTX); - if (!context) { - errno = ENOMEM; - return NULL; - } - - ZERO_STRUCTP(context); - - context->internal = SMB_MALLOC_P(struct smbc_internal_data); - if (!context->internal) { - SAFE_FREE(context); - errno = ENOMEM; - return NULL; - } - - ZERO_STRUCTP(context->internal); - - /* ADD REASONABLE DEFAULTS */ - context->debug = 0; - context->timeout = 20000; /* 20 seconds */ - - context->options.browse_max_lmb_count = 3; /* # LMBs to query */ - context->options.urlencode_readdir_entries = False;/* backward compat */ - context->options.one_share_per_server = False;/* backward compat */ - context->internal->_share_mode = SMBC_SHAREMODE_DENY_NONE; - /* backward compat */ - - context->open = smbc_open_ctx; - context->creat = smbc_creat_ctx; - context->read = smbc_read_ctx; - context->write = smbc_write_ctx; - context->close_fn = smbc_close_ctx; - context->unlink = smbc_unlink_ctx; - context->rename = smbc_rename_ctx; - context->lseek = smbc_lseek_ctx; - context->stat = smbc_stat_ctx; - context->fstat = smbc_fstat_ctx; - context->opendir = smbc_opendir_ctx; - context->closedir = smbc_closedir_ctx; - context->readdir = smbc_readdir_ctx; - context->getdents = smbc_getdents_ctx; - context->mkdir = smbc_mkdir_ctx; - context->rmdir = smbc_rmdir_ctx; - context->telldir = smbc_telldir_ctx; - context->lseekdir = smbc_lseekdir_ctx; - context->fstatdir = smbc_fstatdir_ctx; - context->ftruncate = smbc_ftruncate_ctx; - context->chmod = smbc_chmod_ctx; - context->utimes = smbc_utimes_ctx; - context->setxattr = smbc_setxattr_ctx; - context->getxattr = smbc_getxattr_ctx; - context->removexattr = smbc_removexattr_ctx; - context->listxattr = smbc_listxattr_ctx; - context->open_print_job = smbc_open_print_job_ctx; - context->print_file = smbc_print_file_ctx; - context->list_print_jobs = smbc_list_print_jobs_ctx; - context->unlink_print_job = smbc_unlink_print_job_ctx; - - context->callbacks.check_server_fn = smbc_check_server; - context->callbacks.remove_unused_server_fn = smbc_remove_unused_server; - - smbc_default_cache_functions(context); - - return context; -} - -/* - * Free a context - * - * Returns 0 on success. Otherwise returns 1, the SMBCCTX is _not_ freed - * and thus you'll be leaking memory if not handled properly. - * - */ -int -smbc_free_context(SMBCCTX *context, - int shutdown_ctx) -{ - if (!context) { - errno = EBADF; - return 1; - } - - if (shutdown_ctx) { - SMBCFILE * f; - DEBUG(1,("Performing aggressive shutdown.\n")); - - f = context->internal->_files; - while (f) { - (context->close_fn)(context, f); - f = f->next; - } - context->internal->_files = NULL; - - /* First try to remove the servers the nice way. */ - if (context->callbacks.purge_cached_fn(context)) { - SMBCSRV * s; - SMBCSRV * next; - DEBUG(1, ("Could not purge all servers, " - "Nice way shutdown failed.\n")); - s = context->internal->_servers; - while (s) { - DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", - s, s->cli->fd)); - cli_shutdown(s->cli); - (context->callbacks.remove_cached_srv_fn)(context, - s); - next = s->next; - DLIST_REMOVE(context->internal->_servers, s); - SAFE_FREE(s); - s = next; - } - context->internal->_servers = NULL; - } - } - else { - /* This is the polite way */ - if ((context->callbacks.purge_cached_fn)(context)) { - DEBUG(1, ("Could not purge all servers, " - "free_context failed.\n")); - errno = EBUSY; - return 1; - } - if (context->internal->_servers) { - DEBUG(1, ("Active servers in context, " - "free_context failed.\n")); - errno = EBUSY; - return 1; - } - if (context->internal->_files) { - DEBUG(1, ("Active files in context, " - "free_context failed.\n")); - errno = EBUSY; - return 1; - } - } - - /* Things we have to clean up */ - SAFE_FREE(context->workgroup); - SAFE_FREE(context->netbios_name); - SAFE_FREE(context->user); - - DEBUG(3, ("Context %p successfully freed\n", context)); - SAFE_FREE(context->internal); - SAFE_FREE(context); - return 0; -} - - -/* - * Each time the context structure is changed, we have binary backward - * compatibility issues. Instead of modifying the public portions of the - * context structure to add new options, instead, we put them in the internal - * portion of the context structure and provide a set function for these new - * options. - */ -void -smbc_option_set(SMBCCTX *context, - char *option_name, - ... /* option_value */) -{ - va_list ap; - union { - int i; - bool b; - smbc_get_auth_data_with_context_fn auth_fn; - void *v; - const char *s; - } option_value; - - va_start(ap, option_name); - - if (strcmp(option_name, "debug_to_stderr") == 0) { - /* - * Log to standard error instead of standard output. - */ - option_value.b = (bool) va_arg(ap, int); - context->internal->_debug_stderr = option_value.b; - - } else if (strcmp(option_name, "full_time_names") == 0) { - /* - * Use new-style time attribute names, e.g. WRITE_TIME rather - * than the old-style names such as M_TIME. This allows also - * setting/getting CREATE_TIME which was previously - * unimplemented. (Note that the old C_TIME was supposed to - * be CHANGE_TIME but was confused and sometimes referred to - * CREATE_TIME.) - */ - option_value.b = (bool) va_arg(ap, int); - context->internal->_full_time_names = option_value.b; - - } else if (strcmp(option_name, "open_share_mode") == 0) { - /* - * The share mode to use for files opened with - * smbc_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE. - */ - option_value.i = va_arg(ap, int); - context->internal->_share_mode = - (smbc_share_mode) option_value.i; - - } else if (strcmp(option_name, "auth_function") == 0) { - /* - * Use the new-style authentication function which includes - * the context. - */ - option_value.auth_fn = - va_arg(ap, smbc_get_auth_data_with_context_fn); - context->internal->_auth_fn_with_context = - option_value.auth_fn; - } else if (strcmp(option_name, "user_data") == 0) { - /* - * Save a user data handle which may be retrieved by the user - * with smbc_option_get() - */ - option_value.v = va_arg(ap, void *); - context->internal->_user_data = option_value.v; - } else if (strcmp(option_name, "smb_encrypt_level") == 0) { - /* - * Save an encoded value for encryption level. - * 0 = off, 1 = attempt, 2 = required. - */ - option_value.s = va_arg(ap, const char *); - if (strcmp(option_value.s, "none") == 0) { - context->internal->_smb_encryption_level = 0; - } else if (strcmp(option_value.s, "request") == 0) { - context->internal->_smb_encryption_level = 1; - } else if (strcmp(option_value.s, "require") == 0) { - context->internal->_smb_encryption_level = 2; - } - } - - va_end(ap); -} - - -/* - * Retrieve the current value of an option - */ -void * -smbc_option_get(SMBCCTX *context, - char *option_name) -{ - if (strcmp(option_name, "debug_stderr") == 0) { - /* - * Log to standard error instead of standard output. - */ -#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->_debug_stderr; -#else - return (void *) context->internal->_debug_stderr; -#endif - } else if (strcmp(option_name, "full_time_names") == 0) { - /* - * Use new-style time attribute names, e.g. WRITE_TIME rather - * than the old-style names such as M_TIME. This allows also - * setting/getting CREATE_TIME which was previously - * unimplemented. (Note that the old C_TIME was supposed to - * be CHANGE_TIME but was confused and sometimes referred to - * CREATE_TIME.) - */ -#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->_full_time_names; -#else - return (void *) context->internal->_full_time_names; -#endif - - } else if (strcmp(option_name, "auth_function") == 0) { - /* - * Use the new-style authentication function which includes - * the context. - */ - return (void *) context->internal->_auth_fn_with_context; - } else if (strcmp(option_name, "user_data") == 0) { - /* - * Save a user data handle which may be retrieved by the user - * with smbc_option_get() - */ - return context->internal->_user_data; - } else if (strcmp(option_name, "smb_encrypt_level") == 0) { - /* - * Return the current smb encrypt negotiate option as a string. - */ - switch (context->internal->_smb_encryption_level) { - case 0: - return (void *) "none"; - case 1: - return (void *) "request"; - case 2: - return (void *) "require"; - } - } else if (strcmp(option_name, "smb_encrypt_on") == 0) { - /* - * Return the current smb encrypt status option as a bool. - * false = off, true = on. We don't know what server is - * being requested, so we only return true if all servers - * are using an encrypted connection. - */ - SMBCSRV *s; - unsigned int num_servers = 0; - - for (s = context->internal->_servers; s; s = s->next) { - num_servers++; - if (s->cli->trans_enc_state == NULL) { - return (void *)false; - } - } - return (void *) (bool) (num_servers > 0); - } - - return NULL; -} - - -/* - * Initialise the library etc - * - * We accept a struct containing handle information. - * valid values for info->debug from 0 to 100, - * and insist that info->fn must be non-null. - */ -SMBCCTX * -smbc_init_context(SMBCCTX *context) -{ - int pid; - char *user = NULL; - char *home = NULL; - - if (!context || !context->internal) { - errno = EBADF; - return NULL; - } - - /* Do not initialise the same client twice */ - if (context->internal->_initialized) { - return 0; - } - - if ((!context->callbacks.auth_fn && - !context->internal->_auth_fn_with_context) || - context->debug < 0 || - context->debug > 100) { - - errno = EINVAL; - return NULL; - - } - - if (!smbc_initialized) { - /* - * Do some library-wide intializations the first time we get - * called - */ - bool conf_loaded = False; - TALLOC_CTX *frame = talloc_stackframe(); - - /* Set this to what the user wants */ - DEBUGLEVEL = context->debug; - - load_case_tables(); - - setup_logging("libsmbclient", True); - if (context->internal->_debug_stderr) { - dbf = x_stderr; - x_setbuf(x_stderr, NULL); - } - - /* Here we would open the smb.conf file if needed ... */ - - in_client = True; /* FIXME, make a param */ - - home = getenv("HOME"); - if (home) { - char *conf = NULL; - if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) { - if (lp_load(conf, True, False, False, True)) { - conf_loaded = True; - } else { - DEBUG(5, ("Could not load config file: %s\n", - conf)); - } - SAFE_FREE(conf); - } - } - - if (!conf_loaded) { - /* - * Well, if that failed, try the get_dyn_CONFIGFILE - * Which points to the standard locn, and if that - * fails, silently ignore it and use the internal - * defaults ... - */ - - if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { - DEBUG(5, ("Could not load config file: %s\n", - get_dyn_CONFIGFILE())); - } else if (home) { - char *conf; - /* - * We loaded the global config file. Now lets - * load user-specific modifications to the - * global config. - */ - if (asprintf(&conf, - "%s/.smb/smb.conf.append", - home) > 0) { - if (!lp_load(conf, True, False, False, False)) { - DEBUG(10, - ("Could not append config file: " - "%s\n", - conf)); - } - SAFE_FREE(conf); - } - } - } - - load_interfaces(); /* Load the list of interfaces ... */ - - reopen_logs(); /* Get logging working ... */ - - /* - * Block SIGPIPE (from lib/util_sock.c: write()) - * It is not needed and should not stop execution - */ - BlockSignals(True, SIGPIPE); - - /* Done with one-time initialisation */ - smbc_initialized = 1; - - TALLOC_FREE(frame); - } - - if (!context->user) { - /* - * FIXME: Is this the best way to get the user info? - */ - user = getenv("USER"); - /* walk around as "guest" if no username can be found */ - if (!user) context->user = SMB_STRDUP("guest"); - else context->user = SMB_STRDUP(user); - } - - if (!context->netbios_name) { - /* - * We try to get our netbios name from the config. If that - * fails we fall back on constructing our netbios name from - * our hostname etc - */ - if (global_myname()) { - context->netbios_name = SMB_STRDUP(global_myname()); - } - else { - /* - * Hmmm, I want to get hostname as well, but I am too - * lazy for the moment - */ - pid = sys_getpid(); - context->netbios_name = (char *)SMB_MALLOC(17); - if (!context->netbios_name) { - errno = ENOMEM; - return NULL; - } - slprintf(context->netbios_name, 16, - "smbc%s%d", context->user, pid); - } - } - - DEBUG(1, ("Using netbios name %s.\n", context->netbios_name)); - - if (!context->workgroup) { - if (lp_workgroup()) { - context->workgroup = SMB_STRDUP(lp_workgroup()); - } - else { - /* TODO: Think about a decent default workgroup */ - context->workgroup = SMB_STRDUP("samba"); - } - } - - DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); - - /* shortest timeout is 1 second */ - if (context->timeout > 0 && context->timeout < 1000) - context->timeout = 1000; - - /* - * FIXME: Should we check the function pointers here? - */ - - context->internal->_initialized = True; - - return context; -} - - -/* Return the verion of samba, and thus libsmbclient */ -const char * -smbc_version(void) -{ - return samba_version_string(); -} -- cgit From 4ba42cbe0f6bbd25848786e1a87c06aca79b98ea Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Fri, 29 Feb 2008 13:34:35 -0500 Subject: Modified revamp of the libsmbclient interface. Given the tacit (if that) approval by some people, and clear disapproval by others for my proposed clean-up and reorganization of libsmbclient, I've come up with a slightly different approach. This commit changes back to the original libsmbclient.h SMBCCTX structure which will maintain ABI compatibility. I retain, here, the setter and getter functions which all new code should use. Older programs already compiled should continue to work fine. Older programs being recompiled will encounter compile-time errors (intentionally!) so that the code can be corrected to use the setter/getter interfaces. Although this doesn't clean up the interface in the way I had wanted, the code reorganization and requirement for new programs to use the setters and getters allows future progress to be made on libsmbclient without further muddying up the interface, while retaining the ABI compatibility that was the big issue causing disapproval. I hope that this compromise is adequate. Derrell (This used to be commit 56429a3d60b2a48963342f6340b3c01469a892c6) --- source3/libsmb/libsmb_cache.c | 2 +- source3/libsmb/libsmb_context.c | 305 ++++++++++++++++++++++----------------- source3/libsmb/libsmb_dir.c | 70 ++++----- source3/libsmb/libsmb_file.c | 36 ++--- source3/libsmb/libsmb_path.c | 7 +- source3/libsmb/libsmb_printjob.c | 14 +- source3/libsmb/libsmb_server.c | 33 +++-- source3/libsmb/libsmb_stat.c | 10 +- source3/libsmb/libsmb_xattr.c | 22 +-- 9 files changed, 272 insertions(+), 227 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index e0571fa9fe..7ff92f1b4e 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -151,7 +151,7 @@ SMBC_get_cached_server(SMBCCTX * context, * a connection to the server (other than the * attribute server connection) is cool. */ - if (context->one_share_per_server) { + if (context->options.one_share_per_server) { /* * The currently connected share name * doesn't match the requested share, so diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 1505d50a43..6b7a19e1e4 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -41,6 +41,15 @@ SMBCCTX * smbc_new_context(void) { SMBCCTX *context; + + /* + * All newly added context fields should be placed in SMBC_internal_data, + * not directly in SMBCCTX. + */ +# undef OLD +# define OLD(field) context->field +# undef NEW +# define NEW(field) context->internal->field context = SMB_MALLOC_P(SMBCCTX); if (!context) { @@ -48,66 +57,73 @@ smbc_new_context(void) return NULL; } - - /* Initialize the context and establish reasonable defaults */ ZERO_STRUCTP(context); + + context->internal = SMB_MALLOC_P(struct SMBC_internal_data); + if (!context->internal) { + SAFE_FREE(context); + errno = ENOMEM; + return NULL; + } + + /* Initialize the context and establish reasonable defaults */ + ZERO_STRUCTP(context->internal); - context->debug = 0; - context->timeout = 20000; /* 20 seconds */ + OLD(config.debug) = 0; + OLD(config.timeout) = 20000; /* 20 seconds */ - context->full_time_names = False; - context->share_mode = SMBC_SHAREMODE_DENY_NONE; - context->smb_encryption_level = 0; - context->browse_max_lmb_count = 3; /* # LMBs to query */ - context->urlencode_readdir_entries = False; - context->one_share_per_server = False; - context->use_kerberos = False; - context->fallback_after_kerberos = False; - context->no_auto_anonymous_login = False; + NEW(full_time_names) = False; + NEW(share_mode) = SMBC_SHAREMODE_DENY_NONE; + NEW(smb_encryption_level) = 0; + NEW(browse_max_lmb_count) = 3; /* # LMBs to query */ + NEW(urlencode_readdir_entries) = False; + NEW(one_share_per_server) = False; - context->server.get_auth_data_fn = SMBC_get_auth_data; - context->server.check_server_fn = SMBC_check_server; - context->server.remove_unused_server_fn = SMBC_remove_unused_server; + OLD(server.get_auth_data_fn) = SMBC_get_auth_data; + OLD(server.check_server_fn) = SMBC_check_server; + OLD(server.remove_unused_server_fn) = SMBC_remove_unused_server; - context->cache.server_cache_data = NULL; - context->cache.add_cached_server_fn = SMBC_add_cached_server; - context->cache.get_cached_server_fn = SMBC_get_cached_server; - context->cache.remove_cached_server_fn = SMBC_remove_cached_server; - context->cache.purge_cached_server_fn = SMBC_purge_cached_servers; + OLD(cache.server_cache_data) = NULL; + OLD(cache.add_cached_server_fn) = SMBC_add_cached_server; + OLD(cache.get_cached_server_fn) = SMBC_get_cached_server; + OLD(cache.remove_cached_server_fn) = SMBC_remove_cached_server; + OLD(cache.purge_cached_servers_fn) = SMBC_purge_cached_servers; - context->posix_emu.open_fn = SMBC_open_ctx; - context->posix_emu.creat_fn = SMBC_creat_ctx; - context->posix_emu.read_fn = SMBC_read_ctx; - context->posix_emu.write_fn = SMBC_write_ctx; - context->posix_emu.close_fn = SMBC_close_ctx; - context->posix_emu.unlink_fn = SMBC_unlink_ctx; - context->posix_emu.rename_fn = SMBC_rename_ctx; - context->posix_emu.lseek_fn = SMBC_lseek_ctx; - context->posix_emu.ftruncate_fn = SMBC_ftruncate_ctx; - context->posix_emu.stat_fn = SMBC_stat_ctx; - context->posix_emu.fstat_fn = SMBC_fstat_ctx; - context->posix_emu.opendir_fn = SMBC_opendir_ctx; - context->posix_emu.closedir_fn = SMBC_closedir_ctx; - context->posix_emu.readdir_fn = SMBC_readdir_ctx; - context->posix_emu.getdents_fn = SMBC_getdents_ctx; - context->posix_emu.mkdir_fn = SMBC_mkdir_ctx; - context->posix_emu.rmdir_fn = SMBC_rmdir_ctx; - context->posix_emu.telldir_fn = SMBC_telldir_ctx; - context->posix_emu.lseekdir_fn = SMBC_lseekdir_ctx; - context->posix_emu.fstatdir_fn = SMBC_fstatdir_ctx; - context->posix_emu.chmod_fn = SMBC_chmod_ctx; - context->posix_emu.utimes_fn = SMBC_utimes_ctx; - context->posix_emu.setxattr_fn = SMBC_setxattr_ctx; - context->posix_emu.getxattr_fn = SMBC_getxattr_ctx; - context->posix_emu.removexattr_fn = SMBC_removexattr_ctx; - context->posix_emu.listxattr_fn = SMBC_listxattr_ctx; + OLD(posix_emu.open_fn) = SMBC_open_ctx; + OLD(posix_emu.creat_fn) = SMBC_creat_ctx; + OLD(posix_emu.read_fn) = SMBC_read_ctx; + OLD(posix_emu.write_fn) = SMBC_write_ctx; + OLD(posix_emu.close_fn) = SMBC_close_ctx; + OLD(posix_emu.unlink_fn) = SMBC_unlink_ctx; + OLD(posix_emu.rename_fn) = SMBC_rename_ctx; + OLD(posix_emu.lseek_fn) = SMBC_lseek_ctx; + NEW(posix_emu.ftruncate_fn) = SMBC_ftruncate_ctx; + OLD(posix_emu.stat_fn) = SMBC_stat_ctx; + OLD(posix_emu.fstat_fn) = SMBC_fstat_ctx; + OLD(posix_emu.opendir_fn) = SMBC_opendir_ctx; + OLD(posix_emu.closedir_fn) = SMBC_closedir_ctx; + OLD(posix_emu.readdir_fn) = SMBC_readdir_ctx; + OLD(posix_emu.getdents_fn) = SMBC_getdents_ctx; + OLD(posix_emu.mkdir_fn) = SMBC_mkdir_ctx; + OLD(posix_emu.rmdir_fn) = SMBC_rmdir_ctx; + OLD(posix_emu.telldir_fn) = SMBC_telldir_ctx; + OLD(posix_emu.lseekdir_fn) = SMBC_lseekdir_ctx; + OLD(posix_emu.fstatdir_fn) = SMBC_fstatdir_ctx; + OLD(posix_emu.chmod_fn) = SMBC_chmod_ctx; + OLD(posix_emu.utimes_fn) = SMBC_utimes_ctx; + OLD(posix_emu.setxattr_fn) = SMBC_setxattr_ctx; + OLD(posix_emu.getxattr_fn) = SMBC_getxattr_ctx; + OLD(posix_emu.removexattr_fn) = SMBC_removexattr_ctx; + OLD(posix_emu.listxattr_fn) = SMBC_listxattr_ctx; - context->printing.open_print_job_fn = SMBC_open_print_job_ctx; - context->printing.print_file_fn = SMBC_print_file_ctx; - context->printing.list_print_jobs_fn = SMBC_list_print_jobs_ctx; - context->printing.unlink_print_job_fn = SMBC_unlink_print_job_ctx; + OLD(printing.open_print_job_fn) = SMBC_open_print_job_ctx; + OLD(printing.print_file_fn) = SMBC_print_file_ctx; + OLD(printing.list_print_jobs_fn) = SMBC_list_print_jobs_ctx; + OLD(printing.unlink_print_job_fn) = SMBC_unlink_print_job_ctx; return context; +#undef OLD +#undef NEW } /* @@ -130,20 +146,20 @@ smbc_free_context(SMBCCTX *context, SMBCFILE * f; DEBUG(1,("Performing aggressive shutdown.\n")); - f = context->files; + f = context->internal->files; while (f) { (context->posix_emu.close_fn)(context, f); f = f->next; } - context->files = NULL; + context->internal->files = NULL; /* First try to remove the servers the nice way. */ - if (context->cache.purge_cached_server_fn(context)) { + if (context->cache.purge_cached_servers_fn(context)) { SMBCSRV * s; SMBCSRV * next; DEBUG(1, ("Could not purge all servers, " "Nice way shutdown failed.\n")); - s = context->servers; + s = context->internal->servers; while (s) { DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", s, s->cli->fd)); @@ -151,28 +167,28 @@ smbc_free_context(SMBCCTX *context, (context->cache.remove_cached_server_fn)(context, s); next = s->next; - DLIST_REMOVE(context->servers, s); + DLIST_REMOVE(context->internal->servers, s); SAFE_FREE(s); s = next; } - context->servers = NULL; + context->internal->servers = NULL; } } else { /* This is the polite way */ - if ((context->cache.purge_cached_server_fn)(context)) { + if ((context->cache.purge_cached_servers_fn)(context)) { DEBUG(1, ("Could not purge all servers, " "free_context failed.\n")); errno = EBUSY; return 1; } - if (context->servers) { + if (context->internal->servers) { DEBUG(1, ("Active servers in context, " "free_context failed.\n")); errno = EBUSY; return 1; } - if (context->files) { + if (context->internal->files) { DEBUG(1, ("Active files in context, " "free_context failed.\n")); errno = EBUSY; @@ -181,9 +197,9 @@ smbc_free_context(SMBCCTX *context, } /* Things we have to clean up */ - SAFE_FREE(context->workgroup); - SAFE_FREE(context->netbios_name); - SAFE_FREE(context->user); + SAFE_FREE(context->config.workgroup); + SAFE_FREE(context->config.netbios_name); + SAFE_FREE(context->config.user); DEBUG(3, ("Context %p successfully freed\n", context)); SAFE_FREE(context); @@ -219,7 +235,7 @@ smbc_option_set(SMBCCTX *context, * Log to standard error instead of standard output. */ option_value.b = (bool) va_arg(ap, int); - context->debug_stderr = option_value.b; + context->internal->debug_stderr = option_value.b; } else if (strcmp(option_name, "full_time_names") == 0) { /* @@ -231,7 +247,7 @@ smbc_option_set(SMBCCTX *context, * CREATE_TIME.) */ option_value.b = (bool) va_arg(ap, int); - context->full_time_names = option_value.b; + context->internal->full_time_names = option_value.b; } else if (strcmp(option_name, "open_share_mode") == 0) { /* @@ -239,7 +255,7 @@ smbc_option_set(SMBCCTX *context, * SMBC_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE. */ option_value.i = va_arg(ap, int); - context->share_mode = (smbc_share_mode) option_value.i; + context->internal->share_mode = (smbc_share_mode) option_value.i; } else if (strcmp(option_name, "user_data") == 0) { /* @@ -247,7 +263,7 @@ smbc_option_set(SMBCCTX *context, * with smbc_option_get() */ option_value.v = va_arg(ap, void *); - context->user_data = option_value.v; + context->internal->user_data = option_value.v; } else if (strcmp(option_name, "smb_encrypt_level") == 0) { /* * Save an encoded value for encryption level. @@ -255,11 +271,11 @@ smbc_option_set(SMBCCTX *context, */ option_value.s = va_arg(ap, const char *); if (strcmp(option_value.s, "none") == 0) { - context->smb_encryption_level = 0; + context->internal->smb_encryption_level = 0; } else if (strcmp(option_value.s, "request") == 0) { - context->smb_encryption_level = 1; + context->internal->smb_encryption_level = 1; } else if (strcmp(option_value.s, "require") == 0) { - context->smb_encryption_level = 2; + context->internal->smb_encryption_level = 2; } } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { /* @@ -280,7 +296,7 @@ smbc_option_set(SMBCCTX *context, * variable is probably somewhere around 3. (Default: 3). */ option_value.i = va_arg(ap, int); - context->browse_max_lmb_count = option_value.i; + context->internal->browse_max_lmb_count = option_value.i; } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { /* @@ -307,7 +323,7 @@ smbc_option_set(SMBCCTX *context, * For backwards compatibility, this option defaults to False. */ option_value.b = (bool) va_arg(ap, int); - context->urlencode_readdir_entries = option_value.b; + context->internal->urlencode_readdir_entries = option_value.b; } else if (strcmp(option_name, "one_share_per_server") == 0) { /* @@ -321,19 +337,31 @@ smbc_option_set(SMBCCTX *context, * and issuing a new TREE CONNECT when the share is accessed. */ option_value.b = (bool) va_arg(ap, int); - context->one_share_per_server = option_value.b; + context->options.one_share_per_server = option_value.b; } else if (strcmp(option_name, "use_kerberos") == 0) { option_value.b = (bool) va_arg(ap, int); - context->use_kerberos = option_value.b; + if (option_value.b) { + context->flags.bits |= SMB_CTX_FLAG_USE_KERBEROS; + } else { + context->flags.bits &= ~SMB_CTX_FLAG_USE_KERBEROS; + } } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { option_value.b = (bool) va_arg(ap, int); - context->fallback_after_kerberos = option_value.b; + if (option_value.b) { + context->flags.bits |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + } else { + context->flags.bits &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + } } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { option_value.b = (bool) va_arg(ap, int); - context->no_auto_anonymous_login = option_value.b; + if (option_value.b) { + context->flags.bits |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; + } else { + context->flags.bits &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; + } } va_end(ap); @@ -347,14 +375,16 @@ void * smbc_option_get(SMBCCTX *context, char *option_name) { + int bits; + if (strcmp(option_name, "debug_stderr") == 0) { /* * Log to standard error instead of standard output. */ #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->debug_stderr; + return (void *) (intptr_t) context->internal->debug_stderr; #else - return (void *) context->debug_stderr; + return (void *) context->internal->debug_stderr; #endif } else if (strcmp(option_name, "full_time_names") == 0) { @@ -367,9 +397,9 @@ smbc_option_get(SMBCCTX *context, * CREATE_TIME.) */ #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->full_time_names; + return (void *) (intptr_t) context->internal->full_time_names; #else - return (void *) context->full_time_names; + return (void *) context->internal->full_time_names; #endif } else if (strcmp(option_name, "user_data") == 0) { @@ -377,13 +407,13 @@ smbc_option_get(SMBCCTX *context, * Return the user data handle which was saved by the user * with smbc_option_set() */ - return context->user_data; + return context->internal->user_data; } else if (strcmp(option_name, "smb_encrypt_level") == 0) { /* * Return the current smb encrypt negotiate option as a string. */ - switch (context->smb_encryption_level) { + switch (context->internal->smb_encryption_level) { case 0: return (void *) "none"; case 1: @@ -402,7 +432,7 @@ smbc_option_get(SMBCCTX *context, SMBCSRV *s; unsigned int num_servers = 0; - for (s = context->servers; s; s = s->next) { + for (s = context->internal->servers; s; s = s->next) { num_servers++; if (s->cli->trans_enc_state == NULL) { return (void *)false; @@ -433,9 +463,9 @@ smbc_option_get(SMBCCTX *context, * variable is probably somewhere around 3. (Default: 3). */ #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->browse_max_lmb_count; + return (void *) (intptr_t) context->internal->browse_max_lmb_count; #else - return (void *) context->browse_max_lmb_count; + return (void *) context->internal->browse_max_lmb_count; #endif } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { @@ -463,9 +493,9 @@ smbc_option_get(SMBCCTX *context, * For backwards compatibility, this option defaults to False. */ #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->urlencode_readdir_entries; + return (void *)(intptr_t) context->internal->urlencode_readdir_entries; #else - return (void *) (bool) context->urlencode_readdir_entries; + return (void *) (bool) context->internal->urlencode_readdir_entries; #endif } else if (strcmp(option_name, "one_share_per_server") == 0) { @@ -480,30 +510,43 @@ smbc_option_get(SMBCCTX *context, * and issuing a new TREE CONNECT when the share is accessed. */ #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->one_share_per_server; + return (void *) (intptr_t) context->internal->one_share_per_server; #else - return (void *) (bool) context->one_share_per_server; + return (void *) (bool) context->internal->one_share_per_server; #endif } else if (strcmp(option_name, "use_kerberos") == 0) { + bits = context->flags.bits; #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->use_kerberos; + return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS + ? (void *) (intptr_t) 1 + : (void *) (intptr_t) 0); #else - return (void *) (bool) context->use_kerberos; + return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS + ? (void *) (bool) 1 + : (void *) (bool) 0); #endif } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->fallback_after_kerberos; + return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS + ? (void *) (intptr_t) 1 + : (void *) (intptr_t) 0); #else - return (void *) (bool) context->fallback_after_kerberos; + return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS + ? (void *) (bool) 1 + : (void *) (bool) 0); #endif } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->no_auto_anonymous_login; + return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON + ? (void *) (intptr_t) 1 + : (void *) (intptr_t) 0); #else - return (void *) (bool) context->no_auto_anonymous_login; + return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON + ? (void *) (bool) 1 + : (void *) (bool) 0); #endif } @@ -532,13 +575,13 @@ smbc_init_context(SMBCCTX *context) } /* Do not initialise the same client twice */ - if (context->initialized) { + if (context->internal->initialized) { return 0; } if (!context->server.get_auth_data_fn || - context->debug < 0 || - context->debug > 100) { + context->config.debug < 0 || + context->config.debug > 100) { errno = EINVAL; return NULL; @@ -554,12 +597,12 @@ smbc_init_context(SMBCCTX *context) TALLOC_CTX *frame = talloc_stackframe(); /* Set this to what the user wants */ - DEBUGLEVEL = context->debug; + DEBUGLEVEL = context->config.debug; load_case_tables(); setup_logging("libsmbclient", True); - if (context->debug_stderr) { + if (context->internal->debug_stderr) { dbf = x_stderr; x_setbuf(x_stderr, NULL); } @@ -630,24 +673,24 @@ smbc_init_context(SMBCCTX *context) TALLOC_FREE(frame); } - if (!context->user) { + if (!context->config.user) { /* * FIXME: Is this the best way to get the user info? */ user = getenv("USER"); /* walk around as "guest" if no username can be found */ - if (!user) context->user = SMB_STRDUP("guest"); - else context->user = SMB_STRDUP(user); + if (!user) context->config.user = SMB_STRDUP("guest"); + else context->config.user = SMB_STRDUP(user); } - if (!context->netbios_name) { + if (!context->config.netbios_name) { /* * We try to get our netbios name from the config. If that * fails we fall back on constructing our netbios name from * our hostname etc */ if (global_myname()) { - context->netbios_name = SMB_STRDUP(global_myname()); + context->config.netbios_name = SMB_STRDUP(global_myname()); } else { /* @@ -655,39 +698,39 @@ smbc_init_context(SMBCCTX *context) * lazy for the moment */ pid = sys_getpid(); - context->netbios_name = (char *)SMB_MALLOC(17); - if (!context->netbios_name) { + context->config.netbios_name = (char *)SMB_MALLOC(17); + if (!context->config.netbios_name) { errno = ENOMEM; return NULL; } - slprintf(context->netbios_name, 16, - "smbc%s%d", context->user, pid); + slprintf(context->config.netbios_name, 16, + "smbc%s%d", context->config.user, pid); } } - DEBUG(1, ("Using netbios name %s.\n", context->netbios_name)); + DEBUG(1, ("Using netbios name %s.\n", context->config.netbios_name)); - if (!context->workgroup) { + if (!context->config.workgroup) { if (lp_workgroup()) { - context->workgroup = SMB_STRDUP(lp_workgroup()); + context->config.workgroup = SMB_STRDUP(lp_workgroup()); } else { /* TODO: Think about a decent default workgroup */ - context->workgroup = SMB_STRDUP("samba"); + context->config.workgroup = SMB_STRDUP("samba"); } } - DEBUG(1, ("Using workgroup %s.\n", context->workgroup)); + DEBUG(1, ("Using workgroup %s.\n", context->config.workgroup)); /* shortest timeout is 1 second */ - if (context->timeout > 0 && context->timeout < 1000) - context->timeout = 1000; + if (context->config.timeout > 0 && context->config.timeout < 1000) + context->config.timeout = 1000; /* * FIXME: Should we check the function pointers here? */ - context->initialized = True; + context->internal->initialized = True; return context; } @@ -705,56 +748,56 @@ smbc_version(void) char * smbc_getNetbiosName(SMBCCTX *c) { - return c->netbios_name; + return c->config.netbios_name; } /** Set the netbios name used for making connections */ void smbc_setNetbiosName(SMBCCTX *c, char * netbios_name) { - c->netbios_name = netbios_name; + c->config.netbios_name = netbios_name; } /** Get the workgroup used for making connections */ char * smbc_getWorkgroup(SMBCCTX *c) { - return c->workgroup; + return c->config.workgroup; } /** Set the workgroup used for making connections */ void smbc_setWorkgroup(SMBCCTX *c, char * workgroup) { - c->workgroup = workgroup; + c->config.workgroup = workgroup; } /** Get the username used for making connections */ char * smbc_getUser(SMBCCTX *c) { - return c->user; + return c->config.user; } /** Set the username used for making connections */ void smbc_setUser(SMBCCTX *c, char * user) { - c->user = user; + c->config.user = user; } /** Get the debug level */ int smbc_getDebug(SMBCCTX *c) { - return c->debug; + return c->config.debug; } /** Set the debug level */ void smbc_setDebug(SMBCCTX *c, int debug) { - c->debug = debug; + c->config.debug = debug; } /** @@ -764,7 +807,7 @@ smbc_setDebug(SMBCCTX *c, int debug) int smbc_getTimeout(SMBCCTX *c) { - return c->timeout; + return c->config.timeout; } /** @@ -774,7 +817,7 @@ smbc_getTimeout(SMBCCTX *c) void smbc_setTimeout(SMBCCTX *c, int timeout) { - c->timeout = timeout; + c->config.timeout = timeout; } /** Get the function for obtaining authentication data */ @@ -886,7 +929,7 @@ smbc_setFunctionRemoveCachedServer(SMBCCTX *c, smbc_purge_cached_srv_fn smbc_getFunctionPurgeCachedServers(SMBCCTX *c) { - return c->cache.purge_cached_server_fn; + return c->cache.purge_cached_servers_fn; } /** @@ -896,7 +939,7 @@ smbc_getFunctionPurgeCachedServers(SMBCCTX *c) void smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn) { - c->cache.purge_cached_server_fn = fn; + c->cache.purge_cached_servers_fn = fn; } /** @@ -1014,13 +1057,13 @@ smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn) smbc_ftruncate_fn smbc_getFunctionFtruncate(SMBCCTX *c) { - return c->posix_emu.ftruncate_fn; + return c->internal->posix_emu.ftruncate_fn; } void smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn) { - c->posix_emu.ftruncate_fn = fn; + c->internal->posix_emu.ftruncate_fn = fn; } smbc_close_fn diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 9cb3351433..25020762a2 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -356,7 +356,7 @@ SMBC_opendir_ctx(SMBCCTX *context, struct sockaddr_storage rem_ss; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { DEBUG(4, ("no valid context\n")); errno = EINVAL + 8192; TALLOC_FREE(frame); @@ -400,7 +400,7 @@ SMBC_opendir_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -446,9 +446,9 @@ SMBC_opendir_ctx(SMBCCTX *context, } /* Determine how many local master browsers to query */ - max_lmb_count = (context->browse_max_lmb_count == 0 + max_lmb_count = (context->internal->browse_max_lmb_count == 0 ? INT_MAX - : context->browse_max_lmb_count); + : context->internal->browse_max_lmb_count); memset(&u_info, '\0', sizeof(u_info)); u_info.username = talloc_strdup(frame,user); @@ -826,7 +826,7 @@ SMBC_opendir_ctx(SMBCCTX *context, } - DLIST_ADD(context->files, dir); + DLIST_ADD(context->internal->files, dir); TALLOC_FREE(frame); return dir; @@ -842,13 +842,13 @@ SMBC_closedir_ctx(SMBCCTX *context, { TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (!dir || !SMBC_dlist_contains(context->files, dir)) { + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { errno = EBADF; TALLOC_FREE(frame); return -1; @@ -856,7 +856,7 @@ SMBC_closedir_ctx(SMBCCTX *context, remove_dir(dir); /* Clean it up */ - DLIST_REMOVE(context->files, dir); + DLIST_REMOVE(context->internal->files, dir); if (dir) { @@ -875,7 +875,7 @@ smbc_readdir_internal(SMBCCTX * context, struct smbc_dirent *src, int max_namebuf_len) { - if (context->urlencode_readdir_entries) { + if (context->internal->urlencode_readdir_entries) { /* url-encode the name. get back remaining buffer space */ max_namebuf_len = @@ -919,7 +919,7 @@ SMBC_readdir_ctx(SMBCCTX *context, /* Check that all is ok first ... */ - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; DEBUG(0, ("Invalid context in SMBC_readdir_ctx()\n")); @@ -928,7 +928,7 @@ SMBC_readdir_ctx(SMBCCTX *context, } - if (!dir || !SMBC_dlist_contains(context->files, dir)) { + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { errno = EBADF; DEBUG(0, ("Invalid dir in SMBC_readdir_ctx()\n")); @@ -960,8 +960,8 @@ SMBC_readdir_ctx(SMBCCTX *context, } - dirp = (struct smbc_dirent *)context->dirent; - maxlen = (sizeof(context->dirent) - + dirp = (struct smbc_dirent *)context->internal->dirent; + maxlen = (sizeof(context->internal->dirent) - sizeof(struct smbc_dirent)); smbc_readdir_internal(context, dirp, dirent, maxlen); @@ -991,7 +991,7 @@ SMBC_getdents_ctx(SMBCCTX *context, /* Check that all is ok first ... */ - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -999,7 +999,7 @@ SMBC_getdents_ctx(SMBCCTX *context, } - if (!dir || !SMBC_dlist_contains(context->files, dir)) { + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { errno = EBADF; TALLOC_FREE(frame); @@ -1033,8 +1033,8 @@ SMBC_getdents_ctx(SMBCCTX *context, } /* Do urlencoding of next entry, if so selected */ - dirent = (struct smbc_dirent *)context->dirent; - maxlen = (sizeof(context->dirent) - + dirent = (struct smbc_dirent *)context->internal->dirent; + maxlen = (sizeof(context->internal->dirent) - sizeof(struct smbc_dirent)); smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen); @@ -1102,7 +1102,7 @@ SMBC_mkdir_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1132,7 +1132,7 @@ SMBC_mkdir_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1209,7 +1209,7 @@ SMBC_rmdir_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; @@ -1239,7 +1239,7 @@ SMBC_rmdir_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1325,7 +1325,7 @@ SMBC_telldir_ctx(SMBCCTX *context, { TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -1333,7 +1333,7 @@ SMBC_telldir_ctx(SMBCCTX *context, } - if (!dir || !SMBC_dlist_contains(context->files, dir)) { + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { errno = EBADF; TALLOC_FREE(frame); @@ -1408,7 +1408,7 @@ SMBC_lseekdir_ctx(SMBCCTX *context, struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -1465,7 +1465,7 @@ SMBC_fstatdir_ctx(SMBCCTX *context, struct stat *st) { - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; return -1; @@ -1490,7 +1490,7 @@ SMBC_chmod_ctx(SMBCCTX *context, uint16 mode; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -1521,7 +1521,7 @@ SMBC_chmod_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1570,7 +1570,7 @@ SMBC_utimes_ctx(SMBCCTX *context, time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -1627,7 +1627,7 @@ SMBC_utimes_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1668,7 +1668,7 @@ SMBC_unlink_ctx(SMBCCTX *context, SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -1699,7 +1699,7 @@ SMBC_unlink_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1802,8 +1802,8 @@ SMBC_rename_ctx(SMBCCTX *ocontext, TALLOC_CTX *frame = talloc_stackframe(); if (!ocontext || !ncontext || - !ocontext->initialized || - !ncontext->initialized) { + !ocontext->internal->initialized || + !ncontext->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -1834,7 +1834,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, } if (!user1 || user1[0] == (char)0) { - user1 = talloc_strdup(frame, ocontext->user); + user1 = talloc_strdup(frame, ocontext->config.user); if (!user1) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1858,7 +1858,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, } if (!user2 || user2[0] == (char)0) { - user2 = talloc_strdup(frame, ncontext->user); + user2 = talloc_strdup(frame, ncontext->config.user); if (!user2) { errno = ENOMEM; TALLOC_FREE(frame); diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 619176697b..62b990ed00 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -46,7 +46,7 @@ SMBC_open_ctx(SMBCCTX *context, int fd; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -78,7 +78,7 @@ SMBC_open_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -120,7 +120,7 @@ SMBC_open_ctx(SMBCCTX *context, /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ if ((fd = cli_open(targetcli, targetpath, flags, - context->share_mode)) < 0) { + context->internal->share_mode)) < 0) { /* Handle the error ... */ @@ -139,7 +139,7 @@ SMBC_open_ctx(SMBCCTX *context, file->offset = 0; file->file = True; - DLIST_ADD(context->files, file); + DLIST_ADD(context->internal->files, file); /* * If the file was opened in O_APPEND mode, all write @@ -208,7 +208,7 @@ SMBC_creat_ctx(SMBCCTX *context, mode_t mode) { - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; return NULL; @@ -246,7 +246,7 @@ SMBC_read_ctx(SMBCCTX *context, */ off_t offset; - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -256,7 +256,7 @@ SMBC_read_ctx(SMBCCTX *context, DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; @@ -338,7 +338,7 @@ SMBC_write_ctx(SMBCCTX *context, /* First check all pointers before dereferencing them */ - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -346,7 +346,7 @@ SMBC_write_ctx(SMBCCTX *context, } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; @@ -418,14 +418,14 @@ SMBC_close_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; @@ -470,7 +470,7 @@ SMBC_close_ctx(SMBCCTX *context, * from the server cache if unused */ errno = SMBC_errno(context, targetcli); srv = file->srv; - DLIST_REMOVE(context->files, file); + DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); (context->server.remove_unused_server_fn)(context, srv); @@ -479,7 +479,7 @@ SMBC_close_ctx(SMBCCTX *context, } - DLIST_REMOVE(context->files, file); + DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); TALLOC_FREE(frame); @@ -509,7 +509,7 @@ SMBC_getatr(SMBCCTX * context, time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -698,14 +698,14 @@ SMBC_lseek_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); @@ -803,14 +803,14 @@ SMBC_ftruncate_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index 2533f536c3..6706a59ba8 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -252,7 +252,8 @@ SMBC_parse_path(TALLOC_CTX *ctx, * to the workgroup in the provided context. */ if (pp_workgroup != NULL) { - *pp_workgroup = talloc_strdup(ctx, context->workgroup); + *pp_workgroup = + talloc_strdup(ctx, context->config.workgroup); } if (pp_options) { @@ -296,13 +297,13 @@ SMBC_parse_path(TALLOC_CTX *ctx, } if (*p == '/') { - int wl = strlen(context->workgroup); + int wl = strlen(context->config.workgroup); if (wl > 16) { wl = 16; } - *pp_server = talloc_strdup(ctx, context->workgroup); + *pp_server = talloc_strdup(ctx, context->config.workgroup); if (!*pp_server) { return -1; } diff --git a/source3/libsmb/libsmb_printjob.c b/source3/libsmb/libsmb_printjob.c index f106080b6f..a03c15e024 100644 --- a/source3/libsmb/libsmb_printjob.c +++ b/source3/libsmb/libsmb_printjob.c @@ -42,7 +42,7 @@ SMBC_open_print_job_ctx(SMBCCTX *context, char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -99,8 +99,8 @@ SMBC_print_file_ctx(SMBCCTX *c_file, char buf[4096]; TALLOC_CTX *frame = talloc_stackframe(); - if (!c_file || !c_file->initialized || - !c_print || !c_print->initialized) { + if (!c_file || !c_file->internal->initialized || + !c_print || !c_print->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -189,7 +189,7 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context, char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -220,7 +220,7 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -267,7 +267,7 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context, int err; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); @@ -298,7 +298,7 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 978a843d30..70e0d57273 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -58,12 +58,12 @@ SMBC_remove_unused_server(SMBCCTX * context, SMBCFILE * file; /* are we being fooled ? */ - if (!context || !context->initialized || !srv) { + if (!context || !context->internal->initialized || !srv) { return 1; } /* Check all open files/directories for a relation with this server */ - for (file = context->files; file; file = file->next) { + for (file = context->internal->files; file; file = file->next) { if (file->srv == srv) { /* Still used */ DEBUG(3, ("smbc_remove_usused_server: " @@ -73,7 +73,7 @@ SMBC_remove_unused_server(SMBCCTX * context, } } - DLIST_REMOVE(context->servers, srv); + DLIST_REMOVE(context->internal->servers, srv); cli_shutdown(srv->cli); srv->cli = NULL; @@ -251,7 +251,7 @@ SMBC_server(TALLOC_CTX *ctx, * If we found a connection and we're only allowed one share per * server... */ - if (srv && *share != '\0' && context->one_share_per_server) { + if (srv && *share != '\0' && context->internal->one_share_per_server) { /* * ... then if there's no current connection to the share, @@ -322,7 +322,7 @@ SMBC_server(TALLOC_CTX *ctx, return NULL; } - make_nmb_name(&calling, context->netbios_name, 0x0); + make_nmb_name(&calling, context->config.netbios_name, 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server)); @@ -339,14 +339,14 @@ SMBC_server(TALLOC_CTX *ctx, return NULL; } - if (context->use_kerberos) { + if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) { c->use_kerberos = True; } - if (context->fallback_after_kerberos) { + if (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { c->fallback_after_kerberos = True; } - c->timeout = context->timeout; + c->timeout = context->config.timeout; /* * Force use of port 139 for first try if share is $IPC, empty, or @@ -428,7 +428,8 @@ SMBC_server(TALLOC_CTX *ctx, /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; - if (context->no_auto_anonymous_login || + if ((context->flags.bits & + SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || !NT_STATUS_IS_OK(cli_session_setup(c, username_used, *pp_password, 1, *pp_password, 0, @@ -451,7 +452,7 @@ SMBC_server(TALLOC_CTX *ctx, DEBUG(4,(" tconx ok\n")); - if (context->smb_encryption_level) { + if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(c, username_used, @@ -466,7 +467,7 @@ SMBC_server(TALLOC_CTX *ctx, DEBUG(4,(" SMB encrypt failed\n")); - if (context->smb_encryption_level == 2) { + if (context->internal->smb_encryption_level == 2) { cli_shutdown(c); errno = EPERM; return NULL; @@ -512,7 +513,7 @@ SMBC_server(TALLOC_CTX *ctx, DEBUG(2, ("Server connect ok: //%s/%s: %p\n", server, share, srv)); - DLIST_ADD(context->servers, srv); + DLIST_ADD(context->internal->servers, srv); return srv; failed: @@ -566,7 +567,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, } flags = 0; - if (context->use_kerberos) { + if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } @@ -586,7 +587,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, return NULL; } - if (context->smb_encryption_level) { + if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, *pp_username, @@ -602,7 +603,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, DEBUG(4,(" SMB encrypt failed on IPC$\n")); - if (context->smb_encryption_level == 2) { + if (context->internal->smb_encryption_level == 2) { cli_shutdown(ipc_cli); errno = EPERM; return NULL; @@ -668,7 +669,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, return NULL; } - DLIST_ADD(context->servers, ipc_srv); + DLIST_ADD(context->internal->servers, ipc_srv); } return ipc_srv; diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 06238863b7..6072547e08 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -35,7 +35,7 @@ static ino_t generate_inode(SMBCCTX *context, const char *name) { - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; return -1; @@ -126,7 +126,7 @@ SMBC_stat_ctx(SMBCCTX *context, SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -157,7 +157,7 @@ SMBC_stat_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame,context->user); + user = talloc_strdup(frame,context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -222,14 +222,14 @@ SMBC_fstat_ctx(SMBCCTX *context, SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - if (!file || !SMBC_dlist_contains(context->files, file)) { + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index 93ca0706b2..a420299341 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -609,7 +609,7 @@ dos_attr_parse(SMBCCTX *context, } attr_strings; /* Determine whether to use old-style or new-style attribute names */ - if (context->full_time_names) { + if (context->internal->full_time_names) { /* new-style names */ attr_strings.create_time_attr = "CREATE_TIME"; attr_strings.access_time_attr = "ACCESS_TIME"; @@ -759,7 +759,7 @@ cacl_get(SMBCCTX *context, } excl_attr_strings; /* Determine whether to use old-style or new-style attribute names */ - if (context->full_time_names) { + if (context->internal->full_time_names) { /* new-style names */ attr_strings.create_time_attr = "CREATE_TIME"; attr_strings.access_time_attr = "ACCESS_TIME"; @@ -1689,7 +1689,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } attr_strings; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -1721,7 +1721,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1893,7 +1893,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } /* Determine whether to use old-style or new-style attribute names */ - if (context->full_time_names) { + if (context->internal->full_time_names) { /* new-style names */ attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; @@ -1984,7 +1984,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, } attr_strings; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -2015,7 +2015,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -2041,7 +2041,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, } /* Determine whether to use old-style or new-style attribute names */ - if (context->full_time_names) { + if (context->internal->full_time_names) { /* new-style names */ attr_strings.create_time_attr = "system.dos_attr.CREATE_TIME"; attr_strings.access_time_attr = "system.dos_attr.ACCESS_TIME"; @@ -2118,7 +2118,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - if (!context || !context->initialized) { + if (!context || !context->internal->initialized) { errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); @@ -2149,7 +2149,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->user); + user = talloc_strdup(frame, context->config.user); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -2270,7 +2270,7 @@ SMBC_listxattr_ctx(SMBCCTX *context, ; const char * supported; - if (context->full_time_names) { + if (context->internal->full_time_names) { supported = supported_new; retsize = sizeof(supported_new); } else { -- cgit From 223940d9a887c5b98a5c873797302a6a9407ad7f Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 1 Mar 2008 20:44:21 -0500 Subject: Additional revamped libsmbclient documentation - Ensured that all public functions have documentation in libsmbclient.h - Reformatted for "proper" indentation - Re-added temporarily-disabled alternate authentication function capability Derrell (This used to be commit 64b7150d92849a1e1e2416b9dcc12fae8d6bea99) --- source3/libsmb/libsmb_cache.c | 54 +- source3/libsmb/libsmb_compat.c | 52 +- source3/libsmb/libsmb_context.c | 1508 +++++++++++++++++++++----------------- source3/libsmb/libsmb_dir.c | 930 +++++++++++------------ source3/libsmb/libsmb_file.c | 393 +++++----- source3/libsmb/libsmb_misc.c | 10 +- source3/libsmb/libsmb_path.c | 114 +-- source3/libsmb/libsmb_printjob.c | 178 ++--- source3/libsmb/libsmb_server.c | 275 +++---- source3/libsmb/libsmb_stat.c | 132 ++-- source3/libsmb/libsmb_xattr.c | 636 ++++++++-------- 11 files changed, 2232 insertions(+), 2050 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index 7ff92f1b4e..ff13fd7eac 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -35,10 +35,10 @@ struct smbc_server_cache { char *workgroup; char *username; SMBCSRV *server; - + struct smbc_server_cache *next, *prev; }; - + /* @@ -54,51 +54,51 @@ SMBC_add_cached_server(SMBCCTX * context, const char * username) { struct smbc_server_cache * srvcache = NULL; - + if (!(srvcache = SMB_MALLOC_P(struct smbc_server_cache))) { errno = ENOMEM; DEBUG(3, ("Not enough space for server cache allocation\n")); return 1; } - + ZERO_STRUCTP(srvcache); - + srvcache->server = newsrv; - + srvcache->server_name = SMB_STRDUP(server); if (!srvcache->server_name) { errno = ENOMEM; goto failed; } - + srvcache->share_name = SMB_STRDUP(share); if (!srvcache->share_name) { errno = ENOMEM; goto failed; } - + srvcache->workgroup = SMB_STRDUP(workgroup); if (!srvcache->workgroup) { errno = ENOMEM; goto failed; } - + srvcache->username = SMB_STRDUP(username); if (!srvcache->username) { errno = ENOMEM; goto failed; } - + DLIST_ADD((context->cache.server_cache_data), srvcache); return 0; - - failed: + +failed: SAFE_FREE(srvcache->server_name); SAFE_FREE(srvcache->share_name); SAFE_FREE(srvcache->workgroup); SAFE_FREE(srvcache->username); SAFE_FREE(srvcache); - + return 1; } @@ -117,19 +117,19 @@ SMBC_get_cached_server(SMBCCTX * context, const char * user) { struct smbc_server_cache * srv = NULL; - + /* Search the cache lines */ for (srv = context->cache.server_cache_data; srv; srv = srv->next) { - + if (strcmp(server,srv->server_name) == 0 && strcmp(workgroup,srv->workgroup) == 0 && strcmp(user, srv->username) == 0) { - + /* If the share name matches, we're cool */ if (strcmp(share, srv->share_name) == 0) { return srv->server; } - + /* * We only return an empty share name or the attribute * server on an exact match (which would have been @@ -137,7 +137,7 @@ SMBC_get_cached_server(SMBCCTX * context, */ if (*share == '\0' || strcmp(share, "*IPC$") == 0) continue; - + /* * Never return an empty share name or the attribute * server if it wasn't what was requested. @@ -145,7 +145,7 @@ SMBC_get_cached_server(SMBCCTX * context, if (*srv->share_name == '\0' || strcmp(srv->share_name, "*IPC$") == 0) continue; - + /* * If we're only allowing one share per server, then * a connection to the server (other than the @@ -164,7 +164,7 @@ SMBC_get_cached_server(SMBCCTX * context, context->cache.remove_cached_server_fn(context, srv->server); continue; } - + /* * Save the new share name. We've * disconnected from the old share, and are @@ -179,13 +179,13 @@ SMBC_get_cached_server(SMBCCTX * context, context->cache.remove_cached_server_fn(context, srv->server); continue; } - - + + return srv->server; } } } - + return NULL; } @@ -200,10 +200,10 @@ SMBC_remove_cached_server(SMBCCTX * context, SMBCSRV * server) { struct smbc_server_cache * srv = NULL; - + for (srv = context->cache.server_cache_data; srv; srv = srv->next) { if (server == srv->server) { - + /* remove this sucker */ DLIST_REMOVE(context->cache.server_cache_data, srv); SAFE_FREE(srv->server_name); @@ -229,13 +229,13 @@ SMBC_purge_cached_servers(SMBCCTX * context) struct smbc_server_cache * srv; struct smbc_server_cache * next; int could_not_purge_all = 0; - + for (srv = context->cache.server_cache_data, next = (srv ? srv->next :NULL); srv; srv = next, next = (srv ? srv->next : NULL)) { - + if (SMBC_remove_unused_server(context, srv->server)) { /* could not be removed */ could_not_purge_all = 1; diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 7a0536a92d..9ef5e51fa9 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -55,11 +55,11 @@ static int add_fd(SMBCFILE * file) { struct smbc_compat_fdlist * f = smbc_compat_fd_avail; - + if (f) { /* We found one that's available */ DLIST_REMOVE(smbc_compat_fd_avail, f); - + } else { /* * None were available, so allocate one. Keep the number of @@ -72,19 +72,19 @@ add_fd(SMBCFILE * file) errno = EMFILE; return -1; } - + f = SMB_MALLOC_P(struct smbc_compat_fdlist); if (!f) { errno = ENOMEM; return -1; } - + f->fd = SMBC_BASE_FD + smbc_compat_nextfd++; } - + f->file = file; DLIST_ADD(smbc_compat_fd_in_use, f); - + return f->fd; } @@ -95,13 +95,13 @@ static int del_fd(int fd) { struct smbc_compat_fdlist * f = smbc_compat_fd_in_use; - + while (f) { if (f->fd == fd) break; f = f->next; } - + if (f) { /* found */ DLIST_REMOVE(smbc_compat_fd_in_use, f); @@ -111,7 +111,7 @@ del_fd(int fd) } return 1; } - + int @@ -122,17 +122,17 @@ smbc_init(smbc_get_auth_data_fn fn, statcont = smbc_new_context(); if (!statcont) return -1; - + smbc_setDebug(statcont, debug); smbc_setFunctionAuthData(statcont, fn); - + if (!smbc_init_context(statcont)) { smbc_free_context(statcont, False); return -1; } - + smbc_compat_initialized = 1; - + return 0; } return 0; @@ -143,11 +143,11 @@ SMBCCTX * smbc_set_context(SMBCCTX * context) { SMBCCTX *old_context = statcont; - + if (context) { /* Save provided context. It must have been initialized! */ statcont = context; - + /* You'd better know what you're doing. We won't help you. */ smbc_compat_initialized = 1; } @@ -163,11 +163,11 @@ smbc_open(const char *furl, { SMBCFILE * file; int fd; - + file = smbc_getFunctionOpen(statcont)(statcont, furl, flags, mode); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) smbc_getFunctionClose(statcont)(statcont, file); @@ -181,11 +181,11 @@ smbc_creat(const char *furl, { SMBCFILE * file; int fd; - + file = smbc_getFunctionCreat(statcont)(statcont, furl, mode); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) { /* Hmm... should we delete the file too ? I guess we could try */ @@ -250,15 +250,15 @@ smbc_opendir(const char *durl) { SMBCFILE * file; int fd; - + file = smbc_getFunctionOpendir(statcont)(statcont, durl); if (!file) return -1; - + fd = add_fd(file); if (fd == -1) smbc_getFunctionClosedir(statcont)(statcont, file); - + return fd; } @@ -357,14 +357,14 @@ smbc_utime(const char *fname, struct utimbuf *utbuf) { struct timeval tv[2]; - + if (utbuf == NULL) return smbc_getFunctionUtimes(statcont)(statcont, fname, NULL); - + tv[0].tv_sec = utbuf->actime; tv[1].tv_sec = utbuf->modtime; tv[0].tv_usec = tv[1].tv_usec = 0; - + return smbc_getFunctionUtimes(statcont)(statcont, fname, tv); } #endif @@ -519,7 +519,7 @@ int smbc_open_print_job(const char *fname) { SMBCFILE * file; - + file = smbc_getFunctionOpenPrintJob(statcont)(statcont, fname); if (!file) return -1; return file->cli_fd; diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 6b7a19e1e4..8af49d12be 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -40,88 +40,88 @@ static int SMBC_initialized = 0; SMBCCTX * smbc_new_context(void) { - SMBCCTX *context; - - /* - * All newly added context fields should be placed in SMBC_internal_data, - * not directly in SMBCCTX. - */ -# undef OLD -# define OLD(field) context->field -# undef NEW -# define NEW(field) context->internal->field - - context = SMB_MALLOC_P(SMBCCTX); - if (!context) { - errno = ENOMEM; - return NULL; - } - - ZERO_STRUCTP(context); - - context->internal = SMB_MALLOC_P(struct SMBC_internal_data); - if (!context->internal) { - SAFE_FREE(context); - errno = ENOMEM; - return NULL; - } - - /* Initialize the context and establish reasonable defaults */ - ZERO_STRUCTP(context->internal); - - OLD(config.debug) = 0; - OLD(config.timeout) = 20000; /* 20 seconds */ - - NEW(full_time_names) = False; - NEW(share_mode) = SMBC_SHAREMODE_DENY_NONE; - NEW(smb_encryption_level) = 0; - NEW(browse_max_lmb_count) = 3; /* # LMBs to query */ - NEW(urlencode_readdir_entries) = False; - NEW(one_share_per_server) = False; - - OLD(server.get_auth_data_fn) = SMBC_get_auth_data; - OLD(server.check_server_fn) = SMBC_check_server; - OLD(server.remove_unused_server_fn) = SMBC_remove_unused_server; - - OLD(cache.server_cache_data) = NULL; - OLD(cache.add_cached_server_fn) = SMBC_add_cached_server; - OLD(cache.get_cached_server_fn) = SMBC_get_cached_server; - OLD(cache.remove_cached_server_fn) = SMBC_remove_cached_server; - OLD(cache.purge_cached_servers_fn) = SMBC_purge_cached_servers; - - OLD(posix_emu.open_fn) = SMBC_open_ctx; - OLD(posix_emu.creat_fn) = SMBC_creat_ctx; - OLD(posix_emu.read_fn) = SMBC_read_ctx; - OLD(posix_emu.write_fn) = SMBC_write_ctx; - OLD(posix_emu.close_fn) = SMBC_close_ctx; - OLD(posix_emu.unlink_fn) = SMBC_unlink_ctx; - OLD(posix_emu.rename_fn) = SMBC_rename_ctx; - OLD(posix_emu.lseek_fn) = SMBC_lseek_ctx; - NEW(posix_emu.ftruncate_fn) = SMBC_ftruncate_ctx; - OLD(posix_emu.stat_fn) = SMBC_stat_ctx; - OLD(posix_emu.fstat_fn) = SMBC_fstat_ctx; - OLD(posix_emu.opendir_fn) = SMBC_opendir_ctx; - OLD(posix_emu.closedir_fn) = SMBC_closedir_ctx; - OLD(posix_emu.readdir_fn) = SMBC_readdir_ctx; - OLD(posix_emu.getdents_fn) = SMBC_getdents_ctx; - OLD(posix_emu.mkdir_fn) = SMBC_mkdir_ctx; - OLD(posix_emu.rmdir_fn) = SMBC_rmdir_ctx; - OLD(posix_emu.telldir_fn) = SMBC_telldir_ctx; - OLD(posix_emu.lseekdir_fn) = SMBC_lseekdir_ctx; - OLD(posix_emu.fstatdir_fn) = SMBC_fstatdir_ctx; - OLD(posix_emu.chmod_fn) = SMBC_chmod_ctx; - OLD(posix_emu.utimes_fn) = SMBC_utimes_ctx; - OLD(posix_emu.setxattr_fn) = SMBC_setxattr_ctx; - OLD(posix_emu.getxattr_fn) = SMBC_getxattr_ctx; - OLD(posix_emu.removexattr_fn) = SMBC_removexattr_ctx; - OLD(posix_emu.listxattr_fn) = SMBC_listxattr_ctx; - - OLD(printing.open_print_job_fn) = SMBC_open_print_job_ctx; - OLD(printing.print_file_fn) = SMBC_print_file_ctx; - OLD(printing.list_print_jobs_fn) = SMBC_list_print_jobs_ctx; - OLD(printing.unlink_print_job_fn) = SMBC_unlink_print_job_ctx; - - return context; + SMBCCTX *context; + + /* + * All newly added context fields should be placed in + * SMBC_internal_data, not directly in SMBCCTX. + */ +#undef OLD +#define OLD(field) context->field +#undef NEW +#define NEW(field) context->internal->field + + context = SMB_MALLOC_P(SMBCCTX); + if (!context) { + errno = ENOMEM; + return NULL; + } + + ZERO_STRUCTP(context); + + context->internal = SMB_MALLOC_P(struct SMBC_internal_data); + if (!context->internal) { + SAFE_FREE(context); + errno = ENOMEM; + return NULL; + } + + /* Initialize the context and establish reasonable defaults */ + ZERO_STRUCTP(context->internal); + + OLD(config.debug) = 0; + OLD(config.timeout) = 20000; /* 20 seconds */ + + NEW(full_time_names) = False; + NEW(share_mode) = SMBC_SHAREMODE_DENY_NONE; + NEW(smb_encryption_level) = 0; + OLD(options.browse_max_lmb_count) = 3; /* # LMBs to query */ + OLD(options.urlencode_readdir_entries) = False; + OLD(options.one_share_per_server) = False; + + OLD(server.get_auth_data_fn) = SMBC_get_auth_data; + OLD(server.check_server_fn) = SMBC_check_server; + OLD(server.remove_unused_server_fn) = SMBC_remove_unused_server; + + OLD(cache.server_cache_data) = NULL; + OLD(cache.add_cached_server_fn) = SMBC_add_cached_server; + OLD(cache.get_cached_server_fn) = SMBC_get_cached_server; + OLD(cache.remove_cached_server_fn) = SMBC_remove_cached_server; + OLD(cache.purge_cached_servers_fn) = SMBC_purge_cached_servers; + + OLD(posix_emu.open_fn) = SMBC_open_ctx; + OLD(posix_emu.creat_fn) = SMBC_creat_ctx; + OLD(posix_emu.read_fn) = SMBC_read_ctx; + OLD(posix_emu.write_fn) = SMBC_write_ctx; + OLD(posix_emu.close_fn) = SMBC_close_ctx; + OLD(posix_emu.unlink_fn) = SMBC_unlink_ctx; + OLD(posix_emu.rename_fn) = SMBC_rename_ctx; + OLD(posix_emu.lseek_fn) = SMBC_lseek_ctx; + NEW(posix_emu.ftruncate_fn) = SMBC_ftruncate_ctx; + OLD(posix_emu.stat_fn) = SMBC_stat_ctx; + OLD(posix_emu.fstat_fn) = SMBC_fstat_ctx; + OLD(posix_emu.opendir_fn) = SMBC_opendir_ctx; + OLD(posix_emu.closedir_fn) = SMBC_closedir_ctx; + OLD(posix_emu.readdir_fn) = SMBC_readdir_ctx; + OLD(posix_emu.getdents_fn) = SMBC_getdents_ctx; + OLD(posix_emu.mkdir_fn) = SMBC_mkdir_ctx; + OLD(posix_emu.rmdir_fn) = SMBC_rmdir_ctx; + OLD(posix_emu.telldir_fn) = SMBC_telldir_ctx; + OLD(posix_emu.lseekdir_fn) = SMBC_lseekdir_ctx; + OLD(posix_emu.fstatdir_fn) = SMBC_fstatdir_ctx; + OLD(posix_emu.chmod_fn) = SMBC_chmod_ctx; + OLD(posix_emu.utimes_fn) = SMBC_utimes_ctx; + OLD(posix_emu.setxattr_fn) = SMBC_setxattr_ctx; + OLD(posix_emu.getxattr_fn) = SMBC_getxattr_ctx; + OLD(posix_emu.removexattr_fn) = SMBC_removexattr_ctx; + OLD(posix_emu.listxattr_fn) = SMBC_listxattr_ctx; + + OLD(printing.open_print_job_fn) = SMBC_open_print_job_ctx; + OLD(printing.print_file_fn) = SMBC_print_file_ctx; + OLD(printing.list_print_jobs_fn) = SMBC_list_print_jobs_ctx; + OLD(printing.unlink_print_job_fn) = SMBC_unlink_print_job_ctx; + + return context; #undef OLD #undef NEW } @@ -137,420 +137,268 @@ int smbc_free_context(SMBCCTX *context, int shutdown_ctx) { - if (!context) { - errno = EBADF; - return 1; - } - - if (shutdown_ctx) { - SMBCFILE * f; - DEBUG(1,("Performing aggressive shutdown.\n")); - - f = context->internal->files; - while (f) { - (context->posix_emu.close_fn)(context, f); - f = f->next; + if (!context) { + errno = EBADF; + return 1; } - context->internal->files = NULL; - /* First try to remove the servers the nice way. */ - if (context->cache.purge_cached_servers_fn(context)) { - SMBCSRV * s; - SMBCSRV * next; - DEBUG(1, ("Could not purge all servers, " - "Nice way shutdown failed.\n")); - s = context->internal->servers; - while (s) { - DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", - s, s->cli->fd)); - cli_shutdown(s->cli); - (context->cache.remove_cached_server_fn)(context, - s); - next = s->next; - DLIST_REMOVE(context->internal->servers, s); - SAFE_FREE(s); - s = next; - } - context->internal->servers = NULL; - } - } - else { - /* This is the polite way */ - if ((context->cache.purge_cached_servers_fn)(context)) { - DEBUG(1, ("Could not purge all servers, " - "free_context failed.\n")); - errno = EBUSY; - return 1; - } - if (context->internal->servers) { - DEBUG(1, ("Active servers in context, " - "free_context failed.\n")); - errno = EBUSY; - return 1; + if (shutdown_ctx) { + SMBCFILE * f; + DEBUG(1,("Performing aggressive shutdown.\n")); + + f = context->internal->files; + while (f) { + (context->posix_emu.close_fn)(context, f); + f = f->next; + } + context->internal->files = NULL; + + /* First try to remove the servers the nice way. */ + if (context->cache.purge_cached_servers_fn(context)) { + SMBCSRV * s; + SMBCSRV * next; + DEBUG(1, ("Could not purge all servers, " + "Nice way shutdown failed.\n")); + s = context->internal->servers; + while (s) { + DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", + s, s->cli->fd)); + cli_shutdown(s->cli); + (context->cache.remove_cached_server_fn)(context, + s); + next = s->next; + DLIST_REMOVE(context->internal->servers, s); + SAFE_FREE(s); + s = next; + } + context->internal->servers = NULL; + } } - if (context->internal->files) { - DEBUG(1, ("Active files in context, " - "free_context failed.\n")); - errno = EBUSY; - return 1; + else { + /* This is the polite way */ + if ((context->cache.purge_cached_servers_fn)(context)) { + DEBUG(1, ("Could not purge all servers, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->internal->servers) { + DEBUG(1, ("Active servers in context, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } + if (context->internal->files) { + DEBUG(1, ("Active files in context, " + "free_context failed.\n")); + errno = EBUSY; + return 1; + } } - } - - /* Things we have to clean up */ - SAFE_FREE(context->config.workgroup); - SAFE_FREE(context->config.netbios_name); - SAFE_FREE(context->config.user); - - DEBUG(3, ("Context %p successfully freed\n", context)); - SAFE_FREE(context); - return 0; + + /* Things we have to clean up */ + SAFE_FREE(context->config.workgroup); + SAFE_FREE(context->config.netbios_name); + SAFE_FREE(context->config.user); + + DEBUG(3, ("Context %p successfully freed\n", context)); + SAFE_FREE(context); + return 0; } -/* - * Each time the context structure is changed, we have binary backward - * compatibility issues. Instead of modifying the public portions of the - * context structure to add new options, instead, we put them in the internal - * portion of the context structure and provide a set function for these new - * options. +/** + * Deprecated interface. Do not use. Instead, use the various + * smbc_setOption*() functions or smbc_setFunctionAuthDataWithContext(). */ void smbc_option_set(SMBCCTX *context, char *option_name, ... /* option_value */) { - va_list ap; - union { - int i; - bool b; - smbc_get_auth_data_with_context_fn auth_fn; - void *v; - const char *s; - } option_value; - - va_start(ap, option_name); - - if (strcmp(option_name, "debug_to_stderr") == 0) { - /* - * Log to standard error instead of standard output. - */ - option_value.b = (bool) va_arg(ap, int); - context->internal->debug_stderr = option_value.b; - - } else if (strcmp(option_name, "full_time_names") == 0) { - /* - * Use new-style time attribute names, e.g. WRITE_TIME rather - * than the old-style names such as M_TIME. This allows also - * setting/getting CREATE_TIME which was previously - * unimplemented. (Note that the old C_TIME was supposed to - * be CHANGE_TIME but was confused and sometimes referred to - * CREATE_TIME.) - */ - option_value.b = (bool) va_arg(ap, int); - context->internal->full_time_names = option_value.b; - - } else if (strcmp(option_name, "open_share_mode") == 0) { - /* - * The share mode to use for files opened with - * SMBC_open_ctx(). The default is SMBC_SHAREMODE_DENY_NONE. - */ - option_value.i = va_arg(ap, int); - context->internal->share_mode = (smbc_share_mode) option_value.i; - - } else if (strcmp(option_name, "user_data") == 0) { - /* - * Save a user data handle which may be retrieved by the user - * with smbc_option_get() - */ - option_value.v = va_arg(ap, void *); - context->internal->user_data = option_value.v; - } else if (strcmp(option_name, "smb_encrypt_level") == 0) { - /* - * Save an encoded value for encryption level. - * 0 = off, 1 = attempt, 2 = required. - */ - option_value.s = va_arg(ap, const char *); - if (strcmp(option_value.s, "none") == 0) { - context->internal->smb_encryption_level = 0; - } else if (strcmp(option_value.s, "request") == 0) { - context->internal->smb_encryption_level = 1; - } else if (strcmp(option_value.s, "require") == 0) { - context->internal->smb_encryption_level = 2; - } - } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { - /* - * From how many local master browsers should the list of - * workgroups be retrieved? It can take up to 12 minutes or - * longer after a server becomes a local master browser, for - * it to have the entire browse list (the list of - * workgroups/domains) from an entire network. Since a client - * never knows which local master browser will be found first, - * the one which is found first and used to retrieve a browse - * list may have an incomplete or empty browse list. By - * requesting the browse list from multiple local master - * browsers, a more complete list can be generated. For small - * networks (few workgroups), it is recommended that this - * value be set to 0, causing the browse lists from all found - * local master browsers to be retrieved and merged. For - * networks with many workgroups, a suitable value for this - * variable is probably somewhere around 3. (Default: 3). - */ - option_value.i = va_arg(ap, int); - context->internal->browse_max_lmb_count = option_value.i; + va_list ap; + union { + int i; + bool b; + smbc_get_auth_data_with_context_fn auth_fn; + void *v; + const char *s; + } option_value; - } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { - /* - * There is a difference in the desired return strings from - * smbc_readdir() depending upon whether the filenames are to - * be displayed to the user, or whether they are to be - * appended to the path name passed to smbc_opendir() to call - * a further smbc_ function (e.g. open the file with - * smbc_open()). In the former case, the filename should be - * in "human readable" form. In the latter case, the smbc_ - * functions expect a URL which must be url-encoded. Those - * functions decode the URL. If, for example, smbc_readdir() - * returned a file name of "abc%20def.txt", passing a path - * with this file name attached to smbc_open() would cause - * smbc_open to attempt to open the file "abc def.txt" since - * the %20 is decoded into a space. - * - * Set this option to True if the names returned by - * smbc_readdir() should be url-encoded such that they can be - * passed back to another smbc_ call. Set it to False if the - * names returned by smbc_readdir() are to be presented to the - * user. - * - * For backwards compatibility, this option defaults to False. - */ - option_value.b = (bool) va_arg(ap, int); - context->internal->urlencode_readdir_entries = option_value.b; + va_start(ap, option_name); - } else if (strcmp(option_name, "one_share_per_server") == 0) { - /* - * Some Windows versions appear to have a limit to the number - * of concurrent SESSIONs and/or TREE CONNECTions. In - * one-shot programs (i.e. the program runs and then quickly - * ends, thereby shutting down all connections), it is - * probably reasonable to establish a new connection for each - * share. In long-running applications, the limitation can be - * avoided by using only a single connection to each server, - * and issuing a new TREE CONNECT when the share is accessed. - */ - option_value.b = (bool) va_arg(ap, int); - context->options.one_share_per_server = option_value.b; - - } else if (strcmp(option_name, "use_kerberos") == 0) { - option_value.b = (bool) va_arg(ap, int); - if (option_value.b) { - context->flags.bits |= SMB_CTX_FLAG_USE_KERBEROS; - } else { - context->flags.bits &= ~SMB_CTX_FLAG_USE_KERBEROS; - } - - } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { - option_value.b = (bool) va_arg(ap, int); - if (option_value.b) { - context->flags.bits |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; - } else { - context->flags.bits &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + if (strcmp(option_name, "debug_to_stderr") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionDebugToStderr(context, option_value.b); + + } else if (strcmp(option_name, "full_time_names") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionFullTimeNames(context, option_value.b); + + } else if (strcmp(option_name, "open_share_mode") == 0) { + option_value.i = va_arg(ap, int); + smbc_setOptionOpenShareMode(context, option_value.i); + + } else if (strcmp(option_name, "auth_function") == 0) { + option_value.auth_fn = + va_arg(ap, smbc_get_auth_data_with_context_fn); + smbc_setFunctionAuthDataWithContext(context, option_value.auth_fn); + + } else if (strcmp(option_name, "user_data") == 0) { + option_value.v = va_arg(ap, void *); + smbc_setOptionUserData(context, option_value.v); + + } else if (strcmp(option_name, "smb_encrypt_level") == 0) { + option_value.s = va_arg(ap, const char *); + if (strcmp(option_value.s, "none") == 0) { + smbc_setOptionSmbEncryptionLevel(context, + SMBC_ENCRYPTLEVEL_NONE); + } else if (strcmp(option_value.s, "request") == 0) { + smbc_setOptionSmbEncryptionLevel(context, + SMBC_ENCRYPTLEVEL_REQUEST); + } else if (strcmp(option_value.s, "require") == 0) { + smbc_setOptionSmbEncryptionLevel(context, + SMBC_ENCRYPTLEVEL_REQUIRE); + } + + } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { + option_value.i = va_arg(ap, int); + smbc_setOptionBrowseMaxLmbCount(context, option_value.i); + + } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionUrlEncodeReaddirEntries(context, option_value.b); + + } else if (strcmp(option_name, "one_share_per_server") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionOneSharePerServer(context, option_value.b); + + } else if (strcmp(option_name, "use_kerberos") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionUseKerberos(context, option_value.b); + + } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionFallbackAfterKerberos(context, option_value.b); + + } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { + option_value.b = (bool) va_arg(ap, int); + smbc_setOptionNoAutoAnonymousLogin(context, option_value.b); } - } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { - option_value.b = (bool) va_arg(ap, int); - if (option_value.b) { - context->flags.bits |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; - } else { - context->flags.bits &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; - } - } - - va_end(ap); + va_end(ap); } /* - * Retrieve the current value of an option + * Deprecated interface. Do not use. Instead, use the various + * smbc_getOption*() functions. */ void * smbc_option_get(SMBCCTX *context, char *option_name) { - int bits; - - if (strcmp(option_name, "debug_stderr") == 0) { - /* - * Log to standard error instead of standard output. - */ + int bits; + + if (strcmp(option_name, "debug_stderr") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->debug_stderr; + return (void *) (intptr_t) smbc_getOptionDebugToStderr(context); #else - return (void *) context->internal->debug_stderr; + return (void *) smbc_getOptionDebugToStderr(context); #endif - - } else if (strcmp(option_name, "full_time_names") == 0) { - /* - * Use new-style time attribute names, e.g. WRITE_TIME rather - * than the old-style names such as M_TIME. This allows also - * setting/getting CREATE_TIME which was previously - * unimplemented. (Note that the old C_TIME was supposed to - * be CHANGE_TIME but was confused and sometimes referred to - * CREATE_TIME.) - */ + + } else if (strcmp(option_name, "full_time_names") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->full_time_names; + return (void *) (intptr_t) smbc_getOptionFullTimeNames(context); #else - return (void *) context->internal->full_time_names; + return (void *) smbc_getOptionFullTimeNames(context); #endif - - } else if (strcmp(option_name, "user_data") == 0) { - /* - * Return the user data handle which was saved by the user - * with smbc_option_set() - */ - return context->internal->user_data; - - } else if (strcmp(option_name, "smb_encrypt_level") == 0) { - /* - * Return the current smb encrypt negotiate option as a string. - */ - switch (context->internal->smb_encryption_level) { - case 0: - return (void *) "none"; - case 1: - return (void *) "request"; - case 2: - return (void *) "require"; - } - - } else if (strcmp(option_name, "smb_encrypt_on") == 0) { - /* - * Return the current smb encrypt status option as a bool. - * false = off, true = on. We don't know what server is - * being requested, so we only return true if all servers - * are using an encrypted connection. - */ - SMBCSRV *s; - unsigned int num_servers = 0; - - for (s = context->internal->servers; s; s = s->next) { - num_servers++; - if (s->cli->trans_enc_state == NULL) { - return (void *)false; - } - } + + } else if (strcmp(option_name, "open_share_mode") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) (bool) (num_servers > 0); + return (void *) (intptr_t) smbc_getOptionOpenShareMode(context); #else - return (void *) (bool) (num_servers > 0); + return (void *) smbc_getOptionOpenShareMode(context); #endif - - } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { - /* - * From how many local master browsers should the list of - * workgroups be retrieved? It can take up to 12 minutes or - * longer after a server becomes a local master browser, for - * it to have the entire browse list (the list of - * workgroups/domains) from an entire network. Since a client - * never knows which local master browser will be found first, - * the one which is found first and used to retrieve a browse - * list may have an incomplete or empty browse list. By - * requesting the browse list from multiple local master - * browsers, a more complete list can be generated. For small - * networks (few workgroups), it is recommended that this - * value be set to 0, causing the browse lists from all found - * local master browsers to be retrieved and merged. For - * networks with many workgroups, a suitable value for this - * variable is probably somewhere around 3. (Default: 3). - */ + + } else if (strcmp(option_name, "auth_function") == 0) { + return (void *) smbc_getFunctionAuthDataWithContext(context); + + } else if (strcmp(option_name, "user_data") == 0) { + return smbc_getOptionUserData(context); + + } else if (strcmp(option_name, "smb_encrypt_level") == 0) { + switch(smbc_getOptionSmbEncryptionLevel(context)) + { + case 0: + return (void *) "none"; + case 1: + return (void *) "request"; + case 2: + return (void *) "require"; + } + + } else if (strcmp(option_name, "smb_encrypt_on") == 0) { + SMBCSRV *s; + unsigned int num_servers = 0; + + for (s = context->internal->servers; s; s = s->next) { + num_servers++; + if (s->cli->trans_enc_state == NULL) { + return (void *)false; + } + } #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->browse_max_lmb_count; + return (void *) (intptr_t) (bool) (num_servers > 0); #else - return (void *) context->internal->browse_max_lmb_count; + return (void *) (bool) (num_servers > 0); #endif - - } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { - /* - * There is a difference in the desired return strings from - * smbc_readdir() depending upon whether the filenames are to - * be displayed to the user, or whether they are to be - * appended to the path name passed to smbc_opendir() to call - * a further smbc_ function (e.g. open the file with - * smbc_open()). In the former case, the filename should be - * in "human readable" form. In the latter case, the smbc_ - * functions expect a URL which must be url-encoded. Those - * functions decode the URL. If, for example, smbc_readdir() - * returned a file name of "abc%20def.txt", passing a path - * with this file name attached to smbc_open() would cause - * smbc_open to attempt to open the file "abc def.txt" since - * the %20 is decoded into a space. - * - * Set this option to True if the names returned by - * smbc_readdir() should be url-encoded such that they can be - * passed back to another smbc_ call. Set it to False if the - * names returned by smbc_readdir() are to be presented to the - * user. - * - * For backwards compatibility, this option defaults to False. - */ + + } else if (strcmp(option_name, "browse_max_lmb_count") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *)(intptr_t) context->internal->urlencode_readdir_entries; + return (void *) (intptr_t) smbc_getOptionBrowseMaxLmbCount(context); #else - return (void *) (bool) context->internal->urlencode_readdir_entries; + return (void *) smbc_getOptionBrowseMaxLmbCount(context); #endif - - } else if (strcmp(option_name, "one_share_per_server") == 0) { - /* - * Some Windows versions appear to have a limit to the number - * of concurrent SESSIONs and/or TREE CONNECTions. In - * one-shot programs (i.e. the program runs and then quickly - * ends, thereby shutting down all connections), it is - * probably reasonable to establish a new connection for each - * share. In long-running applications, the limitation can be - * avoided by using only a single connection to each server, - * and issuing a new TREE CONNECT when the share is accessed. - */ + + } else if (strcmp(option_name, "urlencode_readdir_entries") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (void *) (intptr_t) context->internal->one_share_per_server; + return (void *)(intptr_t) smbc_getOptionUrlEncodeReaddirEntries(context); #else - return (void *) (bool) context->internal->one_share_per_server; + return (void *) (bool) smbc_getOptionUrlEncodeReaddirEntries(context); #endif - - } else if (strcmp(option_name, "use_kerberos") == 0) { - bits = context->flags.bits; + + } else if (strcmp(option_name, "one_share_per_server") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS - ? (void *) (intptr_t) 1 - : (void *) (intptr_t) 0); + return (void *) (intptr_t) smbc_getOptionOneSharePerServer(context); #else - return (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS - ? (void *) (bool) 1 - : (void *) (bool) 0); + return (void *) (bool) smbc_getOptionOneSharePerServer(context); #endif - - } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { + + } else if (strcmp(option_name, "use_kerberos") == 0) { + bits = context->flags.bits; #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS - ? (void *) (intptr_t) 1 - : (void *) (intptr_t) 0); + return (void *) (intptr_t) smbc_getOptionUseKerberos(context); #else - return (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS - ? (void *) (bool) 1 - : (void *) (bool) 0); + return (void *) (bool) smbc_getOptionUseKerberos(context); #endif - - } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { + + } else if (strcmp(option_name, "fallback_after_kerberos") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) - return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON - ? (void *) (intptr_t) 1 - : (void *) (intptr_t) 0); + return (void *)(intptr_t) smbc_getOptionFallbackAfterKerberos(context); #else - return (context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON - ? (void *) (bool) 1 - : (void *) (bool) 0); + return (void *) (bool) smbc_getOptionFallbackAfterKerberos(context); #endif - } - - return NULL; + + } else if (strcmp(option_name, "no_auto_anonymous_login") == 0) { +#if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) + return (void *) (intptr_t) smbc_getOptionNoAutoAnonymousLogin(context); +#else + return (void *) (bool) smbc_getOptionNoAutoAnonymousLogin(context); +#endif + } + + return NULL; } @@ -564,175 +412,175 @@ smbc_option_get(SMBCCTX *context, SMBCCTX * smbc_init_context(SMBCCTX *context) { - int pid; - char *user = NULL; - char *home = NULL; - extern bool in_client; - - if (!context) { - errno = EBADF; - return NULL; - } - - /* Do not initialise the same client twice */ - if (context->internal->initialized) { - return 0; - } - - if (!context->server.get_auth_data_fn || - context->config.debug < 0 || - context->config.debug > 100) { + int pid; + char *user = NULL; + char *home = NULL; + extern bool in_client; - errno = EINVAL; - return NULL; - - } - - if (!SMBC_initialized) { - /* - * Do some library-wide intializations the first time we get - * called - */ - bool conf_loaded = False; - TALLOC_CTX *frame = talloc_stackframe(); - - /* Set this to what the user wants */ - DEBUGLEVEL = context->config.debug; - - load_case_tables(); - - setup_logging("libsmbclient", True); - if (context->internal->debug_stderr) { - dbf = x_stderr; - x_setbuf(x_stderr, NULL); + if (!context) { + errno = EBADF; + return NULL; } - /* Here we would open the smb.conf file if needed ... */ + /* Do not initialise the same client twice */ + if (context->internal->initialized) { + return 0; + } - in_client = True; /* FIXME, make a param */ + if (!context->server.get_auth_data_fn || + context->config.debug < 0 || + context->config.debug > 100) { + + errno = EINVAL; + return NULL; + + } - home = getenv("HOME"); - if (home) { - char *conf = NULL; - if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) { - if (lp_load(conf, True, False, False, True)) { - conf_loaded = True; - } else { - DEBUG(5, ("Could not load config file: %s\n", - conf)); + if (!SMBC_initialized) { + /* + * Do some library-wide intializations the first time we get + * called + */ + bool conf_loaded = False; + TALLOC_CTX *frame = talloc_stackframe(); + + /* Set this to what the user wants */ + DEBUGLEVEL = context->config.debug; + + load_case_tables(); + + setup_logging("libsmbclient", True); + if (context->internal->debug_stderr) { + dbf = x_stderr; + x_setbuf(x_stderr, NULL); } - SAFE_FREE(conf); - } + + /* Here we would open the smb.conf file if needed ... */ + + in_client = True; /* FIXME, make a param */ + + home = getenv("HOME"); + if (home) { + char *conf = NULL; + if (asprintf(&conf, "%s/.smb/smb.conf", home) > 0) { + if (lp_load(conf, True, False, False, True)) { + conf_loaded = True; + } else { + DEBUG(5, ("Could not load config file: %s\n", + conf)); + } + SAFE_FREE(conf); + } + } + + if (!conf_loaded) { + /* + * Well, if that failed, try the get_dyn_CONFIGFILE + * Which points to the standard locn, and if that + * fails, silently ignore it and use the internal + * defaults ... + */ + + if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { + DEBUG(5, ("Could not load config file: %s\n", + get_dyn_CONFIGFILE())); + } else if (home) { + char *conf; + /* + * We loaded the global config file. Now lets + * load user-specific modifications to the + * global config. + */ + if (asprintf(&conf, + "%s/.smb/smb.conf.append", + home) > 0) { + if (!lp_load(conf, True, False, False, False)) { + DEBUG(10, + ("Could not append config file: " + "%s\n", + conf)); + } + SAFE_FREE(conf); + } + } + } + + load_interfaces(); /* Load the list of interfaces ... */ + + reopen_logs(); /* Get logging working ... */ + + /* + * Block SIGPIPE (from lib/util_sock.c: write()) + * It is not needed and should not stop execution + */ + BlockSignals(True, SIGPIPE); + + /* Done with one-time initialisation */ + SMBC_initialized = 1; + + TALLOC_FREE(frame); } - if (!conf_loaded) { - /* - * Well, if that failed, try the get_dyn_CONFIGFILE - * Which points to the standard locn, and if that - * fails, silently ignore it and use the internal - * defaults ... - */ - - if (!lp_load(get_dyn_CONFIGFILE(), True, False, False, False)) { - DEBUG(5, ("Could not load config file: %s\n", - get_dyn_CONFIGFILE())); - } else if (home) { - char *conf; + if (!context->config.user) { /* - * We loaded the global config file. Now lets - * load user-specific modifications to the - * global config. + * FIXME: Is this the best way to get the user info? */ - if (asprintf(&conf, - "%s/.smb/smb.conf.append", - home) > 0) { - if (!lp_load(conf, True, False, False, False)) { - DEBUG(10, - ("Could not append config file: " - "%s\n", - conf)); - } - SAFE_FREE(conf); + user = getenv("USER"); + /* walk around as "guest" if no username can be found */ + if (!user) context->config.user = SMB_STRDUP("guest"); + else context->config.user = SMB_STRDUP(user); + } + + if (!context->config.netbios_name) { + /* + * We try to get our netbios name from the config. If that + * fails we fall back on constructing our netbios name from + * our hostname etc + */ + if (global_myname()) { + context->config.netbios_name = SMB_STRDUP(global_myname()); + } + else { + /* + * Hmmm, I want to get hostname as well, but I am too + * lazy for the moment + */ + pid = sys_getpid(); + context->config.netbios_name = (char *)SMB_MALLOC(17); + if (!context->config.netbios_name) { + errno = ENOMEM; + return NULL; + } + slprintf(context->config.netbios_name, 16, + "smbc%s%d", context->config.user, pid); + } + } + + DEBUG(1, ("Using netbios name %s.\n", context->config.netbios_name)); + + if (!context->config.workgroup) { + if (lp_workgroup()) { + context->config.workgroup = SMB_STRDUP(lp_workgroup()); + } + else { + /* TODO: Think about a decent default workgroup */ + context->config.workgroup = SMB_STRDUP("samba"); } - } } - load_interfaces(); /* Load the list of interfaces ... */ + DEBUG(1, ("Using workgroup %s.\n", context->config.workgroup)); - reopen_logs(); /* Get logging working ... */ + /* shortest timeout is 1 second */ + if (context->config.timeout > 0 && context->config.timeout < 1000) + context->config.timeout = 1000; /* - * Block SIGPIPE (from lib/util_sock.c: write()) - * It is not needed and should not stop execution + * FIXME: Should we check the function pointers here? */ - BlockSignals(True, SIGPIPE); - /* Done with one-time initialisation */ - SMBC_initialized = 1; + context->internal->initialized = True; - TALLOC_FREE(frame); - } - - if (!context->config.user) { - /* - * FIXME: Is this the best way to get the user info? - */ - user = getenv("USER"); - /* walk around as "guest" if no username can be found */ - if (!user) context->config.user = SMB_STRDUP("guest"); - else context->config.user = SMB_STRDUP(user); - } - - if (!context->config.netbios_name) { - /* - * We try to get our netbios name from the config. If that - * fails we fall back on constructing our netbios name from - * our hostname etc - */ - if (global_myname()) { - context->config.netbios_name = SMB_STRDUP(global_myname()); - } - else { - /* - * Hmmm, I want to get hostname as well, but I am too - * lazy for the moment - */ - pid = sys_getpid(); - context->config.netbios_name = (char *)SMB_MALLOC(17); - if (!context->config.netbios_name) { - errno = ENOMEM; - return NULL; - } - slprintf(context->config.netbios_name, 16, - "smbc%s%d", context->config.user, pid); - } - } - - DEBUG(1, ("Using netbios name %s.\n", context->config.netbios_name)); - - if (!context->config.workgroup) { - if (lp_workgroup()) { - context->config.workgroup = SMB_STRDUP(lp_workgroup()); - } - else { - /* TODO: Think about a decent default workgroup */ - context->config.workgroup = SMB_STRDUP("samba"); - } - } - - DEBUG(1, ("Using workgroup %s.\n", context->config.workgroup)); - - /* shortest timeout is 1 second */ - if (context->config.timeout > 0 && context->config.timeout < 1000) - context->config.timeout = 1000; - - /* - * FIXME: Should we check the function pointers here? - */ - - context->internal->initialized = True; - - return context; + return context; } @@ -740,7 +588,7 @@ smbc_init_context(SMBCCTX *context) const char * smbc_version(void) { - return samba_version_string(); + return samba_version_string(); } @@ -748,56 +596,56 @@ smbc_version(void) char * smbc_getNetbiosName(SMBCCTX *c) { - return c->config.netbios_name; + return c->config.netbios_name; } /** Set the netbios name used for making connections */ void smbc_setNetbiosName(SMBCCTX *c, char * netbios_name) { - c->config.netbios_name = netbios_name; + c->config.netbios_name = netbios_name; } /** Get the workgroup used for making connections */ char * smbc_getWorkgroup(SMBCCTX *c) { - return c->config.workgroup; + return c->config.workgroup; } /** Set the workgroup used for making connections */ void smbc_setWorkgroup(SMBCCTX *c, char * workgroup) { - c->config.workgroup = workgroup; + c->config.workgroup = workgroup; } /** Get the username used for making connections */ char * smbc_getUser(SMBCCTX *c) { - return c->config.user; + return c->config.user; } /** Set the username used for making connections */ void smbc_setUser(SMBCCTX *c, char * user) { - c->config.user = user; + c->config.user = user; } /** Get the debug level */ int smbc_getDebug(SMBCCTX *c) { - return c->config.debug; + return c->config.debug; } /** Set the debug level */ void smbc_setDebug(SMBCCTX *c, int debug) { - c->config.debug = debug; + c->config.debug = debug; } /** @@ -807,7 +655,7 @@ smbc_setDebug(SMBCCTX *c, int debug) int smbc_getTimeout(SMBCCTX *c) { - return c->config.timeout; + return c->config.timeout; } /** @@ -817,43 +665,339 @@ smbc_getTimeout(SMBCCTX *c) void smbc_setTimeout(SMBCCTX *c, int timeout) { - c->config.timeout = timeout; + c->config.timeout = timeout; } -/** Get the function for obtaining authentication data */ +/** Get whether to log to standard error instead of standard output */ +smbc_bool +smbc_getOptionDebugToStderr(SMBCCTX *c) +{ + return c->internal->debug_stderr; +} + +/** Set whether to log to standard error instead of standard output */ +void +smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b) +{ + c->internal->debug_stderr = b; +} + +/** + * Get whether to use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also setting/getting + * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME + * was supposed to be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +smbc_bool +smbc_getOptionFullTimeNames(SMBCCTX *c) +{ + return c->internal->full_time_names; +} + +/** + * Set whether to use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also setting/getting + * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME + * was supposed to be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +void +smbc_setOptionFullTimeNames(SMBCCTX *c, smbc_bool b) +{ + c->internal->full_time_names = b; +} + +/** + * Get the share mode to use for files opened with SMBC_open_ctx(). The + * default is SMBC_SHAREMODE_DENY_NONE. + */ +smbc_share_mode +smbc_getOptionOpenShareMode(SMBCCTX *c) +{ + return c->internal->share_mode; +} + +/** + * Set the share mode to use for files opened with SMBC_open_ctx(). The + * default is SMBC_SHAREMODE_DENY_NONE. + */ +void +smbc_setOptionOpenShareMode(SMBCCTX *c, smbc_share_mode share_mode) +{ + c->internal->share_mode = share_mode; +} + +/** Retrieve a previously set user data handle */ +void * +smbc_getOptionUserData(SMBCCTX *c) +{ + return c->internal->user_data; +} + +/** Save a user data handle */ +void +smbc_setOptionUserData(SMBCCTX *c, void *user_data) +{ + c->internal->user_data = user_data; +} +/** Get the encoded value for encryption level. */ +smbc_smb_encrypt_level +smbc_getOptionSmbEncryptionLevel(SMBCCTX *c) +{ + return c->internal->smb_encryption_level; +} + +/** Set the encoded value for encryption level. */ +void +smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level) +{ + c->internal->smb_encryption_level = level; +} + +/** + * Get from how many local master browsers should the list of workgroups be + * retrieved. It can take up to 12 minutes or longer after a server becomes a + * local master browser, for it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client never knows + * which local master browser will be found first, the one which is found + * first and used to retrieve a browse list may have an incomplete or empty + * browse list. By requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small networks (few + * workgroups), it is recommended that this value be set to 0, causing the + * browse lists from all found local master browsers to be retrieved and + * merged. For networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +int +smbc_getOptionBrowseMaxLmbCount(SMBCCTX *c) +{ + return c->options.browse_max_lmb_count; +} + +/** + * Set from how many local master browsers should the list of workgroups be + * retrieved. It can take up to 12 minutes or longer after a server becomes a + * local master browser, for it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client never knows + * which local master browser will be found first, the one which is found + * first and used to retrieve a browse list may have an incomplete or empty + * browse list. By requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small networks (few + * workgroups), it is recommended that this value be set to 0, causing the + * browse lists from all found local master browsers to be retrieved and + * merged. For networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +void +smbc_setOptionBrowseMaxLmbCount(SMBCCTX *c, int count) +{ + c->options.browse_max_lmb_count = count; +} + +/** + * Get whether to url-encode readdir entries. + * + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +smbc_bool +smbc_getOptionUrlEncodeReaddirEntries(SMBCCTX *c) +{ + return c->options.urlencode_readdir_entries; +} + +/** + * Set whether to url-encode readdir entries. + * + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +void +smbc_setOptionUrlEncodeReaddirEntries(SMBCCTX *c, smbc_bool b) +{ + c->options.urlencode_readdir_entries = b; +} + +/** + * Get whether to use the same connection for all shares on a server. + * + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +smbc_bool +smbc_getOptionOneSharePerServer(SMBCCTX *c) +{ + return c->options.one_share_per_server; +} + +/** + * Set whether to use the same connection for all shares on a server. + * + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +void +smbc_setOptionOneSharePerServer(SMBCCTX *c, smbc_bool b) +{ + c->options.one_share_per_server = b; +} + +/** Get whether to enable use of kerberos */ +smbc_bool +smbc_getOptionUseKerberos(SMBCCTX *c) +{ + return c->flags.bits & SMB_CTX_FLAG_USE_KERBEROS ? True : False; +} + +/** Set whether to enable use of kerberos */ +void +smbc_setOptionUseKerberos(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags.bits |= SMB_CTX_FLAG_USE_KERBEROS; + } else { + c->flags.bits &= ~SMB_CTX_FLAG_USE_KERBEROS; + } +} + +/** Get whether to fallback after kerberos */ +smbc_bool +smbc_getOptionFallbackAfterKerberos(SMBCCTX *c) +{ + return c->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS ? True : False; +} + +/** Set whether to fallback after kerberos */ +void +smbc_setOptionFallbackAfterKerberos(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags.bits |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + } else { + c->flags.bits &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + } +} + +/** Get whether to automatically select anonymous login */ +smbc_bool +smbc_getOptionNoAutoAnonymousLogin(SMBCCTX *c) +{ + return c->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON ? True : False; +} + +/** Set whether to automatically select anonymous login */ +void +smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags.bits |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; + } else { + c->flags.bits &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; + } +} + +/** Get the function for obtaining authentication data */ smbc_get_auth_data_fn smbc_getFunctionAuthData(SMBCCTX *c) { - return c->server.get_auth_data_fn; + return c->server.get_auth_data_fn; } /** Set the function for obtaining authentication data */ void smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn) { - c->server.get_auth_data_fn = fn; + c->internal->auth_fn_with_context = NULL; + c->server.get_auth_data_fn = fn; +} + +/** Get the new-style authentication function which includes the context. */ +smbc_get_auth_data_with_context_fn +smbc_getFunctionAuthDataWithContext(SMBCCTX *c) +{ + return c->internal->auth_fn_with_context; +} + +/** Set the new-style authentication function which includes the context. */ +void +smbc_setFunctionAuthDataWithContext(SMBCCTX *c, + smbc_get_auth_data_with_context_fn fn) +{ + c->server.get_auth_data_fn = NULL; + c->internal->auth_fn_with_context = fn; } /** Get the function for checking if a server is still good */ smbc_check_server_fn smbc_getFunctionCheckServer(SMBCCTX *c) { - return c->server.check_server_fn; + return c->server.check_server_fn; } /** Set the function for checking if a server is still good */ void smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn) { - c->server.check_server_fn = fn; + c->server.check_server_fn = fn; } /** Get the function for removing a server if unused */ smbc_remove_unused_server_fn smbc_getFunctionRemoveUnusedServer(SMBCCTX *c) { - return c->server.remove_unused_server_fn; + return c->server.remove_unused_server_fn; } /** Set the function for removing a server if unused */ @@ -861,21 +1005,21 @@ void smbc_setFunctionRemoveUnusedServer(SMBCCTX *c, smbc_remove_unused_server_fn fn) { - c->server.remove_unused_server_fn = fn; + c->server.remove_unused_server_fn = fn; } /** Get the function to store private data of the server cache */ struct smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c) { - return c->cache.server_cache_data; + return c->cache.server_cache_data; } /** Set the function to store private data of the server cache */ void smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache) { - c->cache.server_cache_data = cache; + c->cache.server_cache_data = cache; } @@ -883,35 +1027,35 @@ smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache) smbc_add_cached_srv_fn smbc_getFunctionAddCachedServer(SMBCCTX *c) { - return c->cache.add_cached_server_fn; + return c->cache.add_cached_server_fn; } /** Set the function for adding a cached server */ void smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn) { - c->cache.add_cached_server_fn = fn; + c->cache.add_cached_server_fn = fn; } /** Get the function for server cache lookup */ smbc_get_cached_srv_fn smbc_getFunctionGetCachedServer(SMBCCTX *c) { - return c->cache.get_cached_server_fn; + return c->cache.get_cached_server_fn; } /** Set the function for server cache lookup */ void smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn) { - c->cache.get_cached_server_fn = fn; + c->cache.get_cached_server_fn = fn; } /** Get the function for server cache removal */ smbc_remove_cached_srv_fn smbc_getFunctionRemoveCachedServer(SMBCCTX *c) { - return c->cache.remove_cached_server_fn; + return c->cache.remove_cached_server_fn; } /** Set the function for server cache removal */ @@ -919,7 +1063,7 @@ void smbc_setFunctionRemoveCachedServer(SMBCCTX *c, smbc_remove_cached_srv_fn fn) { - c->cache.remove_cached_server_fn = fn; + c->cache.remove_cached_server_fn = fn; } /** @@ -929,7 +1073,7 @@ smbc_setFunctionRemoveCachedServer(SMBCCTX *c, smbc_purge_cached_srv_fn smbc_getFunctionPurgeCachedServers(SMBCCTX *c) { - return c->cache.purge_cached_servers_fn; + return c->cache.purge_cached_servers_fn; } /** @@ -939,7 +1083,7 @@ smbc_getFunctionPurgeCachedServers(SMBCCTX *c) void smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn) { - c->cache.purge_cached_servers_fn = fn; + c->cache.purge_cached_servers_fn = fn; } /** @@ -949,133 +1093,133 @@ smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn) smbc_open_fn smbc_getFunctionOpen(SMBCCTX *c) { - return c->posix_emu.open_fn; + return c->posix_emu.open_fn; } void smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn) { - c->posix_emu.open_fn = fn; + c->posix_emu.open_fn = fn; } smbc_creat_fn smbc_getFunctionCreat(SMBCCTX *c) { - return c->posix_emu.creat_fn; + return c->posix_emu.creat_fn; } void smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn) { - c->posix_emu.creat_fn = fn; + c->posix_emu.creat_fn = fn; } smbc_read_fn smbc_getFunctionRead(SMBCCTX *c) { - return c->posix_emu.read_fn; + return c->posix_emu.read_fn; } void smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn) { - c->posix_emu.read_fn = fn; + c->posix_emu.read_fn = fn; } smbc_write_fn smbc_getFunctionWrite(SMBCCTX *c) { - return c->posix_emu.write_fn; + return c->posix_emu.write_fn; } void smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn) { - c->posix_emu.write_fn = fn; + c->posix_emu.write_fn = fn; } smbc_unlink_fn smbc_getFunctionUnlink(SMBCCTX *c) { - return c->posix_emu.unlink_fn; + return c->posix_emu.unlink_fn; } void smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn) { - c->posix_emu.unlink_fn = fn; + c->posix_emu.unlink_fn = fn; } smbc_rename_fn smbc_getFunctionRename(SMBCCTX *c) { - return c->posix_emu.rename_fn; + return c->posix_emu.rename_fn; } void smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn) { - c->posix_emu.rename_fn = fn; + c->posix_emu.rename_fn = fn; } smbc_lseek_fn smbc_getFunctionLseek(SMBCCTX *c) { - return c->posix_emu.lseek_fn; + return c->posix_emu.lseek_fn; } void smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn) { - c->posix_emu.lseek_fn = fn; + c->posix_emu.lseek_fn = fn; } smbc_stat_fn smbc_getFunctionStat(SMBCCTX *c) { - return c->posix_emu.stat_fn; + return c->posix_emu.stat_fn; } void smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn) { - c->posix_emu.stat_fn = fn; + c->posix_emu.stat_fn = fn; } smbc_fstat_fn smbc_getFunctionFstat(SMBCCTX *c) { - return c->posix_emu.fstat_fn; + return c->posix_emu.fstat_fn; } void smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn) { - c->posix_emu.fstat_fn = fn; + c->posix_emu.fstat_fn = fn; } smbc_ftruncate_fn smbc_getFunctionFtruncate(SMBCCTX *c) { - return c->internal->posix_emu.ftruncate_fn; + return c->internal->posix_emu.ftruncate_fn; } void smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn) { - c->internal->posix_emu.ftruncate_fn = fn; + c->internal->posix_emu.ftruncate_fn = fn; } smbc_close_fn smbc_getFunctionClose(SMBCCTX *c) { - return c->posix_emu.close_fn; + return c->posix_emu.close_fn; } void smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn) { - c->posix_emu.close_fn = fn; + c->posix_emu.close_fn = fn; } @@ -1086,109 +1230,109 @@ smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn) smbc_opendir_fn smbc_getFunctionOpendir(SMBCCTX *c) { - return c->posix_emu.opendir_fn; + return c->posix_emu.opendir_fn; } void smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn) { - c->posix_emu.opendir_fn = fn; + c->posix_emu.opendir_fn = fn; } smbc_closedir_fn smbc_getFunctionClosedir(SMBCCTX *c) { - return c->posix_emu.closedir_fn; + return c->posix_emu.closedir_fn; } void smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn) { - c->posix_emu.closedir_fn = fn; + c->posix_emu.closedir_fn = fn; } smbc_readdir_fn smbc_getFunctionReaddir(SMBCCTX *c) { - return c->posix_emu.readdir_fn; + return c->posix_emu.readdir_fn; } void smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn) { - c->posix_emu.readdir_fn = fn; + c->posix_emu.readdir_fn = fn; } smbc_getdents_fn smbc_getFunctionGetdents(SMBCCTX *c) { - return c->posix_emu.getdents_fn; + return c->posix_emu.getdents_fn; } void smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn) { - c->posix_emu.getdents_fn = fn; + c->posix_emu.getdents_fn = fn; } smbc_mkdir_fn smbc_getFunctionMkdir(SMBCCTX *c) { - return c->posix_emu.mkdir_fn; + return c->posix_emu.mkdir_fn; } void smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn) { - c->posix_emu.mkdir_fn = fn; + c->posix_emu.mkdir_fn = fn; } smbc_rmdir_fn smbc_getFunctionRmdir(SMBCCTX *c) { - return c->posix_emu.rmdir_fn; + return c->posix_emu.rmdir_fn; } void smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn) { - c->posix_emu.rmdir_fn = fn; + c->posix_emu.rmdir_fn = fn; } smbc_telldir_fn smbc_getFunctionTelldir(SMBCCTX *c) { - return c->posix_emu.telldir_fn; + return c->posix_emu.telldir_fn; } void smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn) { - c->posix_emu.telldir_fn = fn; + c->posix_emu.telldir_fn = fn; } smbc_lseekdir_fn smbc_getFunctionLseekdir(SMBCCTX *c) { - return c->posix_emu.lseekdir_fn; + return c->posix_emu.lseekdir_fn; } void smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn) { - c->posix_emu.lseekdir_fn = fn; + c->posix_emu.lseekdir_fn = fn; } smbc_fstatdir_fn smbc_getFunctionFstatdir(SMBCCTX *c) { - return c->posix_emu.fstatdir_fn; + return c->posix_emu.fstatdir_fn; } void smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn) { - c->posix_emu.fstatdir_fn = fn; + c->posix_emu.fstatdir_fn = fn; } @@ -1199,73 +1343,73 @@ smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn) smbc_chmod_fn smbc_getFunctionChmod(SMBCCTX *c) { - return c->posix_emu.chmod_fn; + return c->posix_emu.chmod_fn; } void smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn) { - c->posix_emu.chmod_fn = fn; + c->posix_emu.chmod_fn = fn; } smbc_utimes_fn smbc_getFunctionUtimes(SMBCCTX *c) { - return c->posix_emu.utimes_fn; + return c->posix_emu.utimes_fn; } void smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn) { - c->posix_emu.utimes_fn = fn; + c->posix_emu.utimes_fn = fn; } smbc_setxattr_fn smbc_getFunctionSetxattr(SMBCCTX *c) { - return c->posix_emu.setxattr_fn; + return c->posix_emu.setxattr_fn; } void smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn) { - c->posix_emu.setxattr_fn = fn; + c->posix_emu.setxattr_fn = fn; } smbc_getxattr_fn smbc_getFunctionGetxattr(SMBCCTX *c) { - return c->posix_emu.getxattr_fn; + return c->posix_emu.getxattr_fn; } void smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn) { - c->posix_emu.getxattr_fn = fn; + c->posix_emu.getxattr_fn = fn; } smbc_removexattr_fn smbc_getFunctionRemovexattr(SMBCCTX *c) { - return c->posix_emu.removexattr_fn; + return c->posix_emu.removexattr_fn; } void smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn) { - c->posix_emu.removexattr_fn = fn; + c->posix_emu.removexattr_fn = fn; } smbc_listxattr_fn smbc_getFunctionListxattr(SMBCCTX *c) { - return c->posix_emu.listxattr_fn; + return c->posix_emu.listxattr_fn; } void smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn) { - c->posix_emu.listxattr_fn = fn; + c->posix_emu.listxattr_fn = fn; } @@ -1276,51 +1420,51 @@ smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn) smbc_print_file_fn smbc_getFunctionPrintFile(SMBCCTX *c) { - return c->printing.print_file_fn; + return c->printing.print_file_fn; } void smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn) { - c->printing.print_file_fn = fn; + c->printing.print_file_fn = fn; } smbc_open_print_job_fn smbc_getFunctionOpenPrintJob(SMBCCTX *c) { - return c->printing.open_print_job_fn; + return c->printing.open_print_job_fn; } void smbc_setFunctionOpenPrintJob(SMBCCTX *c, smbc_open_print_job_fn fn) { - c->printing.open_print_job_fn = fn; + c->printing.open_print_job_fn = fn; } smbc_list_print_jobs_fn smbc_getFunctionListPrintJobs(SMBCCTX *c) { - return c->printing.list_print_jobs_fn; + return c->printing.list_print_jobs_fn; } void smbc_setFunctionListPrintJobs(SMBCCTX *c, smbc_list_print_jobs_fn fn) { - c->printing.list_print_jobs_fn = fn; + c->printing.list_print_jobs_fn = fn; } smbc_unlink_print_job_fn smbc_getFunctionUnlinkPrintJob(SMBCCTX *c) { - return c->printing.unlink_print_job_fn; + return c->printing.unlink_print_job_fn; } void smbc_setFunctionUnlinkPrintJob(SMBCCTX *c, - smbc_unlink_print_job_fn fn) + smbc_unlink_print_job_fn fn) { - c->printing.unlink_print_job_fn = fn; + c->printing.unlink_print_job_fn = fn; } diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 25020762a2..2ece2ab8ed 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -36,19 +36,19 @@ static void remove_dir(SMBCFILE *dir) { struct smbc_dir_list *d,*f; - + d = dir->dir_list; while (d) { - + f = d; d = d->next; - + SAFE_FREE(f->dirent); SAFE_FREE(f); - + } - + dir->dir_list = dir->dir_end = dir->dir_next = NULL; - + } static int @@ -61,63 +61,63 @@ add_dirent(SMBCFILE *dir, int size; int name_length = (name == NULL ? 0 : strlen(name)); int comment_len = (comment == NULL ? 0 : strlen(comment)); - + /* * Allocate space for the dirent, which must be increased by the * size of the name and the comment and 1 each for the null terminator. */ - + size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; - + dirent = (struct smbc_dirent *)SMB_MALLOC(size); - + if (!dirent) { - + dir->dir_error = ENOMEM; return -1; - + } - + ZERO_STRUCTP(dirent); - + if (dir->dir_list == NULL) { - + dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); if (!dir->dir_list) { - + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; - + } ZERO_STRUCTP(dir->dir_list); - + dir->dir_end = dir->dir_next = dir->dir_list; } else { - + dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); - + if (!dir->dir_end->next) { - + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; - + } ZERO_STRUCTP(dir->dir_end->next); - + dir->dir_end = dir->dir_end->next; } - + dir->dir_end->next = NULL; dir->dir_end->dirent = dirent; - + dirent->smbc_type = type; dirent->namelen = name_length; dirent->commentlen = comment_len; dirent->dirlen = size; - + /* * dirent->namelen + 1 includes the null (no null termination needed) * Ditto for dirent->commentlen. @@ -126,9 +126,9 @@ add_dirent(SMBCFILE *dir, strncpy(dirent->name, (name?name:""), dirent->namelen + 1); dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); - + return 0; - + } static void @@ -142,18 +142,18 @@ list_unique_wg_fn(const char *name, struct smbc_dirent *dirent; int dirent_type; int do_remove = 0; - + dirent_type = dir->dir_type; - + if (add_dirent(dir, name, comment, dirent_type) < 0) { - + /* An error occurred, what do we do? */ /* FIXME: Add some code here */ } - + /* Point to the one just added */ dirent = dir->dir_end->dirent; - + /* See if this was a duplicate */ for (dir_list = dir->dir_list; dir_list != dir->dir_end; @@ -163,7 +163,7 @@ list_unique_wg_fn(const char *name, /* Duplicate. End end of list need to be removed. */ do_remove = 1; } - + if (do_remove && dir_list->next == dir->dir_end) { /* Found the end of the list. Remove it. */ dir->dir_end = dir_list; @@ -183,7 +183,7 @@ list_fn(const char *name, { SMBCFILE *dir = (SMBCFILE *)state; int dirent_type; - + /* * We need to process the type a little ... * @@ -195,27 +195,27 @@ list_fn(const char *name, * administrative shares: * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 */ - + if (dir->dir_type == SMBC_FILE_SHARE) { switch (type) { case 0 | 0x80000000: case 0: dirent_type = SMBC_FILE_SHARE; break; - + case 1: dirent_type = SMBC_PRINTER_SHARE; break; - + case 2: dirent_type = SMBC_COMMS_SHARE; break; - + case 3 | 0x80000000: case 3: dirent_type = SMBC_IPC_SHARE; break; - + default: dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ break; @@ -224,12 +224,12 @@ list_fn(const char *name, else { dirent_type = dir->dir_type; } - + if (add_dirent(dir, name, comment, dirent_type) < 0) { - + /* An error occurred, what do we do? */ /* FIXME: Add some code here */ - + } } @@ -239,16 +239,16 @@ dir_list_fn(const char *mnt, const char *mask, void *state) { - + if (add_dirent((SMBCFILE *)state, finfo->name, "", (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { - + /* Handle an error ... */ - + /* FIXME: Add some code ... */ - + } - + } static int @@ -270,14 +270,14 @@ net_share_enum_rpc(struct cli_state *cli, fstring comment = ""; struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; - + /* Open the server service pipe */ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); if (!pipe_hnd) { DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); return -1; } - + /* Issue the NetShareEnum RPC call and retrieve the response */ init_enum_hnd(&enum_hnd, 0); result = rpccli_srvsvc_net_share_enum(pipe_hnd, @@ -286,35 +286,35 @@ net_share_enum_rpc(struct cli_state *cli, &ctr, preferred_len, &enum_hnd); - + /* Was it successful? */ if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { /* Nope. Go clean up. */ goto done; } - + /* For each returned entry... */ for (i = 0; i < ctr.num_entries; i++) { - + /* pull out the share name */ rpcstr_pull_unistr2_fstring( name, &ctr.share.info1[i].info_1_str.uni_netname); - + /* pull out the share's comment */ rpcstr_pull_unistr2_fstring( comment, &ctr.share.info1[i].info_1_str.uni_remark); - + /* Get the type value */ type = ctr.share.info1[i].info_1.type; - + /* Add this share to the list */ (*fn)(name, type, comment, state); } - + done: /* Close the server service pipe */ cli_rpc_pipe_close(pipe_hnd); - + /* Tell 'em if it worked */ return W_ERROR_IS_OK(result) ? 0 : -1; } @@ -332,10 +332,10 @@ SMBC_check_options(char *server, DEBUG(4, ("SMBC_check_options(): server='%s' share='%s' " "path='%s' options='%s'\n", server, share, path, options)); - + /* No options at all is always ok */ if (! *options) return 0; - + /* Currently, we don't support any options. */ return -1; } @@ -346,7 +346,11 @@ SMBC_opendir_ctx(SMBCCTX *context, const char *fname) { int saved_errno; - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *options = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *options = NULL; char *workgroup = NULL; char *path = NULL; uint16 mode; @@ -355,42 +359,42 @@ SMBC_opendir_ctx(SMBCCTX *context, SMBCFILE *dir = NULL; struct sockaddr_storage rem_ss; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { DEBUG(4, ("no valid context\n")); errno = EINVAL + 8192; TALLOC_FREE(frame); return NULL; - + } - + if (!fname) { DEBUG(4, ("no valid fname\n")); errno = EINVAL + 8193; TALLOC_FREE(frame); return NULL; } - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - &options)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + &options)) { DEBUG(4, ("no valid path\n")); errno = EINVAL + 8194; TALLOC_FREE(frame); return NULL; } - + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' " "path='%s' options='%s'\n", fname, server, share, path, options)); - + /* Ensure the options are valid */ if (SMBC_check_options(server, share, path, options)) { DEBUG(4, ("unacceptable options (%s)\n", options)); @@ -398,7 +402,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -407,35 +411,35 @@ SMBC_opendir_ctx(SMBCCTX *context, return NULL; } } - + dir = SMB_MALLOC_P(SMBCFILE); - + if (!dir) { errno = ENOMEM; TALLOC_FREE(frame); return NULL; } - + ZERO_STRUCTP(dir); - + dir->cli_fd = 0; dir->fname = SMB_STRDUP(fname); dir->srv = NULL; dir->offset = 0; dir->file = False; dir->dir_list = dir->dir_next = dir->dir_end = NULL; - + if (server[0] == (char)0) { - + int i; int count; int max_lmb_count; struct ip_service *ip_list; struct ip_service server_addr; struct user_auth_info u_info; - + if (share[0] != (char)0 || path[0] != (char)0) { - + errno = EINVAL + 8196; if (dir) { SAFE_FREE(dir->fname); @@ -444,12 +448,12 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + /* Determine how many local master browsers to query */ - max_lmb_count = (context->internal->browse_max_lmb_count == 0 + max_lmb_count = (context->options.browse_max_lmb_count == 0 ? INT_MAX - : context->internal->browse_max_lmb_count); - + : context->options.browse_max_lmb_count); + memset(&u_info, '\0', sizeof(u_info)); u_info.username = talloc_strdup(frame,user); u_info.password = talloc_strdup(frame,password); @@ -461,7 +465,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + /* * We have server and share and path empty but options * requesting that we scan all master browsers for their list @@ -470,16 +474,16 @@ SMBC_opendir_ctx(SMBCCTX *context, * doesn't work, then try our other methods which return only * a single master browser. */ - + ip_list = NULL; if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, - &count))) + &count))) { - + SAFE_FREE(ip_list); - + if (!find_master_ip(workgroup, &server_addr.ss)) { - + if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -488,7 +492,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + ip_list = (struct ip_service *)memdup( &server_addr, sizeof(server_addr)); if (ip_list == NULL) { @@ -498,17 +502,17 @@ SMBC_opendir_ctx(SMBCCTX *context, } count = 1; } - + for (i = 0; i < count && i < max_lmb_count; i++) { char addr[INET6_ADDRSTRLEN]; char *wg_ptr = NULL; struct cli_state *cli = NULL; - + print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), addr)); - + cli = get_ipc_connect_master_ip(talloc_tos(), &ip_list[i], &u_info, @@ -518,39 +522,39 @@ SMBC_opendir_ctx(SMBCCTX *context, if (!cli) { continue; } - + workgroup = talloc_strdup(frame, wg_ptr); server = talloc_strdup(frame, cli->desthost); - + cli_shutdown(cli); - + if (!workgroup || !server) { errno = ENOMEM; TALLOC_FREE(frame); return NULL; } - + DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); - + /* * For each returned master browser IP address, get a * connection to IPC$ on the server if we do not * already have one, and determine the * workgroups/domains that it knows about. */ - + srv = SMBC_server(frame, context, True, server, "IPC$", &workgroup, &user, &password); if (!srv) { continue; } - + dir->srv = srv; dir->dir_type = SMBC_WORKGROUP; - + /* Now, list the stuff ... */ - + if (!cli_NetServerEnum(srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, @@ -559,7 +563,7 @@ SMBC_opendir_ctx(SMBCCTX *context, continue; } } - + SAFE_FREE(ip_list); } else { /* @@ -568,7 +572,7 @@ SMBC_opendir_ctx(SMBCCTX *context, */ if (*share == '\0') { if (*path != '\0') { - + /* Should not have empty share with path */ errno = EINVAL + 8197; if (dir) { @@ -577,9 +581,9 @@ SMBC_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } - + /* * We don't know if is really a server name * or is a workgroup/domain name. If we already have @@ -588,15 +592,16 @@ SMBC_opendir_ctx(SMBCCTX *context, * <1B>, or <20> translates. We check * to see if is an IP address first. */ - + /* * See if we have an existing server. Do not * establish a connection if one does not already * exist. */ - srv = SMBC_server(frame, context, False, server, "IPC$", + srv = SMBC_server(frame, context, False, + server, "IPC$", &workgroup, &user, &password); - + /* * If no existing server and not an IP addr, look for * LMB or DMB @@ -605,20 +610,20 @@ SMBC_opendir_ctx(SMBCCTX *context, !is_ipaddress(server) && (resolve_name(server, &rem_ss, 0x1d) || /* LMB */ resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */ - + fstring buserver; - + dir->dir_type = SMBC_SERVER; - + /* * Get the backup list ... */ if (!name_status_find(server, 0, 0, &rem_ss, buserver)) { - - DEBUG(0, ("Could not get name of " - "local/domain master browser " - "for server %s\n", server)); + + DEBUG(0,("Could not get name of " + "local/domain master browser " + "for server %s\n", server)); if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -626,16 +631,17 @@ SMBC_opendir_ctx(SMBCCTX *context, errno = EPERM; TALLOC_FREE(frame); return NULL; - + } - + /* * Get a connection to IPC$ on the server if * we do not already have one */ srv = SMBC_server(frame, context, True, buserver, "IPC$", - &workgroup, &user, &password); + &workgroup, + &user, &password); if (!srv) { DEBUG(0, ("got no contact to IPC$\n")); if (dir) { @@ -644,16 +650,16 @@ SMBC_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } - + dir->srv = srv; - + /* Now, list the servers ... */ if (!cli_NetServerEnum(srv->cli, server, 0x0000FFFE, list_fn, (void *)dir)) { - + if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -663,15 +669,17 @@ SMBC_opendir_ctx(SMBCCTX *context, } } else if (srv || (resolve_name(server, &rem_ss, 0x20))) { - - /* If we hadn't found the server, get one now */ + + /* + * If we hadn't found the server, get one now + */ if (!srv) { srv = SMBC_server(frame, context, True, server, "IPC$", &workgroup, &user, &password); } - + if (!srv) { if (dir) { SAFE_FREE(dir->fname); @@ -679,14 +687,14 @@ SMBC_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } - + dir->dir_type = SMBC_FILE_SHARE; dir->srv = srv; - + /* List the shares ... */ - + if (net_share_enum_rpc( srv->cli, list_fn, @@ -695,7 +703,7 @@ SMBC_opendir_ctx(SMBCCTX *context, srv->cli, list_fn, (void *)dir) < 0) { - + errno = cli_errno(srv->cli); if (dir) { SAFE_FREE(dir->fname); @@ -703,7 +711,7 @@ SMBC_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } } else { /* Neither the workgroup nor server exists */ @@ -715,7 +723,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + } else { /* @@ -724,13 +732,13 @@ SMBC_opendir_ctx(SMBCCTX *context, */ char *targetpath; struct cli_state *targetcli; - + /* We connect to the server and list the directory */ dir->dir_type = SMBC_FILE_SHARE; - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { if (dir) { SAFE_FREE(dir->fname); @@ -739,11 +747,11 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + dir->srv = srv; - + /* Now, list the files ... */ - + p = path + strlen(path); path = talloc_asprintf_append(path, "\\*"); if (!path) { @@ -754,7 +762,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); @@ -765,47 +773,48 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, (void *)dir) < 0) { - + if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); } saved_errno = SMBC_errno(context, targetcli); - + if (saved_errno == EINVAL) { - /* - * See if they asked to opendir something - * other than a directory. If so, the - * converted error value we got would have - * been EINVAL rather than ENOTDIR. - */ - *p = '\0'; /* restore original path */ - - if (SMBC_getatr(context, srv, path, - &mode, NULL, - NULL, NULL, NULL, NULL, - NULL) && - ! IS_DOS_DIR(mode)) { - - /* It is. Correct the error value */ - saved_errno = ENOTDIR; - } + /* + * See if they asked to opendir + * something other than a directory. + * If so, the converted error value we + * got would have been EINVAL rather + * than ENOTDIR. + */ + *p = '\0'; /* restore original path */ + + if (SMBC_getatr(context, srv, path, + &mode, NULL, + NULL, NULL, NULL, NULL, + NULL) && + ! IS_DOS_DIR(mode)) { + + /* It is. Correct the error value */ + saved_errno = ENOTDIR; + } } - + /* * If there was an error and the server is no * good any more... */ if (cli_is_error(targetcli) && (context->server.check_server_fn)(context, srv)) { - + /* ... then remove it. */ if ((context->server.remove_unused_server_fn)(context, - srv)) { + srv)) { /* * We could not remove the * server completely, remove @@ -817,19 +826,19 @@ SMBC_opendir_ctx(SMBCCTX *context, (context->cache.remove_cached_server_fn)(context, srv); } } - + errno = saved_errno; TALLOC_FREE(frame); return NULL; } } - + } - + DLIST_ADD(context->internal->files, dir); TALLOC_FREE(frame); return dir; - + } /* @@ -841,32 +850,32 @@ SMBC_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + remove_dir(dir); /* Clean it up */ - + DLIST_REMOVE(context->internal->files, dir); - + if (dir) { - + SAFE_FREE(dir->fname); SAFE_FREE(dir); /* Free the space too */ } - + TALLOC_FREE(frame); return 0; - + } static void @@ -875,29 +884,29 @@ smbc_readdir_internal(SMBCCTX * context, struct smbc_dirent *src, int max_namebuf_len) { - if (context->internal->urlencode_readdir_entries) { - + if (context->options.urlencode_readdir_entries) { + /* url-encode the name. get back remaining buffer space */ max_namebuf_len = SMBC_urlencode(dest->name, src->name, max_namebuf_len); - + /* We now know the name length */ dest->namelen = strlen(dest->name); - + /* Save the pointer to the beginning of the comment */ dest->comment = dest->name + dest->namelen + 1; - + /* Copy the comment */ strncpy(dest->comment, src->comment, max_namebuf_len - 1); dest->comment[max_namebuf_len - 1] = '\0'; - + /* Save other fields */ dest->smbc_type = src->smbc_type; dest->commentlen = strlen(dest->comment); dest->dirlen = ((dest->comment + dest->commentlen + 1) - (char *) dest); } else { - + /* No encoding. Just copy the entry as is. */ memcpy(dest, src, src->dirlen); dest->comment = (char *)(&dest->name + src->namelen + 1); @@ -916,58 +925,58 @@ SMBC_readdir_ctx(SMBCCTX *context, int maxlen; struct smbc_dirent *dirp, *dirent; TALLOC_CTX *frame = talloc_stackframe(); - + /* Check that all is ok first ... */ - + if (!context || !context->internal->initialized) { - + errno = EINVAL; DEBUG(0, ("Invalid context in SMBC_readdir_ctx()\n")); TALLOC_FREE(frame); return NULL; - + } - + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { - + errno = EBADF; DEBUG(0, ("Invalid dir in SMBC_readdir_ctx()\n")); TALLOC_FREE(frame); return NULL; - + } - + if (dir->file != False) { /* FIXME, should be dir, perhaps */ - + errno = ENOTDIR; DEBUG(0, ("Found file vs directory in SMBC_readdir_ctx()\n")); TALLOC_FREE(frame); return NULL; - + } - + if (!dir->dir_next) { TALLOC_FREE(frame); return NULL; } - + dirent = dir->dir_next->dirent; if (!dirent) { - + errno = ENOENT; TALLOC_FREE(frame); return NULL; - + } - + dirp = (struct smbc_dirent *)context->internal->dirent; maxlen = (sizeof(context->internal->dirent) - sizeof(struct smbc_dirent)); - + smbc_readdir_internal(context, dirp, dirent, maxlen); - + dir->dir_next = dir->dir_next->next; - + TALLOC_FREE(frame); return dirp; } @@ -988,98 +997,99 @@ SMBC_getdents_ctx(SMBCCTX *context, char *ndir = (char *)dirp; struct smbc_dir_list *dirlist; TALLOC_CTX *frame = talloc_stackframe(); - + /* Check that all is ok first ... */ - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { - + errno = EBADF; TALLOC_FREE(frame); return -1; - + } - + if (dir->file != False) { /* FIXME, should be dir, perhaps */ - + errno = ENOTDIR; TALLOC_FREE(frame); return -1; - + } - + /* * Now, retrieve the number of entries that will fit in what was passed * We have to figure out if the info is in the list, or we need to * send a request to the server to get the info. */ - + while ((dirlist = dir->dir_next)) { struct smbc_dirent *dirent; - + if (!dirlist->dirent) { - + errno = ENOENT; /* Bad error */ TALLOC_FREE(frame); return -1; - + } - + /* Do urlencoding of next entry, if so selected */ dirent = (struct smbc_dirent *)context->internal->dirent; maxlen = (sizeof(context->internal->dirent) - sizeof(struct smbc_dirent)); - smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen); - + smbc_readdir_internal(context, dirent, + dirlist->dirent, maxlen); + reqd = dirent->dirlen; - + if (rem < reqd) { - + if (rem < count) { /* We managed to copy something */ - + errno = 0; TALLOC_FREE(frame); return count - rem; - + } else { /* Nothing copied ... */ - + errno = EINVAL; /* Not enough space ... */ TALLOC_FREE(frame); return -1; - + } - + } - + memcpy(ndir, dirent, reqd); /* Copy the data in ... */ - + ((struct smbc_dirent *)ndir)->comment = (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1); - + ndir += reqd; - + rem -= reqd; - + dir->dir_next = dirlist = dirlist -> next; } - + TALLOC_FREE(frame); - + if (rem == count) return 0; else return count - rem; - + } /* @@ -1101,36 +1111,36 @@ SMBC_mkdir_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -1139,37 +1149,37 @@ SMBC_mkdir_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { - + TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ - + } - + /*d_printf(">>>mkdir: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; } /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ - + if (!cli_mkdir(targetcli, targetpath)) { - + errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - + } - + TALLOC_FREE(frame); return 0; - + } /* @@ -1208,36 +1218,36 @@ SMBC_rmdir_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -1246,38 +1256,38 @@ SMBC_rmdir_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { - + TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ - + } - + /*d_printf(">>>rmdir: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; } /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ - - + + if (!cli_rmdir(targetcli, targetpath)) { - + errno = SMBC_errno(context, targetcli); - + if (errno == EACCES) { /* Check if the dir empty or not */ - + /* Local storage to avoid buffer overflows */ char *lpath; - + smbc_rmdir_dirempty = True; /* Make this so ... */ - + lpath = talloc_asprintf(frame, "%s\\*", targetpath); if (!lpath) { @@ -1285,34 +1295,34 @@ SMBC_rmdir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (cli_list(targetcli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn, NULL) < 0) { - + /* Fix errno to ignore latest error ... */ DEBUG(5, ("smbc_rmdir: " "cli_list returned an error: %d\n", SMBC_errno(context, targetcli))); errno = EACCES; - + } - + if (smbc_rmdir_dirempty) errno = EACCES; else errno = ENOTEMPTY; - + } - + TALLOC_FREE(frame); return -1; - + } - + TALLOC_FREE(frame); return 0; - + } /* @@ -1324,38 +1334,38 @@ SMBC_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { - + errno = EBADF; TALLOC_FREE(frame); return -1; - + } - + if (dir->file != False) { /* FIXME, should be dir, perhaps */ - + errno = ENOTDIR; TALLOC_FREE(frame); return -1; - + } - + /* See if we're already at the end. */ if (dir->dir_next == NULL) { /* We are. */ TALLOC_FREE(frame); return -1; } - + /* * We return the pointer here as the offset */ @@ -1369,28 +1379,28 @@ SMBC_telldir_ctx(SMBCCTX *context, static struct smbc_dir_list * check_dir_ent(struct smbc_dir_list *list, - struct smbc_dirent *dirent) + struct smbc_dirent *dirent) { - + /* Run down the list looking for what we want */ - + if (dirent) { - + struct smbc_dir_list *tmp = list; - + while (tmp) { - + if (tmp->dirent == dirent) return tmp; - + tmp = tmp->next; - + } - + } - + return NULL; /* Not found, or an error */ - + } @@ -1407,50 +1417,50 @@ SMBC_lseekdir_ctx(SMBCCTX *context, struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (dir->file != False) { /* FIXME, should be dir, perhaps */ - + errno = ENOTDIR; TALLOC_FREE(frame); return -1; - + } - + /* Now, check what we were passed and see if it is OK ... */ - + if (dirent == NULL) { /* Seek to the begining of the list */ - + dir->dir_next = dir->dir_list; TALLOC_FREE(frame); return 0; - + } - + if (offset == -1) { /* Seek to the end of the list */ dir->dir_next = NULL; TALLOC_FREE(frame); return 0; } - + /* Now, run down the list and make sure that the entry is OK */ /* This may need to be changed if we change the format of the list */ - + if ((list_ent = check_dir_ent(dir->dir_list, dirent)) == NULL) { errno = EINVAL; /* Bad entry */ TALLOC_FREE(frame); return -1; } - + dir->dir_next = list_ent; - + TALLOC_FREE(frame); return 0; } @@ -1464,13 +1474,13 @@ SMBC_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) { - + if (!context || !context->internal->initialized) { - + errno = EINVAL; return -1; } - + /* No code yet ... */ return 0; } @@ -1489,37 +1499,37 @@ SMBC_chmod_ctx(SMBCCTX *context, char *path = NULL; uint16 mode; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -1528,28 +1538,28 @@ SMBC_chmod_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + mode = 0; - + if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - + if (!cli_setatr(srv->cli, path, mode, 0)) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } - + TALLOC_FREE(frame); return 0; } @@ -1569,63 +1579,63 @@ SMBC_utimes_ctx(SMBCCTX *context, time_t access_time; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (tbuf == NULL) { access_time = write_time = time(NULL); } else { access_time = tbuf[0].tv_sec; write_time = tbuf[1].tv_sec; } - + if (DEBUGLVL(4)) { char *p; char atimebuf[32]; char mtimebuf[32]; - + strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1); atimebuf[sizeof(atimebuf) - 1] = '\0'; if ((p = strchr(atimebuf, '\n')) != NULL) { *p = '\0'; } - + strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1); mtimebuf[sizeof(mtimebuf) - 1] = '\0'; if ((p = strchr(mtimebuf, '\n')) != NULL) { *p = '\0'; } - + dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n", fname, atimebuf, mtimebuf); } - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -1634,21 +1644,21 @@ SMBC_utimes_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (!SMBC_setatr(context, srv, path, 0, access_time, write_time, 0, 0)) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_setatr */ } - + TALLOC_FREE(frame); return 0; } @@ -1661,43 +1671,47 @@ int SMBC_unlink_ctx(SMBCCTX *context, const char *fname) { - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; char *path = NULL; char *targetpath = NULL; struct cli_state *targetcli = NULL; SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - + } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -1706,31 +1720,31 @@ SMBC_unlink_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* SMBC_server sets errno */ - + } - + /*d_printf(">>>unlink: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", srv->cli, path, - &targetcli, &targetpath)) { + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); TALLOC_FREE(frame); return -1; } /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ - + if (!cli_unlink(targetcli, targetpath)) { - + errno = SMBC_errno(context, targetcli); - + if (errno == EACCES) { /* Check if the file is a directory */ - + int saverr = errno; SMB_OFF_T size = 0; uint16 mode = 0; @@ -1738,39 +1752,39 @@ SMBC_unlink_ctx(SMBCCTX *context, struct timespec access_time_ts; struct timespec change_time_ts; SMB_INO_T ino = 0; - + if (!SMBC_getatr(context, srv, path, &mode, &size, NULL, &access_time_ts, &write_time_ts, &change_time_ts, &ino)) { - + /* Hmmm, bad error ... What? */ - + errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - + } else { - + if (IS_DOS_DIR(mode)) errno = EISDIR; else errno = saverr; /* Restore this */ - + } } - + TALLOC_FREE(frame); return -1; - + } - + TALLOC_FREE(frame); return 0; /* Success ... */ - + } /* @@ -1800,39 +1814,39 @@ SMBC_rename_ctx(SMBCCTX *ocontext, struct cli_state *targetcli2 = NULL; SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!ocontext || !ncontext || !ocontext->internal->initialized || !ncontext->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!oname || !nname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - + if (SMBC_parse_path(frame, - ocontext, - oname, - &workgroup, - &server1, - &share1, - &path1, - &user1, - &password1, - NULL)) { + ocontext, + oname, + &workgroup, + &server1, + &share1, + &path1, + &user1, + &password1, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user1 || user1[0] == (char)0) { user1 = talloc_strdup(frame, ocontext->config.user); if (!user1) { @@ -1841,22 +1855,22 @@ SMBC_rename_ctx(SMBCCTX *ocontext, return -1; } } - + if (SMBC_parse_path(frame, - ncontext, - nname, - NULL, - &server2, - &share2, - &path2, - &user2, - &password2, - NULL)) { + ncontext, + nname, + NULL, + &server2, + &share2, + &path2, + &user2, + &password2, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user2 || user2[0] == (char)0) { user2 = talloc_strdup(frame, ncontext->config.user); if (!user2) { @@ -1865,7 +1879,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, return -1; } } - + if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { /* Can't rename across file systems, or users?? */ @@ -1873,18 +1887,18 @@ SMBC_rename_ctx(SMBCCTX *ocontext, TALLOC_FREE(frame); return -1; } - + srv = SMBC_server(frame, ocontext, True, server1, share1, &workgroup, &user1, &password1); if (!srv) { TALLOC_FREE(frame); return -1; - + } - + /*d_printf(">>>rename: resolving %s\n", path1);*/ if (!cli_resolve_path(frame, "", srv->cli, path1, - &targetcli1, &targetpath1)) { + &targetcli1, &targetpath1)) { d_printf("Could not resolve %s\n", path1); TALLOC_FREE(frame); return -1; @@ -1892,13 +1906,13 @@ SMBC_rename_ctx(SMBCCTX *ocontext, /*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/ /*d_printf(">>>rename: resolving %s\n", path2);*/ if (!cli_resolve_path(frame, "", srv->cli, path2, - &targetcli2, &targetpath2)) { + &targetcli2, &targetpath2)) { d_printf("Could not resolve %s\n", path2); TALLOC_FREE(frame); return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ - + if (strcmp(targetcli1->desthost, targetcli2->desthost) || strcmp(targetcli1->share, targetcli2->share)) { @@ -1907,21 +1921,21 @@ SMBC_rename_ctx(SMBCCTX *ocontext, TALLOC_FREE(frame); return -1; } - + if (!cli_rename(targetcli1, targetpath1, targetpath2)) { int eno = SMBC_errno(ocontext, targetcli1); - + if (eno != EEXIST || !cli_unlink(targetcli1, targetpath2) || !cli_rename(targetcli1, targetpath1, targetpath2)) { - + errno = eno; TALLOC_FREE(frame); return -1; - + } } - + TALLOC_FREE(frame); return 0; /* Success */ } diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 62b990ed00..73c9b96978 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -37,7 +37,11 @@ SMBC_open_ctx(SMBCCTX *context, int flags, mode_t mode) { - char *server = NULL, *share = NULL, *user = NULL, *password = NULL, *workgroup = NULL; + char *server = NULL; + char *share = NULL; + char *user = NULL; + char *password = NULL; + char *workgroup = NULL; char *path = NULL; char *targetpath = NULL; struct cli_state *targetcli = NULL; @@ -45,38 +49,38 @@ SMBC_open_ctx(SMBCCTX *context, SMBCFILE *file = NULL; int fd; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return NULL; - + } - + if (!fname) { - + errno = EINVAL; TALLOC_FREE(frame); return NULL; - + } - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return NULL; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -85,62 +89,63 @@ SMBC_open_ctx(SMBCCTX *context, return NULL; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { if (errno == EPERM) errno = EACCES; TALLOC_FREE(frame); return NULL; /* SMBC_server sets errno */ } - + /* Hmmm, the test for a directory is suspect here ... FIXME */ - + if (strlen(path) > 0 && path[strlen(path) - 1] == '\\') { fd = -1; } else { file = SMB_MALLOC_P(SMBCFILE); - + if (!file) { errno = ENOMEM; TALLOC_FREE(frame); return NULL; } - + ZERO_STRUCTP(file); - + /*d_printf(">>>open: resolving %s\n", path);*/ - if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { + if (!cli_resolve_path(frame, "", srv->cli, path, + &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); SAFE_FREE(file); TALLOC_FREE(frame); return NULL; } /*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/ - + if ((fd = cli_open(targetcli, targetpath, flags, context->internal->share_mode)) < 0) { - + /* Handle the error ... */ - + SAFE_FREE(file); errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return NULL; - + } - + /* Fill in file struct */ - + file->cli_fd = fd; file->fname = SMB_STRDUP(fname); file->srv = srv; file->offset = 0; file->file = True; - + DLIST_ADD(context->internal->files, file); - + /* * If the file was opened in O_APPEND mode, all write * operations should be appended to the file. To do that, @@ -171,51 +176,50 @@ SMBC_open_ctx(SMBCCTX *context, return NULL; } } - + TALLOC_FREE(frame); return file; - + } - + /* Check if opendir needed ... */ - + if (fd == -1) { int eno = 0; - + eno = SMBC_errno(context, srv->cli); file = (context->posix_emu.opendir_fn)(context, fname); if (!file) errno = eno; TALLOC_FREE(frame); return file; - + } - + errno = EINVAL; /* FIXME, correct errno ? */ TALLOC_FREE(frame); return NULL; - + } /* * Routine to create a file */ -static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC; /* FIXME: Do we need this */ - SMBCFILE * SMBC_creat_ctx(SMBCCTX *context, const char *path, mode_t mode) { - + if (!context || !context->internal->initialized) { - + errno = EINVAL; return NULL; - + } - - return SMBC_open_ctx(context, path, creat_bits, mode); + + return SMBC_open_ctx(context, path, + O_WRONLY | O_CREAT | O_TRUNC, mode); } /* @@ -234,7 +238,7 @@ SMBC_read_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + /* * offset: * @@ -245,51 +249,51 @@ SMBC_read_ctx(SMBCCTX *context, * retrieving data at an offset greater than 4GB. */ off_t offset; - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + DEBUG(4, ("smbc_read(%p, %d)\n", file, (int)count)); - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; - + } - + offset = file->offset; - + /* Check that the buffer exists ... */ - + if (buf == NULL) { errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + /*d_printf(">>>read: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>read: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -298,24 +302,24 @@ SMBC_read_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - + ret = cli_read(targetcli, file->cli_fd, (char *)buf, offset, count); - + if (ret < 0) { - + errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - + } - + file->offset += ret; - + DEBUG(4, (" --> %d\n", ret)); - + TALLOC_FREE(frame); return ret; /* Success, ret bytes of data ... */ - + } /* @@ -335,50 +339,50 @@ SMBC_write_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + /* First check all pointers before dereferencing them */ - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + /* Check that the buffer exists ... */ - + if (buf == NULL) { errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + offset = file->offset; /* See "offset" comment in SMBC_read_ctx() */ - + /*d_printf(">>>write: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>write: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -387,18 +391,19 @@ SMBC_write_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>write: resolved path as %s\n", targetpath);*/ - - ret = cli_write(targetcli, file->cli_fd, 0, (char *)buf, offset, count); - + + ret = cli_write(targetcli, file->cli_fd, + 0, (char *)buf, offset, count); + if (ret <= 0) { errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - + } - + file->offset += ret; - + TALLOC_FREE(frame); return ret; /* Success, 0 bytes of data ... */ } @@ -417,42 +422,42 @@ SMBC_close_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + /* IS a dir ... */ if (!file->file) { TALLOC_FREE(frame); return (context->posix_emu.closedir_fn)(context, file); } - + /*d_printf(">>>close: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>close: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -461,9 +466,9 @@ SMBC_close_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>close: resolved path as %s\n", targetpath);*/ - + if (!cli_close(targetcli, file->cli_fd)) { - + DEBUG(3, ("cli_close failed on %s. purging server.\n", file->fname)); /* Deallocate slot and remove the server @@ -476,14 +481,14 @@ SMBC_close_ctx(SMBCCTX *context, (context->server.remove_unused_server_fn)(context, srv); TALLOC_FREE(frame); return -1; - + } - + DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); TALLOC_FREE(frame); - + return 0; } @@ -508,14 +513,14 @@ SMBC_getatr(SMBCCTX * context, struct cli_state *targetcli = NULL; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /* path fixup for . and .. */ if (strequal(path, ".") || strequal(path, "..")) { fixedpath = talloc_strdup(frame, "\\"); @@ -535,14 +540,14 @@ SMBC_getatr(SMBCCTX * context, trim_string(fixedpath, NULL, "\\."); } DEBUG(4,("SMBC_getatr: sending qpathinfo\n")); - + if (!cli_resolve_path(frame, "", srv->cli, fixedpath, - &targetcli, &targetpath)) { + &targetcli, &targetpath)) { d_printf("Couldn't resolve %s\n", path); TALLOC_FREE(frame); return False; } - + if (!srv->no_pathinfo2 && cli_qpathinfo2(targetcli, targetpath, create_time_ts, @@ -553,45 +558,45 @@ SMBC_getatr(SMBCCTX * context, TALLOC_FREE(frame); return True; } - + /* if this is NT then don't bother with the getatr */ if (targetcli->capabilities & CAP_NT_SMBS) { errno = EPERM; TALLOC_FREE(frame); return False; } - + if (cli_getatr(targetcli, targetpath, mode, size, &write_time)) { - + struct timespec w_time_ts; - + w_time_ts = convert_time_t_to_timespec(write_time); - + if (write_time_ts != NULL) { *write_time_ts = w_time_ts; } - + if (create_time_ts != NULL) { *create_time_ts = w_time_ts; } - + if (access_time_ts != NULL) { *access_time_ts = w_time_ts; } - + if (change_time_ts != NULL) { *change_time_ts = w_time_ts; } - + srv->no_pathinfo2 = True; TALLOC_FREE(frame); return True; } - + errno = EPERM; TALLOC_FREE(frame); return False; - + } /* @@ -615,7 +620,7 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, int fd; int ret; TALLOC_CTX *frame = talloc_stackframe(); - + /* * First, try setpathinfo (if qpathinfo succeeded), for it is the * modern function for "new code" to be using, and it works given a @@ -629,7 +634,7 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, write_time, change_time, mode)) { - + /* * setpathinfo is not supported; go to plan B. * @@ -639,27 +644,27 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, * cli_setattrE() which should work on all OS versions, and * supports both times. */ - + /* Don't try {q,set}pathinfo() again, with this server */ srv->no_pathinfo = True; - + /* Open the file */ if ((fd = cli_open(srv->cli, path, O_RDWR, DENY_NONE)) < 0) { - + errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } - + /* Set the new attributes */ ret = cli_setattrE(srv->cli, fd, change_time, access_time, write_time); - + /* Close the file */ cli_close(srv->cli, fd); - + /* * Unfortunately, setattrE() doesn't have a provision for * setting the access mode (attributes). We'll have to try @@ -669,14 +674,14 @@ SMBC_setatr(SMBCCTX * context, SMBCSRV *srv, char *path, if (ret && mode != (uint16) -1) { ret = cli_setatr(srv->cli, path, mode, 0); } - + if (! ret) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return False; } } - + TALLOC_FREE(frame); return True; } @@ -697,56 +702,56 @@ SMBC_lseek_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { - + errno = EBADF; TALLOC_FREE(frame); return -1; - + } - + if (!file->file) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; /* Can't lseek a dir ... */ - + } - + switch (whence) { case SEEK_SET: file->offset = offset; break; - + case SEEK_CUR: file->offset += offset; break; - + case SEEK_END: /*d_printf(">>>lseek: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>lseek: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -755,32 +760,32 @@ SMBC_lseek_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/ - + if (!cli_qfileinfo(targetcli, file->cli_fd, NULL, &size, NULL, NULL, NULL, NULL, NULL)) { - SMB_OFF_T b_size = size; + SMB_OFF_T b_size = size; if (!cli_getattrE(targetcli, file->cli_fd, NULL, &b_size, NULL, NULL, NULL)) - { - errno = EINVAL; - TALLOC_FREE(frame); - return -1; - } else - size = b_size; + { + errno = EINVAL; + TALLOC_FREE(frame); + return -1; + } else + size = b_size; } file->offset = size + offset; break; - + default: errno = EINVAL; break; - + } - + TALLOC_FREE(frame); return file->offset; - + } @@ -802,26 +807,26 @@ SMBC_ftruncate_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + if (!file->file) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, context, @@ -837,7 +842,7 @@ SMBC_ftruncate_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>fstat: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -846,14 +851,14 @@ SMBC_ftruncate_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - + if (!cli_ftruncate(targetcli, file->cli_fd, size)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + TALLOC_FREE(frame); return 0; - + } diff --git a/source3/libsmb/libsmb_misc.c b/source3/libsmb/libsmb_misc.c index f2fd919ef6..dd7add5a61 100644 --- a/source3/libsmb/libsmb_misc.c +++ b/source3/libsmb/libsmb_misc.c @@ -50,24 +50,24 @@ SMBC_errno(SMBCCTX *context, struct cli_state *c) { int ret = cli_errno(c); - + if (cli_is_dos_error(c)) { uint8 eclass; uint32 ecode; - + cli_dos_error(c, &eclass, &ecode); DEBUG(3,("smbc_error %d %d (0x%x) -> %d\n", (int)eclass, (int)ecode, (int)ecode, ret)); } else { NTSTATUS status; - + status = cli_nt_error(c); - + DEBUG(3,("smbc errno %s -> %d\n", nt_errstr(status), ret)); } - + return ret; } diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index 6706a59ba8..c962f898e0 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -31,13 +31,13 @@ static int hex2int( unsigned int _char ) { - if ( _char >= 'A' && _char <='F') - return _char - 'A' + 10; - if ( _char >= 'a' && _char <='f') - return _char - 'a' + 10; - if ( _char >= '0' && _char <='9') - return _char - '0'; - return -1; + if ( _char >= 'A' && _char <='F') + return _char - 'A' + 10; + if ( _char >= 'a' && _char <='f') + return _char - 'a' + 10; + if ( _char >= '0' && _char <='9') + return _char - '0'; + return -1; } /* @@ -60,19 +60,19 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) int err_count = 0; size_t newlen = 1; char *p, *dest; - + if (old_length == 0) { return 0; } - + *pp_dest = NULL; for (i = 0; i < old_length; ) { unsigned char character = src[i++]; - + if (character == '%') { int a = i+1 < old_length ? hex2int(src[i]) : -1; int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - + /* Replace valid sequence */ if (a != -1 && b != -1) { /* Replace valid %xx sequence with %dd */ @@ -87,20 +87,20 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) } newlen++; } - + dest = TALLOC_ARRAY(ctx, char, newlen); if (!dest) { return err_count; } - + err_count = 0; for (p = dest, i = 0; i < old_length; ) { unsigned char character = src[i++]; - + if (character == '%') { int a = i+1 < old_length ? hex2int(src[i]) : -1; int b = i+1 < old_length ? hex2int(src[i+1]) : -1; - + /* Replace valid sequence */ if (a != -1 && b != -1) { /* Replace valid %xx sequence with %dd */ @@ -115,7 +115,7 @@ urldecode_talloc(TALLOC_CTX *ctx, char **pp_dest, const char *src) } *p++ = character; } - + *p = '\0'; *pp_dest = dest; return err_count; @@ -129,7 +129,7 @@ SMBC_urldecode(char *dest, TALLOC_CTX *frame = talloc_stackframe(); char *pdest; int ret = urldecode_talloc(frame, &pdest, src); - + if (pdest) { strlcpy(dest, pdest, max_dest_len); } @@ -151,9 +151,9 @@ SMBC_urlencode(char *dest, int max_dest_len) { char hex[] = "0123456789ABCDEF"; - + for (; *src != '\0' && max_dest_len >= 3; src++) { - + if ((*src < '0' && *src != '-' && *src != '.') || @@ -172,10 +172,10 @@ SMBC_urlencode(char *dest, max_dest_len--; } } - + *dest++ = '\0'; max_dest_len--; - + return max_dest_len; } @@ -196,9 +196,9 @@ SMBC_urlencode(char *dest, * * The method of locating the list of workgroups varies * depending upon the setting of the context variable - * context->browse_max_lmb_count. This value determines - * the maximum number of local master browsers to query - * for the list of workgroups. In order to ensure that + * context->options.browse_max_lmb_count. This value + * determines the maximum number of local master browsers to + * query for the list of workgroups. In order to ensure that * a complete list of workgroups is obtained, all master * browsers must be queried, but if there are many * workgroups, the time spent querying can begin to add up. @@ -234,75 +234,75 @@ SMBC_parse_path(TALLOC_CTX *ctx, const char *p; char *q, *r; int len; - + /* Ensure these returns are at least valid pointers. */ *pp_server = talloc_strdup(ctx, ""); *pp_share = talloc_strdup(ctx, ""); *pp_path = talloc_strdup(ctx, ""); *pp_user = talloc_strdup(ctx, ""); *pp_password = talloc_strdup(ctx, ""); - + if (!*pp_server || !*pp_share || !*pp_path || - !*pp_user || !*pp_password) { + !*pp_user || !*pp_password) { return -1; } - + /* * Assume we wont find an authentication domain to parse, so default * to the workgroup in the provided context. */ if (pp_workgroup != NULL) { *pp_workgroup = - talloc_strdup(ctx, context->config.workgroup); + talloc_strdup(ctx, context->config.workgroup); } - + if (pp_options) { *pp_options = talloc_strdup(ctx, ""); } s = talloc_strdup(ctx, fname); - + /* see if it has the right prefix */ len = strlen(smbc_prefix); if (strncmp(s,smbc_prefix,len) || (s[len] != '/' && s[len] != 0)) { return -1; /* What about no smb: ? */ } - + p = s + len; - + /* Watch the test below, we are testing to see if we should exit */ - + if (strncmp(p, "//", 2) && strncmp(p, "\\\\", 2)) { DEBUG(1, ("Invalid path (does not begin with smb://")); return -1; } - + p += 2; /* Skip the double slash */ - + /* See if any options were specified */ if ((q = strrchr(p, '?')) != NULL ) { /* There are options. Null terminate here and point to them */ *q++ = '\0'; - + DEBUG(4, ("Found options '%s'", q)); - + /* Copy the options */ if (*pp_options != NULL) { TALLOC_FREE(*pp_options); *pp_options = talloc_strdup(ctx, q); } } - + if (*p == '\0') { goto decoding; } - + if (*p == '/') { int wl = strlen(context->config.workgroup); - + if (wl > 16) { wl = 16; } - + *pp_server = talloc_strdup(ctx, context->config.workgroup); if (!*pp_server) { return -1; @@ -310,27 +310,27 @@ SMBC_parse_path(TALLOC_CTX *ctx, *pp_server[wl] = '\0'; return 0; } - + /* * ok, its for us. Now parse out the server, share etc. * * However, we want to parse out [[domain;]user[:password]@] if it * exists ... */ - + /* check that '@' occurs before '/', if '/' exists at all */ q = strchr_m(p, '@'); r = strchr_m(p, '/'); if (q && (!r || q < r)) { char *userinfo = NULL; const char *u; - + next_token_no_ltrim_talloc(ctx, &p, &userinfo, "@"); if (!userinfo) { return -1; } u = userinfo; - + if (strchr_m(u, ';')) { char *workgroup; next_token_no_ltrim_talloc(ctx, &u, &workgroup, ";"); @@ -341,7 +341,7 @@ SMBC_parse_path(TALLOC_CTX *ctx, *pp_workgroup = workgroup; } } - + if (strchr_m(u, ':')) { next_token_no_ltrim_talloc(ctx, &u, pp_user, ":"); if (!*pp_user) { @@ -358,27 +358,27 @@ SMBC_parse_path(TALLOC_CTX *ctx, } } } - + if (!next_token_talloc(ctx, &p, pp_server, "/")) { return -1; } - + if (*p == (char)0) { goto decoding; /* That's it ... */ } - + if (!next_token_talloc(ctx, &p, pp_share, "/")) { return -1; } - + /* * Prepend a leading slash if there's a file path, as required by * NetApp filers. */ if (*p != '\0') { *pp_path = talloc_asprintf(ctx, - "\\%s", - p); + "\\%s", + p); } else { *pp_path = talloc_strdup(ctx, ""); } @@ -386,15 +386,15 @@ SMBC_parse_path(TALLOC_CTX *ctx, return -1; } string_replace(*pp_path, '/', '\\'); - - decoding: - + +decoding: + (void) urldecode_talloc(ctx, pp_path, *pp_path); (void) urldecode_talloc(ctx, pp_server, *pp_server); (void) urldecode_talloc(ctx, pp_share, *pp_share); (void) urldecode_talloc(ctx, pp_user, *pp_user); (void) urldecode_talloc(ctx, pp_password, *pp_password); - + return 0; } diff --git a/source3/libsmb/libsmb_printjob.c b/source3/libsmb/libsmb_printjob.c index a03c15e024..545225cae4 100644 --- a/source3/libsmb/libsmb_printjob.c +++ b/source3/libsmb/libsmb_printjob.c @@ -41,39 +41,39 @@ SMBC_open_print_job_ctx(SMBCCTX *context, char *password = NULL; char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return NULL; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return NULL; } - + DEBUG(4, ("SMBC_open_print_job_ctx(%s)\n", fname)); - + if (SMBC_parse_path(frame, - context, - fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return NULL; } - + /* What if the path is empty, or the file exists? */ - + TALLOC_FREE(frame); return (context->posix_emu.open_fn)(context, fname, O_WRONLY, 666); } @@ -98,77 +98,79 @@ SMBC_print_file_ctx(SMBCCTX *c_file, int tot_bytes = 0; char buf[4096]; TALLOC_CTX *frame = talloc_stackframe(); - + if (!c_file || !c_file->internal->initialized || !c_print || !c_print->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (!fname && !printq) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + /* Try to open the file for reading ... */ - - if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname, O_RDONLY, 0666)) < 0) { + + if ((long)(fid1 = smbc_getFunctionOpen(c_file)(c_file, fname, + O_RDONLY, 0666)) < 0) { DEBUG(3, ("Error, fname=%s, errno=%i\n", fname, errno)); TALLOC_FREE(frame); return -1; /* smbc_open sets errno */ } - + /* Now, try to open the printer file for writing */ - - if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print, printq)) < 0) { - + + if ((long)(fid2 = smbc_getFunctionOpenPrintJob(c_print)(c_print, + printq)) < 0) { + saverr = errno; /* Save errno */ smbc_getFunctionClose(c_file)(c_file, fid1); errno = saverr; TALLOC_FREE(frame); return -1; - + } - + while ((bytes = smbc_getFunctionRead(c_file)(c_file, fid1, buf, sizeof(buf))) > 0) { - + tot_bytes += bytes; - + if ((smbc_getFunctionWrite(c_print)(c_print, fid2, buf, bytes)) < 0) { - + saverr = errno; smbc_getFunctionClose(c_file)(c_file, fid1); smbc_getFunctionClose(c_print)(c_print, fid2); errno = saverr; - + } - + } - + saverr = errno; - - smbc_getFunctionClose(c_file)(c_file, fid1); /* We have to close these anyway */ + + smbc_getFunctionClose(c_file)(c_file, fid1); smbc_getFunctionClose(c_print)(c_print, fid2); - + if (bytes < 0) { - + errno = saverr; TALLOC_FREE(frame); return -1; - + } - + TALLOC_FREE(frame); return tot_bytes; - + } /* @@ -188,37 +190,37 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context, char *workgroup = NULL; char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_list_print_jobs(%s)\n", fname)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -227,25 +229,25 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (cli_print_queue(srv->cli, (void (*)(struct print_job_info *))fn) < 0) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } - + TALLOC_FREE(frame); return 0; - + } /* @@ -266,37 +268,37 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context, char *path = NULL; int err; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_unlink_print_job(%s)\n", fname)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -305,30 +307,30 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { - + TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ - + } - + if ((err = cli_printjob_del(srv->cli, id)) != 0) { - + if (err < 0) errno = SMBC_errno(context, srv->cli); else if (err == ERRnosuchprintjob) errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + TALLOC_FREE(frame); return 0; - + } diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 70e0d57273..4f51388870 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -40,7 +40,7 @@ SMBC_check_server(SMBCCTX * context, { socklen_t size; struct sockaddr addr; - + size = sizeof(addr); return (getpeername(server->cli->fd, &addr, &size) == -1); } @@ -56,12 +56,12 @@ SMBC_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) { SMBCFILE * file; - + /* are we being fooled ? */ if (!context || !context->internal->initialized || !srv) { return 1; } - + /* Check all open files/directories for a relation with this server */ for (file = context->internal->files; file; file = file->next) { if (file->srv == srv) { @@ -72,16 +72,16 @@ SMBC_remove_unused_server(SMBCCTX * context, return 1; } } - + DLIST_REMOVE(context->internal->servers, srv); - + cli_shutdown(srv->cli); srv->cli = NULL; - + DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); - + (context->cache.remove_cached_server_fn)(context, srv); - + SAFE_FREE(srv); return 0; } @@ -101,21 +101,21 @@ SMBC_call_auth_fn(TALLOC_CTX *ctx, fstring workgroup; fstring username; fstring password; - + strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); strlcpy(username, *pp_username, sizeof(username)); strlcpy(password, *pp_password, sizeof(password)); - + (context->server.get_auth_data_fn)( server, share, workgroup, sizeof(workgroup), username, sizeof(username), password, sizeof(password)); - + TALLOC_FREE(*pp_workgroup); TALLOC_FREE(*pp_username); TALLOC_FREE(*pp_password); - + *pp_workgroup = talloc_strdup(ctx, workgroup); *pp_username = talloc_strdup(ctx, username); *pp_password = talloc_strdup(ctx, password); @@ -144,23 +144,23 @@ SMBC_find_server(TALLOC_CTX *ctx, { SMBCSRV *srv; int auth_called = 0; - - check_server_cache: - + +check_server_cache: + srv = (context->cache.get_cached_server_fn)(context, server, share, *pp_workgroup, *pp_username); - + if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] || - !*pp_password || !(*pp_password)[0])) { + !*pp_password || !(*pp_password)[0])) { SMBC_call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - + pp_workgroup, pp_username, pp_password); + if (!pp_workgroup || !pp_username || !pp_password) { return NULL; } - + /* * However, smbc_auth_fn may have picked up info relating to * an existing connection, so try for an existing connection @@ -168,9 +168,9 @@ SMBC_find_server(TALLOC_CTX *ctx, */ auth_called = 1; goto check_server_cache; - + } - + if (srv) { if ((context->server.check_server_fn)(context, srv)) { /* @@ -189,17 +189,17 @@ SMBC_find_server(TALLOC_CTX *ctx, (context->cache.remove_cached_server_fn)(context, srv); } - + /* * Maybe there are more cached connections to this * server */ goto check_server_cache; } - + return srv; } - + return NULL; } @@ -234,25 +234,25 @@ SMBC_server(TALLOC_CTX *ctx, int port_try_next; const char *username_used; NTSTATUS status; - + zero_addr(&ss); ZERO_STRUCT(c); - + if (server[0] == 0) { errno = EPERM; return NULL; } - + /* Look for a cached connection */ srv = SMBC_find_server(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - + pp_workgroup, pp_username, pp_password); + /* * If we found a connection and we're only allowed one share per * server... */ - if (srv && *share != '\0' && context->internal->one_share_per_server) { - + if (srv && *share != '\0' && context->options.one_share_per_server) { + /* * ... then if there's no current connection to the share, * connect to it. SMBC_find_server(), or rather the function @@ -264,8 +264,10 @@ SMBC_server(TALLOC_CTX *ctx, if (srv->cli->cnum == (uint16) -1) { /* Ensure we have accurate auth info */ SMBC_call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); - + pp_workgroup, + pp_username, + pp_password); + if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; cli_shutdown(srv->cli); @@ -274,17 +276,17 @@ SMBC_server(TALLOC_CTX *ctx, srv); return NULL; } - + /* * We don't need to renegotiate encryption * here as the encryption context is not per * tid. */ - + if (!cli_send_tconX(srv->cli, share, "?????", - *pp_password, - strlen(*pp_password)+1)) { - + *pp_password, + strlen(*pp_password)+1)) { + errno = SMBC_errno(context, srv->cli); cli_shutdown(srv->cli); srv->cli = NULL; @@ -292,7 +294,7 @@ SMBC_server(TALLOC_CTX *ctx, srv); srv = NULL; } - + /* * Regenerate the dev value since it's based on both * server and share @@ -303,51 +305,51 @@ SMBC_server(TALLOC_CTX *ctx, } } } - + /* If we have a connection... */ if (srv) { - + /* ... then we're done here. Give 'em what they came for. */ return srv; } - + /* If we're not asked to connect when a connection doesn't exist... */ if (! connect_if_not_found) { /* ... then we're done here. */ return NULL; } - + if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; return NULL; } - + make_nmb_name(&calling, context->config.netbios_name, 0x0); make_nmb_name(&called , server, 0x20); - + DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server)); - + DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); - - again: - + +again: + zero_addr(&ss); - + /* have to open a new connection */ if ((c = cli_initialise()) == NULL) { errno = ENOMEM; return NULL; } - + if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) { c->use_kerberos = True; } if (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { c->fallback_after_kerberos = True; } - + c->timeout = context->config.timeout; - + /* * Force use of port 139 for first try if share is $IPC, empty, or * null, so browse lists can work @@ -359,15 +361,15 @@ SMBC_server(TALLOC_CTX *ctx, port_try_first = 445; port_try_next = 139; } - + c->port = port_try_first; - + status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { - + /* First connection attempt failed. Try alternate port. */ c->port = port_try_next; - + status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { cli_shutdown(c); @@ -375,33 +377,36 @@ SMBC_server(TALLOC_CTX *ctx, return NULL; } } - + if (!cli_session_request(c, &calling, &called)) { cli_shutdown(c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } else { /* Try one more time, but ensure we don't loop */ - + /* Only try this if server is an IP address ... */ - + if (is_ipaddress(server) && !tried_reverse) { fstring remote_name; struct sockaddr_storage rem_ss; - + if (!interpret_string_addr(&rem_ss, server, - NI_NUMERICHOST)) { + NI_NUMERICHOST)) { DEBUG(4, ("Could not convert IP address " - "%s to struct sockaddr_storage\n", - server)); + "%s to struct sockaddr_storage\n", + server)); errno = ETIMEDOUT; return NULL; } - + tried_reverse++; /* Yuck */ - - if (name_status_find("*", 0, 0, &rem_ss, remote_name)) { - make_nmb_name(&called, remote_name, 0x20); + + if (name_status_find("*", 0, 0, + &rem_ss, remote_name)) { + make_nmb_name(&called, + remote_name, + 0x20); goto again; } } @@ -409,64 +414,66 @@ SMBC_server(TALLOC_CTX *ctx, errno = ETIMEDOUT; return NULL; } - + DEBUG(4,(" session request ok\n")); - + if (!cli_negprot(c)) { cli_shutdown(c); errno = ETIMEDOUT; return NULL; } - + username_used = *pp_username; - + if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, - *pp_password, strlen(*pp_password), - *pp_password, strlen(*pp_password), + *pp_password, + strlen(*pp_password), + *pp_password, + strlen(*pp_password), *pp_workgroup))) { - + /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; - + if ((context->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || !NT_STATUS_IS_OK(cli_session_setup(c, username_used, *pp_password, 1, *pp_password, 0, *pp_workgroup))) { - + cli_shutdown(c); errno = EPERM; return NULL; } } - + DEBUG(4,(" session setup ok\n")); - + if (!cli_send_tconX(c, share, "?????", *pp_password, strlen(*pp_password)+1)) { errno = SMBC_errno(context, c); cli_shutdown(c); return NULL; } - + DEBUG(4,(" tconx ok\n")); - + if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(c, - username_used, - *pp_password, - *pp_workgroup))) { - + username_used, + *pp_password, + *pp_workgroup))) { + /* * context->smb_encryption_level == 1 * means don't fail if encryption can't be negotiated, * == 2 means fail if encryption can't be negotiated. */ - + DEBUG(4,(" SMB encrypt failed\n")); - + if (context->internal->smb_encryption_level == 2) { cli_shutdown(c); errno = EPERM; @@ -475,25 +482,25 @@ SMBC_server(TALLOC_CTX *ctx, } DEBUG(4,(" SMB encrypt ok\n")); } - + /* * Ok, we have got a nice connection * Let's allocate a server structure. */ - + srv = SMB_MALLOC_P(SMBCSRV); if (!srv) { errno = ENOMEM; goto failed; } - + ZERO_STRUCTP(srv); srv->cli = c; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->no_pathinfo = False; srv->no_pathinfo2 = False; srv->no_nt_session = False; - + /* now add it to the cache (internal or external) */ /* Let the cache function set errno if it wants to */ errno = 0; @@ -509,19 +516,19 @@ SMBC_server(TALLOC_CTX *ctx, } goto failed; } - + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", server, share, srv)); - + DLIST_ADD(context->internal->servers, srv); return srv; - - failed: + +failed: cli_shutdown(c); if (!srv) { return NULL; } - + SAFE_FREE(srv); return NULL; } @@ -545,32 +552,34 @@ SMBC_attr_server(TALLOC_CTX *ctx, struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; SMBCSRV *ipc_srv=NULL; - + /* * See if we've already created this special connection. Reference * our "special" share name '*IPC$', which is an impossible real share * name due to the leading asterisk. */ ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", - pp_workgroup, pp_username, pp_password); + pp_workgroup, pp_username, pp_password); if (!ipc_srv) { - + /* We didn't find a cached connection. Get the password */ if (!*pp_password || (*pp_password)[0] == '\0') { /* ... then retrieve it now. */ SMBC_call_auth_fn(ctx, context, server, share, - pp_workgroup, pp_username, pp_password); + pp_workgroup, + pp_username, + pp_password); if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; return NULL; } } - + flags = 0; if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } - + zero_addr(&ss); nt_status = cli_full_connection(&ipc_cli, global_myname(), server, @@ -586,23 +595,23 @@ SMBC_attr_server(TALLOC_CTX *ctx, errno = ENOTSUP; return NULL; } - + if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, - *pp_username, - *pp_password, - *pp_workgroup))) { - + *pp_username, + *pp_password, + *pp_workgroup))) { + /* * context->smb_encryption_level == * 1 means don't fail if encryption can't be * negotiated, == 2 means fail if encryption * can't be negotiated. */ - + DEBUG(4,(" SMB encrypt failed on IPC$\n")); - + if (context->internal->smb_encryption_level == 2) { cli_shutdown(ipc_cli); errno = EPERM; @@ -611,49 +620,49 @@ SMBC_attr_server(TALLOC_CTX *ctx, } DEBUG(4,(" SMB encrypt ok on IPC$\n")); } - + ipc_srv = SMB_MALLOC_P(SMBCSRV); if (!ipc_srv) { errno = ENOMEM; cli_shutdown(ipc_cli); return NULL; } - + ZERO_STRUCTP(ipc_srv); ipc_srv->cli = ipc_cli; - + pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, PI_LSARPC, &nt_status); if (!pipe_hnd) { - DEBUG(1, ("cli_nt_session_open fail!\n")); - errno = ENOTSUP; - cli_shutdown(ipc_srv->cli); - free(ipc_srv); - return NULL; + DEBUG(1, ("cli_nt_session_open fail!\n")); + errno = ENOTSUP; + cli_shutdown(ipc_srv->cli); + free(ipc_srv); + return NULL; } - + /* * Some systems don't support * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 * so we might as well do it too. */ - + nt_status = rpccli_lsa_open_policy( - pipe_hnd, - talloc_tos(), - True, - GENERIC_EXECUTE_ACCESS, - &ipc_srv->pol); - + pipe_hnd, + talloc_tos(), + True, + GENERIC_EXECUTE_ACCESS, + &ipc_srv->pol); + if (!NT_STATUS_IS_OK(nt_status)) { - errno = SMBC_errno(context, ipc_srv->cli); - cli_shutdown(ipc_srv->cli); - return NULL; + errno = SMBC_errno(context, ipc_srv->cli); + cli_shutdown(ipc_srv->cli); + return NULL; } - + /* now add it to the cache (internal or external) */ - + errno = 0; /* let cache function set errno if it likes */ if ((context->cache.add_cached_server_fn)(context, ipc_srv, server, @@ -668,9 +677,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, free(ipc_srv); return NULL; } - + DLIST_ADD(context->internal->servers, ipc_srv); } - + return ipc_srv; } diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index 6072547e08..b733eab74f 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -33,18 +33,18 @@ static ino_t generate_inode(SMBCCTX *context, - const char *name) + const char *name) { if (!context || !context->internal->initialized) { - + errno = EINVAL; return -1; - + } - + if (!*name) return 2; /* FIXME, why 2 ??? */ return (ino_t)str_checksum(name); - + } /* @@ -54,26 +54,26 @@ generate_inode(SMBCCTX *context, static int setup_stat(SMBCCTX *context, - struct stat *st, - char *fname, - SMB_OFF_T size, - int mode) + struct stat *st, + char *fname, + SMB_OFF_T size, + int mode) { TALLOC_CTX *frame = talloc_stackframe(); - + st->st_mode = 0; - + if (IS_DOS_DIR(mode)) { st->st_mode = SMBC_DIR_MODE; } else { st->st_mode = SMBC_FILE_MODE; } - + if (IS_DOS_ARCHIVE(mode)) st->st_mode |= S_IXUSR; if (IS_DOS_SYSTEM(mode)) st->st_mode |= S_IXGRP; if (IS_DOS_HIDDEN(mode)) st->st_mode |= S_IXOTH; if (!IS_DOS_READONLY(mode)) st->st_mode |= S_IWUSR; - + st->st_size = size; #ifdef HAVE_STAT_ST_BLKSIZE st->st_blksize = 512; @@ -86,20 +86,20 @@ setup_stat(SMBCCTX *context, #endif st->st_uid = getuid(); st->st_gid = getgid(); - + if (IS_DOS_DIR(mode)) { st->st_nlink = 2; } else { st->st_nlink = 1; } - + if (st->st_ino == 0) { st->st_ino = generate_inode(context, fname); } - + TALLOC_FREE(frame); return True; /* FIXME: Is this needed ? */ - + } /* @@ -125,37 +125,37 @@ SMBC_stat_ctx(SMBCCTX *context, uint16 mode = 0; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_stat(%s)\n", fname)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame,context->config.user); if (!user) { @@ -164,15 +164,15 @@ SMBC_stat_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (!SMBC_getatr(context, srv, path, &mode, &size, NULL, &access_time_ts, @@ -183,19 +183,19 @@ SMBC_stat_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + st->st_ino = ino; - + setup_stat(context, st, (char *) fname, size, mode); - + set_atimespec(st, access_time_ts); set_ctimespec(st, change_time_ts); set_mtimespec(st, write_time_ts); st->st_dev = srv->dev; - + TALLOC_FREE(frame); return 0; - + } /* @@ -221,41 +221,41 @@ SMBC_fstat_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; SMB_INO_T ino = 0; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!file || !SMBC_dlist_contains(context->internal->files, file)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + if (!file->file) { TALLOC_FREE(frame); return (context->posix_emu.fstatdir_fn)(context, file, st); } - + /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ if (SMBC_parse_path(frame, - context, - file->fname, - NULL, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + file->fname, + NULL, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + /*d_printf(">>>fstat: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", file->srv->cli, path, &targetcli, &targetpath)) { @@ -264,39 +264,39 @@ SMBC_fstat_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/ - + if (!cli_qfileinfo(targetcli, file->cli_fd, &mode, &size, NULL, &access_time_ts, &write_time_ts, &change_time_ts, &ino)) { - + time_t change_time, access_time, write_time; - + if (!cli_getattrE(targetcli, file->cli_fd, &mode, &size, - &change_time, &access_time, &write_time)) { - + &change_time, &access_time, &write_time)) { + errno = EINVAL; TALLOC_FREE(frame); return -1; } - + change_time_ts = convert_time_t_to_timespec(change_time); access_time_ts = convert_time_t_to_timespec(access_time); write_time_ts = convert_time_t_to_timespec(write_time); } - + st->st_ino = ino; - + setup_stat(context, st, file->fname, size, mode); - + set_atimespec(st, access_time_ts); set_ctimespec(st, change_time_ts); set_mtimespec(st, write_time_ts); st->st_dev = file->srv->dev; - + TALLOC_FREE(frame); return 0; - + } diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index a420299341..3c08412d59 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -34,16 +34,16 @@ static struct rpc_pipe_client * find_lsa_pipe_hnd(struct cli_state *ipc_cli) { struct rpc_pipe_client *pipe_hnd; - + for (pipe_hnd = ipc_cli->pipe_list; pipe_hnd; pipe_hnd = pipe_hnd->next) { - + if (pipe_hnd->pipe_idx == PI_LSARPC) { return pipe_hnd; } } - + return NULL; } @@ -59,19 +59,19 @@ ace_compare(SEC_ACE *ace1, { bool b1; bool b2; - + /* If the ACEs are equal, we have nothing more to do. */ if (sec_ace_equal(ace1, ace2)) { return 0; } - + /* Inherited follow non-inherited */ b1 = ((ace1->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); b2 = ((ace2->flags & SEC_ACE_FLAG_INHERITED_ACE) != 0); if (b1 != b2) { return (b1 ? 1 : -1); } - + /* * What shall we do with AUDITs and ALARMs? It's undefined. We'll * sort them after DENY and ALLOW. @@ -87,7 +87,7 @@ ace_compare(SEC_ACE *ace1, if (b1 != b2) { return (b1 ? 1 : -1); } - + /* Allowed ACEs follow denied ACEs */ b1 = (ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED || ace1->type == SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT); @@ -96,7 +96,7 @@ ace_compare(SEC_ACE *ace1, if (b1 != b2) { return (b1 ? 1 : -1); } - + /* * ACEs applying to an entity's object follow those applying to the * entity itself @@ -108,34 +108,34 @@ ace_compare(SEC_ACE *ace1, if (b1 != b2) { return (b1 ? 1 : -1); } - + /* * If we get this far, the ACEs are similar as far as the * characteristics we typically care about (those defined by the * referenced MS document). We'll now sort by characteristics that * just seems reasonable. */ - + if (ace1->type != ace2->type) { return ace2->type - ace1->type; } - + if (sid_compare(&ace1->trustee, &ace2->trustee)) { return sid_compare(&ace1->trustee, &ace2->trustee); } - + if (ace1->flags != ace2->flags) { return ace1->flags - ace2->flags; } - + if (ace1->access_mask != ace2->access_mask) { return ace1->access_mask - ace2->access_mask; } - + if (ace1->size != ace2->size) { return ace1->size - ace2->size; } - + return memcmp(ace1, ace2, sizeof(SEC_ACE)); } @@ -145,10 +145,10 @@ sort_acl(SEC_ACL *the_acl) { uint32 i; if (!the_acl) return; - + qsort(the_acl->aces, the_acl->num_aces, sizeof(the_acl->aces[0]), QSORT_CAST ace_compare); - + for (i=1;inum_aces;) { if (sec_ace_equal(&the_acl->aces[i-1], &the_acl->aces[i])) { int j; @@ -175,32 +175,32 @@ convert_sid_to_string(struct cli_state *ipc_cli, enum lsa_SidType *types = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); TALLOC_CTX *ctx; - + sid_to_fstring(str, sid); - + if (numeric) { return; /* no lookup desired */ } - + if (!pipe_hnd) { return; } - + /* Ask LSA to convert the sid to a name */ - + ctx = talloc_stackframe(); - + if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_sids(pipe_hnd, ctx, - pol, 1, sid, &domains, - &names, &types)) || + pol, 1, sid, &domains, + &names, &types)) || !domains || !domains[0] || !names || !names[0]) { TALLOC_FREE(ctx); return; } - + TALLOC_FREE(ctx); /* Converted OK */ - + slprintf(str, sizeof(fstring) - 1, "%s%s%s", domains[0], lp_winbind_separator(), names[0]); @@ -219,31 +219,32 @@ convert_string_to_sid(struct cli_state *ipc_cli, bool result = True; TALLOC_CTX *ctx = NULL; struct rpc_pipe_client *pipe_hnd = find_lsa_pipe_hnd(ipc_cli); - + if (!pipe_hnd) { return False; } - + if (numeric) { if (strncmp(str, "S-", 2) == 0) { return string_to_sid(sid, str); } - + result = False; goto done; } - + ctx = talloc_stackframe(); if (!NT_STATUS_IS_OK(rpccli_lsa_lookup_names(pipe_hnd, ctx, - pol, 1, &str, NULL, 1, &sids, - &types))) { + pol, 1, &str, + NULL, 1, &sids, + &types))) { result = False; goto done; } - + sid_copy(sid, &sids[0]); - done: - +done: + TALLOC_FREE(ctx); return result; } @@ -271,7 +272,7 @@ parse_ace(struct cli_state *ipc_cli, uint32 mask; }; TALLOC_CTX *frame = talloc_stackframe(); - + /* These values discovered by inspection */ static const struct perm_value special_values[] = { { "R", 0x00120089 }, @@ -282,15 +283,15 @@ parse_ace(struct cli_state *ipc_cli, { "O", 0x00080000 }, { NULL, 0 }, }; - + static const struct perm_value standard_values[] = { { "READ", 0x001200a9 }, { "CHANGE", 0x001301bf }, { "FULL", 0x001f01ff }, { NULL, 0 }, }; - - + + ZERO_STRUCTP(ace); p = strchr_m(str,':'); if (!p) { @@ -300,25 +301,25 @@ parse_ace(struct cli_state *ipc_cli, *p = '\0'; p++; /* Try to parse numeric form */ - + if (sscanf(p, "%i/%i/%i", &atype, &aflags, &amask) == 3 && convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { goto done; } - + /* Try to parse text form */ - + if (!convert_string_to_sid(ipc_cli, pol, numeric, &sid, str)) { TALLOC_FREE(frame); return false; } - + cp = p; if (!next_token_talloc(frame, &cp, &tok, "/")) { TALLOC_FREE(frame); return false; } - + if (StrnCaseCmp(tok, "ALLOWED", strlen("ALLOWED")) == 0) { atype = SEC_ACE_TYPE_ACCESS_ALLOWED; } else if (StrnCaseCmp(tok, "DENIED", strlen("DENIED")) == 0) { @@ -327,20 +328,20 @@ parse_ace(struct cli_state *ipc_cli, TALLOC_FREE(frame); return false; } - + /* Only numeric form accepted for flags at present */ - + if (!(next_token_talloc(frame, &cp, &tok, "/") && sscanf(tok, "%i", &aflags))) { TALLOC_FREE(frame); return false; } - + if (!next_token_talloc(frame, &cp, &tok, "/")) { TALLOC_FREE(frame); return false; } - + if (strncmp(tok, "0x", 2) == 0) { if (sscanf(tok, "%i", &amask) != 1) { TALLOC_FREE(frame); @@ -348,39 +349,39 @@ parse_ace(struct cli_state *ipc_cli, } goto done; } - + for (v = standard_values; v->perm; v++) { if (strcmp(tok, v->perm) == 0) { amask = v->mask; goto done; } } - + p = tok; - + while(*p) { bool found = False; - + for (v = special_values; v->perm; v++) { if (v->perm[0] == *p) { amask |= v->mask; found = True; } } - + if (!found) { TALLOC_FREE(frame); return false; } p++; } - + if (*p) { TALLOC_FREE(frame); return false; } - - done: + +done: mask = amask; init_sec_ace(ace, &sid, atype, mask, aflags); TALLOC_FREE(frame); @@ -395,13 +396,14 @@ add_ace(SEC_ACL **the_acl, { SEC_ACL *newacl; SEC_ACE *aces; - + if (! *the_acl) { (*the_acl) = make_sec_acl(ctx, 3, 1, ace); return True; } - - if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, 1+(*the_acl)->num_aces)) == NULL) { + + if ((aces = SMB_CALLOC_ARRAY(SEC_ACE, + 1+(*the_acl)->num_aces)) == NULL) { return False; } memcpy(aces, (*the_acl)->aces, (*the_acl)->num_aces * sizeof(SEC_ACE)); @@ -430,17 +432,17 @@ sec_desc_parse(TALLOC_CTX *ctx, DOM_SID *owner_sid=NULL; SEC_ACL *dacl=NULL; int revision=1; - + while (next_token_talloc(ctx, &p, &tok, "\t,\r\n")) { - + if (StrnCaseCmp(tok,"REVISION:", 9) == 0) { revision = strtol(tok+9, NULL, 16); continue; } - + if (StrnCaseCmp(tok,"OWNER:", 6) == 0) { if (owner_sid) { - DEBUG(5, ("OWNER specified more than once!\n")); + DEBUG(5,("OWNER specified more than once!\n")); goto done; } owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); @@ -453,10 +455,10 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"OWNER+:", 7) == 0) { if (owner_sid) { - DEBUG(5, ("OWNER specified more than once!\n")); + DEBUG(5,("OWNER specified more than once!\n")); goto done; } owner_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); @@ -469,10 +471,10 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"GROUP:", 6) == 0) { if (group_sid) { - DEBUG(5, ("GROUP specified more than once!\n")); + DEBUG(5,("GROUP specified more than once!\n")); goto done; } group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); @@ -485,10 +487,10 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"GROUP+:", 7) == 0) { if (group_sid) { - DEBUG(5, ("GROUP specified more than once!\n")); + DEBUG(5,("GROUP specified more than once!\n")); goto done; } group_sid = SMB_CALLOC_ARRAY(DOM_SID, 1); @@ -501,7 +503,7 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"ACL:", 4) == 0) { SEC_ACE ace; if (!parse_ace(ipc_cli, pol, &ace, numeric, tok+4)) { @@ -514,7 +516,7 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + if (StrnCaseCmp(tok,"ACL+:", 5) == 0) { SEC_ACE ace; if (!parse_ace(ipc_cli, pol, &ace, False, tok+5)) { @@ -527,18 +529,18 @@ sec_desc_parse(TALLOC_CTX *ctx, } continue; } - + DEBUG(5, ("Failed to parse security descriptor\n")); goto done; } - + ret = make_sec_desc(ctx, revision, SEC_DESC_SELF_RELATIVE, owner_sid, group_sid, NULL, dacl, &sd_size); - - done: + +done: SAFE_FREE(group_sid); SAFE_FREE(owner_sid); - + return ret; } @@ -558,13 +560,13 @@ dos_attr_query(SMBCCTX *context, uint16 mode = 0; SMB_INO_T inode = 0; DOS_ATTR_DESC *ret; - + ret = TALLOC_P(ctx, DOS_ATTR_DESC); if (!ret) { errno = ENOMEM; return NULL; } - + /* Obtain the DOS attributes */ if (!SMBC_getatr(context, srv, CONST_DISCARD(char *, filename), &mode, &size, @@ -577,7 +579,7 @@ dos_attr_query(SMBCCTX *context, DEBUG(5, ("dos_attr_query Failed to query old attributes\n")); return NULL; } - + ret->mode = mode; ret->size = size; ret->create_time = convert_timespec_to_time_t(create_time_ts); @@ -585,7 +587,7 @@ dos_attr_query(SMBCCTX *context, ret->write_time = convert_timespec_to_time_t(write_time_ts); ret->change_time = convert_timespec_to_time_t(change_time_ts); ret->inode = inode; - + return ret; } @@ -607,7 +609,7 @@ dos_attr_parse(SMBCCTX *context, const char * write_time_attr; const char * change_time_attr; } attr_strings; - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->full_time_names) { /* new-style names */ @@ -622,7 +624,7 @@ dos_attr_parse(SMBCCTX *context, attr_strings.write_time_attr = "M_TIME"; attr_strings.change_time_attr = "C_TIME"; } - + /* if this is to set the entire ACL... */ if (*str == '*') { /* ... then increment past the first colon if there is one */ @@ -632,7 +634,7 @@ dos_attr_parse(SMBCCTX *context, p = str; } } - + frame = talloc_stackframe(); while (next_token_talloc(frame, &p, &tok, "\t,\r\n")) { if (StrnCaseCmp(tok, "MODE:", 5) == 0) { @@ -647,30 +649,30 @@ dos_attr_parse(SMBCCTX *context, } continue; } - + if (StrnCaseCmp(tok, "SIZE:", 5) == 0) { dad->size = (SMB_OFF_T)atof(tok+5); continue; } - + n = strlen(attr_strings.access_time_attr); if (StrnCaseCmp(tok, attr_strings.access_time_attr, n) == 0) { dad->access_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } - + n = strlen(attr_strings.change_time_attr); if (StrnCaseCmp(tok, attr_strings.change_time_attr, n) == 0) { dad->change_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } - + n = strlen(attr_strings.write_time_attr); if (StrnCaseCmp(tok, attr_strings.write_time_attr, n) == 0) { dad->write_time = (time_t)strtol(tok+n+1, NULL, 10); continue; } - + if (attr_strings.create_time_attr != NULL) { n = strlen(attr_strings.create_time_attr); if (StrnCaseCmp(tok, attr_strings.create_time_attr, @@ -680,7 +682,7 @@ dos_attr_parse(SMBCCTX *context, continue; } } - + if (StrnCaseCmp(tok, "INODE:", 6) == 0) { dad->inode = (SMB_INO_T)atof(tok+6); continue; @@ -757,7 +759,7 @@ cacl_get(SMBCCTX *context, const char * write_time_attr; const char * change_time_attr; } excl_attr_strings; - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->full_time_names) { /* new-style names */ @@ -765,7 +767,7 @@ cacl_get(SMBCCTX *context, attr_strings.access_time_attr = "ACCESS_TIME"; attr_strings.write_time_attr = "WRITE_TIME"; attr_strings.change_time_attr = "CHANGE_TIME"; - + excl_attr_strings.create_time_attr = "CREATE_TIME"; excl_attr_strings.access_time_attr = "ACCESS_TIME"; excl_attr_strings.write_time_attr = "WRITE_TIME"; @@ -776,28 +778,28 @@ cacl_get(SMBCCTX *context, attr_strings.access_time_attr = "A_TIME"; attr_strings.write_time_attr = "M_TIME"; attr_strings.change_time_attr = "C_TIME"; - + excl_attr_strings.create_time_attr = NULL; excl_attr_strings.access_time_attr = "dos_attr.A_TIME"; excl_attr_strings.write_time_attr = "dos_attr.M_TIME"; excl_attr_strings.change_time_attr = "dos_attr.C_TIME"; } - + /* Copy name so we can strip off exclusions (if any are specified) */ strncpy(name_sandbox, attr_name, sizeof(name_sandbox) - 1); - + /* Ensure name is null terminated */ name_sandbox[sizeof(name_sandbox) - 1] = '\0'; - + /* Play in the sandbox */ name = name_sandbox; - + /* If there are any exclusions, point to them and mask them from name */ if ((pExclude = strchr(name, '!')) != NULL) { *pExclude++ = '\0'; } - + all = (StrnCaseCmp(name, "system.*", 8) == 0); all_nt = (StrnCaseCmp(name, "system.nt_sec_desc.*", 20) == 0); all_nt_acls = (StrnCaseCmp(name, "system.nt_sec_desc.acl.*", 24) == 0); @@ -805,71 +807,77 @@ cacl_get(SMBCCTX *context, some_nt = (StrnCaseCmp(name, "system.nt_sec_desc.", 19) == 0); some_dos = (StrnCaseCmp(name, "system.dos_attr.", 16) == 0); numeric = (* (name + strlen(name) - 1) != '+'); - + /* Look for exclusions from "all" requests */ if (all || all_nt || all_dos) { - + /* Exclusions are delimited by '!' */ for (; pExclude != NULL; pExclude = (p == NULL ? NULL : p + 1)) { - - /* Find end of this exclusion name */ - if ((p = strchr(pExclude, '!')) != NULL) - { - *p = '\0'; - } - - /* Which exclusion name is this? */ - if (StrCaseCmp(pExclude, "nt_sec_desc.revision") == 0) { - exclude_nt_revision = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.owner") == 0) { - exclude_nt_owner = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.group") == 0) { - exclude_nt_group = True; - } - else if (StrCaseCmp(pExclude, "nt_sec_desc.acl") == 0) { - exclude_nt_acl = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.mode") == 0) { - exclude_dos_mode = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.size") == 0) { - exclude_dos_size = True; - } - else if (excl_attr_strings.create_time_attr != NULL && - StrCaseCmp(pExclude, - excl_attr_strings.change_time_attr) == 0) { - exclude_dos_create_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.access_time_attr) == 0) { - exclude_dos_access_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.write_time_attr) == 0) { - exclude_dos_write_time = True; - } - else if (StrCaseCmp(pExclude, - excl_attr_strings.change_time_attr) == 0) { - exclude_dos_change_time = True; - } - else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { - exclude_dos_inode = True; - } - else { - DEBUG(5, ("cacl_get received unknown exclusion: %s\n", - pExclude)); - errno = ENOATTR; - return -1; + + /* Find end of this exclusion name */ + if ((p = strchr(pExclude, '!')) != NULL) + { + *p = '\0'; + } + + /* Which exclusion name is this? */ + if (StrCaseCmp(pExclude, + "nt_sec_desc.revision") == 0) { + exclude_nt_revision = True; + } + else if (StrCaseCmp(pExclude, + "nt_sec_desc.owner") == 0) { + exclude_nt_owner = True; + } + else if (StrCaseCmp(pExclude, + "nt_sec_desc.group") == 0) { + exclude_nt_group = True; + } + else if (StrCaseCmp(pExclude, + "nt_sec_desc.acl") == 0) { + exclude_nt_acl = True; + } + else if (StrCaseCmp(pExclude, + "dos_attr.mode") == 0) { + exclude_dos_mode = True; + } + else if (StrCaseCmp(pExclude, + "dos_attr.size") == 0) { + exclude_dos_size = True; + } + else if (excl_attr_strings.create_time_attr != NULL && + StrCaseCmp(pExclude, + excl_attr_strings.change_time_attr) == 0) { + exclude_dos_create_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.access_time_attr) == 0) { + exclude_dos_access_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.write_time_attr) == 0) { + exclude_dos_write_time = True; + } + else if (StrCaseCmp(pExclude, + excl_attr_strings.change_time_attr) == 0) { + exclude_dos_change_time = True; + } + else if (StrCaseCmp(pExclude, "dos_attr.inode") == 0) { + exclude_dos_inode = True; + } + else { + DEBUG(5, ("cacl_get received unknown exclusion: %s\n", + pExclude)); + errno = ENOATTR; + return -1; + } } - } } - + n_used = 0; - + /* * If we are (possibly) talking to an NT or new system and some NT * attributes have been requested... @@ -877,28 +885,28 @@ cacl_get(SMBCCTX *context, if (ipc_cli && (all || some_nt || all_nt_acls)) { /* Point to the portion after "system.nt_sec_desc." */ name += 19; /* if (all) this will be invalid but unused */ - + /* ... then obtain any NT attributes which were requested */ fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - + if (fnum == -1) { DEBUG(5, ("cacl_get failed to open %s: %s\n", filename, cli_errstr(cli))); errno = 0; return -1; } - + sd = cli_query_secdesc(cli, fnum, ctx); - + if (!sd) { DEBUG(5, ("cacl_get Failed to query old descriptor\n")); errno = 0; return -1; } - + cli_close(cli, fnum); - + if (! exclude_nt_revision) { if (all || all_nt) { if (determine_size) { @@ -929,7 +937,7 @@ cacl_get(SMBCCTX *context, sd->revision); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -939,7 +947,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_nt_owner) { /* Get owner and group sid */ if (sd->owner_sid) { @@ -950,7 +958,7 @@ cacl_get(SMBCCTX *context, } else { fstrcpy(sidstr, ""); } - + if (all || all_nt) { if (determine_size) { p = talloc_asprintf(ctx, ",OWNER:%s", @@ -977,7 +985,7 @@ cacl_get(SMBCCTX *context, sidstr); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -987,7 +995,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_nt_group) { if (sd->group_sid) { convert_sid_to_string(ipc_cli, pol, @@ -996,7 +1004,7 @@ cacl_get(SMBCCTX *context, } else { fstrcpy(sidstr, ""); } - + if (all || all_nt) { if (determine_size) { p = talloc_asprintf(ctx, ",GROUP:%s", @@ -1023,7 +1031,7 @@ cacl_get(SMBCCTX *context, "%s", sidstr); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1033,16 +1041,16 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_nt_acl) { /* Add aces to value buffer */ for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) { - + SEC_ACE *ace = &sd->dacl->aces[i]; convert_sid_to_string(ipc_cli, pol, sidstr, numeric, &ace->trustee); - + if (all || all_nt) { if (determine_size) { p = talloc_asprintf( @@ -1125,15 +1133,15 @@ cacl_get(SMBCCTX *context, n = 0; } } - + /* Restore name pointer to its original value */ name -= 19; } - + if (all || some_dos) { /* Point to the portion after "system.dos_attr." */ name += 16; /* if (all) this will be invalid but unused */ - + /* Obtain the DOS attributes */ if (!SMBC_getatr(context, srv, filename, &mode, &size, &create_time_ts, @@ -1141,17 +1149,17 @@ cacl_get(SMBCCTX *context, &write_time_ts, &change_time_ts, &ino)) { - + errno = SMBC_errno(context, srv->cli); return -1; - + } - + create_time = convert_timespec_to_time_t(create_time_ts); access_time = convert_timespec_to_time_t(access_time_ts); write_time = convert_timespec_to_time_t(write_time_ts); change_time = convert_timespec_to_time_t(change_time_ts); - + if (! exclude_dos_mode) { if (all || all_dos) { if (determine_size) { @@ -1189,7 +1197,7 @@ cacl_get(SMBCCTX *context, "0x%x", mode); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1199,7 +1207,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_size) { if (all || all_dos) { if (determine_size) { @@ -1234,7 +1242,7 @@ cacl_get(SMBCCTX *context, (double)size); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1244,7 +1252,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_create_time && attr_strings.create_time_attr != NULL) { if (all || all_dos) { @@ -1277,7 +1285,7 @@ cacl_get(SMBCCTX *context, "%lu", create_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1287,7 +1295,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_access_time) { if (all || all_dos) { if (determine_size) { @@ -1319,7 +1327,7 @@ cacl_get(SMBCCTX *context, "%lu", access_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1329,7 +1337,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_write_time) { if (all || all_dos) { if (determine_size) { @@ -1361,7 +1369,7 @@ cacl_get(SMBCCTX *context, "%lu", write_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1371,7 +1379,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_change_time) { if (all || all_dos) { if (determine_size) { @@ -1403,7 +1411,7 @@ cacl_get(SMBCCTX *context, "%lu", change_time); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1413,7 +1421,7 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + if (! exclude_dos_inode) { if (all || all_dos) { if (determine_size) { @@ -1448,7 +1456,7 @@ cacl_get(SMBCCTX *context, (double) ino); } } - + if (!determine_size && n > bufsize) { errno = ERANGE; return -1; @@ -1458,16 +1466,16 @@ cacl_get(SMBCCTX *context, bufsize -= n; n = 0; } - + /* Restore name pointer to its original value */ name -= 16; } - + if (n_used == 0) { errno = ENOATTR; return -1; } - + return n_used; } @@ -1495,68 +1503,68 @@ cacl_set(TALLOC_CTX *ctx, int ret = 0; char *p; bool numeric = True; - + /* the_acl will be null for REMOVE_ALL operations */ if (the_acl) { numeric = ((p = strchr(the_acl, ':')) != NULL && p > the_acl && p[-1] != '+'); - + /* if this is to set the entire ACL... */ if (*the_acl == '*') { /* ... then increment past the first colon */ the_acl = p + 1; } - + sd = sec_desc_parse(ctx, ipc_cli, pol, numeric, CONST_DISCARD(char *, the_acl)); - + if (!sd) { errno = EINVAL; return -1; } } - + /* SMBC_XATTR_MODE_REMOVE_ALL is the only caller that doesn't deref sd */ - + if (!sd && (mode != SMBC_XATTR_MODE_REMOVE_ALL)) { errno = EINVAL; return -1; } - + /* The desired access below is the only one I could find that works with NT4, W2KP and Samba */ - + fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - + if (fnum == -1) { DEBUG(5, ("cacl_set failed to open %s: %s\n", filename, cli_errstr(cli))); errno = 0; return -1; } - + old = cli_query_secdesc(cli, fnum, ctx); - + if (!old) { DEBUG(5, ("cacl_set Failed to query old descriptor\n")); errno = 0; return -1; } - + cli_close(cli, fnum); - + switch (mode) { case SMBC_XATTR_MODE_REMOVE_ALL: old->dacl->num_aces = 0; dacl = old->dacl; break; - + case SMBC_XATTR_MODE_REMOVE: for (i=0;sd->dacl && idacl->num_aces;i++) { bool found = False; - + for (j=0;old->dacl && jdacl->num_aces;j++) { if (sec_ace_equal(&sd->dacl->aces[i], &old->dacl->aces[j])) { @@ -1571,7 +1579,7 @@ cacl_set(TALLOC_CTX *ctx, break; } } - + if (!found) { err = ENOATTR; ret = -1; @@ -1579,11 +1587,11 @@ cacl_set(TALLOC_CTX *ctx, } } break; - + case SMBC_XATTR_MODE_ADD: for (i=0;sd->dacl && idacl->num_aces;i++) { bool found = False; - + for (j=0;old->dacl && jdacl->num_aces;j++) { if (sid_equal(&sd->dacl->aces[i].trustee, &old->dacl->aces[j].trustee)) { @@ -1597,67 +1605,67 @@ cacl_set(TALLOC_CTX *ctx, found = True; } } - + if (!found && (flags & SMBC_XATTR_FLAG_REPLACE)) { err = ENOATTR; ret = -1; goto failed; } - + for (i=0;sd->dacl && idacl->num_aces;i++) { add_ace(&old->dacl, &sd->dacl->aces[i], ctx); } } dacl = old->dacl; break; - + case SMBC_XATTR_MODE_SET: old = sd; owner_sid = old->owner_sid; group_sid = old->group_sid; dacl = old->dacl; break; - + case SMBC_XATTR_MODE_CHOWN: owner_sid = sd->owner_sid; break; - + case SMBC_XATTR_MODE_CHGRP: group_sid = sd->group_sid; break; } - + /* Denied ACE entries must come before allowed ones */ sort_acl(old->dacl); - + /* Create new security descriptor and set it */ sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, owner_sid, group_sid, NULL, dacl, &sd_size); - + fnum = cli_nt_create(cli, filename, WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); - + if (fnum == -1) { DEBUG(5, ("cacl_set failed to open %s: %s\n", filename, cli_errstr(cli))); errno = 0; return -1; } - + if (!cli_set_secdesc(cli, fnum, sd)) { DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli))); ret = -1; } - + /* Clean up */ - - failed: + +failed: cli_close(cli, fnum); - + if (err != 0) { errno = err; } - + return ret; } @@ -1688,38 +1696,38 @@ SMBC_setxattr_ctx(SMBCCTX *context, const char * change_time_attr; } attr_strings; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_setxattr(%s, %s, %.*s)\n", fname, name, (int) size, (const char*)value)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -1728,14 +1736,14 @@ SMBC_setxattr_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (! srv->no_nt_session) { ipc_srv = SMBC_attr_server(frame, context, server, share, &workgroup, &user, &password); @@ -1745,7 +1753,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + /* * Are they asking to set the entire set of known attributes? */ @@ -1761,7 +1769,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (ipc_srv) { ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, @@ -1773,13 +1781,13 @@ SMBC_setxattr_ctx(SMBCCTX *context, } else { ret = 0; } - + /* get a DOS Attribute Descriptor with current attributes */ dad = dos_attr_query(context, talloc_tos(), path, srv); if (dad) { /* Overwrite old with new, using what was provided */ dos_attr_parse(context, dad, srv, namevalue); - + /* Set the new DOS attributes */ if (! SMBC_setatr(context, srv, path, dad->create_time, @@ -1787,12 +1795,12 @@ SMBC_setxattr_ctx(SMBCCTX *context, dad->write_time, dad->change_time, dad->mode)) { - + /* cause failure if NT failed too */ dad = NULL; } } - + /* we only fail if both NT and DOS sets failed */ if (ret < 0 && ! dad) { ret = -1; /* in case dad was null */ @@ -1800,11 +1808,11 @@ SMBC_setxattr_ctx(SMBCCTX *context, else { ret = 0; } - + TALLOC_FREE(frame); return ret; } - + /* * Are they asking to set an access control element or to set * the entire access control list? @@ -1814,12 +1822,12 @@ SMBC_setxattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.revision") == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { - + /* Yup. */ char *namevalue = talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); - + if (! ipc_srv) { ret = -1; /* errno set by SMBC_server() */ } @@ -1838,18 +1846,18 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* * Are they asking to set the owner? */ if (StrCaseCmp(name, "system.nt_sec_desc.owner") == 0 || StrCaseCmp(name, "system.nt_sec_desc.owner+") == 0) { - + /* Yup. */ char *namevalue = talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); - + if (! ipc_srv) { ret = -1; /* errno set by SMBC_server() */ } @@ -1864,18 +1872,18 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* * Are they asking to set the group? */ if (StrCaseCmp(name, "system.nt_sec_desc.group") == 0 || StrCaseCmp(name, "system.nt_sec_desc.group+") == 0) { - + /* Yup. */ char *namevalue = talloc_asprintf(talloc_tos(), "%s:%s", name+19, (const char *) value); - + if (! ipc_srv) { /* errno set by SMBC_server() */ ret = -1; @@ -1891,7 +1899,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->full_time_names) { /* new-style names */ @@ -1906,7 +1914,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, attr_strings.write_time_attr = "system.dos_attr.M_TIME"; attr_strings.change_time_attr = "system.dos_attr.C_TIME"; } - + /* * Are they asking to set a DOS attribute? */ @@ -1917,7 +1925,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, StrCaseCmp(name, attr_strings.access_time_attr) == 0 || StrCaseCmp(name, attr_strings.write_time_attr) == 0 || StrCaseCmp(name, attr_strings.change_time_attr) == 0) { - + /* get a DOS Attribute Descriptor with current attributes */ dad = dos_attr_query(context, talloc_tos(), path, srv); if (dad) { @@ -1930,7 +1938,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } else { /* Overwrite old with provided new params */ dos_attr_parse(context, dad, srv, namevalue); - + /* Set the new DOS attributes */ ret2 = SMBC_setatr(context, srv, path, dad->create_time, @@ -1938,7 +1946,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, dad->write_time, dad->change_time, dad->mode); - + /* ret2 has True (success) / False (failure) */ if (ret2) { ret = 0; @@ -1949,11 +1957,11 @@ SMBC_setxattr_ctx(SMBCCTX *context, } else { ret = -1; } - + TALLOC_FREE(frame); return ret; } - + /* Unsupported attribute name */ errno = EINVAL; TALLOC_FREE(frame); @@ -1983,37 +1991,37 @@ SMBC_getxattr_ctx(SMBCCTX *context, const char * change_time_attr; } attr_strings; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_getxattr(%s, %s)\n", fname, name)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -2022,14 +2030,14 @@ SMBC_getxattr_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (! srv->no_nt_session) { ipc_srv = SMBC_attr_server(frame, context, server, share, &workgroup, &user, &password); @@ -2039,7 +2047,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + /* Determine whether to use old-style or new-style attribute names */ if (context->internal->full_time_names) { /* new-style names */ @@ -2054,7 +2062,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, attr_strings.write_time_attr = "system.dos_attr.M_TIME"; attr_strings.change_time_attr = "system.dos_attr.C_TIME"; } - + /* Are they requesting a supported attribute? */ if (StrCaseCmp(name, "system.*") == 0 || StrnCaseCmp(name, "system.*!", 9) == 0 || @@ -2081,7 +2089,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, StrCaseCmp(name, attr_strings.write_time_attr) == 0 || StrCaseCmp(name, attr_strings.change_time_attr) == 0 || StrCaseCmp(name, "system.dos_attr.inode") == 0) { - + /* Yup. */ ret = cacl_get(context, talloc_tos(), srv, ipc_srv == NULL ? NULL : ipc_srv->cli, @@ -2094,7 +2102,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* Unsupported attribute name */ errno = EINVAL; TALLOC_FREE(frame); @@ -2117,37 +2125,37 @@ SMBC_removexattr_ctx(SMBCCTX *context, char *workgroup = NULL; char *path = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_removexattr(%s, %s)\n", fname, name)); - + if (SMBC_parse_path(frame, - context, - fname, - &workgroup, - &server, - &share, - &path, - &user, - &password, - NULL)) { + context, + fname, + &workgroup, + &server, + &share, + &path, + &user, + &password, + NULL)) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, context->config.user); if (!user) { @@ -2156,14 +2164,14 @@ SMBC_removexattr_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (! srv->no_nt_session) { ipc_srv = SMBC_attr_server(frame, context, server, share, &workgroup, &user, &password); @@ -2173,16 +2181,16 @@ SMBC_removexattr_ctx(SMBCCTX *context, } else { ipc_srv = NULL; } - + if (! ipc_srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_attr_server */ } - + /* Are they asking to set the entire ACL? */ if (StrCaseCmp(name, "system.nt_sec_desc.*") == 0 || StrCaseCmp(name, "system.nt_sec_desc.*+") == 0) { - + /* Yup. */ ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, @@ -2190,7 +2198,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* * Are they asking to remove one or more spceific security descriptor * attributes? @@ -2202,7 +2210,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, StrCaseCmp(name, "system.nt_sec_desc.group+") == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl", 22) == 0 || StrnCaseCmp(name, "system.nt_sec_desc.acl+", 23) == 0) { - + /* Yup. */ ret = cacl_set(talloc_tos(), srv->cli, ipc_srv->cli, &ipc_srv->pol, path, @@ -2210,7 +2218,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, TALLOC_FREE(frame); return ret; } - + /* Unsupported attribute name */ errno = EINVAL; TALLOC_FREE(frame); @@ -2269,7 +2277,7 @@ SMBC_listxattr_ctx(SMBCCTX *context, "system.dos_attr.change_time\0" ; const char * supported; - + if (context->internal->full_time_names) { supported = supported_new; retsize = sizeof(supported_new); @@ -2277,16 +2285,16 @@ SMBC_listxattr_ctx(SMBCCTX *context, supported = supported_old; retsize = sizeof(supported_old); } - + if (size == 0) { return retsize; } - + if (retsize > size) { errno = ERANGE; return -1; } - + /* this can't be strcpy() because there are embedded null characters */ memcpy(list, supported, retsize); return retsize; -- cgit From fc65c6698e74e40828e218dc2e6de0c094bfe6e0 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 1 Mar 2008 21:19:52 -0500 Subject: Return NULL, not 0, from a function which returns a pointer. (This used to be commit 23cb9c49e3724cecaa66655ef64c3111bf14c552) --- source3/libsmb/libsmb_cache.c | 1 - source3/libsmb/libsmb_context.c | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index ff13fd7eac..c45aba4544 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -1,4 +1,3 @@ - /* Unix SMB/CIFS implementation. SMB client library implementation (server cache) diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 8af49d12be..c107ab2220 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -424,7 +424,7 @@ smbc_init_context(SMBCCTX *context) /* Do not initialise the same client twice */ if (context->internal->initialized) { - return 0; + return NULL; } if (!context->server.get_auth_data_fn || @@ -446,7 +446,7 @@ smbc_init_context(SMBCCTX *context) /* Set this to what the user wants */ DEBUGLEVEL = context->config.debug; - + load_case_tables(); setup_logging("libsmbclient", True); -- cgit From 1363ee9d65965704f716965c6cbcfc0693ca2401 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 3 Mar 2008 18:13:33 -0500 Subject: Continued revamping of libsmbclient. - James suggested using gcc's "deprecated" attribute to mark the context structure fields to generate warnings. This creates a scenario with the best of all worlds. I'm able to move to an organization that more easily allows future enhancements, while avoiding any mandatory changes by applications. Thanks, James! - Updated WHATSNEW.txt so that it accurately reflects the current state of affairs. Derrell (This used to be commit a67f96fbe9683b46c2149f7cb439d13f7f0e6ecd) --- source3/libsmb/libsmb_cache.c | 16 +- source3/libsmb/libsmb_context.c | 1078 ++++---------------------------------- source3/libsmb/libsmb_dir.c | 30 +- source3/libsmb/libsmb_file.c | 8 +- source3/libsmb/libsmb_path.c | 6 +- source3/libsmb/libsmb_printjob.c | 6 +- source3/libsmb/libsmb_server.c | 75 +-- source3/libsmb/libsmb_setget.c | 905 ++++++++++++++++++++++++++++++++ source3/libsmb/libsmb_stat.c | 4 +- source3/libsmb/libsmb_xattr.c | 6 +- 10 files changed, 1091 insertions(+), 1043 deletions(-) create mode 100644 source3/libsmb/libsmb_setget.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_cache.c b/source3/libsmb/libsmb_cache.c index c45aba4544..bfacea368d 100644 --- a/source3/libsmb/libsmb_cache.c +++ b/source3/libsmb/libsmb_cache.c @@ -88,7 +88,7 @@ SMBC_add_cached_server(SMBCCTX * context, goto failed; } - DLIST_ADD((context->cache.server_cache_data), srvcache); + DLIST_ADD(context->internal->server_cache, srvcache); return 0; failed: @@ -118,7 +118,7 @@ SMBC_get_cached_server(SMBCCTX * context, struct smbc_server_cache * srv = NULL; /* Search the cache lines */ - for (srv = context->cache.server_cache_data; srv; srv = srv->next) { + for (srv = context->internal->server_cache; srv; srv = srv->next) { if (strcmp(server,srv->server_name) == 0 && strcmp(workgroup,srv->workgroup) == 0 && @@ -150,7 +150,7 @@ SMBC_get_cached_server(SMBCCTX * context, * a connection to the server (other than the * attribute server connection) is cool. */ - if (context->options.one_share_per_server) { + if (smbc_getOptionOneSharePerServer(context)) { /* * The currently connected share name * doesn't match the requested share, so @@ -160,7 +160,7 @@ SMBC_get_cached_server(SMBCCTX * context, /* Sigh. Couldn't disconnect. */ cli_shutdown(srv->server->cli); srv->server->cli = NULL; - context->cache.remove_cached_server_fn(context, srv->server); + smbc_getFunctionRemoveCachedServer(context)(context, srv->server); continue; } @@ -175,7 +175,7 @@ SMBC_get_cached_server(SMBCCTX * context, /* Out of memory. */ cli_shutdown(srv->server->cli); srv->server->cli = NULL; - context->cache.remove_cached_server_fn(context, srv->server); + smbc_getFunctionRemoveCachedServer(context)(context, srv->server); continue; } @@ -200,11 +200,11 @@ SMBC_remove_cached_server(SMBCCTX * context, { struct smbc_server_cache * srv = NULL; - for (srv = context->cache.server_cache_data; srv; srv = srv->next) { + for (srv = context->internal->server_cache; srv; srv = srv->next) { if (server == srv->server) { /* remove this sucker */ - DLIST_REMOVE(context->cache.server_cache_data, srv); + DLIST_REMOVE(context->internal->server_cache, srv); SAFE_FREE(srv->server_name); SAFE_FREE(srv->share_name); SAFE_FREE(srv->workgroup); @@ -229,7 +229,7 @@ SMBC_purge_cached_servers(SMBCCTX * context) struct smbc_server_cache * next; int could_not_purge_all = 0; - for (srv = context->cache.server_cache_data, + for (srv = context->internal->server_cache, next = (srv ? srv->next :NULL); srv; srv = next, diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index c107ab2220..c04f751696 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -46,11 +46,6 @@ smbc_new_context(void) * All newly added context fields should be placed in * SMBC_internal_data, not directly in SMBCCTX. */ -#undef OLD -#define OLD(field) context->field -#undef NEW -#define NEW(field) context->internal->field - context = SMB_MALLOC_P(SMBCCTX); if (!context) { errno = ENOMEM; @@ -69,61 +64,59 @@ smbc_new_context(void) /* Initialize the context and establish reasonable defaults */ ZERO_STRUCTP(context->internal); - OLD(config.debug) = 0; - OLD(config.timeout) = 20000; /* 20 seconds */ - - NEW(full_time_names) = False; - NEW(share_mode) = SMBC_SHAREMODE_DENY_NONE; - NEW(smb_encryption_level) = 0; - OLD(options.browse_max_lmb_count) = 3; /* # LMBs to query */ - OLD(options.urlencode_readdir_entries) = False; - OLD(options.one_share_per_server) = False; - - OLD(server.get_auth_data_fn) = SMBC_get_auth_data; - OLD(server.check_server_fn) = SMBC_check_server; - OLD(server.remove_unused_server_fn) = SMBC_remove_unused_server; - - OLD(cache.server_cache_data) = NULL; - OLD(cache.add_cached_server_fn) = SMBC_add_cached_server; - OLD(cache.get_cached_server_fn) = SMBC_get_cached_server; - OLD(cache.remove_cached_server_fn) = SMBC_remove_cached_server; - OLD(cache.purge_cached_servers_fn) = SMBC_purge_cached_servers; - - OLD(posix_emu.open_fn) = SMBC_open_ctx; - OLD(posix_emu.creat_fn) = SMBC_creat_ctx; - OLD(posix_emu.read_fn) = SMBC_read_ctx; - OLD(posix_emu.write_fn) = SMBC_write_ctx; - OLD(posix_emu.close_fn) = SMBC_close_ctx; - OLD(posix_emu.unlink_fn) = SMBC_unlink_ctx; - OLD(posix_emu.rename_fn) = SMBC_rename_ctx; - OLD(posix_emu.lseek_fn) = SMBC_lseek_ctx; - NEW(posix_emu.ftruncate_fn) = SMBC_ftruncate_ctx; - OLD(posix_emu.stat_fn) = SMBC_stat_ctx; - OLD(posix_emu.fstat_fn) = SMBC_fstat_ctx; - OLD(posix_emu.opendir_fn) = SMBC_opendir_ctx; - OLD(posix_emu.closedir_fn) = SMBC_closedir_ctx; - OLD(posix_emu.readdir_fn) = SMBC_readdir_ctx; - OLD(posix_emu.getdents_fn) = SMBC_getdents_ctx; - OLD(posix_emu.mkdir_fn) = SMBC_mkdir_ctx; - OLD(posix_emu.rmdir_fn) = SMBC_rmdir_ctx; - OLD(posix_emu.telldir_fn) = SMBC_telldir_ctx; - OLD(posix_emu.lseekdir_fn) = SMBC_lseekdir_ctx; - OLD(posix_emu.fstatdir_fn) = SMBC_fstatdir_ctx; - OLD(posix_emu.chmod_fn) = SMBC_chmod_ctx; - OLD(posix_emu.utimes_fn) = SMBC_utimes_ctx; - OLD(posix_emu.setxattr_fn) = SMBC_setxattr_ctx; - OLD(posix_emu.getxattr_fn) = SMBC_getxattr_ctx; - OLD(posix_emu.removexattr_fn) = SMBC_removexattr_ctx; - OLD(posix_emu.listxattr_fn) = SMBC_listxattr_ctx; - - OLD(printing.open_print_job_fn) = SMBC_open_print_job_ctx; - OLD(printing.print_file_fn) = SMBC_print_file_ctx; - OLD(printing.list_print_jobs_fn) = SMBC_list_print_jobs_ctx; - OLD(printing.unlink_print_job_fn) = SMBC_unlink_print_job_ctx; + smbc_setDebug(context, 0); + smbc_setTimeout(context, 20000); + + smbc_setOptionFullTimeNames(context, False); + smbc_setOptionOpenShareMode(context, SMBC_SHAREMODE_DENY_NONE); + smbc_setOptionSmbEncryptionLevel(context, SMBC_ENCRYPTLEVEL_NONE); + smbc_setOptionBrowseMaxLmbCount(context, 3); /* # LMBs to query */ + smbc_setOptionUrlEncodeReaddirEntries(context, False); + smbc_setOptionOneSharePerServer(context, False); + + smbc_setFunctionAuthData(context, SMBC_get_auth_data); + smbc_setFunctionCheckServer(context, SMBC_check_server); + smbc_setFunctionRemoveUnusedServer(context, SMBC_remove_unused_server); + + smbc_setOptionUserData(context, NULL); + smbc_setFunctionAddCachedServer(context, SMBC_add_cached_server); + smbc_setFunctionGetCachedServer(context, SMBC_get_cached_server); + smbc_setFunctionRemoveCachedServer(context, SMBC_remove_cached_server); + smbc_setFunctionPurgeCachedServers(context, SMBC_purge_cached_servers); + + smbc_setFunctionOpen(context, SMBC_open_ctx); + smbc_setFunctionCreat(context, SMBC_creat_ctx); + smbc_setFunctionRead(context, SMBC_read_ctx); + smbc_setFunctionWrite(context, SMBC_write_ctx); + smbc_setFunctionClose(context, SMBC_close_ctx); + smbc_setFunctionUnlink(context, SMBC_unlink_ctx); + smbc_setFunctionRename(context, SMBC_rename_ctx); + smbc_setFunctionLseek(context, SMBC_lseek_ctx); + smbc_setFunctionFtruncate(context, SMBC_ftruncate_ctx); + smbc_setFunctionStat(context, SMBC_stat_ctx); + smbc_setFunctionFstat(context, SMBC_fstat_ctx); + smbc_setFunctionOpendir(context, SMBC_opendir_ctx); + smbc_setFunctionClosedir(context, SMBC_closedir_ctx); + smbc_setFunctionReaddir(context, SMBC_readdir_ctx); + smbc_setFunctionGetdents(context, SMBC_getdents_ctx); + smbc_setFunctionMkdir(context, SMBC_mkdir_ctx); + smbc_setFunctionRmdir(context, SMBC_rmdir_ctx); + smbc_setFunctionTelldir(context, SMBC_telldir_ctx); + smbc_setFunctionLseekdir(context, SMBC_lseekdir_ctx); + smbc_setFunctionFstatdir(context, SMBC_fstatdir_ctx); + smbc_setFunctionChmod(context, SMBC_chmod_ctx); + smbc_setFunctionUtimes(context, SMBC_utimes_ctx); + smbc_setFunctionSetxattr(context, SMBC_setxattr_ctx); + smbc_setFunctionGetxattr(context, SMBC_getxattr_ctx); + smbc_setFunctionRemovexattr(context, SMBC_removexattr_ctx); + smbc_setFunctionListxattr(context, SMBC_listxattr_ctx); + + smbc_setFunctionOpenPrintJob(context, SMBC_open_print_job_ctx); + smbc_setFunctionPrintFile(context, SMBC_print_file_ctx); + smbc_setFunctionListPrintJobs(context, SMBC_list_print_jobs_ctx); + smbc_setFunctionUnlinkPrintJob(context, SMBC_unlink_print_job_ctx); return context; -#undef OLD -#undef NEW } /* @@ -148,13 +141,13 @@ smbc_free_context(SMBCCTX *context, f = context->internal->files; while (f) { - (context->posix_emu.close_fn)(context, f); + smbc_getFunctionClose(context)(context, f); f = f->next; } context->internal->files = NULL; /* First try to remove the servers the nice way. */ - if (context->cache.purge_cached_servers_fn(context)) { + if (smbc_getFunctionPurgeCachedServers(context)(context)) { SMBCSRV * s; SMBCSRV * next; DEBUG(1, ("Could not purge all servers, " @@ -164,7 +157,7 @@ smbc_free_context(SMBCCTX *context, DEBUG(1, ("Forced shutdown: %p (fd=%d)\n", s, s->cli->fd)); cli_shutdown(s->cli); - (context->cache.remove_cached_server_fn)(context, + smbc_getFunctionRemoveCachedServer(context)(context, s); next = s->next; DLIST_REMOVE(context->internal->servers, s); @@ -176,7 +169,7 @@ smbc_free_context(SMBCCTX *context, } else { /* This is the polite way */ - if ((context->cache.purge_cached_servers_fn)(context)) { + if (smbc_getFunctionPurgeCachedServers(context)(context)) { DEBUG(1, ("Could not purge all servers, " "free_context failed.\n")); errno = EBUSY; @@ -197,9 +190,14 @@ smbc_free_context(SMBCCTX *context, } /* Things we have to clean up */ - SAFE_FREE(context->config.workgroup); - SAFE_FREE(context->config.netbios_name); - SAFE_FREE(context->config.user); + free(smbc_getWorkgroup(context)); + smbc_setWorkgroup(context, NULL); + + free(smbc_getNetbiosName(context)); + smbc_setNetbiosName(context, NULL); + + free(smbc_getUser(context)); + smbc_setUser(context, NULL); DEBUG(3, ("Context %p successfully freed\n", context)); SAFE_FREE(context); @@ -298,8 +296,6 @@ void * smbc_option_get(SMBCCTX *context, char *option_name) { - int bits; - if (strcmp(option_name, "debug_stderr") == 0) { #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) return (void *) (intptr_t) smbc_getOptionDebugToStderr(context); @@ -376,7 +372,6 @@ smbc_option_get(SMBCCTX *context, #endif } else if (strcmp(option_name, "use_kerberos") == 0) { - bits = context->flags.bits; #if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T) return (void *) (intptr_t) smbc_getOptionUseKerberos(context); #else @@ -427,9 +422,9 @@ smbc_init_context(SMBCCTX *context) return NULL; } - if (!context->server.get_auth_data_fn || - context->config.debug < 0 || - context->config.debug > 100) { + if (!smbc_getFunctionAuthData(context) || + smbc_getDebug(context) < 0 || + smbc_getDebug(context) > 100) { errno = EINVAL; return NULL; @@ -444,9 +439,6 @@ smbc_init_context(SMBCCTX *context) bool conf_loaded = False; TALLOC_CTX *frame = talloc_stackframe(); - /* Set this to what the user wants */ - DEBUGLEVEL = context->config.debug; - load_case_tables(); setup_logging("libsmbclient", True); @@ -521,58 +513,84 @@ smbc_init_context(SMBCCTX *context) TALLOC_FREE(frame); } - if (!context->config.user) { + if (!smbc_getUser(context)) { /* * FIXME: Is this the best way to get the user info? */ user = getenv("USER"); /* walk around as "guest" if no username can be found */ - if (!user) context->config.user = SMB_STRDUP("guest"); - else context->config.user = SMB_STRDUP(user); + if (!user) { + user = SMB_STRDUP("guest"); + } else { + user = SMB_STRDUP(user); + } + + if (!user) { + errno = ENOMEM; + return NULL; + } + + smbc_setUser(context, user); } - if (!context->config.netbios_name) { + if (!smbc_getNetbiosName(context)) { /* * We try to get our netbios name from the config. If that * fails we fall back on constructing our netbios name from * our hostname etc */ + char *netbios_name; if (global_myname()) { - context->config.netbios_name = SMB_STRDUP(global_myname()); - } - else { + netbios_name = SMB_STRDUP(global_myname()); + } else { /* * Hmmm, I want to get hostname as well, but I am too * lazy for the moment */ pid = sys_getpid(); - context->config.netbios_name = (char *)SMB_MALLOC(17); - if (!context->config.netbios_name) { + netbios_name = (char *)SMB_MALLOC(17); + if (!netbios_name) { errno = ENOMEM; return NULL; } - slprintf(context->config.netbios_name, 16, - "smbc%s%d", context->config.user, pid); + slprintf(netbios_name, 16, + "smbc%s%d", smbc_getUser(context), pid); } + + if (!netbios_name) { + errno = ENOMEM; + return NULL; + } + + smbc_setNetbiosName(context, netbios_name); } - DEBUG(1, ("Using netbios name %s.\n", context->config.netbios_name)); + DEBUG(1, ("Using netbios name %s.\n", smbc_getNetbiosName(context))); - if (!context->config.workgroup) { + if (!smbc_getWorkgroup(context)) { + char *workgroup; + if (lp_workgroup()) { - context->config.workgroup = SMB_STRDUP(lp_workgroup()); + workgroup = SMB_STRDUP(lp_workgroup()); } else { /* TODO: Think about a decent default workgroup */ - context->config.workgroup = SMB_STRDUP("samba"); + workgroup = SMB_STRDUP("samba"); } + + if (!workgroup) { + errno = ENOMEM; + return NULL; + } + + smbc_setWorkgroup(context, workgroup); } - DEBUG(1, ("Using workgroup %s.\n", context->config.workgroup)); + DEBUG(1, ("Using workgroup %s.\n", smbc_getWorkgroup(context))); /* shortest timeout is 1 second */ - if (context->config.timeout > 0 && context->config.timeout < 1000) - context->config.timeout = 1000; + if (smbc_getTimeout(context) > 0 && smbc_getTimeout(context) < 1000) + smbc_setTimeout(context, 1000); /* * FIXME: Should we check the function pointers here? @@ -592,879 +610,3 @@ smbc_version(void) } -/** Get the netbios name used for making connections */ -char * -smbc_getNetbiosName(SMBCCTX *c) -{ - return c->config.netbios_name; -} - -/** Set the netbios name used for making connections */ -void -smbc_setNetbiosName(SMBCCTX *c, char * netbios_name) -{ - c->config.netbios_name = netbios_name; -} - -/** Get the workgroup used for making connections */ -char * -smbc_getWorkgroup(SMBCCTX *c) -{ - return c->config.workgroup; -} - -/** Set the workgroup used for making connections */ -void -smbc_setWorkgroup(SMBCCTX *c, char * workgroup) -{ - c->config.workgroup = workgroup; -} - -/** Get the username used for making connections */ -char * -smbc_getUser(SMBCCTX *c) -{ - return c->config.user; -} - -/** Set the username used for making connections */ -void -smbc_setUser(SMBCCTX *c, char * user) -{ - c->config.user = user; -} - -/** Get the debug level */ -int -smbc_getDebug(SMBCCTX *c) -{ - return c->config.debug; -} - -/** Set the debug level */ -void -smbc_setDebug(SMBCCTX *c, int debug) -{ - c->config.debug = debug; -} - -/** - * Get the timeout used for waiting on connections and response data - * (in milliseconds) - */ -int -smbc_getTimeout(SMBCCTX *c) -{ - return c->config.timeout; -} - -/** - * Set the timeout used for waiting on connections and response data - * (in milliseconds) - */ -void -smbc_setTimeout(SMBCCTX *c, int timeout) -{ - c->config.timeout = timeout; -} - -/** Get whether to log to standard error instead of standard output */ -smbc_bool -smbc_getOptionDebugToStderr(SMBCCTX *c) -{ - return c->internal->debug_stderr; -} - -/** Set whether to log to standard error instead of standard output */ -void -smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b) -{ - c->internal->debug_stderr = b; -} - -/** - * Get whether to use new-style time attribute names, e.g. WRITE_TIME rather - * than the old-style names such as M_TIME. This allows also setting/getting - * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME - * was supposed to be CHANGE_TIME but was confused and sometimes referred to - * CREATE_TIME.) - */ -smbc_bool -smbc_getOptionFullTimeNames(SMBCCTX *c) -{ - return c->internal->full_time_names; -} - -/** - * Set whether to use new-style time attribute names, e.g. WRITE_TIME rather - * than the old-style names such as M_TIME. This allows also setting/getting - * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME - * was supposed to be CHANGE_TIME but was confused and sometimes referred to - * CREATE_TIME.) - */ -void -smbc_setOptionFullTimeNames(SMBCCTX *c, smbc_bool b) -{ - c->internal->full_time_names = b; -} - -/** - * Get the share mode to use for files opened with SMBC_open_ctx(). The - * default is SMBC_SHAREMODE_DENY_NONE. - */ -smbc_share_mode -smbc_getOptionOpenShareMode(SMBCCTX *c) -{ - return c->internal->share_mode; -} - -/** - * Set the share mode to use for files opened with SMBC_open_ctx(). The - * default is SMBC_SHAREMODE_DENY_NONE. - */ -void -smbc_setOptionOpenShareMode(SMBCCTX *c, smbc_share_mode share_mode) -{ - c->internal->share_mode = share_mode; -} - -/** Retrieve a previously set user data handle */ -void * -smbc_getOptionUserData(SMBCCTX *c) -{ - return c->internal->user_data; -} - -/** Save a user data handle */ -void -smbc_setOptionUserData(SMBCCTX *c, void *user_data) -{ - c->internal->user_data = user_data; -} - -/** Get the encoded value for encryption level. */ -smbc_smb_encrypt_level -smbc_getOptionSmbEncryptionLevel(SMBCCTX *c) -{ - return c->internal->smb_encryption_level; -} - -/** Set the encoded value for encryption level. */ -void -smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level) -{ - c->internal->smb_encryption_level = level; -} - -/** - * Get from how many local master browsers should the list of workgroups be - * retrieved. It can take up to 12 minutes or longer after a server becomes a - * local master browser, for it to have the entire browse list (the list of - * workgroups/domains) from an entire network. Since a client never knows - * which local master browser will be found first, the one which is found - * first and used to retrieve a browse list may have an incomplete or empty - * browse list. By requesting the browse list from multiple local master - * browsers, a more complete list can be generated. For small networks (few - * workgroups), it is recommended that this value be set to 0, causing the - * browse lists from all found local master browsers to be retrieved and - * merged. For networks with many workgroups, a suitable value for this - * variable is probably somewhere around 3. (Default: 3). - */ -int -smbc_getOptionBrowseMaxLmbCount(SMBCCTX *c) -{ - return c->options.browse_max_lmb_count; -} - -/** - * Set from how many local master browsers should the list of workgroups be - * retrieved. It can take up to 12 minutes or longer after a server becomes a - * local master browser, for it to have the entire browse list (the list of - * workgroups/domains) from an entire network. Since a client never knows - * which local master browser will be found first, the one which is found - * first and used to retrieve a browse list may have an incomplete or empty - * browse list. By requesting the browse list from multiple local master - * browsers, a more complete list can be generated. For small networks (few - * workgroups), it is recommended that this value be set to 0, causing the - * browse lists from all found local master browsers to be retrieved and - * merged. For networks with many workgroups, a suitable value for this - * variable is probably somewhere around 3. (Default: 3). - */ -void -smbc_setOptionBrowseMaxLmbCount(SMBCCTX *c, int count) -{ - c->options.browse_max_lmb_count = count; -} - -/** - * Get whether to url-encode readdir entries. - * - * There is a difference in the desired return strings from - * smbc_readdir() depending upon whether the filenames are to - * be displayed to the user, or whether they are to be - * appended to the path name passed to smbc_opendir() to call - * a further smbc_ function (e.g. open the file with - * smbc_open()). In the former case, the filename should be - * in "human readable" form. In the latter case, the smbc_ - * functions expect a URL which must be url-encoded. Those - * functions decode the URL. If, for example, smbc_readdir() - * returned a file name of "abc%20def.txt", passing a path - * with this file name attached to smbc_open() would cause - * smbc_open to attempt to open the file "abc def.txt" since - * the %20 is decoded into a space. - * - * Set this option to True if the names returned by - * smbc_readdir() should be url-encoded such that they can be - * passed back to another smbc_ call. Set it to False if the - * names returned by smbc_readdir() are to be presented to the - * user. - * - * For backwards compatibility, this option defaults to False. - */ -smbc_bool -smbc_getOptionUrlEncodeReaddirEntries(SMBCCTX *c) -{ - return c->options.urlencode_readdir_entries; -} - -/** - * Set whether to url-encode readdir entries. - * - * There is a difference in the desired return strings from - * smbc_readdir() depending upon whether the filenames are to - * be displayed to the user, or whether they are to be - * appended to the path name passed to smbc_opendir() to call - * a further smbc_ function (e.g. open the file with - * smbc_open()). In the former case, the filename should be - * in "human readable" form. In the latter case, the smbc_ - * functions expect a URL which must be url-encoded. Those - * functions decode the URL. If, for example, smbc_readdir() - * returned a file name of "abc%20def.txt", passing a path - * with this file name attached to smbc_open() would cause - * smbc_open to attempt to open the file "abc def.txt" since - * the %20 is decoded into a space. - * - * Set this option to True if the names returned by - * smbc_readdir() should be url-encoded such that they can be - * passed back to another smbc_ call. Set it to False if the - * names returned by smbc_readdir() are to be presented to the - * user. - * - * For backwards compatibility, this option defaults to False. - */ -void -smbc_setOptionUrlEncodeReaddirEntries(SMBCCTX *c, smbc_bool b) -{ - c->options.urlencode_readdir_entries = b; -} - -/** - * Get whether to use the same connection for all shares on a server. - * - * Some Windows versions appear to have a limit to the number - * of concurrent SESSIONs and/or TREE CONNECTions. In - * one-shot programs (i.e. the program runs and then quickly - * ends, thereby shutting down all connections), it is - * probably reasonable to establish a new connection for each - * share. In long-running applications, the limitation can be - * avoided by using only a single connection to each server, - * and issuing a new TREE CONNECT when the share is accessed. - */ -smbc_bool -smbc_getOptionOneSharePerServer(SMBCCTX *c) -{ - return c->options.one_share_per_server; -} - -/** - * Set whether to use the same connection for all shares on a server. - * - * Some Windows versions appear to have a limit to the number - * of concurrent SESSIONs and/or TREE CONNECTions. In - * one-shot programs (i.e. the program runs and then quickly - * ends, thereby shutting down all connections), it is - * probably reasonable to establish a new connection for each - * share. In long-running applications, the limitation can be - * avoided by using only a single connection to each server, - * and issuing a new TREE CONNECT when the share is accessed. - */ -void -smbc_setOptionOneSharePerServer(SMBCCTX *c, smbc_bool b) -{ - c->options.one_share_per_server = b; -} - -/** Get whether to enable use of kerberos */ -smbc_bool -smbc_getOptionUseKerberos(SMBCCTX *c) -{ - return c->flags.bits & SMB_CTX_FLAG_USE_KERBEROS ? True : False; -} - -/** Set whether to enable use of kerberos */ -void -smbc_setOptionUseKerberos(SMBCCTX *c, smbc_bool b) -{ - if (b) { - c->flags.bits |= SMB_CTX_FLAG_USE_KERBEROS; - } else { - c->flags.bits &= ~SMB_CTX_FLAG_USE_KERBEROS; - } -} - -/** Get whether to fallback after kerberos */ -smbc_bool -smbc_getOptionFallbackAfterKerberos(SMBCCTX *c) -{ - return c->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS ? True : False; -} - -/** Set whether to fallback after kerberos */ -void -smbc_setOptionFallbackAfterKerberos(SMBCCTX *c, smbc_bool b) -{ - if (b) { - c->flags.bits |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; - } else { - c->flags.bits &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; - } -} - -/** Get whether to automatically select anonymous login */ -smbc_bool -smbc_getOptionNoAutoAnonymousLogin(SMBCCTX *c) -{ - return c->flags.bits & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON ? True : False; -} - -/** Set whether to automatically select anonymous login */ -void -smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b) -{ - if (b) { - c->flags.bits |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; - } else { - c->flags.bits &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; - } -} - -/** Get the function for obtaining authentication data */ -smbc_get_auth_data_fn -smbc_getFunctionAuthData(SMBCCTX *c) -{ - return c->server.get_auth_data_fn; -} - -/** Set the function for obtaining authentication data */ -void -smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn) -{ - c->internal->auth_fn_with_context = NULL; - c->server.get_auth_data_fn = fn; -} - -/** Get the new-style authentication function which includes the context. */ -smbc_get_auth_data_with_context_fn -smbc_getFunctionAuthDataWithContext(SMBCCTX *c) -{ - return c->internal->auth_fn_with_context; -} - -/** Set the new-style authentication function which includes the context. */ -void -smbc_setFunctionAuthDataWithContext(SMBCCTX *c, - smbc_get_auth_data_with_context_fn fn) -{ - c->server.get_auth_data_fn = NULL; - c->internal->auth_fn_with_context = fn; -} - -/** Get the function for checking if a server is still good */ -smbc_check_server_fn -smbc_getFunctionCheckServer(SMBCCTX *c) -{ - return c->server.check_server_fn; -} - -/** Set the function for checking if a server is still good */ -void -smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn) -{ - c->server.check_server_fn = fn; -} - -/** Get the function for removing a server if unused */ -smbc_remove_unused_server_fn -smbc_getFunctionRemoveUnusedServer(SMBCCTX *c) -{ - return c->server.remove_unused_server_fn; -} - -/** Set the function for removing a server if unused */ -void -smbc_setFunctionRemoveUnusedServer(SMBCCTX *c, - smbc_remove_unused_server_fn fn) -{ - c->server.remove_unused_server_fn = fn; -} - -/** Get the function to store private data of the server cache */ -struct -smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c) -{ - return c->cache.server_cache_data; -} - -/** Set the function to store private data of the server cache */ -void -smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache) -{ - c->cache.server_cache_data = cache; -} - - -/** Get the function for adding a cached server */ -smbc_add_cached_srv_fn -smbc_getFunctionAddCachedServer(SMBCCTX *c) -{ - return c->cache.add_cached_server_fn; -} - -/** Set the function for adding a cached server */ -void -smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn) -{ - c->cache.add_cached_server_fn = fn; -} - -/** Get the function for server cache lookup */ -smbc_get_cached_srv_fn -smbc_getFunctionGetCachedServer(SMBCCTX *c) -{ - return c->cache.get_cached_server_fn; -} - -/** Set the function for server cache lookup */ -void -smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn) -{ - c->cache.get_cached_server_fn = fn; -} - -/** Get the function for server cache removal */ -smbc_remove_cached_srv_fn -smbc_getFunctionRemoveCachedServer(SMBCCTX *c) -{ - return c->cache.remove_cached_server_fn; -} - -/** Set the function for server cache removal */ -void -smbc_setFunctionRemoveCachedServer(SMBCCTX *c, - smbc_remove_cached_srv_fn fn) -{ - c->cache.remove_cached_server_fn = fn; -} - -/** - * Get the function for server cache purging. This function tries to - * remove all cached servers (e.g. on disconnect) - */ -smbc_purge_cached_srv_fn -smbc_getFunctionPurgeCachedServers(SMBCCTX *c) -{ - return c->cache.purge_cached_servers_fn; -} - -/** - * Set the function for server cache purging. This function tries to - * remove all cached servers (e.g. on disconnect) - */ -void -smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_srv_fn fn) -{ - c->cache.purge_cached_servers_fn = fn; -} - -/** - * Callable functions for files. - */ - -smbc_open_fn -smbc_getFunctionOpen(SMBCCTX *c) -{ - return c->posix_emu.open_fn; -} - -void -smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn) -{ - c->posix_emu.open_fn = fn; -} - -smbc_creat_fn -smbc_getFunctionCreat(SMBCCTX *c) -{ - return c->posix_emu.creat_fn; -} - -void -smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn) -{ - c->posix_emu.creat_fn = fn; -} - -smbc_read_fn -smbc_getFunctionRead(SMBCCTX *c) -{ - return c->posix_emu.read_fn; -} - -void -smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn) -{ - c->posix_emu.read_fn = fn; -} - -smbc_write_fn -smbc_getFunctionWrite(SMBCCTX *c) -{ - return c->posix_emu.write_fn; -} - -void -smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn) -{ - c->posix_emu.write_fn = fn; -} - -smbc_unlink_fn -smbc_getFunctionUnlink(SMBCCTX *c) -{ - return c->posix_emu.unlink_fn; -} - -void -smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn) -{ - c->posix_emu.unlink_fn = fn; -} - -smbc_rename_fn -smbc_getFunctionRename(SMBCCTX *c) -{ - return c->posix_emu.rename_fn; -} - -void -smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn) -{ - c->posix_emu.rename_fn = fn; -} - -smbc_lseek_fn -smbc_getFunctionLseek(SMBCCTX *c) -{ - return c->posix_emu.lseek_fn; -} - -void -smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn) -{ - c->posix_emu.lseek_fn = fn; -} - -smbc_stat_fn -smbc_getFunctionStat(SMBCCTX *c) -{ - return c->posix_emu.stat_fn; -} - -void -smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn) -{ - c->posix_emu.stat_fn = fn; -} - -smbc_fstat_fn -smbc_getFunctionFstat(SMBCCTX *c) -{ - return c->posix_emu.fstat_fn; -} - -void -smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn) -{ - c->posix_emu.fstat_fn = fn; -} - -smbc_ftruncate_fn -smbc_getFunctionFtruncate(SMBCCTX *c) -{ - return c->internal->posix_emu.ftruncate_fn; -} - -void -smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn) -{ - c->internal->posix_emu.ftruncate_fn = fn; -} - -smbc_close_fn -smbc_getFunctionClose(SMBCCTX *c) -{ - return c->posix_emu.close_fn; -} - -void -smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn) -{ - c->posix_emu.close_fn = fn; -} - - -/** - * Callable functions for directories. - */ - -smbc_opendir_fn -smbc_getFunctionOpendir(SMBCCTX *c) -{ - return c->posix_emu.opendir_fn; -} - -void -smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn) -{ - c->posix_emu.opendir_fn = fn; -} - -smbc_closedir_fn -smbc_getFunctionClosedir(SMBCCTX *c) -{ - return c->posix_emu.closedir_fn; -} - -void -smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn) -{ - c->posix_emu.closedir_fn = fn; -} - -smbc_readdir_fn -smbc_getFunctionReaddir(SMBCCTX *c) -{ - return c->posix_emu.readdir_fn; -} - -void -smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn) -{ - c->posix_emu.readdir_fn = fn; -} - -smbc_getdents_fn -smbc_getFunctionGetdents(SMBCCTX *c) -{ - return c->posix_emu.getdents_fn; -} - -void -smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn) -{ - c->posix_emu.getdents_fn = fn; -} - -smbc_mkdir_fn -smbc_getFunctionMkdir(SMBCCTX *c) -{ - return c->posix_emu.mkdir_fn; -} - -void -smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn) -{ - c->posix_emu.mkdir_fn = fn; -} - -smbc_rmdir_fn -smbc_getFunctionRmdir(SMBCCTX *c) -{ - return c->posix_emu.rmdir_fn; -} - -void -smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn) -{ - c->posix_emu.rmdir_fn = fn; -} - -smbc_telldir_fn -smbc_getFunctionTelldir(SMBCCTX *c) -{ - return c->posix_emu.telldir_fn; -} - -void -smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn) -{ - c->posix_emu.telldir_fn = fn; -} - -smbc_lseekdir_fn -smbc_getFunctionLseekdir(SMBCCTX *c) -{ - return c->posix_emu.lseekdir_fn; -} - -void -smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn) -{ - c->posix_emu.lseekdir_fn = fn; -} - -smbc_fstatdir_fn -smbc_getFunctionFstatdir(SMBCCTX *c) -{ - return c->posix_emu.fstatdir_fn; -} - -void -smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn) -{ - c->posix_emu.fstatdir_fn = fn; -} - - -/** - * Callable functions applicable to both files and directories. - */ - -smbc_chmod_fn -smbc_getFunctionChmod(SMBCCTX *c) -{ - return c->posix_emu.chmod_fn; -} - -void -smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn) -{ - c->posix_emu.chmod_fn = fn; -} - -smbc_utimes_fn -smbc_getFunctionUtimes(SMBCCTX *c) -{ - return c->posix_emu.utimes_fn; -} - -void -smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn) -{ - c->posix_emu.utimes_fn = fn; -} - -smbc_setxattr_fn -smbc_getFunctionSetxattr(SMBCCTX *c) -{ - return c->posix_emu.setxattr_fn; -} - -void -smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn) -{ - c->posix_emu.setxattr_fn = fn; -} - -smbc_getxattr_fn -smbc_getFunctionGetxattr(SMBCCTX *c) -{ - return c->posix_emu.getxattr_fn; -} - -void -smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn) -{ - c->posix_emu.getxattr_fn = fn; -} - -smbc_removexattr_fn -smbc_getFunctionRemovexattr(SMBCCTX *c) -{ - return c->posix_emu.removexattr_fn; -} - -void -smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn) -{ - c->posix_emu.removexattr_fn = fn; -} - -smbc_listxattr_fn -smbc_getFunctionListxattr(SMBCCTX *c) -{ - return c->posix_emu.listxattr_fn; -} - -void -smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn) -{ - c->posix_emu.listxattr_fn = fn; -} - - -/** - * Callable functions related to printing - */ - -smbc_print_file_fn -smbc_getFunctionPrintFile(SMBCCTX *c) -{ - return c->printing.print_file_fn; -} - -void -smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn) -{ - c->printing.print_file_fn = fn; -} - -smbc_open_print_job_fn -smbc_getFunctionOpenPrintJob(SMBCCTX *c) -{ - return c->printing.open_print_job_fn; -} - -void -smbc_setFunctionOpenPrintJob(SMBCCTX *c, - smbc_open_print_job_fn fn) -{ - c->printing.open_print_job_fn = fn; -} - -smbc_list_print_jobs_fn -smbc_getFunctionListPrintJobs(SMBCCTX *c) -{ - return c->printing.list_print_jobs_fn; -} - -void -smbc_setFunctionListPrintJobs(SMBCCTX *c, - smbc_list_print_jobs_fn fn) -{ - c->printing.list_print_jobs_fn = fn; -} - -smbc_unlink_print_job_fn -smbc_getFunctionUnlinkPrintJob(SMBCCTX *c) -{ - return c->printing.unlink_print_job_fn; -} - -void -smbc_setFunctionUnlinkPrintJob(SMBCCTX *c, - smbc_unlink_print_job_fn fn) -{ - c->printing.unlink_print_job_fn = fn; -} - diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 2ece2ab8ed..1486097d51 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -404,7 +404,7 @@ SMBC_opendir_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -450,9 +450,9 @@ SMBC_opendir_ctx(SMBCCTX *context, } /* Determine how many local master browsers to query */ - max_lmb_count = (context->options.browse_max_lmb_count == 0 + max_lmb_count = (smbc_getOptionBrowseMaxLmbCount(context) == 0 ? INT_MAX - : context->options.browse_max_lmb_count); + : smbc_getOptionBrowseMaxLmbCount(context)); memset(&u_info, '\0', sizeof(u_info)); u_info.username = talloc_strdup(frame,user); @@ -810,11 +810,11 @@ SMBC_opendir_ctx(SMBCCTX *context, * good any more... */ if (cli_is_error(targetcli) && - (context->server.check_server_fn)(context, srv)) { + smbc_getFunctionCheckServer(context)(context, srv)) { /* ... then remove it. */ - if ((context->server.remove_unused_server_fn)(context, - srv)) { + if (smbc_getFunctionRemoveUnusedServer(context)(context, + srv)) { /* * We could not remove the * server completely, remove @@ -823,7 +823,7 @@ SMBC_opendir_ctx(SMBCCTX *context, * will be removed when the * last file/dir is closed. */ - (context->cache.remove_cached_server_fn)(context, srv); + smbc_getFunctionRemoveCachedServer(context)(context, srv); } } @@ -884,7 +884,7 @@ smbc_readdir_internal(SMBCCTX * context, struct smbc_dirent *src, int max_namebuf_len) { - if (context->options.urlencode_readdir_entries) { + if (smbc_getOptionUrlEncodeReaddirEntries(context)) { /* url-encode the name. get back remaining buffer space */ max_namebuf_len = @@ -1142,7 +1142,7 @@ SMBC_mkdir_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1249,7 +1249,7 @@ SMBC_rmdir_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1531,7 +1531,7 @@ SMBC_chmod_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1637,7 +1637,7 @@ SMBC_utimes_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1713,7 +1713,7 @@ SMBC_unlink_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1848,7 +1848,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, } if (!user1 || user1[0] == (char)0) { - user1 = talloc_strdup(frame, ocontext->config.user); + user1 = talloc_strdup(frame, smbc_getUser(ocontext)); if (!user1) { errno = ENOMEM; TALLOC_FREE(frame); @@ -1872,7 +1872,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, } if (!user2 || user2[0] == (char)0) { - user2 = talloc_strdup(frame, ncontext->config.user); + user2 = talloc_strdup(frame, smbc_getUser(ncontext)); if (!user2) { errno = ENOMEM; TALLOC_FREE(frame); diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 73c9b96978..423450b23e 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -82,7 +82,7 @@ SMBC_open_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -188,7 +188,7 @@ SMBC_open_ctx(SMBCCTX *context, int eno = 0; eno = SMBC_errno(context, srv->cli); - file = (context->posix_emu.opendir_fn)(context, fname); + file = smbc_getFunctionOpendir(context)(context, fname); if (!file) errno = eno; TALLOC_FREE(frame); return file; @@ -439,7 +439,7 @@ SMBC_close_ctx(SMBCCTX *context, /* IS a dir ... */ if (!file->file) { TALLOC_FREE(frame); - return (context->posix_emu.closedir_fn)(context, file); + return smbc_getFunctionClosedir(context)(context, file); } /*d_printf(">>>close: parsing %s\n", file->fname);*/ @@ -478,7 +478,7 @@ SMBC_close_ctx(SMBCCTX *context, DLIST_REMOVE(context->internal->files, file); SAFE_FREE(file->fname); SAFE_FREE(file); - (context->server.remove_unused_server_fn)(context, srv); + smbc_getFunctionRemoveUnusedServer(context)(context, srv); TALLOC_FREE(frame); return -1; diff --git a/source3/libsmb/libsmb_path.c b/source3/libsmb/libsmb_path.c index c962f898e0..2c3a5f8866 100644 --- a/source3/libsmb/libsmb_path.c +++ b/source3/libsmb/libsmb_path.c @@ -253,7 +253,7 @@ SMBC_parse_path(TALLOC_CTX *ctx, */ if (pp_workgroup != NULL) { *pp_workgroup = - talloc_strdup(ctx, context->config.workgroup); + talloc_strdup(ctx, smbc_getWorkgroup(context)); } if (pp_options) { @@ -297,13 +297,13 @@ SMBC_parse_path(TALLOC_CTX *ctx, } if (*p == '/') { - int wl = strlen(context->config.workgroup); + int wl = strlen(smbc_getWorkgroup(context)); if (wl > 16) { wl = 16; } - *pp_server = talloc_strdup(ctx, context->config.workgroup); + *pp_server = talloc_strdup(ctx, smbc_getWorkgroup(context)); if (!*pp_server) { return -1; } diff --git a/source3/libsmb/libsmb_printjob.c b/source3/libsmb/libsmb_printjob.c index 545225cae4..c8d7ad039d 100644 --- a/source3/libsmb/libsmb_printjob.c +++ b/source3/libsmb/libsmb_printjob.c @@ -75,7 +75,7 @@ SMBC_open_print_job_ctx(SMBCCTX *context, /* What if the path is empty, or the file exists? */ TALLOC_FREE(frame); - return (context->posix_emu.open_fn)(context, fname, O_WRONLY, 666); + return smbc_getFunctionOpen(context)(context, fname, O_WRONLY, 666); } /* @@ -222,7 +222,7 @@ SMBC_list_print_jobs_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -300,7 +300,7 @@ SMBC_unlink_print_job_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 4f51388870..64eb1ea584 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -80,7 +80,7 @@ SMBC_remove_unused_server(SMBCCTX * context, DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); - (context->cache.remove_cached_server_fn)(context, srv); + smbc_getFunctionRemoveCachedServer(context)(context, srv); SAFE_FREE(srv); return 0; @@ -106,11 +106,10 @@ SMBC_call_auth_fn(TALLOC_CTX *ctx, strlcpy(username, *pp_username, sizeof(username)); strlcpy(password, *pp_password, sizeof(password)); - (context->server.get_auth_data_fn)( - server, share, - workgroup, sizeof(workgroup), - username, sizeof(username), - password, sizeof(password)); + smbc_getFunctionAuthData(context)(server, share, + workgroup, sizeof(workgroup), + username, sizeof(username), + password, sizeof(password)); TALLOC_FREE(*pp_workgroup); TALLOC_FREE(*pp_username); @@ -147,10 +146,10 @@ SMBC_find_server(TALLOC_CTX *ctx, check_server_cache: - srv = (context->cache.get_cached_server_fn)(context, - server, share, - *pp_workgroup, - *pp_username); + srv = smbc_getFunctionGetCachedServer(context)(context, + server, share, + *pp_workgroup, + *pp_username); if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] || !*pp_password || !(*pp_password)[0])) { @@ -172,22 +171,22 @@ check_server_cache: } if (srv) { - if ((context->server.check_server_fn)(context, srv)) { + if (smbc_getFunctionCheckServer(context)(context, srv)) { /* * This server is no good anymore * Try to remove it and check for more possible * servers in the cache */ - if ((context->server.remove_unused_server_fn)(context, - srv)) { + if (smbc_getFunctionRemoveUnusedServer(context)(context, + srv)) { /* * We could not remove the server completely, * remove it from the cache so we will not get * it again. It will be removed when the last * file/dir is closed. */ - (context->cache.remove_cached_server_fn)(context, - srv); + smbc_getFunctionRemoveCachedServer(context)(context, + srv); } /* @@ -251,12 +250,14 @@ SMBC_server(TALLOC_CTX *ctx, * If we found a connection and we're only allowed one share per * server... */ - if (srv && *share != '\0' && context->options.one_share_per_server) { + if (srv && + *share != '\0' && + smbc_getOptionOneSharePerServer(context)) { /* * ... then if there's no current connection to the share, * connect to it. SMBC_find_server(), or rather the function - * pointed to by context->cache.get_cached_srv_fn which + * pointed to by context->get_cached_srv_fn which * was called by SMBC_find_server(), will have issued a tree * disconnect if the requested share is not the same as the * one that was already connected. @@ -272,8 +273,8 @@ SMBC_server(TALLOC_CTX *ctx, errno = ENOMEM; cli_shutdown(srv->cli); srv->cli = NULL; - (context->cache.remove_cached_server_fn)(context, - srv); + smbc_getFunctionRemoveCachedServer(context)(context, + srv); return NULL; } @@ -290,8 +291,8 @@ SMBC_server(TALLOC_CTX *ctx, errno = SMBC_errno(context, srv->cli); cli_shutdown(srv->cli); srv->cli = NULL; - (context->cache.remove_cached_server_fn)(context, - srv); + smbc_getFunctionRemoveCachedServer(context)(context, + srv); srv = NULL; } @@ -324,7 +325,7 @@ SMBC_server(TALLOC_CTX *ctx, return NULL; } - make_nmb_name(&calling, context->config.netbios_name, 0x0); + make_nmb_name(&calling, smbc_getNetbiosName(context), 0x0); make_nmb_name(&called , server, 0x20); DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server)); @@ -341,14 +342,15 @@ again: return NULL; } - if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) { + if (smbc_getOptionUseKerberos(context)) { c->use_kerberos = True; } - if (context->flags.bits & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS) { + + if (smbc_getOptionFallbackAfterKerberos(context)) { c->fallback_after_kerberos = True; } - c->timeout = context->config.timeout; + c->timeout = smbc_getTimeout(context); /* * Force use of port 139 for first try if share is $IPC, empty, or @@ -435,8 +437,7 @@ again: /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; - if ((context->flags.bits & - SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON) || + if (smbc_getOptionNoAutoAnonymousLogin(context) || !NT_STATUS_IS_OK(cli_session_setup(c, username_used, *pp_password, 1, *pp_password, 0, @@ -504,10 +505,10 @@ again: /* now add it to the cache (internal or external) */ /* Let the cache function set errno if it wants to */ errno = 0; - if ((context->cache.add_cached_server_fn)(context, srv, - server, share, - *pp_workgroup, - *pp_username)) { + if (smbc_getFunctionAddCachedServer(context)(context, srv, + server, share, + *pp_workgroup, + *pp_username)) { int saved_errno = errno; DEBUG(3, (" Failed to add server to cache\n")); errno = saved_errno; @@ -576,7 +577,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, } flags = 0; - if (context->flags.bits & SMB_CTX_FLAG_USE_KERBEROS) { + if (smbc_getOptionUseKerberos(context)) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } @@ -664,11 +665,11 @@ SMBC_attr_server(TALLOC_CTX *ctx, /* now add it to the cache (internal or external) */ errno = 0; /* let cache function set errno if it likes */ - if ((context->cache.add_cached_server_fn)(context, ipc_srv, - server, - "*IPC$", - *pp_workgroup, - *pp_username)) { + if (smbc_getFunctionAddCachedServer(context)(context, ipc_srv, + server, + "*IPC$", + *pp_workgroup, + *pp_username)) { DEBUG(3, (" Failed to add server to cache\n")); if (errno == 0) { errno = ENOMEM; diff --git a/source3/libsmb/libsmb_setget.c b/source3/libsmb/libsmb_setget.c new file mode 100644 index 0000000000..d0823bd77e --- /dev/null +++ b/source3/libsmb/libsmb_setget.c @@ -0,0 +1,905 @@ +/* + Unix SMB/Netbios implementation. + SMB client library implementation + Copyright (C) Andrew Tridgell 1998 + Copyright (C) Richard Sharpe 2000, 2002 + Copyright (C) John Terpstra 2000 + Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Derrell Lipman 2003-2008 + Copyright (C) Jeremy Allison 2007, 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" +#define __LIBSMBCLIENT_INTERNAL__ +#include "libsmbclient.h" +#include "libsmb_internal.h" + + +/** Get the netbios name used for making connections */ +char * +smbc_getNetbiosName(SMBCCTX *c) +{ + return c->netbios_name; +} + +/** Set the netbios name used for making connections */ +void +smbc_setNetbiosName(SMBCCTX *c, char * netbios_name) +{ + c->netbios_name = netbios_name; +} + +/** Get the workgroup used for making connections */ +char * +smbc_getWorkgroup(SMBCCTX *c) +{ + return c->workgroup; +} + +/** Set the workgroup used for making connections */ +void +smbc_setWorkgroup(SMBCCTX *c, char * workgroup) +{ + c->workgroup = workgroup; +} + +/** Get the username used for making connections */ +char * +smbc_getUser(SMBCCTX *c) +{ + return c->user; +} + +/** Set the username used for making connections */ +void +smbc_setUser(SMBCCTX *c, char * user) +{ + c->user = user; +} + +/** Get the debug level */ +int +smbc_getDebug(SMBCCTX *c) +{ + return c->debug; +} + +/** Set the debug level */ +void +smbc_setDebug(SMBCCTX *c, int debug) +{ + c->debug = debug; + DEBUGLEVEL = debug; +} + +/** + * Get the timeout used for waiting on connections and response data + * (in milliseconds) + */ +int +smbc_getTimeout(SMBCCTX *c) +{ + return c->timeout; +} + +/** + * Set the timeout used for waiting on connections and response data + * (in milliseconds) + */ +void +smbc_setTimeout(SMBCCTX *c, int timeout) +{ + c->timeout = timeout; +} + +/** Get whether to log to standard error instead of standard output */ +smbc_bool +smbc_getOptionDebugToStderr(SMBCCTX *c) +{ + return c->internal->debug_stderr; +} + +/** Set whether to log to standard error instead of standard output */ +void +smbc_setOptionDebugToStderr(SMBCCTX *c, smbc_bool b) +{ + c->internal->debug_stderr = b; +} + +/** + * Get whether to use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also setting/getting + * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME + * was supposed to be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +smbc_bool +smbc_getOptionFullTimeNames(SMBCCTX *c) +{ + return c->internal->full_time_names; +} + +/** + * Set whether to use new-style time attribute names, e.g. WRITE_TIME rather + * than the old-style names such as M_TIME. This allows also setting/getting + * CREATE_TIME which was previously unimplemented. (Note that the old C_TIME + * was supposed to be CHANGE_TIME but was confused and sometimes referred to + * CREATE_TIME.) + */ +void +smbc_setOptionFullTimeNames(SMBCCTX *c, smbc_bool b) +{ + c->internal->full_time_names = b; +} + +/** + * Get the share mode to use for files opened with SMBC_open_ctx(). The + * default is SMBC_SHAREMODE_DENY_NONE. + */ +smbc_share_mode +smbc_getOptionOpenShareMode(SMBCCTX *c) +{ + return c->internal->share_mode; +} + +/** + * Set the share mode to use for files opened with SMBC_open_ctx(). The + * default is SMBC_SHAREMODE_DENY_NONE. + */ +void +smbc_setOptionOpenShareMode(SMBCCTX *c, smbc_share_mode share_mode) +{ + c->internal->share_mode = share_mode; +} + +/** Retrieve a previously set user data handle */ +void * +smbc_getOptionUserData(SMBCCTX *c) +{ + return c->internal->user_data; +} + +/** Save a user data handle */ +void +smbc_setOptionUserData(SMBCCTX *c, void *user_data) +{ + c->internal->user_data = user_data; +} + +/** Get the encoded value for encryption level. */ +smbc_smb_encrypt_level +smbc_getOptionSmbEncryptionLevel(SMBCCTX *c) +{ + return c->internal->smb_encryption_level; +} + +/** Set the encoded value for encryption level. */ +void +smbc_setOptionSmbEncryptionLevel(SMBCCTX *c, smbc_smb_encrypt_level level) +{ + c->internal->smb_encryption_level = level; +} + +/** + * Get from how many local master browsers should the list of workgroups be + * retrieved. It can take up to 12 minutes or longer after a server becomes a + * local master browser, for it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client never knows + * which local master browser will be found first, the one which is found + * first and used to retrieve a browse list may have an incomplete or empty + * browse list. By requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small networks (few + * workgroups), it is recommended that this value be set to 0, causing the + * browse lists from all found local master browsers to be retrieved and + * merged. For networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +int +smbc_getOptionBrowseMaxLmbCount(SMBCCTX *c) +{ + return c->options.browse_max_lmb_count; +} + +/** + * Set from how many local master browsers should the list of workgroups be + * retrieved. It can take up to 12 minutes or longer after a server becomes a + * local master browser, for it to have the entire browse list (the list of + * workgroups/domains) from an entire network. Since a client never knows + * which local master browser will be found first, the one which is found + * first and used to retrieve a browse list may have an incomplete or empty + * browse list. By requesting the browse list from multiple local master + * browsers, a more complete list can be generated. For small networks (few + * workgroups), it is recommended that this value be set to 0, causing the + * browse lists from all found local master browsers to be retrieved and + * merged. For networks with many workgroups, a suitable value for this + * variable is probably somewhere around 3. (Default: 3). + */ +void +smbc_setOptionBrowseMaxLmbCount(SMBCCTX *c, int count) +{ + c->options.browse_max_lmb_count = count; +} + +/** + * Get whether to url-encode readdir entries. + * + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +smbc_bool +smbc_getOptionUrlEncodeReaddirEntries(SMBCCTX *c) +{ + return c->options.urlencode_readdir_entries; +} + +/** + * Set whether to url-encode readdir entries. + * + * There is a difference in the desired return strings from + * smbc_readdir() depending upon whether the filenames are to + * be displayed to the user, or whether they are to be + * appended to the path name passed to smbc_opendir() to call + * a further smbc_ function (e.g. open the file with + * smbc_open()). In the former case, the filename should be + * in "human readable" form. In the latter case, the smbc_ + * functions expect a URL which must be url-encoded. Those + * functions decode the URL. If, for example, smbc_readdir() + * returned a file name of "abc%20def.txt", passing a path + * with this file name attached to smbc_open() would cause + * smbc_open to attempt to open the file "abc def.txt" since + * the %20 is decoded into a space. + * + * Set this option to True if the names returned by + * smbc_readdir() should be url-encoded such that they can be + * passed back to another smbc_ call. Set it to False if the + * names returned by smbc_readdir() are to be presented to the + * user. + * + * For backwards compatibility, this option defaults to False. + */ +void +smbc_setOptionUrlEncodeReaddirEntries(SMBCCTX *c, smbc_bool b) +{ + c->options.urlencode_readdir_entries = b; +} + +/** + * Get whether to use the same connection for all shares on a server. + * + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +smbc_bool +smbc_getOptionOneSharePerServer(SMBCCTX *c) +{ + return c->options.one_share_per_server; +} + +/** + * Set whether to use the same connection for all shares on a server. + * + * Some Windows versions appear to have a limit to the number + * of concurrent SESSIONs and/or TREE CONNECTions. In + * one-shot programs (i.e. the program runs and then quickly + * ends, thereby shutting down all connections), it is + * probably reasonable to establish a new connection for each + * share. In long-running applications, the limitation can be + * avoided by using only a single connection to each server, + * and issuing a new TREE CONNECT when the share is accessed. + */ +void +smbc_setOptionOneSharePerServer(SMBCCTX *c, smbc_bool b) +{ + c->options.one_share_per_server = b; +} + +/** Get whether to enable use of kerberos */ +smbc_bool +smbc_getOptionUseKerberos(SMBCCTX *c) +{ + return c->flags & SMB_CTX_FLAG_USE_KERBEROS ? True : False; +} + +/** Set whether to enable use of kerberos */ +void +smbc_setOptionUseKerberos(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags |= SMB_CTX_FLAG_USE_KERBEROS; + } else { + c->flags &= ~SMB_CTX_FLAG_USE_KERBEROS; + } +} + +/** Get whether to fallback after kerberos */ +smbc_bool +smbc_getOptionFallbackAfterKerberos(SMBCCTX *c) +{ + return c->flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS ? True : False; +} + +/** Set whether to fallback after kerberos */ +void +smbc_setOptionFallbackAfterKerberos(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags |= SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + } else { + c->flags &= ~SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS; + } +} + +/** Get whether to automatically select anonymous login */ +smbc_bool +smbc_getOptionNoAutoAnonymousLogin(SMBCCTX *c) +{ + return c->flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON ? True : False; +} + +/** Set whether to automatically select anonymous login */ +void +smbc_setOptionNoAutoAnonymousLogin(SMBCCTX *c, smbc_bool b) +{ + if (b) { + c->flags |= SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; + } else { + c->flags &= ~SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON; + } +} + +/** Get the function for obtaining authentication data */ +smbc_get_auth_data_fn +smbc_getFunctionAuthData(SMBCCTX *c) +{ + return c->callbacks.auth_fn; +} + +/** Set the function for obtaining authentication data */ +void +smbc_setFunctionAuthData(SMBCCTX *c, smbc_get_auth_data_fn fn) +{ + c->internal->auth_fn_with_context = NULL; + c->callbacks.auth_fn = fn; +} + +/** Get the new-style authentication function which includes the context. */ +smbc_get_auth_data_with_context_fn +smbc_getFunctionAuthDataWithContext(SMBCCTX *c) +{ + return c->internal->auth_fn_with_context; +} + +/** Set the new-style authentication function which includes the context. */ +void +smbc_setFunctionAuthDataWithContext(SMBCCTX *c, + smbc_get_auth_data_with_context_fn fn) +{ + c->callbacks.auth_fn = NULL; + c->internal->auth_fn_with_context = fn; +} + +/** Get the function for checking if a server is still good */ +smbc_check_server_fn +smbc_getFunctionCheckServer(SMBCCTX *c) +{ + return c->callbacks.check_server_fn; +} + +/** Set the function for checking if a server is still good */ +void +smbc_setFunctionCheckServer(SMBCCTX *c, smbc_check_server_fn fn) +{ + c->callbacks.check_server_fn = fn; +} + +/** Get the function for removing a server if unused */ +smbc_remove_unused_server_fn +smbc_getFunctionRemoveUnusedServer(SMBCCTX *c) +{ + return c->callbacks.remove_unused_server_fn; +} + +/** Set the function for removing a server if unused */ +void +smbc_setFunctionRemoveUnusedServer(SMBCCTX *c, + smbc_remove_unused_server_fn fn) +{ + c->callbacks.remove_unused_server_fn = fn; +} + +/** Get the function for adding a cached server */ +smbc_add_cached_srv_fn +smbc_getFunctionAddCachedServer(SMBCCTX *c) +{ + return c->callbacks.add_cached_srv_fn; +} + +/** Set the function for adding a cached server */ +void +smbc_setFunctionAddCachedServer(SMBCCTX *c, smbc_add_cached_srv_fn fn) +{ + c->callbacks.add_cached_srv_fn = fn; +} + +/** Get the function for server cache lookup */ +smbc_get_cached_srv_fn +smbc_getFunctionGetCachedServer(SMBCCTX *c) +{ + return c->callbacks.get_cached_srv_fn; +} + +/** Set the function for server cache lookup */ +void +smbc_setFunctionGetCachedServer(SMBCCTX *c, smbc_get_cached_srv_fn fn) +{ + c->callbacks.get_cached_srv_fn = fn; +} + +/** Get the function for server cache removal */ +smbc_remove_cached_srv_fn +smbc_getFunctionRemoveCachedServer(SMBCCTX *c) +{ + return c->callbacks.remove_cached_srv_fn; +} + +/** Set the function for server cache removal */ +void +smbc_setFunctionRemoveCachedServer(SMBCCTX *c, + smbc_remove_cached_srv_fn fn) +{ + c->callbacks.remove_cached_srv_fn = fn; +} + +/** + * Get the function for server cache purging. This function tries to + * remove all cached servers (e.g. on disconnect) + */ +smbc_purge_cached_fn +smbc_getFunctionPurgeCachedServers(SMBCCTX *c) +{ + return c->callbacks.purge_cached_fn; +} + +/** Set the function to store private data of the server cache */ +void smbc_setServerCacheData(SMBCCTX *c, struct smbc_server_cache * cache) +{ + c->internal->server_cache = cache; +} + +/** Get the function to store private data of the server cache */ +struct smbc_server_cache * smbc_getServerCacheData(SMBCCTX *c) +{ + return c->internal->server_cache; +} + + +/** + * Set the function for server cache purging. This function tries to + * remove all cached servers (e.g. on disconnect) + */ +void +smbc_setFunctionPurgeCachedServers(SMBCCTX *c, smbc_purge_cached_fn fn) +{ + c->callbacks.purge_cached_fn = fn; +} + +/** + * Callable functions for files. + */ + +smbc_open_fn +smbc_getFunctionOpen(SMBCCTX *c) +{ + return c->open; +} + +void +smbc_setFunctionOpen(SMBCCTX *c, smbc_open_fn fn) +{ + c->open = fn; +} + +smbc_creat_fn +smbc_getFunctionCreat(SMBCCTX *c) +{ + return c->creat; +} + +void +smbc_setFunctionCreat(SMBCCTX *c, smbc_creat_fn fn) +{ + c->creat = fn; +} + +smbc_read_fn +smbc_getFunctionRead(SMBCCTX *c) +{ + return c->read; +} + +void +smbc_setFunctionRead(SMBCCTX *c, smbc_read_fn fn) +{ + c->read = fn; +} + +smbc_write_fn +smbc_getFunctionWrite(SMBCCTX *c) +{ + return c->write; +} + +void +smbc_setFunctionWrite(SMBCCTX *c, smbc_write_fn fn) +{ + c->write = fn; +} + +smbc_unlink_fn +smbc_getFunctionUnlink(SMBCCTX *c) +{ + return c->unlink; +} + +void +smbc_setFunctionUnlink(SMBCCTX *c, smbc_unlink_fn fn) +{ + c->unlink = fn; +} + +smbc_rename_fn +smbc_getFunctionRename(SMBCCTX *c) +{ + return c->rename; +} + +void +smbc_setFunctionRename(SMBCCTX *c, smbc_rename_fn fn) +{ + c->rename = fn; +} + +smbc_lseek_fn +smbc_getFunctionLseek(SMBCCTX *c) +{ + return c->lseek; +} + +void +smbc_setFunctionLseek(SMBCCTX *c, smbc_lseek_fn fn) +{ + c->lseek = fn; +} + +smbc_stat_fn +smbc_getFunctionStat(SMBCCTX *c) +{ + return c->stat; +} + +void +smbc_setFunctionStat(SMBCCTX *c, smbc_stat_fn fn) +{ + c->stat = fn; +} + +smbc_fstat_fn +smbc_getFunctionFstat(SMBCCTX *c) +{ + return c->fstat; +} + +void +smbc_setFunctionFstat(SMBCCTX *c, smbc_fstat_fn fn) +{ + c->fstat = fn; +} + +smbc_ftruncate_fn +smbc_getFunctionFtruncate(SMBCCTX *c) +{ + return c->internal->posix_emu.ftruncate_fn; +} + +void +smbc_setFunctionFtruncate(SMBCCTX *c, smbc_ftruncate_fn fn) +{ + c->internal->posix_emu.ftruncate_fn = fn; +} + +smbc_close_fn +smbc_getFunctionClose(SMBCCTX *c) +{ + return c->close_fn; +} + +void +smbc_setFunctionClose(SMBCCTX *c, smbc_close_fn fn) +{ + c->close_fn = fn; +} + + +/** + * Callable functions for directories. + */ + +smbc_opendir_fn +smbc_getFunctionOpendir(SMBCCTX *c) +{ + return c->opendir; +} + +void +smbc_setFunctionOpendir(SMBCCTX *c, smbc_opendir_fn fn) +{ + c->opendir = fn; +} + +smbc_closedir_fn +smbc_getFunctionClosedir(SMBCCTX *c) +{ + return c->closedir; +} + +void +smbc_setFunctionClosedir(SMBCCTX *c, smbc_closedir_fn fn) +{ + c->closedir = fn; +} + +smbc_readdir_fn +smbc_getFunctionReaddir(SMBCCTX *c) +{ + return c->readdir; +} + +void +smbc_setFunctionReaddir(SMBCCTX *c, smbc_readdir_fn fn) +{ + c->readdir = fn; +} + +smbc_getdents_fn +smbc_getFunctionGetdents(SMBCCTX *c) +{ + return c->getdents; +} + +void +smbc_setFunctionGetdents(SMBCCTX *c, smbc_getdents_fn fn) +{ + c->getdents = fn; +} + +smbc_mkdir_fn +smbc_getFunctionMkdir(SMBCCTX *c) +{ + return c->mkdir; +} + +void +smbc_setFunctionMkdir(SMBCCTX *c, smbc_mkdir_fn fn) +{ + c->mkdir = fn; +} + +smbc_rmdir_fn +smbc_getFunctionRmdir(SMBCCTX *c) +{ + return c->rmdir; +} + +void +smbc_setFunctionRmdir(SMBCCTX *c, smbc_rmdir_fn fn) +{ + c->rmdir = fn; +} + +smbc_telldir_fn +smbc_getFunctionTelldir(SMBCCTX *c) +{ + return c->telldir; +} + +void +smbc_setFunctionTelldir(SMBCCTX *c, smbc_telldir_fn fn) +{ + c->telldir = fn; +} + +smbc_lseekdir_fn +smbc_getFunctionLseekdir(SMBCCTX *c) +{ + return c->lseekdir; +} + +void +smbc_setFunctionLseekdir(SMBCCTX *c, smbc_lseekdir_fn fn) +{ + c->lseekdir = fn; +} + +smbc_fstatdir_fn +smbc_getFunctionFstatdir(SMBCCTX *c) +{ + return c->fstatdir; +} + +void +smbc_setFunctionFstatdir(SMBCCTX *c, smbc_fstatdir_fn fn) +{ + c->fstatdir = fn; +} + + +/** + * Callable functions applicable to both files and directories. + */ + +smbc_chmod_fn +smbc_getFunctionChmod(SMBCCTX *c) +{ + return c->chmod; +} + +void +smbc_setFunctionChmod(SMBCCTX *c, smbc_chmod_fn fn) +{ + c->chmod = fn; +} + +smbc_utimes_fn +smbc_getFunctionUtimes(SMBCCTX *c) +{ + return c->utimes; +} + +void +smbc_setFunctionUtimes(SMBCCTX *c, smbc_utimes_fn fn) +{ + c->utimes = fn; +} + +smbc_setxattr_fn +smbc_getFunctionSetxattr(SMBCCTX *c) +{ + return c->setxattr; +} + +void +smbc_setFunctionSetxattr(SMBCCTX *c, smbc_setxattr_fn fn) +{ + c->setxattr = fn; +} + +smbc_getxattr_fn +smbc_getFunctionGetxattr(SMBCCTX *c) +{ + return c->getxattr; +} + +void +smbc_setFunctionGetxattr(SMBCCTX *c, smbc_getxattr_fn fn) +{ + c->getxattr = fn; +} + +smbc_removexattr_fn +smbc_getFunctionRemovexattr(SMBCCTX *c) +{ + return c->removexattr; +} + +void +smbc_setFunctionRemovexattr(SMBCCTX *c, smbc_removexattr_fn fn) +{ + c->removexattr = fn; +} + +smbc_listxattr_fn +smbc_getFunctionListxattr(SMBCCTX *c) +{ + return c->listxattr; +} + +void +smbc_setFunctionListxattr(SMBCCTX *c, smbc_listxattr_fn fn) +{ + c->listxattr = fn; +} + + +/** + * Callable functions related to printing + */ + +smbc_print_file_fn +smbc_getFunctionPrintFile(SMBCCTX *c) +{ + return c->print_file; +} + +void +smbc_setFunctionPrintFile(SMBCCTX *c, smbc_print_file_fn fn) +{ + c->print_file = fn; +} + +smbc_open_print_job_fn +smbc_getFunctionOpenPrintJob(SMBCCTX *c) +{ + return c->open_print_job; +} + +void +smbc_setFunctionOpenPrintJob(SMBCCTX *c, + smbc_open_print_job_fn fn) +{ + c->open_print_job = fn; +} + +smbc_list_print_jobs_fn +smbc_getFunctionListPrintJobs(SMBCCTX *c) +{ + return c->list_print_jobs; +} + +void +smbc_setFunctionListPrintJobs(SMBCCTX *c, + smbc_list_print_jobs_fn fn) +{ + c->list_print_jobs = fn; +} + +smbc_unlink_print_job_fn +smbc_getFunctionUnlinkPrintJob(SMBCCTX *c) +{ + return c->unlink_print_job; +} + +void +smbc_setFunctionUnlinkPrintJob(SMBCCTX *c, + smbc_unlink_print_job_fn fn) +{ + c->unlink_print_job = fn; +} + diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index b733eab74f..27546f687e 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -157,7 +157,7 @@ SMBC_stat_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame,context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -237,7 +237,7 @@ SMBC_fstat_ctx(SMBCCTX *context, if (!file->file) { TALLOC_FREE(frame); - return (context->posix_emu.fstatdir_fn)(context, file, st); + return smbc_getFunctionFstatdir(context)(context, file, st); } /*d_printf(">>>fstat: parsing %s\n", file->fname);*/ diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index 3c08412d59..e17146e611 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -1729,7 +1729,7 @@ SMBC_setxattr_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -2023,7 +2023,7 @@ SMBC_getxattr_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); @@ -2157,7 +2157,7 @@ SMBC_removexattr_ctx(SMBCCTX *context, } if (!user || user[0] == (char)0) { - user = talloc_strdup(frame, context->config.user); + user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { errno = ENOMEM; TALLOC_FREE(frame); -- cgit From e82c9d1c319c216bbb108b16456df03ae2ad6e97 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 6 Mar 2008 11:27:49 +0100 Subject: Check the right pointer for non-NULL Fix Coverity ID 558, 559 (This used to be commit 8e33d19d93ef57a9438aad085aaf04b7c09fe09b) --- source3/libsmb/clidfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 16582f8049..971cde1252 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -1054,7 +1054,7 @@ static bool cli_check_msdfs_proxy(TALLOC_CTX *ctx, split_dfs_path(ctx, refs[0].dfspath, pp_newserver, pp_newshare, &newextrapath ); - if (!pp_newserver || !pp_newshare) { + if ((*pp_newserver == NULL) || (*pp_newshare == NULL)) { return false; } -- cgit From 1ea0a5d0cdaf9cbc1d1a5c0720ae466f07cea816 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 14:41:25 +0100 Subject: Add infrastructure to support async SMB requests (This used to be commit e2153301351559f30f2714345f4c1ca6c5f1a45f) --- source3/libsmb/async_smb.c | 483 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 483 insertions(+) create mode 100644 source3/libsmb/async_smb.c (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c new file mode 100644 index 0000000000..21bcd5b9b1 --- /dev/null +++ b/source3/libsmb/async_smb.c @@ -0,0 +1,483 @@ +/* + Unix SMB/CIFS implementation. + Infrastructure for async SMB client requests + Copyright (C) Volker Lendecke 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "includes.h" + +/* + * Fetch an error out of a NBT packet + */ + +NTSTATUS cli_pull_error(char *buf) +{ + uint32_t flags2 = SVAL(buf, smb_flg2); + + if (flags2 & FLAGS2_32_BIT_ERROR_CODES) { + return NT_STATUS(IVAL(buf, smb_rcls)); + } + + return NT_STATUS_DOS(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); +} + +/* + * Compatibility helper for the sync APIs: Fake NTSTATUS in cli->inbuf + */ + +void cli_set_error(struct cli_state *cli, NTSTATUS status) +{ + uint32_t flags2 = SVAL(cli->inbuf, smb_flg2); + + if (NT_STATUS_IS_DOS(status)) { + SSVAL(cli->inbuf, smb_flg2, + flags2 & ~FLAGS2_32_BIT_ERROR_CODES); + SCVAL(cli->inbuf, smb_rcls, NT_STATUS_DOS_CLASS(status)); + SSVAL(cli->inbuf, smb_err, NT_STATUS_DOS_CODE(status)); + return; + } + + SSVAL(cli->inbuf, smb_flg2, flags2 | FLAGS2_32_BIT_ERROR_CODES); + SIVAL(cli->inbuf, smb_rcls, NT_STATUS_V(status)); + return; +} + +/* + * Allocate a new mid + */ + +static uint16_t cli_new_mid(struct cli_state *cli) +{ + uint16_t result; + struct cli_request *req; + + while (true) { + result = cli->mid++; + if (result == 0) { + continue; + } + + for (req = cli->outstanding_requests; req; req = req->next) { + if (result == req->mid) { + break; + } + } + + if (req == NULL) { + return result; + } + } +} + +static char *cli_request_print(TALLOC_CTX *mem_ctx, struct async_req *req) +{ + char *result = async_req_print(mem_ctx, req); + struct cli_request *cli_req = cli_request_get(req); + + if (result == NULL) { + return NULL; + } + + return talloc_asprintf_append_buffer( + result, "mid=%d\n", cli_req->mid); +} + +static int cli_request_destructor(struct cli_request *req) +{ + if (req->enc_state != NULL) { + common_free_enc_buffer(req->enc_state, req->outbuf); + } + DLIST_REMOVE(req->cli->outstanding_requests, req); + return 0; +} + +/* + * Create a fresh async smb request + */ + +struct async_req *cli_request_new(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint8_t num_words, size_t num_bytes, + struct cli_request **preq) +{ + struct async_req *result; + struct cli_request *cli_req; + size_t bufsize = smb_size + num_words * 2 + num_bytes; + + result = async_req_new(mem_ctx, ev); + if (result == NULL) { + return NULL; + } + + cli_req = (struct cli_request *)talloc_size( + result, sizeof(*cli_req) + bufsize); + if (cli_req == NULL) { + TALLOC_FREE(result); + return NULL; + } + talloc_set_name_const(cli_req, "struct cli_request"); + result->private_data = cli_req; + result->print = cli_request_print; + + cli_req->async = result; + cli_req->cli = cli; + cli_req->outbuf = ((char *)cli_req + sizeof(*cli_req)); + cli_req->sent = 0; + cli_req->mid = cli_new_mid(cli); + cli_req->inbuf = NULL; + cli_req->enc_state = NULL; + + SCVAL(cli_req->outbuf, smb_wct, num_words); + SSVAL(cli_req->outbuf, smb_vwv + num_words * 2, num_bytes); + + DLIST_ADD_END(cli->outstanding_requests, cli_req, + struct cli_request *); + talloc_set_destructor(cli_req, cli_request_destructor); + + DEBUG(10, ("cli_request_new: mid=%d\n", cli_req->mid)); + + *preq = cli_req; + return result; +} + +/* + * Convenience function to get the SMB part out of an async_req + */ + +struct cli_request *cli_request_get(struct async_req *req) +{ + if (req == NULL) { + return NULL; + } + return talloc_get_type_abort(req->private_data, struct cli_request); +} + +/* + * A PDU has arrived on cli->evt_inbuf + */ + +static void handle_incoming_pdu(struct cli_state *cli) +{ + struct cli_request *req; + uint16_t mid; + size_t raw_pdu_len, buf_len, pdu_len; + size_t rest_len; + NTSTATUS status; + + /* + * The encrypted PDU len might differ from the unencrypted one + */ + raw_pdu_len = smb_len(cli->evt_inbuf) + 4; + + /* + * TODO: Handle oplock break requests + */ + + if (cli_encryption_on(cli) && CVAL(cli->evt_inbuf, 0) == 0) { + uint16_t enc_ctx_num; + + status = get_enc_ctx_num((uint8_t *)cli->evt_inbuf, + &enc_ctx_num); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("get_enc_ctx_num returned %s\n", + nt_errstr(status))); + goto invalidate_requests; + } + + if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { + DEBUG(10, ("wrong enc_ctx %d, expected %d\n", + enc_ctx_num, + cli->trans_enc_state->enc_ctx_num)); + status = NT_STATUS_INVALID_HANDLE; + goto invalidate_requests; + } + + status = common_decrypt_buffer(cli->trans_enc_state, + cli->evt_inbuf); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("common_decrypt_buffer returned %s\n", + nt_errstr(status))); + goto invalidate_requests; + } + } + + if (!cli_check_sign_mac(cli, cli->evt_inbuf)) { + DEBUG(10, ("cli_check_sign_mac failed\n")); + status = NT_STATUS_ACCESS_DENIED; + goto invalidate_requests; + } + + mid = SVAL(cli->evt_inbuf, smb_mid); + + DEBUG(10, ("handle_incoming_pdu: got mid %d\n", mid)); + + for (req = cli->outstanding_requests; req; req = req->next) { + if (req->mid == mid) { + break; + } + } + + buf_len = talloc_get_size(cli->evt_inbuf); + pdu_len = smb_len(cli->evt_inbuf) + 4; + rest_len = buf_len - raw_pdu_len; + + if (req == NULL) { + DEBUG(3, ("Request for mid %d not found, dumping PDU\n", mid)); + + memmove(cli->evt_inbuf, cli->evt_inbuf + raw_pdu_len, + buf_len - raw_pdu_len); + + cli->evt_inbuf = TALLOC_REALLOC_ARRAY(NULL, cli->evt_inbuf, + char, rest_len); + return; + } + + if (buf_len == pdu_len) { + /* + * Optimal case: Exactly one PDU was in the socket buffer + */ + req->inbuf = talloc_move(req, &cli->evt_inbuf); + goto done; + } + + DEBUG(11, ("buf_len = %d, pdu_len = %d, splitting buffer\n", + (int)buf_len, (int)pdu_len)); + + if (pdu_len < rest_len) { + /* + * The PDU is shorter, talloc_memdup that one. + */ + req->inbuf = (char *)talloc_memdup( + req, cli->evt_inbuf, pdu_len); + + memmove(cli->evt_inbuf, + cli->evt_inbuf + raw_pdu_len, + buf_len - raw_pdu_len); + + cli->evt_inbuf = TALLOC_REALLOC_ARRAY( + NULL, cli->evt_inbuf, char, rest_len); + } + else { + /* + * The PDU is larger than the rest, + * talloc_memdup the rest + */ + req->inbuf = talloc_move(req, &cli->evt_inbuf); + + cli->evt_inbuf = (char *)talloc_memdup( + cli, req->inbuf + raw_pdu_len, + rest_len); + } + + if ((req->inbuf == NULL) || (cli->evt_inbuf == NULL)) { + status = NT_STATUS_NO_MEMORY; + goto invalidate_requests; + } + + done: + async_req_done(req->async); + return; + + invalidate_requests: + + DEBUG(10, ("handle_incoming_pdu: Aborting with %s\n", + nt_errstr(status))); + + for (req = cli->outstanding_requests; req; req = req->next) { + async_req_error(req->async, status); + } + return; +} + +/* + * fd event callback. This is the basic connection to the socket + */ + +static void cli_state_handler(struct event_context *event_ctx, + struct fd_event *event, uint16 flags, void *p) +{ + struct cli_state *cli = (struct cli_state *)p; + struct cli_request *req; + + DEBUG(11, ("cli_state_handler called with flags %d\n", flags)); + + if (flags & EVENT_FD_READ) { + int res, available; + size_t old_size, new_size; + char *tmp; + + res = ioctl(cli->fd, FIONREAD, &available); + if (res == -1) { + DEBUG(10, ("ioctl(FIONREAD) failed: %s\n", + strerror(errno))); + goto sock_error; + } + + if (available == 0) { + /* EOF */ + goto sock_error; + } + + old_size = talloc_get_size(cli->evt_inbuf); + new_size = old_size + available; + + if (new_size < old_size) { + /* wrap */ + goto sock_error; + } + + tmp = TALLOC_REALLOC_ARRAY(cli, cli->evt_inbuf, char, + new_size); + if (tmp == NULL) { + /* nomem */ + goto sock_error; + } + cli->evt_inbuf = tmp; + + res = recv(cli->fd, cli->evt_inbuf + old_size, available, 0); + if (res == -1) { + DEBUG(10, ("recv failed: %s\n", strerror(errno))); + goto sock_error; + } + + DEBUG(11, ("cli_state_handler: received %d bytes, " + "smb_len(evt_inbuf) = %d\n", (int)res, + smb_len(cli->evt_inbuf))); + + /* recv *might* have returned less than announced */ + new_size = old_size + res; + + /* shrink, so I don't expect errors here */ + cli->evt_inbuf = TALLOC_REALLOC_ARRAY(cli, cli->evt_inbuf, + char, new_size); + + while ((cli->evt_inbuf != NULL) + && ((smb_len(cli->evt_inbuf) + 4) <= new_size)) { + /* + * we've got a complete NBT level PDU in evt_inbuf + */ + handle_incoming_pdu(cli); + new_size = talloc_get_size(cli->evt_inbuf); + } + } + + if (flags & EVENT_FD_WRITE) { + size_t to_send; + ssize_t sent; + + for (req = cli->outstanding_requests; req; req = req->next) { + to_send = smb_len(req->outbuf)+4; + if (to_send > req->sent) { + break; + } + } + + if (req == NULL) { + event_fd_set_not_writeable(event); + return; + } + + sent = send(cli->fd, req->outbuf + req->sent, + to_send - req->sent, 0); + + if (sent < 0) { + goto sock_error; + } + + req->sent += sent; + + if (req->sent == to_send) { + return; + } + } + return; + + sock_error: + for (req = cli->outstanding_requests; req; req = req->next) { + req->async->state = ASYNC_REQ_ERROR; + req->async->status = map_nt_error_from_unix(errno); + } + TALLOC_FREE(cli->fd_event); + close(cli->fd); + cli->fd = -1; +} + +/* + * Holder for a talloc_destructor, we need to zero out the pointers in cli + * when deleting + */ +struct cli_tmp_event { + struct cli_state *cli; +}; + +static int cli_tmp_event_destructor(struct cli_tmp_event *e) +{ + TALLOC_FREE(e->cli->fd_event); + TALLOC_FREE(e->cli->event_ctx); + return 0; +} + +/* + * Create a temporary event context for use in the sync helper functions + */ + +struct cli_tmp_event *cli_tmp_event_ctx(TALLOC_CTX *mem_ctx, + struct cli_state *cli) +{ + struct cli_tmp_event *state; + + if (cli->event_ctx != NULL) { + return NULL; + } + + state = talloc(mem_ctx, struct cli_tmp_event); + if (state == NULL) { + return NULL; + } + state->cli = cli; + talloc_set_destructor(state, cli_tmp_event_destructor); + + cli->event_ctx = event_context_init(state); + if (cli->event_ctx == NULL) { + TALLOC_FREE(state); + return NULL; + } + + cli->fd_event = event_add_fd(cli->event_ctx, state, cli->fd, + EVENT_FD_READ, cli_state_handler, cli); + if (cli->fd_event == NULL) { + TALLOC_FREE(state); + return NULL; + } + return state; +} + +/* + * Attach an event context permanently to a cli_struct + */ + +NTSTATUS cli_add_event_ctx(struct cli_state *cli, + struct event_context *event_ctx) +{ + cli->event_ctx = event_ctx; + cli->fd_event = event_add_fd(event_ctx, cli, cli->fd, EVENT_FD_READ, + cli_state_handler, cli); + if (cli->fd_event == NULL) { + return NT_STATUS_NO_MEMORY; + } + return NT_STATUS_OK; +} -- cgit From 62445788350b2f174537d877d721d92147f93ec7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 15:21:33 +0100 Subject: Add async cli_pull support This is the big (and potentially controversial) one. It took a phone call to explain to metze what is going on inside cli_pull_read_done, but I would really like everybody to understand this function. It is a very good and reasonably complex example of async programming. If we want more asynchronism in s3, this is what we will have to deal with :-) Make use of it in the smbclient "get" command. Volker (This used to be commit 76f9b360ee1d973630d82d401eeddce858189301) --- source3/libsmb/clireadwrite.c | 425 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index af13ed8f73..5aee8f18bd 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -19,6 +19,431 @@ #include "includes.h" +/**************************************************************************** + Calculate the recommended read buffer size +****************************************************************************/ +static size_t cli_read_max_bufsize(struct cli_state *cli) +{ + if (!client_is_signing_on(cli) && !cli_encryption_on(cli) == false + && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { + return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; + } + if (cli->capabilities & CAP_LARGE_READX) { + return cli->is_samba + ? CLI_SAMBA_MAX_LARGE_READX_SIZE + : CLI_WINDOWS_MAX_LARGE_READX_SIZE; + } + return (cli->max_xmit - (smb_size+32)) & ~1023; +} + +/* + * Send a read&x request + */ + +struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, + struct cli_state *cli, int fnum, + off_t offset, size_t size) +{ + struct async_req *result; + struct cli_request *req; + bool bigoffset = False; + char *enc_buf; + + if (size > cli_read_max_bufsize(cli)) { + DEBUG(0, ("cli_read_andx_send got size=%d, can only handle " + "size=%d\n", (int)size, + (int)cli_read_max_bufsize(cli))); + return NULL; + } + + result = cli_request_new(mem_ctx, cli->event_ctx, cli, 12, 0, &req); + if (result == NULL) { + DEBUG(0, ("cli_request_new failed\n")); + return NULL; + } + + req = cli_request_get(result); + + req->data.read.ofs = offset; + req->data.read.size = size; + req->data.read.received = 0; + req->data.read.rcvbuf = NULL; + + if ((SMB_BIG_UINT)offset >> 32) + bigoffset = True; + + cli_set_message(req->outbuf, bigoffset ? 12 : 10, 0, False); + + SCVAL(req->outbuf,smb_com,SMBreadX); + SSVAL(req->outbuf,smb_tid,cli->cnum); + cli_setup_packet_buf(cli, req->outbuf); + + SCVAL(req->outbuf,smb_vwv0,0xFF); + SCVAL(req->outbuf,smb_vwv0+1,0); + SSVAL(req->outbuf,smb_vwv1,0); + SSVAL(req->outbuf,smb_vwv2,fnum); + SIVAL(req->outbuf,smb_vwv3,offset); + SSVAL(req->outbuf,smb_vwv5,size); + SSVAL(req->outbuf,smb_vwv6,size); + SSVAL(req->outbuf,smb_vwv7,(size >> 16)); + SSVAL(req->outbuf,smb_vwv8,0); + SSVAL(req->outbuf,smb_vwv9,0); + SSVAL(req->outbuf,smb_mid,req->mid); + + if (bigoffset) { + SIVAL(req->outbuf, smb_vwv10, + (((SMB_BIG_UINT)offset)>>32) & 0xffffffff); + } + + cli_calculate_sign_mac(cli, req->outbuf); + + event_fd_set_writeable(cli->fd_event); + + if (cli_encryption_on(cli)) { + NTSTATUS status; + status = cli_encrypt_message(cli, req->outbuf, &enc_buf); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Error in encrypting client message. " + "Error %s\n", nt_errstr(status))); + TALLOC_FREE(req); + return NULL; + } + req->outbuf = enc_buf; + req->enc_state = cli->trans_enc_state; + } + + return result; +} + +/* + * Pull the data out of a finished async read_and_x request. rcvbuf is + * talloced from the request, so better make sure that you copy it away before + * you talloc_free(req). "rcvbuf" is NOT a talloc_ctx of its own, so do not + * talloc_move it! + */ + +NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, + uint8_t **rcvbuf) +{ + struct cli_request *cli_req = cli_request_get(req); + NTSTATUS status; + size_t size; + + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; + } + + status = cli_pull_error(cli_req->inbuf); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* size is the number of bytes the server returned. + * Might be zero. */ + size = SVAL(cli_req->inbuf, smb_vwv5); + size |= (((unsigned int)(SVAL(cli_req->inbuf, smb_vwv7))) << 16); + + if (size > cli_req->data.read.size) { + DEBUG(5,("server returned more than we wanted!\n")); + return NT_STATUS_UNEXPECTED_IO_ERROR; + } + + if (size < 0) { + DEBUG(5,("read return < 0!\n")); + return NT_STATUS_UNEXPECTED_IO_ERROR; + } + + *rcvbuf = (uint8_t *) + (smb_base(cli_req->inbuf) + SVAL(cli_req->inbuf, smb_vwv6)); + *received = size; + return NT_STATUS_OK; +} + +/* + * Parallel read support. + * + * cli_pull sends as many read&x requests as the server would allow via + * max_mux at a time. When replies flow back in, the data is written into + * the callback function "sink" in the right order. + */ + +struct cli_pull_state { + struct async_req *req; + + struct cli_state *cli; + uint16_t fnum; + off_t start_offset; + size_t size; + + NTSTATUS (*sink)(char *buf, size_t n, void *priv); + void *priv; + + size_t chunk_size; + + /* + * Outstanding requests + */ + int num_reqs; + struct async_req **reqs; + + /* + * For how many bytes did we send requests already? + */ + off_t requested; + + /* + * Next request index to push into "sink". This walks around the "req" + * array, taking care that the requests are pushed to "sink" in the + * right order. If necessary (i.e. replies don't come in in the right + * order), replies are held back in "reqs". + */ + int top_req; + + /* + * How many bytes did we push into "sink"? + */ + + off_t pushed; +}; + +static char *cli_pull_print(TALLOC_CTX *mem_ctx, struct async_req *req) +{ + struct cli_pull_state *state = talloc_get_type_abort( + req->private_data, struct cli_pull_state); + char *result; + + result = async_req_print(mem_ctx, req); + if (result == NULL) { + return NULL; + } + + return talloc_asprintf_append_buffer( + result, "num_reqs=%d, top_req=%d", + state->num_reqs, state->top_req); +} + +static void cli_pull_read_done(struct async_req *read_req); + +/* + * Prepare an async pull request + */ + +struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, + uint16_t fnum, off_t start_offset, + size_t size, size_t window_size, + NTSTATUS (*sink)(char *buf, size_t n, + void *priv), + void *priv) +{ + struct async_req *result; + struct cli_pull_state *state; + int i; + + result = async_req_new(mem_ctx, cli->event_ctx); + if (result == NULL) { + goto failed; + } + state = talloc(result, struct cli_pull_state); + if (state == NULL) { + goto failed; + } + result->private_data = state; + result->print = cli_pull_print; + state->req = result; + + state->cli = cli; + state->fnum = fnum; + state->start_offset = start_offset; + state->size = size; + state->sink = sink; + state->priv = priv; + + state->pushed = 0; + state->top_req = 0; + state->chunk_size = cli_read_max_bufsize(cli); + + state->num_reqs = MAX(window_size/state->chunk_size, 1); + state->num_reqs = MIN(state->num_reqs, cli->max_mux); + + state->reqs = TALLOC_ZERO_ARRAY(state, struct async_req *, + state->num_reqs); + if (state->reqs == NULL) { + goto failed; + } + + state->requested = 0; + + for (i=0; inum_reqs; i++) { + size_t size_left, request_thistime; + + if (state->requested >= size) { + state->num_reqs = i; + break; + } + + size_left = size - state->requested; + request_thistime = MIN(size_left, state->chunk_size); + + state->reqs[i] = cli_read_andx_send( + state->reqs, cli, fnum, + state->start_offset + state->requested, + request_thistime); + + if (state->reqs[i] == NULL) { + goto failed; + } + + state->reqs[i]->async.fn = cli_pull_read_done; + state->reqs[i]->async.priv = result; + + state->requested += request_thistime; + } + return result; + +failed: + TALLOC_FREE(result); + return NULL; +} + +/* + * Handle incoming read replies, push the data into sink and send out new + * requests if necessary. + */ + +static void cli_pull_read_done(struct async_req *read_req) +{ + struct async_req *pull_req = talloc_get_type_abort( + read_req->async.priv, struct async_req); + struct cli_pull_state *state = talloc_get_type_abort( + pull_req->private_data, struct cli_pull_state); + struct cli_request *read_state = cli_request_get(read_req); + NTSTATUS status; + + status = cli_read_andx_recv(read_req, &read_state->data.read.received, + &read_state->data.read.rcvbuf); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(state->req, status); + return; + } + + /* + * This loop is the one to take care of out-of-order replies. All + * pending requests are in state->reqs, state->reqs[top_req] is the + * one that is to be pushed next. If however a request later than + * top_req is replied to, then we can't push yet. If top_req is + * replied to at a later point then, we need to push all the finished + * requests. + */ + + while (state->reqs[state->top_req] != NULL) { + struct cli_request *top_read; + + DEBUG(11, ("cli_pull_read_done: top_req = %d\n", + state->top_req)); + + if (state->reqs[state->top_req]->state < ASYNC_REQ_DONE) { + DEBUG(11, ("cli_pull_read_done: top request not yet " + "done\n")); + return; + } + + top_read = cli_request_get(state->reqs[state->top_req]); + + DEBUG(10, ("cli_pull_read_done: Pushing %d bytes, %d already " + "pushed\n", (int)top_read->data.read.received, + (int)state->pushed)); + + status = state->sink((char *)top_read->data.read.rcvbuf, + top_read->data.read.received, + state->priv); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(state->req, status); + return; + } + state->pushed += top_read->data.read.received; + + TALLOC_FREE(state->reqs[state->top_req]); + + if (state->requested < state->size) { + struct async_req *new_req; + size_t size_left, request_thistime; + + size_left = state->size - state->requested; + request_thistime = MIN(size_left, state->chunk_size); + + DEBUG(10, ("cli_pull_read_done: Requesting %d bytes " + "at %d, position %d\n", + (int)request_thistime, + (int)(state->start_offset + + state->requested), + state->top_req)); + + new_req = cli_read_andx_send( + state->reqs, state->cli, state->fnum, + state->start_offset + state->requested, + request_thistime); + + if (async_req_nomem(new_req, state->req)) { + return; + } + + new_req->async.fn = cli_pull_read_done; + new_req->async.priv = pull_req; + + state->reqs[state->top_req] = new_req; + state->requested += request_thistime; + } + + state->top_req = (state->top_req+1) % state->num_reqs; + } + + async_req_done(pull_req); +} + +NTSTATUS cli_pull_recv(struct async_req *req, ssize_t *received) +{ + struct cli_pull_state *state = talloc_get_type_abort( + req->private_data, struct cli_pull_state); + + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; + } + *received = state->pushed; + return NT_STATUS_OK; +} + +NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, + off_t start_offset, size_t size, size_t window_size, + NTSTATUS (*sink)(char *buf, size_t n, void *priv), + void *priv, ssize_t *received) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct async_req *req; + NTSTATUS result = NT_STATUS_NO_MEMORY; + + if (cli_tmp_event_ctx(frame, cli) == NULL) { + goto nomem; + } + + req = cli_pull_send(frame, cli, fnum, start_offset, size, window_size, + sink, priv); + if (req == NULL) { + goto nomem; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(cli->event_ctx); + } + + result = cli_pull_recv(req, received); + nomem: + TALLOC_FREE(frame); + return result; +} + /**************************************************************************** Issue a single SMBread and don't wait for a reply. ****************************************************************************/ -- cgit From a01522749055d5d44865a255d094ff5255f8ac04 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Feb 2008 15:26:01 +0100 Subject: Convert cli_read to use cli_pull (This used to be commit d69b20111a849152a7d9108763207c813bf9068b) --- source3/libsmb/clireadwrite.c | 178 ++++-------------------------------------- 1 file changed, 15 insertions(+), 163 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 5aee8f18bd..c618509f01 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -444,175 +444,27 @@ NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, return result; } -/**************************************************************************** -Issue a single SMBread and don't wait for a reply. -****************************************************************************/ - -static bool cli_issue_read(struct cli_state *cli, int fnum, off_t offset, - size_t size, int i) +static NTSTATUS cli_read_sink(char *buf, size_t n, void *priv) { - bool bigoffset = False; - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - if ((SMB_BIG_UINT)offset >> 32) - bigoffset = True; - - cli_set_message(cli->outbuf,bigoffset ? 12 : 10,0,True); - - SCVAL(cli->outbuf,smb_com,SMBreadX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SCVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,fnum); - SIVAL(cli->outbuf,smb_vwv3,offset); - SSVAL(cli->outbuf,smb_vwv5,size); - SSVAL(cli->outbuf,smb_vwv6,size); - SSVAL(cli->outbuf,smb_vwv7,(size >> 16)); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - if (bigoffset) { - SIVAL(cli->outbuf,smb_vwv10,(((SMB_BIG_UINT)offset)>>32) & 0xffffffff); - } - - return cli_send_smb(cli); + char **pbuf = (char **)priv; + memcpy(*pbuf, buf, n); + *pbuf += n; + return NT_STATUS_OK; } -/**************************************************************************** - Read size bytes at offset offset using SMBreadX. -****************************************************************************/ - -ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) +ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, + off_t offset, size_t size) { - char *p; - size_t size2; - size_t readsize; - ssize_t total = 0; - /* We can only do direct reads if not signing or encrypting. */ - bool direct_reads = !client_is_signing_on(cli) && !cli_encryption_on(cli); - - if (size == 0) - return 0; - - /* - * Set readsize to the maximum size we can handle in one readX, - * rounded down to a multiple of 1024. - */ - - if (client_is_signing_on(cli) == false && - cli_encryption_on(cli) == false && - (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { - readsize = CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; - } else if (cli->capabilities & CAP_LARGE_READX) { - if (cli->is_samba) { - readsize = CLI_SAMBA_MAX_LARGE_READX_SIZE; - } else { - readsize = CLI_WINDOWS_MAX_LARGE_READX_SIZE; - } - } else { - readsize = (cli->max_xmit - (smb_size+32)) & ~1023; - } - - while (total < size) { - readsize = MIN(readsize, size-total); - - /* Issue a read and receive a reply */ - - if (!cli_issue_read(cli, fnum, offset, readsize, 0)) - return -1; - - if (direct_reads) { - if (!cli_receive_smb_readX_header(cli)) - return -1; - } else { - if (!cli_receive_smb(cli)) - return -1; - } - - /* Check for error. Make sure to check for DOS and NT - errors. */ - - if (cli_is_error(cli)) { - bool recoverable_error = False; - NTSTATUS status = NT_STATUS_OK; - uint8 eclass = 0; - uint32 ecode = 0; - - if (cli_is_nt_error(cli)) - status = cli_nt_error(cli); - else - cli_dos_error(cli, &eclass, &ecode); - - /* - * ERRDOS ERRmoredata or STATUS_MORE_ENRTIES is a - * recoverable error, plus we have valid data in the - * packet so don't error out here. - */ - - if ((eclass == ERRDOS && ecode == ERRmoredata) || - NT_STATUS_V(status) == NT_STATUS_V(STATUS_MORE_ENTRIES)) - recoverable_error = True; - - if (!recoverable_error) - return -1; - } - - /* size2 is the number of bytes the server returned. - * Might be zero. */ - size2 = SVAL(cli->inbuf, smb_vwv5); - size2 |= (((unsigned int)(SVAL(cli->inbuf, smb_vwv7))) << 16); - - if (size2 > readsize) { - DEBUG(5,("server returned more than we wanted!\n")); - return -1; - } else if (size2 < 0) { - DEBUG(5,("read return < 0!\n")); - return -1; - } - - if (size2) { - /* smb_vwv6 is the offset in the packet of the returned - * data bytes. Only valid if size2 != 0. */ - - if (!direct_reads) { - /* Copy data into buffer */ - p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); - memcpy(buf + total, p, size2); - } else { - /* Ensure the remaining data matches the return size. */ - ssize_t toread = smb_len_large(cli->inbuf) - SVAL(cli->inbuf,smb_vwv6); - - /* Ensure the size is correct. */ - if (toread != size2) { - DEBUG(5,("direct read logic fail toread (%d) != size2 (%u)\n", - (int)toread, (unsigned int)size2 )); - return -1; - } - - /* Read data directly into buffer */ - toread = cli_receive_smb_data(cli,buf+total,size2); - if (toread != size2) { - DEBUG(5,("direct read read failure toread (%d) != size2 (%u)\n", - (int)toread, (unsigned int)size2 )); - return -1; - } - } - } - - total += size2; - offset += size2; - - /* - * If the server returned less than we asked for we're at EOF. - */ + NTSTATUS status; + ssize_t ret; - if (size2 < readsize) - break; + status = cli_pull(cli, fnum, offset, size, size, + cli_read_sink, &buf, &ret); + if (!NT_STATUS_IS_OK(status)) { + cli_set_error(cli, status); + return -1; } - - return total; + return ret; } #if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */ -- cgit From 5b80b9340fb64413f68d625cf5ca57344c0adbd7 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 6 Mar 2008 09:00:37 -0500 Subject: Check for NULL pointers before dereferencing them. (This used to be commit 6f65390cec218a6aac4370ee381f30439617dcec) --- source3/libsmb/libsmb_server.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 64eb1ea584..37612c6e39 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -144,6 +144,10 @@ SMBC_find_server(TALLOC_CTX *ctx, SMBCSRV *srv; int auth_called = 0; + if (!pp_workgroup || !pp_username || !pp_password) { + return NULL; + } + check_server_cache: srv = smbc_getFunctionGetCachedServer(context)(context, @@ -156,10 +160,6 @@ check_server_cache: SMBC_call_auth_fn(ctx, context, server, share, pp_workgroup, pp_username, pp_password); - if (!pp_workgroup || !pp_username || !pp_password) { - return NULL; - } - /* * However, smbc_auth_fn may have picked up info relating to * an existing connection, so try for an existing connection -- cgit From 5eb347193f7f52bfc672b83da6e45b59db31423c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 6 Mar 2008 12:44:41 +0100 Subject: Fix a "nested extern declaration" warning (This used to be commit e473e6d50c56f52ef5e4853e4ca3b3548af06f51) --- source3/libsmb/libsmb_context.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index c04f751696..212b42fa88 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -27,6 +27,8 @@ #include "libsmb_internal.h" +extern bool in_client; + /* * Is the logging working / configfile read ? */ @@ -410,7 +412,6 @@ smbc_init_context(SMBCCTX *context) int pid; char *user = NULL; char *home = NULL; - extern bool in_client; if (!context) { errno = EBADF; -- cgit From 914cd3e483bd83fb4d8e769b90d9136336ea51e9 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 6 Mar 2008 10:41:42 -0500 Subject: Eliminate global variable in_client and a plethora of extern declarations. Derrell (This used to be commit b7f34e7ef2907b498a0645ce68f2773ed7d60cdc) --- source3/libsmb/libsmb_context.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 212b42fa88..3e67943c83 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -27,8 +27,6 @@ #include "libsmb_internal.h" -extern bool in_client; - /* * Is the logging working / configfile read ? */ @@ -450,7 +448,7 @@ smbc_init_context(SMBCCTX *context) /* Here we would open the smb.conf file if needed ... */ - in_client = True; /* FIXME, make a param */ + lp_set_in_client(True); home = getenv("HOME"); if (home) { -- cgit From 6a2dbea79433465518a47a275f3ed5fbaa887c1e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 1 Mar 2008 19:54:17 +0100 Subject: Fix some typos (This used to be commit cfa1b838144800c0758969921b8904fd62e46c07) --- source3/libsmb/unexpected.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index 5fbc33cdf5..df4d2119e2 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -22,7 +22,7 @@ static TDB_CONTEXT *tdbd = NULL; -/* the key type used in the unexpeceted packet database */ +/* the key type used in the unexpected packet database */ struct unexpected_key { enum packet_type packet_type; time_t timestamp; @@ -32,7 +32,7 @@ struct unexpected_key { /**************************************************************************** All unexpected packets are passed in here, to be stored in a unexpected packet database. This allows nmblookup and other tools to receive packets - erroneoously sent to the wrong port by broken MS systems. + erroneously sent to the wrong port by broken MS systems. **************************************************************************/ void unexpected_packet(struct packet_struct *p) -- cgit From 8da1e033a876ab273bf4949535b31817585a953d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 2 Mar 2008 09:43:19 +0100 Subject: Pass specific packets to build_nmb and build_dgram To me it was not clear what parts of struct packet_struct are actually used in build_packet(). This makes it a bit more clear that only the specific parts are used. (This used to be commit eb8b6f2404e49d6a837935c5b411d78fb6ff23ef) --- source3/libsmb/nmblib.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c index 15a9a93ff2..bfe5e7b97b 100644 --- a/source3/libsmb/nmblib.c +++ b/source3/libsmb/nmblib.c @@ -849,9 +849,8 @@ static bool send_udp(int fd,char *buf,int len,struct in_addr ip,int port) If buf == NULL this is a length calculation. ******************************************************************/ -static int build_dgram(char *buf, size_t len, struct packet_struct *p) +static int build_dgram(char *buf, size_t len, struct dgram_packet *dgram) { - struct dgram_packet *dgram = &p->packet.dgram; unsigned char *ubuf = (unsigned char *)buf; int offset=0; @@ -926,9 +925,8 @@ bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2) If buf == NULL this is a length calculation. ******************************************************************/ -static int build_nmb(char *buf, size_t len, struct packet_struct *p) +static int build_nmb(char *buf, size_t len, struct nmb_packet *nmb) { - struct nmb_packet *nmb = &p->packet.nmb; unsigned char *ubuf = (unsigned char *)buf; int offset=0; @@ -1058,11 +1056,11 @@ int build_packet(char *buf, size_t buflen, struct packet_struct *p) switch (p->packet_type) { case NMB_PACKET: - len = build_nmb(buf,buflen,p); + len = build_nmb(buf,buflen,&p->packet.nmb); break; case DGRAM_PACKET: - len = build_dgram(buf,buflen,p); + len = build_dgram(buf,buflen,&p->packet.dgram); break; } -- cgit From 464f74df2f6f50525c3701025860fe0435d9c91c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 7 Mar 2008 15:03:20 +0100 Subject: Move inbuf handling to before the PDU handling In an error case, correctly discard the offending PDU (This used to be commit 0aa195b5d623e1f26f2a1b9e91323a5ddd3ff282) --- source3/libsmb/async_smb.c | 117 +++++++++++++++++++++++---------------------- 1 file changed, 59 insertions(+), 58 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 21bcd5b9b1..04c22a9d17 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -174,24 +174,72 @@ static void handle_incoming_pdu(struct cli_state *cli) { struct cli_request *req; uint16_t mid; - size_t raw_pdu_len, buf_len, pdu_len; - size_t rest_len; + size_t raw_pdu_len, buf_len, pdu_len, rest_len; + char *pdu; NTSTATUS status; /* * The encrypted PDU len might differ from the unencrypted one */ raw_pdu_len = smb_len(cli->evt_inbuf) + 4; + buf_len = talloc_get_size(cli->evt_inbuf); + rest_len = buf_len - raw_pdu_len; + + if (buf_len == raw_pdu_len) { + /* + * Optimal case: Exactly one PDU was in the socket buffer + */ + pdu = cli->evt_inbuf; + cli->evt_inbuf = NULL; + } + else { + DEBUG(11, ("buf_len = %d, raw_pdu_len = %d, splitting " + "buffer\n", (int)buf_len, (int)raw_pdu_len)); + + if (raw_pdu_len < rest_len) { + /* + * The PDU is shorter, talloc_memdup that one. + */ + pdu = (char *)talloc_memdup( + cli, cli->evt_inbuf, raw_pdu_len); + + memmove(cli->evt_inbuf, cli->evt_inbuf + raw_pdu_len, + buf_len - raw_pdu_len); + + cli->evt_inbuf = TALLOC_REALLOC_ARRAY( + NULL, cli->evt_inbuf, char, rest_len); + + if (pdu == NULL) { + status = NT_STATUS_NO_MEMORY; + goto invalidate_requests; + } + } + else { + /* + * The PDU is larger than the rest, talloc_memdup the + * rest + */ + pdu = cli->evt_inbuf; + + cli->evt_inbuf = (char *)talloc_memdup( + cli, pdu + raw_pdu_len, rest_len); + + if (cli->evt_inbuf == NULL) { + status = NT_STATUS_NO_MEMORY; + goto invalidate_requests; + } + } + + } /* * TODO: Handle oplock break requests */ - if (cli_encryption_on(cli) && CVAL(cli->evt_inbuf, 0) == 0) { + if (cli_encryption_on(cli) && CVAL(pdu, 0) == 0) { uint16_t enc_ctx_num; - status = get_enc_ctx_num((uint8_t *)cli->evt_inbuf, - &enc_ctx_num); + status = get_enc_ctx_num((uint8_t *)pdu, &enc_ctx_num); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("get_enc_ctx_num returned %s\n", nt_errstr(status))); @@ -207,7 +255,7 @@ static void handle_incoming_pdu(struct cli_state *cli) } status = common_decrypt_buffer(cli->trans_enc_state, - cli->evt_inbuf); + pdu); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("common_decrypt_buffer returned %s\n", nt_errstr(status))); @@ -215,13 +263,13 @@ static void handle_incoming_pdu(struct cli_state *cli) } } - if (!cli_check_sign_mac(cli, cli->evt_inbuf)) { + if (!cli_check_sign_mac(cli, pdu)) { DEBUG(10, ("cli_check_sign_mac failed\n")); status = NT_STATUS_ACCESS_DENIED; goto invalidate_requests; } - mid = SVAL(cli->evt_inbuf, smb_mid); + mid = SVAL(pdu, smb_mid); DEBUG(10, ("handle_incoming_pdu: got mid %d\n", mid)); @@ -231,64 +279,17 @@ static void handle_incoming_pdu(struct cli_state *cli) } } - buf_len = talloc_get_size(cli->evt_inbuf); - pdu_len = smb_len(cli->evt_inbuf) + 4; - rest_len = buf_len - raw_pdu_len; + pdu_len = smb_len(pdu) + 4; if (req == NULL) { DEBUG(3, ("Request for mid %d not found, dumping PDU\n", mid)); - memmove(cli->evt_inbuf, cli->evt_inbuf + raw_pdu_len, - buf_len - raw_pdu_len); - - cli->evt_inbuf = TALLOC_REALLOC_ARRAY(NULL, cli->evt_inbuf, - char, rest_len); + TALLOC_FREE(pdu); return; } - if (buf_len == pdu_len) { - /* - * Optimal case: Exactly one PDU was in the socket buffer - */ - req->inbuf = talloc_move(req, &cli->evt_inbuf); - goto done; - } - - DEBUG(11, ("buf_len = %d, pdu_len = %d, splitting buffer\n", - (int)buf_len, (int)pdu_len)); - - if (pdu_len < rest_len) { - /* - * The PDU is shorter, talloc_memdup that one. - */ - req->inbuf = (char *)talloc_memdup( - req, cli->evt_inbuf, pdu_len); - - memmove(cli->evt_inbuf, - cli->evt_inbuf + raw_pdu_len, - buf_len - raw_pdu_len); - - cli->evt_inbuf = TALLOC_REALLOC_ARRAY( - NULL, cli->evt_inbuf, char, rest_len); - } - else { - /* - * The PDU is larger than the rest, - * talloc_memdup the rest - */ - req->inbuf = talloc_move(req, &cli->evt_inbuf); - - cli->evt_inbuf = (char *)talloc_memdup( - cli, req->inbuf + raw_pdu_len, - rest_len); - } - - if ((req->inbuf == NULL) || (cli->evt_inbuf == NULL)) { - status = NT_STATUS_NO_MEMORY; - goto invalidate_requests; - } + req->inbuf = talloc_move(req, &pdu); - done: async_req_done(req->async); return; -- cgit From 973734cde620585e409d2c125184a2388ab26041 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 8 Mar 2008 22:28:01 +0100 Subject: Correctly calculate the max read size (This used to be commit f556c9e162e2bc0d16710e994a00edc33a146cd5) --- source3/libsmb/clireadwrite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index c618509f01..9bd8170673 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -24,7 +24,7 @@ ****************************************************************************/ static size_t cli_read_max_bufsize(struct cli_state *cli) { - if (!client_is_signing_on(cli) && !cli_encryption_on(cli) == false + if (!client_is_signing_on(cli) && !cli_encryption_on(cli) && (cli->posix_capabilities & CIFS_UNIX_LARGE_READ_CAP)) { return CLI_SAMBA_MAX_POSIX_LARGE_READX_SIZE; } -- cgit From d185fb48fb5a05f9ed83c7c0b9dff7f2bbcae732 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 7 Mar 2008 17:37:07 +0100 Subject: Remove insane amount of whitespace. Guenther (This used to be commit 8216310e9f0d7dcccfe761a184a014b7b2ce03c5) --- source3/libsmb/libsmb_dir.c | 736 ++++++++++++++++++++++---------------------- 1 file changed, 368 insertions(+), 368 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 1486097d51..45db914d18 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -1,23 +1,23 @@ -/* +/* Unix SMB/Netbios implementation. SMB client library implementation Copyright (C) Andrew Tridgell 1998 Copyright (C) Richard Sharpe 2000, 2002 Copyright (C) John Terpstra 2000 - Copyright (C) Tom Jansen (Ninja ISD) 2002 + Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -36,19 +36,19 @@ static void remove_dir(SMBCFILE *dir) { struct smbc_dir_list *d,*f; - + d = dir->dir_list; while (d) { - + f = d; d = d->next; - + SAFE_FREE(f->dirent); SAFE_FREE(f); - + } - + dir->dir_list = dir->dir_end = dir->dir_next = NULL; - + } static int @@ -61,63 +61,63 @@ add_dirent(SMBCFILE *dir, int size; int name_length = (name == NULL ? 0 : strlen(name)); int comment_len = (comment == NULL ? 0 : strlen(comment)); - + /* - * Allocate space for the dirent, which must be increased by the + * Allocate space for the dirent, which must be increased by the * size of the name and the comment and 1 each for the null terminator. */ - + size = sizeof(struct smbc_dirent) + name_length + comment_len + 2; - + dirent = (struct smbc_dirent *)SMB_MALLOC(size); - + if (!dirent) { - + dir->dir_error = ENOMEM; return -1; - + } - + ZERO_STRUCTP(dirent); - + if (dir->dir_list == NULL) { - + dir->dir_list = SMB_MALLOC_P(struct smbc_dir_list); if (!dir->dir_list) { - + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; - + } ZERO_STRUCTP(dir->dir_list); - + dir->dir_end = dir->dir_next = dir->dir_list; } else { - + dir->dir_end->next = SMB_MALLOC_P(struct smbc_dir_list); - + if (!dir->dir_end->next) { - + SAFE_FREE(dirent); dir->dir_error = ENOMEM; return -1; - + } ZERO_STRUCTP(dir->dir_end->next); - + dir->dir_end = dir->dir_end->next; } - + dir->dir_end->next = NULL; dir->dir_end->dirent = dirent; - + dirent->smbc_type = type; dirent->namelen = name_length; dirent->commentlen = comment_len; dirent->dirlen = size; - + /* * dirent->namelen + 1 includes the null (no null termination needed) * Ditto for dirent->commentlen. @@ -126,9 +126,9 @@ add_dirent(SMBCFILE *dir, strncpy(dirent->name, (name?name:""), dirent->namelen + 1); dirent->comment = (char *)(&dirent->name + dirent->namelen + 1); strncpy(dirent->comment, (comment?comment:""), dirent->commentlen + 1); - + return 0; - + } static void @@ -142,18 +142,18 @@ list_unique_wg_fn(const char *name, struct smbc_dirent *dirent; int dirent_type; int do_remove = 0; - + dirent_type = dir->dir_type; - + if (add_dirent(dir, name, comment, dirent_type) < 0) { - + /* An error occurred, what do we do? */ /* FIXME: Add some code here */ } - + /* Point to the one just added */ dirent = dir->dir_end->dirent; - + /* See if this was a duplicate */ for (dir_list = dir->dir_list; dir_list != dir->dir_end; @@ -163,7 +163,7 @@ list_unique_wg_fn(const char *name, /* Duplicate. End end of list need to be removed. */ do_remove = 1; } - + if (do_remove && dir_list->next == dir->dir_end) { /* Found the end of the list. Remove it. */ dir->dir_end = dir_list; @@ -183,7 +183,7 @@ list_fn(const char *name, { SMBCFILE *dir = (SMBCFILE *)state; int dirent_type; - + /* * We need to process the type a little ... * @@ -195,27 +195,27 @@ list_fn(const char *name, * administrative shares: * ADMIN$, IPC$, C$, D$, E$ ... are type |= 0x80000000 */ - + if (dir->dir_type == SMBC_FILE_SHARE) { switch (type) { case 0 | 0x80000000: case 0: dirent_type = SMBC_FILE_SHARE; break; - + case 1: dirent_type = SMBC_PRINTER_SHARE; break; - + case 2: dirent_type = SMBC_COMMS_SHARE; break; - + case 3 | 0x80000000: case 3: dirent_type = SMBC_IPC_SHARE; break; - + default: dirent_type = SMBC_FILE_SHARE; /* FIXME, error? */ break; @@ -224,12 +224,12 @@ list_fn(const char *name, else { dirent_type = dir->dir_type; } - + if (add_dirent(dir, name, comment, dirent_type) < 0) { - + /* An error occurred, what do we do? */ /* FIXME: Add some code here */ - + } } @@ -239,16 +239,16 @@ dir_list_fn(const char *mnt, const char *mask, void *state) { - - if (add_dirent((SMBCFILE *)state, finfo->name, "", + + if (add_dirent((SMBCFILE *)state, finfo->name, "", (finfo->mode&aDIR?SMBC_DIR:SMBC_FILE)) < 0) { - + /* Handle an error ... */ - + /* FIXME: Add some code ... */ - - } - + + } + } static int @@ -270,14 +270,14 @@ net_share_enum_rpc(struct cli_state *cli, fstring comment = ""; struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; - + /* Open the server service pipe */ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); if (!pipe_hnd) { DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); return -1; } - + /* Issue the NetShareEnum RPC call and retrieve the response */ init_enum_hnd(&enum_hnd, 0); result = rpccli_srvsvc_net_share_enum(pipe_hnd, @@ -286,35 +286,35 @@ net_share_enum_rpc(struct cli_state *cli, &ctr, preferred_len, &enum_hnd); - + /* Was it successful? */ if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { /* Nope. Go clean up. */ goto done; } - + /* For each returned entry... */ for (i = 0; i < ctr.num_entries; i++) { - + /* pull out the share name */ rpcstr_pull_unistr2_fstring( name, &ctr.share.info1[i].info_1_str.uni_netname); - + /* pull out the share's comment */ rpcstr_pull_unistr2_fstring( comment, &ctr.share.info1[i].info_1_str.uni_remark); - + /* Get the type value */ type = ctr.share.info1[i].info_1.type; - + /* Add this share to the list */ (*fn)(name, type, comment, state); } - + done: /* Close the server service pipe */ cli_rpc_pipe_close(pipe_hnd); - + /* Tell 'em if it worked */ return W_ERROR_IS_OK(result) ? 0 : -1; } @@ -332,10 +332,10 @@ SMBC_check_options(char *server, DEBUG(4, ("SMBC_check_options(): server='%s' share='%s' " "path='%s' options='%s'\n", server, share, path, options)); - + /* No options at all is always ok */ if (! *options) return 0; - + /* Currently, we don't support any options. */ return -1; } @@ -359,22 +359,22 @@ SMBC_opendir_ctx(SMBCCTX *context, SMBCFILE *dir = NULL; struct sockaddr_storage rem_ss; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { DEBUG(4, ("no valid context\n")); errno = EINVAL + 8192; TALLOC_FREE(frame); return NULL; - + } - + if (!fname) { DEBUG(4, ("no valid fname\n")); errno = EINVAL + 8193; TALLOC_FREE(frame); return NULL; } - + if (SMBC_parse_path(frame, context, fname, @@ -390,11 +390,11 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + DEBUG(4, ("parsed path: fname='%s' server='%s' share='%s' " "path='%s' options='%s'\n", fname, server, share, path, options)); - + /* Ensure the options are valid */ if (SMBC_check_options(server, share, path, options)) { DEBUG(4, ("unacceptable options (%s)\n", options)); @@ -402,7 +402,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -411,35 +411,35 @@ SMBC_opendir_ctx(SMBCCTX *context, return NULL; } } - + dir = SMB_MALLOC_P(SMBCFILE); - + if (!dir) { errno = ENOMEM; TALLOC_FREE(frame); return NULL; } - + ZERO_STRUCTP(dir); - + dir->cli_fd = 0; dir->fname = SMB_STRDUP(fname); dir->srv = NULL; dir->offset = 0; dir->file = False; dir->dir_list = dir->dir_next = dir->dir_end = NULL; - + if (server[0] == (char)0) { - + int i; int count; int max_lmb_count; struct ip_service *ip_list; struct ip_service server_addr; struct user_auth_info u_info; - + if (share[0] != (char)0 || path[0] != (char)0) { - + errno = EINVAL + 8196; if (dir) { SAFE_FREE(dir->fname); @@ -448,12 +448,12 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + /* Determine how many local master browsers to query */ max_lmb_count = (smbc_getOptionBrowseMaxLmbCount(context) == 0 ? INT_MAX : smbc_getOptionBrowseMaxLmbCount(context)); - + memset(&u_info, '\0', sizeof(u_info)); u_info.username = talloc_strdup(frame,user); u_info.password = talloc_strdup(frame,password); @@ -465,7 +465,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + /* * We have server and share and path empty but options * requesting that we scan all master browsers for their list @@ -474,16 +474,16 @@ SMBC_opendir_ctx(SMBCCTX *context, * doesn't work, then try our other methods which return only * a single master browser. */ - + ip_list = NULL; if (!NT_STATUS_IS_OK(name_resolve_bcast(MSBROWSE, 1, &ip_list, &count))) { - + SAFE_FREE(ip_list); - + if (!find_master_ip(workgroup, &server_addr.ss)) { - + if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -492,7 +492,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + ip_list = (struct ip_service *)memdup( &server_addr, sizeof(server_addr)); if (ip_list == NULL) { @@ -502,17 +502,17 @@ SMBC_opendir_ctx(SMBCCTX *context, } count = 1; } - + for (i = 0; i < count && i < max_lmb_count; i++) { char addr[INET6_ADDRSTRLEN]; char *wg_ptr = NULL; struct cli_state *cli = NULL; - + print_sockaddr(addr, sizeof(addr), &ip_list[i].ss); DEBUG(99, ("Found master browser %d of %d: %s\n", i+1, MAX(count, max_lmb_count), addr)); - + cli = get_ipc_connect_master_ip(talloc_tos(), &ip_list[i], &u_info, @@ -522,39 +522,39 @@ SMBC_opendir_ctx(SMBCCTX *context, if (!cli) { continue; } - + workgroup = talloc_strdup(frame, wg_ptr); server = talloc_strdup(frame, cli->desthost); - + cli_shutdown(cli); - + if (!workgroup || !server) { errno = ENOMEM; TALLOC_FREE(frame); return NULL; } - + DEBUG(4, ("using workgroup %s %s\n", workgroup, server)); - + /* * For each returned master browser IP address, get a * connection to IPC$ on the server if we do not * already have one, and determine the * workgroups/domains that it knows about. */ - + srv = SMBC_server(frame, context, True, server, "IPC$", &workgroup, &user, &password); if (!srv) { continue; } - + dir->srv = srv; dir->dir_type = SMBC_WORKGROUP; - + /* Now, list the stuff ... */ - + if (!cli_NetServerEnum(srv->cli, workgroup, SV_TYPE_DOMAIN_ENUM, @@ -563,7 +563,7 @@ SMBC_opendir_ctx(SMBCCTX *context, continue; } } - + SAFE_FREE(ip_list); } else { /* @@ -572,7 +572,7 @@ SMBC_opendir_ctx(SMBCCTX *context, */ if (*share == '\0') { if (*path != '\0') { - + /* Should not have empty share with path */ errno = EINVAL + 8197; if (dir) { @@ -581,9 +581,9 @@ SMBC_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } - + /* * We don't know if is really a server name * or is a workgroup/domain name. If we already have @@ -592,7 +592,7 @@ SMBC_opendir_ctx(SMBCCTX *context, * <1B>, or <20> translates. We check * to see if is an IP address first. */ - + /* * See if we have an existing server. Do not * establish a connection if one does not already @@ -601,7 +601,7 @@ SMBC_opendir_ctx(SMBCCTX *context, srv = SMBC_server(frame, context, False, server, "IPC$", &workgroup, &user, &password); - + /* * If no existing server and not an IP addr, look for * LMB or DMB @@ -610,17 +610,17 @@ SMBC_opendir_ctx(SMBCCTX *context, !is_ipaddress(server) && (resolve_name(server, &rem_ss, 0x1d) || /* LMB */ resolve_name(server, &rem_ss, 0x1b) )) { /* DMB */ - + fstring buserver; - + dir->dir_type = SMBC_SERVER; - + /* * Get the backup list ... */ if (!name_status_find(server, 0, 0, &rem_ss, buserver)) { - + DEBUG(0,("Could not get name of " "local/domain master browser " "for server %s\n", server)); @@ -631,9 +631,9 @@ SMBC_opendir_ctx(SMBCCTX *context, errno = EPERM; TALLOC_FREE(frame); return NULL; - + } - + /* * Get a connection to IPC$ on the server if * we do not already have one @@ -650,16 +650,16 @@ SMBC_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } - + dir->srv = srv; - + /* Now, list the servers ... */ if (!cli_NetServerEnum(srv->cli, server, 0x0000FFFE, list_fn, (void *)dir)) { - + if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); @@ -669,7 +669,7 @@ SMBC_opendir_ctx(SMBCCTX *context, } } else if (srv || (resolve_name(server, &rem_ss, 0x20))) { - + /* * If we hadn't found the server, get one now */ @@ -679,7 +679,7 @@ SMBC_opendir_ctx(SMBCCTX *context, &workgroup, &user, &password); } - + if (!srv) { if (dir) { SAFE_FREE(dir->fname); @@ -687,14 +687,14 @@ SMBC_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } - + dir->dir_type = SMBC_FILE_SHARE; dir->srv = srv; - + /* List the shares ... */ - + if (net_share_enum_rpc( srv->cli, list_fn, @@ -703,7 +703,7 @@ SMBC_opendir_ctx(SMBCCTX *context, srv->cli, list_fn, (void *)dir) < 0) { - + errno = cli_errno(srv->cli); if (dir) { SAFE_FREE(dir->fname); @@ -711,7 +711,7 @@ SMBC_opendir_ctx(SMBCCTX *context, } TALLOC_FREE(frame); return NULL; - + } } else { /* Neither the workgroup nor server exists */ @@ -723,7 +723,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + } else { /* @@ -732,13 +732,13 @@ SMBC_opendir_ctx(SMBCCTX *context, */ char *targetpath; struct cli_state *targetcli; - + /* We connect to the server and list the directory */ dir->dir_type = SMBC_FILE_SHARE; - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { if (dir) { SAFE_FREE(dir->fname); @@ -747,11 +747,11 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + dir->srv = srv; - + /* Now, list the files ... */ - + p = path + strlen(path); path = talloc_asprintf_append(path, "\\*"); if (!path) { @@ -762,7 +762,7 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); @@ -773,17 +773,17 @@ SMBC_opendir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return NULL; } - + if (cli_list(targetcli, targetpath, aDIR | aSYSTEM | aHIDDEN, dir_list_fn, (void *)dir) < 0) { - + if (dir) { SAFE_FREE(dir->fname); SAFE_FREE(dir); } saved_errno = SMBC_errno(context, targetcli); - + if (saved_errno == EINVAL) { /* * See if they asked to opendir @@ -793,28 +793,28 @@ SMBC_opendir_ctx(SMBCCTX *context, * than ENOTDIR. */ *p = '\0'; /* restore original path */ - + if (SMBC_getatr(context, srv, path, &mode, NULL, NULL, NULL, NULL, NULL, NULL) && ! IS_DOS_DIR(mode)) { - + /* It is. Correct the error value */ saved_errno = ENOTDIR; } } - + /* * If there was an error and the server is no * good any more... */ if (cli_is_error(targetcli) && smbc_getFunctionCheckServer(context)(context, srv)) { - + /* ... then remove it. */ if (smbc_getFunctionRemoveUnusedServer(context)(context, - srv)) { + srv)) { /* * We could not remove the * server completely, remove @@ -826,19 +826,19 @@ SMBC_opendir_ctx(SMBCCTX *context, smbc_getFunctionRemoveCachedServer(context)(context, srv); } } - + errno = saved_errno; TALLOC_FREE(frame); return NULL; } } - + } - + DLIST_ADD(context->internal->files, dir); TALLOC_FREE(frame); return dir; - + } /* @@ -850,32 +850,32 @@ SMBC_closedir_ctx(SMBCCTX *context, SMBCFILE *dir) { TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { errno = EBADF; TALLOC_FREE(frame); return -1; } - + remove_dir(dir); /* Clean it up */ - + DLIST_REMOVE(context->internal->files, dir); - + if (dir) { - + SAFE_FREE(dir->fname); SAFE_FREE(dir); /* Free the space too */ } - + TALLOC_FREE(frame); return 0; - + } static void @@ -885,33 +885,33 @@ smbc_readdir_internal(SMBCCTX * context, int max_namebuf_len) { if (smbc_getOptionUrlEncodeReaddirEntries(context)) { - + /* url-encode the name. get back remaining buffer space */ max_namebuf_len = SMBC_urlencode(dest->name, src->name, max_namebuf_len); - + /* We now know the name length */ dest->namelen = strlen(dest->name); - + /* Save the pointer to the beginning of the comment */ dest->comment = dest->name + dest->namelen + 1; - + /* Copy the comment */ strncpy(dest->comment, src->comment, max_namebuf_len - 1); dest->comment[max_namebuf_len - 1] = '\0'; - + /* Save other fields */ dest->smbc_type = src->smbc_type; dest->commentlen = strlen(dest->comment); dest->dirlen = ((dest->comment + dest->commentlen + 1) - (char *) dest); } else { - + /* No encoding. Just copy the entry as is. */ memcpy(dest, src, src->dirlen); dest->comment = (char *)(&dest->name + src->namelen + 1); } - + } /* @@ -925,58 +925,58 @@ SMBC_readdir_ctx(SMBCCTX *context, int maxlen; struct smbc_dirent *dirp, *dirent; TALLOC_CTX *frame = talloc_stackframe(); - + /* Check that all is ok first ... */ - + if (!context || !context->internal->initialized) { - + errno = EINVAL; DEBUG(0, ("Invalid context in SMBC_readdir_ctx()\n")); TALLOC_FREE(frame); return NULL; - + } - + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { - + errno = EBADF; DEBUG(0, ("Invalid dir in SMBC_readdir_ctx()\n")); TALLOC_FREE(frame); return NULL; - + } - + if (dir->file != False) { /* FIXME, should be dir, perhaps */ - + errno = ENOTDIR; DEBUG(0, ("Found file vs directory in SMBC_readdir_ctx()\n")); TALLOC_FREE(frame); return NULL; - + } - + if (!dir->dir_next) { TALLOC_FREE(frame); return NULL; } - + dirent = dir->dir_next->dirent; if (!dirent) { - + errno = ENOENT; TALLOC_FREE(frame); return NULL; - + } - + dirp = (struct smbc_dirent *)context->internal->dirent; maxlen = (sizeof(context->internal->dirent) - sizeof(struct smbc_dirent)); - + smbc_readdir_internal(context, dirp, dirent, maxlen); - + dir->dir_next = dir->dir_next->next; - + TALLOC_FREE(frame); return dirp; } @@ -997,99 +997,99 @@ SMBC_getdents_ctx(SMBCCTX *context, char *ndir = (char *)dirp; struct smbc_dir_list *dirlist; TALLOC_CTX *frame = talloc_stackframe(); - + /* Check that all is ok first ... */ - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { - + errno = EBADF; TALLOC_FREE(frame); return -1; - + } - + if (dir->file != False) { /* FIXME, should be dir, perhaps */ - + errno = ENOTDIR; TALLOC_FREE(frame); return -1; - + } - - /* + + /* * Now, retrieve the number of entries that will fit in what was passed - * We have to figure out if the info is in the list, or we need to + * We have to figure out if the info is in the list, or we need to * send a request to the server to get the info. */ - + while ((dirlist = dir->dir_next)) { struct smbc_dirent *dirent; - + if (!dirlist->dirent) { - + errno = ENOENT; /* Bad error */ TALLOC_FREE(frame); return -1; - + } - + /* Do urlencoding of next entry, if so selected */ dirent = (struct smbc_dirent *)context->internal->dirent; maxlen = (sizeof(context->internal->dirent) - sizeof(struct smbc_dirent)); smbc_readdir_internal(context, dirent, dirlist->dirent, maxlen); - + reqd = dirent->dirlen; - + if (rem < reqd) { - + if (rem < count) { /* We managed to copy something */ - + errno = 0; TALLOC_FREE(frame); return count - rem; - + } else { /* Nothing copied ... */ - + errno = EINVAL; /* Not enough space ... */ TALLOC_FREE(frame); return -1; - + } - + } - + memcpy(ndir, dirent, reqd); /* Copy the data in ... */ - - ((struct smbc_dirent *)ndir)->comment = + + ((struct smbc_dirent *)ndir)->comment = (char *)(&((struct smbc_dirent *)ndir)->name + dirent->namelen + 1); - + ndir += reqd; - + rem -= reqd; - + dir->dir_next = dirlist = dirlist -> next; } - + TALLOC_FREE(frame); - + if (rem == count) return 0; else return count - rem; - + } /* @@ -1111,21 +1111,21 @@ SMBC_mkdir_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_mkdir(%s)\n", fname)); - + if (SMBC_parse_path(frame, context, fname, @@ -1140,7 +1140,7 @@ SMBC_mkdir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -1149,17 +1149,17 @@ SMBC_mkdir_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { - + TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ - + } - + /*d_printf(">>>mkdir: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { @@ -1168,18 +1168,18 @@ SMBC_mkdir_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ - + if (!cli_mkdir(targetcli, targetpath)) { - + errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - - } - + + } + TALLOC_FREE(frame); return 0; - + } /* @@ -1218,21 +1218,21 @@ SMBC_rmdir_ctx(SMBCCTX *context, char *targetpath = NULL; struct cli_state *targetcli = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_rmdir(%s)\n", fname)); - + if (SMBC_parse_path(frame, context, fname, @@ -1247,7 +1247,7 @@ SMBC_rmdir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -1256,17 +1256,17 @@ SMBC_rmdir_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { - + TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ - + } - + /*d_printf(">>>rmdir: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { @@ -1275,19 +1275,19 @@ SMBC_rmdir_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/ - - + + if (!cli_rmdir(targetcli, targetpath)) { - + errno = SMBC_errno(context, targetcli); - + if (errno == EACCES) { /* Check if the dir empty or not */ - + /* Local storage to avoid buffer overflows */ char *lpath; - + smbc_rmdir_dirempty = True; /* Make this so ... */ - + lpath = talloc_asprintf(frame, "%s\\*", targetpath); if (!lpath) { @@ -1295,34 +1295,34 @@ SMBC_rmdir_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (cli_list(targetcli, lpath, aDIR | aSYSTEM | aHIDDEN, rmdir_list_fn, NULL) < 0) { - + /* Fix errno to ignore latest error ... */ DEBUG(5, ("smbc_rmdir: " "cli_list returned an error: %d\n", SMBC_errno(context, targetcli))); errno = EACCES; - + } - + if (smbc_rmdir_dirempty) errno = EACCES; else errno = ENOTEMPTY; - + } - + TALLOC_FREE(frame); return -1; - - } - + + } + TALLOC_FREE(frame); return 0; - + } /* @@ -1334,38 +1334,38 @@ SMBC_telldir_ctx(SMBCCTX *context, SMBCFILE *dir) { TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (!dir || !SMBC_dlist_contains(context->internal->files, dir)) { - + errno = EBADF; TALLOC_FREE(frame); return -1; - + } - + if (dir->file != False) { /* FIXME, should be dir, perhaps */ - + errno = ENOTDIR; TALLOC_FREE(frame); return -1; - + } - + /* See if we're already at the end. */ if (dir->dir_next == NULL) { /* We are. */ TALLOC_FREE(frame); return -1; } - + /* * We return the pointer here as the offset */ @@ -1378,29 +1378,29 @@ SMBC_telldir_ctx(SMBCCTX *context, */ static struct smbc_dir_list * -check_dir_ent(struct smbc_dir_list *list, +check_dir_ent(struct smbc_dir_list *list, struct smbc_dirent *dirent) { - + /* Run down the list looking for what we want */ - + if (dirent) { - + struct smbc_dir_list *tmp = list; - + while (tmp) { - + if (tmp->dirent == dirent) return tmp; - + tmp = tmp->next; - + } - + } - + return NULL; /* Not found, or an error */ - + } @@ -1417,50 +1417,50 @@ SMBC_lseekdir_ctx(SMBCCTX *context, struct smbc_dirent *dirent = (struct smbc_dirent *)l_offset; struct smbc_dir_list *list_ent = (struct smbc_dir_list *)NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (dir->file != False) { /* FIXME, should be dir, perhaps */ - + errno = ENOTDIR; TALLOC_FREE(frame); return -1; - + } - + /* Now, check what we were passed and see if it is OK ... */ - + if (dirent == NULL) { /* Seek to the begining of the list */ - + dir->dir_next = dir->dir_list; TALLOC_FREE(frame); return 0; - + } - + if (offset == -1) { /* Seek to the end of the list */ dir->dir_next = NULL; TALLOC_FREE(frame); return 0; } - + /* Now, run down the list and make sure that the entry is OK */ /* This may need to be changed if we change the format of the list */ - + if ((list_ent = check_dir_ent(dir->dir_list, dirent)) == NULL) { errno = EINVAL; /* Bad entry */ TALLOC_FREE(frame); return -1; } - + dir->dir_next = list_ent; - + TALLOC_FREE(frame); return 0; } @@ -1474,13 +1474,13 @@ SMBC_fstatdir_ctx(SMBCCTX *context, SMBCFILE *dir, struct stat *st) { - + if (!context || !context->internal->initialized) { - + errno = EINVAL; return -1; } - + /* No code yet ... */ return 0; } @@ -1499,22 +1499,22 @@ SMBC_chmod_ctx(SMBCCTX *context, char *path = NULL; uint16 mode; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_chmod(%s, 0%3o)\n", fname, newmode)); - + if (SMBC_parse_path(frame, context, fname, @@ -1529,7 +1529,7 @@ SMBC_chmod_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -1538,28 +1538,28 @@ SMBC_chmod_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + mode = 0; - + if (!(newmode & (S_IWUSR | S_IWGRP | S_IWOTH))) mode |= aRONLY; if ((newmode & S_IXUSR) && lp_map_archive(-1)) mode |= aARCH; if ((newmode & S_IXGRP) && lp_map_system(-1)) mode |= aSYSTEM; if ((newmode & S_IXOTH) && lp_map_hidden(-1)) mode |= aHIDDEN; - + if (!cli_setatr(srv->cli, path, mode, 0)) { errno = SMBC_errno(context, srv->cli); TALLOC_FREE(frame); return -1; } - + TALLOC_FREE(frame); return 0; } @@ -1579,48 +1579,48 @@ SMBC_utimes_ctx(SMBCCTX *context, time_t access_time; time_t write_time; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + if (tbuf == NULL) { access_time = write_time = time(NULL); } else { access_time = tbuf[0].tv_sec; write_time = tbuf[1].tv_sec; } - + if (DEBUGLVL(4)) { char *p; char atimebuf[32]; char mtimebuf[32]; - + strncpy(atimebuf, ctime(&access_time), sizeof(atimebuf) - 1); atimebuf[sizeof(atimebuf) - 1] = '\0'; if ((p = strchr(atimebuf, '\n')) != NULL) { *p = '\0'; } - + strncpy(mtimebuf, ctime(&write_time), sizeof(mtimebuf) - 1); mtimebuf[sizeof(mtimebuf) - 1] = '\0'; if ((p = strchr(mtimebuf, '\n')) != NULL) { *p = '\0'; } - + dbgtext("smbc_utimes(%s, atime = %s mtime = %s)\n", fname, atimebuf, mtimebuf); } - + if (SMBC_parse_path(frame, context, fname, @@ -1635,7 +1635,7 @@ SMBC_utimes_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -1644,21 +1644,21 @@ SMBC_utimes_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_server */ } - + if (!SMBC_setatr(context, srv, path, 0, access_time, write_time, 0, 0)) { TALLOC_FREE(frame); return -1; /* errno set by SMBC_setatr */ } - + TALLOC_FREE(frame); return 0; } @@ -1681,22 +1681,22 @@ SMBC_unlink_ctx(SMBCCTX *context, struct cli_state *targetcli = NULL; SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!context || !context->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; - + } - + if (!fname) { errno = EINVAL; TALLOC_FREE(frame); return -1; - + } - + if (SMBC_parse_path(frame, context, fname, @@ -1711,7 +1711,7 @@ SMBC_unlink_ctx(SMBCCTX *context, TALLOC_FREE(frame); return -1; } - + if (!user || user[0] == (char)0) { user = talloc_strdup(frame, smbc_getUser(context)); if (!user) { @@ -1720,16 +1720,16 @@ SMBC_unlink_ctx(SMBCCTX *context, return -1; } } - + srv = SMBC_server(frame, context, True, server, share, &workgroup, &user, &password); - + if (!srv) { TALLOC_FREE(frame); return -1; /* SMBC_server sets errno */ - + } - + /*d_printf(">>>unlink: resolving %s\n", path);*/ if (!cli_resolve_path(frame, "", srv->cli, path, &targetcli, &targetpath)) { @@ -1738,13 +1738,13 @@ SMBC_unlink_ctx(SMBCCTX *context, return -1; } /*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/ - + if (!cli_unlink(targetcli, targetpath)) { - + errno = SMBC_errno(context, targetcli); - + if (errno == EACCES) { /* Check if the file is a directory */ - + int saverr = errno; SMB_OFF_T size = 0; uint16 mode = 0; @@ -1752,39 +1752,39 @@ SMBC_unlink_ctx(SMBCCTX *context, struct timespec access_time_ts; struct timespec change_time_ts; SMB_INO_T ino = 0; - + if (!SMBC_getatr(context, srv, path, &mode, &size, NULL, &access_time_ts, &write_time_ts, &change_time_ts, &ino)) { - + /* Hmmm, bad error ... What? */ - + errno = SMBC_errno(context, targetcli); TALLOC_FREE(frame); return -1; - + } else { - + if (IS_DOS_DIR(mode)) errno = EISDIR; else errno = saverr; /* Restore this */ - + } } - + TALLOC_FREE(frame); return -1; - + } - + TALLOC_FREE(frame); return 0; /* Success ... */ - + } /* @@ -1793,7 +1793,7 @@ SMBC_unlink_ctx(SMBCCTX *context, int SMBC_rename_ctx(SMBCCTX *ocontext, - const char *oname, + const char *oname, SMBCCTX *ncontext, const char *nname) { @@ -1814,24 +1814,24 @@ SMBC_rename_ctx(SMBCCTX *ocontext, struct cli_state *targetcli2 = NULL; SMBCSRV *srv = NULL; TALLOC_CTX *frame = talloc_stackframe(); - + if (!ocontext || !ncontext || !ocontext->internal->initialized || !ncontext->internal->initialized) { - + errno = EINVAL; /* Best I can think of ... */ TALLOC_FREE(frame); return -1; } - + if (!oname || !nname) { errno = EINVAL; TALLOC_FREE(frame); return -1; } - + DEBUG(4, ("smbc_rename(%s,%s)\n", oname, nname)); - + if (SMBC_parse_path(frame, ocontext, oname, @@ -1846,7 +1846,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, TALLOC_FREE(frame); return -1; } - + if (!user1 || user1[0] == (char)0) { user1 = talloc_strdup(frame, smbc_getUser(ocontext)); if (!user1) { @@ -1855,7 +1855,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, return -1; } } - + if (SMBC_parse_path(frame, ncontext, nname, @@ -1870,7 +1870,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, TALLOC_FREE(frame); return -1; } - + if (!user2 || user2[0] == (char)0) { user2 = talloc_strdup(frame, smbc_getUser(ncontext)); if (!user2) { @@ -1879,7 +1879,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, return -1; } } - + if (strcmp(server1, server2) || strcmp(share1, share2) || strcmp(user1, user2)) { /* Can't rename across file systems, or users?? */ @@ -1887,15 +1887,15 @@ SMBC_rename_ctx(SMBCCTX *ocontext, TALLOC_FREE(frame); return -1; } - + srv = SMBC_server(frame, ocontext, True, server1, share1, &workgroup, &user1, &password1); if (!srv) { TALLOC_FREE(frame); return -1; - + } - + /*d_printf(">>>rename: resolving %s\n", path1);*/ if (!cli_resolve_path(frame, "", srv->cli, path1, &targetcli1, &targetpath1)) { @@ -1912,7 +1912,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, return -1; } /*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/ - + if (strcmp(targetcli1->desthost, targetcli2->desthost) || strcmp(targetcli1->share, targetcli2->share)) { @@ -1921,21 +1921,21 @@ SMBC_rename_ctx(SMBCCTX *ocontext, TALLOC_FREE(frame); return -1; } - + if (!cli_rename(targetcli1, targetpath1, targetpath2)) { int eno = SMBC_errno(ocontext, targetcli1); - + if (eno != EEXIST || !cli_unlink(targetcli1, targetpath2) || !cli_rename(targetcli1, targetpath1, targetpath2)) { - + errno = eno; TALLOC_FREE(frame); return -1; - + } } - + TALLOC_FREE(frame); return 0; /* Success */ } -- cgit From a6fa0ca3219db5d849ad835fc994cb158c87e02a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 10 Mar 2008 04:58:43 +0100 Subject: Use rpccli_srvsvc_NetShareEnumAll in libsmbclient. Guenther (This used to be commit 6aad05f3f12fd6b3276486f60c10f5b3fd3fa17c) --- source3/libsmb/libsmb_dir.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 45db914d18..f836989004 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -261,15 +261,16 @@ net_share_enum_rpc(struct cli_state *cli, { int i; WERROR result; - ENUM_HND enum_hnd; - uint32 info_level = 1; uint32 preferred_len = 0xffffffff; uint32 type; - SRV_SHARE_INFO_CTR ctr; + struct srvsvc_NetShareInfoCtr info_ctr; + struct srvsvc_NetShareCtr1 ctr1; fstring name = ""; fstring comment = ""; struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; + uint32_t resume_handle = 0; + uint32_t total_entries = 0; /* Open the server service pipe */ pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); @@ -278,34 +279,39 @@ net_share_enum_rpc(struct cli_state *cli, return -1; } + ZERO_STRUCT(info_ctr); + ZERO_STRUCT(ctr1); + + info_ctr.level = 1; + info_ctr.ctr.ctr1 = &ctr1; + /* Issue the NetShareEnum RPC call and retrieve the response */ - init_enum_hnd(&enum_hnd, 0); - result = rpccli_srvsvc_net_share_enum(pipe_hnd, - talloc_tos(), - info_level, - &ctr, - preferred_len, - &enum_hnd); + nt_status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, talloc_tos(), + pipe_hnd->cli->desthost, + &info_ctr, + preferred_len, + &total_entries, + &resume_handle, + &result); /* Was it successful? */ - if (!W_ERROR_IS_OK(result) || ctr.num_entries == 0) { + if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result) || + total_entries == 0) { /* Nope. Go clean up. */ goto done; } /* For each returned entry... */ - for (i = 0; i < ctr.num_entries; i++) { + for (i = 0; i < total_entries; i++) { /* pull out the share name */ - rpcstr_pull_unistr2_fstring( - name, &ctr.share.info1[i].info_1_str.uni_netname); + fstrcpy(name, info_ctr.ctr.ctr1->array[i].name); /* pull out the share's comment */ - rpcstr_pull_unistr2_fstring( - comment, &ctr.share.info1[i].info_1_str.uni_remark); + fstrcpy(comment, info_ctr.ctr.ctr1->array[i].comment); /* Get the type value */ - type = ctr.share.info1[i].info_1.type; + type = info_ctr.ctr.ctr1->array[i].type; /* Add this share to the list */ (*fn)(name, type, comment, state); -- cgit From 5e86a172a567ca9a60d74d1076430fb5e70b27a6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 12 Mar 2008 16:19:56 +0100 Subject: For convenience reasons, always create cli->srv_name_slash in the rpc_client. Guenther (This used to be commit 6363c383d6989d2dfb2ee488ffa7aeb128c5385b) --- source3/libsmb/cliconnect.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 912b841d5e..5e8a586cd0 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1485,6 +1485,7 @@ NTSTATUS cli_connect(struct cli_state *cli, } fstrcpy(cli->desthost, host); + fstr_sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost); /* allow hostnames of the form NAME#xx and do a netbios lookup */ if ((p = strchr(cli->desthost, '#'))) { -- cgit From e2ab1a0f98e04e8d5b81ef485f3fd6986cec206f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 15 Mar 2008 22:22:53 +0100 Subject: Fix Coverity ID 555 (This used to be commit 44122f06d02492a7a0a37413d6f975c3b1e3c283) --- source3/libsmb/namequery.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index ad16452e3e..0191bf7618 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1051,6 +1051,7 @@ NTSTATUS resolve_wins(const char *name, DEBUG(3,("resolve_wins: cannot receive WINS replies " "on IPv6 address %s\n", addr)); + wins_srv_tags_free(wins_tags); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 8b0783072aad83f5a2ce10737ca9d3077af95bf9 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Mon, 17 Mar 2008 11:34:25 -0400 Subject: Fix use of AuthDataWithContext capability During my initial plans for, and the subsequent discussion of a more significant change to the API for libsmbclient, I had removed the AuthDataWithContext usage, in favor of a more generalized planned interface. When the API returned to its original state, I neglected to reinsert this code. Use of an authentication function with the context can be tested using examples/libsmbclient/testbrowse -C Derrell (This used to be commit 38eab68dfb2d8abe8ad00f5a86fc54c778d0d303) --- source3/libsmb/libsmb_context.c | 3 ++- source3/libsmb/libsmb_server.c | 22 ++++++++++++++++++---- 2 files changed, 20 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 3e67943c83..dd78bcee35 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -421,7 +421,8 @@ smbc_init_context(SMBCCTX *context) return NULL; } - if (!smbc_getFunctionAuthData(context) || + if ((!smbc_getFunctionAuthData(context) && + !smbc_getFunctionAuthDataWithContext(context)) || smbc_getDebug(context) < 0 || smbc_getDebug(context) > 100) { diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 37612c6e39..7af5ca3a24 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -101,15 +101,29 @@ SMBC_call_auth_fn(TALLOC_CTX *ctx, fstring workgroup; fstring username; fstring password; + smbc_get_auth_data_with_context_fn auth_with_context_fn; strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); strlcpy(username, *pp_username, sizeof(username)); strlcpy(password, *pp_password, sizeof(password)); - smbc_getFunctionAuthData(context)(server, share, - workgroup, sizeof(workgroup), - username, sizeof(username), - password, sizeof(password)); + /* See if there's an authentication with context function provided */ + auth_with_context_fn = smbc_getFunctionAuthDataWithContext(context); + if (auth_with_context_fn) + { + (* auth_with_context_fn)(context, + server, share, + workgroup, sizeof(workgroup), + username, sizeof(username), + password, sizeof(password)); + } + else + { + smbc_getFunctionAuthData(context)(server, share, + workgroup, sizeof(workgroup), + username, sizeof(username), + password, sizeof(password)); + } TALLOC_FREE(*pp_workgroup); TALLOC_FREE(*pp_username); -- cgit From 16cbc22a99c0a302d248dc006ac0016042c1e3ec Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 18 Mar 2008 13:20:10 +0100 Subject: Fix bug 5334 I did not test with a zero length file :-) (This used to be commit 7d7a73944c2dcf078f7bc8de65d575f32f9aa851) --- source3/libsmb/clireadwrite.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 9bd8170673..13c024a264 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -262,6 +262,14 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, state->pushed = 0; state->top_req = 0; + + if (size == 0) { + if (!async_post_status(result, NT_STATUS_OK)) { + goto failed; + } + return result; + } + state->chunk_size = cli_read_max_bufsize(cli); state->num_reqs = MAX(window_size/state->chunk_size, 1); -- cgit From b2ec8372bac987525e3bfa448212ea4f1d8fe5d9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Mar 2008 22:37:24 +0100 Subject: !NT_STATUS_IS_OK != NT_STATUS_IS_ERR When reading from a pipe, Windows return STATUS_BUFFER_OVERFLOW which is *not* an error. (This used to be commit 24018d882d1b1cfece47c533fe5bbca91de124cc) --- source3/libsmb/clireadwrite.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 13c024a264..64a6b7b4eb 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -136,7 +136,7 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, status = cli_pull_error(cli_req->inbuf); - if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_IS_ERR(status)) { return status; } -- cgit From fe1a6668c89b0dc2bbb3c30ab737fd4ab1146966 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 20 Mar 2008 00:31:26 +0100 Subject: Add error mapping for WERR_SERVICE_NEVER_STARTED. Guenther (This used to be commit 818044d877597ba5c11dc7f30bab929c4b41db89) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 203f682599..278875a523 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -96,6 +96,7 @@ werror_code_struct dos_errs[] = { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, { "WERR_NO_SUCH_SERVICE", WERR_NO_SUCH_SERVICE }, { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, + { "WERR_SERVICE_NEVER_STARTED", WERR_SERVICE_NEVER_STARTED }, { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE}, { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS}, { "WERR_PASSWORD_MUST_CHANGE", WERR_PASSWORD_MUST_CHANGE }, -- cgit From 4b3351e5dc07e9350cc2a846b5efe4c7e2d599f6 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 21 Mar 2008 13:39:48 +0100 Subject: On Solaris, size_t seems to be only 32 bit. Fix bug 5341, thanks a lot to Karoly Vegh for testing it! Volker (This used to be commit 19eb8c9316b10b1277121e90d0d3ef50ee562118) --- source3/libsmb/clireadwrite.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 64a6b7b4eb..f292fcb2d0 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -175,7 +175,7 @@ struct cli_pull_state { struct cli_state *cli; uint16_t fnum; off_t start_offset; - size_t size; + SMB_OFF_T size; NTSTATUS (*sink)(char *buf, size_t n, void *priv); void *priv; @@ -232,7 +232,7 @@ static void cli_pull_read_done(struct async_req *read_req); struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, uint16_t fnum, off_t start_offset, - size_t size, size_t window_size, + SMB_OFF_T size, size_t window_size, NTSTATUS (*sink)(char *buf, size_t n, void *priv), void *priv) @@ -284,7 +284,8 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, state->requested = 0; for (i=0; inum_reqs; i++) { - size_t size_left, request_thistime; + SMB_OFF_T size_left; + size_t request_thistime; if (state->requested >= size) { state->num_reqs = i; @@ -376,7 +377,8 @@ static void cli_pull_read_done(struct async_req *read_req) if (state->requested < state->size) { struct async_req *new_req; - size_t size_left, request_thistime; + SMB_OFF_T size_left; + size_t request_thistime; size_left = state->size - state->requested; request_thistime = MIN(size_left, state->chunk_size); @@ -424,7 +426,7 @@ NTSTATUS cli_pull_recv(struct async_req *req, ssize_t *received) } NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, - off_t start_offset, size_t size, size_t window_size, + off_t start_offset, SMB_OFF_T size, size_t window_size, NTSTATUS (*sink)(char *buf, size_t n, void *priv), void *priv, ssize_t *received) { -- cgit From e6a1027757ef08a5a780175b93ebdb314e91cdba Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 25 Mar 2008 22:35:20 +0100 Subject: Fix a valgrind error In winbind, we're using the info3 struct to send it to the winbind client after netsamlogon_cache_store. Without this info3->base.account_name.string was prematurely freed. (This used to be commit aa4377561b691e2c5108c18aeb34fff39d8775df) --- source3/libsmb/samlogon_cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 73b570c383..235880910c 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -149,7 +149,7 @@ bool netsamlogon_cache_store(const char *username, struct netr_SamInfo3 *info3) /* so we fill it in since winbindd_getpwnam() makes use of it */ if (!info3->base.account_name.string) { - info3->base.account_name.string = talloc_strdup(mem_ctx, username); + info3->base.account_name.string = talloc_strdup(info3, username); } r.timestamp = t; -- cgit From 76a819c9c0e8f0636e455e203bdbe086f34e1b6c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 28 Mar 2008 13:36:31 +0100 Subject: Use NDR for netr_DsRGetDCNameInfo un-/marshalling in dsgetdcname. Guenther (This used to be commit 7fa53911054a39681df3f08d19aad92f60d59e28) --- source3/libsmb/dsgetdcname.c | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index bc9f4b92c8..d0a08fddb7 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -298,8 +298,7 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, char *key; bool ret = false; DATA_BLOB blob; - unsigned char *buf = NULL; - int len = 0; + enum ndr_err_code ndr_err; if (!gencache_init()) { return NT_STATUS_INTERNAL_DB_ERROR; @@ -312,14 +311,12 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL; - len = pack_dsdcinfo(info, &buf); - if (len == -1) { - return NT_STATUS_UNSUCCESSFUL; + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info, + (ndr_push_flags_fn_t)ndr_push_netr_DsRGetDCNameInfo); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); } - blob = data_blob(buf, len); - SAFE_FREE(buf); - if (gencache_lock_entry(key) != 0) { data_blob_free(&blob); return NT_STATUS_LOCK_NOT_GRANTED; @@ -404,12 +401,13 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, struct GUID *domain_guid, uint32_t flags, const char *site_name, - struct netr_DsRGetDCNameInfo **info, + struct netr_DsRGetDCNameInfo **info_p, bool *expired) { char *key; DATA_BLOB blob; - NTSTATUS status; + enum ndr_err_code ndr_err; + struct netr_DsRGetDCNameInfo *info; if (!gencache_init()) { return NT_STATUS_INTERNAL_DB_ERROR; @@ -424,25 +422,37 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, return NT_STATUS_OBJECT_NAME_NOT_FOUND; } - status = unpack_dsdcinfo(mem_ctx, blob.data, blob.length, info); - if (!NT_STATUS_IS_OK(status)) { - data_blob_free(&blob); - return status; + info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); + if (!info) { + return NT_STATUS_NO_MEMORY; } + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, info, + (ndr_pull_flags_fn_t)ndr_pull_netr_DsRGetDCNameInfo); + data_blob_free(&blob); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + dsgetdcname_cache_delete(mem_ctx, domain_name); + return ndr_map_error2ntstatus(ndr_err); + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(netr_DsRGetDCNameInfo, info); + } /* check flags */ - if (!check_cldap_reply_required_flags((*info)->dc_flags, flags)) { + if (!check_cldap_reply_required_flags(info->dc_flags, flags)) { DEBUG(10,("invalid flags\n")); return NT_STATUS_INVALID_PARAMETER; } if ((flags & DS_IP_REQUIRED) && - ((*info)->dc_address_type != DS_ADDRESS_TYPE_INET)) { + (info->dc_address_type != DS_ADDRESS_TYPE_INET)) { return NT_STATUS_INVALID_PARAMETER_MIX; } + *info_p = info; + return NT_STATUS_OK; } -- cgit From 7f1a0a5cdf29073326457558cd474b46c670107e Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 28 Mar 2008 13:37:25 +0100 Subject: Remove unneeded pack_dsdcinfo/unpack_dsdcinfo. Guenther (This used to be commit 34dd8f32e1b7fe256ab5dfde5ef5bb8abeec121a) --- source3/libsmb/dsgetdcname.c | 144 ------------------------------------------- 1 file changed, 144 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index d0a08fddb7..7af43648d7 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -107,150 +107,6 @@ void debug_dsdcinfo_flags(int lvl, uint32_t flags) DEBUGADD(lvl,("\n")); } -/********************************************************************* - ********************************************************************/ - -static int pack_dsdcinfo(struct netr_DsRGetDCNameInfo *info, - unsigned char **buf) -{ - unsigned char *buffer = NULL; - int len = 0; - int buflen = 0; - UUID_FLAT guid_flat; - - DEBUG(10,("pack_dsdcinfo: Packing dsdcinfo\n")); - - ZERO_STRUCT(guid_flat); - - if (!GUID_all_zero(&info->domain_guid)) { - smb_uuid_pack(info->domain_guid, &guid_flat); - } - - again: - len = 0; - - if (buflen > 0) { - DEBUG(10,("pack_dsdcinfo: Packing domain %s (%s)\n", - info->domain_name, info->dc_unc)); - } - - len += tdb_pack(buffer+len, buflen-len, "ffdBffdff", - info->dc_unc, - info->dc_address, - info->dc_address_type, - UUID_FLAT_SIZE, guid_flat.info, - info->domain_name, - info->forest_name, - info->dc_flags, - info->dc_site_name, - info->client_site_name); - - if (buflen < len) { - SAFE_FREE(buffer); - if ((buffer = SMB_MALLOC_ARRAY(unsigned char, len)) == NULL ) { - DEBUG(0,("pack_dsdcinfo: failed to alloc buffer!\n")); - buflen = -1; - goto done; - } - buflen = len; - goto again; - } - - *buf = buffer; - - done: - return buflen; -} - -/********************************************************************* - ********************************************************************/ - -static NTSTATUS unpack_dsdcinfo(TALLOC_CTX *mem_ctx, - unsigned char *buf, - int buflen, - struct netr_DsRGetDCNameInfo **info_ret) -{ - int len = 0; - struct netr_DsRGetDCNameInfo *info = NULL; - uint32_t guid_len = 0; - unsigned char *guid_buf = NULL; - UUID_FLAT guid_flat; - - /* forgive me 6 times */ - fstring dc_unc; - fstring dc_address; - fstring domain_name; - fstring forest_name; - fstring dc_site_name; - fstring client_site_name; - - info = TALLOC_ZERO_P(mem_ctx, struct netr_DsRGetDCNameInfo); - NT_STATUS_HAVE_NO_MEMORY(info); - - len += tdb_unpack(buf+len, buflen-len, "ffdBffdff", - &dc_unc, - &dc_address, - &info->dc_address_type, - &guid_len, &guid_buf, - &domain_name, - &forest_name, - &info->dc_flags, - &dc_site_name, - &client_site_name); - if (len == -1) { - DEBUG(5,("unpack_dsdcinfo: Failed to unpack domain\n")); - goto failed; - } - - info->dc_unc = - talloc_strdup(mem_ctx, dc_unc); - info->dc_address = - talloc_strdup(mem_ctx, dc_address); - info->domain_name = - talloc_strdup(mem_ctx, domain_name); - info->forest_name = - talloc_strdup(mem_ctx, forest_name); - info->dc_site_name = - talloc_strdup(mem_ctx, dc_site_name); - info->client_site_name = - talloc_strdup(mem_ctx, client_site_name); - - if (!info->dc_unc || - !info->dc_address || - !info->domain_name || - !info->forest_name || - !info->dc_site_name || - !info->client_site_name) { - goto failed; - } - - if (guid_len > 0) { - struct GUID guid; - - if (guid_len != UUID_FLAT_SIZE) { - goto failed; - } - - memcpy(&guid_flat.info, guid_buf, guid_len); - smb_uuid_unpack(guid_flat, &guid); - - info->domain_guid = guid; - SAFE_FREE(guid_buf); - } - - DEBUG(10,("unpack_dcscinfo: Unpacked domain %s (%s)\n", - info->domain_name, info->dc_unc)); - - *info_ret = info; - - return NT_STATUS_OK; - - failed: - TALLOC_FREE(info); - SAFE_FREE(guid_buf); - return NT_STATUS_NO_MEMORY; -} - /**************************************************************** ****************************************************************/ -- cgit From 33a8e9b5377d2d6bffeb0640d388fa4c8e2f8c65 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 28 Mar 2008 13:40:13 +0100 Subject: Check for buffer in decode_wkssvc_join_password_buffer. Guenther (This used to be commit 2134d80c05fd7a37f44317335b40d7961c429c7b) --- source3/libsmb/smbencrypt.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index c547a4a003..e7198b801d 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -748,16 +748,24 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, struct MD5Context ctx; uint32_t pwd_len; - DATA_BLOB confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); + DATA_BLOB confounded_session_key; int confounder_len = 8; uint8_t confounder[8]; + *pwd = NULL; + + if (!pwd_buf) { + return WERR_BAD_PASSWORD; + } + if (session_key->length != 16) { DEBUG(10,("invalid session key\n")); return WERR_BAD_PASSWORD; } + confounded_session_key = data_blob_talloc(mem_ctx, NULL, 16); + memcpy(&confounder, &pwd_buf->data[0], confounder_len); memcpy(&buffer, &pwd_buf->data[8], 516); @@ -769,6 +777,7 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, SamOEMhashBlob(buffer, 516, &confounded_session_key); if (!decode_pw_buffer(mem_ctx, buffer, pwd, &pwd_len, STR_UNICODE)) { + data_blob_free(&confounded_session_key); return WERR_BAD_PASSWORD; } -- cgit From 8f6b03b673ff9d2bc012eef0e2e093b4f02db362 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 28 Mar 2008 15:21:14 +0100 Subject: More ssize_t->SMB_OFF_T (This used to be commit 8dd6458049d1b9d6849730ac19c39b049a68f302) --- source3/libsmb/clireadwrite.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index f292fcb2d0..668a2693d3 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -191,7 +191,7 @@ struct cli_pull_state { /* * For how many bytes did we send requests already? */ - off_t requested; + SMB_OFF_T requested; /* * Next request index to push into "sink". This walks around the "req" @@ -205,7 +205,7 @@ struct cli_pull_state { * How many bytes did we push into "sink"? */ - off_t pushed; + SMB_OFF_T pushed; }; static char *cli_pull_print(TALLOC_CTX *mem_ctx, struct async_req *req) @@ -412,7 +412,7 @@ static void cli_pull_read_done(struct async_req *read_req) async_req_done(pull_req); } -NTSTATUS cli_pull_recv(struct async_req *req, ssize_t *received) +NTSTATUS cli_pull_recv(struct async_req *req, SMB_OFF_T *received) { struct cli_pull_state *state = talloc_get_type_abort( req->private_data, struct cli_pull_state); @@ -428,7 +428,7 @@ NTSTATUS cli_pull_recv(struct async_req *req, ssize_t *received) NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, off_t start_offset, SMB_OFF_T size, size_t window_size, NTSTATUS (*sink)(char *buf, size_t n, void *priv), - void *priv, ssize_t *received) + void *priv, SMB_OFF_T *received) { TALLOC_CTX *frame = talloc_stackframe(); struct async_req *req; @@ -466,7 +466,7 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) { NTSTATUS status; - ssize_t ret; + SMB_OFF_T ret; status = cli_pull(cli, fnum, offset, size, size, cli_read_sink, &buf, &ret); -- cgit From 9644b6cb50ec01c04a0d6ab17a8e39054fd8b0f8 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 28 Mar 2008 15:49:13 +0100 Subject: Add a talloc context parameter to current_timestring() to fix memleaks. current_timestring used to return a string talloced to talloc_tos(). When called by DEBUG from a TALLOC_FREE, this produced messages "no talloc stackframe around, leaking memory". For example when used from net conf. This also adds a temporary talloc context to alloc_sub_basic(). For this purpose, the exit strategy is slightly altered: a common exit point is used for success and failure. Michael (This used to be commit 16b5800d4e3a8b88bac67b2550d14e0aaaa302a9) --- source3/libsmb/trusts_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index c079fb149a..8c2f69cee3 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -123,7 +123,7 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", - current_timestring(False))); + current_timestring(debug_ctx(), False))); /* * Return the result of trying to write the new password * back into the trust account file. -- cgit From d1e99642f731919bce36dd089b000ef4433b4450 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 28 Mar 2008 10:12:07 -0700 Subject: Fix bug #5326 - OS/2 servers give strange "high word" replies for print jobs. Jeremy. (This used to be commit d090d25cb702965b3d5e4635a26a06f2b62d235d) --- source3/libsmb/clireadwrite.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 668a2693d3..e79fd90614 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -745,7 +745,9 @@ ssize_t cli_write(struct cli_state *cli, break; bwritten += SVAL(cli->inbuf, smb_vwv2); - bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))<<16); + if (writesize > 0xFFFF) { + bwritten += (((int)(SVAL(cli->inbuf, smb_vwv4)))<<16); + } } while (received < issued && cli_receive_smb(cli)) { -- cgit From 99d35904552b01ef9f2adc40e16887da9eb4de69 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 2 Apr 2008 02:29:48 +0200 Subject: Fix NETLOGON credential chain with Windows 2008 all over the place. In order to avoid receiving NT_STATUS_DOWNGRADE_DETECTED from a w2k8 netr_ServerAuthenticate2 reply, we need to start with the AD netlogon negotiate flags everywhere (not only when running in security=ads). Only for NT4 we need to do a downgrade to the returned negotiate flags. Tested with w2k8, w2ksp4, w2k3r2 and nt4sp6. Guenther (This used to be commit 0970369ca0cb9ae465cff40e5c75739824daf1d0) --- source3/libsmb/trusts_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 8c2f69cee3..c3f5f2538a 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -40,7 +40,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX already have valid creds. If not we must set them up. */ if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - uint32 neg_flags = NETLOGON_NEG_SELECT_AUTH2_FLAGS; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; result = rpccli_netlogon_setup_creds(cli, cli->cli->desthost, /* server name */ -- cgit From da7863c4c9cc22ae8392b0ce42bb360ced5c0581 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 2 Apr 2008 12:23:07 +0200 Subject: Apply some const in clirap. Guenther (This used to be commit 8a1a9f967db25d3928f19e46d60af249f934f323) --- source3/libsmb/clirap2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index d5795643e8..9cc8110576 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1469,7 +1469,7 @@ int cli_NetShareDelete(struct cli_state *cli, const char * share_name ) * ************************************************************************/ -bool cli_get_pdc_name(struct cli_state *cli, char *workgroup, char **pdc_name) +bool cli_get_pdc_name(struct cli_state *cli, const char *workgroup, char **pdc_name) { char *rparam = NULL; char *rdata = NULL; -- cgit From b028fd3f8c99e6d36237f5a312fd0bc800b38edd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 2 Apr 2008 15:26:27 +0200 Subject: Add NT_STATUS_RPC_CANNOT_SUPPORT. Guenther (This used to be commit 9e15ce03ca66a0b5ffdb39dd2faaad6e0f967e31) --- source3/libsmb/nterr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 608fe9db20..fc6340342f 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -539,6 +539,7 @@ static const nt_err_code_struct nt_errs[] = { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { "STATUS_NO_MORE_FILES", STATUS_NO_MORE_FILES }, + { "NT_STATUS_RPC_CANNOT_SUPPORT", NT_STATUS_RPC_CANNOT_SUPPORT }, { NULL, NT_STATUS(0) } }; -- cgit From 69b23a39cde21989946fc9f44defec6d2302b5da Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 4 Apr 2008 01:44:43 +0200 Subject: Always uppercase cli->srv_name_slash. Not that I think it is of any importance... Guenther (This used to be commit 352f8440c74bc22416e21783e1dc5fecf5869902) --- source3/libsmb/cliconnect.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 5e8a586cd0..8bdc284693 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1486,6 +1486,7 @@ NTSTATUS cli_connect(struct cli_state *cli, fstrcpy(cli->desthost, host); fstr_sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost); + strupper_m(cli->srv_name_slash); /* allow hostnames of the form NAME#xx and do a netbios lookup */ if ((p = strchr(cli->desthost, '#'))) { -- cgit From 1a64916775e8ef5081f1cf0627f15396b6457830 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Apr 2008 15:28:14 -0700 Subject: When using plaintext ucs2 passwords clistr_push calls ucs2_align, which causes the space taken by the unicode password to be one byte too long (as we're on an odd byte boundary here). Reduce the count by 1 to cope with this. Fixes smbclient against NetApp servers which can't cope. Fix from bryan.kolodziej@allenlund.com in bug #3840. Jeremy. (This used to be commit 1e7e7d86a1ae1cd2c3cc3de9f36b7326ad249b82) --- source3/libsmb/cliconnect.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 8bdc284693..4573f39eb3 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -247,9 +247,16 @@ static NTSTATUS cli_session_setup_plaintext(struct cli_state *cli, p += clistr_push(cli, p, pass, -1, STR_TERMINATE); /* password */ SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf))); } - else { + else { + /* For ucs2 passwords clistr_push calls ucs2_align, which causes + * the space taken by the unicode password to be one byte too + * long (as we're on an odd byte boundary here). Reduce the + * count by 1 to cope with this. Fixes smbclient against NetApp + * servers which can't cope. Fix from + * bryan.kolodziej@allenlund.com in bug #3840. + */ p += clistr_push(cli, p, pass, -1, STR_UNICODE|STR_TERMINATE); /* unicode password */ - SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))); + SSVAL(cli->outbuf,smb_vwv8,PTR_DIFF(p, smb_buf(cli->outbuf))-1); } p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */ @@ -1033,7 +1040,6 @@ NTSTATUS cli_session_setup(struct cli_state *cli, } return NT_STATUS_OK; - } /**************************************************************************** -- cgit From aa41d74843dd6532c300da682472787759b6d82d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 7 Apr 2008 10:18:36 +0200 Subject: Fix a misleading debug message (This used to be commit 494b32197f0872b115f0cd1a35421d00a89360a6) --- source3/libsmb/cliconnect.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4573f39eb3..b76814e45f 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1093,8 +1093,9 @@ bool cli_send_tconX(struct cli_state *cli, if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) && *pass && passlen != 24) { if (!lp_client_lanman_auth()) { - DEBUG(1, ("Server requested LANMAN password (share-level security) but 'client use lanman auth'" - " is disabled\n")); + DEBUG(1, ("Server requested LANMAN password " + "(share-level security) but " + "'client lanman auth' is disabled\n")); return False; } -- cgit From 2dfec9e829e6e4c11ebde8c204e06b81cc596a29 Mon Sep 17 00:00:00 2001 From: James Peach Date: Mon, 7 Apr 2008 15:00:41 -0700 Subject: Use bool for BOOL and true/false for True/False. We need lowercase bool to get the declarations picked up by the prototype parser. (This used to be commit fd168e7b5065ba15b1cf56522b6810b8e6fdd7d5) --- source3/libsmb/asn1.c | 139 +++++++++++++++++++++++++++----------------------- 1 file changed, 76 insertions(+), 63 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 99c5b0b1bd..bdbe49b111 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -36,19 +36,19 @@ void asn1_free(ASN1_DATA *data) /* write to the ASN1 buffer, advancing the buffer pointer */ bool asn1_write(ASN1_DATA *data, const void *p, int len) { - if (data->has_error) return False; + if (data->has_error) return false; if (data->length < data->ofs+len) { data->data = SMB_REALLOC_ARRAY(data->data, unsigned char, data->ofs+len); if (!data->data) { - data->has_error = True; - return False; + data->has_error = true; + return false; } data->length = data->ofs+len; } memcpy(data->data + data->ofs, p, len); data->ofs += len; - return True; + return true; } /* useful fn for writing a uint8 */ @@ -65,8 +65,8 @@ bool asn1_push_tag(ASN1_DATA *data, uint8 tag) asn1_write_uint8(data, tag); nesting = SMB_MALLOC_P(struct nesting); if (!nesting) { - data->has_error = True; - return False; + data->has_error = true; + return false; } nesting->start = data->ofs; @@ -82,14 +82,14 @@ bool asn1_pop_tag(ASN1_DATA *data) size_t len; if (data->has_error) { - return False; + return false; } nesting = data->nesting; if (!nesting) { - data->has_error = True; - return False; + data->has_error = true; + return false; } len = data->ofs - (nesting->start+1); /* yes, this is ugly. We don't know in advance how many bytes the length @@ -97,23 +97,23 @@ bool asn1_pop_tag(ASN1_DATA *data) need to correct our mistake */ if (len > 0xFFFF) { data->data[nesting->start] = 0x83; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; memmove(data->data+nesting->start+4, data->data+nesting->start+1, len); data->data[nesting->start+1] = (len>>16) & 0xFF; data->data[nesting->start+2] = (len>>8) & 0xFF; data->data[nesting->start+3] = len&0xff; } else if (len > 255) { data->data[nesting->start] = 0x82; - if (!asn1_write_uint8(data, 0)) return False; - if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return false; + if (!asn1_write_uint8(data, 0)) return false; memmove(data->data+nesting->start+3, data->data+nesting->start+1, len); data->data[nesting->start+1] = len>>8; data->data[nesting->start+2] = len&0xff; } else if (len > 127) { data->data[nesting->start] = 0x81; - if (!asn1_write_uint8(data, 0)) return False; + if (!asn1_write_uint8(data, 0)) return false; memmove(data->data+nesting->start+2, data->data+nesting->start+1, len); data->data[nesting->start+1] = len; } else { @@ -122,14 +122,14 @@ bool asn1_pop_tag(ASN1_DATA *data) data->nesting = nesting->next; free(nesting); - return True; + return true; } /* write an integer */ bool asn1_write_Integer(ASN1_DATA *data, int i) { - if (!asn1_push_tag(data, ASN1_INTEGER)) return False; + if (!asn1_push_tag(data, ASN1_INTEGER)) return false; do { asn1_write_uint8(data, i); i = i >> 8; @@ -145,13 +145,13 @@ bool asn1_write_OID(ASN1_DATA *data, const char *OID) char *newp; if (!asn1_push_tag(data, ASN1_OID)) - return False; + return false; v = strtol(p, &newp, 10); p = newp; v2 = strtol(p, &newp, 10); p = newp; if (!asn1_write_uint8(data, 40*v + v2)) - return False; + return false; while (*p) { v = strtol(p, &newp, 10); @@ -161,7 +161,7 @@ bool asn1_write_OID(ASN1_DATA *data, const char *OID) if (v >= (1<<14)) asn1_write_uint8(data, 0x80 | ((v>>14)&0xff)); if (v >= (1<<7)) asn1_write_uint8(data, 0x80 | ((v>>7)&0xff)); if (!asn1_write_uint8(data, v&0x7f)) - return False; + return false; } return asn1_pop_tag(data); } @@ -209,13 +209,13 @@ bool asn1_check_BOOLEAN(ASN1_DATA *data, bool v) asn1_read_uint8(data, &b); if (b != ASN1_BOOLEAN) { - data->has_error = True; - return False; + data->has_error = true; + return false; } asn1_read_uint8(data, &b); if (b != v) { - data->has_error = True; - return False; + data->has_error = true; + return false; } return !data->has_error; } @@ -227,31 +227,31 @@ bool asn1_load(ASN1_DATA *data, DATA_BLOB blob) ZERO_STRUCTP(data); data->data = (unsigned char *)memdup(blob.data, blob.length); if (!data->data) { - data->has_error = True; - return False; + data->has_error = true; + return false; } data->length = blob.length; - return True; + return true; } /* read from a ASN1 buffer, advancing the buffer pointer */ bool asn1_read(ASN1_DATA *data, void *p, int len) { if (data->has_error) - return False; + return false; if (len < 0 || data->ofs + len < data->ofs || data->ofs + len < len) { - data->has_error = True; - return False; + data->has_error = true; + return false; } if (data->ofs + len > data->length) { - data->has_error = True; - return False; + data->has_error = true; + return false; } memcpy(p, data->data + data->ofs, len); data->ofs += len; - return True; + return true; } /* read a uint8 from a ASN1 buffer */ @@ -260,6 +260,19 @@ bool asn1_read_uint8(ASN1_DATA *data, uint8 *v) return asn1_read(data, v, 1); } +/* + * Check thta the value of the ASN1 buffer at the current offset equals tag. + */ +bool asn1_check_tag(ASN1_DATA *data, uint8 tag) +{ + if (data->has_error || data->ofs >= data->length || data->ofs < 0) { + data->has_error = true; + return false; + } + + return (tag == data->data[data->ofs]); +} + /* start reading a nested asn1 structure */ bool asn1_start_tag(ASN1_DATA *data, uint8 tag) { @@ -267,34 +280,34 @@ bool asn1_start_tag(ASN1_DATA *data, uint8 tag) struct nesting *nesting; if (!asn1_read_uint8(data, &b)) - return False; + return false; if (b != tag) { - data->has_error = True; - return False; + data->has_error = true; + return false; } nesting = SMB_MALLOC_P(struct nesting); if (!nesting) { - data->has_error = True; - return False; + data->has_error = true; + return false; } if (!asn1_read_uint8(data, &b)) { SAFE_FREE(nesting); - return False; + return false; } if (b & 0x80) { int n = b & 0x7f; if (!asn1_read_uint8(data, &b)) { SAFE_FREE(nesting); - return False; + return false; } nesting->taglen = b; while (n > 1) { if (!asn1_read_uint8(data, &b)) { SAFE_FREE(nesting); - return False; + return false; } nesting->taglen = (nesting->taglen << 8) | b; n--; @@ -316,20 +329,20 @@ bool asn1_end_tag(ASN1_DATA *data) /* make sure we read it all */ if (asn1_tag_remaining(data) != 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } nesting = data->nesting; if (!nesting) { - data->has_error = True; - return False; + data->has_error = true; + return false; } data->nesting = nesting->next; free(nesting); - return True; + return true; } /* work out how many bytes are left in this nested tag */ @@ -339,7 +352,7 @@ int asn1_tag_remaining(ASN1_DATA *data) return 0; if (!data->nesting) { - data->has_error = True; + data->has_error = true; return -1; } return data->nesting->taglen - (data->ofs - data->nesting->start); @@ -407,15 +420,15 @@ bool asn1_check_OID(ASN1_DATA *data, const char *OID) char *id; if (!asn1_read_OID(data, &id)) { - return False; + return false; } if (strcmp(id, OID) != 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } free(id); - return True; + return true; } /* read a GeneralString from a ASN1 buffer */ @@ -427,17 +440,17 @@ bool asn1_read_GeneralString(ASN1_DATA *data, char **s) *s = NULL; if (!asn1_start_tag(data, ASN1_GENERAL_STRING)) { - return False; + return false; } len = asn1_tag_remaining(data); if (len < 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } str = SMB_MALLOC_ARRAY(char, len+1); if (!str) { - data->has_error = True; - return False; + data->has_error = true; + return false; } asn1_read(data, str, len); str[len] = 0; @@ -454,11 +467,11 @@ bool asn1_read_OctetString(ASN1_DATA *data, DATA_BLOB *blob) { int len; ZERO_STRUCTP(blob); - if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return False; + if (!asn1_start_tag(data, ASN1_OCTET_STRING)) return false; len = asn1_tag_remaining(data); if (len < 0) { - data->has_error = True; - return False; + data->has_error = true; + return false; } *blob = data_blob(NULL, len); asn1_read(data, blob->data, len); @@ -472,7 +485,7 @@ bool asn1_read_Integer(ASN1_DATA *data, int *i) uint8 b; *i = 0; - if (!asn1_start_tag(data, ASN1_INTEGER)) return False; + if (!asn1_start_tag(data, ASN1_INTEGER)) return false; while (asn1_tag_remaining(data)>0) { asn1_read_uint8(data, &b); *i = (*i << 8) + b; @@ -485,12 +498,12 @@ bool asn1_read_Integer(ASN1_DATA *data, int *i) bool asn1_check_enumerated(ASN1_DATA *data, int v) { uint8 b; - if (!asn1_start_tag(data, ASN1_ENUMERATED)) return False; + if (!asn1_start_tag(data, ASN1_ENUMERATED)) return false; asn1_read_uint8(data, &b); asn1_end_tag(data); if (v != b) - data->has_error = False; + data->has_error = false; return !data->has_error; } @@ -498,7 +511,7 @@ bool asn1_check_enumerated(ASN1_DATA *data, int v) /* write an enumarted value to the stream */ bool asn1_write_enumerated(ASN1_DATA *data, uint8 v) { - if (!asn1_push_tag(data, ASN1_ENUMERATED)) return False; + if (!asn1_push_tag(data, ASN1_ENUMERATED)) return false; asn1_write_uint8(data, v); asn1_pop_tag(data); return !data->has_error; -- cgit From f700ee6418c7b861efdb0f8eaa61b99ad598b7c3 Mon Sep 17 00:00:00 2001 From: Bill Ricker Date: Mon, 7 Apr 2008 15:02:56 -0700 Subject: Fix Kerberos interop with Mac OS X 10.5 clients. Ignore optional req_flags. Use the Kerberos mechanism OID negotiated with the client rather than hardcoding OID_KERBEROS5_OLD. (This used to be commit 59a2bcf30fef14ecc826271862b645dd3a61cb48) --- source3/libsmb/clispnego.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a75032a47d..fa9dba098f 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -246,6 +246,18 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_end_tag(&data); asn1_end_tag(&data); + /* Skip any optional req_flags that are sent per RFC 4178 */ + if (asn1_check_tag(&data, ASN1_CONTEXT(1))) { + uint8 flags; + + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_BITFIELD); + while (asn1_tag_remaining(&data) > 0) + asn1_read_uint8(&data, &flags); + asn1_end_tag(&data); + asn1_end_tag(&data); + } + asn1_start_tag(&data, ASN1_CONTEXT(2)); asn1_read_OctetString(&data,secblob); asn1_end_tag(&data); -- cgit From e49200c1a2836bda4a86b034153365b8d9e99ce1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 8 Apr 2008 14:10:48 +0200 Subject: Add CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS define. This allows to switch on the cli->fallback_after_kerberos switch. Guenther (This used to be commit 15ba45e567d910c1b2336dcc0c475e12b082f30f) --- source3/libsmb/cliconnect.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index b76814e45f..949bca747d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1652,6 +1652,11 @@ again: else if (flags & CLI_FULL_CONNECTION_USE_KERBEROS) cli->use_kerberos = True; + if ((flags & CLI_FULL_CONNECTION_FALLBACK_AFTER_KERBEROS) && + cli->use_kerberos) { + cli->fallback_after_kerberos = true; + } + if (!cli_negprot(cli)) { DEBUG(1,("failed negprot\n")); nt_status = cli_nt_error(cli); -- cgit From 1db69e9180d28c1abcc85e017561c36007a3ab5b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 10 Apr 2008 21:21:27 +0200 Subject: Add some more cli_cm_set_X functions. Guenther (This used to be commit 882475f5566592b3a675d3609c3af8cf7d4e256d) --- source3/libsmb/clidfs.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 971cde1252..0b55d930aa 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -46,6 +46,7 @@ static struct cm_cred_struct { char *password; bool got_pass; bool use_kerberos; + bool fallback_after_kerberos; int signing_state; } cm_creds; @@ -172,6 +173,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, c->protocol = max_protocol; c->use_kerberos = cm_creds.use_kerberos; + c->fallback_after_kerberos = cm_creds.fallback_after_kerberos; cli_setup_signing_state(c, cm_creds.signing_state); if (!cli_session_request(c, &calling, &called)) { @@ -199,7 +201,7 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, return NULL; } - if (!cm_creds.got_pass) { + if (!cm_creds.got_pass && !cm_creds.use_kerberos) { char *pass = getpass("Password: "); if (pass) { cm_set_password(pass); @@ -461,6 +463,9 @@ static void cm_set_password(const char *newpass) } } +/**************************************************************************** +****************************************************************************/ + void cli_cm_set_credentials(void) { SAFE_FREE(cm_creds.username); @@ -471,6 +476,7 @@ void cli_cm_set_credentials(void) } cm_creds.use_kerberos = get_cmdline_auth_info_use_kerberos(); + cm_creds.fallback_after_kerberos = false; cm_creds.signing_state = get_cmdline_auth_info_signing_state(); } @@ -493,6 +499,51 @@ void cli_cm_set_dest_name_type(int type) /**************************************************************************** ****************************************************************************/ +void cli_cm_set_signing_state(int state) +{ + cm_creds.signing_state = state; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_username(const char *username) +{ + SAFE_FREE(cm_creds.username); + cm_creds.username = SMB_STRDUP(username); +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_password(const char *newpass) +{ + SAFE_FREE(cm_creds.password); + cm_creds.password = SMB_STRDUP(newpass); + if (cm_creds.password) { + cm_creds.got_pass = true; + } +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_use_kerberos(void) +{ + cm_creds.use_kerberos = true; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_fallback_after_kerberos(void) +{ + cm_creds.fallback_after_kerberos = true; +} + +/**************************************************************************** +****************************************************************************/ + void cli_cm_set_dest_ss(struct sockaddr_storage *pss) { dest_ss = *pss; -- cgit From bb869741ddc3d82da02c96bef592dab6074ff142 Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Mon, 3 Mar 2008 13:32:54 -0800 Subject: Cleanup size_t return values in convert_string_allocate This patch is the first iteration of an inside-out conversion to cleanup functions in charcnv.c returning size_t == -1 to indicate failure. (This used to be commit 59124382d2894a1b194b48dd82bc5f956959eb48) --- source3/libsmb/climessage.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/climessage.c b/source3/libsmb/climessage.c index 00c25aa725..808190e79c 100644 --- a/source3/libsmb/climessage.c +++ b/source3/libsmb/climessage.c @@ -71,7 +71,7 @@ bool cli_message_start(struct cli_state *cli, const char *host, const char *user int cli_message_text_build(struct cli_state *cli, const char *msg, int len, int grp) { char *msgdos; - int lendos; + size_t lendos; char *p; memset(cli->outbuf,'\0',smb_size); @@ -85,7 +85,8 @@ int cli_message_text_build(struct cli_state *cli, const char *msg, int len, int p = smb_buf(cli->outbuf); *p++ = 1; - if ((lendos = (int)convert_string_allocate(NULL,CH_UNIX, CH_DOS, msg,len, (void **)(void *)&msgdos, True)) < 0 || !msgdos) { + if (!convert_string_allocate(NULL, CH_UNIX, CH_DOS, msg, len, + (void **)(void *)&msgdos, &lendos, True) || !msgdos) { DEBUG(3,("Conversion failed, sending message in UNIX charset\n")); SSVAL(p, 0, len); p += 2; if (len > cli->bufsize - PTR_DIFF(p,cli->outbuf)) { -- cgit From 98abf71ff525711bda177b4b8b64f0f43d872891 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sat, 12 Apr 2008 18:30:14 +0200 Subject: Add WERR_USER_ALREADY_EXISTS and WERR_PASSWORD_RESTRICTION. Guenther (This used to be commit eefd03d39b107598e9b0d1f35def7b17073d8ebc) --- source3/libsmb/doserr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 278875a523..cd3c2fef5e 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -66,6 +66,7 @@ werror_code_struct dos_errs[] = { "WERR_USER_EXISTS", WERR_USER_EXISTS }, { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, + { "WERR_USER_ALREADY_EXISTS", WERR_USER_ALREADY_EXISTS }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, @@ -82,6 +83,7 @@ werror_code_struct dos_errs[] = { "WERR_DEFAULT_JOIN_REQUIRED", WERR_DEFAULT_JOIN_REQUIRED }, { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, + { "WERR_PASSWORD_RESTRICTION", WERR_PASSWORD_RESTRICTION }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_TIME_SKEW", WERR_TIME_SKEW }, @@ -124,6 +126,8 @@ werror_str_struct dos_err_strs[] = { { WERR_PASSWORD_MUST_CHANGE, "The password must be changed" }, { WERR_ACCOUNT_LOCKED_OUT, "Account locked out" }, { WERR_TIME_SKEW, "Time difference between client and server" }, + { WERR_USER_ALREADY_EXISTS, "User already exists" }, + { WERR_PASSWORD_RESTRICTION, "Password does not meet restrictions" }, }; /***************************************************************************** -- cgit From 394150d2692ff1249d0945f719202fdf287ff42e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 29 Mar 2008 17:20:15 +0100 Subject: Make use of ZERO_STRUCT instead of memset in namequery.c (This used to be commit 4f1d49615e1407b9c3ad5eeb50a248b8fee50e23) --- source3/libsmb/namequery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 0191bf7618..893c9265fd 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1270,7 +1270,7 @@ static NTSTATUS resolve_hosts(const char *name, int name_type, continue; } - memset(&ss, '\0', sizeof(ss)); + ZERO_STRUCT(ss); memcpy(&ss, res->ai_addr, res->ai_addrlen); *return_count += 1; -- cgit From 202e8cc57efc1f69f0d6dd57a6e9bc38ea8e4afd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 14 Apr 2008 15:48:23 +0200 Subject: doserr: Add WERR_INVALID_DOMAIN_STATE and WERR_INVALID_DOMAIN_ROLE. Guenther (This used to be commit 91a55fc27dc100cf193cfa2613771312f018449e) --- source3/libsmb/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index cd3c2fef5e..fb5f2e1bac 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -86,6 +86,8 @@ werror_code_struct dos_errs[] = { "WERR_PASSWORD_RESTRICTION", WERR_PASSWORD_RESTRICTION }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, + { "WERR_INVALID_DOMAIN_STATE", WERR_INVALID_DOMAIN_STATE }, + { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, { "WERR_TIME_SKEW", WERR_TIME_SKEW }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, -- cgit From 44912a9fb9e2cf96b0117790fb6d5e4e7c6eca45 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 16 Apr 2008 02:23:20 +0200 Subject: errors: Add WERR_NONE_MAPPED. Guenther (This used to be commit dc165e1c80586664ddb4d3d68182598d02ba204a) --- source3/libsmb/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index fb5f2e1bac..3ac1568122 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -85,6 +85,7 @@ werror_code_struct dos_errs[] = { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, { "WERR_PASSWORD_RESTRICTION", WERR_PASSWORD_RESTRICTION }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, + { "WERR_NONE_MAPPED", WERR_NONE_MAPPED }, { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_DOMAIN_STATE", WERR_INVALID_DOMAIN_STATE }, { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, @@ -130,6 +131,7 @@ werror_str_struct dos_err_strs[] = { { WERR_TIME_SKEW, "Time difference between client and server" }, { WERR_USER_ALREADY_EXISTS, "User already exists" }, { WERR_PASSWORD_RESTRICTION, "Password does not meet restrictions" }, + { WERR_NONE_MAPPED, "Could not map names to SIDs" }, }; /***************************************************************************** -- cgit From c1d4243c5a02dad3159c494697dea9154a6ea199 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 16 Apr 2008 02:37:27 +0200 Subject: errors: Add WERR_NO_SUCH_USER. Guenther (This used to be commit 82803186febfe6a55c1a598073657c2c4a513000) --- source3/libsmb/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 3ac1568122..8761106e58 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -67,6 +67,7 @@ werror_code_struct dos_errs[] = { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, { "WERR_USER_ALREADY_EXISTS", WERR_USER_ALREADY_EXISTS }, + { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, @@ -132,6 +133,7 @@ werror_str_struct dos_err_strs[] = { { WERR_USER_ALREADY_EXISTS, "User already exists" }, { WERR_PASSWORD_RESTRICTION, "Password does not meet restrictions" }, { WERR_NONE_MAPPED, "Could not map names to SIDs" }, + { WERR_NO_SUCH_USER, "No such User" }, }; /***************************************************************************** -- cgit From f466e53b64fffa34b3af33f0380ece5886db5c91 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 16 Apr 2008 23:56:03 +0200 Subject: dsgetdcname: Fix discover_dc_dns. Guenther (This used to be commit 2fe416ffa5c7efd2e6a644e4c8bac756152881d9) --- source3/libsmb/dsgetdcname.c | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 7af43648d7..00841f0684 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -418,6 +418,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, struct dns_rr_srv *dcs = NULL; int numdcs = 0; int numaddrs = 0; + struct ip_service_name *dclist = NULL; + int count = 0; if ((!(flags & DS_DIRECTORY_SERVICE_REQUIRED)) && (!(flags & DS_KDC_REQUIRED)) && @@ -460,9 +462,10 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, numaddrs += MAX(dcs[i].num_ips,1); } - if ((*returned_dclist = TALLOC_ZERO_ARRAY(mem_ctx, - struct ip_service_name, - numaddrs)) == NULL) { + dclist = TALLOC_ZERO_ARRAY(mem_ctx, + struct ip_service_name, + numaddrs); + if (!dclist) { return NT_STATUS_NO_MEMORY; } @@ -471,15 +474,16 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, *return_count = 0; i = 0; j = 0; - while (i < numdcs && (*return_countport = dcs[i].port; r->hostname = dcs[i].hostname; if (!(flags & DS_IP_REQUIRED)) { - (*return_count)++; + count++; continue; } @@ -511,13 +515,19 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, * anything about the DC's -- jerry */ if (!is_zero_addr(&r->ss)) { - (*return_count)++; + count++; continue; } } - return (*return_count > 0) ? NT_STATUS_OK : - NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + *returned_dclist = dclist; + *return_count = count; + + if (count > 0) { + return NT_STATUS_OK; + } + + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; } /**************************************************************** @@ -590,7 +600,7 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, const char *domain_name, uint32_t flags, - struct ip_service_name **dclist, + struct ip_service_name *dclist, int num_dcs, struct netr_DsRGetDCNameInfo **info) { @@ -607,7 +617,9 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, ZERO_STRUCT(r); - if ((ads_cldap_netlogon(dclist[i]->hostname, + DEBUG(10,("LDAP ping to %s\n", dclist[i].hostname)); + + if ((ads_cldap_netlogon(dclist[i].hostname, domain_name, &r)) && (check_cldap_reply_required_flags(r.flags, flags))) { valid_dc = true; @@ -645,7 +657,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, if (flags & DS_IP_REQUIRED) { char addr[INET6_ADDRSTRLEN]; - print_sockaddr(addr, sizeof(addr), &dclist[i]->ss); + print_sockaddr(addr, sizeof(addr), &dclist[i].ss); dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr); dc_address_type = DS_ADDRESS_TYPE_INET; @@ -723,7 +735,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, NT_STATUS_NOT_OK_RETURN(status); return process_dc_dns(mem_ctx, domain_name, flags, - &dclist, num_dcs, info); + dclist, num_dcs, info); } status = discover_dc_dns(mem_ctx, domain_name, domain_guid, flags, @@ -731,7 +743,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, if (NT_STATUS_IS_OK(status) && num_dcs != 0) { - status = process_dc_dns(mem_ctx, domain_name, flags, &dclist, + status = process_dc_dns(mem_ctx, domain_name, flags, dclist, num_dcs, info); if (NT_STATUS_IS_OK(status)) { return status; -- cgit From bbded540b689d3f0c6ed3ddb61eae3b8a5569372 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 16 Apr 2008 23:52:34 +0200 Subject: Move GETDC mailslot out of winbindd. Guenther (This used to be commit b003ba65e34bb92bf71a7943957715cd7acbcce0) --- source3/libsmb/clidgram.c | 165 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 66c6ee1022..baee95b9aa 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -119,3 +119,168 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, MSG_SEND_PACKET, (uint8 *)&p, sizeof(p))); } + +static void mailslot_name(struct in_addr dc_ip, fstring name) +{ + fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr); +} + +bool send_getdc_request(struct messaging_context *msg_ctx, + struct sockaddr_storage *dc_ss, + const char *domain_name, + const DOM_SID *sid) +{ + char outbuf[1024]; + struct in_addr dc_ip; + char *p; + fstring my_acct_name; + fstring my_mailslot; + size_t sid_size; + + if (dc_ss->ss_family != AF_INET) { + return false; + } + + dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; + mailslot_name(dc_ip, my_mailslot); + + memset(outbuf, '\0', sizeof(outbuf)); + + p = outbuf; + + SCVAL(p, 0, SAMLOGON); + p++; + + SCVAL(p, 0, 0); /* Count pointer ... */ + p++; + + SIVAL(p, 0, 0); /* The sender's token ... */ + p += 2; + + p += dos_PutUniCode(p, global_myname(), + sizeof(outbuf) - PTR_DIFF(p, outbuf), True); + fstr_sprintf(my_acct_name, "%s$", global_myname()); + p += dos_PutUniCode(p, my_acct_name, + sizeof(outbuf) - PTR_DIFF(p, outbuf), True); + + if (strlen(my_mailslot)+1 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) { + return false; + } + + memcpy(p, my_mailslot, strlen(my_mailslot)+1); + p += strlen(my_mailslot)+1; + + if (sizeof(outbuf) - PTR_DIFF(p, outbuf) < 8) { + return false; + } + + SIVAL(p, 0, 0x80); + p+=4; + + sid_size = ndr_size_dom_sid(sid, 0); + + SIVAL(p, 0, sid_size); + p+=4; + + p = ALIGN4(p, outbuf); + if (PTR_DIFF(p, outbuf) > sizeof(outbuf)) { + return false; + } + + if (sid_size + 8 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) { + return false; + } + if (sid) { + sid_linearize(p, sizeof(outbuf) - PTR_DIFF(p, outbuf), sid); + } + + p += sid_size; + + SIVAL(p, 0, 1); + SSVAL(p, 4, 0xffff); + SSVAL(p, 6, 0xffff); + p+=8; + + return cli_send_mailslot(msg_ctx, + False, "\\MAILSLOT\\NET\\NTLOGON", 0, + outbuf, PTR_DIFF(p, outbuf), + global_myname(), 0, domain_name, 0x1c, + dc_ss); +} + +bool receive_getdc_response(struct sockaddr_storage *dc_ss, + const char *domain_name, + fstring dc_name) +{ + struct packet_struct *packet; + fstring my_mailslot; + char *buf, *p; + fstring dcname, user, domain; + int len; + struct in_addr dc_ip; + + if (dc_ss->ss_family != AF_INET) { + return false; + } + dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; + mailslot_name(dc_ip, my_mailslot); + + packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot); + + if (packet == NULL) { + DEBUG(5, ("Did not receive packet for %s\n", my_mailslot)); + return False; + } + + DEBUG(5, ("Received packet for %s\n", my_mailslot)); + + buf = packet->packet.dgram.data; + len = packet->packet.dgram.datasize; + + if (len < 70) { + /* 70 is a completely arbitrary value to make sure + the SVAL below does not read uninitialized memory */ + DEBUG(3, ("GetDC got short response\n")); + return False; + } + + /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */ + p = buf+SVAL(buf, smb_vwv10); + + switch (CVAL(p, 0)) { + case SAMLOGON_R: + case SAMLOGON_UNK_R: + p+=2; + pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p), + STR_TERMINATE|STR_NOALIGN); + p = skip_unibuf(p, PTR_DIFF(buf+len, p)); + pull_ucs2(buf, user, p, sizeof(user), PTR_DIFF(buf+len, p), + STR_TERMINATE|STR_NOALIGN); + p = skip_unibuf(p, PTR_DIFF(buf+len, p)); + pull_ucs2(buf, domain, p, sizeof(domain), PTR_DIFF(buf+len, p), + STR_TERMINATE|STR_NOALIGN); + p = skip_unibuf(p, PTR_DIFF(buf+len, p)); + + if (!strequal(domain, domain_name)) { + DEBUG(3, ("GetDC: Expected domain %s, got %s\n", + domain_name, domain)); + return False; + } + break; + + default: + DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0))); + return False; + } + p = dcname; + if (*p == '\\') p += 1; + if (*p == '\\') p += 1; + + fstrcpy(dc_name, p); + + DEBUG(10, ("GetDC gave name %s for domain %s\n", + dc_name, domain)); + + return True; +} + -- cgit From b7d2e94296f2201177e2fc08b0c6e12e4a36af50 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 16:54:26 +0200 Subject: Fix bug 5399 Thanks to Jason Mader! Volker (This used to be commit 36740f4959194cfaa98b1e37eed08f22edbda1e4) --- source3/libsmb/clireadwrite.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index e79fd90614..12ba4b737f 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -150,11 +150,6 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, return NT_STATUS_UNEXPECTED_IO_ERROR; } - if (size < 0) { - DEBUG(5,("read return < 0!\n")); - return NT_STATUS_UNEXPECTED_IO_ERROR; - } - *rcvbuf = (uint8_t *) (smb_base(cli_req->inbuf) + SVAL(cli_req->inbuf, smb_vwv6)); *received = size; -- cgit From b46d340fd5d7e88684ac77000e17c1899ff608b2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 18:17:13 +0200 Subject: Refactoring: Make struct rpc_pipe_client its own talloc parent (This used to be commit a6d74a5a562b54f0b36934965f545fdeb1e8b34a) --- source3/libsmb/clientgen.c | 2 +- source3/libsmb/passchange.c | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 64191239d3..860cb948ac 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -650,7 +650,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) cli->pipe_name, cli->cli->desthost )); DLIST_REMOVE(cli->cli->pipe_list, cli); - talloc_destroy(cli->mem_ctx); + talloc_destroy(cli); return ret; } diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 468750f801..2f9a87dee4 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -177,8 +177,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } } - if (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, pipe_hnd->mem_ctx, user_name, - new_passwd, old_passwd))) { + result = rpccli_samr_chgpasswd_user(pipe_hnd, talloc_tos(), + user_name, new_passwd, old_passwd); + if (NT_STATUS_IS_OK(result)) { /* Great - it all worked! */ cli_shutdown(cli); return NT_STATUS_OK; @@ -206,11 +207,9 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); if ( pipe_hnd && - (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user(pipe_hnd, - pipe_hnd->mem_ctx, - user_name, - new_passwd, - old_passwd)))) { + (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user( + pipe_hnd, talloc_tos(), user_name, + new_passwd, old_passwd)))) { /* Great - it all worked! */ cli_shutdown(cli); return NT_STATUS_OK; -- cgit From 2a2188591b5ed922d09dc723adcf10f8b8f5e5a0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 21:56:43 +0200 Subject: Add "desthost" to rpc_pipe_client This reduces the dependency on cli_state (This used to be commit 783afab9c891dd7bcb78895b2a639b6f3a0edf5b) --- source3/libsmb/clientgen.c | 4 ++-- source3/libsmb/libsmb_dir.c | 2 +- source3/libsmb/trusts_util.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 860cb948ac..ef2c2639cd 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -638,7 +638,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) "to machine %s. Error was %s\n", cli->pipe_name, (int) cli->fnum, - cli->cli->desthost, + cli->desthost, cli_errstr(cli->cli))); } @@ -647,7 +647,7 @@ bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) } DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", - cli->pipe_name, cli->cli->desthost )); + cli->pipe_name, cli->desthost )); DLIST_REMOVE(cli->cli->pipe_list, cli); talloc_destroy(cli); diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index f836989004..612a8772c0 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -287,7 +287,7 @@ net_share_enum_rpc(struct cli_state *cli, /* Issue the NetShareEnum RPC call and retrieve the response */ nt_status = rpccli_srvsvc_NetShareEnumAll(pipe_hnd, talloc_tos(), - pipe_hnd->cli->desthost, + pipe_hnd->desthost, &info_ctr, preferred_len, &total_entries, diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index c3f5f2538a..20ac0143fd 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -43,7 +43,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; result = rpccli_netlogon_setup_creds(cli, - cli->cli->desthost, /* server name */ + cli->desthost, /* server name */ lp_workgroup(), /* domain */ global_myname(), /* client name */ global_myname(), /* machine account name */ -- cgit From 9048cafbeaf82d1916de6538024fd660612dd25f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 19 Apr 2008 23:03:16 +0200 Subject: Move srv_name_slash from cli_state to rpc_pipe_client (This used to be commit a9061e52e1ff8e31aa480f4a30cda64c9d93214e) --- source3/libsmb/cliconnect.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 949bca747d..7d3d246da5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1492,8 +1492,6 @@ NTSTATUS cli_connect(struct cli_state *cli, } fstrcpy(cli->desthost, host); - fstr_sprintf(cli->srv_name_slash, "\\\\%s", cli->desthost); - strupper_m(cli->srv_name_slash); /* allow hostnames of the form NAME#xx and do a netbios lookup */ if ((p = strchr(cli->desthost, '#'))) { -- cgit From f56eedb95c64593ceff0ef91b99729c5071aa7ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 11:45:41 +0200 Subject: Remove the pipe_idx variable from rpc_pipe_client (This used to be commit 4840febcd481563c3d9b2fabc1fe1b2ae5a76cf6) --- source3/libsmb/libsmb_xattr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index e17146e611..8763205d1f 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -39,7 +39,7 @@ find_lsa_pipe_hnd(struct cli_state *ipc_cli) pipe_hnd; pipe_hnd = pipe_hnd->next) { - if (pipe_hnd->pipe_idx == PI_LSARPC) { + if (rpccli_is_pipe_idx(pipe_hnd, PI_LSARPC)) { return pipe_hnd; } } -- cgit From e73e8297f5484b6c7f525917679414c09a145cf0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Apr 2008 13:51:46 +0200 Subject: Replace cli_rpc_pipe_close by a talloc destructor on rpc_pipe_struct (This used to be commit 99fc3283c4ecc791f5a242bd1983b4352ce3e6cf) --- source3/libsmb/clientgen.c | 48 +++++---------------------------------------- source3/libsmb/libsmb_dir.c | 2 +- source3/libsmb/passchange.c | 2 +- 3 files changed, 7 insertions(+), 45 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ef2c2639cd..e64b6fa278 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -616,55 +616,17 @@ struct cli_state *cli_initialise(void) return NULL; } -/**************************************************************************** - External interface. - Close an open named pipe over SMB. Free any authentication data. - Returns false if the cli_close call failed. - ****************************************************************************/ - -bool cli_rpc_pipe_close(struct rpc_pipe_client *cli) -{ - bool ret; - - if (!cli) { - return false; - } - - ret = cli_close(cli->cli, cli->fnum); - - if (!ret) { - DEBUG(1,("cli_rpc_pipe_close: cli_close failed on pipe %s, " - "fnum 0x%x " - "to machine %s. Error was %s\n", - cli->pipe_name, - (int) cli->fnum, - cli->desthost, - cli_errstr(cli->cli))); - } - - if (cli->auth.cli_auth_data_free_func) { - (*cli->auth.cli_auth_data_free_func)(&cli->auth); - } - - DEBUG(10,("cli_rpc_pipe_close: closed pipe %s to machine %s\n", - cli->pipe_name, cli->desthost )); - - DLIST_REMOVE(cli->cli->pipe_list, cli); - talloc_destroy(cli); - return ret; -} - /**************************************************************************** Close all pipes open on this session. ****************************************************************************/ void cli_nt_pipes_close(struct cli_state *cli) { - struct rpc_pipe_client *cp, *next; - - for (cp = cli->pipe_list; cp; cp = next) { - next = cp->next; - cli_rpc_pipe_close(cp); + while (cli->pipe_list != NULL) { + /* + * No TALLOC_FREE here! + */ + talloc_free(cli->pipe_list); } } diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 612a8772c0..aea4f103b6 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -319,7 +319,7 @@ net_share_enum_rpc(struct cli_state *cli, done: /* Close the server service pipe */ - cli_rpc_pipe_close(pipe_hnd); + TALLOC_FREE(pipe_hnd); /* Tell 'em if it worked */ return W_ERROR_IS_OK(result) ? 0 : -1; diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 2f9a87dee4..8f7cbf265e 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -196,7 +196,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } /* OK, that failed, so try again... */ - cli_rpc_pipe_close(pipe_hnd); + TALLOC_FREE(pipe_hnd); /* Try anonymous NTLMSSP... */ cli_init_creds(cli, "", "", NULL); -- cgit From e03321697efa5d43fdb3de409bc39abb9678ad4d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Sun, 20 Apr 2008 22:56:09 +0200 Subject: cli_cm: Make nicer password prompt in do_connect(). Guenther (This used to be commit cc967e76a39808e8311cc96c17078a0fce26c11a) --- source3/libsmb/clidfs.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 0b55d930aa..7b63f9535e 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -202,10 +202,15 @@ static struct cli_state *do_connect(TALLOC_CTX *ctx, } if (!cm_creds.got_pass && !cm_creds.use_kerberos) { - char *pass = getpass("Password: "); + char *label = NULL; + char *pass; + label = talloc_asprintf(ctx, "Enter %s's password: ", + cm_creds.username); + pass = getpass(label); if (pass) { cm_set_password(pass); } + TALLOC_FREE(label); } username = cm_creds.username ? cm_creds.username : ""; -- cgit From b437f095956165e930d88bb08cb7eb117a41ccbc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 10:25:28 +0200 Subject: samlogoncache: Use data_blob_const in netsamlogon_cache_get. Guenther (This used to be commit f27a20f25c9b2038621a6394821bbedbf17daa73) --- source3/libsmb/samlogon_cache.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 235880910c..2d2588f70c 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -213,8 +213,7 @@ struct netr_SamInfo3 *netsamlogon_cache_get(TALLOC_CTX *mem_ctx, const DOM_SID * goto done; } - blob.data = (uint8 *)data.dptr; - blob.length = data.dsize; + blob = data_blob_const(data.dptr, data.dsize); ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, (ndr_pull_flags_fn_t)ndr_pull_netsamlogoncache_entry); -- cgit From 937091161b82782d3578c80a6e56123c86050752 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 10:55:23 +0200 Subject: winbind: Use libnbt for NTLOGON SAMLOGON mailslot request and reply. Guenther (This used to be commit 2d6a1c5da64195784b0b102edb268356a24d84b5) --- source3/libsmb/clidgram.c | 207 +++++++++++++++++++++++----------------------- 1 file changed, 105 insertions(+), 102 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index baee95b9aa..fed5fc0a14 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -120,9 +120,10 @@ bool cli_send_mailslot(struct messaging_context *msg_ctx, (uint8 *)&p, sizeof(p))); } -static void mailslot_name(struct in_addr dc_ip, fstring name) +static const char *mailslot_name(TALLOC_CTX *mem_ctx, struct in_addr dc_ip) { - fstr_sprintf(name, "\\MAILSLOT\\NET\\GETDC%X", dc_ip.s_addr); + return talloc_asprintf(mem_ctx, "%s%X", + NBT_MAILSLOT_GETDC, dc_ip.s_addr); } bool send_getdc_request(struct messaging_context *msg_ctx, @@ -130,100 +131,91 @@ bool send_getdc_request(struct messaging_context *msg_ctx, const char *domain_name, const DOM_SID *sid) { - char outbuf[1024]; struct in_addr dc_ip; - char *p; - fstring my_acct_name; - fstring my_mailslot; - size_t sid_size; + const char *my_acct_name = NULL; + const char *my_mailslot = NULL; + struct nbt_ntlogon_packet packet; + struct nbt_ntlogon_sam_logon *s; + enum ndr_err_code ndr_err; + DATA_BLOB blob; + struct dom_sid my_sid; + TALLOC_CTX *mem_ctx = talloc_tos(); + + ZERO_STRUCT(packet); + ZERO_STRUCT(my_sid); if (dc_ss->ss_family != AF_INET) { return false; } - dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; - mailslot_name(dc_ip, my_mailslot); - - memset(outbuf, '\0', sizeof(outbuf)); - - p = outbuf; - - SCVAL(p, 0, SAMLOGON); - p++; - - SCVAL(p, 0, 0); /* Count pointer ... */ - p++; - - SIVAL(p, 0, 0); /* The sender's token ... */ - p += 2; - - p += dos_PutUniCode(p, global_myname(), - sizeof(outbuf) - PTR_DIFF(p, outbuf), True); - fstr_sprintf(my_acct_name, "%s$", global_myname()); - p += dos_PutUniCode(p, my_acct_name, - sizeof(outbuf) - PTR_DIFF(p, outbuf), True); + if (sid) { + my_sid = *sid; + } - if (strlen(my_mailslot)+1 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) { + dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; + my_mailslot = mailslot_name(mem_ctx, dc_ip); + if (!my_mailslot) { return false; } - memcpy(p, my_mailslot, strlen(my_mailslot)+1); - p += strlen(my_mailslot)+1; - - if (sizeof(outbuf) - PTR_DIFF(p, outbuf) < 8) { + my_acct_name = talloc_asprintf(mem_ctx, "%s$", global_myname()); + if (!my_acct_name) { return false; } - SIVAL(p, 0, 0x80); - p+=4; - - sid_size = ndr_size_dom_sid(sid, 0); - - SIVAL(p, 0, sid_size); - p+=4; - - p = ALIGN4(p, outbuf); - if (PTR_DIFF(p, outbuf) > sizeof(outbuf)) { - return false; + packet.command = NTLOGON_SAM_LOGON; + s = &packet.req.logon; + + s->request_count = 0; + s->computer_name = global_myname(); + s->user_name = my_acct_name; + s->mailslot_name = my_mailslot; + s->acct_control = ACB_WSTRUST; + s->sid = my_sid; + s->nt_version = 1; + s->lmnt_token = 0xffff; + s->lm20_token = 0xffff; + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(nbt_ntlogon_packet, &packet); } - if (sid_size + 8 > sizeof(outbuf) - PTR_DIFF(p, outbuf)) { + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &packet, + (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; } - if (sid) { - sid_linearize(p, sizeof(outbuf) - PTR_DIFF(p, outbuf), sid); - } - - p += sid_size; - - SIVAL(p, 0, 1); - SSVAL(p, 4, 0xffff); - SSVAL(p, 6, 0xffff); - p+=8; return cli_send_mailslot(msg_ctx, - False, "\\MAILSLOT\\NET\\NTLOGON", 0, - outbuf, PTR_DIFF(p, outbuf), + false, NBT_MAILSLOT_NTLOGON, 0, + (char *)blob.data, blob.length, global_myname(), 0, domain_name, 0x1c, dc_ss); } bool receive_getdc_response(struct sockaddr_storage *dc_ss, const char *domain_name, - fstring dc_name) + const char **dc_name) { struct packet_struct *packet; - fstring my_mailslot; - char *buf, *p; - fstring dcname, user, domain; - int len; + const char *my_mailslot = NULL; struct in_addr dc_ip; + TALLOC_CTX *mem_ctx = talloc_tos(); + DATA_BLOB blob; + struct nbt_ntlogon_packet r; + union dgram_message_body p; + enum ndr_err_code ndr_err; if (dc_ss->ss_family != AF_INET) { return false; } + dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; - mailslot_name(dc_ip, my_mailslot); + + my_mailslot = mailslot_name(mem_ctx, dc_ip); + if (!my_mailslot) { + return false; + } packet = receive_unexpected(DGRAM_PACKET, 0, my_mailslot); @@ -234,52 +226,63 @@ bool receive_getdc_response(struct sockaddr_storage *dc_ss, DEBUG(5, ("Received packet for %s\n", my_mailslot)); - buf = packet->packet.dgram.data; - len = packet->packet.dgram.datasize; + blob = data_blob_const(packet->packet.dgram.data, + packet->packet.dgram.datasize); - if (len < 70) { - /* 70 is a completely arbitrary value to make sure - the SVAL below does not read uninitialized memory */ - DEBUG(3, ("GetDC got short response\n")); - return False; + if (blob.length < 4) { + DEBUG(0,("invalid length: %d\n", (int)blob.length)); + return false; } - /* This should be (buf-4)+SVAL(buf-4, smb_vwv12)... */ - p = buf+SVAL(buf, smb_vwv10); - - switch (CVAL(p, 0)) { - case SAMLOGON_R: - case SAMLOGON_UNK_R: - p+=2; - pull_ucs2(buf, dcname, p, sizeof(dcname), PTR_DIFF(buf+len, p), - STR_TERMINATE|STR_NOALIGN); - p = skip_unibuf(p, PTR_DIFF(buf+len, p)); - pull_ucs2(buf, user, p, sizeof(user), PTR_DIFF(buf+len, p), - STR_TERMINATE|STR_NOALIGN); - p = skip_unibuf(p, PTR_DIFF(buf+len, p)); - pull_ucs2(buf, domain, p, sizeof(domain), PTR_DIFF(buf+len, p), - STR_TERMINATE|STR_NOALIGN); - p = skip_unibuf(p, PTR_DIFF(buf+len, p)); - - if (!strequal(domain, domain_name)) { - DEBUG(3, ("GetDC: Expected domain %s, got %s\n", - domain_name, domain)); - return False; - } - break; - - default: - DEBUG(8, ("GetDC got invalid response type %d\n", CVAL(p, 0))); - return False; + if (RIVAL(blob.data,0) != DGRAM_SMB) { + DEBUG(0,("invalid packet\n")); + return false; + } + + blob.data += 4; + blob.length -= 4; + + ndr_err = ndr_pull_union_blob_all(&blob, mem_ctx, &p, DGRAM_SMB, + (ndr_pull_flags_fn_t)ndr_pull_dgram_smb_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("failed to parse packet\n")); + return false; + } + + if (p.smb.smb_command != SMB_TRANSACTION) { + DEBUG(0,("invalid smb_command: %d\n", p.smb.smb_command)); + return false; + } + + blob = p.smb.body.trans.data; + + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, + (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0,("failed to parse packet\n")); + return false; + } + + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(nbt_ntlogon_packet, &r); + } + + if (!strequal(r.req.reply.domain, domain_name)) { + DEBUG(3, ("GetDC: Expected domain %s, got %s\n", + domain_name, r.req.reply.domain)); + return false; + } + + *dc_name = talloc_strdup(mem_ctx, r.req.reply.server); + if (!*dc_name) { + return false; } - p = dcname; - if (*p == '\\') p += 1; - if (*p == '\\') p += 1; - fstrcpy(dc_name, p); + if (**dc_name == '\\') *dc_name += 1; + if (**dc_name == '\\') *dc_name += 1; DEBUG(10, ("GetDC gave name %s for domain %s\n", - dc_name, domain)); + *dc_name, r.req.reply.domain)); return True; } -- cgit From 1eca3f138c9368116a405f3871d39884375af0dd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 17:51:36 +0200 Subject: winbind: pass down existing talloc context. Guenther (This used to be commit 675bf42cfff89b05f21d77ca74eba20c4a24d44c) --- source3/libsmb/clidgram.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index fed5fc0a14..83e50e553d 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -126,7 +126,8 @@ static const char *mailslot_name(TALLOC_CTX *mem_ctx, struct in_addr dc_ip) NBT_MAILSLOT_GETDC, dc_ip.s_addr); } -bool send_getdc_request(struct messaging_context *msg_ctx, +bool send_getdc_request(TALLOC_CTX *mem_ctx, + struct messaging_context *msg_ctx, struct sockaddr_storage *dc_ss, const char *domain_name, const DOM_SID *sid) @@ -139,7 +140,6 @@ bool send_getdc_request(struct messaging_context *msg_ctx, enum ndr_err_code ndr_err; DATA_BLOB blob; struct dom_sid my_sid; - TALLOC_CTX *mem_ctx = talloc_tos(); ZERO_STRUCT(packet); ZERO_STRUCT(my_sid); @@ -193,14 +193,14 @@ bool send_getdc_request(struct messaging_context *msg_ctx, dc_ss); } -bool receive_getdc_response(struct sockaddr_storage *dc_ss, +bool receive_getdc_response(TALLOC_CTX *mem_ctx, + struct sockaddr_storage *dc_ss, const char *domain_name, const char **dc_name) { struct packet_struct *packet; const char *my_mailslot = NULL; struct in_addr dc_ip; - TALLOC_CTX *mem_ctx = talloc_tos(); DATA_BLOB blob; struct nbt_ntlogon_packet r; union dgram_message_body p; -- cgit From ba98dd4989db16028a2690d382ab178524ce765b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:26:32 +0200 Subject: libads: Use libnbt for CLDAP reply parsing. Guenther (This used to be commit 751f3064a508341c0ebae45e8de9f5311d915d70) --- source3/libsmb/dsgetdcname.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 00841f0684..531ab11622 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -196,7 +196,7 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, const char *site_name, struct netr_DsRGetDCNameInfo *info) { - struct cldap_netlogon_reply r; + struct nbt_cldap_netlogon_5 r; /* check if matching entry is older then 15 minutes, if yes, send * CLDAP/MAILSLOT ping again and store the cached data */ @@ -606,12 +606,11 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, { int i = 0; bool valid_dc = false; - struct cldap_netlogon_reply r; + struct nbt_cldap_netlogon_5 r; const char *dc_hostname, *dc_domain_name; const char *dc_address; uint32_t dc_address_type; uint32_t dc_flags; - struct GUID dc_guid; for (i=0; i Date: Mon, 21 Apr 2008 19:47:13 +0200 Subject: cldap: add talloc context to ads_cldap_netlogon(). Guenther (This used to be commit 4cee7b1bd5cd97c414b73d6f39238958480cdcf3) --- source3/libsmb/dsgetdcname.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 531ab11622..0b3b3d9bbf 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -203,7 +203,7 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, ZERO_STRUCT(r); - if (ads_cldap_netlogon(info->dc_unc, + if (ads_cldap_netlogon(mem_ctx, info->dc_unc, info->domain_name, &r)) { dsgetdcname_cache_delete(mem_ctx, domain_name); @@ -618,7 +618,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, DEBUG(10,("LDAP ping to %s\n", dclist[i].hostname)); - if ((ads_cldap_netlogon(dclist[i].hostname, + if ((ads_cldap_netlogon(mem_ctx, dclist[i].hostname, domain_name, &r)) && (check_cldap_reply_required_flags(r.server_type, flags))) { valid_dc = true; -- cgit From bcbac69d1a38e128ffe8b763ac027d6eab33dcec Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 21 Apr 2008 19:59:27 +0200 Subject: cldap: avoid duplicate definitions so remove ads_cldap.h. Guenther (This used to be commit 538eefe22ad69540b9f73ffaa613d6be045de199) --- source3/libsmb/dsgetdcname.c | 14 +++++++------- source3/libsmb/namequery_dc.c | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 0b3b3d9bbf..7834632806 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -225,26 +225,26 @@ static bool check_cldap_reply_required_flags(uint32_t ret_flags, uint32_t req_flags) { if (req_flags & DS_PDC_REQUIRED) - RETURN_ON_FALSE(ret_flags & ADS_PDC); + RETURN_ON_FALSE(ret_flags & NBT_SERVER_PDC); if (req_flags & DS_GC_SERVER_REQUIRED) - RETURN_ON_FALSE(ret_flags & ADS_GC); + RETURN_ON_FALSE(ret_flags & NBT_SERVER_GC); if (req_flags & DS_ONLY_LDAP_NEEDED) - RETURN_ON_FALSE(ret_flags & ADS_LDAP); + RETURN_ON_FALSE(ret_flags & NBT_SERVER_LDAP); if ((req_flags & DS_DIRECTORY_SERVICE_REQUIRED) || (req_flags & DS_DIRECTORY_SERVICE_PREFERRED)) - RETURN_ON_FALSE(ret_flags & ADS_DS); + RETURN_ON_FALSE(ret_flags & NBT_SERVER_DS); if (req_flags & DS_KDC_REQUIRED) - RETURN_ON_FALSE(ret_flags & ADS_KDC); + RETURN_ON_FALSE(ret_flags & NBT_SERVER_KDC); if (req_flags & DS_TIMESERV_REQUIRED) - RETURN_ON_FALSE(ret_flags & ADS_TIMESERV); + RETURN_ON_FALSE(ret_flags & NBT_SERVER_TIMESERV); if (req_flags & DS_WRITABLE_REQUIRED) - RETURN_ON_FALSE(ret_flags & ADS_WRITABLE); + RETURN_ON_FALSE(ret_flags & NBT_SERVER_WRITABLE); return true; } diff --git a/source3/libsmb/namequery_dc.c b/source3/libsmb/namequery_dc.c index 06926a762b..d080f8f0b7 100644 --- a/source3/libsmb/namequery_dc.c +++ b/source3/libsmb/namequery_dc.c @@ -99,7 +99,7 @@ static bool ads_dc_name(const char *domain, } #ifdef HAVE_KRB5 - if (is_our_primary_domain(domain) && (ads->config.flags & ADS_KDC)) { + if (is_our_primary_domain(domain) && (ads->config.flags & NBT_SERVER_KDC)) { if (ads_closest_dc(ads)) { /* We're going to use this KDC for this realm/domain. If we are using sites, then force the krb5 libs -- cgit From b78453326bf41cf3af239a5415dfef80a842d555 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Apr 2008 08:01:51 +0200 Subject: Remove the "pwd" struct from rpc_pipe_client The only user of this was decrypt_trustdom_secret, and this only needs the NT hash anyway. (This used to be commit 3d8c2a47e677a4c4aacf4abf148b1bd8163c3351) --- source3/libsmb/smbencrypt.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index e7198b801d..11f8780a47 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -630,27 +630,23 @@ void sess_crypt_blob(DATA_BLOB *out, const DATA_BLOB *in, const DATA_BLOB *sessi } /* Decrypts password-blob with session-key - * @param pass password for session-key + * @param nt_hash NT hash for the session key * @param data_in DATA_BLOB encrypted password * * Returns cleartext password in CH_UNIX * Caller must free the returned string */ -char *decrypt_trustdom_secret(const char *pass, DATA_BLOB *data_in) +char *decrypt_trustdom_secret(uint8_t nt_hash[16], DATA_BLOB *data_in) { DATA_BLOB data_out, sess_key; - uchar nt_hash[16]; uint32_t length; uint32_t version; fstring cleartextpwd; - if (!data_in || !pass) + if (!data_in || !nt_hash) return NULL; - /* generate md4 password-hash derived from the NT UNICODE password */ - E_md4hash(pass, nt_hash); - /* hashed twice with md4 */ mdfour(nt_hash, nt_hash, 16); -- cgit From bd3991ac970c1b0856e2e8525fe683c0b1596ea1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 22 Apr 2008 00:04:25 +0200 Subject: dsgetdcname: add very basic flat name support. Guenther (This used to be commit bb72d0b71e2a85d50e7bd893670c3eec69717580) --- source3/libsmb/dsgetdcname.c | 177 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 168 insertions(+), 9 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 7834632806..874a7749b7 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -391,15 +391,60 @@ static NTSTATUS discover_dc_netbios(TALLOC_CTX *mem_ctx, const char *domain_name, uint32_t flags, struct ip_service_name **returned_dclist, - int *return_count) + int *returned_count) { + NTSTATUS status; + enum nbt_name_type name_type = NBT_NAME_LOGON; + struct ip_service *iplist; + int i; + struct ip_service_name *dclist = NULL; + int count; + + *returned_dclist = NULL; + *returned_count = 0; + if (lp_disable_netbios()) { return NT_STATUS_NOT_SUPPORTED; } - /* FIXME: code here */ + if (flags & DS_PDC_REQUIRED) { + name_type = NBT_NAME_PDC; + } - return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + status = internal_resolve_name(domain_name, name_type, NULL, + &iplist, &count, + "lmhosts wins bcast"); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("discover_dc_netbios: failed to find DC\n")); + return status; + } + + dclist = TALLOC_ZERO_ARRAY(mem_ctx, struct ip_service_name, count); + if (!dclist) { + return NT_STATUS_NO_MEMORY; + } + + for (i=0; iss = iplist[i].ss; + r->port = iplist[i].port; + r->hostname = talloc_strdup(mem_ctx, addr); + if (!r->hostname) { + return NT_STATUS_NO_MEMORY; + } + + } + + *returned_dclist = dclist; + *returned_count = count; + + return NT_STATUS_OK; } /**************************************************************** @@ -688,16 +733,130 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +static struct event_context *ev_context(void) +{ + static struct event_context *ctx; + + if (!ctx && !(ctx = event_context_init(NULL))) { + smb_panic("Could not init event context"); + } + return ctx; +} + +/**************************************************************** +****************************************************************/ + +static struct messaging_context *msg_context(TALLOC_CTX *mem_ctx) +{ + static struct messaging_context *ctx; + + if (!ctx && !(ctx = messaging_init(mem_ctx, server_id_self(), + ev_context()))) { + smb_panic("Could not init messaging context"); + } + return ctx; +} + +/**************************************************************** +****************************************************************/ + static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, const char *domain_name, uint32_t flags, - struct ip_service_name **dclist, + struct ip_service_name *dclist, int num_dcs, struct netr_DsRGetDCNameInfo **info) { - /* FIXME: code here */ + struct sockaddr_storage ss; + struct ip_service ip_list; + enum nbt_name_type name_type = NBT_NAME_LOGON; + + int i; + const char *dc_hostname, *dc_domain_name; + const char *dc_address; + uint32_t dc_address_type; + uint32_t dc_flags = 0; + const char *dc_name = NULL; + fstring tmp_dc_name; + struct messaging_context *msg_ctx = msg_context(mem_ctx); + + if (flags & DS_PDC_REQUIRED) { + name_type = NBT_NAME_PDC; + } + + DEBUG(10,("process_dc_netbios\n")); + + for (i=0; i Date: Tue, 22 Apr 2008 00:05:05 +0200 Subject: dsgetdcname: Fix discover_dc_dns(). Guenther (This used to be commit ec86deb349850c634b49cd5a536e9281a4a6e7d8) --- source3/libsmb/dsgetdcname.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 874a7749b7..5af65c5dca 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -524,8 +524,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, struct ip_service_name *r = &dclist[count]; - r->port = dcs[i].port; - r->hostname = dcs[i].hostname; + r->port = dcs[count].port; + r->hostname = dcs[count].hostname; if (!(flags & DS_IP_REQUIRED)) { count++; -- cgit From aba7809188025f09b10631f822fedbe8671acddb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 22 Apr 2008 00:06:57 +0200 Subject: build: fix the build. Guenther (This used to be commit 09a0001063d5bdd9bdc7abfbf1467beb062de049) --- source3/libsmb/namequery.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 893c9265fd..c987890e69 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1423,8 +1423,8 @@ static NTSTATUS resolve_ads(const char *name, resolve_hosts() when looking up DC's via SRV RR entries in DNS **********************************************************************/ -static NTSTATUS internal_resolve_name(const char *name, - int name_type, +NTSTATUS internal_resolve_name(const char *name, + int name_type, const char *sitename, struct ip_service **return_iplist, int *return_count, -- cgit From e66d452466514a16c15acf64cbb9494b46ea92c1 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 24 Apr 2008 21:28:03 +0200 Subject: mailslot: allow to define nt_version in send_getdc_request(). Guenther (This used to be commit ce3728191b23badfd5eb92701e4cebf84273b61e) --- source3/libsmb/clidgram.c | 5 +++-- source3/libsmb/dsgetdcname.c | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 83e50e553d..41d6916b97 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -130,7 +130,8 @@ bool send_getdc_request(TALLOC_CTX *mem_ctx, struct messaging_context *msg_ctx, struct sockaddr_storage *dc_ss, const char *domain_name, - const DOM_SID *sid) + const DOM_SID *sid, + uint32_t nt_version) { struct in_addr dc_ip; const char *my_acct_name = NULL; @@ -172,7 +173,7 @@ bool send_getdc_request(TALLOC_CTX *mem_ctx, s->mailslot_name = my_mailslot; s->acct_control = ACB_WSTRUST; s->sid = my_sid; - s->nt_version = 1; + s->nt_version = nt_version; s->lmnt_token = 0xffff; s->lm20_token = 0xffff; diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 5af65c5dca..f357e92b9b 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -796,7 +796,8 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, } if (send_getdc_request(mem_ctx, msg_ctx, - &dclist[i].ss, domain_name, NULL)) + &dclist[i].ss, domain_name, + NULL, 1)) { int k; smb_msleep(100); -- cgit From 012d6782111a2700ee80c79be1a1c07a41dab952 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 24 Apr 2008 21:29:48 +0200 Subject: mailslot: make sure we are looking at the correct reply structure. Guenther (This used to be commit c6ce07fdf57c8b63ba6d72b622be261723cb55e3) --- source3/libsmb/clidgram.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 41d6916b97..ba958fa6f9 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -207,6 +207,9 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, union dgram_message_body p; enum ndr_err_code ndr_err; + const char *returned_dc = NULL; + const char *returned_domain = NULL; + if (dc_ss->ss_family != AF_INET) { return false; } @@ -268,13 +271,27 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, NDR_PRINT_DEBUG(nbt_ntlogon_packet, &r); } - if (!strequal(r.req.reply.domain, domain_name)) { + switch (r.command) { + case NTLOGON_SAM_LOGON_REPLY: + case NTLOGON_SAM_LOGON_REPLY15: + returned_domain = r.req.reply.domain; + returned_dc = r.req.reply.server; + break; + case NTLOGON_RESPONSE_FROM_PDC2: + returned_domain = r.req.reply2.domain; + returned_dc = r.req.reply2.pdc_name; + break; + default: + return false; + } + + if (!strequal(returned_domain, domain_name)) { DEBUG(3, ("GetDC: Expected domain %s, got %s\n", - domain_name, r.req.reply.domain)); + domain_name, returned_domain)); return false; } - *dc_name = talloc_strdup(mem_ctx, r.req.reply.server); + *dc_name = talloc_strdup(mem_ctx, returned_dc); if (!*dc_name) { return false; } @@ -283,7 +300,7 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, if (**dc_name == '\\') *dc_name += 1; DEBUG(10, ("GetDC gave name %s for domain %s\n", - *dc_name, r.req.reply.domain)); + *dc_name, returned_domain)); return True; } -- cgit From b77601a4b7c9d0f472eb51dad1d491d54a6dcbdc Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 24 Apr 2008 21:37:42 +0200 Subject: mailslot: allow to give back struct nbt_ntlogon_packet. Guenther (This used to be commit 2b178dcae608ecc05f62593a7a0c2a127b8b7ca2) --- source3/libsmb/clidgram.c | 11 ++++++++++- source3/libsmb/dsgetdcname.c | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index ba958fa6f9..fba009d427 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -197,7 +197,8 @@ bool send_getdc_request(TALLOC_CTX *mem_ctx, bool receive_getdc_response(TALLOC_CTX *mem_ctx, struct sockaddr_storage *dc_ss, const char *domain_name, - const char **dc_name) + const char **dc_name, + struct nbt_ntlogon_packet **reply) { struct packet_struct *packet; const char *my_mailslot = NULL; @@ -299,6 +300,14 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, if (**dc_name == '\\') *dc_name += 1; if (**dc_name == '\\') *dc_name += 1; + if (reply) { + *reply = talloc_memdup(mem_ctx, &r, + sizeof(struct nbt_ntlogon_packet)); + if (!*reply) { + return false; + } + } + DEBUG(10, ("GetDC gave name %s for domain %s\n", *dc_name, returned_domain)); diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index f357e92b9b..af1dc04059 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -779,6 +779,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, const char *dc_name = NULL; fstring tmp_dc_name; struct messaging_context *msg_ctx = msg_context(mem_ctx); + struct nbt_ntlogon_packet *reply = NULL; if (flags & DS_PDC_REQUIRED) { name_type = NBT_NAME_PDC; @@ -805,7 +806,8 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, if (receive_getdc_response(mem_ctx, &dclist[i].ss, domain_name, - &dc_name)) { + &dc_name, + &reply)) { namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); dc_hostname = dc_name; dc_domain_name = talloc_strdup_upper(mem_ctx, domain_name); -- cgit From 051ff45c6041accdf4f74d33db16158a3aa95a4c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 24 Apr 2008 21:53:55 +0200 Subject: mailslot/dsgetdcname: do what XP does and request nt_version 11. This allows dsgetdcname to query for a flat, non-dns domain name and come back with all information about the DC (site names, guid, forest, etc.) based on a mailslot reply. The version 11 request is downgraded to version 1 in case we do a query against NT4. Guenther (This used to be commit d8b2ff3c8769e8da9c21dec483e6edb7aa2d00f3) --- source3/libsmb/dsgetdcname.c | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index af1dc04059..fbc3bda6e4 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -777,6 +777,10 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, uint32_t dc_address_type; uint32_t dc_flags = 0; const char *dc_name = NULL; + const char *dc_forest = NULL; + const char *dc_server_site = NULL; + const char *dc_client_site = NULL; + struct GUID *dc_domain_guid = NULL; fstring tmp_dc_name; struct messaging_context *msg_ctx = msg_context(mem_ctx); struct nbt_ntlogon_packet *reply = NULL; @@ -798,7 +802,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, if (send_getdc_request(mem_ctx, msg_ctx, &dclist[i].ss, domain_name, - NULL, 1)) + NULL, 11)) { int k; smb_msleep(100); @@ -835,6 +839,25 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, make_reply: + if (reply && reply->command == NTLOGON_RESPONSE_FROM_PDC2) { + + dc_flags |= reply->req.reply2.server_type; + dc_forest = reply->req.reply2.forest; + dc_server_site = reply->req.reply2.server_site; + dc_client_site = reply->req.reply2.client_site; + + dc_domain_guid = &reply->req.reply2.domain_uuid; + + if (flags & DS_RETURN_DNS_NAME) { + dc_domain_name = reply->req.reply2.dns_domain; + dc_hostname = reply->req.reply2.pdc_dns_name; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; + } else if (flags & DS_RETURN_FLAT_NAME) { + dc_domain_name = reply->req.reply2.domain; + dc_hostname = reply->req.reply2.pdc_name; + } + } + if (flags & DS_IP_REQUIRED) { char addr[INET6_ADDRSTRLEN]; print_sockaddr(addr, sizeof(addr), &dclist[i].ss); @@ -849,16 +872,20 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, dc_flags |= NBT_SERVER_PDC | NBT_SERVER_WRITABLE; } + if (dc_forest) { + dc_flags |= DS_DNS_FOREST; + } + return make_domain_controller_info(mem_ctx, dc_hostname, dc_address, dc_address_type, - NULL, + dc_domain_guid, dc_domain_name, - NULL, + dc_forest, dc_flags, - NULL, - NULL, + dc_server_site, + dc_client_site, info); } -- cgit From 9e9d40d0977add05ac65d35251c1a5986c721e48 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Apr 2008 10:39:37 +0200 Subject: Refactoring: Make cli_pipe_auth_data a pointer off rpc_pipe_client (This used to be commit f665afaaa3eff9ef54112e08ed034a6e1bb30edc) --- source3/libsmb/trusts_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 20ac0143fd..6b3bbaf1d8 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -39,7 +39,7 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX /* Check if the netlogon pipe is open using schannel. If so we already have valid creds. If not we must set them up. */ - if (cli->auth.auth_type != PIPE_AUTH_TYPE_SCHANNEL) { + if (cli->auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) { uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; result = rpccli_netlogon_setup_creds(cli, -- cgit From dddac2bc8f97c6ece4242281e817415c77b181a2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 24 Apr 2008 22:19:23 +0200 Subject: errors: add WERR_INVALID_DOMAINNAME. Guenther (This used to be commit b11a5e70d38239fb50ba4606656e2168cc398a12) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 8761106e58..7a7cceef24 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -76,6 +76,7 @@ werror_code_struct dos_errs[] = { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, { "WERR_INVALID_COMPUTER_NAME", WERR_INVALID_COMPUTER_NAME }, + { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, { "WERR_DC_NOT_FOUND", WERR_DC_NOT_FOUND }, { "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED }, -- cgit From d0411c19dc847919b2a7941d91d2605c885e2b62 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 29 Apr 2008 20:10:17 +0200 Subject: errors: add WERR_NOT_FOUND. Guenther (This used to be commit b9ac03bdfa5763c713674acd966ab5d4371992a5) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 7a7cceef24..450d6ee911 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -104,6 +104,7 @@ werror_code_struct dos_errs[] = { "WERR_NO_SUCH_SERVICE", WERR_NO_SUCH_SERVICE }, { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, { "WERR_SERVICE_NEVER_STARTED", WERR_SERVICE_NEVER_STARTED }, + { "WERR_NOT_FOUND", WERR_NOT_FOUND }, { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE}, { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS}, { "WERR_PASSWORD_MUST_CHANGE", WERR_PASSWORD_MUST_CHANGE }, -- cgit From e7142ef180d88e5e0daa6b853a04ff9f1ce4d22a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 30 Apr 2008 18:47:40 +0200 Subject: ntlmssp: replace UNKNOWN_02000000 with NTLMSSP_NEGOTIATE_VERSION. Guenther (This used to be commit 2c41d69bcf6f0897ef9d444a8f167aff1772d562) --- source3/libsmb/ntlmssp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/ntlmssp.c b/source3/libsmb/ntlmssp.c index 7082ea7e4e..a0e54ce769 100644 --- a/source3/libsmb/ntlmssp.c +++ b/source3/libsmb/ntlmssp.c @@ -95,6 +95,8 @@ void debug_ntlmssp_flags(uint32 neg_flags) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_VERSION) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_VERSION\n")); if (neg_flags & NTLMSSP_NEGOTIATE_128) DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) @@ -449,8 +451,8 @@ static void ntlmssp_handle_neg_flags(struct ntlmssp_state *ntlmssp_state, /* Woop Woop - unknown flag for Windows compatibility... What does this really do ? JRA. */ - if (!(neg_flags & NTLMSSP_UNKNOWN_02000000)) { - ntlmssp_state->neg_flags &= ~NTLMSSP_UNKNOWN_02000000; + if (!(neg_flags & NTLMSSP_NEGOTIATE_VERSION)) { + ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_VERSION; } if ((neg_flags & NTLMSSP_REQUEST_TARGET)) { @@ -934,7 +936,7 @@ NTSTATUS ntlmssp_server_start(NTLMSSP_STATE **ntlmssp_state) (*ntlmssp_state)->neg_flags = NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_56 | - NTLMSSP_UNKNOWN_02000000 | + NTLMSSP_NEGOTIATE_VERSION | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_NTLM2 | -- cgit From 4d8836ab96889bcdc35e86bedffa6117f9c35095 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 5 May 2008 16:58:24 +0200 Subject: Fix client authentication with -P switch in client tools (Bug 5435). Guenther (This used to be commit d077ef64cd1d9bbaeb936566c2c70da508de829f) --- source3/libsmb/cliconnect.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 7d3d246da5..671f0e7bc5 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -795,6 +795,8 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, int i; bool got_kerberos_mechanism = False; DATA_BLOB blob; + const char *p = NULL; + char *account = NULL; DEBUG(3,("Doing spnego session setup (blob length=%lu)\n", (unsigned long)cli->secblob.length)); @@ -925,7 +927,17 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, ntlmssp: - return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, user, pass, domain)); + account = talloc_strdup(talloc_tos(), user); + ADS_ERROR_HAVE_NO_MEMORY(account); + + /* when falling back to ntlmssp while authenticating with a machine + * account strip off the realm - gd */ + + if ((p = strchr_m(user, '@')) != NULL) { + account[PTR_DIFF(p,user)] = '\0'; + } + + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, domain)); } /**************************************************************************** @@ -1867,12 +1879,18 @@ struct cli_state *get_ipc_connect(char *server, { struct cli_state *cli; NTSTATUS nt_status; + uint32_t flags = CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK; + + if (user_info->use_kerberos) { + flags |= CLI_FULL_CONNECTION_USE_KERBEROS; + } nt_status = cli_full_connection(&cli, NULL, server, server_ss, 0, "IPC$", "IPC", user_info->username ? user_info->username : "", lp_workgroup(), user_info->password ? user_info->password : "", - CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK, Undefined, NULL); + flags, + Undefined, NULL); if (NT_STATUS_IS_OK(nt_status)) { return cli; -- cgit From 7245a8e3b889ad6127d2cbf62a5a7f6e465e6bbd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 5 May 2008 17:24:17 +0200 Subject: Fix a C++ warning (This used to be commit e7a4027acf38bf5800d9d8ba477afb5daaf517ce) --- source3/libsmb/clidgram.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index fba009d427..1d3293c60f 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -301,8 +301,8 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, if (**dc_name == '\\') *dc_name += 1; if (reply) { - *reply = talloc_memdup(mem_ctx, &r, - sizeof(struct nbt_ntlogon_packet)); + *reply = (struct nbt_ntlogon_packet *)talloc_memdup( + mem_ctx, &r, sizeof(struct nbt_ntlogon_packet)); if (!*reply) { return false; } -- cgit From 5c02872a10c3f650c31ec7ce78fa6732d6646961 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 5 May 2008 17:22:49 +0200 Subject: dsgetdcname: use correct dc name for name cache store. Guenther (This used to be commit ce1556d0fb993b78f02ac4cc4f8a45ab7a0b5397) --- source3/libsmb/dsgetdcname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index fbc3bda6e4..de647ad8bf 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -830,7 +830,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, { dc_hostname = tmp_dc_name; dc_domain_name = talloc_strdup_upper(mem_ctx, domain_name); - namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); + namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } } -- cgit From 1f6065765c148251488acd068fdea98717f7233f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 5 May 2008 18:04:41 +0200 Subject: mailslot/cldap: use nt_version bits in queries. Guenther (This used to be commit b261f063125f8454d8f4e8f6b6f8aa5bc393ea34) --- source3/libsmb/dsgetdcname.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index de647ad8bf..1bd54d80e6 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -784,6 +784,9 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, fstring tmp_dc_name; struct messaging_context *msg_ctx = msg_context(mem_ctx); struct nbt_ntlogon_packet *reply = NULL; + uint32_t nt_version = NETLOGON_VERSION_1 | + NETLOGON_VERSION_5 | + NETLOGON_VERSION_5EX_WITH_IP; if (flags & DS_PDC_REQUIRED) { name_type = NBT_NAME_PDC; @@ -802,7 +805,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, if (send_getdc_request(mem_ctx, msg_ctx, &dclist[i].ss, domain_name, - NULL, 11)) + NULL, nt_version)) { int k; smb_msleep(100); -- cgit From 611d79d0ed27a1762c40caeb12b383fd96a58511 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 6 May 2008 09:48:16 +0200 Subject: build: fix the build w/o ldap. Guenther (This used to be commit a159ec5f1f3ec8e9232b8f3230a996a3f9986bc1) --- source3/libsmb/cliconnect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 671f0e7bc5..751f10bc53 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -928,7 +928,9 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, ntlmssp: account = talloc_strdup(talloc_tos(), user); - ADS_ERROR_HAVE_NO_MEMORY(account); + if (!account) { + return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); + } /* when falling back to ntlmssp while authenticating with a machine * account strip off the realm - gd */ -- cgit From 7b5ec90b727b4653ca7ccd05cb0f51ff5c670971 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 14:09:41 +0200 Subject: dsgetdcname: remove invalid assumptions when using DNS for the DC query. Guenther (This used to be commit a81818ae54159755df441cc6421e5b272035f412) --- source3/libsmb/dsgetdcname.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 1bd54d80e6..1006b975c7 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -466,14 +466,6 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, struct ip_service_name *dclist = NULL; int count = 0; - if ((!(flags & DS_DIRECTORY_SERVICE_REQUIRED)) && - (!(flags & DS_KDC_REQUIRED)) && - (!(flags & DS_GC_SERVER_REQUIRED)) && - (!(flags & DS_PDC_REQUIRED))) { - DEBUG(1,("discover_dc_dns: invalid flags\n")); - return NT_STATUS_INVALID_PARAMETER; - } - if (flags & DS_PDC_REQUIRED) { status = ads_dns_query_pdc(mem_ctx, domain_name, &dcs, &numdcs); @@ -490,9 +482,8 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, status = ads_dns_query_dcs_guid(mem_ctx, domain_name, domain_guid, &dcs, &numdcs); } else { - /* FIXME: ? */ - DEBUG(1,("discover_dc_dns: not enough input\n")); - status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + status = ads_dns_query_dcs(mem_ctx, domain_name, site_name, + &dcs, &numdcs); } if (!NT_STATUS_IS_OK(status)) { -- cgit From fcdee399884ae73eaf10663fb718f148bb4aff24 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 14:38:35 +0200 Subject: dsgetdcname: add map_ds_flags_to_nt_version. Guenther (This used to be commit 1809ea22c31ee28e109f49701f91534177027165) --- source3/libsmb/dsgetdcname.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 1006b975c7..c7eb8005bc 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -633,6 +633,32 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +static uint32_t map_ds_flags_to_nt_version(uint32_t flags) +{ + uint32_t nt_version = 0; + + if (flags & DS_PDC_REQUIRED) { + nt_version |= NETLOGON_VERSION_PDC; + } + + if (flags & DS_GC_SERVER_REQUIRED) { + nt_version |= NETLOGON_VERSION_GC; + } + + if (flags & DS_TRY_NEXTCLOSEST_SITE) { + nt_version |= NETLOGON_VERSION_WITH_CLOSEST_SITE; + } + + if (flags & DS_IP_REQUIRED) { + nt_version |= NETLOGON_VERSION_IP; + } + + return nt_version; +} + +/**************************************************************** +****************************************************************/ + static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, const char *domain_name, uint32_t flags, @@ -783,6 +809,8 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, name_type = NBT_NAME_PDC; } + nt_version |= map_ds_flags_to_nt_version(flags); + DEBUG(10,("process_dc_netbios\n")); for (i=0; i Date: Wed, 7 May 2008 15:21:41 +0200 Subject: dsgetdcname: add pull_mailslot_cldap_reply(). Guenther (This used to be commit 95fb01d8702342265f8837a368dc42f4a4d394d5) --- source3/libsmb/dsgetdcname.c | 84 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index c7eb8005bc..98c9997575 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -1023,3 +1023,87 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, return status; } + +/**************************************************************** +****************************************************************/ + +bool pull_mailslot_cldap_reply(TALLOC_CTX *mem_ctx, + const DATA_BLOB *blob, + union nbt_cldap_netlogon *r, + uint32_t *nt_version) +{ + enum ndr_err_code ndr_err; + uint32_t nt_version_query = ((*nt_version) & 0x000000ff); + uint16_t command = 0; + + ndr_err = ndr_pull_struct_blob(blob, mem_ctx, &command, + (ndr_pull_flags_fn_t)ndr_pull_uint16); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return false; + } + + switch (command) { + case 0x13: /* 19 */ + case 0x15: /* 21 */ + case 0x17: /* 23 */ + break; + default: + DEBUG(1,("got unexpected command: %d (0x%08x)\n", + command, command)); + return false; + } + + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + + /* when the caller requested just those nt_version bits that the server + * was able to reply to, we are fine and all done. otherwise we need to + * assume downgraded replies which are painfully parsed here - gd */ + + if (nt_version_query & NETLOGON_VERSION_WITH_CLOSEST_SITE) { + nt_version_query &= ~NETLOGON_VERSION_WITH_CLOSEST_SITE; + } + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + if (nt_version_query & NETLOGON_VERSION_5EX_WITH_IP) { + nt_version_query &= ~NETLOGON_VERSION_5EX_WITH_IP; + } + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + if (nt_version_query & NETLOGON_VERSION_5EX) { + nt_version_query &= ~NETLOGON_VERSION_5EX; + } + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + if (nt_version_query & NETLOGON_VERSION_5) { + nt_version_query &= ~NETLOGON_VERSION_5; + } + ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); + if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + goto done; + } + + return false; + + done: + if (DEBUGLEVEL >= 10) { + NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon, nt_version_query, r); + } + + *nt_version = nt_version_query; + + return true; +} -- cgit From cdd9913c4a7d254ab3ef677737493f9f540272c7 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 15:49:09 +0200 Subject: cldap: let ads_cldap_netlogon() return all possible cldap replies. Guenther (This used to be commit 6f9d5e1cc94bc90685b54c04622b8f3357bd2f69) --- source3/libsmb/dsgetdcname.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 98c9997575..1fd42120ee 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -196,15 +196,13 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, const char *site_name, struct netr_DsRGetDCNameInfo *info) { - struct nbt_cldap_netlogon_5 r; + uint32_t nt_version = NETLOGON_VERSION_1; /* check if matching entry is older then 15 minutes, if yes, send * CLDAP/MAILSLOT ping again and store the cached data */ - ZERO_STRUCT(r); - if (ads_cldap_netlogon(mem_ctx, info->dc_unc, - info->domain_name, &r)) { + info->domain_name, &nt_version, NULL)) { dsgetdcname_cache_delete(mem_ctx, domain_name); -- cgit From 9b4ea32c2d42f5d7f3e52fad3f81d932e654d4d0 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 16:49:39 +0200 Subject: dsgetdcname: add get_cldap_reply_server_flags(). Guenther (This used to be commit 3c05c56d4c0aac8106684cda3152c65299c63075) --- source3/libsmb/dsgetdcname.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 1fd42120ee..5d6e2daba4 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -217,6 +217,38 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +static uint32_t get_cldap_reply_server_flags(union nbt_cldap_netlogon *r, + uint32_t nt_version) +{ + switch (nt_version & 0x000000ff) { + case 0: + case 1: + return 0; + case 2: + case 3: + return r->logon3.server_type; + case 4: + case 5: + case 6: + case 7: + return r->logon5.server_type; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + return r->logon13.server_type; + default: + return r->logon29.server_type; + } +} + +/**************************************************************** +****************************************************************/ + #define RETURN_ON_FALSE(x) if (!x) return false; static bool check_cldap_reply_required_flags(uint32_t ret_flags, -- cgit From 81aa670343d77de0782f2275f7bba9d396d24bec Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 18:36:03 +0200 Subject: dsgetdcname: add make_dc_info_from_cldap_reply(). Guenther (This used to be commit 9db2e50a20caabaf90ce03203a066ddd7820d33a) --- source3/libsmb/dsgetdcname.c | 146 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 5d6e2daba4..72a0bb5984 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -640,6 +640,7 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, if (forest_name) { info->forest_name = talloc_strdup(mem_ctx, forest_name); NT_STATUS_HAVE_NO_MEMORY(info->forest_name); + flags |= DS_DNS_FOREST; } info->dc_flags = flags; @@ -663,6 +664,151 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, + uint32_t flags, + struct sockaddr_storage *ss, + uint32_t nt_version, + union nbt_cldap_netlogon *r, + struct netr_DsRGetDCNameInfo **info) +{ + const char *dc_hostname, *dc_domain_name; + const char *dc_address = NULL; + const char *dc_forest = NULL; + uint32_t dc_address_type = 0; + uint32_t dc_flags = 0; + struct GUID *dc_domain_guid = NULL; + const char *dc_server_site = NULL; + const char *dc_client_site = NULL; + + char addr[INET6_ADDRSTRLEN]; + + print_sockaddr(addr, sizeof(addr), ss); + + dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr); + NT_STATUS_HAVE_NO_MEMORY(dc_address); + dc_address_type = DS_ADDRESS_TYPE_INET; + + switch (nt_version & 0x000000ff) { + case 0: + return NT_STATUS_INVALID_PARAMETER; + case 1: + dc_hostname = r->logon1.pdc_name; + dc_domain_name = r->logon1.domain_name; + if (flags & DS_PDC_REQUIRED) { + dc_flags = NBT_SERVER_WRITABLE | NBT_SERVER_PDC; + } + break; + case 2: + case 3: + switch (flags & 0xf0000000) { + case DS_RETURN_FLAT_NAME: + dc_hostname = r->logon3.pdc_name; + dc_domain_name = r->logon3.domain_name; + break; + case DS_RETURN_DNS_NAME: + default: + dc_hostname = r->logon3.pdc_dns_name; + dc_domain_name = r->logon3.dns_domain; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; + break; + } + + dc_flags |= r->logon3.server_type; + dc_forest = r->logon3.forest; + dc_domain_guid = &r->logon3.domain_uuid; + + break; + case 4: + case 5: + case 6: + case 7: + switch (flags & 0xf0000000) { + case DS_RETURN_FLAT_NAME: + dc_hostname = r->logon5.pdc_name; + dc_domain_name = r->logon5.domain; + break; + case DS_RETURN_DNS_NAME: + default: + dc_hostname = r->logon5.pdc_dns_name; + dc_domain_name = r->logon5.dns_domain; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; + break; + } + + dc_flags |= r->logon5.server_type; + dc_forest = r->logon5.forest; + dc_domain_guid = &r->logon5.domain_uuid; + dc_server_site = r->logon5.server_site; + dc_client_site = r->logon5.client_site; + + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + switch (flags & 0xf0000000) { + case DS_RETURN_FLAT_NAME: + dc_hostname = r->logon13.pdc_name; + dc_domain_name = r->logon13.domain; + break; + case DS_RETURN_DNS_NAME: + default: + dc_hostname = r->logon13.pdc_dns_name; + dc_domain_name = r->logon13.dns_domain; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; + break; + } + + dc_flags |= r->logon13.server_type; + dc_forest = r->logon13.forest; + dc_domain_guid = &r->logon13.domain_uuid; + dc_server_site = r->logon13.server_site; + dc_client_site = r->logon13.client_site; + + break; + default: + switch (flags & 0xf0000000) { + case DS_RETURN_FLAT_NAME: + dc_hostname = r->logon29.pdc_name; + dc_domain_name = r->logon29.domain; + break; + case DS_RETURN_DNS_NAME: + default: + dc_hostname = r->logon29.pdc_dns_name; + dc_domain_name = r->logon29.dns_domain; + dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; + break; + } + + dc_flags |= r->logon29.server_type; + dc_forest = r->logon29.forest; + dc_domain_guid = &r->logon29.domain_uuid; + dc_server_site = r->logon29.server_site; + dc_client_site = r->logon29.client_site; + + break; + } + + return make_domain_controller_info(mem_ctx, + dc_hostname, + dc_address, + dc_address_type, + dc_domain_guid, + dc_domain_name, + dc_forest, + dc_flags, + dc_server_site, + dc_client_site, + info); +} + +/**************************************************************** +****************************************************************/ + static uint32_t map_ds_flags_to_nt_version(uint32_t flags) { uint32_t nt_version = 0; -- cgit From 0354d00ddfae53f278bd2b3480f3eaeefe84e518 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 18:38:37 +0200 Subject: dsgetdcname: use make_dc_info_from_cldap_reply() for cldap replies. Guenther (This used to be commit a3e5b073f0474543ca74b40775ce1d7f80719c96) --- source3/libsmb/dsgetdcname.c | 84 +++++++++++--------------------------------- 1 file changed, 21 insertions(+), 63 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 72a0bb5984..6ea60ab854 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -254,6 +254,10 @@ static uint32_t get_cldap_reply_server_flags(union nbt_cldap_netlogon *r, static bool check_cldap_reply_required_flags(uint32_t ret_flags, uint32_t req_flags) { + if (ret_flags == 0) { + return true; + } + if (req_flags & DS_PDC_REQUIRED) RETURN_ON_FALSE(ret_flags & NBT_SERVER_PDC); @@ -844,23 +848,26 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, { int i = 0; bool valid_dc = false; - struct nbt_cldap_netlogon_5 r; - const char *dc_hostname, *dc_domain_name; - const char *dc_address; - uint32_t dc_address_type; - uint32_t dc_flags; + union nbt_cldap_netlogon *r = NULL; + uint32_t nt_version = NETLOGON_VERSION_5 | + NETLOGON_VERSION_5EX; + uint32_t ret_flags = 0; for (i=0; i Date: Wed, 7 May 2008 18:39:24 +0200 Subject: dsgetdcname: map additional flags to nt_version. Guenther (This used to be commit 1009123b8600e6ccebe180f4a2f87c217638fef8) --- source3/libsmb/dsgetdcname.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 6ea60ab854..a278c4ef50 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -853,6 +853,8 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, NETLOGON_VERSION_5EX; uint32_t ret_flags = 0; + nt_version |= map_ds_flags_to_nt_version(flags); + for (i=0; i Date: Wed, 7 May 2008 18:55:45 +0200 Subject: dsgetdcname: wait a little longer for mailslot replies. Guenther (This used to be commit bc0d7a90dcc7bf702b24feb16abf4634ff178671) --- source3/libsmb/dsgetdcname.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index a278c4ef50..b64f340456 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -963,7 +963,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, NULL, nt_version)) { int k; - smb_msleep(100); + smb_msleep(300); for (k=0; k<5; k++) { if (receive_getdc_response(mem_ctx, &dclist[i].ss, @@ -976,7 +976,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, NT_STATUS_HAVE_NO_MEMORY(dc_domain_name); goto make_reply; } - smb_msleep(500); + smb_msleep(1500); } } -- cgit From 9be17e2187a93633b23761fc2f6f0b40c94db809 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 18:57:43 +0200 Subject: dsgetdcname: mailslot replies are identical to the cldap ones, use cldap everywhere. Guenther (This used to be commit fe904ee77a7fec1674e9db660978c40c17897f77) --- source3/libsmb/clidgram.c | 62 ++++++++++++++++++++++------------ source3/libsmb/dsgetdcname.c | 79 +++++++++++--------------------------------- 2 files changed, 60 insertions(+), 81 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 1d3293c60f..367b028396 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -197,14 +197,15 @@ bool send_getdc_request(TALLOC_CTX *mem_ctx, bool receive_getdc_response(TALLOC_CTX *mem_ctx, struct sockaddr_storage *dc_ss, const char *domain_name, + uint32_t *nt_version, const char **dc_name, - struct nbt_ntlogon_packet **reply) + union nbt_cldap_netlogon **reply) { struct packet_struct *packet; const char *my_mailslot = NULL; struct in_addr dc_ip; DATA_BLOB blob; - struct nbt_ntlogon_packet r; + union nbt_cldap_netlogon r; union dgram_message_body p; enum ndr_err_code ndr_err; @@ -259,31 +260,50 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, return false; } + if (DEBUGLEVEL >= 10) { + NDR_PRINT_DEBUG(dgram_smb_packet, &p); + } + blob = p.smb.body.trans.data; - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, - (ndr_pull_flags_fn_t)ndr_pull_nbt_ntlogon_packet); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(0,("failed to parse packet\n")); + if (!pull_mailslot_cldap_reply(mem_ctx, &blob, + &r, nt_version)) + { return false; } - if (DEBUGLEVEL >= 10) { - NDR_PRINT_DEBUG(nbt_ntlogon_packet, &r); - } - - switch (r.command) { - case NTLOGON_SAM_LOGON_REPLY: - case NTLOGON_SAM_LOGON_REPLY15: - returned_domain = r.req.reply.domain; - returned_dc = r.req.reply.server; + switch (*nt_version) { + case 1: + returned_domain = r.logon1.domain_name; + returned_dc = r.logon1.pdc_name; + break; + case 2: + case 3: + returned_domain = r.logon3.domain_name; + returned_dc = r.logon3.pdc_name; break; - case NTLOGON_RESPONSE_FROM_PDC2: - returned_domain = r.req.reply2.domain; - returned_dc = r.req.reply2.pdc_name; + case 4: + case 5: + case 6: + case 7: + returned_domain = r.logon5.domain; + returned_dc = r.logon5.pdc_name; + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + returned_domain = r.logon13.domain; + returned_dc = r.logon13.pdc_name; break; default: - return false; + returned_domain = r.logon29.domain; + returned_dc = r.logon29.pdc_name; + break; } if (!strequal(returned_domain, domain_name)) { @@ -301,8 +321,8 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, if (**dc_name == '\\') *dc_name += 1; if (reply) { - *reply = (struct nbt_ntlogon_packet *)talloc_memdup( - mem_ctx, &r, sizeof(struct nbt_ntlogon_packet)); + *reply = (union nbt_cldap_netlogon *)talloc_memdup( + mem_ctx, &r, sizeof(union nbt_cldap_netlogon)); if (!*reply) { return false; } diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index b64f340456..a21fc9a217 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -925,18 +925,10 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, enum nbt_name_type name_type = NBT_NAME_LOGON; int i; - const char *dc_hostname, *dc_domain_name; - const char *dc_address; - uint32_t dc_address_type; - uint32_t dc_flags = 0; const char *dc_name = NULL; - const char *dc_forest = NULL; - const char *dc_server_site = NULL; - const char *dc_client_site = NULL; - struct GUID *dc_domain_guid = NULL; fstring tmp_dc_name; struct messaging_context *msg_ctx = msg_context(mem_ctx); - struct nbt_ntlogon_packet *reply = NULL; + union nbt_cldap_netlogon *reply = NULL; uint32_t nt_version = NETLOGON_VERSION_1 | NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX_WITH_IP; @@ -968,12 +960,10 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, if (receive_getdc_response(mem_ctx, &dclist[i].ss, domain_name, + &nt_version, &dc_name, &reply)) { namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); - dc_hostname = dc_name; - dc_domain_name = talloc_strdup_upper(mem_ctx, domain_name); - NT_STATUS_HAVE_NO_MEMORY(dc_domain_name); goto make_reply; } smb_msleep(1500); @@ -986,65 +976,34 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, &dclist[i].ss, tmp_dc_name)) { - dc_hostname = tmp_dc_name; - dc_domain_name = talloc_strdup_upper(mem_ctx, domain_name); - namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); - goto make_reply; - } - } + struct nbt_cldap_netlogon_1 logon1; - return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; + reply = TALLOC_ZERO_P(mem_ctx, union nbt_cldap_netlogon); + NT_STATUS_HAVE_NO_MEMORY(reply); - make_reply: + ZERO_STRUCT(logon1); - if (reply && reply->command == NTLOGON_RESPONSE_FROM_PDC2) { + nt_version = NETLOGON_VERSION_1; - dc_flags |= reply->req.reply2.server_type; - dc_forest = reply->req.reply2.forest; - dc_server_site = reply->req.reply2.server_site; - dc_client_site = reply->req.reply2.client_site; + logon1.nt_version = nt_version; + logon1.pdc_name = tmp_dc_name; + logon1.domain_name = talloc_strdup_upper(mem_ctx, domain_name); + NT_STATUS_HAVE_NO_MEMORY(logon1.domain_name); - dc_domain_guid = &reply->req.reply2.domain_uuid; + reply->logon1 = logon1; - if (flags & DS_RETURN_DNS_NAME) { - dc_domain_name = reply->req.reply2.dns_domain; - dc_hostname = reply->req.reply2.pdc_dns_name; - dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; - } else if (flags & DS_RETURN_FLAT_NAME) { - dc_domain_name = reply->req.reply2.domain; - dc_hostname = reply->req.reply2.pdc_name; - } - } + namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); - if (flags & DS_IP_REQUIRED) { - char addr[INET6_ADDRSTRLEN]; - print_sockaddr(addr, sizeof(addr), &dclist[i].ss); - dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr); - dc_address_type = DS_ADDRESS_TYPE_INET; - } else { - dc_address = talloc_asprintf(mem_ctx, "\\\\%s", dc_hostname); - dc_address_type = DS_ADDRESS_TYPE_NETBIOS; + goto make_reply; + } } - if (flags & DS_PDC_REQUIRED) { - dc_flags |= NBT_SERVER_PDC | NBT_SERVER_WRITABLE; - } + return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; - if (dc_forest) { - dc_flags |= DS_DNS_FOREST; - } + make_reply: - return make_domain_controller_info(mem_ctx, - dc_hostname, - dc_address, - dc_address_type, - dc_domain_guid, - dc_domain_name, - dc_forest, - dc_flags, - dc_server_site, - dc_client_site, - info); + return make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, + nt_version, reply, info); } /**************************************************************** -- cgit From eaef936523b9fbd62e53b7b8f8ee6576da525eb4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 21:02:50 +0200 Subject: dsgetdcname: remove invalid assumption in discover_dc_dns(). Guenther (This used to be commit f48b2e844b673e99c84cb24f3c3718352ab93ce5) --- source3/libsmb/dsgetdcname.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index a21fc9a217..981994ca43 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -552,11 +552,6 @@ static NTSTATUS discover_dc_dns(TALLOC_CTX *mem_ctx, r->port = dcs[count].port; r->hostname = dcs[count].hostname; - if (!(flags & DS_IP_REQUIRED)) { - count++; - continue; - } - /* If we don't have an IP list for a name, lookup it up */ if (!dcs[i].ss_s) { -- cgit From 8441681819dcbc54143ac0f590c2795750daa96c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 21:04:10 +0200 Subject: dsgetdcname: be more paranoid about the existance of an ip_address. Guenther (This used to be commit d13fe66f3d9ba152e3e8197ee6682e175163a6cd) --- source3/libsmb/dsgetdcname.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 981994ca43..388c7be395 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -621,7 +621,12 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, } if (dc_address) { - info->dc_address = talloc_strdup(mem_ctx, dc_address); + if (!(dc_address[0] == '\\' && dc_address[1] == '\\')) { + info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", + dc_address); + } else { + info->dc_address = talloc_strdup(mem_ctx, dc_address); + } NT_STATUS_HAVE_NO_MEMORY(info->dc_address); } @@ -681,16 +686,21 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, char addr[INET6_ADDRSTRLEN]; - print_sockaddr(addr, sizeof(addr), ss); - - dc_address = talloc_asprintf(mem_ctx, "\\\\%s", addr); - NT_STATUS_HAVE_NO_MEMORY(dc_address); - dc_address_type = DS_ADDRESS_TYPE_INET; + if (ss) { + print_sockaddr(addr, sizeof(addr), ss); + dc_address = addr; + dc_address_type = DS_ADDRESS_TYPE_INET; + } switch (nt_version & 0x000000ff) { case 0: return NT_STATUS_INVALID_PARAMETER; case 1: + if (!ss) { + dc_address = r->logon1.pdc_name; + dc_address_type = DS_ADDRESS_TYPE_NETBIOS; + } + dc_hostname = r->logon1.pdc_name; dc_domain_name = r->logon1.domain_name; if (flags & DS_PDC_REQUIRED) { @@ -699,6 +709,11 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, break; case 2: case 3: + if (!ss) { + dc_address = r->logon3.pdc_ip; + dc_address_type = DS_ADDRESS_TYPE_INET; + } + switch (flags & 0xf0000000) { case DS_RETURN_FLAT_NAME: dc_hostname = r->logon3.pdc_name; @@ -721,6 +736,11 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, case 5: case 6: case 7: + if (!ss) { + dc_address = r->logon5.pdc_name; + dc_address_type = DS_ADDRESS_TYPE_NETBIOS; + } + switch (flags & 0xf0000000) { case DS_RETURN_FLAT_NAME: dc_hostname = r->logon5.pdc_name; @@ -749,6 +769,11 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, case 13: case 14: case 15: + if (!ss) { + dc_address = r->logon13.dc_sock_addr.pdc_ip; + dc_address_type = DS_ADDRESS_TYPE_INET; + } + switch (flags & 0xf0000000) { case DS_RETURN_FLAT_NAME: dc_hostname = r->logon13.pdc_name; @@ -770,6 +795,11 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, break; default: + if (!ss) { + dc_address = r->logon29.dc_sock_addr.pdc_ip; + dc_address_type = DS_ADDRESS_TYPE_INET; + } + switch (flags & 0xf0000000) { case DS_RETURN_FLAT_NAME: dc_hostname = r->logon29.pdc_name; -- cgit From 9adc40a38fd0e5dc0ad9de4654c8bc6a05a19d7b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 21:06:23 +0200 Subject: dsgetdcname: simply call ourself with DS_FORCE_REDISCOVERY after cache expiry. Guenther (This used to be commit 847f258632f6d49a3fd45f466c5d3d8c6222ff85) --- source3/libsmb/dsgetdcname.c | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 388c7be395..247cfd3526 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -196,22 +196,14 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, const char *site_name, struct netr_DsRGetDCNameInfo *info) { - uint32_t nt_version = NETLOGON_VERSION_1; - - /* check if matching entry is older then 15 minutes, if yes, send - * CLDAP/MAILSLOT ping again and store the cached data */ - - if (ads_cldap_netlogon(mem_ctx, info->dc_unc, - info->domain_name, &nt_version, NULL)) { - - dsgetdcname_cache_delete(mem_ctx, domain_name); - - return dsgetdcname_cache_store(mem_ctx, - info->domain_name, - info); - } - - return NT_STATUS_INVALID_NETWORK_RESPONSE; + struct netr_DsRGetDCNameInfo *dc_info; + + return dsgetdcname(mem_ctx, + domain_name, + domain_guid, + site_name, + flags | DS_FORCE_REDISCOVERY, + &dc_info); } /**************************************************************** -- cgit From 5d7a60afd8ab7e84eef6b5726e162d9b861df7b9 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 21:08:20 +0200 Subject: dsgetdcname: pure cosmetics. Guenther (This used to be commit 4b56c294e8ba045c84cab538b3d286e433d292ed) --- source3/libsmb/dsgetdcname.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 247cfd3526..4cafc71ff2 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -945,7 +945,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, const char *dc_name = NULL; fstring tmp_dc_name; struct messaging_context *msg_ctx = msg_context(mem_ctx); - union nbt_cldap_netlogon *reply = NULL; + union nbt_cldap_netlogon *r = NULL; uint32_t nt_version = NETLOGON_VERSION_1 | NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX_WITH_IP; @@ -979,7 +979,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, domain_name, &nt_version, &dc_name, - &reply)) { + &r)) { namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } @@ -995,8 +995,8 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, { struct nbt_cldap_netlogon_1 logon1; - reply = TALLOC_ZERO_P(mem_ctx, union nbt_cldap_netlogon); - NT_STATUS_HAVE_NO_MEMORY(reply); + r = TALLOC_ZERO_P(mem_ctx, union nbt_cldap_netlogon); + NT_STATUS_HAVE_NO_MEMORY(r); ZERO_STRUCT(logon1); @@ -1007,7 +1007,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, logon1.domain_name = talloc_strdup_upper(mem_ctx, domain_name); NT_STATUS_HAVE_NO_MEMORY(logon1.domain_name); - reply->logon1 = logon1; + r->logon1 = logon1; namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); @@ -1020,7 +1020,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, make_reply: return make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, - nt_version, reply, info); + nt_version, r, info); } /**************************************************************** -- cgit From 5e24d83e417931409eaa66a5e09dcd3b12ad162f Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 21:25:05 +0200 Subject: dsgetdcname: fix gencache store for dsgetdcname(). While storing always a type 29 reply structure in gencache, we are now able to deliver correct data according to return flags such as DS_RETURN_FLAT_NAME and DS_RETURN_DNS_NAME out of the cached data from gencache. Guenther (This used to be commit c67b6dc0ca866781043e443177d550e23b83ae36) --- source3/libsmb/dsgetdcname.c | 204 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 184 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 4cafc71ff2..208daf334c 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -32,6 +32,13 @@ struct ip_service_name { const char *hostname; }; +static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, + uint32_t flags, + struct sockaddr_storage *ss, + uint32_t nt_version, + union nbt_cldap_netlogon *r, + struct netr_DsRGetDCNameInfo **info); + /**************************************************************** ****************************************************************/ @@ -148,13 +155,11 @@ static NTSTATUS dsgetdcname_cache_delete(TALLOC_CTX *mem_ctx, static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, const char *domain_name, - struct netr_DsRGetDCNameInfo *info) + const DATA_BLOB *blob) { time_t expire_time; char *key; bool ret = false; - DATA_BLOB blob; - enum ndr_err_code ndr_err; if (!gencache_init()) { return NT_STATUS_INTERNAL_DB_ERROR; @@ -167,19 +172,11 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL; - ndr_err = ndr_push_struct_blob(&blob, mem_ctx, info, - (ndr_push_flags_fn_t)ndr_push_netr_DsRGetDCNameInfo); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return ndr_map_error2ntstatus(ndr_err); - } - if (gencache_lock_entry(key) != 0) { - data_blob_free(&blob); return NT_STATUS_LOCK_NOT_GRANTED; } - ret = gencache_set_data_blob(key, &blob, expire_time); - data_blob_free(&blob); + ret = gencache_set_data_blob(key, blob, expire_time); gencache_unlock_entry(key); @@ -189,6 +186,149 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +#define SET_STRING(x) \ + talloc_strdup(mem_ctx, x); \ + NT_STATUS_HAVE_NO_MEMORY(x); + +static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx, + uint32_t flags, + struct sockaddr_storage *ss, + uint32_t nt_version, + union nbt_cldap_netlogon *r, + struct nbt_cldap_netlogon_29 *p) +{ + char addr[INET6_ADDRSTRLEN]; + + ZERO_STRUCTP(p); + + print_sockaddr(addr, sizeof(addr), ss); + p->dc_sock_addr_size = 0x10; + p->dc_sock_addr.sa_family = 2; + p->dc_sock_addr.pdc_ip = talloc_strdup(mem_ctx, addr); + + switch (nt_version & 0x000000ff) { + case 0: + return NT_STATUS_INVALID_PARAMETER; + case 1: + p->pdc_name = SET_STRING(r->logon1.pdc_name); + p->domain = SET_STRING(r->logon1.domain_name); + + if (flags & DS_PDC_REQUIRED) { + p->server_type = NBT_SERVER_WRITABLE | + NBT_SERVER_PDC; + } + break; + case 2: + case 3: + p->pdc_name = SET_STRING(r->logon3.pdc_name); + p->domain = SET_STRING(r->logon3.domain_name); + p->pdc_dns_name = SET_STRING(r->logon3.pdc_dns_name); + p->dns_domain = SET_STRING(r->logon3.dns_domain); + p->server_type = r->logon3.server_type; + p->forest = SET_STRING(r->logon3.forest); + p->domain_uuid = r->logon3.domain_uuid; + + break; + case 4: + case 5: + case 6: + case 7: + p->pdc_name = SET_STRING(r->logon5.pdc_name); + p->domain = SET_STRING(r->logon5.domain); + p->pdc_dns_name = SET_STRING(r->logon5.pdc_dns_name); + p->dns_domain = SET_STRING(r->logon5.dns_domain); + p->server_type = r->logon5.server_type; + p->forest = SET_STRING(r->logon5.forest); + p->domain_uuid = r->logon5.domain_uuid; + p->server_site = SET_STRING(r->logon5.server_site); + p->client_site = SET_STRING(r->logon5.client_site); + + break; + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + p->pdc_name = SET_STRING(r->logon13.pdc_name); + p->domain = SET_STRING(r->logon13.domain); + p->pdc_dns_name = SET_STRING(r->logon13.pdc_dns_name); + p->dns_domain = SET_STRING(r->logon13.dns_domain); + p->server_type = r->logon13.server_type; + p->forest = SET_STRING(r->logon13.forest); + p->domain_uuid = r->logon13.domain_uuid; + p->server_site = SET_STRING(r->logon13.server_site); + p->client_site = SET_STRING(r->logon13.client_site); + + break; + default: + p->pdc_name = SET_STRING(r->logon29.pdc_name); + p->domain = SET_STRING(r->logon29.domain); + p->pdc_dns_name = SET_STRING(r->logon29.pdc_dns_name); + p->dns_domain = SET_STRING(r->logon29.dns_domain); + p->server_type = r->logon29.server_type; + p->forest = SET_STRING(r->logon29.forest); + p->domain_uuid = r->logon29.domain_uuid; + p->server_site = SET_STRING(r->logon29.server_site); + p->client_site = SET_STRING(r->logon29.client_site); + p->next_closest_site = SET_STRING(r->logon29.next_closest_site); + + break; + } + + return NT_STATUS_OK; +} + +/**************************************************************** +****************************************************************/ + +static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx, + uint32_t flags, + struct sockaddr_storage *ss, + uint32_t nt_version, + union nbt_cldap_netlogon *r) +{ + DATA_BLOB blob; + enum ndr_err_code ndr_err; + NTSTATUS status; + struct nbt_cldap_netlogon_29 logon29; + + status = map_logon29_from_cldap_reply(mem_ctx, flags, ss, + nt_version, r, &logon29); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &logon29, + (ndr_push_flags_fn_t)ndr_push_nbt_cldap_netlogon_29); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return ndr_map_error2ntstatus(ndr_err); + } + + if (logon29.domain) { + status = dsgetdcname_cache_store(mem_ctx, logon29.domain, &blob); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + } + if (logon29.dns_domain) { + status = dsgetdcname_cache_store(mem_ctx, logon29.dns_domain, &blob); + if (!NT_STATUS_IS_OK(status)) { + goto done; + } + } + + done: + data_blob_free(&blob); + + return status; +} + +/**************************************************************** +****************************************************************/ + static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, const char *domain_name, struct GUID *domain_guid, @@ -290,6 +430,9 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, DATA_BLOB blob; enum ndr_err_code ndr_err; struct netr_DsRGetDCNameInfo *info; + union nbt_cldap_netlogon p; + struct nbt_cldap_netlogon_29 r; + NTSTATUS status; if (!gencache_init()) { return NT_STATUS_INTERNAL_DB_ERROR; @@ -309,8 +452,8 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, info, - (ndr_pull_flags_fn_t)ndr_pull_netr_DsRGetDCNameInfo); + ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, &r, + (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon_29); data_blob_free(&blob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -318,6 +461,15 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, return ndr_map_error2ntstatus(ndr_err); } + p.logon29 = r; + + status = make_dc_info_from_cldap_reply(mem_ctx, flags, NULL, + NETLOGON_VERSION_WITH_CLOSEST_SITE, + &p, &info); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (DEBUGLEVEL >= 10) { NDR_PRINT_DEBUG(netr_DsRGetDCNameInfo, info); } @@ -869,6 +1021,7 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, uint32_t nt_version = NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX; uint32_t ret_flags = 0; + NTSTATUS status; nt_version |= map_ds_flags_to_nt_version(flags); @@ -896,8 +1049,14 @@ static NTSTATUS process_dc_dns(TALLOC_CTX *mem_ctx, return NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; } - return make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, - nt_version, r, info); + status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, + nt_version, r, info); + if (NT_STATUS_IS_OK(status)) { + return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, + nt_version, r); + } + + return status; } /**************************************************************** @@ -940,7 +1099,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, struct sockaddr_storage ss; struct ip_service ip_list; enum nbt_name_type name_type = NBT_NAME_LOGON; - + NTSTATUS status; int i; const char *dc_name = NULL; fstring tmp_dc_name; @@ -1019,8 +1178,14 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, make_reply: - return make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, - nt_version, r, info); + status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, + nt_version, r, info); + if (NT_STATUS_IS_OK(status)) { + return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, + nt_version, r); + } + + return status; } /**************************************************************** @@ -1129,7 +1294,6 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, &myinfo); if (NT_STATUS_IS_OK(status)) { - dsgetdcname_cache_store(mem_ctx, domain_name, myinfo); *info = myinfo; } -- cgit From 4bd94c8338bef61477170bc41a8073739d55d812 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 7 May 2008 21:31:59 +0200 Subject: cldap: move out cldap object to fix the build. Guenther (This used to be commit 56be9c98d24e64bf855439df21766d30f448f407) --- source3/libsmb/dsgetdcname.c | 84 -------------------------------------------- 1 file changed, 84 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 208daf334c..0db457a45a 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -1299,87 +1299,3 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, return status; } - -/**************************************************************** -****************************************************************/ - -bool pull_mailslot_cldap_reply(TALLOC_CTX *mem_ctx, - const DATA_BLOB *blob, - union nbt_cldap_netlogon *r, - uint32_t *nt_version) -{ - enum ndr_err_code ndr_err; - uint32_t nt_version_query = ((*nt_version) & 0x000000ff); - uint16_t command = 0; - - ndr_err = ndr_pull_struct_blob(blob, mem_ctx, &command, - (ndr_pull_flags_fn_t)ndr_pull_uint16); - if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - return false; - } - - switch (command) { - case 0x13: /* 19 */ - case 0x15: /* 21 */ - case 0x17: /* 23 */ - break; - default: - DEBUG(1,("got unexpected command: %d (0x%08x)\n", - command, command)); - return false; - } - - ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - goto done; - } - - /* when the caller requested just those nt_version bits that the server - * was able to reply to, we are fine and all done. otherwise we need to - * assume downgraded replies which are painfully parsed here - gd */ - - if (nt_version_query & NETLOGON_VERSION_WITH_CLOSEST_SITE) { - nt_version_query &= ~NETLOGON_VERSION_WITH_CLOSEST_SITE; - } - ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - goto done; - } - if (nt_version_query & NETLOGON_VERSION_5EX_WITH_IP) { - nt_version_query &= ~NETLOGON_VERSION_5EX_WITH_IP; - } - ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - goto done; - } - if (nt_version_query & NETLOGON_VERSION_5EX) { - nt_version_query &= ~NETLOGON_VERSION_5EX; - } - ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - goto done; - } - if (nt_version_query & NETLOGON_VERSION_5) { - nt_version_query &= ~NETLOGON_VERSION_5; - } - ndr_err = ndr_pull_union_blob_all(blob, mem_ctx, r, nt_version_query, - (ndr_pull_flags_fn_t)ndr_pull_nbt_cldap_netlogon); - if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - goto done; - } - - return false; - - done: - if (DEBUGLEVEL >= 10) { - NDR_PRINT_UNION_DEBUG(nbt_cldap_netlogon, nt_version_query, r); - } - - *nt_version = nt_version_query; - - return true; -} -- cgit From e668cb45941b4cbe7dbcb5bb2e4de3fb1d3784de Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 May 2008 12:16:04 +0200 Subject: dsgetdcname: add map_dc_and_domain_names() for consolidating returned names. Guenther (This used to be commit eb7fee6e2a00326c03aa013058247e06279a4930) --- source3/libsmb/dsgetdcname.c | 129 ++++++++++++++++++++++++++----------------- 1 file changed, 79 insertions(+), 50 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 0db457a45a..2c8f42399f 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -812,6 +812,44 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ +static void map_dc_and_domain_names(uint32_t flags, + const char *dc_name, + const char *domain_name, + const char *dns_dc_name, + const char *dns_domain_name, + uint32_t *dc_flags, + const char **hostname_p, + const char **domain_p) +{ + switch (flags & 0xf0000000) { + case DS_RETURN_FLAT_NAME: + if (dc_name && domain_name && + *dc_name && *domain_name) { + *hostname_p = dc_name; + *domain_p = domain_name; + break; + } + case DS_RETURN_DNS_NAME: + default: + if (dns_dc_name && dns_domain_name && + *dns_dc_name && *dns_domain_name) { + *hostname_p = dns_dc_name; + *domain_p = dns_domain_name; + *dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; + break; + } + if (dc_name && domain_name && + *dc_name && *domain_name) { + *hostname_p = dc_name; + *domain_p = domain_name; + break; + } + } +} + +/**************************************************************** +****************************************************************/ + static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, uint32_t flags, struct sockaddr_storage *ss, @@ -845,8 +883,15 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, dc_address_type = DS_ADDRESS_TYPE_NETBIOS; } - dc_hostname = r->logon1.pdc_name; - dc_domain_name = r->logon1.domain_name; + map_dc_and_domain_names(flags, + r->logon1.pdc_name, + r->logon1.domain_name, + NULL, + NULL, + &dc_flags, + &dc_hostname, + &dc_domain_name); + if (flags & DS_PDC_REQUIRED) { dc_flags = NBT_SERVER_WRITABLE | NBT_SERVER_PDC; } @@ -858,18 +903,14 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, dc_address_type = DS_ADDRESS_TYPE_INET; } - switch (flags & 0xf0000000) { - case DS_RETURN_FLAT_NAME: - dc_hostname = r->logon3.pdc_name; - dc_domain_name = r->logon3.domain_name; - break; - case DS_RETURN_DNS_NAME: - default: - dc_hostname = r->logon3.pdc_dns_name; - dc_domain_name = r->logon3.dns_domain; - dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; - break; - } + map_dc_and_domain_names(flags, + r->logon3.pdc_name, + r->logon3.domain_name, + r->logon3.pdc_dns_name, + r->logon3.dns_domain, + &dc_flags, + &dc_hostname, + &dc_domain_name); dc_flags |= r->logon3.server_type; dc_forest = r->logon3.forest; @@ -885,18 +926,14 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, dc_address_type = DS_ADDRESS_TYPE_NETBIOS; } - switch (flags & 0xf0000000) { - case DS_RETURN_FLAT_NAME: - dc_hostname = r->logon5.pdc_name; - dc_domain_name = r->logon5.domain; - break; - case DS_RETURN_DNS_NAME: - default: - dc_hostname = r->logon5.pdc_dns_name; - dc_domain_name = r->logon5.dns_domain; - dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; - break; - } + map_dc_and_domain_names(flags, + r->logon5.pdc_name, + r->logon5.domain, + r->logon5.pdc_dns_name, + r->logon5.dns_domain, + &dc_flags, + &dc_hostname, + &dc_domain_name); dc_flags |= r->logon5.server_type; dc_forest = r->logon5.forest; @@ -918,18 +955,14 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, dc_address_type = DS_ADDRESS_TYPE_INET; } - switch (flags & 0xf0000000) { - case DS_RETURN_FLAT_NAME: - dc_hostname = r->logon13.pdc_name; - dc_domain_name = r->logon13.domain; - break; - case DS_RETURN_DNS_NAME: - default: - dc_hostname = r->logon13.pdc_dns_name; - dc_domain_name = r->logon13.dns_domain; - dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; - break; - } + map_dc_and_domain_names(flags, + r->logon13.pdc_name, + r->logon13.domain, + r->logon13.pdc_dns_name, + r->logon13.dns_domain, + &dc_flags, + &dc_hostname, + &dc_domain_name); dc_flags |= r->logon13.server_type; dc_forest = r->logon13.forest; @@ -944,18 +977,14 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, dc_address_type = DS_ADDRESS_TYPE_INET; } - switch (flags & 0xf0000000) { - case DS_RETURN_FLAT_NAME: - dc_hostname = r->logon29.pdc_name; - dc_domain_name = r->logon29.domain; - break; - case DS_RETURN_DNS_NAME: - default: - dc_hostname = r->logon29.pdc_dns_name; - dc_domain_name = r->logon29.dns_domain; - dc_flags |= DS_DNS_DOMAIN | DS_DNS_CONTROLLER; - break; - } + map_dc_and_domain_names(flags, + r->logon29.pdc_name, + r->logon29.domain, + r->logon29.pdc_dns_name, + r->logon29.dns_domain, + &dc_flags, + &dc_hostname, + &dc_domain_name); dc_flags |= r->logon29.server_type; dc_forest = r->logon29.forest; -- cgit From c58ab8f3b251f9fbf79fc8a528717e0756c02a76 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 May 2008 14:24:46 +0200 Subject: dsgetdcname: the forest name should never be empty. Guenther (This used to be commit 2c0a96f1e5fc065fdbeb5671cfa693009321dde8) --- source3/libsmb/dsgetdcname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 2c8f42399f..8021f8f054 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -785,7 +785,7 @@ static NTSTATUS make_domain_controller_info(TALLOC_CTX *mem_ctx, NT_STATUS_HAVE_NO_MEMORY(info->domain_name); } - if (forest_name) { + if (forest_name && *forest_name) { info->forest_name = talloc_strdup(mem_ctx, forest_name); NT_STATUS_HAVE_NO_MEMORY(info->forest_name); flags |= DS_DNS_FOREST; -- cgit From 67c644aa591c051cfe1e3f3536186ecf0b4449f2 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 May 2008 18:32:22 +0200 Subject: dsgetdcname: use existing messaging_context if possible. Guenther (This used to be commit 7889516a384c155a9045aad4409c041fddd0d98d) --- source3/libsmb/dsgetdcname.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 8021f8f054..d414d24783 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -330,6 +330,7 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx, ****************************************************************/ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, + struct messaging_context *msg_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, @@ -339,6 +340,7 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, struct netr_DsRGetDCNameInfo *dc_info; return dsgetdcname(mem_ctx, + msg_ctx, domain_name, domain_guid, site_name, @@ -494,6 +496,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, ****************************************************************/ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, + struct messaging_context *msg_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, @@ -516,7 +519,8 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, } if (expired) { - status = dsgetdcname_cache_refresh(mem_ctx, domain_name, + status = dsgetdcname_cache_refresh(mem_ctx, msg_ctx, + domain_name, domain_guid, flags, site_name, *info); if (!NT_STATUS_IS_OK(status)) { @@ -1119,6 +1123,7 @@ static struct messaging_context *msg_context(TALLOC_CTX *mem_ctx) ****************************************************************/ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, + struct messaging_context *msg_ctx, const char *domain_name, uint32_t flags, struct ip_service_name *dclist, @@ -1132,12 +1137,15 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, int i; const char *dc_name = NULL; fstring tmp_dc_name; - struct messaging_context *msg_ctx = msg_context(mem_ctx); union nbt_cldap_netlogon *r = NULL; uint32_t nt_version = NETLOGON_VERSION_1 | NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX_WITH_IP; + if (!msg_ctx) { + msg_ctx = msg_context(mem_ctx); + } + if (flags & DS_PDC_REQUIRED) { name_type = NBT_NAME_PDC; } @@ -1221,6 +1229,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, ****************************************************************/ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, + struct messaging_context *msg_ctx, const char *domain_name, struct GUID *domain_guid, uint32_t flags, @@ -1239,7 +1248,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, &dclist, &num_dcs); NT_STATUS_NOT_OK_RETURN(status); - return process_dc_netbios(mem_ctx, domain_name, flags, + return process_dc_netbios(mem_ctx, msg_ctx, domain_name, flags, dclist, num_dcs, info); } @@ -1269,7 +1278,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, &num_dcs); NT_STATUS_NOT_OK_RETURN(status); - return process_dc_netbios(mem_ctx, domain_name, flags, dclist, + return process_dc_netbios(mem_ctx, msg_ctx, domain_name, flags, dclist, num_dcs, info); } @@ -1280,6 +1289,7 @@ static NTSTATUS dsgetdcname_rediscover(TALLOC_CTX *mem_ctx, ********************************************************************/ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, + struct messaging_context *msg_ctx, const char *domain_name, struct GUID *domain_guid, const char *site_name, @@ -1306,7 +1316,7 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, goto rediscover; } - status = dsgetdcname_cached(mem_ctx, domain_name, domain_guid, + status = dsgetdcname_cached(mem_ctx, msg_ctx, domain_name, domain_guid, flags, site_name, &myinfo); if (NT_STATUS_IS_OK(status)) { *info = myinfo; @@ -1318,7 +1328,7 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, } rediscover: - status = dsgetdcname_rediscover(mem_ctx, domain_name, + status = dsgetdcname_rediscover(mem_ctx, msg_ctx, domain_name, domain_guid, flags, site_name, &myinfo); -- cgit From d59cf703ba5d6ac18e4399d12b043d5e68230403 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 9 May 2008 17:41:50 +0200 Subject: dsgetdcname: make use of nbt_cldap_netlogon_15. Guenther (This used to be commit 5b0eda98f3d127399770f7a037ad3277dbe23393) --- source3/libsmb/dsgetdcname.c | 99 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 91 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index d414d24783..43c9699ce7 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -206,10 +206,12 @@ static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx, p->dc_sock_addr.sa_family = 2; p->dc_sock_addr.pdc_ip = talloc_strdup(mem_ctx, addr); - switch (nt_version & 0x000000ff) { + switch (nt_version & 0x0000001f) { case 0: return NT_STATUS_INVALID_PARAMETER; case 1: + case 16: + case 17: p->pdc_name = SET_STRING(r->logon1.pdc_name); p->domain = SET_STRING(r->logon1.domain_name); @@ -220,6 +222,8 @@ static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx, break; case 2: case 3: + case 18: + case 19: p->pdc_name = SET_STRING(r->logon3.pdc_name); p->domain = SET_STRING(r->logon3.domain_name); p->pdc_dns_name = SET_STRING(r->logon3.pdc_dns_name); @@ -263,7 +267,29 @@ static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx, p->client_site = SET_STRING(r->logon13.client_site); break; - default: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + p->pdc_name = SET_STRING(r->logon15.pdc_name); + p->domain = SET_STRING(r->logon15.domain); + p->pdc_dns_name = SET_STRING(r->logon15.pdc_dns_name); + p->dns_domain = SET_STRING(r->logon15.dns_domain); + p->server_type = r->logon15.server_type; + p->forest = SET_STRING(r->logon15.forest); + p->domain_uuid = r->logon15.domain_uuid; + p->server_site = SET_STRING(r->logon15.server_site); + p->client_site = SET_STRING(r->logon15.client_site); + + break; + case 29: + case 30: + case 31: p->pdc_name = SET_STRING(r->logon29.pdc_name); p->domain = SET_STRING(r->logon29.domain); p->pdc_dns_name = SET_STRING(r->logon29.pdc_dns_name); @@ -276,6 +302,8 @@ static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx, p->next_closest_site = SET_STRING(r->logon29.next_closest_site); break; + default: + return NT_STATUS_INVALID_PARAMETER; } return NT_STATUS_OK; @@ -354,12 +382,16 @@ static NTSTATUS dsgetdcname_cache_refresh(TALLOC_CTX *mem_ctx, static uint32_t get_cldap_reply_server_flags(union nbt_cldap_netlogon *r, uint32_t nt_version) { - switch (nt_version & 0x000000ff) { + switch (nt_version & 0x0000001f) { case 0: case 1: + case 16: + case 17: return 0; case 2: case 3: + case 18: + case 19: return r->logon3.server_type; case 4: case 5: @@ -375,8 +407,22 @@ static uint32_t get_cldap_reply_server_flags(union nbt_cldap_netlogon *r, case 14: case 15: return r->logon13.server_type; - default: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + return r->logon15.server_type; + case 29: + case 30: + case 31: return r->logon29.server_type; + default: + return 0; } } @@ -466,7 +512,7 @@ static NTSTATUS dsgetdcname_cache_fetch(TALLOC_CTX *mem_ctx, p.logon29 = r; status = make_dc_info_from_cldap_reply(mem_ctx, flags, NULL, - NETLOGON_VERSION_WITH_CLOSEST_SITE, + 29, &p, &info); if (!NT_STATUS_IS_OK(status)) { return status; @@ -878,10 +924,11 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, dc_address_type = DS_ADDRESS_TYPE_INET; } - switch (nt_version & 0x000000ff) { + switch (nt_version & 0x0000001f) { case 0: - return NT_STATUS_INVALID_PARAMETER; case 1: + case 16: + case 17: if (!ss) { dc_address = r->logon1.pdc_name; dc_address_type = DS_ADDRESS_TYPE_NETBIOS; @@ -902,6 +949,8 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, break; case 2: case 3: + case 18: + case 19: if (!ss) { dc_address = r->logon3.pdc_ip; dc_address_type = DS_ADDRESS_TYPE_INET; @@ -975,7 +1024,39 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, dc_client_site = r->logon13.client_site; break; - default: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + if (!ss) { + dc_address = r->logon15.pdc_name; + dc_address_type = DS_ADDRESS_TYPE_NETBIOS; + } + + map_dc_and_domain_names(flags, + r->logon15.pdc_name, + r->logon15.domain, + r->logon15.pdc_dns_name, + r->logon15.dns_domain, + &dc_flags, + &dc_hostname, + &dc_domain_name); + + dc_flags |= r->logon15.server_type; + dc_forest = r->logon15.forest; + dc_domain_guid = &r->logon15.domain_uuid; + dc_server_site = r->logon15.server_site; + dc_client_site = r->logon15.client_site; + + break; + case 29: + case 30: + case 31: if (!ss) { dc_address = r->logon29.dc_sock_addr.pdc_ip; dc_address_type = DS_ADDRESS_TYPE_INET; @@ -997,6 +1078,8 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, dc_client_site = r->logon29.client_site; break; + default: + return NT_STATUS_INVALID_PARAMETER; } return make_domain_controller_info(mem_ctx, -- cgit From 1830d6b1599c93b81fd79b4cdc982f20263e1249 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 9 May 2008 17:56:04 +0200 Subject: dsgetdcname: add reminder that we need to support ipv6 here once we know how. Guenther (This used to be commit 4b3617bf505a835a6d4bb9b80c4ad837a2082dea) --- source3/libsmb/dsgetdcname.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 43c9699ce7..30d7c94822 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -202,8 +202,10 @@ static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx, ZERO_STRUCTP(p); print_sockaddr(addr, sizeof(addr), ss); - p->dc_sock_addr_size = 0x10; - p->dc_sock_addr.sa_family = 2; + + /* FIXME */ + p->dc_sock_addr_size = 0x10; /* the w32 winsock addr size */ + p->dc_sock_addr.sa_family = 2; /* AF_INET */ p->dc_sock_addr.pdc_ip = talloc_strdup(mem_ctx, addr); switch (nt_version & 0x0000001f) { -- cgit From 8ef2ada0ef36f946c79e5523db90f8d1d03d6607 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 13 May 2008 15:19:46 +0200 Subject: Revert "Fix signing bug found by Volker. That one was *subtle*." This reverts commit 816aea6c1a426eb2450061b847729e22bdac33a0. (This used to be commit e402e6508ca0806deef4c4044cfa6461b682850a) --- source3/libsmb/clitrans.c | 14 ++++++++ source3/libsmb/smb_signing.c | 79 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 88 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index bfb31fdb74..aa9c2fb296 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -94,9 +94,14 @@ bool cli_send_trans(struct cli_state *cli, int trans, return False; } + /* Note we're in a trans state. Save the sequence + * numbers for replies. */ + client_set_trans_sign_state_on(cli, mid); + if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { + client_set_trans_sign_state_off(cli, mid); return(False); } @@ -138,6 +143,7 @@ bool cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { + client_set_trans_sign_state_off(cli, mid); return False; } @@ -344,6 +350,7 @@ bool cli_receive_trans(struct cli_state *cli,int trans, } } + client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } @@ -411,9 +418,14 @@ bool cli_send_nt_trans(struct cli_state *cli, return False; } + /* Note we're in a trans state. Save the sequence + * numbers for replies. */ + client_set_trans_sign_state_on(cli, mid); + if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { + client_set_trans_sign_state_off(cli, mid); return(False); } @@ -455,6 +467,7 @@ bool cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); if (!cli_send_smb(cli)) { + client_set_trans_sign_state_off(cli, mid); return False; } @@ -682,5 +695,6 @@ bool cli_receive_nt_trans(struct cli_state *cli, } } + client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index bd6d97123d..ea1eb05cfb 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -25,6 +25,7 @@ struct outstanding_packet_lookup { struct outstanding_packet_lookup *prev, *next; uint16 mid; uint32 reply_seq_num; + bool can_delete; /* Set to False in trans state. */ }; struct smb_basic_signing_context { @@ -41,9 +42,7 @@ static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, /* Ensure we only add a mid once. */ for (t = *list; t; t = t->next) { if (t->mid == mid) { - DLIST_REMOVE(*list, t); - SAFE_FREE(t); - break; + return False; } } @@ -52,6 +51,7 @@ static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, t->mid = mid; t->reply_seq_num = reply_seq_num; + t->can_delete = True; /* * Add to the *start* of the list not the end of the list. @@ -78,8 +78,23 @@ static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, *reply_seq_num = t->reply_seq_num; DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - DLIST_REMOVE(*list, t); - SAFE_FREE(t); + if (t->can_delete) { + DLIST_REMOVE(*list, t); + SAFE_FREE(t); + } + return True; + } + } + return False; +} + +static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) +{ + struct outstanding_packet_lookup *t; + + for (t = *list; t; t = t->next) { + if (t->mid == mid) { + t->can_delete = can_delete_entry; return True; } } @@ -593,6 +608,60 @@ bool cli_check_sign_mac(struct cli_state *cli, char *buf) return True; } +/*********************************************************** + Enter trans/trans2/nttrans state. +************************************************************/ + +bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) +{ + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!data) { + return False; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { + return False; + } + + return True; +} + +/*********************************************************** + Leave trans/trans2/nttrans state. +************************************************************/ + +bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) +{ + uint32 reply_seq_num; + struct smb_sign_info *si = &cli->sign_info; + struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; + + if (!si->doing_signing) { + return True; + } + + if (!data) { + return False; + } + + if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { + return False; + } + + /* Now delete the stored mid entry. */ + if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { + return False; + } + + return True; +} + /*********************************************************** Is client signing on ? ************************************************************/ -- cgit From 44b7f672b87f103a2fd5cffeff48d2f7819042f8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 13 May 2008 16:23:19 +0200 Subject: Fix signing problem in the client with transs requests This is a different fix than Jeremy put into 3-0-test with 040db1ce85 and other branches with different hashes. Jeremy, I think your fix led to bug 5436, so I reverted your fix. This fixes the original problem I found with the transs requests for large rpc queries in a different way. Please check! Thanks, Volker (This used to be commit c572d537e088a3fffb057181cad9a3692e40b815) --- source3/libsmb/clitrans.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index aa9c2fb296..4bb70f1a08 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -112,6 +112,9 @@ bool cli_send_trans(struct cli_state *cli, int trans, this_lparam = MIN(lparam-tot_param,cli->max_xmit - 500); /* hack */ this_ldata = MIN(ldata-tot_data,cli->max_xmit - (500+this_lparam)); + client_set_trans_sign_state_off(cli, mid); + client_set_trans_sign_state_on(cli, mid); + cli_set_message(cli->outbuf,trans==SMBtrans?8:9,0,True); SCVAL(cli->outbuf,smb_com,(trans==SMBtrans ? SMBtranss : SMBtranss2)); -- cgit From c49487805bad03be6a27fc236f60c31dc97ec6ee Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 14 May 2008 09:41:24 +0200 Subject: mailslot: Also pick domain name and pdc name from type 15 cldap reply. Guenther (This used to be commit 836877c4005ba081c0a4cc97726830d6dbd62d34) --- source3/libsmb/clidgram.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index 367b028396..8b35a69def 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -274,11 +274,16 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, switch (*nt_version) { case 1: + case 16: + case 17: + returned_domain = r.logon1.domain_name; returned_dc = r.logon1.pdc_name; break; case 2: case 3: + case 18: + case 19: returned_domain = r.logon3.domain_name; returned_dc = r.logon3.pdc_name; break; @@ -300,10 +305,26 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, returned_domain = r.logon13.domain; returned_dc = r.logon13.pdc_name; break; - default: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + returned_domain = r.logon15.domain; + returned_dc = r.logon15.pdc_name; + break; + case 29: + case 30: + case 31: returned_domain = r.logon29.domain; returned_dc = r.logon29.pdc_name; break; + default: + return false; } if (!strequal(returned_domain, domain_name)) { -- cgit From 5547e5a416109524501c5c5be78efa0f8d10e749 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 14 May 2008 09:42:23 +0200 Subject: dsgetdcname: In case we didn't get a mailslot reply, don't cache the nodestatus. Guenther (This used to be commit 12e47be02f93e2f41af5772f6a83568b3574d032) --- source3/libsmb/dsgetdcname.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 30d7c94822..1538502e9a 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -1223,6 +1223,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, const char *dc_name = NULL; fstring tmp_dc_name; union nbt_cldap_netlogon *r = NULL; + bool store_cache = false; uint32_t nt_version = NETLOGON_VERSION_1 | NETLOGON_VERSION_5 | NETLOGON_VERSION_5EX_WITH_IP; @@ -1261,6 +1262,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, &nt_version, &dc_name, &r)) { + store_cache = true; namecache_store(dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; } @@ -1302,7 +1304,7 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, status = make_dc_info_from_cldap_reply(mem_ctx, flags, &dclist[i].ss, nt_version, r, info); - if (NT_STATUS_IS_OK(status)) { + if (NT_STATUS_IS_OK(status) && store_cache) { return store_cldap_reply(mem_ctx, flags, &dclist[i].ss, nt_version, r); } -- cgit From 2e8b43c58d6d276ef5856816f0259df51ccd9837 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 May 2008 16:41:18 +0200 Subject: dsgetdcname: check for invalid sitename/flag combinations. Guenther (This used to be commit 255e509474cae92802e90613ccaddb6627ee77cd) --- source3/libsmb/dsgetdcname.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 1538502e9a..3326c10f5e 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -582,7 +582,8 @@ static NTSTATUS dsgetdcname_cached(TALLOC_CTX *mem_ctx, /**************************************************************** ****************************************************************/ -static bool check_allowed_required_flags(uint32_t flags) +static bool check_allowed_required_flags(uint32_t flags, + const char *site_name) { uint32_t return_type = flags & (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME); uint32_t offered_type = flags & (DS_IS_FLAT_NAME|DS_IS_DNS_NAME); @@ -593,6 +594,10 @@ static bool check_allowed_required_flags(uint32_t flags) debug_dsdcinfo_flags(10, flags); + if ((flags & DS_TRY_NEXTCLOSEST_SITE) && site_name) { + return false; + } + if (return_type == (DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME)) { return false; } @@ -1394,7 +1399,7 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, *info = NULL; - if (!check_allowed_required_flags(flags)) { + if (!check_allowed_required_flags(flags, site_name)) { DEBUG(0,("invalid flags specified\n")); return NT_STATUS_INVALID_PARAMETER; } -- cgit From 4d593cdb19ec228adbf30cc8c408521e5770167c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 May 2008 16:59:46 +0200 Subject: dsgetdcname: add site support. Guenther (This used to be commit e305368538eaa72e3008a5517db3708936924297) --- source3/libsmb/dsgetdcname.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 3326c10f5e..16148a39d5 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -1390,6 +1390,7 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, { NTSTATUS status = NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND; struct netr_DsRGetDCNameInfo *myinfo = NULL; + char *query_site = NULL; DEBUG(10,("dsgetdcname: domain_name: %s, " "domain_guid: %s, site_name: %s, flags: 0x%08x\n", @@ -1404,29 +1405,38 @@ NTSTATUS dsgetdcname(TALLOC_CTX *mem_ctx, return NT_STATUS_INVALID_PARAMETER; } + if (!site_name) { + query_site = sitename_fetch(domain_name); + } else { + query_site = SMB_STRDUP(site_name); + } + if (flags & DS_FORCE_REDISCOVERY) { goto rediscover; } status = dsgetdcname_cached(mem_ctx, msg_ctx, domain_name, domain_guid, - flags, site_name, &myinfo); + flags, query_site, &myinfo); if (NT_STATUS_IS_OK(status)) { *info = myinfo; - return status; + goto done; } if (flags & DS_BACKGROUND_ONLY) { - return status; + goto done; } rediscover: status = dsgetdcname_rediscover(mem_ctx, msg_ctx, domain_name, - domain_guid, flags, site_name, + domain_guid, flags, query_site, &myinfo); if (NT_STATUS_IS_OK(status)) { *info = myinfo; } + done: + SAFE_FREE(query_site); + return status; } -- cgit From 175cca17299421df74831eec9ab2f43994087e5c Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 15 May 2008 17:47:07 +0200 Subject: dsgetdcname: store client sitename for mailslot and cldap replies. Guenther (This used to be commit a01ed719c31998620927dc9b1664ba8e36bd9b21) --- source3/libsmb/dsgetdcname.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 16148a39d5..d57689cd48 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -342,12 +342,18 @@ static NTSTATUS store_cldap_reply(TALLOC_CTX *mem_ctx, if (!NT_STATUS_IS_OK(status)) { goto done; } + if (logon29.client_site) { + sitename_store(logon29.domain, logon29.client_site); + } } if (logon29.dns_domain) { status = dsgetdcname_cache_store(mem_ctx, logon29.dns_domain, &blob); if (!NT_STATUS_IS_OK(status)) { goto done; } + if (logon29.client_site) { + sitename_store(logon29.dns_domain, logon29.client_site); + } } done: -- cgit From fb37f156009611af0dd454a0fb0829a09cd638ac Mon Sep 17 00:00:00 2001 From: Tim Prouty Date: Tue, 29 Apr 2008 14:36:24 -0700 Subject: Cleanup size_t return values in callers of convert_string_allocate This patch is the second iteration of an inside-out conversion to cleanup functions in charcnv.c returning size_t == -1 to indicate failure. (This used to be commit 6b189dabc562d86dcaa685419d0cb6ea276f100d) --- source3/libsmb/clikrb5.c | 9 ++++++--- source3/libsmb/clirap.c | 12 ++++++------ source3/libsmb/smbencrypt.c | 12 ++++++------ 3 files changed, 18 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index c289740ab2..7688b0bd12 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -52,8 +52,9 @@ { krb5_error_code ret; char *utf8_name; + size_t converted_size; - if (push_utf8_allocate(&utf8_name, name) == (size_t)-1) { + if (!push_utf8_allocate(&utf8_name, name, &converted_size)) { return ENOMEM; } @@ -73,9 +74,10 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, { krb5_error_code ret; char *utf8_name; + size_t converted_size; *principal = NULL; - if (push_utf8_allocate(&utf8_name, name) == (size_t)-1) { + if (!push_utf8_allocate(&utf8_name, name, &converted_size)) { return ENOMEM; } @@ -96,6 +98,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, { krb5_error_code ret; char *utf8_name; + size_t converted_size; *unix_name = NULL; ret = krb5_unparse_name(context, principal, &utf8_name); @@ -103,7 +106,7 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, return ret; } - if (pull_utf8_allocate(unix_name, utf8_name)==-1) { + if (!pull_utf8_allocate(unix_name, utf8_name, &converted_size)) { krb5_free_unparsed_name(context, utf8_name); return ENOMEM; } diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 8c167e1257..cf4f4987cf 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -904,14 +904,14 @@ bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname, tmp_buf[nlen] = 0; tmp_buf[nlen+1] = 0; - size = convert_string_talloc(streams, CH_UTF16, CH_UNIX, - tmp_buf, nlen+2, &vstr, - false); - TALLOC_FREE(tmp_buf); - - if (size == -1) { + if (!convert_string_talloc(streams, CH_UTF16, CH_UNIX, tmp_buf, + nlen+2, &vstr, &size, false)) + { + TALLOC_FREE(tmp_buf); goto fail; } + + TALLOC_FREE(tmp_buf); streams[num_streams].name = (char *)vstr; num_streams++; diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index 11f8780a47..f339b6b9f6 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -172,15 +172,15 @@ bool ntv2_owf_gen(const uchar owf[16], HMACMD5Context ctx; - user_byte_len = push_ucs2_allocate(&user, user_in); - if (user_byte_len == (size_t)-1) { - DEBUG(0, ("push_uss2_allocate() for user returned -1 (probably malloc() failure)\n")); + if (!push_ucs2_allocate(&user, user_in, &user_byte_len)) { + DEBUG(0, ("push_uss2_allocate() for user failed: %s\n", + strerror(errno))); return False; } - domain_byte_len = push_ucs2_allocate(&domain, domain_in); - if (domain_byte_len == (size_t)-1) { - DEBUG(0, ("push_uss2_allocate() for domain returned -1 (probably malloc() failure)\n")); + if (!push_ucs2_allocate(&domain, domain_in, &domain_byte_len)) { + DEBUG(0, ("push_uss2_allocate() for domain failed: %s\n", + strerror(errno))); return False; } -- cgit From e2d8b0a7923f52cf2be1c3a14f6390aea9c06fe7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 20 May 2008 23:06:38 +0200 Subject: Fix some signed/unsigned warnings (This used to be commit dbb4d8107a61051d8bcf6c4c69ee976efc50b961) --- source3/libsmb/clirap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index cf4f4987cf..61e2fb7f1a 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -865,7 +865,7 @@ bool cli_qpathinfo_streams(struct cli_state *cli, const char *fname, while ((data_len > ofs) && (data_len - ofs >= 24)) { uint32_t nlen, len; - ssize_t size; + size_t size; void *vstr; struct stream_struct *tmp; uint8_t *tmp_buf; -- cgit From b04bcefc582a5df669a3dc1952e2af85700b2207 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 May 2008 12:39:08 -0700 Subject: Fix bug #5479, print spool shares require max_xmit to be adhered to. Jeremy. (This used to be commit 478a359edead0677281a3ca4e64db6521941b0f3) --- source3/libsmb/clireadwrite.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 12ba4b737f..515471e003 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -704,7 +704,12 @@ ssize_t cli_write(struct cli_state *cli, /* Only do massive writes if we can do them direct * with no signing or encrypting - not on a pipe. */ writesize = CLI_SAMBA_MAX_POSIX_LARGE_WRITEX_SIZE; - } else if (cli->capabilities & CAP_LARGE_WRITEX) { + } else if ((cli->capabilities & CAP_LARGE_WRITEX) && + (strcmp(cli->dev, "LPT1:") != 0)) { + + /* Printer devices are restricted to max_xmit + * writesize in Vista and XPSP3. */ + if (cli->is_samba) { writesize = CLI_SAMBA_MAX_LARGE_WRITEX_SIZE; } else if (!client_is_signing_on(cli)) { -- cgit From 4d2f71e53f5a6cdc5b84a0eeab5822a7f8ca48b9 Mon Sep 17 00:00:00 2001 From: "Gerald W. Carter" Date: Fri, 23 May 2008 16:01:45 -0500 Subject: Manually merge Steven Danneman's patch for SPNEGO auth to a trusted Win2008 domain (merged from v3-0-test). commit 8dc4e979776aae0ecaa74b51dc1eac78a7631405 Author: Steven Danneman Date: Wed May 7 13:34:26 2008 -0700 spnego SPN fix when contacting trusted domains cli_session_setup_spnego() was not taking into consideration the situation where we're connecting to a trusted domain, specifically one (like W2K8) which doesn't return a SPN in the NegTokenInit. This caused two problems: 1) When guessing the SPN using kerberos_get_default_realm_from_ccache() we were always using our default realm, not the realm of the domain we're connecting to. 2) When falling back on NTLMSSP for authentication we were passing the name of the domain we're connecting to for use in our credentials when we should be passing our own workgroup name. The fix for both was to split the single "domain" parameter into "user_domain" and "dest_realm" parameters. We use the "user_domain" parameter to pass into the NTLM call, and we used "dest_realm" to create an SPN if none was returned in the NegTokenInit2 packet. If no "dest_realm" is provided we assume we're connecting to our own domain and use the credentials cache to build the SPN. Since we have a reasonable guess at the SPN, I removed the check that defaults us directly to NTLM when negHint is empty. (This used to be commit b78b14c88e8354aadf9ba7644bdb1c29245fe419) --- source3/libsmb/cliconnect.c | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 751f10bc53..134c3c8a1d 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -785,12 +785,16 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use /**************************************************************************** Do a spnego encrypted session setup. + + user_domain: The shortname of the domain the user/machine is a member of. + dest_realm: The realm we're connecting to, if NULL we use our default realm. ****************************************************************************/ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, - const char *pass, const char *domain) + const char *pass, const char *user_domain, + const char * dest_realm) { - char *principal; + char *principal = NULL; char *OIDs[ASN1_MAX_OIDS]; int i; bool got_kerberos_mechanism = False; @@ -813,8 +817,10 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, /* there is 16 bytes of GUID before the real spnego packet starts */ blob = data_blob(cli->secblob.data+16, cli->secblob.length-16); - /* the server sent us the first part of the SPNEGO exchange in the negprot - reply */ + /* The server sent us the first part of the SPNEGO exchange in the + * negprot reply. It is WRONG to depend on the principal sent in the + * negprot reply, but right now we do it. If we don't receive one, + * we try to best guess, then fall back to NTLM. */ if (!spnego_parse_negTokenInit(blob, OIDs, &principal)) { data_blob_free(&blob); return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER); @@ -833,18 +839,6 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, DEBUG(3,("got principal=%s\n", principal ? principal : "")); - if (got_kerberos_mechanism && (principal == NULL)) { - /* - * It is WRONG to depend on the principal sent in the negprot - * reply, but right now we do it. So for safety (don't - * segfault later) disable Kerberos when no principal was - * sent. -- VL - */ - DEBUG(1, ("Kerberos mech was offered, but no principal was " - "sent, disabling Kerberos\n")); - cli->use_kerberos = False; - } - fstrcpy(cli->user_name, user); #ifdef HAVE_KRB5 @@ -897,7 +891,12 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, return ADS_ERROR_NT(NT_STATUS_NO_MEMORY); } - realm = kerberos_get_default_realm_from_ccache(); + if (dest_realm) { + realm = SMB_STRDUP(dest_realm); + strupper_m(realm); + } else { + realm = kerberos_get_default_realm_from_ccache(); + } if (realm && *realm) { if (asprintf(&principal, "%s$@%s", machine, realm) < 0) { @@ -914,7 +913,8 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, } if (principal) { - rc = cli_session_setup_kerberos(cli, principal, domain); + rc = cli_session_setup_kerberos(cli, principal, + dest_realm); if (ADS_ERR_OK(rc) || !cli->fallback_after_kerberos) { SAFE_FREE(principal); return rc; @@ -939,7 +939,7 @@ ntlmssp: account[PTR_DIFF(p,user)] = '\0'; } - return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, domain)); + return ADS_ERROR_NT(cli_session_setup_ntlmssp(cli, account, pass, user_domain)); } /**************************************************************************** @@ -1031,7 +1031,8 @@ NTSTATUS cli_session_setup(struct cli_state *cli, /* if the server supports extended security then use SPNEGO */ if (cli->capabilities & CAP_EXTENDED_SECURITY) { - ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, workgroup); + ADS_STATUS status = cli_session_setup_spnego(cli, user, pass, + workgroup, NULL); if (!ADS_ERR_OK(status)) { DEBUG(3, ("SPNEGO login failed: %s\n", ads_errstr(status))); return ads_ntstatus(status); -- cgit From 6b3bcb3724eed0ddff26dd7af638b606502081ad Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 23 May 2008 23:56:21 +0200 Subject: drsuapi: add all code required for our drsuapi rpc client. Guenther (This used to be commit 7c93190843e77764be4d0f6d4f0b93061c192c98) --- source3/libsmb/asn1.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index bdbe49b111..39413e252e 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -516,3 +516,87 @@ bool asn1_write_enumerated(ASN1_DATA *data, uint8 v) asn1_pop_tag(data); return !data->has_error; } + +bool ber_write_OID_String(DATA_BLOB *blob, const char *OID) +{ + uint_t v, v2; + const char *p = (const char *)OID; + char *newp; + int i; + + v = strtoul(p, &newp, 10); + if (newp[0] != '.') return false; + p = newp + 1; + + v2 = strtoul(p, &newp, 10); + if (newp[0] != '.') return false; + p = newp + 1; + + /*the ber representation can't use more space then the string one */ + *blob = data_blob(NULL, strlen(OID)); + if (!blob->data) return false; + + blob->data[0] = 40*v + v2; + + i = 1; + while (*p) { + v = strtoul(p, &newp, 10); + if (newp[0] == '.') { + p = newp + 1; + } else if (newp[0] == '\0') { + p = newp; + } else { + data_blob_free(blob); + return false; + } + if (v >= (1<<28)) blob->data[i++] = (0x80 | ((v>>28)&0x7f)); + if (v >= (1<<21)) blob->data[i++] = (0x80 | ((v>>21)&0x7f)); + if (v >= (1<<14)) blob->data[i++] = (0x80 | ((v>>14)&0x7f)); + if (v >= (1<<7)) blob->data[i++] = (0x80 | ((v>>7)&0x7f)); + blob->data[i++] = (v&0x7f); + } + + blob->length = i; + + return true; +} + +/* read an object ID from a data blob */ +bool ber_read_OID_String(TALLOC_CTX *mem_ctx, DATA_BLOB blob, const char **OID) +{ + int i; + uint8_t *b; + uint_t v; + char *tmp_oid = NULL; + + if (blob.length < 2) return false; + + b = blob.data; + + tmp_oid = talloc_asprintf(mem_ctx, "%u", b[0]/40); + if (!tmp_oid) goto nomem; + tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", b[0]%40); + if (!tmp_oid) goto nomem; + + for(i = 1, v = 0; i < blob.length; i++) { + v = (v<<7) | (b[i]&0x7f); + if ( ! (b[i] & 0x80)) { + tmp_oid = talloc_asprintf_append_buffer(tmp_oid, ".%u", v); + v = 0; + } + if (!tmp_oid) goto nomem; + } + + if (v != 0) { + talloc_free(tmp_oid); + return false; + } + + *OID = tmp_oid; + return true; + +nomem: + return false; +} + + -- cgit From aacfa7b3ad7060245d906ea49c39533a6f509f26 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 May 2008 13:44:59 +0200 Subject: Fix two bogus uninitalized variable warnings (This used to be commit 194ea682d9a5c12a0125fecc20349ca9cc3d3ea1) --- source3/libsmb/dsgetdcname.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index d57689cd48..be38db1a3a 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -920,7 +920,8 @@ static NTSTATUS make_dc_info_from_cldap_reply(TALLOC_CTX *mem_ctx, union nbt_cldap_netlogon *r, struct netr_DsRGetDCNameInfo **info) { - const char *dc_hostname, *dc_domain_name; + const char *dc_hostname = NULL; + const char *dc_domain_name = NULL; const char *dc_address = NULL; const char *dc_forest = NULL; uint32_t dc_address_type = 0; -- cgit From 372a6c0360a295223b4ccbd9c2de63e800531231 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 26 May 2008 14:19:28 +0200 Subject: doserr: add WERR_REVISION_MISMATCH. Guenther (This used to be commit 017ad275e51ff2d9ddfb4390979f16868f3e6a3f) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 450d6ee911..163656fb55 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -64,6 +64,7 @@ werror_code_struct dos_errs[] = { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, { "WERR_USER_EXISTS", WERR_USER_EXISTS }, + { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, { "WERR_USER_ALREADY_EXISTS", WERR_USER_ALREADY_EXISTS }, -- cgit From c73cc63e9204c8ffcca06aea1073862eba42e701 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 27 May 2008 11:40:50 +0200 Subject: dsgetdcname: use family (instead of sa_family). Guenther (This used to be commit 355fb81e9e42e507717f33a11793258db9169199) --- source3/libsmb/dsgetdcname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index be38db1a3a..8d75593ddc 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -205,7 +205,7 @@ static NTSTATUS map_logon29_from_cldap_reply(TALLOC_CTX *mem_ctx, /* FIXME */ p->dc_sock_addr_size = 0x10; /* the w32 winsock addr size */ - p->dc_sock_addr.sa_family = 2; /* AF_INET */ + p->dc_sock_addr.family = 2; /* AF_INET */ p->dc_sock_addr.pdc_ip = talloc_strdup(mem_ctx, addr); switch (nt_version & 0x0000001f) { -- cgit From d5d4a9511d763cc4a63d3020c5537e852da2ed4c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 May 2008 12:27:57 -0700 Subject: Memory leak fixes from Chere Zhou . Jeremy. (This used to be commit 201bcc8ed291b51be6f4508c6aa1cb17ce6dcbe3) --- source3/libsmb/smbencrypt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index f339b6b9f6..a8a88a8a7e 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -181,6 +181,7 @@ bool ntv2_owf_gen(const uchar owf[16], if (!push_ucs2_allocate(&domain, domain_in, &domain_byte_len)) { DEBUG(0, ("push_uss2_allocate() for domain failed: %s\n", strerror(errno))); + SAFE_FREE(user); return False; } -- cgit From d36434f31268b75040311352f23c92c9a61e8cda Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 28 May 2008 09:31:42 -0700 Subject: Security fix for CVE-2008-1105: Boundary failure when parsing SMB responses can result in a buffer overrun. Jeremy. (This used to be commit 23b825e9d2c74c5b940cf4d3aa56c18692259972) --- source3/libsmb/clientgen.c | 94 ++------------------------------------- source3/libsmb/clireadwrite.c | 100 ------------------------------------------ 2 files changed, 3 insertions(+), 191 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index e64b6fa278..60ec632b83 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -57,8 +57,7 @@ int cli_set_port(struct cli_state *cli, int port) } /**************************************************************************** - Read an smb from a fd ignoring all keepalive packets. Note that the buffer - *MUST* be of size BUFFER_SIZE+SAFETY_MARGIN. + Read an smb from a fd ignoring all keepalive packets. The timeout is in milliseconds This is exactly the same as receive_smb except that it never returns @@ -76,8 +75,8 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) set_smb_read_error(&cli->smb_rw_error, SMB_READ_OK); - status = receive_smb_raw(cli->fd, cli->inbuf, cli->timeout, - maxlen, &len); + status = receive_smb_raw(cli->fd, cli->inbuf, cli->bufsize, + cli->timeout, maxlen, &len); if (!NT_STATUS_IS_OK(status)) { DEBUG(10,("client_receive_smb failed\n")); show_msg(cli->inbuf); @@ -225,93 +224,6 @@ ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len) return -1; } -/**************************************************************************** - Read a smb readX header. - We can only use this if encryption and signing are off. -****************************************************************************/ - -bool cli_receive_smb_readX_header(struct cli_state *cli) -{ - ssize_t len, offset; - - if (cli->fd == -1) - return false; - - again: - - /* Read up to the size of a readX header reply. */ - len = client_receive_smb(cli, (smb_size - 4) + 24); - - if (len > 0) { - /* it might be an oplock break request */ - if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) && - CVAL(cli->inbuf,smb_com) == SMBlockingX && - SVAL(cli->inbuf,smb_vwv6) == 0 && - SVAL(cli->inbuf,smb_vwv7) == 0) { - ssize_t total_len = smb_len(cli->inbuf); - - if (total_len > CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN) { - goto read_err; - } - - /* Read the rest of the data. */ - if ((total_len - len > 0) && - !cli_receive_smb_data(cli,cli->inbuf+len,total_len - len)) { - goto read_err; - } - - if (cli->oplock_handler) { - int fnum = SVAL(cli->inbuf,smb_vwv2); - unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); - if (!cli->oplock_handler(cli, fnum, level)) return false; - } - /* try to prevent loops */ - SCVAL(cli->inbuf,smb_com,0xFF); - goto again; - } - } - - /* If it's not the above size it probably was an error packet. */ - - if ((len == (smb_size - 4) + 24) && !cli_is_error(cli)) { - /* Check it's a non-chained readX reply. */ - if (!(CVAL(cli->inbuf, smb_flg) & FLAG_REPLY) || - (CVAL(cli->inbuf,smb_vwv0) != 0xFF) || - (CVAL(cli->inbuf,smb_com) != SMBreadX)) { - /* - * We're not coping here with asnyc replies to - * other calls. Punt here - we need async client - * libs for this. - */ - goto read_err; - } - - /* - * We know it's a readX reply - ensure we've read the - * padding bytes also. - */ - - offset = SVAL(cli->inbuf,smb_vwv6); - if (offset > len) { - ssize_t ret; - size_t padbytes = offset - len; - ret = cli_receive_smb_data(cli,smb_buf(cli->inbuf),padbytes); - if (ret != padbytes) { - goto read_err; - } - } - } - - return true; - - read_err: - - cli->smb_rw_error = SMB_READ_ERROR; - close(cli->fd); - cli->fd = -1; - return false; -} - static ssize_t write_socket(int fd, const char *buf, size_t len) { ssize_t ret=0; diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 515471e003..057e647983 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -472,106 +472,6 @@ ssize_t cli_read(struct cli_state *cli, int fnum, char *buf, return ret; } -#if 0 /* relies on client_receive_smb(), now a static in libsmb/clientgen.c */ - -/* This call is INCOMPATIBLE with SMB signing. If you remove the #if 0 - you must fix ensure you don't attempt to sign the packets - data - *will* be currupted */ - -/**************************************************************************** -Issue a single SMBreadraw and don't wait for a reply. -****************************************************************************/ - -static bool cli_issue_readraw(struct cli_state *cli, int fnum, off_t offset, - size_t size, int i) -{ - - if (!cli->sign_info.use_smb_signing) { - DEBUG(0, ("Cannot use readraw and SMB Signing\n")); - return False; - } - - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - cli_set_message(cli->outbuf,10,0,True); - - SCVAL(cli->outbuf,smb_com,SMBreadbraw); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,fnum); - SIVAL(cli->outbuf,smb_vwv1,offset); - SSVAL(cli->outbuf,smb_vwv2,size); - SSVAL(cli->outbuf,smb_vwv3,size); - SSVAL(cli->outbuf,smb_mid,cli->mid + i); - - return cli_send_smb(cli); -} - -/**************************************************************************** - Tester for the readraw call. -****************************************************************************/ - -ssize_t cli_readraw(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size) -{ - char *p; - int size2; - size_t readsize; - ssize_t total = 0; - - if (size == 0) - return 0; - - /* - * Set readsize to the maximum size we can handle in one readraw. - */ - - readsize = 0xFFFF; - - while (total < size) { - readsize = MIN(readsize, size-total); - - /* Issue a read and receive a reply */ - - if (!cli_issue_readraw(cli, fnum, offset, readsize, 0)) - return -1; - - if (!client_receive_smb(cli->fd, cli->inbuf, cli->timeout)) - return -1; - - size2 = smb_len(cli->inbuf); - - if (size2 > readsize) { - DEBUG(5,("server returned more than we wanted!\n")); - return -1; - } else if (size2 < 0) { - DEBUG(5,("read return < 0!\n")); - return -1; - } - - /* Copy data into buffer */ - - if (size2) { - p = cli->inbuf + 4; - memcpy(buf + total, p, size2); - } - - total += size2; - offset += size2; - - /* - * If the server returned less than we asked for we're at EOF. - */ - - if (size2 < readsize) - break; - } - - return total; -} -#endif - /**************************************************************************** Issue a single SMBwrite and don't wait for a reply. ****************************************************************************/ -- cgit From 70b37891f9f3f065254c61ec6c5741592d0b3735 Mon Sep 17 00:00:00 2001 From: Chere Zhou Date: Fri, 30 May 2008 13:16:51 -0700 Subject: minor memory leak fix (This used to be commit 0c61631f345436bf88e93219c139af8cfbeea18b) --- source3/libsmb/asn1.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/asn1.c b/source3/libsmb/asn1.c index 39413e252e..aca1c48841 100644 --- a/source3/libsmb/asn1.c +++ b/source3/libsmb/asn1.c @@ -425,6 +425,7 @@ bool asn1_check_OID(ASN1_DATA *data, const char *OID) if (strcmp(id, OID) != 0) { data->has_error = true; + free(id); return false; } free(id); -- cgit From ff7b8bcebf0f09b6f1b0a9719bd9670a4fc11868 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 28 May 2008 13:57:21 +0200 Subject: doserr: Add WERR_GROUP_EXISTS and WERR_SPECIAL_ACCOUNT. Guenther (This used to be commit 058cf7001e8a57ff0a1e19aadf3e0e068b7e69f4) --- source3/libsmb/doserr.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 163656fb55..905ababdfe 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -69,6 +69,7 @@ werror_code_struct dos_errs[] = { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, { "WERR_USER_ALREADY_EXISTS", WERR_USER_ALREADY_EXISTS }, { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, + { "WERR_GROUP_EXISTS", WERR_GROUP_EXISTS }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, @@ -92,6 +93,7 @@ werror_code_struct dos_errs[] = { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, { "WERR_INVALID_DOMAIN_STATE", WERR_INVALID_DOMAIN_STATE }, { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, + { "WERR_SPECIAL_ACCOUNT", WERR_SPECIAL_ACCOUNT }, { "WERR_TIME_SKEW", WERR_TIME_SKEW }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, @@ -137,6 +139,7 @@ werror_str_struct dos_err_strs[] = { { WERR_PASSWORD_RESTRICTION, "Password does not meet restrictions" }, { WERR_NONE_MAPPED, "Could not map names to SIDs" }, { WERR_NO_SUCH_USER, "No such User" }, + { WERR_GROUP_EXISTS, "Group already exists" }, }; /***************************************************************************** -- cgit From 39101acba53f259f5a0147c9dc19f8d1d0dd6212 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 2 Jun 2008 14:45:08 +0200 Subject: errors: add more WERRORs. Guenther (This used to be commit 973de861c98c62ba31ceb63b3434dc201ae8bf06) --- source3/libsmb/doserr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 905ababdfe..12999e7d80 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -62,6 +62,8 @@ werror_code_struct dos_errs[] = { "WERR_BUF_TOO_SMALL", WERR_BUF_TOO_SMALL }, { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, + { "WERR_GROUP_NOT_FOUND", WERR_GROUP_NOT_FOUND }, + { "WERR_USER_NOT_FOUND", WERR_USER_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, { "WERR_USER_EXISTS", WERR_USER_EXISTS }, { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, @@ -70,6 +72,8 @@ werror_code_struct dos_errs[] = { "WERR_USER_ALREADY_EXISTS", WERR_USER_ALREADY_EXISTS }, { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, { "WERR_GROUP_EXISTS", WERR_GROUP_EXISTS }, + { "WERR_MEMBER_IN_GROUP", WERR_MEMBER_IN_GROUP }, + { "WERR_USER_NOT_IN_GROUP", WERR_USER_NOT_IN_GROUP }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, @@ -94,6 +98,7 @@ werror_code_struct dos_errs[] = { "WERR_INVALID_DOMAIN_STATE", WERR_INVALID_DOMAIN_STATE }, { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, { "WERR_SPECIAL_ACCOUNT", WERR_SPECIAL_ACCOUNT }, + { "WERR_ALIAS_EXISTS", WERR_ALIAS_EXISTS }, { "WERR_TIME_SKEW", WERR_TIME_SKEW }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, -- cgit From 1c0a9759b92c92636f83f965950acc12b07b1eed Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 2 Jun 2008 18:37:16 -0700 Subject: Fix bug reported by David Eisner . When allocating cli buffers for large read/write - make sure we take account of the large read/write SMB headers as well as the buffer space. Jeremy. (This used to be commit 19519bca9b64b736d2fe0447b7cd495f00dba60a) --- source3/libsmb/cliconnect.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 134c3c8a1d..4285753e20 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1353,9 +1353,9 @@ bool cli_negprot(struct cli_state *cli) if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) { SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); - cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); - cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+SAFETY_MARGIN); - cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE; + cli->outbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); + cli->inbuf = (char *)SMB_MALLOC(CLI_SAMBA_MAX_LARGE_READX_SIZE+LARGE_WRITEX_HDR_SIZE+SAFETY_MARGIN); + cli->bufsize = CLI_SAMBA_MAX_LARGE_READX_SIZE + LARGE_WRITEX_HDR_SIZE; } } else if (cli->protocol >= PROTOCOL_LANMAN1) { -- cgit From 48a2a3780b051d3c9f87949f091c791aa95e6e5a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 Jun 2008 14:27:26 -0700 Subject: More correct fix (hopefully :-) for any memory leaks. Jerry promised to check :-). Vl also please review. Jeremy. (This used to be commit 8abc6e742147486a62b4a3f9845e34062845d8ea) --- source3/libsmb/namequery.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index c987890e69..24d7ee1a9c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -1835,6 +1835,9 @@ static NTSTATUS get_dc_list(const char *domain, NTSTATUS status; TALLOC_CTX *ctx = talloc_init("get_dc_list"); + *ip_list = NULL; + *count = 0; + if (!ctx) { return NT_STATUS_NO_MEMORY; } @@ -1914,7 +1917,7 @@ static NTSTATUS get_dc_list(const char *domain, p = pserver; while (next_token_talloc(ctx, &p, &name, LIST_SEP)) { - if (strequal(name, "*")) { + if (!done_auto_lookup && strequal(name, "*")) { status = internal_resolve_name(domain, 0x1C, sitename, &auto_ip_list, &auto_count, @@ -2055,6 +2058,12 @@ static NTSTATUS get_dc_list(const char *domain, out: + if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(return_iplist); + *ip_list = NULL; + *count = 0; + } + SAFE_FREE(auto_ip_list); TALLOC_FREE(ctx); return status; @@ -2074,6 +2083,9 @@ NTSTATUS get_sorted_dc_list( const char *domain, NTSTATUS status; enum dc_lookup_type lookup_type = DC_NORMAL_LOOKUP; + *ip_list = NULL; + *count = 0; + DEBUG(8,("get_sorted_dc_list: attempting lookup " "for name %s (sitename %s) using [%s]\n", domain, @@ -2087,6 +2099,8 @@ NTSTATUS get_sorted_dc_list( const char *domain, status = get_dc_list(domain, sitename, ip_list, count, lookup_type, &ordered); if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(*ip_list); + *count = 0; return status; } @@ -2117,6 +2131,8 @@ NTSTATUS get_kdc_list( const char *realm, count, DC_KDC_ONLY, &ordered); if (!NT_STATUS_IS_OK(status)) { + SAFE_FREE(*ip_list); + *count = 0; return status; } -- cgit From d4cbc4408eba4a06931cc93c59555c4abc2f5ee1 Mon Sep 17 00:00:00 2001 From: Marc VanHeyningen Date: Wed, 4 Jun 2008 15:22:50 -0700 Subject: Negative conn cache uses gencache (This used to be commit 8765eb8ad7bb978d3bb9c9ff8e557791fdc43009) --- source3/libsmb/conncache.c | 318 +++++++++++++++++++++++++++------------------ 1 file changed, 189 insertions(+), 129 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index c4a87623d7..2df45c2b0f 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -6,6 +6,7 @@ Copyright (C) Tim Potter 2001 Copyright (C) Andrew Bartlett 2002 Copyright (C) Gerald (Jerry) Carter 2003 + Copyright (C) Marc VanHeyningen 2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,168 +25,227 @@ #include "includes.h" -#define CONNCACHE_ADDR 1 -#define CONNCACHE_NAME 2 - -/* cache entry contains either a server name **or** and IP address as - the key. This means that a server could have two entries (one for each key) */ - -struct failed_connection_cache { - fstring domain_name; - fstring controller; - time_t lookup_time; - NTSTATUS nt_status; - struct failed_connection_cache *prev, *next; -}; - -static struct failed_connection_cache *failed_connection_cache; - -/********************************************************************** - Check for a previously failed connection. - failed_cache_timeout is an a absolute number of seconds after which - we should time this out. If failed_cache_timeout == 0 then time out - immediately. If failed_cache_timeout == -1 then never time out. -**********************************************************************/ - -NTSTATUS check_negative_conn_cache_timeout( const char *domain, const char *server, unsigned int failed_cache_timeout ) +/** + * @file + * Negative connection cache implemented in terms of gencache API + * + * The negative connection cache stores names of servers which have + * been unresponsive so that we don't waste time repeatedly trying + * to contact them. It used to use an in-memory linked list, but + * this limited its utility to a single process + */ + + +/** + * prefix used for all entries put into the general cache + */ +static const char NEGATIVE_CONN_CACHE_PREFIX[] = "NEG_CONN_CACHE"; + +/** + * Marshalls the domain and server name into the key for the gencache + * record + * + * @param[in] domain required + * @param[in] server may be a FQDN or an IP address + * @return the resulting string, which the caller is responsible for + * SAFE_FREE()ing + * @retval NULL returned on error + */ +static char *negative_conn_cache_keystr(const char *domain, const char *server) { - struct failed_connection_cache *fcc; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - /* can't check if we don't have strings */ - - if ( !domain || !server ) - return NT_STATUS_OK; + const char NEGATIVE_CONN_CACHE_KEY_FMT[] = "%s/%s,%s"; + char *keystr = NULL; - for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { + SMB_ASSERT(domain != NULL); + if (server == NULL) + server = ""; - if (!(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller))) { - continue; /* no match; check the next entry */ - } - - /* we have a match so see if it is still current */ - if (failed_cache_timeout != (unsigned int)-1) { - if (failed_cache_timeout == 0 || - (time(NULL) - fcc->lookup_time) > (time_t)failed_cache_timeout) { - /* Cache entry has expired, delete it */ + if (asprintf(&keystr, NEGATIVE_CONN_CACHE_KEY_FMT, + NEGATIVE_CONN_CACHE_PREFIX, domain, server) == -1) + DEBUG(0, ("negative_conn_cache_keystr: malloc error\n")); - DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", - domain, server )); + return keystr; +} - DLIST_REMOVE(failed_connection_cache, fcc); - SAFE_FREE(fcc); +/** + * Marshalls the NT status into a printable value field for the gencache + * record + * + * @param[in] status + * @return the resulting string, which the caller is responsible for + * SAFE_FREE()ing + * @retval NULL returned on error + */ +static char *negative_conn_cache_valuestr(NTSTATUS status) +{ + char *valuestr = NULL; - return NT_STATUS_OK; - } - } + if (asprintf(&valuestr, "%x", NT_STATUS_V(status)) == -1) + DEBUG(0, ("negative_conn_cache_valuestr: malloc error\n")); - /* The timeout hasn't expired yet so return false */ + return valuestr; +} - DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n", - domain, server )); +/** + * Un-marshalls the NT status from a printable field for the gencache + * record + * + * @param[in] value The value field from the record + * @return the decoded NT status + * @retval NT_STATUS_OK returned on error + */ +static NTSTATUS negative_conn_cache_valuedecode(const char *value) +{ + NTSTATUS result = NT_STATUS_OK; - result = fcc->nt_status; - return result; - } + SMB_ASSERT(value != NULL); + if (sscanf(value, "%x", &(NT_STATUS_V(result))) != 1) + DEBUG(0, ("negative_conn_cache_valuestr: unable to parse " + "value field '%s'\n", value)); + return result; +} - /* end of function means no cache entry */ - return NT_STATUS_OK; +/** + * Function passed to gencache_iterate to remove any matching items + * from the list + * + * @param[in] key Key to the record found and to be deleted + * @param[in] value Value to the record (ignored) + * @param[in] timeout Timeout remaining for the record (ignored) + * @param[in] dptr Handle for passing additional data (ignored) + */ +static void delete_matches(const char *key, const char *value, + time_t timeout, void *dptr) +{ + gencache_del(key); } + +/** + * Checks for a given domain/server record in the negative cache + * + * @param[in] domain + * @param[in] server may be either a FQDN or an IP address + * @return The cached failure status + * @retval NT_STATUS_OK returned if no record is found or an error occurs + */ NTSTATUS check_negative_conn_cache( const char *domain, const char *server) { - return check_negative_conn_cache_timeout(domain, server, FAILED_CONNECTION_CACHE_TIMEOUT); + NTSTATUS result = NT_STATUS_OK; + char *key = NULL; + char *value = NULL; + + key = negative_conn_cache_keystr(domain, server); + if (key == NULL) + goto done; + + if (gencache_get(key, &value, (time_t *) NULL)) + result = negative_conn_cache_valuedecode(value); + done: + DEBUG(9,("check_negative_conn_cache returning result %d for domain %s " + "server %s\n", NT_STATUS_V(result), domain, server)); + SAFE_FREE(key); + SAFE_FREE(value); + return result; } -/********************************************************************** - Add an entry to the failed conneciton cache (aither a name of dotted - decimal IP -**********************************************************************/ - -void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) +/** + * Delete any negative cache entry for the given domain/server + * + * @param[in] domain + * @param[in] server may be either a FQDN or an IP address + */ +void delete_negative_conn_cache(const char *domain, const char *server) { - struct failed_connection_cache *fcc; + char *key = NULL; + + key = negative_conn_cache_keystr(domain, server); + if (key == NULL) + goto done; + + gencache_del(key); + DEBUG(9,("delete_negative_conn_cache removing domain %s server %s\n", + domain, server)); + done: + SAFE_FREE(key); + return; +} - SMB_ASSERT(!NT_STATUS_IS_OK(result)); - /* Check we already aren't in the cache. We always have to have - a domain, but maybe not a specific DC name. */ - - for (fcc = failed_connection_cache; fcc; fcc = fcc->next) { - if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) { - DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n", - domain, server )); - /* Update the failed time. */ - fcc->lookup_time = time(NULL); - return; - } - } +/** + * Add an entry to the failed conneciton cache + * + * @param[in] domain + * @param[in] server may be a FQDN or an IP addr in printable form + * @param[in] result error to cache; must not be NT_STATUS_OK + */ +void add_failed_connection_entry(const char *domain, const char *server, + NTSTATUS result) +{ + char *key = NULL; + char *value = NULL; - /* Create negative lookup cache entry for this domain and controller */ + SMB_ASSERT(!NT_STATUS_IS_OK(result)); - if ( !(fcc = SMB_MALLOC_P(struct failed_connection_cache)) ) { - DEBUG(0, ("malloc failed in add_failed_connection_entry!\n")); - return; + key = negative_conn_cache_keystr(domain, server); + if (key == NULL) { + DEBUG(0, ("add_failed_connection_entry: key creation error\n")); + goto done; } - ZERO_STRUCTP(fcc); - - fstrcpy( fcc->domain_name, domain ); - fstrcpy( fcc->controller, server ); - fcc->lookup_time = time(NULL); - fcc->nt_status = result; + value = negative_conn_cache_valuestr(result); + if (value == NULL) { + DEBUG(0, ("add_failed_connection_entry: value creation error\n")); + goto done; + } - DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n", - domain, server )); + if (gencache_set(key, value, + time((time_t *) NULL + FAILED_CONNECTION_CACHE_TIMEOUT))) + DEBUG(9,("add_failed_connection_entry: added domain %s (%s) " + "to failed conn cache\n", domain, server )); + else + DEBUG(1,("add_failed_connection_entry: failed to add " + "domain %s (%s) to failed conn cache\n", + domain, server)); - DLIST_ADD(failed_connection_cache, fcc); + done: + SAFE_FREE(key); + SAFE_FREE(value); + return; } -/**************************************************************************** -****************************************************************************/ - +/** + * Deletes all records from the negative connection cache in all domains + */ void flush_negative_conn_cache( void ) { - struct failed_connection_cache *fcc; - - fcc = failed_connection_cache; - - while (fcc) { - struct failed_connection_cache *fcc_next; - - fcc_next = fcc->next; - DLIST_REMOVE(failed_connection_cache, fcc); - free(fcc); - - fcc = fcc_next; - } - + flush_negative_conn_cache_for_domain("*"); } -/**************************************************************************** - Remove all negative entries for a domain. Used when going to online state in - winbindd. -****************************************************************************/ - + +/** + * Deletes all records for a specified domain from the negative connection + * cache + * + * @param[in] domain String to match against domain portion of keys, or "*" + * to match all domains + */ void flush_negative_conn_cache_for_domain(const char *domain) { - struct failed_connection_cache *fcc; - - fcc = failed_connection_cache; - - while (fcc) { - struct failed_connection_cache *fcc_next; + char *key_pattern = NULL; - fcc_next = fcc->next; - - if (strequal(fcc->domain_name, domain)) { - DEBUG(10,("flush_negative_conn_cache_for_domain: removed server %s " - " from failed cache for domain %s\n", - fcc->controller, domain)); - DLIST_REMOVE(failed_connection_cache, fcc); - free(fcc); - } - - fcc = fcc_next; + key_pattern = negative_conn_cache_keystr(domain,"*"); + if (key_pattern == NULL) { + DEBUG(0, ("flush_negative_conn_cache_for_domain: " + "key creation error\n")); + goto done; } + + gencache_iterate(delete_matches, (void *) NULL, key_pattern); + DEBUG(8, ("flush_negative_conn_cache_for_domain: flushed domain %s\n", + domain)); + + done: + SAFE_FREE(key_pattern); + return; } -- cgit From a191f3d2fede9cfa19261060a2788df75bc15089 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jun 2008 09:00:37 +0200 Subject: Make the gencache based conncache use talloc_tos() (This used to be commit f7f912a478af64b07beeb58673b605da0c46db94) --- source3/libsmb/conncache.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index 2df45c2b0f..b8f98085ce 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -59,10 +59,12 @@ static char *negative_conn_cache_keystr(const char *domain, const char *server) SMB_ASSERT(domain != NULL); if (server == NULL) server = ""; - - if (asprintf(&keystr, NEGATIVE_CONN_CACHE_KEY_FMT, - NEGATIVE_CONN_CACHE_PREFIX, domain, server) == -1) + + keystr = talloc_asprintf(talloc_tos(),NEGATIVE_CONN_CACHE_KEY_FMT, + NEGATIVE_CONN_CACHE_PREFIX, domain, server); + if (keystr == NULL) { DEBUG(0, ("negative_conn_cache_keystr: malloc error\n")); + } return keystr; } @@ -80,8 +82,10 @@ static char *negative_conn_cache_valuestr(NTSTATUS status) { char *valuestr = NULL; - if (asprintf(&valuestr, "%x", NT_STATUS_V(status)) == -1) + valuestr = talloc_asprintf(talloc_tos(), "%x", NT_STATUS_V(status)); + if (valuestr == NULL) { DEBUG(0, ("negative_conn_cache_valuestr: malloc error\n")); + } return valuestr; } @@ -144,7 +148,7 @@ NTSTATUS check_negative_conn_cache( const char *domain, const char *server) done: DEBUG(9,("check_negative_conn_cache returning result %d for domain %s " "server %s\n", NT_STATUS_V(result), domain, server)); - SAFE_FREE(key); + TALLOC_FREE(key); SAFE_FREE(value); return result; } @@ -167,7 +171,7 @@ void delete_negative_conn_cache(const char *domain, const char *server) DEBUG(9,("delete_negative_conn_cache removing domain %s server %s\n", domain, server)); done: - SAFE_FREE(key); + TALLOC_FREE(key); return; } @@ -192,13 +196,13 @@ void add_failed_connection_entry(const char *domain, const char *server, DEBUG(0, ("add_failed_connection_entry: key creation error\n")); goto done; } - + value = negative_conn_cache_valuestr(result); if (value == NULL) { DEBUG(0, ("add_failed_connection_entry: value creation error\n")); goto done; } - + if (gencache_set(key, value, time((time_t *) NULL + FAILED_CONNECTION_CACHE_TIMEOUT))) DEBUG(9,("add_failed_connection_entry: added domain %s (%s) " @@ -209,8 +213,8 @@ void add_failed_connection_entry(const char *domain, const char *server, domain, server)); done: - SAFE_FREE(key); - SAFE_FREE(value); + TALLOC_FREE(key); + TALLOC_FREE(value); return; } @@ -246,6 +250,6 @@ void flush_negative_conn_cache_for_domain(const char *domain) domain)); done: - SAFE_FREE(key_pattern); + TALLOC_FREE(key_pattern); return; } -- cgit From dd30dd2a14f4a883d737150de80d896b941180c5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 5 Jun 2008 09:36:34 +0200 Subject: Fix a crash in add_failed_connection_entry (This used to be commit 2a689aa66af1de3d2e0d08b51e33e9a7015d6cb7) --- source3/libsmb/conncache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index b8f98085ce..05344f4071 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -204,7 +204,8 @@ void add_failed_connection_entry(const char *domain, const char *server, } if (gencache_set(key, value, - time((time_t *) NULL + FAILED_CONNECTION_CACHE_TIMEOUT))) + time((time_t *) NULL) + + FAILED_CONNECTION_CACHE_TIMEOUT)) DEBUG(9,("add_failed_connection_entry: added domain %s (%s) " "to failed conn cache\n", domain, server )); else -- cgit From 513bc4e791676e18c448c21c5392cb9b05a49fa4 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Jun 2008 16:18:50 +0200 Subject: dsgetdcname: allow to use NULL mem_ctx. Guenther (This used to be commit d20353d30c2e08a6c6d67ae8b8c2faa26004249c) --- source3/libsmb/dsgetdcname.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 8d75593ddc..2a445cbd5a 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -119,7 +119,7 @@ void debug_dsdcinfo_flags(int lvl, uint32_t flags) static char *dsgetdcname_cache_key(TALLOC_CTX *mem_ctx, const char *domain) { - if (!mem_ctx || !domain) { + if (!domain) { return NULL; } -- cgit From fd288b4110a988ef37f153dfee95381f6675a7ef Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 17 Jun 2008 17:58:38 +0200 Subject: clikrb5: remove unrequired create_kerberos_key_from_string_direct() prototype. Guenther (This used to be commit ec86852fc6ce2d88ad5835c8fcb337c68fd6f6bc) --- source3/libsmb/clikrb5.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 7688b0bd12..4c535d2bcf 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -210,11 +210,11 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, #endif #if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_USE_ENCTYPE) && defined(HAVE_KRB5_STRING_TO_KEY) && defined(HAVE_KRB5_ENCRYPT_BLOCK) - int create_kerberos_key_from_string_direct(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key, - krb5_enctype enctype) +static int create_kerberos_key_from_string_direct(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) { int ret; krb5_data salt; @@ -231,11 +231,11 @@ static krb5_error_code smb_krb5_parse_name_norealm_conv(krb5_context context, return ret; } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) - int create_kerberos_key_from_string_direct(krb5_context context, - krb5_principal host_princ, - krb5_data *password, - krb5_keyblock *key, - krb5_enctype enctype) +static int create_kerberos_key_from_string_direct(krb5_context context, + krb5_principal host_princ, + krb5_data *password, + krb5_keyblock *key, + krb5_enctype enctype) { int ret; krb5_salt salt; -- cgit From 0ac8c5d49a8b0d5535eebf80871003f6c19af5eb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 18 Jun 2008 12:45:57 +0200 Subject: kerberos: make smb_krb5_kt_add_entry public, allow to pass keys without salting them. Guenther (This used to be commit 7c4da23be1105dc224033b21eb486e7fcdc7d9c5) --- source3/libsmb/clikrb5.c | 56 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 18 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 4c535d2bcf..52c729625c 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -214,20 +214,31 @@ static int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, - krb5_enctype enctype) + krb5_enctype enctype, + bool no_salt) { int ret; krb5_data salt; krb5_encrypt_block eblock; - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return ret; + if (no_salt) { + key->contents = (krb5_octet *)SMB_MALLOC(password->length); + if (!key->contents) { + return ENOMEM; + } + memcpy(key->contents, password->data, password->length); + key->length = password->length; + key->enctype = enctype; + } else { + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; + } + krb5_use_enctype(context, &eblock, enctype); + ret = krb5_string_to_key(context, &eblock, key, password, &salt); + SAFE_FREE(salt.data); } - krb5_use_enctype(context, &eblock, enctype); - ret = krb5_string_to_key(context, &eblock, key, password, &salt); - SAFE_FREE(salt.data); return ret; } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) @@ -235,19 +246,27 @@ static int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, - krb5_enctype enctype) + krb5_enctype enctype, + bool no_salt) { int ret; krb5_salt salt; - ret = krb5_get_pw_salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); - return ret; + if (no_salt) { + return krb5_keyblock_init(context, enctype, + password->data, password->length, + key); + } else { + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; + } + + ret = krb5_string_to_key_salt(context, enctype, (const char *)password->data, salt, key); + krb5_free_salt(context, salt); } - - ret = krb5_string_to_key_salt(context, enctype, (const char *)password->data, salt, key); - krb5_free_salt(context, salt); + return ret; } #else @@ -258,7 +277,8 @@ static int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, - krb5_enctype enctype) + krb5_enctype enctype, + bool no_salt) { krb5_principal salt_princ = NULL; int ret; @@ -268,7 +288,7 @@ static int create_kerberos_key_from_string_direct(krb5_context context, * its behavior. */ salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype); - ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype); + ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype, no_salt); if (salt_princ) { krb5_free_principal(context, salt_princ); } -- cgit From 640a2972c555a456ea9a083bdc7aae8ea283492a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 18 Jun 2008 12:48:35 +0200 Subject: kerberos: add smb_krb5_keytab_name(). Guenther (This used to be commit c273ce8798062d1b55100411f3e92a01bdbf611c) --- source3/libsmb/clikrb5.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 52c729625c..2aae9df53e 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1727,6 +1727,28 @@ done: return ret; } +krb5_error_code smb_krb5_keytab_name(TALLOC_CTX *mem_ctx, + krb5_context context, + krb5_keytab keytab, + const char **keytab_name) +{ + char keytab_string[MAX_KEYTAB_NAME_LEN]; + krb5_error_code ret = 0; + + ret = krb5_kt_get_name(context, keytab, + keytab_string, MAX_KEYTAB_NAME_LEN - 2); + if (ret) { + return ret; + } + + *keytab_name = talloc_strdup(mem_ctx, keytab_string); + if (!*keytab_name) { + return ENOMEM; + } + + return ret; +} + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, -- cgit From 9a5fc5b5d3d9ec334a35cadb49bf69c36076dcea Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 23 Jun 2008 16:02:04 +0200 Subject: crypto: add decrypt_drsuapi_blob from samba4. Guenther (This used to be commit 3b6352a60e6683963af1641786f9c230d49ebfb5) --- source3/libsmb/smbencrypt.c | 114 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c index a8a88a8a7e..0742976635 100644 --- a/source3/libsmb/smbencrypt.c +++ b/source3/libsmb/smbencrypt.c @@ -782,3 +782,117 @@ WERROR decode_wkssvc_join_password_buffer(TALLOC_CTX *mem_ctx, return WERR_OK; } + +DATA_BLOB decrypt_drsuapi_blob(TALLOC_CTX *mem_ctx, + const DATA_BLOB *session_key, + bool rcrypt, + uint32_t rid, + const DATA_BLOB *buffer) +{ + DATA_BLOB confounder; + DATA_BLOB enc_buffer; + + struct MD5Context md5; + uint8_t _enc_key[16]; + DATA_BLOB enc_key; + + DATA_BLOB dec_buffer; + + uint32_t crc32_given; + uint32_t crc32_calc; + DATA_BLOB checked_buffer; + + DATA_BLOB plain_buffer; + + /* + * the combination "c[3] s[1] e[1] d[0]..." + * was successful!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + + /* + * the first 16 bytes at the beginning are the confounder + * followed by the 4 byte crc32 checksum + */ + if (buffer->length < 20) { + return data_blob_const(NULL, 0); + } + confounder = data_blob_const(buffer->data, 16); + enc_buffer = data_blob_const(buffer->data + 16, buffer->length - 16); + + /* + * build the encryption key md5 over the session key followed + * by the confounder + * + * here the gensec session key is used and + * not the dcerpc ncacn_ip_tcp "SystemLibraryDTC" key! + */ + enc_key = data_blob_const(_enc_key, sizeof(_enc_key)); + MD5Init(&md5); + MD5Update(&md5, session_key->data, session_key->length); + MD5Update(&md5, confounder.data, confounder.length); + MD5Final(enc_key.data, &md5); + + /* + * copy the encrypted buffer part and + * decrypt it using the created encryption key using arcfour + */ + dec_buffer = data_blob_talloc(mem_ctx, enc_buffer.data, enc_buffer.length); + if (!dec_buffer.data) { + return data_blob_const(NULL, 0); + } + SamOEMhashBlob(dec_buffer.data, dec_buffer.length, &enc_key); + + /* + * the first 4 byte are the crc32 checksum + * of the remaining bytes + */ + crc32_given = IVAL(dec_buffer.data, 0); + crc32_calc = crc32_calc_buffer((const char *)dec_buffer.data + 4 , dec_buffer.length - 4); + if (crc32_given != crc32_calc) { + DEBUG(1,("CRC32: given[0x%08X] calc[0x%08X]\n", + crc32_given, crc32_calc)); + return data_blob_const(NULL, 0); + } + checked_buffer = data_blob_talloc(mem_ctx, dec_buffer.data + 4, dec_buffer.length - 4); + if (!checked_buffer.data) { + return data_blob_const(NULL, 0); + } + + /* + * some attributes seem to be in a usable form after this decryption + * (supplementalCredentials, priorValue, currentValue, trustAuthOutgoing, + * trustAuthIncoming, initialAuthOutgoing, initialAuthIncoming) + * At least supplementalCredentials contains plaintext + * like "Primary:Kerberos" (in unicode form) + * + * some attributes seem to have some additional encryption + * dBCSPwd, unicodePwd, ntPwdHistory, lmPwdHistory + * + * it's the sam_rid_crypt() function, as the value is constant, + * so it doesn't depend on sessionkeys. + */ + if (rcrypt) { + uint32_t i, num_hashes; + + if ((checked_buffer.length % 16) != 0) { + return data_blob_const(NULL, 0); + } + + plain_buffer = data_blob_talloc(mem_ctx, checked_buffer.data, checked_buffer.length); + if (!plain_buffer.data) { + return data_blob_const(NULL, 0); + } + + num_hashes = plain_buffer.length / 16; + for (i = 0; i < num_hashes; i++) { + uint32_t offset = i * 16; + sam_pwd_hash(rid, checked_buffer.data + offset, plain_buffer.data + offset, 0); + } + } else { + plain_buffer = checked_buffer; + } + + return plain_buffer; +} + + -- cgit From 059293cbf4553a3b4dbfe78dcadb362ec344ef3b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 25 Jun 2008 10:35:59 +0200 Subject: rename rpccli_samr_chgpasswd_user to rpccli_samr_chgpasswd_user2. Guenther (This used to be commit 5b4650d56c04be0c498413f17afb2cf6d0e7d548) --- source3/libsmb/passchange.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 8f7cbf265e..3b82e5767f 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -177,8 +177,8 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } } - result = rpccli_samr_chgpasswd_user(pipe_hnd, talloc_tos(), - user_name, new_passwd, old_passwd); + result = rpccli_samr_chgpasswd_user2(pipe_hnd, talloc_tos(), + user_name, new_passwd, old_passwd); if (NT_STATUS_IS_OK(result)) { /* Great - it all worked! */ cli_shutdown(cli); @@ -207,7 +207,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); if ( pipe_hnd && - (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user( + (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user2( pipe_hnd, talloc_tos(), user_name, new_passwd, old_passwd)))) { /* Great - it all worked! */ -- cgit From 5a4cf3dbf24809a61d4d1d62036e05f5d108d0f6 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 26 Jun 2008 09:49:13 +0200 Subject: errors: add WERR_DS_DRA_BAD_NC and WERR_DS_DRA_BAD_DN. Guenther (This used to be commit 2efe18f7c96d8d122943342b9af1db62a1432771) --- source3/libsmb/doserr.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 12999e7d80..bbb12e0a29 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -118,6 +118,8 @@ werror_code_struct dos_errs[] = { "WERR_PASSWORD_MUST_CHANGE", WERR_PASSWORD_MUST_CHANGE }, { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, { "WERR_ACCOUNT_LOCKED_OUT", WERR_ACCOUNT_LOCKED_OUT }, + { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, + { "WERR_DS_DRA_BAD_NC", WERR_DS_DRA_BAD_NC }, { NULL, W_ERROR(0) } }; @@ -145,6 +147,8 @@ werror_str_struct dos_err_strs[] = { { WERR_NONE_MAPPED, "Could not map names to SIDs" }, { WERR_NO_SUCH_USER, "No such User" }, { WERR_GROUP_EXISTS, "Group already exists" }, + { WERR_DS_DRA_BAD_DN, "An invalid distinguished name was specified for this replication" }, + { WERR_DS_DRA_BAD_NC, "An invalid naming context was specified for this replication operation" }, }; /***************************************************************************** -- cgit From 23cafd02d3222b910dbc30a7eab20ebdcc81ab33 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Jun 2008 13:19:40 -0700 Subject: Fix return of uninitialized variable. Jeremy. (This used to be commit 384052f546af8c1c6848c03cad4f2ba618ba7209) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2aae9df53e..cbe8f24909 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -217,7 +217,7 @@ static int create_kerberos_key_from_string_direct(krb5_context context, krb5_enctype enctype, bool no_salt) { - int ret; + int ret = 0; krb5_data salt; krb5_encrypt_block eblock; -- cgit From 4a09c5a09f791738453947f07abe8d0f100fe53d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Jul 2008 15:39:41 -0700 Subject: Two more fixes from Jim Brown for SGI compiler warnings. Jeremy. (This used to be commit d85cbdbe296ec6de5bdbd66a90ca41345f55c837) --- source3/libsmb/clientgen.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 60ec632b83..2c0950de03 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -97,7 +97,12 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) return -1; } - if (len < 0) { + /* + * I don't believe len can be < 0 with NT_STATUS_OK + * returned above, but this check doesn't hurt. JRA. + */ + + if ((ssize_t)len < 0) { return len; } -- cgit From 962beb287239b525ed4828ae13b85de31448d256 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 3 Jul 2008 15:15:57 +0200 Subject: Pass NULL to gencache_get when we are not interested in the timeout value (This used to be commit 16062dfc3dcc8f1ca0024a3ae21effb889c7ffc0) --- source3/libsmb/namecache.c | 6 ++---- source3/libsmb/namequery.c | 3 +-- source3/libsmb/trustdom_cache.c | 6 ++---- 3 files changed, 5 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index ba706e5ee2..1f462ba79a 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -200,7 +200,6 @@ bool namecache_fetch(const char *name, int *num_names) { char *key, *value; - time_t timeout; /* exit now if null pointers were passed as they're required further */ if (!ip_list || !num_names) { @@ -225,7 +224,7 @@ bool namecache_fetch(const char *name, return False; } - if (!gencache_get(key, &value, &timeout)) { + if (!gencache_get(key, &value, NULL)) { DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); SAFE_FREE(key); return False; @@ -367,7 +366,6 @@ bool namecache_status_fetch(const char *keyname, { char *key = NULL; char *value = NULL; - time_t timeout; if (!gencache_init()) return False; @@ -377,7 +375,7 @@ bool namecache_status_fetch(const char *keyname, if (!key) return False; - if (!gencache_get(key, &value, &timeout)) { + if (!gencache_get(key, &value, NULL)) { DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key)); SAFE_FREE(key); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 24d7ee1a9c..9b50d209b9 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -112,7 +112,6 @@ bool saf_delete( const char *domain ) char *saf_fetch( const char *domain ) { char *server = NULL; - time_t timeout; bool ret = False; char *key = NULL; @@ -126,7 +125,7 @@ char *saf_fetch( const char *domain ) key = saf_key( domain ); - ret = gencache_get( key, &server, &timeout ); + ret = gencache_get( key, &server, NULL ); SAFE_FREE( key ); diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 6755de3814..92dde0c6c8 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -164,7 +164,6 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, bool trustdom_cache_fetch(const char* name, DOM_SID* sid) { char *key = NULL, *value = NULL; - time_t timeout; /* init the cache */ if (!gencache_init()) @@ -179,7 +178,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) if (!key) return False; - if (!gencache_get(key, &value, &timeout)) { + if (!gencache_get(key, &value, NULL)) { DEBUG(5, ("no entry for trusted domain %s found.\n", name)); SAFE_FREE(key); return False; @@ -207,14 +206,13 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) uint32 trustdom_cache_fetch_timestamp( void ) { char *value = NULL; - time_t timeout; uint32 timestamp; /* init the cache */ if (!gencache_init()) return False; - if (!gencache_get(TDOMTSKEY, &value, &timeout)) { + if (!gencache_get(TDOMTSKEY, &value, NULL)) { DEBUG(5, ("no timestamp for trusted domain cache located.\n")); SAFE_FREE(value); return 0; -- cgit From 352b5c18579c9610c15e5c24e012e60cd972b95a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 3 Jul 2008 16:24:27 +0200 Subject: Remove gencache_[un]lock_entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Günther agreed that it might be unnecessary in dsgetdcname_cache_store() :-) (This used to be commit 7a5a575ffe5196caecedc93970a25abfbe6f8059) --- source3/libsmb/dsgetdcname.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 2a445cbd5a..afc87030d0 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -159,7 +159,6 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, { time_t expire_time; char *key; - bool ret = false; if (!gencache_init()) { return NT_STATUS_INTERNAL_DB_ERROR; @@ -172,15 +171,8 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL; - if (gencache_lock_entry(key) != 0) { - return NT_STATUS_LOCK_NOT_GRANTED; - } - - ret = gencache_set_data_blob(key, blob, expire_time); - - gencache_unlock_entry(key); - - return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + return gencache_set_data_blob(key, blob, expire_time) + ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } /**************************************************************** -- cgit From 31262a59bcf1cb04631c2efca169e417ef597bec Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Tue, 8 Jul 2008 20:44:39 -0400 Subject: [BUG 5580] Allow access to DFS shares via libsmbclient Brian Sheehan provided a nice patch intended for the 3.0 code base. This commit applies a similar patch for the 3.3 code base. It adds a new public function to libsmbclient -- smbc_set_credentials() -- that may be called from the authentication callback when DFS referrals are in use. Derrell (This used to be commit 888f922bd0d1c84a687d404e95ae314a9dd0aee1) --- source3/libsmb/libsmb_context.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index dd78bcee35..51948d1648 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -610,3 +610,23 @@ smbc_version(void) } +/* + * Set the credentials so DFS will work when following referrals. + */ +void +smbc_set_credentials(char *workgroup, + char *user, + char *password, + bool use_kerberos, + char *signing_state) +{ + + set_cmdline_auth_info_username(user); + set_cmdline_auth_info_password(password); + set_cmdline_auth_info_use_kerberos(use_kerberos); + if (! set_cmdline_auth_info_signing_state(signing_state)) { + DEBUG(0, ("Invalid signing state: %s", signing_state)); + } + set_global_myworkgroup(workgroup); + cli_cm_set_credentials(); +} -- cgit From d670d0a09bec3b6900421df17fc9d959545ee953 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Jul 2008 17:44:09 +0200 Subject: Revert "Remove gencache_[un]lock_entry" This reverts commit 7a5a575ffe5196caecedc93970a25abfbe6f8059. (This used to be commit 62e444dd50ae974c2ab9a553cdf7f188a8f2c538) --- source3/libsmb/dsgetdcname.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index afc87030d0..2a445cbd5a 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -159,6 +159,7 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, { time_t expire_time; char *key; + bool ret = false; if (!gencache_init()) { return NT_STATUS_INTERNAL_DB_ERROR; @@ -171,8 +172,15 @@ static NTSTATUS dsgetdcname_cache_store(TALLOC_CTX *mem_ctx, expire_time = time(NULL) + DSGETDCNAME_CACHE_TTL; - return gencache_set_data_blob(key, blob, expire_time) - ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; + if (gencache_lock_entry(key) != 0) { + return NT_STATUS_LOCK_NOT_GRANTED; + } + + ret = gencache_set_data_blob(key, blob, expire_time); + + gencache_unlock_entry(key); + + return ret ? NT_STATUS_OK : NT_STATUS_UNSUCCESSFUL; } /**************************************************************** -- cgit From d3def9a18cc701573530154ed420278f007f06a3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 11 Jul 2008 17:44:25 +0200 Subject: Revert "Pass NULL to gencache_get when we are not interested in the timeout value" This reverts commit 16062dfc3dcc8f1ca0024a3ae21effb889c7ffc0. (This used to be commit 114ca8577568cdb5a81d8734f1d1d096f1b36c36) --- source3/libsmb/namecache.c | 6 ++++-- source3/libsmb/namequery.c | 3 ++- source3/libsmb/trustdom_cache.c | 6 ++++-- 3 files changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/namecache.c b/source3/libsmb/namecache.c index 1f462ba79a..ba706e5ee2 100644 --- a/source3/libsmb/namecache.c +++ b/source3/libsmb/namecache.c @@ -200,6 +200,7 @@ bool namecache_fetch(const char *name, int *num_names) { char *key, *value; + time_t timeout; /* exit now if null pointers were passed as they're required further */ if (!ip_list || !num_names) { @@ -224,7 +225,7 @@ bool namecache_fetch(const char *name, return False; } - if (!gencache_get(key, &value, NULL)) { + if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for %s#%02X found.\n", name, name_type)); SAFE_FREE(key); return False; @@ -366,6 +367,7 @@ bool namecache_status_fetch(const char *keyname, { char *key = NULL; char *value = NULL; + time_t timeout; if (!gencache_init()) return False; @@ -375,7 +377,7 @@ bool namecache_status_fetch(const char *keyname, if (!key) return False; - if (!gencache_get(key, &value, NULL)) { + if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("namecache_status_fetch: no entry for %s found.\n", key)); SAFE_FREE(key); diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c index 9b50d209b9..24d7ee1a9c 100644 --- a/source3/libsmb/namequery.c +++ b/source3/libsmb/namequery.c @@ -112,6 +112,7 @@ bool saf_delete( const char *domain ) char *saf_fetch( const char *domain ) { char *server = NULL; + time_t timeout; bool ret = False; char *key = NULL; @@ -125,7 +126,7 @@ char *saf_fetch( const char *domain ) key = saf_key( domain ); - ret = gencache_get( key, &server, NULL ); + ret = gencache_get( key, &server, &timeout ); SAFE_FREE( key ); diff --git a/source3/libsmb/trustdom_cache.c b/source3/libsmb/trustdom_cache.c index 92dde0c6c8..6755de3814 100644 --- a/source3/libsmb/trustdom_cache.c +++ b/source3/libsmb/trustdom_cache.c @@ -164,6 +164,7 @@ bool trustdom_cache_store(char* name, char* alt_name, const DOM_SID *sid, bool trustdom_cache_fetch(const char* name, DOM_SID* sid) { char *key = NULL, *value = NULL; + time_t timeout; /* init the cache */ if (!gencache_init()) @@ -178,7 +179,7 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) if (!key) return False; - if (!gencache_get(key, &value, NULL)) { + if (!gencache_get(key, &value, &timeout)) { DEBUG(5, ("no entry for trusted domain %s found.\n", name)); SAFE_FREE(key); return False; @@ -206,13 +207,14 @@ bool trustdom_cache_fetch(const char* name, DOM_SID* sid) uint32 trustdom_cache_fetch_timestamp( void ) { char *value = NULL; + time_t timeout; uint32 timestamp; /* init the cache */ if (!gencache_init()) return False; - if (!gencache_get(TDOMTSKEY, &value, NULL)) { + if (!gencache_get(TDOMTSKEY, &value, &timeout)) { DEBUG(5, ("no timestamp for trusted domain cache located.\n")); SAFE_FREE(value); return 0; -- cgit From 1939177582867fb54a416f3ea979ebd8d4335885 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Tue, 15 Jul 2008 23:05:13 +0200 Subject: fix build warning. Guenther (This used to be commit 507660706901a79544d436046127947e4baa7e52) --- source3/libsmb/clirap2.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap2.c b/source3/libsmb/clirap2.c index 9cc8110576..a15fa5f7d8 100644 --- a/source3/libsmb/clirap2.c +++ b/source3/libsmb/clirap2.c @@ -1856,6 +1856,7 @@ bool cli_NetWkstaUserLogoff(struct cli_state *cli, const char *user, const char +WORDSIZE]; /* buffer size? */ char upperbuf[MAX(RAP_USERNAME_LEN,RAP_MACHNAME_LEN)]; int res = -1; + char *tmp = NULL; memset(param, 0, sizeof(param)); @@ -1866,11 +1867,13 @@ bool cli_NetWkstaUserLogoff(struct cli_state *cli, const char *user, const char PUTDWORD(p, 0); /* Null pointer */ strlcpy(upperbuf, user, sizeof(upperbuf)); strupper_m(upperbuf); - PUTSTRINGF(p, upperbuf, RAP_USERNAME_LEN); + tmp = upperbuf; + PUTSTRINGF(p, tmp, RAP_USERNAME_LEN); p++; /* strange format, but ok */ strlcpy(upperbuf, workstation, sizeof(upperbuf)); strupper_m(upperbuf); - PUTSTRINGF(p, upperbuf, RAP_MACHNAME_LEN); + tmp = upperbuf; + PUTSTRINGF(p, tmp, RAP_MACHNAME_LEN); PUTWORD(p, CLI_BUFFER_SIZE); PUTWORD(p, CLI_BUFFER_SIZE); -- cgit From 525a3f3c491ae83feb94bc2d7e1979643641166d Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Tue, 15 Jul 2008 14:57:32 +0200 Subject: Release still reachable memory if the smbclient context is freed. Signed-off-by: Andreas Schneider (This used to be commit 7a65053bc8579b4f56045fb2c658a91a4af0dfea) --- source3/libsmb/libsmb_context.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 51948d1648..114f775086 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -200,6 +200,22 @@ smbc_free_context(SMBCCTX *context, smbc_setUser(context, NULL); DEBUG(3, ("Context %p successfully freed\n", context)); + + gfree_names(); + gfree_loadparm(); + gfree_case_tables(); + gfree_charcnv(); + gfree_interfaces(); + + gencache_shutdown(); + secrets_shutdown(); + + /* release the talloc null_context memory last */ + talloc_disable_null_tracking(); + + gfree_debugsyms(); + + SAFE_FREE(context->internal); SAFE_FREE(context); return 0; } @@ -411,6 +427,9 @@ smbc_init_context(SMBCCTX *context) char *user = NULL; char *home = NULL; + /* track talloc null_context memory */ + talloc_enable_null_tracking(); + if (!context) { errno = EBADF; return NULL; -- cgit From a49f6f17c622fbdc3f358a923b6a682ff7504fda Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 16 Jul 2008 09:45:02 -0400 Subject: Fix typos. libsmbclient doesn't have bool defined; rather it uses smbc_bool Derrell (This used to be commit e1ade80f468e8ed827f9d4fd035d79546fa0ee0a) --- source3/libsmb/libsmb_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index 51948d1648..b9b74fe7d2 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -617,7 +617,7 @@ void smbc_set_credentials(char *workgroup, char *user, char *password, - bool use_kerberos, + smbc_bool use_kerberos, char *signing_state) { -- cgit From 43892abff68054928312fd54e50d5bdebe604b63 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 16 Jul 2008 12:05:52 +0200 Subject: The buf in the smbclient write function should be const. As we try to provide POSIX function, we should use const like all other POSIX function. Signed-off-by: Andreas Schneider Signed-off-by: Derrell Lipman (This used to be commit 36e5df59544de9df140ca40ad0efd77afd8e1468) --- source3/libsmb/libsmb_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 423450b23e..7b287096c2 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -329,7 +329,7 @@ SMBC_read_ctx(SMBCCTX *context, ssize_t SMBC_write_ctx(SMBCCTX *context, SMBCFILE *file, - void *buf, + const void *buf, size_t count) { int ret; -- cgit From cd90c85bab1fbe8e731a5a694aba708e4396c2f2 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Wed, 16 Jul 2008 10:45:09 -0400 Subject: The compatibility function also should have a const buffer pointer (This used to be commit b731447ec539d454002300fd755dddcad2351d6c) --- source3/libsmb/libsmb_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_compat.c b/source3/libsmb/libsmb_compat.c index 9ef5e51fa9..ad8fd922db 100644 --- a/source3/libsmb/libsmb_compat.c +++ b/source3/libsmb/libsmb_compat.c @@ -207,7 +207,7 @@ smbc_read(int fd, ssize_t smbc_write(int fd, - void *buf, + const void *buf, size_t bufsize) { SMBCFILE * file = find_fd(fd); -- cgit From c400d0a0afbed31a1c372f288910a80089b5dd38 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 17 Jul 2008 12:29:02 +0200 Subject: Use the macro to call samba_version_string(). Signed-off-by: Andreas Schneider Signed-off-by: Stefan Metzmacher (This used to be commit d2682295f55a18d526434062834c033aa18e794b) --- source3/libsmb/libsmb_context.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index be26a92ca9..a9f0dd16b3 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -625,7 +625,7 @@ smbc_init_context(SMBCCTX *context) const char * smbc_version(void) { - return samba_version_string(); + return SAMBA_VERSION_STRING; } -- cgit From 1335da2a7cc639310e5d389e8e8dbe67c4e7ca25 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open_noauth Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit 9abc9dc4dc13bd3e42f98eff64eacf24b51f5779) --- source3/libsmb/libsmb_dir.c | 5 +++-- source3/libsmb/libsmb_server.c | 7 +++---- source3/libsmb/passchange.c | 10 ++++++---- source3/libsmb/trusts_util.c | 5 +++-- 4 files changed, 15 insertions(+), 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index aea4f103b6..aa313f2c05 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -273,8 +273,9 @@ net_share_enum_rpc(struct cli_state *cli, uint32_t total_entries = 0; /* Open the server service pipe */ - pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SRVSVC, &nt_status); - if (!pipe_hnd) { + nt_status = cli_rpc_pipe_open_noauth(cli, &ndr_table_srvsvc.syntax_id, + &pipe_hnd); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("net_share_enum_rpc pipe open fail!\n")); return -1; } diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 7af5ca3a24..0a3287bc82 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -646,10 +646,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, ZERO_STRUCTP(ipc_srv); ipc_srv->cli = ipc_cli; - pipe_hnd = cli_rpc_pipe_open_noauth(ipc_srv->cli, - PI_LSARPC, - &nt_status); - if (!pipe_hnd) { + nt_status = cli_rpc_pipe_open_noauth( + ipc_srv->cli, &ndr_table_lsarpc.syntax_id, &pipe_hnd); + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(1, ("cli_nt_session_open fail!\n")); errno = ENOTSUP; cli_shutdown(ipc_srv->cli); diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 3b82e5767f..86c7b52160 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -152,10 +152,11 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam * will just fail. So we do it anonymously, there's no other * way. */ - pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); + result = cli_rpc_pipe_open_noauth( + cli, &ndr_table_samr.syntax_id, &pipe_hnd); } - if (!pipe_hnd) { + if (!NT_STATUS_IS_OK(result)) { if (lp_client_lanman_auth()) { /* Use the old RAP method. */ if (!cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { @@ -204,9 +205,10 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam result = NT_STATUS_UNSUCCESSFUL; /* OK, this is ugly, but... try an anonymous pipe. */ - pipe_hnd = cli_rpc_pipe_open_noauth(cli, PI_SAMR, &result); + result = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id, + &pipe_hnd); - if ( pipe_hnd && + if ( NT_STATUS_IS_OK(result) && (NT_STATUS_IS_OK(result = rpccli_samr_chgpasswd_user2( pipe_hnd, talloc_tos(), user_name, new_passwd, old_passwd)))) { diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index 6b3bbaf1d8..f4fdf9eb6f 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -201,8 +201,9 @@ bool enumerate_domain_trusts( TALLOC_CTX *mem_ctx, const char *domain, /* open the LSARPC_PIPE */ - lsa_pipe = cli_rpc_pipe_open_noauth( cli, PI_LSARPC, &result ); - if ( !lsa_pipe) { + result = cli_rpc_pipe_open_noauth(cli, &ndr_table_lsarpc.syntax_id, + &lsa_pipe); + if (!NT_STATUS_IS_OK(result)) { goto done; } -- cgit From e0be03d8d5006f92ed479b84cd30ebfe510fa68a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 20 Jul 2008 11:04:31 +0200 Subject: Refactoring: Change calling conventions for cli_rpc_pipe_open_ntlmssp Pass in ndr_syntax_id instead of pipe_idx, return NTSTATUS (This used to be commit a13f0599551609394904b99e4014d580ec65c506) --- source3/libsmb/passchange.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index 86c7b52160..c8a4406949 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -136,13 +136,13 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam /* Try not to give the password away too easily */ if (!pass_must_change) { - pipe_hnd = cli_rpc_pipe_open_ntlmssp(cli, - PI_SAMR, - PIPE_AUTH_LEVEL_PRIVACY, - "", /* what domain... ? */ - user_name, - old_passwd, - &result); + result = cli_rpc_pipe_open_ntlmssp(cli, + &ndr_table_samr.syntax_id, + PIPE_AUTH_LEVEL_PRIVACY, + "", /* what domain... ? */ + user_name, + old_passwd, + &pipe_hnd); } else { /* * If the user password must be changed the ntlmssp bind will -- cgit From 45934af4985028d53b5f1a48709daf000404f8cc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 21 Jul 2008 12:01:12 +0200 Subject: Remove one reference to PI_LSARPC (This used to be commit 40247e8d3d53502fa8d7cc6b3eb9ed43f51142f3) --- source3/libsmb/libsmb_xattr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index 8763205d1f..2d8389c770 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -39,7 +39,8 @@ find_lsa_pipe_hnd(struct cli_state *ipc_cli) pipe_hnd; pipe_hnd = pipe_hnd->next) { - if (rpccli_is_pipe_idx(pipe_hnd, PI_LSARPC)) { + if (ndr_syntax_id_equal(&pipe_hnd->abstract_syntax, + &ndr_table_lsarpc.syntax_id)) { return pipe_hnd; } } -- cgit From bf622cb8766fa3d66d597d3cf0971b081a8089dc Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Aug 2008 15:29:06 +0200 Subject: Fix a typo (This used to be commit 37bd2815c70176046bbe0232222b9f59dfa159c4) --- source3/libsmb/clifile.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 12c427a6fa..12b10ba0a0 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -715,10 +715,10 @@ int cli_nt_delete_on_close(struct cli_state *cli, int fnum, bool flag) ****************************************************************************/ int cli_nt_create_full(struct cli_state *cli, const char *fname, - uint32 CreatFlags, uint32 DesiredAccess, - uint32 FileAttributes, uint32 ShareAccess, - uint32 CreateDisposition, uint32 CreateOptions, - uint8 SecuityFlags) + uint32 CreatFlags, uint32 DesiredAccess, + uint32 FileAttributes, uint32 ShareAccess, + uint32 CreateDisposition, uint32 CreateOptions, + uint8 SecurityFlags) { char *p; int len; @@ -744,7 +744,7 @@ int cli_nt_create_full(struct cli_state *cli, const char *fname, SIVAL(cli->outbuf,smb_ntcreate_CreateDisposition, CreateDisposition); SIVAL(cli->outbuf,smb_ntcreate_CreateOptions, CreateOptions); SIVAL(cli->outbuf,smb_ntcreate_ImpersonationLevel, 0x02); - SCVAL(cli->outbuf,smb_ntcreate_SecurityFlags, SecuityFlags); + SCVAL(cli->outbuf,smb_ntcreate_SecurityFlags, SecurityFlags); p = smb_buf(cli->outbuf); /* this alignment and termination is critical for netapp filers. Don't change */ -- cgit From 711efc06c82349faa979c3653226f4e944f59d18 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Aug 2008 16:05:49 +0200 Subject: cli_request_new() already gave use the req, remove a pointless function call (This used to be commit 08e97bd369ebe3ab1fd92433b168585faea92c68) --- source3/libsmb/clireadwrite.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 057e647983..a57f1e0785 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -62,8 +62,6 @@ struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, return NULL; } - req = cli_request_get(result); - req->data.read.ofs = offset; req->data.read.size = size; req->data.read.received = 0; -- cgit From 70c2a5b02eba592b30c9239383445c2c16295ba0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 4 Aug 2008 13:52:18 +0200 Subject: clikrb5: don't use krb5_keyblock_init() when no salt is specified If the caller wants to create a key with no salt we should not use krb5_keyblock_init() (only used when using heimdal) because it does sanity checks on the key length. metze (This used to be commit c83de77b750837a110611d7023c4cf71d2d0bab1) --- source3/libsmb/clikrb5.c | 65 ++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 35 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index cbe8f24909..d5d7c1f3b9 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -31,10 +31,12 @@ #define KRB5_KEY_TYPE(k) ((k)->keytype) #define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) #define KRB5_KEY_DATA(k) ((k)->keyvalue.data) +#define KRB5_KEY_DATA_CAST void #else /* MIT */ #define KRB5_KEY_TYPE(k) ((k)->enctype) #define KRB5_KEY_LENGTH(k) ((k)->length) #define KRB5_KEY_DATA(k) ((k)->contents) +#define KRB5_KEY_DATA_CAST krb5_octet #endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ /************************************************************** @@ -214,31 +216,21 @@ static int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, - krb5_enctype enctype, - bool no_salt) + krb5_enctype enctype) { int ret = 0; krb5_data salt; krb5_encrypt_block eblock; - if (no_salt) { - key->contents = (krb5_octet *)SMB_MALLOC(password->length); - if (!key->contents) { - return ENOMEM; - } - memcpy(key->contents, password->data, password->length); - key->length = password->length; - key->enctype = enctype; - } else { - ret = krb5_principal2salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); - return ret; - } - krb5_use_enctype(context, &eblock, enctype); - ret = krb5_string_to_key(context, &eblock, key, password, &salt); - SAFE_FREE(salt.data); + ret = krb5_principal2salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret))); + return ret; } + krb5_use_enctype(context, &eblock, enctype); + ret = krb5_string_to_key(context, &eblock, key, password, &salt); + SAFE_FREE(salt.data); + return ret; } #elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT) @@ -246,27 +238,20 @@ static int create_kerberos_key_from_string_direct(krb5_context context, krb5_principal host_princ, krb5_data *password, krb5_keyblock *key, - krb5_enctype enctype, - bool no_salt) + krb5_enctype enctype) { int ret; krb5_salt salt; - if (no_salt) { - return krb5_keyblock_init(context, enctype, - password->data, password->length, - key); - } else { - ret = krb5_get_pw_salt(context, host_princ, &salt); - if (ret) { - DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); - return ret; - } - - ret = krb5_string_to_key_salt(context, enctype, (const char *)password->data, salt, key); - krb5_free_salt(context, salt); + ret = krb5_get_pw_salt(context, host_princ, &salt); + if (ret) { + DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret))); + return ret; } + ret = krb5_string_to_key_salt(context, enctype, (const char *)password->data, salt, key); + krb5_free_salt(context, salt); + return ret; } #else @@ -287,8 +272,18 @@ static int create_kerberos_key_from_string_direct(krb5_context context, * principal/enctype in a non-obvious way. If it is, try to match * its behavior. */ + if (no_salt) { + KRB5_KEY_DATA(key) = (KRB5_KEY_DATA_CAST *)SMB_MALLOC(password->length); + if (!KRB5_KEY_DATA(key)) { + return ENOMEM; + } + memcpy(KRB5_KEY_DATA(key), password->data, password->length); + KRB5_KEY_LENGTH(key) = password->length; + KRB5_KEY_TYPE(key) = enctype; + return 0; + } salt_princ = kerberos_fetch_salt_princ_for_host_princ(context, host_princ, enctype); - ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype, no_salt); + ret = create_kerberos_key_from_string_direct(context, salt_princ ? salt_princ : host_princ, password, key, enctype); if (salt_princ) { krb5_free_principal(context, salt_princ); } -- cgit From 617bf10c66f45b6ed83d7f5441586606261e0560 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Aug 2008 17:55:57 -0700 Subject: Fix bug #5675 with a varient of Tim Waugh's patch, as proposed by James Peach. Jeremy. (This used to be commit 5c27ad75836136c39774c9456d63f46fa62e281f) --- source3/libsmb/cliconnect.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 4285753e20..8ef14d7973 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -797,7 +797,6 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, char *principal = NULL; char *OIDs[ASN1_MAX_OIDS]; int i; - bool got_kerberos_mechanism = False; DATA_BLOB blob; const char *p = NULL; char *account = NULL; @@ -832,7 +831,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, DEBUG(3,("got OID=%s\n", OIDs[i])); if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 || strcmp(OIDs[i], OID_KERBEROS5) == 0) { - got_kerberos_mechanism = True; + cli->got_kerberos_mechanism = True; } free(OIDs[i]); } @@ -845,7 +844,7 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user, /* If password is set we reauthenticate to kerberos server * and do not store results */ - if (got_kerberos_mechanism && cli->use_kerberos) { + if (cli->got_kerberos_mechanism && cli->use_kerberos) { ADS_STATUS rc; if (pass && *pass) { -- cgit From e8c7ff3e880c7c7e696c5ba7baa8536b4ea7cb89 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Aug 2008 14:32:15 -0700 Subject: Add Derrick Schommer's kerberos delegation patch. Some work by me and advice by Love. Jeremy. (This used to be commit ecc3838e4cb5d0c0769ec6d9a34a877ca584ffcc) --- source3/libsmb/clifsinfo.c | 2 +- source3/libsmb/clikrb5.c | 186 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 185 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifsinfo.c b/source3/libsmb/clifsinfo.c index 0005c3908a..5e73b61cd2 100644 --- a/source3/libsmb/clifsinfo.c +++ b/source3/libsmb/clifsinfo.c @@ -528,7 +528,7 @@ static NTSTATUS make_cli_gss_blob(struct smb_trans_enc_state *es, &es->s.gss_state->gss_ctx, srv_name, GSS_C_NO_OID, /* default OID. */ - GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG, + GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG, GSS_C_INDEFINITE, /* requested ticket lifetime. */ NULL, /* no channel bindings */ p_tok_in, diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index d5d7c1f3b9..9d39483eae 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -39,6 +39,18 @@ #define KRB5_KEY_DATA_CAST krb5_octet #endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ +#define GSSAPI_CHECKSUM 0x8003 /* Checksum type value for Kerberos */ +#define GSSAPI_BNDLENGTH 16 /* Bind Length (rfc-1964 pg.3) */ +#define GSSAPI_CHECKSUM_SIZE (12+GSSAPI_BNDLENGTH) + +#if defined(TKT_FLG_OK_AS_DELEGATE) && defined(HAVE_KRB5_FWD_TGT_CREDS) +static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context, + krb5_auth_context *auth_context, + krb5_creds *credsp, + krb5_ccache ccache, + krb5_data *authenticator); +#endif + /************************************************************** Wrappers around kerberos string functions that convert from utf8 -> unix charset and vica versa. @@ -654,6 +666,8 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, bool creds_ready = False; int i = 0, maxtries = 3; + ZERO_STRUCT(in_data); + retval = smb_krb5_parse_name(context, principal, &server); if (retval) { DEBUG(1,("ads_krb5_mk_req: Failed to parse principal %s\n", principal)); @@ -709,14 +723,69 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, *expire_time = (time_t)credsp->times.endtime; } - in_data.length = 0; +#if defined(TKT_FLG_OK_AS_DELEGATE) && defined(HAVE_KRB5_FWD_TGT_CREDS) + if( credsp->ticket_flags & TKT_FLG_OK_AS_DELEGATE ) { + /* Fetch a forwarded TGT from the KDC so that we can hand off a 2nd ticket + as part of the kerberos exchange. */ + + DEBUG( 3, ("ads_krb5_mk_req: server marked as OK to delegate to, building forwardable TGT\n") ); + + if( *auth_context == NULL ) { + /* Allocate if it has not yet been allocated. */ + retval = krb5_auth_con_init( context, auth_context ); + if (retval) { + DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_init failed (%s)\n", + error_message(retval))); + goto cleanup_creds; + } + } + + retval = krb5_auth_con_setuseruserkey( context, *auth_context, &credsp->keyblock ); + if (retval) { + DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_setuseruserkey failed (%s)\n", + error_message(retval))); + goto cleanup_creds; + } + + /* Must use a subkey for forwarded tickets. */ + retval = krb5_auth_con_setflags( context, *auth_context, KRB5_AUTH_CONTEXT_USE_SUBKEY); + if (retval) { + DEBUG(1,("ads_krb5_mk_req: krb5_auth_con_setflags failed (%s)\n", + error_message(retval))); + goto cleanup_creds; + } + + retval = ads_krb5_get_fwd_ticket( context, + auth_context, + credsp, + ccache, + &in_data ); + if (retval) { + DEBUG( 1, ("ads_krb5_get_fwd_ticket failed (%s)\n", error_message( retval ) ) ); + goto cleanup_creds; + } + + if (retval) { + DEBUG( 1, ("krb5_auth_con_set_req_cksumtype failed (%s)\n", + error_message( retval ) ) ); + goto cleanup_creds; + } + + } +#endif + retval = krb5_mk_req_extended(context, auth_context, ap_req_options, &in_data, credsp, outbuf); if (retval) { DEBUG(1,("ads_krb5_mk_req: krb5_mk_req_extended failed (%s)\n", error_message(retval))); } - + + if (in_data.data) { + free( in_data.data ); + in_data.length = 0; + } + krb5_free_creds(context, credsp); cleanup_creds: @@ -1744,6 +1813,119 @@ krb5_error_code smb_krb5_keytab_name(TALLOC_CTX *mem_ctx, return ret; } +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) +/************************************************************** +Routine: ads_krb5_get_fwd_ticket + Description: + When a service ticket is flagged as trusted + for delegation we should provide a forwardable + ticket so that the remote host can act on our + behalf. This is done by taking the 2nd forwardable + TGT and storing it in the GSS-API authenticator + "checksum". This routine will populate + the krb5_data authenticator with this TGT. + Parameters: + krb5_context context: The kerberos context for this authentication. + krb5_auth_context: The authentication context. + krb5_creds *credsp: The ticket credentials (AS-REP). + krb5_ccache ccache: The credentials cache. + krb5_data &authenticator: The checksum field that will store the TGT, and + authenticator.data must be freed by the caller. + + Returns: + krb5_error_code: 0 if no errors, otherwise set. +**************************************************************/ + +static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context, + krb5_auth_context *auth_context, + krb5_creds *credsp, + krb5_ccache ccache, + krb5_data *authenticator) +{ + krb5_data fwdData; + krb5_error_code retval = 0; + char *pChksum = NULL; + char *p = NULL; + + ZERO_STRUCT(fwdData); + ZERO_STRUCTP(authenticator); + + retval = krb5_fwd_tgt_creds(context,/* Krb5 context [in] */ + *auth_context, /* Authentication context [in] */ + CONST_DISCARD(char *, KRB5_TGS_NAME), /* Ticket service name ("krbtgt") [in] */ + credsp->client, /* Client principal for the tgt [in] */ + credsp->server, /* Server principal for the tgt [in] */ + ccache, /* Credential cache to use for storage [in] */ + 1, /* Turn on for "Forwardable ticket" [in] */ + &fwdData ); /* Resulting response [out] */ + + + if (retval) { + DEBUG(1,("ads_krb5_get_fwd_ticket: krb5_fwd_tgt_creds failed (%s)\n", + error_message(retval))); + goto out; + } + + if ((unsigned int)GSSAPI_CHECKSUM_SIZE + (unsigned int)fwdData.length < + (unsigned int)GSSAPI_CHECKSUM_SIZE) { + retval = EINVAL; + goto out; + } + + /* We're going to allocate a gssChecksum structure with a little + extra data the length of the kerberos credentials length + (APPLICATION 22) so that we can pack it on the end of the structure. + */ + + pChksum = SMB_MALLOC(GSSAPI_CHECKSUM_SIZE + fwdData.length ); + if (!pChksum) { + retval = ENOMEM; + goto out; + } + + p = pChksum; + + SIVAL(p, 0, GSSAPI_BNDLENGTH); + p += 4; + + /* Zero out the bindings fields */ + memset(p, '\0', GSSAPI_BNDLENGTH ); + p += GSSAPI_BNDLENGTH; + + SIVAL(p, 0, GSS_C_DELEG_FLAG ); + p += 4; + SSVAL(p, 0, 1 ); + p += 2; + SSVAL(p, 0, fwdData.length ); + p += 2; + + /* Migrate the kerberos KRB_CRED data to the checksum delegation */ + memcpy(p, fwdData.data, fwdData.length ); + p += fwdData.length; + + /* We need to do this in order to allow our GSS-API */ + retval = krb5_auth_con_set_req_cksumtype( context, *auth_context, GSSAPI_CHECKSUM ); + if (retval) { + goto out; + } + + /* We now have a service ticket, now turn it into an AP-REQ. */ + authenticator->length = ntohs(fwdData.length + GSSAPI_CHECKSUM_SIZE); + + /* Caller should call free() when they're done with this. */ + authenticator->data = (char *)pChksum; + + out: + + /* Remove that input data, we never needed it anyway. */ + if (fwdData.length > 0) { + krb5_free_data_contents( context, &fwdData ); + } + + return retval; +} +#endif + #else /* HAVE_KRB5 */ /* this saves a few linking headaches */ int cli_krb5_get_ticket(const char *principal, time_t time_offset, -- cgit From 6d99eedafc3f35a4cdd544c6eea9a7f527193b50 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Aug 2008 15:15:36 -0700 Subject: Try and fix the build for systems that don't have krb5_auth_con_set_req_cksumtype(). Jeremy. (This used to be commit 8598e7b06ec57ca6fcde863270e6bb0e2de9993e) --- source3/libsmb/clikrb5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 9d39483eae..9cd5cd3310 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -43,7 +43,7 @@ #define GSSAPI_BNDLENGTH 16 /* Bind Length (rfc-1964 pg.3) */ #define GSSAPI_CHECKSUM_SIZE (12+GSSAPI_BNDLENGTH) -#if defined(TKT_FLG_OK_AS_DELEGATE) && defined(HAVE_KRB5_FWD_TGT_CREDS) +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context, krb5_auth_context *auth_context, krb5_creds *credsp, @@ -723,7 +723,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, *expire_time = (time_t)credsp->times.endtime; } -#if defined(TKT_FLG_OK_AS_DELEGATE) && defined(HAVE_KRB5_FWD_TGT_CREDS) +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) if( credsp->ticket_flags & TKT_FLG_OK_AS_DELEGATE ) { /* Fetch a forwarded TGT from the KDC so that we can hand off a 2nd ticket as part of the kerberos exchange. */ @@ -1813,7 +1813,7 @@ krb5_error_code smb_krb5_keytab_name(TALLOC_CTX *mem_ctx, return ret; } -#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) /************************************************************** Routine: ads_krb5_get_fwd_ticket Description: -- cgit From 3acde0d74711e4e7169dd4b0a0a2ea8fa476cef2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Aug 2008 16:08:11 -0700 Subject: One more build fix. Ensure we have KRB5_AUTH_CONTEXT_USE_SUBKEY defined before we compile the new code. Jeremy. (This used to be commit 7686752c5b015b15a6729631ba4aeedd25ebc659) --- source3/libsmb/clikrb5.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 9cd5cd3310..2052d5a1bc 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -43,7 +43,7 @@ #define GSSAPI_BNDLENGTH 16 /* Bind Length (rfc-1964 pg.3) */ #define GSSAPI_CHECKSUM_SIZE (12+GSSAPI_BNDLENGTH) -#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context, krb5_auth_context *auth_context, krb5_creds *credsp, @@ -723,7 +723,7 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, *expire_time = (time_t)credsp->times.endtime; } -#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) if( credsp->ticket_flags & TKT_FLG_OK_AS_DELEGATE ) { /* Fetch a forwarded TGT from the KDC so that we can hand off a 2nd ticket as part of the kerberos exchange. */ @@ -1813,7 +1813,7 @@ krb5_error_code smb_krb5_keytab_name(TALLOC_CTX *mem_ctx, return ret; } -#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) +#if defined(TKT_FLG_OK_AS_DELEGATE ) && defined(HAVE_KRB5_FWD_TGT_CREDS) && defined(HAVE_KRB5_AUTH_CON_SET_REQ_CKSUMTYPE) && defined(KRB5_AUTH_CONTEXT_USE_SUBKEY) /************************************************************** Routine: ads_krb5_get_fwd_ticket Description: -- cgit From c7257754cdda2e7137969417eb56481192b0654a Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 11 Aug 2008 11:20:38 +0200 Subject: fix build warning. Guenther (This used to be commit 85021d6a459c957cc276a93c3515029244f52677) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 2052d5a1bc..5bb33b11d7 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1877,7 +1877,7 @@ static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context, (APPLICATION 22) so that we can pack it on the end of the structure. */ - pChksum = SMB_MALLOC(GSSAPI_CHECKSUM_SIZE + fwdData.length ); + pChksum = (char *)SMB_MALLOC(GSSAPI_CHECKSUM_SIZE + fwdData.length ); if (!pChksum) { retval = ENOMEM; goto out; -- cgit From 050db35262e8fb8d475e0b193c6a8c12f517307b Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 1 Aug 2008 17:22:00 +0200 Subject: doserr: add WERR_MEMBER_IN_ALIAS. Guenther (This used to be commit b62de0d1944de3dba55e182e0d8eb7c6ca5ec045) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index bbb12e0a29..50b5b2238c 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -99,6 +99,7 @@ werror_code_struct dos_errs[] = { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, { "WERR_SPECIAL_ACCOUNT", WERR_SPECIAL_ACCOUNT }, { "WERR_ALIAS_EXISTS", WERR_ALIAS_EXISTS }, + { "WERR_MEMBER_IN_ALIAS", WERR_MEMBER_IN_ALIAS }, { "WERR_TIME_SKEW", WERR_TIME_SKEW }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, -- cgit From 03991ab0734ecbb87a75238d1356fbe0e5b1d38d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Aug 2008 13:35:15 -0700 Subject: Fix bug 5686 - libsmbclient segfaults with more than one SMBCCTX. Here is a patch to allow many subsystems to be re-initialized. The only functional change I made was to remove the null context tracking, as the memory allocated here is designed to be left for the complete lifetime of the program. Freeing this early (when all smb contexts are destroyed) could crash other users of talloc. Jeremy. (This used to be commit 8c630efd25cf17aff59448ca05c1b44a41964b16) --- source3/libsmb/libsmb_context.c | 38 ++++++++++++++++---------------------- 1 file changed, 16 insertions(+), 22 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_context.c b/source3/libsmb/libsmb_context.c index a9f0dd16b3..19843383de 100644 --- a/source3/libsmb/libsmb_context.c +++ b/source3/libsmb/libsmb_context.c @@ -30,9 +30,8 @@ /* * Is the logging working / configfile read ? */ -static int SMBC_initialized = 0; - - +static bool SMBC_initialized; +static unsigned int initialized_ctx_count; /* * Get a new empty handle to fill in with your own info @@ -201,22 +200,19 @@ smbc_free_context(SMBCCTX *context, DEBUG(3, ("Context %p successfully freed\n", context)); - gfree_names(); - gfree_loadparm(); - gfree_case_tables(); - gfree_charcnv(); - gfree_interfaces(); - - gencache_shutdown(); - secrets_shutdown(); - - /* release the talloc null_context memory last */ - talloc_disable_null_tracking(); + SAFE_FREE(context->internal); + SAFE_FREE(context); - gfree_debugsyms(); + if (initialized_ctx_count) { + initialized_ctx_count--; + } - SAFE_FREE(context->internal); - SAFE_FREE(context); + if (initialized_ctx_count == 0 && SMBC_initialized) { + gencache_shutdown(); + secrets_shutdown(); + gfree_all(); + SMBC_initialized = false; + } return 0; } @@ -427,9 +423,6 @@ smbc_init_context(SMBCCTX *context) char *user = NULL; char *home = NULL; - /* track talloc null_context memory */ - talloc_enable_null_tracking(); - if (!context) { errno = EBADF; return NULL; @@ -527,7 +520,7 @@ smbc_init_context(SMBCCTX *context) BlockSignals(True, SIGPIPE); /* Done with one-time initialisation */ - SMBC_initialized = 1; + SMBC_initialized = true; TALLOC_FREE(frame); } @@ -616,7 +609,8 @@ smbc_init_context(SMBCCTX *context) */ context->internal->initialized = True; - + initialized_ctx_count++; + return context; } -- cgit From 870c54ebb4097d14e3e89a3b81df4c3fc9b57ad3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Aug 2008 17:40:30 +0200 Subject: If it is a forced DOS error, nt_errstr should say so (This used to be commit ef5489ac805237274d6088aaa7ae870cc0deb52f) --- source3/libsmb/nterr.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index fc6340342f..a52a1bc6e1 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -658,6 +658,11 @@ const char *nt_errstr(NTSTATUS nt_code) } #endif + if (NT_STATUS_IS_DOS(nt_code)) { + return smb_dos_err_name(NT_STATUS_DOS_CLASS(nt_code), + NT_STATUS_DOS_CODE(nt_code)); + } + while (nt_errs[idx].nt_errstr != NULL) { if (NT_STATUS_EQUAL(nt_errs[idx].nt_errcode, nt_code)) { return nt_errs[idx].nt_errstr; -- cgit From 8d03db99b8c0623929f9351940a7e80adbf45e73 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Aug 2008 18:19:06 +0200 Subject: Revert "If it is a forced DOS error, nt_errstr should say so" This reverts commit ef5489ac805237274d6088aaa7ae870cc0deb52f. (This used to be commit e987e9956f02557c7ec87a369b92f87083fda620) --- source3/libsmb/nterr.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index a52a1bc6e1..fc6340342f 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -658,11 +658,6 @@ const char *nt_errstr(NTSTATUS nt_code) } #endif - if (NT_STATUS_IS_DOS(nt_code)) { - return smb_dos_err_name(NT_STATUS_DOS_CLASS(nt_code), - NT_STATUS_DOS_CODE(nt_code)); - } - while (nt_errs[idx].nt_errstr != NULL) { if (NT_STATUS_EQUAL(nt_errs[idx].nt_errcode, nt_code)) { return nt_errs[idx].nt_errstr; -- cgit From b48ba00dc67cc7235a135615b0ee25245ac8474b Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 13 Aug 2008 18:03:51 -0400 Subject: Prevent NT_STATUS 0xF1000000 errors from appearing when dos errors are used and there is no error. It should be mapped directly to NT_STATUS_OK. smbclient to older servers didn't work. (This used to be commit 78f009b7ef1f1d63b21df9ba6da7fcca01c12109) --- source3/libsmb/async_smb.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 04c22a9d17..58bba2bfc7 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -31,6 +31,12 @@ NTSTATUS cli_pull_error(char *buf) return NT_STATUS(IVAL(buf, smb_rcls)); } + /* if the client uses dos errors, but there is no error, + we should return no error here, otherwise it looks + like an unknown bad NT_STATUS. jmcd */ + if (CVAL(buf, smb_rcls) == 0) + return NT_STATUS_OK; + return NT_STATUS_DOS(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); } -- cgit From 2597c97d3a274bdb96e9958a79aa70d84381a12a Mon Sep 17 00:00:00 2001 From: Igor Mammedov Date: Mon, 18 Aug 2008 09:55:11 -0700 Subject: Fix length error in wrapping spnego blob (This used to be commit 16ee95494ba495c5f5ff8779206f380db1067b2d) --- source3/libsmb/clikrb5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 5bb33b11d7..fa21ad3467 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1910,7 +1910,7 @@ static krb5_error_code ads_krb5_get_fwd_ticket( krb5_context context, } /* We now have a service ticket, now turn it into an AP-REQ. */ - authenticator->length = ntohs(fwdData.length + GSSAPI_CHECKSUM_SIZE); + authenticator->length = fwdData.length + GSSAPI_CHECKSUM_SIZE; /* Caller should call free() when they're done with this. */ authenticator->data = (char *)pChksum; -- cgit From b67adb49ecbb7eff4446321962f3a00984e88d01 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 21 Aug 2008 15:05:35 +0200 Subject: Fix Bug #5710 and make machine account password changing work again. When we negotiated NETLOGON_NEG_PASSWORD_SET2 we need to use NetrServerPasswordSet2 to change the machine password. Tested with NT4, W2k, W2k3 and W2k8. Guenther (This used to be commit 5820360451e4db0fad0472f814cae667b2ea51fd) --- source3/libsmb/trusts_util.c | 75 ++++++++++++++++++++++++++++++-------------- 1 file changed, 52 insertions(+), 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/trusts_util.c b/source3/libsmb/trusts_util.c index f4fdf9eb6f..08a49930b4 100644 --- a/source3/libsmb/trusts_util.c +++ b/source3/libsmb/trusts_util.c @@ -31,34 +31,60 @@ static NTSTATUS just_change_the_password(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const unsigned char orig_trust_passwd_hash[16], + const char *new_trust_pwd_cleartext, const unsigned char new_trust_passwd_hash[16], uint32 sec_channel_type) { NTSTATUS result; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; - /* Check if the netlogon pipe is open using schannel. If so we - already have valid creds. If not we must set them up. */ - - if (cli->auth->auth_type != PIPE_AUTH_TYPE_SCHANNEL) { - uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; - - result = rpccli_netlogon_setup_creds(cli, - cli->desthost, /* server name */ - lp_workgroup(), /* domain */ - global_myname(), /* client name */ - global_myname(), /* machine account name */ - orig_trust_passwd_hash, - sec_channel_type, - &neg_flags); - - if (!NT_STATUS_IS_OK(result)) { - DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", - nt_errstr(result))); - return result; - } + result = rpccli_netlogon_setup_creds(cli, + cli->desthost, /* server name */ + lp_workgroup(), /* domain */ + global_myname(), /* client name */ + global_myname(), /* machine account name */ + orig_trust_passwd_hash, + sec_channel_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(result)) { + DEBUG(3,("just_change_the_password: unable to setup creds (%s)!\n", + nt_errstr(result))); + return result; } - { + if (neg_flags & NETLOGON_NEG_PASSWORD_SET2) { + + struct netr_Authenticator clnt_creds, srv_cred; + struct netr_CryptPassword new_password; + struct samr_CryptPassword password_buf; + + netlogon_creds_client_step(cli->dc, &clnt_creds); + + encode_pw_buffer(password_buf.data, new_trust_pwd_cleartext, STR_UNICODE); + + SamOEMhash(password_buf.data, cli->dc->sess_key, 516); + memcpy(new_password.data, password_buf.data, 512); + new_password.length = IVAL(password_buf.data, 512); + + result = rpccli_netr_ServerPasswordSet2(cli, mem_ctx, + cli->dc->remote_machine, + cli->dc->mach_acct, + sec_channel_type, + global_myname(), + &clnt_creds, + &srv_cred, + &new_password); + + /* Always check returned credentials. */ + if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { + DEBUG(0,("rpccli_netr_ServerPasswordSet2: " + "credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + + } else { + struct netr_Authenticator clnt_creds, srv_cred; struct samr_Password new_password; @@ -118,8 +144,11 @@ NTSTATUS trust_pw_change_and_store_it(struct rpc_pipe_client *cli, TALLOC_CTX *m E_md4hash(new_trust_passwd, new_trust_passwd_hash); - nt_status = just_change_the_password(cli, mem_ctx, orig_trust_passwd_hash, - new_trust_passwd_hash, sec_channel_type); + nt_status = just_change_the_password(cli, mem_ctx, + orig_trust_passwd_hash, + new_trust_passwd, + new_trust_passwd_hash, + sec_channel_type); if (NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("%s : trust_pw_change_and_store_it: Changed password.\n", -- cgit From 56cd17dfe145c2df2b39ad295136c4922bee8e43 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Aug 2008 19:57:19 +0200 Subject: Protect against short read&x replies (This used to be commit 4ed73cbbbeff4b554cc8d28252b756241396b3a1) --- source3/libsmb/clireadwrite.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index a57f1e0785..4d3027694f 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -138,6 +138,10 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, return status; } + if (wct < 12) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + /* size is the number of bytes the server returned. * Might be zero. */ size = SVAL(cli_req->inbuf, smb_vwv5); -- cgit From 1924e7931cf83124529edb79620a8494ddcad0e9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 23 Aug 2008 15:40:43 +0200 Subject: Revert "Protect against short read&x replies" This reverts commit 4ed73cbbbeff4b554cc8d28252b756241396b3a1. ... how did this end up here?? Volker (This used to be commit 7dd9fd0956bd1c46105d1072c4774972933ab9ec) --- source3/libsmb/clireadwrite.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 4d3027694f..a57f1e0785 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -138,10 +138,6 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, return status; } - if (wct < 12) { - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - /* size is the number of bytes the server returned. * Might be zero. */ size = SVAL(cli_req->inbuf, smb_vwv5); -- cgit From 1d26beb7084efdfcadb4a1cebe5a0d7cdcd2b454 Mon Sep 17 00:00:00 2001 From: Ephi Dror Date: Wed, 27 Aug 2008 17:28:34 -0700 Subject: Correct the netsamlogon_clear_cached_user function. (This used to be commit bb13312d9d53b1e048b3a0bfeeca088f9db84cd3) --- source3/libsmb/samlogon_cache.c | 54 ++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/samlogon_cache.c b/source3/libsmb/samlogon_cache.c index 2d2588f70c..4abe5bb6de 100644 --- a/source3/libsmb/samlogon_cache.c +++ b/source3/libsmb/samlogon_cache.c @@ -59,48 +59,30 @@ bool netsamlogon_cache_shutdown(void) Clear cache getpwnam and getgroups entries from the winbindd cache ***********************************************************************/ -void netsamlogon_clear_cached_user(TDB_CONTEXT *tdb, struct netr_SamInfo3 *info3) +void netsamlogon_clear_cached_user(struct netr_SamInfo3 *info3) { - bool got_tdb = false; - DOM_SID sid; - fstring key_str, sid_string; - - /* We may need to call this function from smbd which will not have - winbindd_cache.tdb open. Open the tdb if a NULL is passed. */ - - if (!tdb) { - tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), - WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE, - TDB_DEFAULT, O_RDWR, 0600); - if (!tdb) { - DEBUG(5, ("netsamlogon_clear_cached_user: failed to open cache\n")); - return; - } - got_tdb = true; - } - - sid_copy(&sid, info3->base.domain_sid); - sid_append_rid(&sid, info3->base.rid); - - /* Clear U/SID cache entry */ - - fstr_sprintf(key_str, "U/%s", sid_to_fstring(sid_string, &sid)); - - DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str)); - - tdb_delete(tdb, string_tdb_data(key_str)); + DOM_SID user_sid; + fstring keystr, tmp; - /* Clear UG/SID cache entry */ + if (!info3) { + return; + } - fstr_sprintf(key_str, "UG/%s", sid_to_fstring(sid_string, &sid)); + if (!netsamlogon_cache_init()) { + DEBUG(0,("netsamlogon_clear_cached_user: cannot open " + "%s for write!\n", + NETSAMLOGON_TDB)); + return; + } + sid_copy(&user_sid, info3->base.domain_sid); + sid_append_rid(&user_sid, info3->base.rid); - DEBUG(10, ("netsamlogon_clear_cached_user: clearing %s\n", key_str)); + /* Prepare key as DOMAIN-SID/USER-RID string */ + slprintf(keystr, sizeof(keystr), "%s", sid_to_fstring(tmp, &user_sid)); - tdb_delete(tdb, string_tdb_data(key_str)); + DEBUG(10,("netsamlogon_clear_cached_user: SID [%s]\n", keystr)); - if (got_tdb) { - tdb_close(tdb); - } + tdb_delete_bystring(netsamlogon_tdb, keystr); } /*********************************************************************** -- cgit From 58aa97c0d9db06588d1aba4f06a3c98ed2098d8f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Aug 2008 23:14:51 +0200 Subject: Refactoring: Add the routine cli_request_send() cli_request_send() is supposed to bundle all generic SMB-header handling. This makes cli_request_new static to async_smb.c. (This used to be commit 7e73dd4e7622db64d30d48ba106892e0895fc188) --- source3/libsmb/async_smb.c | 62 ++++++++++++++++++++++++++++++++++--- source3/libsmb/clireadwrite.c | 71 +++++++++++++++---------------------------- 2 files changed, 82 insertions(+), 51 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 58bba2bfc7..454bd8169b 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -114,11 +114,11 @@ static int cli_request_destructor(struct cli_request *req) * Create a fresh async smb request */ -struct async_req *cli_request_new(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct cli_state *cli, - uint8_t num_words, size_t num_bytes, - struct cli_request **preq) +static struct async_req *cli_request_new(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint8_t num_words, size_t num_bytes, + struct cli_request **preq) { struct async_req *result; struct cli_request *cli_req; @@ -160,6 +160,58 @@ struct async_req *cli_request_new(TALLOC_CTX *mem_ctx, return result; } +/* + * Ship a new smb request to the server + */ +struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, + uint8_t smb_command, + uint8_t additional_flags, + uint8_t wct, const uint16_t *vwv, + uint16_t num_bytes, const uint8_t *bytes) +{ + struct async_req *result; + struct cli_request *req; + + result = cli_request_new(mem_ctx, cli->event_ctx, cli, wct, num_bytes, + &req); + if (result == NULL) { + DEBUG(0, ("cli_request_new failed\n")); + return NULL; + } + + cli_set_message(req->outbuf, wct, num_bytes, false); + SCVAL(req->outbuf, smb_com, smb_command); + SSVAL(req->outbuf, smb_tid, cli->cnum); + cli_setup_packet_buf(cli, req->outbuf); + + memcpy(req->outbuf + smb_vwv0, vwv, sizeof(uint16_t) * wct); + memcpy(smb_buf(req->outbuf), bytes, num_bytes); + SSVAL(req->outbuf, smb_mid, req->mid); + SCVAL(cli->outbuf, smb_flg, + CVAL(cli->outbuf,smb_flg) | additional_flags); + + cli_calculate_sign_mac(cli, req->outbuf); + + if (cli_encryption_on(cli)) { + NTSTATUS status; + char *enc_buf; + + status = cli_encrypt_message(cli, req->outbuf, &enc_buf); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Error in encrypting client message. " + "Error %s\n", nt_errstr(status))); + TALLOC_FREE(req); + return NULL; + } + req->outbuf = enc_buf; + req->enc_state = cli->trans_enc_state; + } + + event_fd_set_writeable(cli->fd_event); + + return result; +} + /* * Convenience function to get the SMB part out of an async_req */ diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index a57f1e0785..2b34fce5bd 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -47,7 +47,9 @@ struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, struct async_req *result; struct cli_request *req; bool bigoffset = False; - char *enc_buf; + + uint16_t vwv[12]; + uint8_t wct = 10; if (size > cli_read_max_bufsize(cli)) { DEBUG(0, ("cli_read_andx_send got size=%d, can only handle " @@ -56,60 +58,37 @@ struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, return NULL; } - result = cli_request_new(mem_ctx, cli->event_ctx, cli, 12, 0, &req); + SCVAL(vwv + 0, 0, 0xFF); + SCVAL(vwv + 0, 1, 0); + SSVAL(vwv + 1, 0, 0); + SSVAL(vwv + 2, 0, fnum); + SIVAL(vwv + 3, 0, offset); + SSVAL(vwv + 5, 0, size); + SSVAL(vwv + 6, 0, size); + SSVAL(vwv + 7, 0, (size >> 16)); + SSVAL(vwv + 8, 0, 0); + SSVAL(vwv + 9, 0, 0); + + if ((SMB_BIG_UINT)offset >> 32) { + bigoffset = True; + SIVAL(vwv + 10, 0, + (((SMB_BIG_UINT)offset)>>32) & 0xffffffff); + wct += 2; + } + + result = cli_request_send(mem_ctx, cli, SMBreadX, 0, wct, vwv, + 0, NULL); if (result == NULL) { - DEBUG(0, ("cli_request_new failed\n")); return NULL; } + req = cli_request_get(result); + req->data.read.ofs = offset; req->data.read.size = size; req->data.read.received = 0; req->data.read.rcvbuf = NULL; - if ((SMB_BIG_UINT)offset >> 32) - bigoffset = True; - - cli_set_message(req->outbuf, bigoffset ? 12 : 10, 0, False); - - SCVAL(req->outbuf,smb_com,SMBreadX); - SSVAL(req->outbuf,smb_tid,cli->cnum); - cli_setup_packet_buf(cli, req->outbuf); - - SCVAL(req->outbuf,smb_vwv0,0xFF); - SCVAL(req->outbuf,smb_vwv0+1,0); - SSVAL(req->outbuf,smb_vwv1,0); - SSVAL(req->outbuf,smb_vwv2,fnum); - SIVAL(req->outbuf,smb_vwv3,offset); - SSVAL(req->outbuf,smb_vwv5,size); - SSVAL(req->outbuf,smb_vwv6,size); - SSVAL(req->outbuf,smb_vwv7,(size >> 16)); - SSVAL(req->outbuf,smb_vwv8,0); - SSVAL(req->outbuf,smb_vwv9,0); - SSVAL(req->outbuf,smb_mid,req->mid); - - if (bigoffset) { - SIVAL(req->outbuf, smb_vwv10, - (((SMB_BIG_UINT)offset)>>32) & 0xffffffff); - } - - cli_calculate_sign_mac(cli, req->outbuf); - - event_fd_set_writeable(cli->fd_event); - - if (cli_encryption_on(cli)) { - NTSTATUS status; - status = cli_encrypt_message(cli, req->outbuf, &enc_buf); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Error in encrypting client message. " - "Error %s\n", nt_errstr(status))); - TALLOC_FREE(req); - return NULL; - } - req->outbuf = enc_buf; - req->enc_state = cli->trans_enc_state; - } - return result; } -- cgit From 8f408a676eb1d2bac665d8212d727dafeecd386e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 1 Aug 2008 23:18:15 +0200 Subject: Add async cli_close (This used to be commit f84a2b5dbf8a072a9e356fa39523f65d042a2643) --- source3/libsmb/clifile.c | 51 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 13 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 12b10ba0a0..20357bbec0 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -865,28 +865,53 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode Close a file. ****************************************************************************/ -bool cli_close(struct cli_state *cli, int fnum) +struct async_req *cli_close_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, + int fnum) { - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); + uint16_t vwv[3]; - cli_set_message(cli->outbuf,3,0,True); + SSVAL(vwv+0, 0, fnum); + SIVALS(vwv+1, 0, -1); - SCVAL(cli->outbuf,smb_com,SMBclose); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); + return cli_request_send(mem_ctx, cli, SMBclose, 0, 3, vwv, 0, NULL); +} - SSVAL(cli->outbuf,smb_vwv0,fnum); - SIVALS(cli->outbuf,smb_vwv1,-1); +NTSTATUS cli_close_recv(struct async_req *req) +{ + struct cli_request *cli_req = cli_request_get(req); - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return False; + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; } - return !cli_is_error(cli); + return cli_pull_error(cli_req->inbuf); } +bool cli_close(struct cli_state *cli, int fnum) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct async_req *req; + bool result = false; + + if (cli_tmp_event_ctx(frame, cli) == NULL) { + goto fail; + } + + req = cli_close_send(frame, cli, fnum); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(cli->event_ctx); + } + + result = NT_STATUS_IS_OK(cli_close_recv(req)); + fail: + TALLOC_FREE(frame); + return result; +} /**************************************************************************** Truncate a file to a specified size -- cgit From de9fcfc79504fbca0350a99269b4a3423e5f2561 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 2 Aug 2008 18:44:39 +0200 Subject: Add async open&x (This used to be commit faf353edd60967efac4d5c222db14fa730866273) --- source3/libsmb/clifile.c | 150 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 117 insertions(+), 33 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index 20357bbec0..d5157877bf 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -781,19 +781,61 @@ int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0); } +static uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str) +{ + size_t buflen = talloc_get_size(buf); + char *converted; + size_t converted_size; + + /* + * We're pushing into an SMB buffer, align odd + */ + if (ucs2 && (buflen % 2 == 0)) { + buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, buflen + 1); + if (buf == NULL) { + return NULL; + } + buf[buflen] = '\0'; + buflen += 1; + } + + if (!convert_string_allocate(talloc_tos(), CH_UNIX, + ucs2 ? CH_UTF16LE : CH_DOS, + str, strlen(str)+1, &converted, + &converted_size, true)) { + return NULL; + } + + buf = TALLOC_REALLOC_ARRAY(NULL, buf, uint8_t, + buflen + converted_size); + if (buf == NULL) { + return NULL; + } + + memcpy(buf + buflen, converted, converted_size); + + TALLOC_FREE(converted); + return buf; +} + /**************************************************************************** Open a file WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ -int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode) +struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, + const char *fname, int flags, int share_mode) { - char *p; - unsigned openfn=0; - unsigned accessmode=0; + unsigned openfn = 0; + unsigned accessmode = 0; + uint8_t additional_flags = 0; + uint8_t *bytes; + uint16_t vwv[15]; + struct async_req *result; - if (flags & O_CREAT) + if (flags & O_CREAT) { openfn |= (1<<4); + } if (!(flags & O_EXCL)) { if (flags & O_TRUNC) openfn |= (1<<1); @@ -819,46 +861,88 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode accessmode = 0xFF; } - memset(cli->outbuf,'\0',smb_size); - memset(cli->inbuf,'\0',smb_size); - - cli_set_message(cli->outbuf,15,0, true); - - SCVAL(cli->outbuf,smb_com,SMBopenX); - SSVAL(cli->outbuf,smb_tid,cli->cnum); - cli_setup_packet(cli); - - SSVAL(cli->outbuf,smb_vwv0,0xFF); - SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ - SSVAL(cli->outbuf,smb_vwv3,accessmode); - SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); - SSVAL(cli->outbuf,smb_vwv5,0); - SSVAL(cli->outbuf,smb_vwv8,openfn); + SCVAL(vwv + 0, 0, 0xFF); + SCVAL(vwv + 0, 1, 0); + SSVAL(vwv + 1, 0, 0); + SSVAL(vwv + 2, 0, 0); /* no additional info */ + SSVAL(vwv + 3, 0, accessmode); + SSVAL(vwv + 4, 0, aSYSTEM | aHIDDEN); + SSVAL(vwv + 5, 0, 0); + SIVAL(vwv + 6, 0, 0); + SSVAL(vwv + 8, 0, openfn); + SIVAL(vwv + 9, 0, 0); + SIVAL(vwv + 11, 0, 0); + SIVAL(vwv + 13, 0, 0); if (cli->use_oplocks) { /* if using oplocks then ask for a batch oplock via core and extended methods */ - SCVAL(cli->outbuf,smb_flg, CVAL(cli->outbuf,smb_flg)| - FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK); - SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6); + additional_flags = + FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK; + SSVAL(vwv+2, 0, SVAL(vwv+2, 0) | 6); } - p = smb_buf(cli->outbuf); - p += clistr_push(cli, p, fname, - cli->bufsize - PTR_DIFF(p,cli->outbuf), STR_TERMINATE); + bytes = talloc_array(talloc_tos(), uint8_t, 0); + if (bytes == NULL) { + return NULL; + } - cli_setup_bcc(cli, p); + bytes = smb_bytes_push_str( + bytes, (cli->capabilities & CAP_UNICODE) != 0, fname); + if (bytes == NULL) { + return NULL; + } - cli_send_smb(cli); - if (!cli_receive_smb(cli)) { - return -1; + result = cli_request_send(mem_ctx, cli, SMBopenX, additional_flags, + 15, vwv, talloc_get_size(bytes), bytes); + TALLOC_FREE(bytes); + return result; +} + +NTSTATUS cli_open_recv(struct async_req *req, int *fnum) +{ + struct cli_request *cli_req = cli_request_get(req); + NTSTATUS status; + + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; } - if (cli_is_error(cli)) { - return -1; + status = cli_pull_error(cli_req->inbuf); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + *fnum = SVAL(cli_req->inbuf, smb_vwv2); + + return NT_STATUS_OK; +} + +int cli_open(struct cli_state *cli, const char *fname, int flags, + int share_mode) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct async_req *req; + int result = -1; + + if (cli_tmp_event_ctx(frame, cli) == NULL) { + goto fail; + } + + req = cli_open_send(frame, cli, fname, flags, share_mode); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(cli->event_ctx); } - return SVAL(cli->inbuf,smb_vwv2); + cli_open_recv(req, &result); + fail: + TALLOC_FREE(frame); + return result; } /**************************************************************************** -- cgit From 2650207d4adbfd68974fc2b342dd2af079a2552c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 24 Aug 2008 14:17:43 +0200 Subject: Remove cli->event_ctx, pass it explicitly Storing the event_context as permanent state in struct cli_state creates more complex code than necessary IMO. (This used to be commit debb37f703075008e5ea7d34d214cfa4d0f8f916) --- source3/libsmb/async_smb.c | 94 +++++++++++-------------------------------- source3/libsmb/clifile.c | 44 +++++++++++++++----- source3/libsmb/clireadwrite.c | 33 ++++++++++----- 3 files changed, 81 insertions(+), 90 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 454bd8169b..e58b753da2 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -19,6 +19,9 @@ #include "includes.h" +static void cli_state_handler(struct event_context *event_ctx, + struct fd_event *event, uint16 flags, void *p); + /* * Fetch an error out of a NBT packet */ @@ -107,6 +110,9 @@ static int cli_request_destructor(struct cli_request *req) common_free_enc_buffer(req->enc_state, req->outbuf); } DLIST_REMOVE(req->cli->outstanding_requests, req); + if (req->cli->outstanding_requests == NULL) { + TALLOC_FREE(req->cli->fd_event); + } return 0; } @@ -163,7 +169,9 @@ static struct async_req *cli_request_new(TALLOC_CTX *mem_ctx, /* * Ship a new smb request to the server */ -struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, +struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, uint8_t smb_command, uint8_t additional_flags, uint8_t wct, const uint16_t *vwv, @@ -172,10 +180,20 @@ struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, struct async_req *result; struct cli_request *req; - result = cli_request_new(mem_ctx, cli->event_ctx, cli, wct, num_bytes, - &req); + if (cli->fd_event == NULL) { + SMB_ASSERT(cli->outstanding_requests == NULL); + cli->fd_event = event_add_fd(ev, cli, cli->fd, + EVENT_FD_READ, + cli_state_handler, cli); + if (cli->fd_event == NULL) { + return NULL; + } + } + + result = cli_request_new(mem_ctx, ev, cli, wct, num_bytes, &req); if (result == NULL) { DEBUG(0, ("cli_request_new failed\n")); + TALLOC_FREE(cli->fd_event); return NULL; } @@ -446,7 +464,9 @@ static void cli_state_handler(struct event_context *event_ctx, } if (req == NULL) { - event_fd_set_not_writeable(event); + if (cli->fd_event != NULL) { + event_fd_set_not_writeable(cli->fd_event); + } return; } @@ -474,69 +494,3 @@ static void cli_state_handler(struct event_context *event_ctx, close(cli->fd); cli->fd = -1; } - -/* - * Holder for a talloc_destructor, we need to zero out the pointers in cli - * when deleting - */ -struct cli_tmp_event { - struct cli_state *cli; -}; - -static int cli_tmp_event_destructor(struct cli_tmp_event *e) -{ - TALLOC_FREE(e->cli->fd_event); - TALLOC_FREE(e->cli->event_ctx); - return 0; -} - -/* - * Create a temporary event context for use in the sync helper functions - */ - -struct cli_tmp_event *cli_tmp_event_ctx(TALLOC_CTX *mem_ctx, - struct cli_state *cli) -{ - struct cli_tmp_event *state; - - if (cli->event_ctx != NULL) { - return NULL; - } - - state = talloc(mem_ctx, struct cli_tmp_event); - if (state == NULL) { - return NULL; - } - state->cli = cli; - talloc_set_destructor(state, cli_tmp_event_destructor); - - cli->event_ctx = event_context_init(state); - if (cli->event_ctx == NULL) { - TALLOC_FREE(state); - return NULL; - } - - cli->fd_event = event_add_fd(cli->event_ctx, state, cli->fd, - EVENT_FD_READ, cli_state_handler, cli); - if (cli->fd_event == NULL) { - TALLOC_FREE(state); - return NULL; - } - return state; -} - -/* - * Attach an event context permanently to a cli_struct - */ - -NTSTATUS cli_add_event_ctx(struct cli_state *cli, - struct event_context *event_ctx) -{ - cli->event_ctx = event_ctx; - cli->fd_event = event_add_fd(event_ctx, cli, cli->fd, EVENT_FD_READ, - cli_state_handler, cli); - if (cli->fd_event == NULL) { - return NT_STATUS_NO_MEMORY; - } - return NT_STATUS_OK; -} diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index d5157877bf..dfb0ce8c11 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -823,7 +823,8 @@ static uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str) WARNING: if you open with O_WRONLY then getattrE won't work! ****************************************************************************/ -struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, +struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, const char *fname, int flags, int share_mode) { unsigned openfn = 0; @@ -893,7 +894,7 @@ struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, return NULL; } - result = cli_request_send(mem_ctx, cli, SMBopenX, additional_flags, + result = cli_request_send(mem_ctx, ev, cli, SMBopenX, additional_flags, 15, vwv, talloc_get_size(bytes), bytes); TALLOC_FREE(bytes); return result; @@ -923,20 +924,30 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, int share_mode) { TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; struct async_req *req; int result = -1; - if (cli_tmp_event_ctx(frame, cli) == NULL) { + if (cli->fd_event != NULL) { + /* + * Can't use sync call while an async call is in flight + */ + cli_set_error(cli, NT_STATUS_INVALID_PARAMETER); goto fail; } - req = cli_open_send(frame, cli, fname, flags, share_mode); + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = cli_open_send(frame, ev, cli, fname, flags, share_mode); if (req == NULL) { goto fail; } while (req->state < ASYNC_REQ_DONE) { - event_loop_once(cli->event_ctx); + event_loop_once(ev); } cli_open_recv(req, &result); @@ -949,15 +960,16 @@ int cli_open(struct cli_state *cli, const char *fname, int flags, Close a file. ****************************************************************************/ -struct async_req *cli_close_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, - int fnum) +struct async_req *cli_close_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, int fnum) { uint16_t vwv[3]; SSVAL(vwv+0, 0, fnum); SIVALS(vwv+1, 0, -1); - return cli_request_send(mem_ctx, cli, SMBclose, 0, 3, vwv, 0, NULL); + return cli_request_send(mem_ctx, ev, cli, SMBclose, 0, 3, vwv, + 0, NULL); } NTSTATUS cli_close_recv(struct async_req *req) @@ -975,20 +987,30 @@ NTSTATUS cli_close_recv(struct async_req *req) bool cli_close(struct cli_state *cli, int fnum) { TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; struct async_req *req; bool result = false; - if (cli_tmp_event_ctx(frame, cli) == NULL) { + if (cli->fd_event != NULL) { + /* + * Can't use sync call while an async call is in flight + */ + cli_set_error(cli, NT_STATUS_INVALID_PARAMETER); + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { goto fail; } - req = cli_close_send(frame, cli, fnum); + req = cli_close_send(frame, ev, cli, fnum); if (req == NULL) { goto fail; } while (req->state < ASYNC_REQ_DONE) { - event_loop_once(cli->event_ctx); + event_loop_once(ev); } result = NT_STATUS_IS_OK(cli_close_recv(req)); diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index 2b34fce5bd..d2c8f3c1ba 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -41,6 +41,7 @@ static size_t cli_read_max_bufsize(struct cli_state *cli) */ struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, struct cli_state *cli, int fnum, off_t offset, size_t size) { @@ -76,7 +77,7 @@ struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, wct += 2; } - result = cli_request_send(mem_ctx, cli, SMBreadX, 0, wct, vwv, + result = cli_request_send(mem_ctx, ev, cli, SMBreadX, 0, wct, vwv, 0, NULL); if (result == NULL) { return NULL; @@ -144,6 +145,7 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, struct cli_pull_state { struct async_req *req; + struct event_context *ev; struct cli_state *cli; uint16_t fnum; off_t start_offset; @@ -202,7 +204,9 @@ static void cli_pull_read_done(struct async_req *read_req); * Prepare an async pull request */ -struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, +struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, uint16_t fnum, off_t start_offset, SMB_OFF_T size, size_t window_size, NTSTATUS (*sink)(char *buf, size_t n, @@ -213,7 +217,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, struct cli_pull_state *state; int i; - result = async_req_new(mem_ctx, cli->event_ctx); + result = async_req_new(mem_ctx, ev); if (result == NULL) { goto failed; } @@ -226,6 +230,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, state->req = result; state->cli = cli; + state->ev = ev; state->fnum = fnum; state->start_offset = start_offset; state->size = size; @@ -268,7 +273,7 @@ struct async_req *cli_pull_send(TALLOC_CTX *mem_ctx, struct cli_state *cli, request_thistime = MIN(size_left, state->chunk_size); state->reqs[i] = cli_read_andx_send( - state->reqs, cli, fnum, + state->reqs, ev, cli, fnum, state->start_offset + state->requested, request_thistime); @@ -363,7 +368,8 @@ static void cli_pull_read_done(struct async_req *read_req) state->top_req)); new_req = cli_read_andx_send( - state->reqs, state->cli, state->fnum, + state->reqs, state->ev, state->cli, + state->fnum, state->start_offset + state->requested, request_thistime); @@ -403,21 +409,30 @@ NTSTATUS cli_pull(struct cli_state *cli, uint16_t fnum, void *priv, SMB_OFF_T *received) { TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; struct async_req *req; NTSTATUS result = NT_STATUS_NO_MEMORY; - if (cli_tmp_event_ctx(frame, cli) == NULL) { + if (cli->fd_event != NULL) { + /* + * Can't use sync call while an async call is in flight + */ + return NT_STATUS_INVALID_PARAMETER; + } + + ev = event_context_init(frame); + if (ev == NULL) { goto nomem; } - req = cli_pull_send(frame, cli, fnum, start_offset, size, window_size, - sink, priv); + req = cli_pull_send(frame, ev, cli, fnum, start_offset, size, + window_size, sink, priv); if (req == NULL) { goto nomem; } while (req->state < ASYNC_REQ_DONE) { - event_loop_once(cli->event_ctx); + event_loop_once(ev); } result = cli_pull_recv(req, received); -- cgit From 128524930d490fb5ea637d99bffb36157c80869b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Aug 2008 13:33:41 +0200 Subject: Add cli_pull_reply Along the lines of cli_request_send this abstracts away the smb-level buffer handling when parsing replies we got from the server. (This used to be commit 253134d3aaa359fdfb665709dd5686f69af7f8fd) --- source3/libsmb/async_smb.c | 54 +++++++++++++++++++++++++++++++++++++++++++ source3/libsmb/clifile.c | 20 ++++++++++++---- source3/libsmb/clireadwrite.c | 17 ++++++++++---- 3 files changed, 81 insertions(+), 10 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index e58b753da2..32f0e8abd6 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -230,6 +230,60 @@ struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, return result; } +/** + * @brief Pull reply data out of a request + * @param[in] req The request that we just received a reply for + * @param[out] pwct How many words did the server send? + * @param[out] pvwv The words themselves + * @param[out] pnum_bytes How many bytes did the server send? + * @param[out] pbytes The bytes themselves + * @retval Was the reply formally correct? + */ + +NTSTATUS cli_pull_reply(struct async_req *req, + uint8_t *pwct, uint16_t **pvwv, + uint16_t *pnum_bytes, uint8_t **pbytes) +{ + struct cli_request *cli_req = cli_request_get(req); + uint8_t wct, cmd; + uint16_t num_bytes; + size_t wct_ofs, bytes_offset; + NTSTATUS status; + + status = cli_pull_error(cli_req->inbuf); + + if (NT_STATUS_IS_ERR(status)) { + cli_set_error(cli_req->cli, status); + return status; + } + + cmd = CVAL(cli_req->inbuf, smb_com); + wct_ofs = smb_wct; + + wct = CVAL(cli_req->inbuf, wct_ofs); + + bytes_offset = wct_ofs + 1 + wct * sizeof(uint16_t); + num_bytes = SVAL(cli_req->inbuf, bytes_offset); + + /* + * wct_ofs is a 16-bit value plus 4, wct is a 8-bit value, num_bytes + * is a 16-bit value. So bytes_offset being size_t should be far from + * wrapping. + */ + + if ((bytes_offset + 2 > talloc_get_size(cli_req->inbuf)) + || (bytes_offset > 0xffff)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + *pwct = wct; + *pvwv = (uint16_t *)(cli_req->inbuf + wct_ofs + 1); + *pnum_bytes = num_bytes; + *pbytes = (uint8_t *)cli_req->inbuf + bytes_offset + 2; + + return NT_STATUS_OK; +} + /* * Convenience function to get the SMB part out of an async_req */ diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index dfb0ce8c11..b3032a08eb 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -902,7 +902,10 @@ struct async_req *cli_open_send(TALLOC_CTX *mem_ctx, struct event_context *ev, NTSTATUS cli_open_recv(struct async_req *req, int *fnum) { - struct cli_request *cli_req = cli_request_get(req); + uint8_t wct; + uint16_t *vwv; + uint16_t num_bytes; + uint8_t *bytes; NTSTATUS status; SMB_ASSERT(req->state >= ASYNC_REQ_DONE); @@ -910,12 +913,16 @@ NTSTATUS cli_open_recv(struct async_req *req, int *fnum) return req->status; } - status = cli_pull_error(cli_req->inbuf); + status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes); if (!NT_STATUS_IS_OK(status)) { return status; } - *fnum = SVAL(cli_req->inbuf, smb_vwv2); + if (wct < 3) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + *fnum = SVAL(vwv+2, 0); return NT_STATUS_OK; } @@ -974,14 +981,17 @@ struct async_req *cli_close_send(TALLOC_CTX *mem_ctx, struct event_context *ev, NTSTATUS cli_close_recv(struct async_req *req) { - struct cli_request *cli_req = cli_request_get(req); + uint8_t wct; + uint16_t *vwv; + uint16_t num_bytes; + uint8_t *bytes; SMB_ASSERT(req->state >= ASYNC_REQ_DONE); if (req->state == ASYNC_REQ_ERROR) { return req->status; } - return cli_pull_error(cli_req->inbuf); + return cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes); } bool cli_close(struct cli_state *cli, int fnum) diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index d2c8f3c1ba..b64a4c68f3 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -104,6 +104,10 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, uint8_t **rcvbuf) { struct cli_request *cli_req = cli_request_get(req); + uint8_t wct; + uint16_t *vwv; + uint16_t num_bytes; + uint8_t *bytes; NTSTATUS status; size_t size; @@ -112,24 +116,27 @@ NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, return req->status; } - status = cli_pull_error(cli_req->inbuf); + status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes); if (NT_STATUS_IS_ERR(status)) { return status; } + if (wct < 12) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + /* size is the number of bytes the server returned. * Might be zero. */ - size = SVAL(cli_req->inbuf, smb_vwv5); - size |= (((unsigned int)(SVAL(cli_req->inbuf, smb_vwv7))) << 16); + size = SVAL(vwv + 5, 0); + size |= (((unsigned int)SVAL(vwv + 7, 0)) << 16); if (size > cli_req->data.read.size) { DEBUG(5,("server returned more than we wanted!\n")); return NT_STATUS_UNEXPECTED_IO_ERROR; } - *rcvbuf = (uint8_t *) - (smb_base(cli_req->inbuf) + SVAL(cli_req->inbuf, smb_vwv6)); + *rcvbuf = (uint8_t *)(smb_base(cli_req->inbuf) + SVAL(vwv + 6, 0)); *received = size; return NT_STATUS_OK; } -- cgit From 77d1b29e25512982a1f912adac46bb954ee3d19f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Aug 2008 14:40:15 +0200 Subject: Move "struct cli_request" from client.h to async_smb.h Also add some comments (This used to be commit 2ecc311f785317caf5b60051147dcd085c80d64f) --- source3/libsmb/async_smb.c | 38 ++++++++++++++++++++++++++++++++------ 1 file changed, 32 insertions(+), 6 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 32f0e8abd6..e36e514a16 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -22,8 +22,10 @@ static void cli_state_handler(struct event_context *event_ctx, struct fd_event *event, uint16 flags, void *p); -/* +/** * Fetch an error out of a NBT packet + * @param[in] buf The SMB packet + * @retval The error, converted to NTSTATUS */ NTSTATUS cli_pull_error(char *buf) @@ -43,8 +45,10 @@ NTSTATUS cli_pull_error(char *buf) return NT_STATUS_DOS(CVAL(buf, smb_rcls), SVAL(buf,smb_err)); } -/* +/** * Compatibility helper for the sync APIs: Fake NTSTATUS in cli->inbuf + * @param[in] cli The client connection that just received an error + * @param[in] status The error to set on "cli" */ void cli_set_error(struct cli_state *cli, NTSTATUS status) @@ -64,8 +68,10 @@ void cli_set_error(struct cli_state *cli, NTSTATUS status) return; } -/* +/** * Allocate a new mid + * @param[in] cli The client connection + * @retval The new, unused mid */ static uint16_t cli_new_mid(struct cli_state *cli) @@ -91,6 +97,13 @@ static uint16_t cli_new_mid(struct cli_state *cli) } } +/** + * Print an async req that happens to be a cli_request + * @param[in] mem_ctx The TALLOC_CTX to put the result on + * @param[in] req The request to print + * @retval The string representation of "req" + */ + static char *cli_request_print(TALLOC_CTX *mem_ctx, struct async_req *req) { char *result = async_req_print(mem_ctx, req); @@ -104,6 +117,12 @@ static char *cli_request_print(TALLOC_CTX *mem_ctx, struct async_req *req) result, "mid=%d\n", cli_req->mid); } +/** + * Destroy a cli_request + * @param[in] req The cli_request to kill + * @retval Can't fail + */ + static int cli_request_destructor(struct cli_request *req) { if (req->enc_state != NULL) { @@ -284,8 +303,10 @@ NTSTATUS cli_pull_reply(struct async_req *req, return NT_STATUS_OK; } -/* +/** * Convenience function to get the SMB part out of an async_req + * @param[in] req The request to look at + * @retval The private_data as struct cli_request */ struct cli_request *cli_request_get(struct async_req *req) @@ -296,8 +317,9 @@ struct cli_request *cli_request_get(struct async_req *req) return talloc_get_type_abort(req->private_data, struct cli_request); } -/* +/** * A PDU has arrived on cli->evt_inbuf + * @param[in] cli The cli_state that received something */ static void handle_incoming_pdu(struct cli_state *cli) @@ -434,8 +456,12 @@ static void handle_incoming_pdu(struct cli_state *cli) return; } -/* +/** * fd event callback. This is the basic connection to the socket + * @param[in] event_ctx The event context that called us + * @param[in] event The event that fired + * @param[in] flags EVENT_FD_READ | EVENT_FD_WRITE + * @param[in] p private_data, in this case the cli_state */ static void cli_state_handler(struct event_context *event_ctx, -- cgit From 65dcdf9c32e8ac43344b23db528206c02fcb967c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Aug 2008 15:56:26 +0200 Subject: This adds the code to allow chained requests in libsmb/ This is not compiled yet, but it makes the patches much easier to read if it is add in bulk. (This used to be commit b4c539ba041bab8856c83816f08a35b5f5b21740) --- source3/libsmb/async_smb.c | 534 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 534 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index e36e514a16..e764147432 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -135,6 +135,540 @@ static int cli_request_destructor(struct cli_request *req) return 0; } +#if 0 + +/** + * Is the SMB command able to hold an AND_X successor + * @param[in] cmd The SMB command in question + * @retval Can we add a chained request after "cmd"? + */ + +static bool is_andx_req(uint8_t cmd) +{ + switch (cmd) { + case SMBtconX: + case SMBlockingX: + case SMBopenX: + case SMBreadX: + case SMBwriteX: + case SMBsesssetupX: + case SMBulogoffX: + case SMBntcreateX: + return true; + break; + default: + break; + } + + return false; +} + +/** + * @brief Find the smb_cmd offset of the last command pushed + * @param[in] buf The buffer we're building up + * @retval Where can we put our next andx cmd? + * + * While chaining requests, the "next" request we're looking at needs to put + * its SMB_Command before the data the previous request already built up added + * to the chain. Find the offset to the place where we have to put our cmd. + */ + +static bool find_andx_cmd_ofs(char *buf, size_t *pofs) +{ + uint8_t cmd; + size_t ofs; + + cmd = CVAL(buf, smb_com); + + SMB_ASSERT(is_andx_req(cmd)); + + ofs = smb_vwv0; + + while (CVAL(buf, ofs) != 0xff) { + + if (!is_andx_req(CVAL(buf, ofs))) { + return false; + } + + /* + * ofs is from start of smb header, so add the 4 length + * bytes. The next cmd is right after the wct field. + */ + ofs = SVAL(buf, ofs+2) + 4 + 1; + + SMB_ASSERT(ofs+4 < talloc_get_size(buf)); + } + + *pofs = ofs; + return true; +} + +/** + * @brief Destroy an async_req that is the visible part of a cli_request + * @param[in] req The request to kill + * @retval Return 0 to make talloc happy + * + * This destructor is a bit tricky: Because a cli_request can host more than + * one async_req for chained requests, we need to make sure that the + * "cli_request" that we were part of is correctly destroyed at the right + * time. This is done by NULLing out ourself from the "async" member of our + * "cli_request". If there is none left, then also TALLOC_FREE() the + * cli_request, which was a talloc child of the client connection cli_state. + */ + +static int cli_async_req_destructor(struct async_req *req) +{ + struct cli_request *cli_req = cli_request_get(req); + int i, pending; + bool found = false; + + pending = 0; + + for (i=0; inum_async; i++) { + if (cli_req->async[i] == req) { + cli_req->async[i] = NULL; + found = true; + } + if (cli_req->async[i] != NULL) { + pending += 1; + } + } + + SMB_ASSERT(found); + + if (pending == 0) { + TALLOC_FREE(cli_req); + } + + return 0; +} + +/** + * @brief Chain up a request + * @param[in] mem_ctx The TALLOC_CTX for the result + * @param[in] ev The event context that will call us back + * @param[in] cli The cli_state we queue the request up for + * @param[in] smb_command The command that we want to issue + * @param[in] additional_flags open_and_x wants to add oplock header flags + * @param[in] wct How many words? + * @param[in] vwv The words, already in network order + * @param[in] num_bytes How many bytes? + * @param[in] bytes The data the request ships + * + * cli_request_chain() is the core of the SMB request marshalling routine. It + * will create a new async_req structure in the cli->chain_accumulator->async + * array and marshall the smb_cmd, the vwv array and the bytes into + * cli->chain_accumulator->outbuf. + */ + +static struct async_req *cli_request_chain(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint8_t smb_command, + uint8_t additional_flags, + uint8_t wct, const uint16_t *vwv, + uint16_t num_bytes, + const uint8_t *bytes) +{ + struct async_req **tmp_reqs; + char *tmp_buf; + struct cli_request *req; + size_t old_size, new_size; + size_t ofs; + + req = cli->chain_accumulator; + + tmp_reqs = TALLOC_REALLOC_ARRAY(req, req->async, struct async_req *, + req->num_async + 1); + if (tmp_reqs == NULL) { + DEBUG(0, ("talloc failed\n")); + return NULL; + } + req->async = tmp_reqs; + req->num_async += 1; + + req->async[req->num_async-1] = async_req_new(mem_ctx, ev); + if (req->async[req->num_async-1] == NULL) { + DEBUG(0, ("async_req_new failed\n")); + req->num_async -= 1; + return NULL; + } + req->async[req->num_async-1]->private_data = req; + req->async[req->num_async-1]->print = cli_request_print; + talloc_set_destructor(req->async[req->num_async-1], + cli_async_req_destructor); + + old_size = talloc_get_size(req->outbuf); + + /* + * We need space for the wct field, the words, the byte count field + * and the bytes themselves. + */ + new_size = old_size + 1 + wct * sizeof(uint16_t) + 2 + num_bytes; + + if (new_size > 0xffff) { + DEBUG(1, ("cli_request_chain: %u bytes won't fit\n", + (unsigned)new_size)); + goto fail; + } + + tmp_buf = TALLOC_REALLOC_ARRAY(NULL, req->outbuf, char, new_size); + if (tmp_buf == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; + } + req->outbuf = tmp_buf; + + if (old_size == smb_wct) { + SCVAL(req->outbuf, smb_com, smb_command); + } else { + size_t andx_cmd_ofs; + if (!find_andx_cmd_ofs(req->outbuf, &andx_cmd_ofs)) { + DEBUG(1, ("invalid command chain\n")); + goto fail; + } + SCVAL(req->outbuf, andx_cmd_ofs, smb_command); + SSVAL(req->outbuf, andx_cmd_ofs + 2, old_size - 4); + } + + ofs = old_size; + + SCVAL(req->outbuf, ofs, wct); + ofs += 1; + + memcpy(req->outbuf + ofs, vwv, sizeof(uint16_t) * wct); + ofs += sizeof(uint16_t) * wct; + + SSVAL(req->outbuf, ofs, num_bytes); + ofs += sizeof(uint16_t); + + memcpy(req->outbuf + ofs, bytes, num_bytes); + + return req->async[req->num_async-1]; + + fail: + TALLOC_FREE(req->async[req->num_async-1]); + req->num_async -= 1; + return NULL; +} + +/** + * @brief prepare a cli_state to accept a chain of requests + * @param[in] cli The cli_state we want to queue up in + * @param[in] ev The event_context that will call us back for the socket + * @param[in] size_hint How many bytes are expected, just an optimization + * @retval Did we have enough memory? + * + * cli_chain_cork() sets up a new cli_request in cli->chain_accumulator. If + * cli is used in an async fashion, i.e. if we have outstanding requests, then + * we do not have to create a fd event. If cli is used only with the sync + * helpers, we need to create the fd_event here. + * + * If you want to issue a chained request to the server, do a + * cli_chain_cork(), then do you cli_open_send(), cli_read_and_x_send(), + * cli_close_send() and so on. The async requests that come out of + * cli_xxx_send() are normal async requests with the difference that they + * won't be shipped individually. But the event_context will still trigger the + * req->async.fn to be called on every single request. + * + * You have to take care yourself that you only issue chainable requests in + * the middle of the chain. + */ + +bool cli_chain_cork(struct cli_state *cli, struct event_context *ev, + size_t size_hint) +{ + struct cli_request *req = NULL; + + SMB_ASSERT(cli->chain_accumulator == NULL); + + if (cli->fd_event == NULL) { + SMB_ASSERT(cli->outstanding_requests == NULL); + cli->fd_event = event_add_fd(ev, cli, cli->fd, + EVENT_FD_READ, + cli_state_handler, cli); + if (cli->fd_event == NULL) { + return false; + } + } + + req = talloc(cli, struct cli_request); + if (req == NULL) { + goto fail; + } + req->cli = cli; + + if (size_hint == 0) { + size_hint = 100; + } + req->outbuf = talloc_array(req, char, smb_wct + size_hint); + if (req->outbuf == NULL) { + goto fail; + } + req->outbuf = TALLOC_REALLOC_ARRAY(NULL, req->outbuf, char, smb_wct); + + req->num_async = 0; + req->async = NULL; + + req->enc_state = NULL; + + SSVAL(req->outbuf, smb_tid, cli->cnum); + cli_setup_packet_buf(cli, req->outbuf); + + req->mid = cli_new_mid(cli); + SSVAL(req->outbuf, smb_mid, req->mid); + + cli->chain_accumulator = req; + + DEBUG(10, ("cli_chain_cork: mid=%d\n", req->mid)); + + return true; + fail: + TALLOC_FREE(req); + if (cli->outstanding_requests == NULL) { + TALLOC_FREE(cli->fd_event); + } + return false; +} + +/** + * Ship a request queued up via cli_request_chain() + * @param[in] cl The connection + */ + +void cli_chain_uncork(struct cli_state *cli) +{ + struct cli_request *req = cli->chain_accumulator; + + SMB_ASSERT(req != NULL); + + DLIST_ADD_END(cli->outstanding_requests, req, struct cli_request *); + talloc_set_destructor(req, cli_request_destructor); + + cli->chain_accumulator = NULL; + + smb_setlen(req->outbuf, talloc_get_size(req->outbuf) - 4); + + cli_calculate_sign_mac(cli, req->outbuf); + + if (cli_encryption_on(cli)) { + NTSTATUS status; + char *enc_buf; + + status = cli_encrypt_message(cli, req->outbuf, &enc_buf); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("Error in encrypting client message. " + "Error %s\n", nt_errstr(status))); + TALLOC_FREE(req); + return; + } + req->outbuf = enc_buf; + req->enc_state = cli->trans_enc_state; + } + + req->sent = 0; + + event_fd_set_writeable(cli->fd_event); +} + +/** + * @brief Send a request to the server + * @param[in] mem_ctx The TALLOC_CTX for the result + * @param[in] ev The event context that will call us back + * @param[in] cli The cli_state we queue the request up for + * @param[in] smb_command The command that we want to issue + * @param[in] additional_flags open_and_x wants to add oplock header flags + * @param[in] wct How many words? + * @param[in] vwv The words, already in network order + * @param[in] num_bytes How many bytes? + * @param[in] bytes The data the request ships + * + * This is the generic routine to be used by the cli_xxx_send routines. + */ + +struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct cli_state *cli, + uint8_t smb_command, + uint8_t additional_flags, + uint8_t wct, const uint16_t *vwv, + uint16_t num_bytes, const uint8_t *bytes) +{ + struct async_req *result; + bool uncork = false; + + if (cli->chain_accumulator == NULL) { + if (!cli_chain_cork(cli, ev, + wct * sizeof(uint16_t) + num_bytes + 3)) { + DEBUG(1, ("cli_chain_cork failed\n")); + return NULL; + } + uncork = true; + } + + result = cli_request_chain(mem_ctx, ev, cli, smb_command, + additional_flags, wct, vwv, + num_bytes, bytes); + + if (result == NULL) { + DEBUG(1, ("cli_request_chain failed\n")); + } + + if (uncork) { + cli_chain_uncork(cli); + } + + return result; +} + +/** + * Figure out if there is an andx command behind the current one + * @param[in] buf The smb buffer to look at + * @param[in] ofs The offset to the wct field that is followed by the cmd + * @retval Is there a command following? + */ + +static bool have_andx_command(const char *buf, uint16_t ofs) +{ + uint8_t wct; + size_t buflen = talloc_get_size(buf); + + if ((ofs == buflen-1) || (ofs == buflen)) { + return false; + } + + wct = CVAL(buf, ofs); + if (wct < 2) { + /* + * Not enough space for the command and a following pointer + */ + return false; + } + return (CVAL(buf, ofs+1) != 0xff); +} + +/** + * @brief Pull reply data out of a request + * @param[in] req The request that we just received a reply for + * @param[out] pwct How many words did the server send? + * @param[out] pvwv The words themselves + * @param[out] pnum_bytes How many bytes did the server send? + * @param[out] pbytes The bytes themselves + * @retval Was the reply formally correct? + */ + +NTSTATUS cli_pull_reply(struct async_req *req, + uint8_t *pwct, uint16_t **pvwv, + uint16_t *pnum_bytes, uint8_t **pbytes) +{ + struct cli_request *cli_req = cli_request_get(req); + uint8_t wct, cmd; + uint16_t num_bytes; + size_t wct_ofs, bytes_offset; + int i, j; + NTSTATUS status; + + for (i = 0; i < cli_req->num_async; i++) { + if (req == cli_req->async[i]) { + break; + } + } + + if (i == cli_req->num_async) { + cli_set_error(cli_req->cli, NT_STATUS_INVALID_PARAMETER); + return NT_STATUS_INVALID_PARAMETER; + } + + /** + * The status we pull here is only relevant for the last reply in the + * chain. + */ + + status = cli_pull_error(cli_req->inbuf); + + if (i == 0) { + if (NT_STATUS_IS_ERR(status) + && !have_andx_command(cli_req->inbuf, smb_wct)) { + cli_set_error(cli_req->cli, status); + return status; + } + wct_ofs = smb_wct; + goto done; + } + + cmd = CVAL(cli_req->inbuf, smb_com); + wct_ofs = smb_wct; + + for (j = 0; j < i; j++) { + if (j < i-1) { + if (cmd == 0xff) { + return NT_STATUS_REQUEST_ABORTED; + } + if (!is_andx_req(cmd)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + } + + if (!have_andx_command(cli_req->inbuf, wct_ofs)) { + /* + * This request was not completed because a previous + * request in the chain had received an error. + */ + return NT_STATUS_REQUEST_ABORTED; + } + + wct_ofs = SVAL(cli_req->inbuf, wct_ofs + 3); + + /* + * Skip the all-present length field. No overflow, we've just + * put a 16-bit value into a size_t. + */ + wct_ofs += 4; + + if (wct_ofs+2 > talloc_get_size(cli_req->inbuf)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + cmd = CVAL(cli_req->inbuf, wct_ofs + 1); + } + + if (!have_andx_command(cli_req->inbuf, wct_ofs) + && NT_STATUS_IS_ERR(status)) { + /* + * The last command takes the error code. All further commands + * down the requested chain will get a + * NT_STATUS_REQUEST_ABORTED. + */ + return status; + } + + done: + wct = CVAL(cli_req->inbuf, wct_ofs); + + bytes_offset = wct_ofs + 1 + wct * sizeof(uint16_t); + num_bytes = SVAL(cli_req->inbuf, bytes_offset); + + /* + * wct_ofs is a 16-bit value plus 4, wct is a 8-bit value, num_bytes + * is a 16-bit value. So bytes_offset being size_t should be far from + * wrapping. + */ + + if ((bytes_offset + 2 > talloc_get_size(cli_req->inbuf)) + || (bytes_offset > 0xffff)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + *pwct = wct; + *pvwv = (uint16_t *)(cli_req->inbuf + wct_ofs + 1); + *pnum_bytes = num_bytes; + *pbytes = (uint8_t *)cli_req->inbuf + bytes_offset + 2; + + return NT_STATUS_OK; +} + +#endif + /* * Create a fresh async smb request */ -- cgit From b054f14111337c826548d7728dc2b0a66ab5beae Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 25 Aug 2008 15:59:36 +0200 Subject: Activate code to enable chained requests Add the CHAIN1 torture test (This used to be commit 82992d74a99b056bbfe90e1b79190e0b7c0bf2bd) --- source3/libsmb/async_smb.c | 203 ++++++--------------------------------------- 1 file changed, 27 insertions(+), 176 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index e764147432..4d6c32edfa 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -135,8 +135,6 @@ static int cli_request_destructor(struct cli_request *req) return 0; } -#if 0 - /** * Is the SMB command able to hold an AND_X successor * @param[in] cmd The SMB command in question @@ -667,176 +665,6 @@ NTSTATUS cli_pull_reply(struct async_req *req, return NT_STATUS_OK; } -#endif - -/* - * Create a fresh async smb request - */ - -static struct async_req *cli_request_new(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct cli_state *cli, - uint8_t num_words, size_t num_bytes, - struct cli_request **preq) -{ - struct async_req *result; - struct cli_request *cli_req; - size_t bufsize = smb_size + num_words * 2 + num_bytes; - - result = async_req_new(mem_ctx, ev); - if (result == NULL) { - return NULL; - } - - cli_req = (struct cli_request *)talloc_size( - result, sizeof(*cli_req) + bufsize); - if (cli_req == NULL) { - TALLOC_FREE(result); - return NULL; - } - talloc_set_name_const(cli_req, "struct cli_request"); - result->private_data = cli_req; - result->print = cli_request_print; - - cli_req->async = result; - cli_req->cli = cli; - cli_req->outbuf = ((char *)cli_req + sizeof(*cli_req)); - cli_req->sent = 0; - cli_req->mid = cli_new_mid(cli); - cli_req->inbuf = NULL; - cli_req->enc_state = NULL; - - SCVAL(cli_req->outbuf, smb_wct, num_words); - SSVAL(cli_req->outbuf, smb_vwv + num_words * 2, num_bytes); - - DLIST_ADD_END(cli->outstanding_requests, cli_req, - struct cli_request *); - talloc_set_destructor(cli_req, cli_request_destructor); - - DEBUG(10, ("cli_request_new: mid=%d\n", cli_req->mid)); - - *preq = cli_req; - return result; -} - -/* - * Ship a new smb request to the server - */ -struct async_req *cli_request_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct cli_state *cli, - uint8_t smb_command, - uint8_t additional_flags, - uint8_t wct, const uint16_t *vwv, - uint16_t num_bytes, const uint8_t *bytes) -{ - struct async_req *result; - struct cli_request *req; - - if (cli->fd_event == NULL) { - SMB_ASSERT(cli->outstanding_requests == NULL); - cli->fd_event = event_add_fd(ev, cli, cli->fd, - EVENT_FD_READ, - cli_state_handler, cli); - if (cli->fd_event == NULL) { - return NULL; - } - } - - result = cli_request_new(mem_ctx, ev, cli, wct, num_bytes, &req); - if (result == NULL) { - DEBUG(0, ("cli_request_new failed\n")); - TALLOC_FREE(cli->fd_event); - return NULL; - } - - cli_set_message(req->outbuf, wct, num_bytes, false); - SCVAL(req->outbuf, smb_com, smb_command); - SSVAL(req->outbuf, smb_tid, cli->cnum); - cli_setup_packet_buf(cli, req->outbuf); - - memcpy(req->outbuf + smb_vwv0, vwv, sizeof(uint16_t) * wct); - memcpy(smb_buf(req->outbuf), bytes, num_bytes); - SSVAL(req->outbuf, smb_mid, req->mid); - SCVAL(cli->outbuf, smb_flg, - CVAL(cli->outbuf,smb_flg) | additional_flags); - - cli_calculate_sign_mac(cli, req->outbuf); - - if (cli_encryption_on(cli)) { - NTSTATUS status; - char *enc_buf; - - status = cli_encrypt_message(cli, req->outbuf, &enc_buf); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(0, ("Error in encrypting client message. " - "Error %s\n", nt_errstr(status))); - TALLOC_FREE(req); - return NULL; - } - req->outbuf = enc_buf; - req->enc_state = cli->trans_enc_state; - } - - event_fd_set_writeable(cli->fd_event); - - return result; -} - -/** - * @brief Pull reply data out of a request - * @param[in] req The request that we just received a reply for - * @param[out] pwct How many words did the server send? - * @param[out] pvwv The words themselves - * @param[out] pnum_bytes How many bytes did the server send? - * @param[out] pbytes The bytes themselves - * @retval Was the reply formally correct? - */ - -NTSTATUS cli_pull_reply(struct async_req *req, - uint8_t *pwct, uint16_t **pvwv, - uint16_t *pnum_bytes, uint8_t **pbytes) -{ - struct cli_request *cli_req = cli_request_get(req); - uint8_t wct, cmd; - uint16_t num_bytes; - size_t wct_ofs, bytes_offset; - NTSTATUS status; - - status = cli_pull_error(cli_req->inbuf); - - if (NT_STATUS_IS_ERR(status)) { - cli_set_error(cli_req->cli, status); - return status; - } - - cmd = CVAL(cli_req->inbuf, smb_com); - wct_ofs = smb_wct; - - wct = CVAL(cli_req->inbuf, wct_ofs); - - bytes_offset = wct_ofs + 1 + wct * sizeof(uint16_t); - num_bytes = SVAL(cli_req->inbuf, bytes_offset); - - /* - * wct_ofs is a 16-bit value plus 4, wct is a 8-bit value, num_bytes - * is a 16-bit value. So bytes_offset being size_t should be far from - * wrapping. - */ - - if ((bytes_offset + 2 > talloc_get_size(cli_req->inbuf)) - || (bytes_offset > 0xffff)) { - return NT_STATUS_INVALID_NETWORK_RESPONSE; - } - - *pwct = wct; - *pvwv = (uint16_t *)(cli_req->inbuf + wct_ofs + 1); - *pnum_bytes = num_bytes; - *pbytes = (uint8_t *)cli_req->inbuf + bytes_offset + 2; - - return NT_STATUS_OK; -} - /** * Convenience function to get the SMB part out of an async_req * @param[in] req The request to look at @@ -862,8 +690,11 @@ static void handle_incoming_pdu(struct cli_state *cli) uint16_t mid; size_t raw_pdu_len, buf_len, pdu_len, rest_len; char *pdu; + int i; NTSTATUS status; + int num_async; + /* * The encrypted PDU len might differ from the unencrypted one */ @@ -976,7 +807,24 @@ static void handle_incoming_pdu(struct cli_state *cli) req->inbuf = talloc_move(req, &pdu); - async_req_done(req->async); + /* + * Freeing the last async_req will free the req (see + * cli_async_req_destructor). So make a copy of req->num_async, we + * can't reference it in the last round. + */ + + num_async = req->num_async; + + for (i=0; iasync via its + * destructor cli_async_req_destructor(). + */ + if (req->async[i] != NULL) { + async_req_done(req->async[i]); + } + } return; invalidate_requests: @@ -985,7 +833,7 @@ static void handle_incoming_pdu(struct cli_state *cli) nt_errstr(status))); for (req = cli->outstanding_requests; req; req = req->next) { - async_req_error(req->async, status); + async_req_error(req->async[0], status); } return; } @@ -1101,8 +949,11 @@ static void cli_state_handler(struct event_context *event_ctx, sock_error: for (req = cli->outstanding_requests; req; req = req->next) { - req->async->state = ASYNC_REQ_ERROR; - req->async->status = map_nt_error_from_unix(errno); + int i; + for (i=0; inum_async; i++) { + req->async[i]->state = ASYNC_REQ_ERROR; + req->async[i]->status = map_nt_error_from_unix(errno); + } } TALLOC_FREE(cli->fd_event); close(cli->fd); -- cgit From bb0fc9cfceab7e961eaa9049d111121609ff8174 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 27 Aug 2008 19:26:40 +0200 Subject: Add cli_request->recv_helper Necessary for requests with multiple replies (This used to be commit cb2e338eb33dfb4627f9b43456af0c86d7d268c6) --- source3/libsmb/async_smb.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 4d6c32edfa..b5fa9c44b1 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -409,6 +409,7 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev, req->async = NULL; req->enc_state = NULL; + req->recv_helper.fn = NULL; SSVAL(req->outbuf, smb_tid, cli->cnum); cli_setup_packet_buf(cli, req->outbuf); @@ -822,7 +823,11 @@ static void handle_incoming_pdu(struct cli_state *cli) * destructor cli_async_req_destructor(). */ if (req->async[i] != NULL) { - async_req_done(req->async[i]); + if (req->recv_helper.fn != NULL) { + req->recv_helper.fn(req->async[i]); + } else { + async_req_done(req->async[i]); + } } } return; -- cgit From 228a12681bc7e6eb5bddb75b3b97a74c5eef1c3a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 27 Aug 2008 19:30:57 +0200 Subject: Add async smbecho client support (This used to be commit c1d645fbe39433541d8bfe6b818c855cee318dc5) --- source3/libsmb/clientgen.c | 166 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 139 insertions(+), 27 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 2c0950de03..239ba470a9 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -637,41 +637,153 @@ bool cli_send_keepalive(struct cli_state *cli) return true; } -/**************************************************************************** - Send/receive a SMBecho command: ping the server -****************************************************************************/ +/** + * @brief: Collect a echo reply + * @param[in] req The corresponding async request + * + * There might be more than one echo reply. This helper pulls the reply out of + * the data stream. If all expected replies have arrived, declare the + * async_req done. + */ + +static void cli_echo_recv_helper(struct async_req *req) +{ + struct cli_request *cli_req; + uint8_t wct; + uint16_t *vwv; + uint16_t num_bytes; + uint8_t *bytes; + NTSTATUS status; + + status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes); + if (!NT_STATUS_IS_OK(status)) { + async_req_error(req, status); + return; + } + + cli_req = cli_request_get(req); + + if ((num_bytes != cli_req->data.echo.data.length) + || (memcmp(cli_req->data.echo.data.data, bytes, + num_bytes) != 0)) { + async_req_error(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + return; + } + + cli_req->data.echo.num_echos -= 1; -bool cli_echo(struct cli_state *cli, uint16 num_echos, - unsigned char *data, size_t length) + if (cli_req->data.echo.num_echos == 0) { + client_set_trans_sign_state_off(cli_req->cli, cli_req->mid); + async_req_done(req); + return; + } + + return; +} + +/** + * @brief Send SMBEcho requests + * @param[in] mem_ctx The memory context to put the async_req on + * @param[in] ev The event context that will call us back + * @param[in] cli The connection to send the echo to + * @param[in] num_echos How many times do we want to get the reply? + * @param[in] data The data we want to get back + * @retval The async request + */ + +struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, uint16_t num_echos, + DATA_BLOB data) { - char *p; - int i; + uint16_t vwv[1]; + uint8_t *data_copy; + struct async_req *result; + struct cli_request *req; - SMB_ASSERT(length < 1024); + SSVAL(vwv, 0, num_echos); - memset(cli->outbuf,'\0',smb_size); - cli_set_message(cli->outbuf,1,length,true); - SCVAL(cli->outbuf,smb_com,SMBecho); - SSVAL(cli->outbuf,smb_tid,65535); - SSVAL(cli->outbuf,smb_vwv0,num_echos); - cli_setup_packet(cli); - p = smb_buf(cli->outbuf); - memcpy(p, data, length); - p += length; + data_copy = (uint8_t *)talloc_memdup(mem_ctx, data.data, data.length); + if (data_copy == NULL) { + return NULL; + } - cli_setup_bcc(cli, p); + result = cli_request_send(mem_ctx, ev, cli, SMBecho, 0, 1, vwv, + data.length, data.data); + if (result == NULL) { + TALLOC_FREE(data_copy); + return NULL; + } + req = cli_request_get(result); - cli_send_smb(cli); + client_set_trans_sign_state_on(cli, req->mid); - for (i=0; idata.echo.num_echos = num_echos; + req->data.echo.data.data = talloc_move(req, &data_copy); + req->data.echo.data.length = data.length; - if (cli_is_error(cli)) { - return false; - } + req->recv_helper.fn = cli_echo_recv_helper; + + return result; +} + +/** + * Get the result out from an echo request + * @param[in] req The async_req from cli_echo_send + * @retval Did the server reply correctly? + */ + +NTSTATUS cli_echo_recv(struct async_req *req) +{ + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; } - return true; + return NT_STATUS_OK; +} + +/** + * @brief Send/Receive SMBEcho requests + * @param[in] mem_ctx The memory context to put the async_req on + * @param[in] ev The event context that will call us back + * @param[in] cli The connection to send the echo to + * @param[in] num_echos How many times do we want to get the reply? + * @param[in] data The data we want to get back + * @retval Did the server reply correctly? + */ + +NTSTATUS cli_echo(struct cli_state *cli, uint16_t num_echos, DATA_BLOB data) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli->fd_event != NULL) { + /* + * Can't use sync call while an async call is in flight + */ + cli_set_error(cli, NT_STATUS_INVALID_PARAMETER); + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = cli_echo_send(frame, ev, cli, num_echos, data); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = cli_echo_recv(req); + + fail: + TALLOC_FREE(frame); + return status; } -- cgit From f294f51bf0d136208fee1be343684ea890a499d0 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 28 Aug 2008 15:44:14 +0200 Subject: Remove cli_request_get() req->private_data==NULL at this point is definitely a bug. (This used to be commit ce3dc9f616cafc1289a94ac7cae0beca967d836e) --- source3/libsmb/async_smb.c | 23 ++++++----------------- source3/libsmb/clientgen.c | 4 ++-- source3/libsmb/clireadwrite.c | 12 ++++++++---- 3 files changed, 16 insertions(+), 23 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index b5fa9c44b1..79a924b9db 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -107,7 +107,8 @@ static uint16_t cli_new_mid(struct cli_state *cli) static char *cli_request_print(TALLOC_CTX *mem_ctx, struct async_req *req) { char *result = async_req_print(mem_ctx, req); - struct cli_request *cli_req = cli_request_get(req); + struct cli_request *cli_req = talloc_get_type_abort( + req->private_data, struct cli_request); if (result == NULL) { return NULL; @@ -216,7 +217,8 @@ static bool find_andx_cmd_ofs(char *buf, size_t *pofs) static int cli_async_req_destructor(struct async_req *req) { - struct cli_request *cli_req = cli_request_get(req); + struct cli_request *cli_req = talloc_get_type_abort( + req->private_data, struct cli_request); int i, pending; bool found = false; @@ -560,7 +562,8 @@ NTSTATUS cli_pull_reply(struct async_req *req, uint8_t *pwct, uint16_t **pvwv, uint16_t *pnum_bytes, uint8_t **pbytes) { - struct cli_request *cli_req = cli_request_get(req); + struct cli_request *cli_req = talloc_get_type_abort( + req->private_data, struct cli_request); uint8_t wct, cmd; uint16_t num_bytes; size_t wct_ofs, bytes_offset; @@ -666,20 +669,6 @@ NTSTATUS cli_pull_reply(struct async_req *req, return NT_STATUS_OK; } -/** - * Convenience function to get the SMB part out of an async_req - * @param[in] req The request to look at - * @retval The private_data as struct cli_request - */ - -struct cli_request *cli_request_get(struct async_req *req) -{ - if (req == NULL) { - return NULL; - } - return talloc_get_type_abort(req->private_data, struct cli_request); -} - /** * A PDU has arrived on cli->evt_inbuf * @param[in] cli The cli_state that received something diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 239ba470a9..9d65fb4e94 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -661,7 +661,7 @@ static void cli_echo_recv_helper(struct async_req *req) return; } - cli_req = cli_request_get(req); + cli_req = talloc_get_type_abort(req->private_data, struct cli_request); if ((num_bytes != cli_req->data.echo.data.length) || (memcmp(cli_req->data.echo.data.data, bytes, @@ -713,7 +713,7 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev, TALLOC_FREE(data_copy); return NULL; } - req = cli_request_get(result); + req = talloc_get_type_abort(result->private_data, struct cli_request); client_set_trans_sign_state_on(cli, req->mid); diff --git a/source3/libsmb/clireadwrite.c b/source3/libsmb/clireadwrite.c index b64a4c68f3..ec63281630 100644 --- a/source3/libsmb/clireadwrite.c +++ b/source3/libsmb/clireadwrite.c @@ -83,7 +83,7 @@ struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, return NULL; } - req = cli_request_get(result); + req = talloc_get_type_abort(result->private_data, struct cli_request); req->data.read.ofs = offset; req->data.read.size = size; @@ -103,7 +103,8 @@ struct async_req *cli_read_andx_send(TALLOC_CTX *mem_ctx, NTSTATUS cli_read_andx_recv(struct async_req *req, ssize_t *received, uint8_t **rcvbuf) { - struct cli_request *cli_req = cli_request_get(req); + struct cli_request *cli_req = talloc_get_type_abort( + req->private_data, struct cli_request); uint8_t wct; uint16_t *vwv; uint16_t num_bytes; @@ -311,7 +312,8 @@ static void cli_pull_read_done(struct async_req *read_req) read_req->async.priv, struct async_req); struct cli_pull_state *state = talloc_get_type_abort( pull_req->private_data, struct cli_pull_state); - struct cli_request *read_state = cli_request_get(read_req); + struct cli_request *read_state = talloc_get_type_abort( + read_req->private_data, struct cli_request); NTSTATUS status; status = cli_read_andx_recv(read_req, &read_state->data.read.received, @@ -342,7 +344,9 @@ static void cli_pull_read_done(struct async_req *read_req) return; } - top_read = cli_request_get(state->reqs[state->top_req]); + top_read = talloc_get_type_abort( + state->reqs[state->top_req]->private_data, + struct cli_request); DEBUG(10, ("cli_pull_read_done: Pushing %d bytes, %d already " "pushed\n", (int)top_read->data.read.received, -- cgit From 0380fe9d823d6219441050a9b7298bf039b20742 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Aug 2008 16:08:00 +0200 Subject: kerberos: move the KRB5_KEY* macros to header file. Guenther (This used to be commit c28fa17ffffee3e6fd4897c9c6b4937388a19600) --- source3/libsmb/clikrb5.c | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index fa21ad3467..b6fb7cf050 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -27,18 +27,6 @@ #ifdef HAVE_KRB5 -#ifdef HAVE_KRB5_KEYBLOCK_KEYVALUE /* Heimdal */ -#define KRB5_KEY_TYPE(k) ((k)->keytype) -#define KRB5_KEY_LENGTH(k) ((k)->keyvalue.length) -#define KRB5_KEY_DATA(k) ((k)->keyvalue.data) -#define KRB5_KEY_DATA_CAST void -#else /* MIT */ -#define KRB5_KEY_TYPE(k) ((k)->enctype) -#define KRB5_KEY_LENGTH(k) ((k)->length) -#define KRB5_KEY_DATA(k) ((k)->contents) -#define KRB5_KEY_DATA_CAST krb5_octet -#endif /* HAVE_KRB5_KEYBLOCK_KEYVALUE */ - #define GSSAPI_CHECKSUM 0x8003 /* Checksum type value for Kerberos */ #define GSSAPI_BNDLENGTH 16 /* Bind Length (rfc-1964 pg.3) */ #define GSSAPI_CHECKSUM_SIZE (12+GSSAPI_BNDLENGTH) -- cgit From bff20e14c38d7139033127182b76aa24e471b581 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 22 Aug 2008 14:58:01 +0200 Subject: kerberos: use KRB5_KT_KEY macro where appropriate. Guenther (This used to be commit a042dffd7121bda3dbc9509f69fcfae06ed4cc22) --- source3/libsmb/clikrb5.c | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index b6fb7cf050..bedd7d7aee 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -1045,6 +1045,7 @@ get_key_from_keytab(krb5_context context, krb5_error_code ret; krb5_keytab keytab; char *name = NULL; + krb5_keyblock *keyp; /* We have to open a new keytab handle here, as MIT does an implicit open/getnext/close on krb5_kt_get_entry. We @@ -1077,14 +1078,9 @@ get_key_from_keytab(krb5_context context, goto out; } -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK /* Heimdal */ - ret = krb5_copy_keyblock(context, &entry.keyblock, out_key); -#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEY) /* MIT */ - ret = krb5_copy_keyblock(context, &entry.key, out_key); -#else -#error UNKNOWN_KRB5_KEYTAB_ENTRY_FORMAT -#endif + keyp = KRB5_KT_KEY(&entry); + ret = krb5_copy_keyblock(context, keyp, out_key); if (ret) { DEBUG(0,("get_key_from_keytab: failed to copy key: %s\n", error_message(ret))); goto out; @@ -1572,15 +1568,9 @@ done: #endif /* HAVE_KRB5_GET_INIT_CREDS_OPT_FREE */ } - krb5_enctype smb_get_enctype_from_kt_entry(const krb5_keytab_entry *kt_entry) + krb5_enctype smb_get_enctype_from_kt_entry(krb5_keytab_entry *kt_entry) { -#ifdef HAVE_KRB5_KEYTAB_ENTRY_KEY /* MIT */ - return kt_entry->key.enctype; -#elif defined(HAVE_KRB5_KEYTAB_ENTRY_KEYBLOCK) /* Heimdal */ - return kt_entry->keyblock.keytype; -#else -#error UNKNOWN_KRB5_KEYTAB_ENTRY_KEYBLOCK_FORMAT -#endif + return KRB5_KEY_TYPE(KRB5_KT_KEY(kt_entry)); } -- cgit From 06dd647fe04535474eab85d110d409781544e7a7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 31 Aug 2008 11:45:12 +0200 Subject: Remove a duplicate retval check Jeremy, please check! (This used to be commit 6579005e6490f1a99b3860627ba51decaeb864bd) --- source3/libsmb/clikrb5.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index bedd7d7aee..f940081072 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -749,16 +749,10 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, ccache, &in_data ); if (retval) { - DEBUG( 1, ("ads_krb5_get_fwd_ticket failed (%s)\n", error_message( retval ) ) ); + DEBUG( 1, ("ads_krb5_get_fwd_ticket failed (%s)\n", + error_message( retval ) ) ); goto cleanup_creds; } - - if (retval) { - DEBUG( 1, ("krb5_auth_con_set_req_cksumtype failed (%s)\n", - error_message( retval ) ) ); - goto cleanup_creds; - } - } #endif -- cgit From cad04676ca07d5ae812c7dce26684870788c7535 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 1 Sep 2008 16:22:04 +0200 Subject: Fix typo (This used to be commit 544d1fd19a7e85af5f522c5b6b4b68c6beb093a6) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index b3032a08eb..a8b3440513 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -1892,7 +1892,7 @@ bool cli_set_ea_fnum(struct cli_state *cli, int fnum, const char *ea_name, const } /********************************************************* - Get an extended attribute list tility fn. + Get an extended attribute list utility fn. *********************************************************/ static bool cli_get_ea_list(struct cli_state *cli, -- cgit From 767130ebec474f16e951d1c450cca27e434e9b47 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 1 Sep 2008 21:28:57 +0200 Subject: Fix some nonempty blank lines (This used to be commit 9336cd1c5e5b5d113cd4912d4479dfe609fe261e) --- source3/libsmb/passchange.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c index c8a4406949..4c76234e0c 100644 --- a/source3/libsmb/passchange.c +++ b/source3/libsmb/passchange.c @@ -42,7 +42,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam "%s.\n", remote_machine); return NT_STATUS_UNSUCCESSFUL; } - + cli = cli_initialise(); if (!cli) { return NT_STATUS_NO_MEMORY; @@ -56,10 +56,10 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_shutdown(cli); return result; } - + make_nmb_name(&calling, global_myname() , 0x0); make_nmb_name(&called , remote_machine, 0x20); - + if (!cli_session_request(cli, &calling, &called)) { asprintf(err_str, "machine %s rejected the session setup. " "Error was : %s.\n", @@ -68,7 +68,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_shutdown(cli); return result; } - + cli->protocol = PROTOCOL_NT1; if (!cli_negprot(cli)) { @@ -79,7 +79,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_shutdown(cli); return result; } - + /* Given things like SMB signing, restrict anonymous and the like, try an authenticated connection first */ result = cli_session_setup(cli, user_name, @@ -188,7 +188,7 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam } else if (!(NT_STATUS_EQUAL(result, NT_STATUS_ACCESS_DENIED) || NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL))) { /* it failed, but for reasons such as wrong password, too short etc ... */ - + asprintf(err_str, "machine %s rejected the password change: " "Error was : %s.\n", remote_machine, get_friendly_nt_error_msg(result)); @@ -198,12 +198,12 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam /* OK, that failed, so try again... */ TALLOC_FREE(pipe_hnd); - + /* Try anonymous NTLMSSP... */ cli_init_creds(cli, "", "", NULL); - + result = NT_STATUS_UNSUCCESSFUL; - + /* OK, this is ugly, but... try an anonymous pipe. */ result = cli_rpc_pipe_open_noauth(cli, &ndr_table_samr.syntax_id, &pipe_hnd); @@ -227,10 +227,10 @@ NTSTATUS remote_password_change(const char *remote_machine, const char *user_nam cli_shutdown(cli); return result; } - + /* We have failed to change the user's password, and we think the server just might not support SAMR password changes, so fall back */ - + if (lp_client_lanman_auth()) { /* Use the old RAP method. */ if (cli_oem_change_password(cli, user_name, new_passwd, old_passwd)) { -- cgit From 087a992b973466079f033c55bc5a1f522dc235fd Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Mon, 1 Sep 2008 17:07:33 +0200 Subject: doserr: add WERR_WRONG_PASSWORD. Guenther (This used to be commit 977fec76b77639403ba9ab7bb00c57601e23493d) --- source3/libsmb/doserr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index 50b5b2238c..c62918e214 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -91,6 +91,7 @@ werror_code_struct dos_errs[] = { "WERR_DEFAULT_JOIN_REQUIRED", WERR_DEFAULT_JOIN_REQUIRED }, { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, + { "WERR_WRONG_PASSWORD", WERR_WRONG_PASSWORD }, { "WERR_PASSWORD_RESTRICTION", WERR_PASSWORD_RESTRICTION }, { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, { "WERR_NONE_MAPPED", WERR_NONE_MAPPED }, @@ -150,6 +151,7 @@ werror_str_struct dos_err_strs[] = { { WERR_GROUP_EXISTS, "Group already exists" }, { WERR_DS_DRA_BAD_DN, "An invalid distinguished name was specified for this replication" }, { WERR_DS_DRA_BAD_NC, "An invalid naming context was specified for this replication operation" }, + { WERR_WRONG_PASSWORD, "The current password is incorrect" } }; /***************************************************************************** -- cgit From 304554115a2f2dc316386a9ea5bec237d67f595f Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Wed, 3 Sep 2008 15:31:39 -0700 Subject: Cleanup of DC enumeration in get_dcs() This is a fix for a few small inefficiencies/bugs in the get_dcs() path. * because the third add_one_dc_unique() loop was outside the ADS check all DCs returned from the non-sitename lookup were being tacked onto the dc_name_ip list twice. * add_one_dc_unique() now checks if the given IP address already exists before adding it to the list, making the returned list actually unique * added more thorough doxygen comment headers (This used to be commit cb2d488e1dbd90953c496c5e25d648977884f7e3) --- source3/libsmb/conncache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/conncache.c b/source3/libsmb/conncache.c index 05344f4071..b440d61048 100644 --- a/source3/libsmb/conncache.c +++ b/source3/libsmb/conncache.c @@ -177,7 +177,7 @@ void delete_negative_conn_cache(const char *domain, const char *server) /** - * Add an entry to the failed conneciton cache + * Add an entry to the failed connection cache * * @param[in] domain * @param[in] server may be a FQDN or an IP addr in printable form -- cgit From f912ac962a0e0a79496178227e2a6614f700dde3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 5 Sep 2008 11:48:36 +0200 Subject: Do proper error handling if the socket is closed (This used to be commit e5a27773f97d7017cfa345799c6803fd82c8e797) --- source3/libsmb/async_smb.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 79a924b9db..a4c58aa5c7 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -845,6 +845,7 @@ static void cli_state_handler(struct event_context *event_ctx, { struct cli_state *cli = (struct cli_state *)p; struct cli_request *req; + NTSTATUS status; DEBUG(11, ("cli_state_handler called with flags %d\n", flags)); @@ -857,11 +858,13 @@ static void cli_state_handler(struct event_context *event_ctx, if (res == -1) { DEBUG(10, ("ioctl(FIONREAD) failed: %s\n", strerror(errno))); + status = map_nt_error_from_unix(errno); goto sock_error; } if (available == 0) { /* EOF */ + status = NT_STATUS_END_OF_FILE; goto sock_error; } @@ -870,6 +873,7 @@ static void cli_state_handler(struct event_context *event_ctx, if (new_size < old_size) { /* wrap */ + status = NT_STATUS_UNEXPECTED_IO_ERROR; goto sock_error; } @@ -877,6 +881,7 @@ static void cli_state_handler(struct event_context *event_ctx, new_size); if (tmp == NULL) { /* nomem */ + status = NT_STATUS_NO_MEMORY; goto sock_error; } cli->evt_inbuf = tmp; @@ -884,6 +889,7 @@ static void cli_state_handler(struct event_context *event_ctx, res = recv(cli->fd, cli->evt_inbuf + old_size, available, 0); if (res == -1) { DEBUG(10, ("recv failed: %s\n", strerror(errno))); + status = map_nt_error_from_unix(errno); goto sock_error; } @@ -930,6 +936,7 @@ static void cli_state_handler(struct event_context *event_ctx, to_send - req->sent, 0); if (sent < 0) { + status = map_nt_error_from_unix(errno); goto sock_error; } @@ -945,8 +952,7 @@ static void cli_state_handler(struct event_context *event_ctx, for (req = cli->outstanding_requests; req; req = req->next) { int i; for (i=0; inum_async; i++) { - req->async[i]->state = ASYNC_REQ_ERROR; - req->async[i]->status = map_nt_error_from_unix(errno); + async_req_error(req->async[i], status); } } TALLOC_FREE(cli->fd_event); -- cgit From 60255c3b2e557a233011ea02c761faee0dd3bc7f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 5 Sep 2008 11:47:48 +0200 Subject: Protect against a closed socket (This used to be commit d6cb5fdafbddb08d32b788674eff509cae9525c6) --- source3/libsmb/async_smb.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index a4c58aa5c7..435c8c1cb9 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -382,6 +382,11 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev, SMB_ASSERT(cli->chain_accumulator == NULL); + if (cli->fd == -1) { + DEBUG(10, ("cli->fd closed\n")); + return false; + } + if (cli->fd_event == NULL) { SMB_ASSERT(cli->outstanding_requests == NULL); cli->fd_event = event_add_fd(ev, cli, cli->fd, -- cgit From 7fafa9756a273e200fa251c1dea25e884729628c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 8 Sep 2008 22:39:16 +0200 Subject: Fix a memleak in cli_qfilename (only used in smbtorture) (This used to be commit 7e0cca19fec078c0b46807492a7a035f4fab612b) --- source3/libsmb/clirap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 61e2fb7f1a..3b4db2e26d 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -970,11 +970,16 @@ bool cli_qfilename(struct cli_state *cli, int fnum, char *name, size_t namelen) } if (!rdata || data_len < 4) { + SAFE_FREE(rparam); + SAFE_FREE(rdata); return False; } clistr_pull(cli, name, rdata+4, namelen, IVAL(rdata, 0), STR_UNICODE); + SAFE_FREE(rparam); + SAFE_FREE(rdata); + return True; } -- cgit From 6344b8ec27809950810024956161e041d6e83753 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Sep 2008 14:35:42 +0200 Subject: make smb_bytes_push_str public (This used to be commit d611f599b45ad9dad1027a16a0e8da7d4b96e608) --- source3/libsmb/clifile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c index a8b3440513..d3819af444 100644 --- a/source3/libsmb/clifile.c +++ b/source3/libsmb/clifile.c @@ -781,7 +781,7 @@ int cli_nt_create(struct cli_state *cli, const char *fname, uint32 DesiredAccess FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN, 0x0, 0x0); } -static uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str) +uint8_t *smb_bytes_push_str(uint8_t *buf, bool ucs2, const char *str) { size_t buflen = talloc_get_size(buf); char *converted; -- cgit From 6ba8c105c541636ee79e20eb7c5547ed6d8117e2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Sep 2008 14:37:17 +0200 Subject: Add utility function cli_in_chain() This gives a hint whether a function is called from within the middle of a chain. In particular the trans calls don't really like this. (This used to be commit 4252b32db5ef7483f2c5c52312b6e6dc68d1d687) --- source3/libsmb/async_smb.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 435c8c1cb9..c875acbe48 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -136,6 +136,21 @@ static int cli_request_destructor(struct cli_request *req) return 0; } +/** + * Are there already requests waiting in the chain_accumulator? + * @param[in] cli The cli_state we want to check + * @retval reply :-) + */ + +bool cli_in_chain(struct cli_state *cli) +{ + if (cli->chain_accumulator == NULL) { + return false; + } + + return (cli->chain_accumulator->num_async != 0); +} + /** * Is the SMB command able to hold an AND_X successor * @param[in] cmd The SMB command in question -- cgit From 2a934529942feb1b9411b5351e27cb0b5718ea34 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Sep 2008 14:39:45 +0200 Subject: Move setting the mid field in req->outbuf from _cork to _uncork The async trans calls need this, as for secondary trans calls they have to modify the MID from what cli_request_chain() gave us. (This used to be commit c85de4b7b5db8b54b8bf0f91acbd6d08d1b0bc9d) --- source3/libsmb/async_smb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index c875acbe48..eedc7d4481 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -437,7 +437,6 @@ bool cli_chain_cork(struct cli_state *cli, struct event_context *ev, cli_setup_packet_buf(cli, req->outbuf); req->mid = cli_new_mid(cli); - SSVAL(req->outbuf, smb_mid, req->mid); cli->chain_accumulator = req; @@ -468,6 +467,7 @@ void cli_chain_uncork(struct cli_state *cli) cli->chain_accumulator = NULL; + SSVAL(req->outbuf, smb_mid, req->mid); smb_setlen(req->outbuf, talloc_get_size(req->outbuf) - 4); cli_calculate_sign_mac(cli, req->outbuf); -- cgit From c81b5fd4408c91b0723c4a82c8d791773e5062d5 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Sep 2008 14:47:23 +0200 Subject: Add async trans/trans2/nttrans calls to libsmb Logic stolen from Samba4, naturally the specific implementation differs a bit. (This used to be commit 4b8bc5b03d35d563104791c0d8317d9886e4f032) --- source3/libsmb/clitrans.c | 701 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 701 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 4bb70f1a08..5b84e68fc4 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -701,3 +701,704 @@ bool cli_receive_nt_trans(struct cli_state *cli, client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } + +struct trans_recvblob { + uint8_t *data; + uint32_t max, total, received; +}; + +struct cli_trans_state { + struct cli_state *cli; + struct event_context *ev; + uint8_t cmd; + uint16_t mid; + const char *pipe_name; + uint16_t fid; + uint16_t function; + int flags; + uint16_t *setup; + uint8_t num_setup, max_setup; + uint8_t *param; + uint32_t num_param, param_sent; + uint8_t *data; + uint32_t num_data, data_sent; + + uint8_t num_rsetup; + uint16_t *rsetup; + struct trans_recvblob rparam; + struct trans_recvblob rdata; + + TALLOC_CTX *secondary_request_ctx; +}; + +static void cli_trans_recv_helper(struct async_req *req); + +static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, + struct cli_trans_state *state) +{ + TALLOC_CTX *frame; + struct async_req *result = NULL; + struct cli_request *cli_req; + uint8_t wct; + uint16_t *vwv; + uint8_t *bytes = NULL; + uint16_t param_offset; + uint16_t this_param = 0; + uint16_t this_data = 0; + uint32_t useable_space; + uint8_t cmd; + + frame = talloc_stackframe(); + + cmd = state->cmd; + + if ((state->param_sent != 0) || (state->data_sent != 0)) { + /* The secondary commands are one after the primary ones */ + cmd += 1; + } + + param_offset = smb_size - 4; + + switch (cmd) { + case SMBtrans: + bytes = TALLOC_ZERO_P(talloc_tos(), uint8_t); /* padding */ + if (bytes == NULL) { + goto fail; + } + bytes = smb_bytes_push_str( + bytes, (state->cli->capabilities & CAP_UNICODE) != 0, + state->pipe_name); + if (bytes == NULL) { + goto fail; + } + wct = 14 + state->num_setup; + param_offset += talloc_get_size(bytes); + break; + case SMBtrans2: + bytes = TALLOC_ARRAY(talloc_tos(), uint8_t, 3); /* padding */ + if (bytes == NULL) { + goto fail; + } + bytes[0] = 0; + bytes[1] = 'D'; /* Copy this from "old" 3.0 behaviour */ + bytes[2] = ' '; + wct = 14 + state->num_setup; + param_offset += talloc_get_size(bytes); + break; + case SMBtranss: + wct = 8; + break; + case SMBtranss2: + wct = 9; + break; + case SMBnttrans: + wct = 19 + state->num_setup; + break; + case SMBnttranss: + wct = 18; + break; + default: + goto fail; + } + + useable_space = state->cli->max_xmit - smb_size - sizeof(uint16_t)*wct; + + if (state->param_sent < state->num_param) { + this_param = MIN(state->num_param - state->param_sent, + useable_space); + } + + if (state->data_sent < state->num_data) { + this_data = MIN(state->num_data - state->data_sent, + useable_space - this_param); + } + + vwv = TALLOC_ARRAY(talloc_tos(), uint16_t, wct); + if (vwv == NULL) { + goto fail; + } + param_offset += wct * sizeof(uint16_t); + + DEBUG(10, ("num_setup=%u, max_setup=%u, " + "param_total=%u, this_param=%u, max_param=%u, " + "data_total=%u, this_data=%u, max_data=%u, " + "param_offset=%u, param_disp=%u, data_disp=%u\n", + (unsigned)state->num_setup, (unsigned)state->max_setup, + (unsigned)state->num_param, (unsigned)this_param, + (unsigned)state->rparam.max, + (unsigned)state->num_data, (unsigned)this_data, + (unsigned)state->rdata.max, + (unsigned)param_offset, + (unsigned)state->param_sent, (unsigned)state->data_sent)); + + switch (cmd) { + case SMBtrans: + case SMBtrans2: + SSVAL(vwv + 0, 0, state->num_param); + SSVAL(vwv + 1, 0, state->num_data); + SSVAL(vwv + 2, 0, state->rparam.max); + SSVAL(vwv + 3, 0, state->rdata.max); + SCVAL(vwv + 4, 0, state->max_setup); + SCVAL(vwv + 4, 1, 0); /* reserved */ + SSVAL(vwv + 5, 0, state->flags); + SIVAL(vwv + 6, 0, 0); /* timeout */ + SSVAL(vwv + 8, 0, 0); /* reserved */ + SSVAL(vwv + 9, 0, this_param); + SSVAL(vwv +10, 0, param_offset); + SSVAL(vwv +11, 0, this_data); + SSVAL(vwv +12, 0, param_offset + this_param); + SCVAL(vwv +13, 0, state->num_setup); + SCVAL(vwv +13, 1, 0); /* reserved */ + memcpy(vwv + 14, state->setup, + sizeof(uint16_t) * state->num_setup); + break; + case SMBtranss: + case SMBtranss2: + SSVAL(vwv + 0, 0, state->num_param); + SSVAL(vwv + 1, 0, state->num_data); + SSVAL(vwv + 2, 0, this_param); + SSVAL(vwv + 3, 0, param_offset); + SSVAL(vwv + 4, 0, state->param_sent); + SSVAL(vwv + 5, 0, this_data); + SSVAL(vwv + 6, 0, param_offset + this_param); + SSVAL(vwv + 7, 0, state->data_sent); + if (cmd == SMBtranss2) { + SSVAL(vwv + 8, 0, state->fid); + } + break; + case SMBnttrans: + SCVAL(vwv, 0, state->max_setup); + SSVAL(vwv, 1, 0); /* reserved */ + SIVAL(vwv, 3, state->num_param); + SIVAL(vwv, 7, state->num_data); + SIVAL(vwv, 11, state->rparam.max); + SIVAL(vwv, 15, state->rdata.max); + SIVAL(vwv, 19, this_param); + SIVAL(vwv, 23, param_offset); + SIVAL(vwv, 27, this_data); + SIVAL(vwv, 31, param_offset + this_param); + SCVAL(vwv, 35, state->num_setup); + SSVAL(vwv, 36, state->function); + memcpy(vwv + 19, state->setup, + sizeof(uint16_t) * state->num_setup); + break; + case SMBnttranss: + SSVAL(vwv, 0, 0); /* reserved */ + SCVAL(vwv, 2, 0); /* reserved */ + SIVAL(vwv, 3, state->num_param); + SIVAL(vwv, 7, state->num_data); + SIVAL(vwv, 11, this_param); + SIVAL(vwv, 15, param_offset); + SIVAL(vwv, 19, state->param_sent); + SIVAL(vwv, 23, this_data); + SIVAL(vwv, 27, param_offset + this_param); + SIVAL(vwv, 31, state->data_sent); + SCVAL(vwv, 35, 0); /* reserved */ + break; + } + + bytes = (uint8_t *)talloc_append_blob( + talloc_tos(), bytes, + data_blob_const(state->param + state->param_sent, this_param)); + if (bytes == NULL) { + goto fail; + } + state->param_sent += this_param; + + bytes = (uint8_t *)talloc_append_blob( + talloc_tos(), bytes, + data_blob_const(state->data + state->data_sent, this_data)); + if (bytes == NULL) { + goto fail; + } + state->data_sent += this_data; + + if ((cmd == SMBtrans) || (cmd == SMBtrans2) || (cmd == SMBnttrans)) { + /* + * Primary request, retrieve our mid + */ + result = cli_request_send(mem_ctx, state->ev, state->cli, + cmd, 0, wct, vwv, + talloc_get_size(bytes), bytes); + if (result == NULL) { + goto fail; + } + cli_req = talloc_get_type_abort(result->private_data, + struct cli_request); + state->mid = cli_req->mid; + } else { + uint16_t num_bytes = talloc_get_size(bytes); + /* + * Secondary request, we have to fix up the mid. Thus we do + * the chain_cork/chain/uncork ourselves. + */ + if (!cli_chain_cork(state->cli, state->ev, + wct * sizeof(uint16_t) + num_bytes + 3)) { + goto fail; + } + result = cli_request_send(mem_ctx, state->ev, state->cli, + cmd, 0, wct, vwv, num_bytes, bytes); + if (result == NULL) { + goto fail; + } + cli_req = talloc_get_type_abort(result->private_data, + struct cli_request); + cli_req->recv_helper.fn = cli_trans_recv_helper; + cli_req->recv_helper.priv = state; + cli_req->mid = state->mid; + client_set_trans_sign_state_off(state->cli, state->mid); + cli_chain_uncork(state->cli); + } + + client_set_trans_sign_state_on(state->cli, state->mid); + + fail: + TALLOC_FREE(frame); + return result; +} + +static void cli_trans_ship_rest(struct async_req *req, + struct cli_trans_state *state) +{ + state->secondary_request_ctx = talloc_new(state); + if (state->secondary_request_ctx == NULL) { + async_req_error(req, NT_STATUS_NO_MEMORY); + return; + } + + while ((state->param_sent < state->num_param) + || (state->data_sent < state->num_data)) { + struct async_req *cli_req; + + cli_req = cli_ship_trans(state->secondary_request_ctx, state); + if (cli_req == NULL) { + async_req_error(req, NT_STATUS_NO_MEMORY); + return; + } + } +} + +static bool cli_trans_oob(uint32_t bufsize, uint32_t offset, uint32_t length) +{ + if ((offset + length < offset) || (offset + length < length)) { + /* wrap */ + return true; + } + if ((offset > bufsize) || (offset + length > bufsize)) { + /* overflow */ + return true; + } + return false; +} + +static NTSTATUS cli_pull_trans(struct async_req *req, + struct cli_request *cli_req, + uint8_t smb_cmd, bool expect_first_reply, + uint8_t *pnum_setup, uint16_t **psetup, + uint32_t *ptotal_param, uint32_t *pnum_param, + uint32_t *pparam_disp, uint8_t **pparam, + uint32_t *ptotal_data, uint32_t *pnum_data, + uint32_t *pdata_disp, uint8_t **pdata) +{ + uint32_t param_ofs, data_ofs; + uint8_t wct; + uint16_t *vwv; + uint16_t num_bytes; + uint8_t *bytes; + NTSTATUS status; + + status = cli_pull_reply(req, &wct, &vwv, &num_bytes, &bytes); + + /* + * We can receive something like STATUS_MORE_ENTRIES, so don't use + * !NT_STATUS_IS_OK(status) here. + */ + + if (NT_STATUS_IS_ERR(status)) { + return status; + } + + if (expect_first_reply) { + if ((wct != 0) || (num_bytes != 0)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + return NT_STATUS_OK; + } + + switch (smb_cmd) { + case SMBtrans: + case SMBtrans2: + if (wct < 10) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + *ptotal_param = SVAL(vwv + 0, 0); + *ptotal_data = SVAL(vwv + 1, 0); + *pnum_param = SVAL(vwv + 3, 0); + param_ofs = SVAL(vwv + 4, 0); + *pparam_disp = SVAL(vwv + 5, 0); + *pnum_data = SVAL(vwv + 6, 0); + data_ofs = SVAL(vwv + 7, 0); + *pdata_disp = SVAL(vwv + 8, 0); + *pnum_setup = CVAL(vwv + 9, 0); + if (wct < 10 + (*pnum_setup)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + *psetup = vwv + 10; + + break; + case SMBnttrans: + if (wct < 18) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + *ptotal_param = IVAL(vwv, 3); + *ptotal_data = IVAL(vwv, 7); + *pnum_param = IVAL(vwv, 11); + param_ofs = IVAL(vwv, 15); + *pparam_disp = IVAL(vwv, 19); + *pnum_data = IVAL(vwv, 23); + data_ofs = IVAL(vwv, 27); + *pdata_disp = IVAL(vwv, 31); + *pnum_setup = CVAL(vwv, 35); + *psetup = vwv + 18; + break; + + default: + return NT_STATUS_INTERNAL_ERROR; + } + + /* + * Check for buffer overflows. data_ofs needs to be checked against + * the incoming buffer length, data_disp against the total + * length. Likewise for param_ofs/param_disp. + */ + + if (cli_trans_oob(smb_len(cli_req->inbuf), param_ofs, *pnum_param) + || cli_trans_oob(*ptotal_param, *pparam_disp, *pnum_param) + || cli_trans_oob(smb_len(cli_req->inbuf), data_ofs, *pnum_data) + || cli_trans_oob(*ptotal_data, *pdata_disp, *pnum_data)) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + *pparam = (uint8_t *)cli_req->inbuf + 4 + param_ofs; + *pdata = (uint8_t *)cli_req->inbuf + 4 + data_ofs; + + return NT_STATUS_OK; +} + +static NTSTATUS cli_trans_pull_blob(TALLOC_CTX *mem_ctx, + struct trans_recvblob *blob, + uint32_t total, uint32_t thistime, + uint8_t *buf, uint32_t displacement) +{ + if (blob->data == NULL) { + if (total > blob->max) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + blob->total = total; + blob->data = TALLOC_ARRAY(mem_ctx, uint8_t, total); + if (blob->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + } + + if (total > blob->total) { + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (thistime) { + memcpy(blob->data + displacement, buf, thistime); + blob->received += thistime; + } + + return NT_STATUS_OK; +} + +static void cli_trans_recv_helper(struct async_req *req) +{ + struct cli_request *cli_req = talloc_get_type_abort( + req->private_data, struct cli_request); + struct cli_trans_state *state = talloc_get_type_abort( + cli_req->recv_helper.priv, struct cli_trans_state); + uint8_t num_setup; + uint16_t *setup; + uint32_t total_param, num_param, param_disp; + uint32_t total_data, num_data, data_disp; + uint8_t *param, *data; + bool sent_all; + NTSTATUS status; + + sent_all = (state->param_sent == state->num_param) + && (state->data_sent == state->num_data); + + status = cli_pull_trans( + req, cli_req, state->cmd, !sent_all, &num_setup, &setup, + &total_param, &num_param, ¶m_disp, ¶m, + &total_data, &num_data, &data_disp, &data); + + /* + * We can receive something like STATUS_MORE_ENTRIES, so don't use + * !NT_STATUS_IS_OK(status) here. + */ + + if (NT_STATUS_IS_ERR(status)) { + async_req_error(req, status); + return; + } + + if (!sent_all) { + cli_trans_ship_rest(req, state); + return; + } + + /* + * We've just received a real response. This means that we don't need + * the secondary cli_request structures anymore, they have all been + * shipped to the server. + */ + TALLOC_FREE(state->secondary_request_ctx); + + if (num_setup != 0) { + TALLOC_FREE(state->rsetup); + state->rsetup = (uint16_t *)TALLOC_MEMDUP( + state, setup, sizeof(uint16_t) * num_setup); + if (state->rsetup == NULL) { + async_req_error(req, NT_STATUS_NO_MEMORY); + return; + } + } + + status = cli_trans_pull_blob( + state, &state->rparam, total_param, num_param, param, + param_disp); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("Pulling params failed: %s\n", nt_errstr(status))); + async_req_error(req, status); + return; + } + + status = cli_trans_pull_blob( + state, &state->rdata, total_data, num_data, data, + data_disp); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("Pulling data failed: %s\n", nt_errstr(status))); + async_req_error(req, status); + return; + } + + if ((state->rparam.total == state->rparam.received) + && (state->rdata.total == state->rdata.received)) { + client_set_trans_sign_state_off(state->cli, state->mid); + async_req_done(req); + } +} + +struct async_req *cli_trans_send( + TALLOC_CTX *mem_ctx, struct event_context *ev, + struct cli_state *cli, uint8_t trans_cmd, + const char *pipe_name, uint16_t fid, uint16_t function, int flags, + uint16_t *setup, uint8_t num_setup, uint8_t max_setup, + uint8_t *param, uint32_t num_param, uint32_t max_param, + uint8_t *data, uint32_t num_data, uint32_t max_data) +{ + struct async_req *req; + struct cli_request *cli_req; + struct cli_trans_state *state; + + /* + * We can't use it in a chained request chain, we'd get the offset + * calculations wrong. + */ + + if (cli_in_chain(cli)) { + return NULL; + } + + if ((trans_cmd == SMBtrans) || (trans_cmd == SMBtrans2)) { + if ((num_param > 0xffff) || (max_param > 0xffff) + || (num_data > 0xffff) || (max_data > 0xffff)) { + DEBUG(3, ("Attempt to send invalid trans2 request " + "(setup %u, params %u/%u, data %u/%u)\n", + (unsigned)num_setup, + (unsigned)num_param, (unsigned)max_param, + (unsigned)num_data, (unsigned)max_data)); + return NULL; + } + } + + state = talloc(mem_ctx, struct cli_trans_state); + if (state == NULL) { + goto nomem; + } + + state->cli = cli; + state->ev = ev; + state->cmd = trans_cmd; + state->num_rsetup = 0; + state->rsetup = NULL; + ZERO_STRUCT(state->rparam); + ZERO_STRUCT(state->rdata); + state->secondary_request_ctx = NULL; + + if (trans_cmd == SMBtrans) { + state->pipe_name = talloc_strdup(state, pipe_name); + if (state->pipe_name == NULL) { + goto nomem; + } + } + if (trans_cmd == SMBtrans2) { + state->fid = fid; + } + if (trans_cmd == SMBnttrans) { + state->function = function; + } + + state->flags = flags; + + if (setup != NULL) { + state->setup = (uint16_t *)TALLOC_MEMDUP( + state, setup, sizeof(*setup) * num_setup); + if (state->setup == NULL) { + goto nomem; + } + state->num_setup = num_setup; + } else { + state->setup = NULL; + state->num_setup = 0; + } + + state->max_setup = max_setup; + + if (param != NULL) { + state->param = (uint8_t *)TALLOC_MEMDUP(state, param, + num_param); + if (state->param == NULL) { + goto nomem; + } + state->num_param = num_param; + } else { + state->param = NULL; + state->num_param = 0; + } + + state->param_sent = 0; + state->rparam.max = max_param; + + if (data != NULL) { + state->data = (uint8_t *)TALLOC_MEMDUP(state, data, num_data); + if (state->data == NULL) { + goto nomem; + } + state->num_data = num_data; + } else { + state->data = NULL; + state->num_data = 0; + } + + state->data_sent = 0; + state->rdata.max = max_data; + + req = cli_ship_trans(state, state); + if (req == NULL) { + goto nomem; + } + + cli_req = talloc_get_type_abort(req->private_data, struct cli_request); + cli_req->recv_helper.fn = cli_trans_recv_helper; + cli_req->recv_helper.priv = state; + + return req; + + nomem: + TALLOC_FREE(state); + return NULL; +} + +NTSTATUS cli_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx, + uint16_t **setup, uint8_t *num_setup, + uint8_t **param, uint32_t *num_param, + uint8_t **data, uint32_t *num_data) +{ + struct cli_request *cli_req = talloc_get_type_abort( + req->private_data, struct cli_request); + struct cli_trans_state *state = talloc_get_type_abort( + cli_req->recv_helper.priv, struct cli_trans_state); + + SMB_ASSERT(req->state >= ASYNC_REQ_DONE); + if (req->state == ASYNC_REQ_ERROR) { + return req->status; + } + + if (setup != NULL) { + *setup = talloc_move(mem_ctx, &state->rsetup); + *num_setup = state->num_rsetup; + } else { + TALLOC_FREE(state->rsetup); + } + + if (param != NULL) { + *param = talloc_move(mem_ctx, &state->rparam.data); + *num_param = state->rparam.total; + } else { + TALLOC_FREE(state->rparam.data); + } + + if (data != NULL) { + *data = talloc_move(mem_ctx, &state->rdata.data); + *num_data = state->rdata.total; + } else { + TALLOC_FREE(state->rdata.data); + } + + return NT_STATUS_OK; +} + +NTSTATUS cli_trans(TALLOC_CTX *mem_ctx, struct cli_state *cli, + uint8_t trans_cmd, + const char *pipe_name, uint16_t fid, uint16_t function, + int flags, + uint16_t *setup, uint8_t num_setup, uint8_t max_setup, + uint8_t *param, uint32_t num_param, uint32_t max_param, + uint8_t *data, uint32_t num_data, uint32_t max_data, + uint16_t **rsetup, uint8_t *num_rsetup, + uint8_t **rparam, uint32_t *num_rparam, + uint8_t **rdata, uint32_t *num_rdata) +{ + TALLOC_CTX *frame = talloc_stackframe(); + struct event_context *ev; + struct async_req *req; + NTSTATUS status = NT_STATUS_NO_MEMORY; + + if (cli->fd_event != NULL) { + /* + * Can't use sync call while an async call is in flight + */ + cli_set_error(cli, NT_STATUS_INVALID_PARAMETER); + goto fail; + } + + ev = event_context_init(frame); + if (ev == NULL) { + goto fail; + } + + req = cli_trans_send(frame, ev, cli, trans_cmd, + pipe_name, fid, function, flags, + setup, num_setup, max_setup, + param, num_param, max_param, + data, num_data, max_data); + if (req == NULL) { + goto fail; + } + + while (req->state < ASYNC_REQ_DONE) { + event_loop_once(ev); + } + + status = cli_trans_recv(req, mem_ctx, rsetup, num_rsetup, + rparam, num_rparam, rdata, num_rdata); + fail: + TALLOC_FREE(frame); + return status; +} -- cgit From bb2a7183b91706db80d096504c9d4668c477d36c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Sep 2008 15:03:34 +0200 Subject: Convert cli_qfileinfo to the async trans call (This used to be commit ddc5e77b619db7c2369b3bf72b60360051797087) --- source3/libsmb/clirap.c | 40 +++++++++++++++++++--------------------- 1 file changed, 19 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 3b4db2e26d..631bc3f36b 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -998,8 +998,9 @@ bool cli_qfileinfo(struct cli_state *cli, int fnum, unsigned int data_len = 0; unsigned int param_len = 0; uint16 setup = TRANSACT2_QFILEINFO; - char param[4]; - char *rparam=NULL, *rdata=NULL; + uint8_t param[4]; + uint8_t *rparam=NULL, *rdata=NULL; + NTSTATUS status; /* if its a win95 server then fail this - win95 totally screws it up */ @@ -1010,20 +1011,17 @@ bool cli_qfileinfo(struct cli_state *cli, int fnum, SSVAL(param, 0, fnum); SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); - if (!cli_send_trans(cli, SMBtrans2, - NULL, /* name */ - -1, 0, /* fid, flags */ - &setup, 1, 0, /* setup, length, max */ - param, param_len, 2, /* param, length, max */ - NULL, data_len, cli->max_xmit /* data, length, max */ - )) { - return False; - } + status = cli_trans(talloc_tos(), cli, SMBtrans2, + NULL, -1, 0, 0, /* name, fid, function, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 2, /* param, length, max */ + NULL, 0, MIN(cli->max_xmit, 0xffff), /* data, length, max */ + NULL, NULL, /* rsetup, length */ + &rparam, ¶m_len, /* rparam, length */ + &rdata, &data_len); - if (!cli_receive_trans(cli, SMBtrans2, - &rparam, ¶m_len, - &rdata, &data_len)) { - return False; + if (!NT_STATUS_IS_OK(status)) { + return false; } if (!rdata || data_len < 68) { @@ -1031,16 +1029,16 @@ bool cli_qfileinfo(struct cli_state *cli, int fnum, } if (create_time) { - *create_time = interpret_long_date(rdata+0); + *create_time = interpret_long_date((char *)rdata+0); } if (access_time) { - *access_time = interpret_long_date(rdata+8); + *access_time = interpret_long_date((char *)rdata+8); } if (write_time) { - *write_time = interpret_long_date(rdata+16); + *write_time = interpret_long_date((char *)rdata+16); } if (change_time) { - *change_time = interpret_long_date(rdata+24); + *change_time = interpret_long_date((char *)rdata+24); } if (mode) { *mode = SVAL(rdata, 32); @@ -1052,8 +1050,8 @@ bool cli_qfileinfo(struct cli_state *cli, int fnum, *ino = IVAL(rdata, 64); } - SAFE_FREE(rdata); - SAFE_FREE(rparam); + TALLOC_FREE(rdata); + TALLOC_FREE(rparam); return True; } -- cgit From 7965249bd613eb41eeca24ba8271189e2f90257c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Sep 2008 15:03:51 +0200 Subject: Convert cli_query_secdesc to the async trans call (This used to be commit ab41017896e08d32c8a87bf172654ff2db6b6f1a) --- source3/libsmb/clisecdesc.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clisecdesc.c b/source3/libsmb/clisecdesc.c index adc6fba9af..f0b786c899 100644 --- a/source3/libsmb/clisecdesc.c +++ b/source3/libsmb/clisecdesc.c @@ -25,8 +25,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, TALLOC_CTX *mem_ctx) { - char param[8]; - char *rparam=NULL, *rdata=NULL; + uint8_t param[8]; + uint8_t *rparam=NULL, *rdata=NULL; unsigned int rparam_count=0, rdata_count=0; SEC_DESC *psd = NULL; NTSTATUS status; @@ -34,27 +34,22 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, SIVAL(param, 0, fnum); SIVAL(param, 4, 0x7); - if (!cli_send_nt_trans(cli, - NT_TRANSACT_QUERY_SECURITY_DESC, - 0, - NULL, 0, 0, - param, 8, 4, - NULL, 0, 0x10000)) { - DEBUG(1,("Failed to send NT_TRANSACT_QUERY_SECURITY_DESC\n")); - goto cleanup; - } - + status = cli_trans(talloc_tos(), cli, SMBnttrans, + NULL, -1, /* name, fid */ + NT_TRANSACT_QUERY_SECURITY_DESC, 0, /* function, flags */ + NULL, 0, 0, /* setup, length, max */ + param, 8, 4, /* param, length, max */ + NULL, 0, 0x10000, /* data, length, max */ + NULL, NULL, /* rsetup, length */ + &rparam, &rparam_count, + &rdata, &rdata_count); - if (!cli_receive_nt_trans(cli, - &rparam, &rparam_count, - &rdata, &rdata_count)) { - DEBUG(1,("Failed to recv NT_TRANSACT_QUERY_SECURITY_DESC\n")); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(1, ("NT_TRANSACT_QUERY_SECURITY_DESC failed: %s\n", + nt_errstr(status))); goto cleanup; } - if (cli_is_error(cli)) - goto cleanup; - status = unmarshall_sec_desc(mem_ctx, (uint8 *)rdata, rdata_count, &psd); @@ -66,8 +61,8 @@ SEC_DESC *cli_query_secdesc(struct cli_state *cli, int fnum, cleanup: - SAFE_FREE(rparam); - SAFE_FREE(rdata); + TALLOC_FREE(rparam); + TALLOC_FREE(rdata); return psd; } -- cgit From a1d0f59f4604c4d324c1b082fba43ffa11ea8f97 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 9 Sep 2008 22:13:39 +0200 Subject: Fix make test on sparc and possibly also on AIX (This used to be commit 5721205bff539ed5f8592a86168679ec5a9c368e) --- source3/libsmb/clirap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c index 631bc3f36b..eee8636fdd 100644 --- a/source3/libsmb/clirap.c +++ b/source3/libsmb/clirap.c @@ -997,7 +997,7 @@ bool cli_qfileinfo(struct cli_state *cli, int fnum, { unsigned int data_len = 0; unsigned int param_len = 0; - uint16 setup = TRANSACT2_QFILEINFO; + uint16 setup; uint8_t param[4]; uint8_t *rparam=NULL, *rdata=NULL; NTSTATUS status; @@ -1011,6 +1011,8 @@ bool cli_qfileinfo(struct cli_state *cli, int fnum, SSVAL(param, 0, fnum); SSVAL(param, 2, SMB_QUERY_FILE_ALL_INFO); + SSVAL(&setup, 0, TRANSACT2_QFILEINFO); + status = cli_trans(talloc_tos(), cli, SMBtrans2, NULL, -1, 0, 0, /* name, fid, function, flags */ &setup, 1, 0, /* setup, length, max */ -- cgit From 40b93006c1ea1d6527d669a285a118ce86432d58 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 10 Sep 2008 11:51:02 +0200 Subject: Fix some bogus compiler warnings (This used to be commit 84ed752d9f17b2279bd60f534ce7c02b267a40b2) --- source3/libsmb/clitrans.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 5b84e68fc4..c929f0b7a9 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -1119,11 +1119,16 @@ static void cli_trans_recv_helper(struct async_req *req) req->private_data, struct cli_request); struct cli_trans_state *state = talloc_get_type_abort( cli_req->recv_helper.priv, struct cli_trans_state); - uint8_t num_setup; - uint16_t *setup; - uint32_t total_param, num_param, param_disp; - uint32_t total_data, num_data, data_disp; - uint8_t *param, *data; + uint8_t num_setup = 0; + uint16_t *setup = NULL; + uint32_t total_param = 0; + uint32_t num_param = 0; + uint32_t param_disp = 0; + uint32_t total_data = 0; + uint32_t num_data = 0; + uint32_t data_disp = 0; + uint8_t *param = NULL; + uint8_t *data = NULL; bool sent_all; NTSTATUS status; -- cgit From 3978317af0c265d317258f5f6a04436100437a8c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 Sep 2008 10:18:02 -0700 Subject: Fix blocker bug 5745 kerberos authentication with (lib)smbclient is broken. Jeremy. (This used to be commit a59bd0e4854117a8646f4d388a0f7285362d5ba2) --- source3/libsmb/clikrb5.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index f940081072..b8afb57977 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -749,9 +749,21 @@ static krb5_error_code ads_krb5_mk_req(krb5_context context, ccache, &in_data ); if (retval) { - DEBUG( 1, ("ads_krb5_get_fwd_ticket failed (%s)\n", + DEBUG( 3, ("ads_krb5_get_fwd_ticket failed (%s)\n", error_message( retval ) ) ); - goto cleanup_creds; + + /* + * This is not fatal. Delete the *auth_context and continue + * with krb5_mk_req_extended to get a non-forwardable ticket. + */ + + if (in_data.data) { + free( in_data.data ); + in_data.data = NULL; + in_data.length = 0; + } + krb5_auth_con_free(context, *auth_context); + *auth_context = NULL; } } #endif -- cgit From 65ae60489dc416c75112d576e94d84c26ec54875 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Sep 2008 16:20:59 -0700 Subject: Fix bug #5751 cannot show ACLs on DFS reported by SATOH Fumiyasu . Fix for smbclient and libsmbclient. Jeremy. (This used to be commit dbd5d6b145528527a614c6207d81a6c955e57461) --- source3/libsmb/libsmb_xattr.c | 89 ++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 34 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_xattr.c b/source3/libsmb/libsmb_xattr.c index 2d8389c770..f1b3d1415e 100644 --- a/source3/libsmb/libsmb_xattr.c +++ b/source3/libsmb/libsmb_xattr.c @@ -747,7 +747,7 @@ cacl_get(SMBCCTX *context, SMB_OFF_T size = 0; uint16 mode = 0; SMB_INO_T ino = 0; - struct cli_state *cli = srv->cli; + struct cli_state *cli = srv->cli; struct { const char * create_time_attr; const char * access_time_attr; @@ -884,30 +884,41 @@ cacl_get(SMBCCTX *context, * attributes have been requested... */ if (ipc_cli && (all || some_nt || all_nt_acls)) { + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + /* Point to the portion after "system.nt_sec_desc." */ name += 19; /* if (all) this will be invalid but unused */ - + + if (!cli_resolve_path(ctx, "", cli, filename, + &targetcli, &targetpath)) { + DEBUG(5, ("cacl_get Could not resolve %s\n", + filename)); + errno = ENOENT; + return -1; + } + /* ... then obtain any NT attributes which were requested */ - fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - + fnum = cli_nt_create(targetcli, targetpath, CREATE_ACCESS_READ); + if (fnum == -1) { - DEBUG(5, ("cacl_get failed to open %s: %s\n", - filename, cli_errstr(cli))); - errno = 0; - return -1; - } - - sd = cli_query_secdesc(cli, fnum, ctx); - + DEBUG(5, ("cacl_get failed to open %s: %s\n", + targetpath, cli_errstr(targetcli))); + errno = 0; + return -1; + } + + sd = cli_query_secdesc(targetcli, fnum, ctx); + if (!sd) { DEBUG(5, ("cacl_get Failed to query old descriptor\n")); errno = 0; return -1; } - - cli_close(cli, fnum); - + + cli_close(targetcli, fnum); + if (! exclude_nt_revision) { if (all || all_nt) { if (determine_size) { @@ -1504,7 +1515,9 @@ cacl_set(TALLOC_CTX *ctx, int ret = 0; char *p; bool numeric = True; - + char *targetpath = NULL; + struct cli_state *targetcli = NULL; + /* the_acl will be null for REMOVE_ALL operations */ if (the_acl) { numeric = ((p = strchr(the_acl, ':')) != NULL && @@ -1533,39 +1546,46 @@ cacl_set(TALLOC_CTX *ctx, errno = EINVAL; return -1; } - + + if (!cli_resolve_path(ctx, "", cli, filename, + &targetcli, &targetpath)) { + DEBUG(5,("cacl_set: Could not resolve %s\n", filename)); + errno = ENOENT; + return -1; + } + /* The desired access below is the only one I could find that works with NT4, W2KP and Samba */ - - fnum = cli_nt_create(cli, filename, CREATE_ACCESS_READ); - + + fnum = cli_nt_create(targetcli, targetpath, CREATE_ACCESS_READ); + if (fnum == -1) { DEBUG(5, ("cacl_set failed to open %s: %s\n", - filename, cli_errstr(cli))); + targetpath, cli_errstr(targetcli))); errno = 0; return -1; } - - old = cli_query_secdesc(cli, fnum, ctx); - + + old = cli_query_secdesc(targetcli, fnum, ctx); + if (!old) { DEBUG(5, ("cacl_set Failed to query old descriptor\n")); errno = 0; return -1; } - - cli_close(cli, fnum); - + + cli_close(targetcli, fnum); + switch (mode) { case SMBC_XATTR_MODE_REMOVE_ALL: old->dacl->num_aces = 0; dacl = old->dacl; break; - + case SMBC_XATTR_MODE_REMOVE: for (i=0;sd->dacl && idacl->num_aces;i++) { bool found = False; - + for (j=0;old->dacl && jdacl->num_aces;j++) { if (sec_ace_equal(&sd->dacl->aces[i], &old->dacl->aces[j])) { @@ -1643,25 +1663,26 @@ cacl_set(TALLOC_CTX *ctx, sd = make_sec_desc(ctx, old->revision, SEC_DESC_SELF_RELATIVE, owner_sid, group_sid, NULL, dacl, &sd_size); - fnum = cli_nt_create(cli, filename, + fnum = cli_nt_create(targetcli, targetpath, WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS); if (fnum == -1) { DEBUG(5, ("cacl_set failed to open %s: %s\n", - filename, cli_errstr(cli))); + targetpath, cli_errstr(targetcli))); errno = 0; return -1; } - if (!cli_set_secdesc(cli, fnum, sd)) { - DEBUG(5, ("ERROR: secdesc set failed: %s\n", cli_errstr(cli))); + if (!cli_set_secdesc(targetcli, fnum, sd)) { + DEBUG(5, ("ERROR: secdesc set failed: %s\n", + cli_errstr(targetcli))); ret = -1; } /* Clean up */ failed: - cli_close(cli, fnum); + cli_close(targetcli, fnum); if (err != 0) { errno = err; -- cgit From 9c28ca2b6c967a2b2a073477d4d8070ce138b87e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 11 Sep 2008 18:45:26 +0200 Subject: fix nonempty blank lines (This used to be commit 3111428dd42abf856f646f2a3aa2ee78ff3d3702) --- source3/libsmb/libsmb_server.c | 196 ++++++++++++++++++++--------------------- 1 file changed, 98 insertions(+), 98 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/libsmb_server.c b/source3/libsmb/libsmb_server.c index 0a3287bc82..aeec255350 100644 --- a/source3/libsmb/libsmb_server.c +++ b/source3/libsmb/libsmb_server.c @@ -7,17 +7,17 @@ Copyright (C) Tom Jansen (Ninja ISD) 2002 Copyright (C) Derrell Lipman 2003-2008 Copyright (C) Jeremy Allison 2007, 2008 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -40,7 +40,7 @@ SMBC_check_server(SMBCCTX * context, { socklen_t size; struct sockaddr addr; - + size = sizeof(addr); return (getpeername(server->cli->fd, &addr, &size) == -1); } @@ -56,12 +56,12 @@ SMBC_remove_unused_server(SMBCCTX * context, SMBCSRV * srv) { SMBCFILE * file; - + /* are we being fooled ? */ if (!context || !context->internal->initialized || !srv) { return 1; } - + /* Check all open files/directories for a relation with this server */ for (file = context->internal->files; file; file = file->next) { if (file->srv == srv) { @@ -72,16 +72,16 @@ SMBC_remove_unused_server(SMBCCTX * context, return 1; } } - + DLIST_REMOVE(context->internal->servers, srv); - + cli_shutdown(srv->cli); srv->cli = NULL; - + DEBUG(3, ("smbc_remove_usused_server: %p removed.\n", srv)); - + smbc_getFunctionRemoveCachedServer(context)(context, srv); - + SAFE_FREE(srv); return 0; } @@ -102,11 +102,11 @@ SMBC_call_auth_fn(TALLOC_CTX *ctx, fstring username; fstring password; smbc_get_auth_data_with_context_fn auth_with_context_fn; - + strlcpy(workgroup, *pp_workgroup, sizeof(workgroup)); strlcpy(username, *pp_username, sizeof(username)); strlcpy(password, *pp_password, sizeof(password)); - + /* See if there's an authentication with context function provided */ auth_with_context_fn = smbc_getFunctionAuthDataWithContext(context); if (auth_with_context_fn) @@ -124,11 +124,11 @@ SMBC_call_auth_fn(TALLOC_CTX *ctx, username, sizeof(username), password, sizeof(password)); } - + TALLOC_FREE(*pp_workgroup); TALLOC_FREE(*pp_username); TALLOC_FREE(*pp_password); - + *pp_workgroup = talloc_strdup(ctx, workgroup); *pp_username = talloc_strdup(ctx, username); *pp_password = talloc_strdup(ctx, password); @@ -157,23 +157,23 @@ SMBC_find_server(TALLOC_CTX *ctx, { SMBCSRV *srv; int auth_called = 0; - + if (!pp_workgroup || !pp_username || !pp_password) { return NULL; } - + check_server_cache: - + srv = smbc_getFunctionGetCachedServer(context)(context, server, share, *pp_workgroup, *pp_username); - + if (!auth_called && !srv && (!*pp_username || !(*pp_username)[0] || !*pp_password || !(*pp_password)[0])) { SMBC_call_auth_fn(ctx, context, server, share, pp_workgroup, pp_username, pp_password); - + /* * However, smbc_auth_fn may have picked up info relating to * an existing connection, so try for an existing connection @@ -181,9 +181,9 @@ check_server_cache: */ auth_called = 1; goto check_server_cache; - + } - + if (srv) { if (smbc_getFunctionCheckServer(context)(context, srv)) { /* @@ -202,17 +202,17 @@ check_server_cache: smbc_getFunctionRemoveCachedServer(context)(context, srv); } - + /* * Maybe there are more cached connections to this * server */ goto check_server_cache; } - + return srv; } - + return NULL; } @@ -247,19 +247,19 @@ SMBC_server(TALLOC_CTX *ctx, int port_try_next; const char *username_used; NTSTATUS status; - + zero_addr(&ss); ZERO_STRUCT(c); - + if (server[0] == 0) { errno = EPERM; return NULL; } - + /* Look for a cached connection */ srv = SMBC_find_server(ctx, context, server, share, pp_workgroup, pp_username, pp_password); - + /* * If we found a connection and we're only allowed one share per * server... @@ -267,7 +267,7 @@ SMBC_server(TALLOC_CTX *ctx, if (srv && *share != '\0' && smbc_getOptionOneSharePerServer(context)) { - + /* * ... then if there's no current connection to the share, * connect to it. SMBC_find_server(), or rather the function @@ -282,7 +282,7 @@ SMBC_server(TALLOC_CTX *ctx, pp_workgroup, pp_username, pp_password); - + if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; cli_shutdown(srv->cli); @@ -291,17 +291,17 @@ SMBC_server(TALLOC_CTX *ctx, srv); return NULL; } - + /* * We don't need to renegotiate encryption * here as the encryption context is not per * tid. */ - + if (!cli_send_tconX(srv->cli, share, "?????", *pp_password, strlen(*pp_password)+1)) { - + errno = SMBC_errno(context, srv->cli); cli_shutdown(srv->cli); srv->cli = NULL; @@ -309,7 +309,7 @@ SMBC_server(TALLOC_CTX *ctx, srv); srv = NULL; } - + /* * Regenerate the dev value since it's based on both * server and share @@ -320,42 +320,42 @@ SMBC_server(TALLOC_CTX *ctx, } } } - + /* If we have a connection... */ if (srv) { - + /* ... then we're done here. Give 'em what they came for. */ return srv; } - + /* If we're not asked to connect when a connection doesn't exist... */ if (! connect_if_not_found) { /* ... then we're done here. */ return NULL; } - + if (!*pp_workgroup || !*pp_username || !*pp_password) { errno = ENOMEM; return NULL; } - + make_nmb_name(&calling, smbc_getNetbiosName(context), 0x0); make_nmb_name(&called , server, 0x20); - + DEBUG(4,("SMBC_server: server_n=[%s] server=[%s]\n", server_n, server)); - + DEBUG(4,(" -> server_n=[%s] server=[%s]\n", server_n, server)); - + again: - + zero_addr(&ss); - + /* have to open a new connection */ if ((c = cli_initialise()) == NULL) { errno = ENOMEM; return NULL; } - + if (smbc_getOptionUseKerberos(context)) { c->use_kerberos = True; } @@ -363,9 +363,9 @@ again: if (smbc_getOptionFallbackAfterKerberos(context)) { c->fallback_after_kerberos = True; } - + c->timeout = smbc_getTimeout(context); - + /* * Force use of port 139 for first try if share is $IPC, empty, or * null, so browse lists can work @@ -377,15 +377,15 @@ again: port_try_first = 445; port_try_next = 139; } - + c->port = port_try_first; - + status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { - + /* First connection attempt failed. Try alternate port. */ c->port = port_try_next; - + status = cli_connect(c, server_n, &ss); if (!NT_STATUS_IS_OK(status)) { cli_shutdown(c); @@ -393,20 +393,20 @@ again: return NULL; } } - + if (!cli_session_request(c, &calling, &called)) { cli_shutdown(c); if (strcmp(called.name, "*SMBSERVER")) { make_nmb_name(&called , "*SMBSERVER", 0x20); goto again; } else { /* Try one more time, but ensure we don't loop */ - + /* Only try this if server is an IP address ... */ - + if (is_ipaddress(server) && !tried_reverse) { fstring remote_name; struct sockaddr_storage rem_ss; - + if (!interpret_string_addr(&rem_ss, server, NI_NUMERICHOST)) { DEBUG(4, ("Could not convert IP address " @@ -415,9 +415,9 @@ again: errno = ETIMEDOUT; return NULL; } - + tried_reverse++; /* Yuck */ - + if (name_status_find("*", 0, 0, &rem_ss, remote_name)) { make_nmb_name(&called, @@ -430,65 +430,65 @@ again: errno = ETIMEDOUT; return NULL; } - + DEBUG(4,(" session request ok\n")); - + if (!cli_negprot(c)) { cli_shutdown(c); errno = ETIMEDOUT; return NULL; } - + username_used = *pp_username; - + if (!NT_STATUS_IS_OK(cli_session_setup(c, username_used, *pp_password, strlen(*pp_password), *pp_password, strlen(*pp_password), *pp_workgroup))) { - + /* Failed. Try an anonymous login, if allowed by flags. */ username_used = ""; - + if (smbc_getOptionNoAutoAnonymousLogin(context) || !NT_STATUS_IS_OK(cli_session_setup(c, username_used, *pp_password, 1, *pp_password, 0, *pp_workgroup))) { - + cli_shutdown(c); errno = EPERM; return NULL; } } - + DEBUG(4,(" session setup ok\n")); - + if (!cli_send_tconX(c, share, "?????", *pp_password, strlen(*pp_password)+1)) { errno = SMBC_errno(context, c); cli_shutdown(c); return NULL; } - + DEBUG(4,(" tconx ok\n")); - + if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(c, username_used, *pp_password, *pp_workgroup))) { - + /* * context->smb_encryption_level == 1 * means don't fail if encryption can't be negotiated, * == 2 means fail if encryption can't be negotiated. */ - + DEBUG(4,(" SMB encrypt failed\n")); - + if (context->internal->smb_encryption_level == 2) { cli_shutdown(c); errno = EPERM; @@ -497,25 +497,25 @@ again: } DEBUG(4,(" SMB encrypt ok\n")); } - + /* * Ok, we have got a nice connection * Let's allocate a server structure. */ - + srv = SMB_MALLOC_P(SMBCSRV); if (!srv) { errno = ENOMEM; goto failed; } - + ZERO_STRUCTP(srv); srv->cli = c; srv->dev = (dev_t)(str_checksum(server) ^ str_checksum(share)); srv->no_pathinfo = False; srv->no_pathinfo2 = False; srv->no_nt_session = False; - + /* now add it to the cache (internal or external) */ /* Let the cache function set errno if it wants to */ errno = 0; @@ -531,19 +531,19 @@ again: } goto failed; } - + DEBUG(2, ("Server connect ok: //%s/%s: %p\n", server, share, srv)); - + DLIST_ADD(context->internal->servers, srv); return srv; - + failed: cli_shutdown(c); if (!srv) { return NULL; } - + SAFE_FREE(srv); return NULL; } @@ -567,7 +567,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, struct rpc_pipe_client *pipe_hnd; NTSTATUS nt_status; SMBCSRV *ipc_srv=NULL; - + /* * See if we've already created this special connection. Reference * our "special" share name '*IPC$', which is an impossible real share @@ -576,7 +576,7 @@ SMBC_attr_server(TALLOC_CTX *ctx, ipc_srv = SMBC_find_server(ctx, context, server, "*IPC$", pp_workgroup, pp_username, pp_password); if (!ipc_srv) { - + /* We didn't find a cached connection. Get the password */ if (!*pp_password || (*pp_password)[0] == '\0') { /* ... then retrieve it now. */ @@ -589,12 +589,12 @@ SMBC_attr_server(TALLOC_CTX *ctx, return NULL; } } - + flags = 0; if (smbc_getOptionUseKerberos(context)) { flags |= CLI_FULL_CONNECTION_USE_KERBEROS; } - + zero_addr(&ss); nt_status = cli_full_connection(&ipc_cli, global_myname(), server, @@ -610,23 +610,23 @@ SMBC_attr_server(TALLOC_CTX *ctx, errno = ENOTSUP; return NULL; } - + if (context->internal->smb_encryption_level) { /* Attempt UNIX smb encryption. */ if (!NT_STATUS_IS_OK(cli_force_encryption(ipc_cli, *pp_username, *pp_password, *pp_workgroup))) { - + /* * context->smb_encryption_level == * 1 means don't fail if encryption can't be * negotiated, == 2 means fail if encryption * can't be negotiated. */ - + DEBUG(4,(" SMB encrypt failed on IPC$\n")); - + if (context->internal->smb_encryption_level == 2) { cli_shutdown(ipc_cli); errno = EPERM; @@ -635,17 +635,17 @@ SMBC_attr_server(TALLOC_CTX *ctx, } DEBUG(4,(" SMB encrypt ok on IPC$\n")); } - + ipc_srv = SMB_MALLOC_P(SMBCSRV); if (!ipc_srv) { errno = ENOMEM; cli_shutdown(ipc_cli); return NULL; } - + ZERO_STRUCTP(ipc_srv); ipc_srv->cli = ipc_cli; - + nt_status = cli_rpc_pipe_open_noauth( ipc_srv->cli, &ndr_table_lsarpc.syntax_id, &pipe_hnd); if (!NT_STATUS_IS_OK(nt_status)) { @@ -655,28 +655,28 @@ SMBC_attr_server(TALLOC_CTX *ctx, free(ipc_srv); return NULL; } - + /* * Some systems don't support * SEC_RIGHTS_MAXIMUM_ALLOWED, but NT sends 0x2000000 * so we might as well do it too. */ - + nt_status = rpccli_lsa_open_policy( pipe_hnd, talloc_tos(), True, GENERIC_EXECUTE_ACCESS, &ipc_srv->pol); - + if (!NT_STATUS_IS_OK(nt_status)) { errno = SMBC_errno(context, ipc_srv->cli); cli_shutdown(ipc_srv->cli); return NULL; } - + /* now add it to the cache (internal or external) */ - + errno = 0; /* let cache function set errno if it likes */ if (smbc_getFunctionAddCachedServer(context)(context, ipc_srv, server, @@ -691,9 +691,9 @@ SMBC_attr_server(TALLOC_CTX *ctx, free(ipc_srv); return NULL; } - + DLIST_ADD(context->internal->servers, ipc_srv); } - + return ipc_srv; } -- cgit From 893f78731412f2bf79a507e6ebdcbafbdeacb74d Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Fri, 12 Sep 2008 10:12:01 +0200 Subject: doserr: add WERR_NO_SUCH_ALIAS. Guenther (This used to be commit e065802a61f22e9fdcd4b911805c42c46a79b3f2) --- source3/libsmb/doserr.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c index c62918e214..2716e04d91 100644 --- a/source3/libsmb/doserr.c +++ b/source3/libsmb/doserr.c @@ -100,6 +100,7 @@ werror_code_struct dos_errs[] = { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, { "WERR_SPECIAL_ACCOUNT", WERR_SPECIAL_ACCOUNT }, { "WERR_ALIAS_EXISTS", WERR_ALIAS_EXISTS }, + { "WERR_NO_SUCH_ALIAS", WERR_NO_SUCH_ALIAS }, { "WERR_MEMBER_IN_ALIAS", WERR_MEMBER_IN_ALIAS }, { "WERR_TIME_SKEW", WERR_TIME_SKEW }, { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, -- cgit From f8f1679bc46a99462daf4336be5155db37482361 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 12 Sep 2008 21:19:37 +0200 Subject: Add a paranoia check on incoming PDUs (This used to be commit 8b81b85200b7ca18cf81fdbbc3254d8578b35f43) --- source3/libsmb/async_smb.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index eedc7d4481..b4d93ff968 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -759,6 +759,13 @@ static void handle_incoming_pdu(struct cli_state *cli) } + if ((IVAL(pdu, 4) != 0x424d53ff) /* 0xFF"SMB" */ + && (IVAL(pdu, 4) != 0x424d45ff)) /* 0xFF"EMB" */ { + DEBUG(10, ("Got non-SMB PDU\n")); + status = NT_STATUS_INVALID_NETWORK_RESPONSE; + goto invalidate_requests; + } + /* * TODO: Handle oplock break requests */ -- cgit From d892b1c886e6fbdca485807aaac522312e0a6937 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 12 Sep 2008 21:20:02 +0200 Subject: remove a pointless empty line (This used to be commit fba250ece45f6632c7d89b0ea28baab047e41a8f) --- source3/libsmb/async_smb.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index b4d93ff968..79999b5654 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -756,7 +756,6 @@ static void handle_incoming_pdu(struct cli_state *cli) goto invalidate_requests; } } - } if ((IVAL(pdu, 4) != 0x424d53ff) /* 0xFF"SMB" */ -- cgit From ced409b5f754623652580b708943ead6d98adb6d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 12 Sep 2008 22:26:10 +0200 Subject: Fix "make test" -- gna... (This used to be commit c1d3ae80b5f5f07c5efcd7f3ee301d5c3090f3c6) --- source3/libsmb/async_smb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index 79999b5654..c8d010a3fe 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -759,7 +759,7 @@ static void handle_incoming_pdu(struct cli_state *cli) } if ((IVAL(pdu, 4) != 0x424d53ff) /* 0xFF"SMB" */ - && (IVAL(pdu, 4) != 0x424d45ff)) /* 0xFF"EMB" */ { + && (SVAL(pdu, 4) != 0x45ff)) /* 0xFF"E" */ { DEBUG(10, ("Got non-SMB PDU\n")); status = NT_STATUS_INVALID_NETWORK_RESPONSE; goto invalidate_requests; -- cgit From ffbc38abe116fb6edc1739c6440207edc8230de9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Fri, 12 Sep 2008 23:05:51 +0200 Subject: Factor out validate_smb_crypto (This used to be commit 37fcc9dc462dfb006fdac294e49c0dae7588c103) --- source3/libsmb/async_smb.c | 94 ++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 41 deletions(-) (limited to 'source3/libsmb') diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index c8d010a3fe..d5eac07b48 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -689,6 +689,57 @@ NTSTATUS cli_pull_reply(struct async_req *req, return NT_STATUS_OK; } +/** + * Decrypt a PDU, check the signature + * @param[in] cli The cli_state that received something + * @param[in] pdu The incoming bytes + * @retval error code + */ + + +static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu) +{ + NTSTATUS status; + + if ((IVAL(pdu, 4) != 0x424d53ff) /* 0xFF"SMB" */ + && (SVAL(pdu, 4) != 0x45ff)) /* 0xFF"E" */ { + DEBUG(10, ("Got non-SMB PDU\n")); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + if (cli_encryption_on(cli) && CVAL(pdu, 0) == 0) { + uint16_t enc_ctx_num; + + status = get_enc_ctx_num((uint8_t *)pdu, &enc_ctx_num); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("get_enc_ctx_num returned %s\n", + nt_errstr(status))); + return status; + } + + if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { + DEBUG(10, ("wrong enc_ctx %d, expected %d\n", + enc_ctx_num, + cli->trans_enc_state->enc_ctx_num)); + return NT_STATUS_INVALID_HANDLE; + } + + status = common_decrypt_buffer(cli->trans_enc_state, pdu); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("common_decrypt_buffer returned %s\n", + nt_errstr(status))); + return status; + } + } + + if (!cli_check_sign_mac(cli, pdu)) { + DEBUG(10, ("cli_check_sign_mac failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + + return NT_STATUS_OK; +} + /** * A PDU has arrived on cli->evt_inbuf * @param[in] cli The cli_state that received something @@ -758,47 +809,8 @@ static void handle_incoming_pdu(struct cli_state *cli) } } - if ((IVAL(pdu, 4) != 0x424d53ff) /* 0xFF"SMB" */ - && (SVAL(pdu, 4) != 0x45ff)) /* 0xFF"E" */ { - DEBUG(10, ("Got non-SMB PDU\n")); - status = NT_STATUS_INVALID_NETWORK_RESPONSE; - goto invalidate_requests; - } - - /* - * TODO: Handle oplock break requests - */ - - if (cli_encryption_on(cli) && CVAL(pdu, 0) == 0) { - uint16_t enc_ctx_num; - - status = get_enc_ctx_num((uint8_t *)pdu, &enc_ctx_num); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("get_enc_ctx_num returned %s\n", - nt_errstr(status))); - goto invalidate_requests; - } - - if (enc_ctx_num != cli->trans_enc_state->enc_ctx_num) { - DEBUG(10, ("wrong enc_ctx %d, expected %d\n", - enc_ctx_num, - cli->trans_enc_state->enc_ctx_num)); - status = NT_STATUS_INVALID_HANDLE; - goto invalidate_requests; - } - - status = common_decrypt_buffer(cli->trans_enc_state, - pdu); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10, ("common_decrypt_buffer returned %s\n", - nt_errstr(status))); - goto invalidate_requests; - } - } - - if (!cli_check_sign_mac(cli, pdu)) { - DEBUG(10, ("cli_check_sign_mac failed\n")); - status = NT_STATUS_ACCESS_DENIED; + status = validate_smb_crypto(cli, pdu); + if (!NT_STATUS_IS_OK(status)) { goto invalidate_requests; } -- cgit